diff --git a/.clang-format b/.clang-format index f371a13b4d192..c7060124a47aa 100644 --- a/.clang-format +++ b/.clang-format @@ -140,8 +140,8 @@ ForEachMacros: - 'damon_for_each_scheme_safe' - 'damon_for_each_target' - 'damon_for_each_target_safe' - - 'damos_for_each_filter' - - 'damos_for_each_filter_safe' + - 'damos_for_each_core_filter' + - 'damos_for_each_core_filter_safe' - 'damos_for_each_ops_filter' - 'damos_for_each_ops_filter_safe' - 'damos_for_each_quota_goal' @@ -167,7 +167,7 @@ ForEachMacros: - 'drm_connector_for_each_possible_encoder' - 'drm_exec_for_each_locked_object' - 'drm_exec_for_each_locked_object_reverse' - - 'drm_for_each_bridge_in_chain' + - 'drm_for_each_bridge_in_chain_scoped' - 'drm_for_each_connector_iter' - 'drm_for_each_crtc' - 'drm_for_each_crtc_reverse' @@ -415,6 +415,7 @@ ForEachMacros: - 'for_each_prop_dlc_cpus' - 'for_each_prop_dlc_platforms' - 'for_each_property_of_node' + - 'for_each_pt_level_entry' - 'for_each_rdt_resource' - 'for_each_reg' - 'for_each_reg_filtered' @@ -747,6 +748,7 @@ ForEachMacros: - 'ynl_attr_for_each_nested' - 'ynl_attr_for_each_payload' - 'zorro_for_each_dev' + - 'zpci_bus_for_each' IncludeBlocks: Preserve IncludeCategories: diff --git a/.mailmap b/.mailmap index 59254c22847f6..84309a39d329c 100644 --- a/.mailmap +++ b/.mailmap @@ -174,6 +174,7 @@ Carlos Bilbao Changbin Du Chao Yu Chao Yu +Chen-Yu Tsai Chester Lin Chris Chiu Chris Chiu @@ -185,6 +186,9 @@ Christian Brauner Christian Brauner Christian Brauner Christian Marangi +Christophe Leroy +Christophe Leroy +Christophe Leroy Christophe Ricard Christopher Obbard Christoph Hellwig @@ -299,6 +303,7 @@ Hans de Goede Hans Verkuil Hans Verkuil Hans Verkuil +Hao Ge Harry Yoo <42.hyeyoo@gmail.com> Heiko Carstens Heiko Carstens @@ -344,7 +349,8 @@ Jayachandran C Jayachandran C Jayachandran C Jayachandran C - +Jean-Philippe Brucker +Jean-Philippe Brucker Jean-Michel Hautbois Jean Tourrilhes Jeevan Shriram @@ -498,9 +504,7 @@ Mark Brown Mark Starovoytov Markus Schneider-Pargmann Mark Yao -Martin Kepplinger -Martin Kepplinger -Martin Kepplinger +Martin Kepplinger-Novakovic Martyna Szapar-Mudlaw Mathieu Othacehe Mat Martineau @@ -637,6 +641,7 @@ Peter Oruba Peter Oruba Pierre-Louis Bossart Pratyush Anand +Pratyush Yadav Praveen BP Pradeep Kumar Chitrapu Prasad Sodagudi @@ -694,6 +699,7 @@ Sakari Ailus Sam Protsenko Sam Protsenko Sam Ravnborg +Samuel Kayode Sankeerth Billakanti Santosh Shilimkar Santosh Shilimkar @@ -849,6 +855,9 @@ Vivien Didelot Vlad Dogaru Vladimir Davydov Vladimir Davydov +WangYuli +WangYuli +WangYuli Weiwen Hu WeiXiong Liao Wen Gong @@ -860,6 +869,7 @@ Yakir Yang Yanteng Si Ying Huang Yosry Ahmed +Yu-Chun Lin Yusuke Goda Zack Rusin Zhu Yanjun diff --git a/CREDITS b/CREDITS index fa5397f4ebcdd..ca75f110edb6f 100644 --- a/CREDITS +++ b/CREDITS @@ -16,6 +16,10 @@ D: One of assisting postmasters for vger.kernel.org's lists S: (ask for current address) S: Finland +N: Kishon Vijay Abraham I +E: kishon@kernel.org +D: Generic Phy Framework + N: Thomas Abraham E: thomas.ab@samsung.com D: Samsung pin controller driver @@ -1983,6 +1987,7 @@ D: netfilter: TCP window tracking code D: netfilter: raw table D: netfilter: iprange match D: netfilter: new logging interfaces +D: netfilter: ipset D: netfilter: various other hacks S: Tata S: Hungary @@ -2056,16 +2061,15 @@ S: Korte Heul 95 S: 1403 ND BUSSUM S: The Netherlands -N: Martin Kepplinger +N: Martin Kepplinger-Novakovic E: martink@posteo.de -E: martin.kepplinger@puri.sm -W: http://www.martinkepplinger.com P: 4096R/5AB387D3 F208 2B88 0F9E 4239 3468 6E3F 5003 98DF 5AB3 87D3 D: mma8452 accelerators iio driver D: pegasus_notetaker input driver +D: imx8m media and hi846 sensor driver D: Kernel fixes and cleanups -S: Garnisonstraße 26 -S: 4020 Linz +S: Keplerstr. 6 +S: 4050 Traun S: Austria N: Karl Keyte diff --git a/Documentation/ABI/obsolete/sysfs-kernel-kexec-kdump b/Documentation/ABI/obsolete/sysfs-kernel-kexec-kdump new file mode 100644 index 0000000000000..ba26a6a1d2beb --- /dev/null +++ b/Documentation/ABI/obsolete/sysfs-kernel-kexec-kdump @@ -0,0 +1,71 @@ +NOTE: all the ABIs listed in this file are deprecated and will be removed after 2028. + +Here are the alternative ABIs: ++------------------------------------+-----------------------------------------+ +| Deprecated | Alternative | ++------------------------------------+-----------------------------------------+ +| /sys/kernel/kexec_loaded | /sys/kernel/kexec/loaded | ++------------------------------------+-----------------------------------------+ +| /sys/kernel/kexec_crash_loaded | /sys/kernel/kexec/crash_loaded | ++------------------------------------+-----------------------------------------+ +| /sys/kernel/kexec_crash_size | /sys/kernel/kexec/crash_size | ++------------------------------------+-----------------------------------------+ +| /sys/kernel/crash_elfcorehdr_size | /sys/kernel/kexec/crash_elfcorehdr_size | ++------------------------------------+-----------------------------------------+ +| /sys/kernel/kexec_crash_cma_ranges | /sys/kernel/kexec/crash_cma_ranges | ++------------------------------------+-----------------------------------------+ + + +What: /sys/kernel/kexec_loaded +Date: Jun 2006 +Contact: kexec@lists.infradead.org +Description: read only + Indicates whether a new kernel image has been loaded + into memory using the kexec system call. It shows 1 if + a kexec image is present and ready to boot, or 0 if none + is loaded. +User: kexec tools, kdump service + +What: /sys/kernel/kexec_crash_loaded +Date: Jun 2006 +Contact: kexec@lists.infradead.org +Description: read only + Indicates whether a crash (kdump) kernel is currently + loaded into memory. It shows 1 if a crash kernel has been + successfully loaded for panic handling, or 0 if no crash + kernel is present. +User: Kexec tools, Kdump service + +What: /sys/kernel/kexec_crash_size +Date: Dec 2009 +Contact: kexec@lists.infradead.org +Description: read/write + Shows the amount of memory reserved for loading the crash + (kdump) kernel. It reports the size, in bytes, of the + crash kernel area defined by the crashkernel= parameter. + This interface also allows reducing the crashkernel + reservation by writing a smaller value, and the reclaimed + space is added back to the system RAM. +User: Kdump service + +What: /sys/kernel/crash_elfcorehdr_size +Date: Aug 2023 +Contact: kexec@lists.infradead.org +Description: read only + Indicates the preferred size of the memory buffer for the + ELF core header used by the crash (kdump) kernel. It defines + how much space is needed to hold metadata about the crashed + system, including CPU and memory information. This information + is used by the user space utility kexec to support updating the + in-kernel kdump image during hotplug operations. +User: Kexec tools + +What: /sys/kernel/kexec_crash_cma_ranges +Date: Nov 2025 +Contact: kexec@lists.infradead.org +Description: read only + Provides information about the memory ranges reserved from + the Contiguous Memory Allocator (CMA) area that are allocated + to the crash (kdump) kernel. It lists the start and end physical + addresses of CMA regions assigned for crashkernel use. +User: kdump service diff --git a/Documentation/ABI/stable/sysfs-driver-qaic b/Documentation/ABI/stable/sysfs-driver-qaic new file mode 100644 index 0000000000000..c767a93342b3c --- /dev/null +++ b/Documentation/ABI/stable/sysfs-driver-qaic @@ -0,0 +1,19 @@ +What: /sys/bus/pci/drivers/qaic/XXXX:XX:XX.X/accel/accel/dbc_state +Date: October 2025 +KernelVersion: 6.19 +Contact: Jeff Hugo +Description: Represents the current state of DMA Bridge channel (DBC). Below are the possible + states: + + =================== ========================================================== + IDLE (0) DBC is free and can be activated + ASSIGNED (1) DBC is activated and a workload is running on device + BEFORE_SHUTDOWN (2) Sub-system associated with this workload has crashed and + it will shutdown soon + AFTER_SHUTDOWN (3) Sub-system associated with this workload has crashed and + it has shutdown + BEFORE_POWER_UP (4) Sub-system associated with this workload is shutdown and + it will be powered up soon + AFTER_POWER_UP (5) Sub-system associated with this workload is now powered up + =================== ========================================================== +Users: Any userspace application or clients interested in DBC state. diff --git a/Documentation/ABI/testing/rtc-cdev b/Documentation/ABI/testing/rtc-cdev index 25910c3c3d7eb..cec099a27c6d5 100644 --- a/Documentation/ABI/testing/rtc-cdev +++ b/Documentation/ABI/testing/rtc-cdev @@ -14,7 +14,7 @@ Description: for RTCs that support alarms * RTC_ALM_READ, RTC_ALM_SET: Read or set the alarm time for - RTCs that support alarms. Can be set upto 24 hours in the + RTCs that support alarms. Can be set up to 24 hours in the future. Requires a separate RTC_AIE_ON call to enable the alarm interrupt. (Prefer to use RTC_WKALM_*) diff --git a/Documentation/ABI/testing/sysfs-auxdisplay-linedisp b/Documentation/ABI/testing/sysfs-auxdisplay-linedisp new file mode 100644 index 0000000000000..55f1b559e84eb --- /dev/null +++ b/Documentation/ABI/testing/sysfs-auxdisplay-linedisp @@ -0,0 +1,90 @@ +What: /sys/.../message +Date: October 2021 +KernelVersion: 5.16 +Description: + Controls the text message displayed on character line displays. + + Reading returns the current message with a trailing newline. + Writing updates the displayed message. Messages longer than the + display width will automatically scroll. Trailing newlines in + input are automatically trimmed. + + Writing an empty string clears the display. + + Example: + echo "Hello World" > message + cat message # Returns "Hello World\n" + +What: /sys/.../num_chars +Date: November 2025 +KernelVersion: 6.18 +Contact: Jean-François Lessard +Description: + Read-only attribute showing the character width capacity of + the line display device. Messages longer than this will scroll. + + Example: + cat num_chars # Returns "16\n" for 16-char display + +What: /sys/.../scroll_step_ms +Date: October 2021 +KernelVersion: 5.16 +Description: + Controls the scrolling speed for messages longer than the display + width, specified in milliseconds per scroll step. + + Setting to 0 disables scrolling. Default is 500ms. + + Example: + echo "250" > scroll_step_ms # 4Hz scrolling + cat scroll_step_ms # Returns "250\n" + +What: /sys/.../map_seg7 +Date: January 2024 +KernelVersion: 6.9 +Description: + Read/write binary blob representing the ASCII-to-7-segment + display conversion table used by the linedisp driver, as defined + by struct seg7_conversion_map in . + + Only visible on displays with 7-segment capability. + + This attribute is not human-readable. Writes must match the + struct size exactly, else -EINVAL is returned; reads return the + entire mapping as a binary blob. + + This interface and its implementation match existing conventions + used in segment-mapped display drivers since 2005. + + ABI note: This style of binary sysfs attribute *is an exception* + to current "one value per file, text only" sysfs rules, for + historical compatibility and driver uniformity. New drivers are + discouraged from introducing additional binary sysfs ABIs. + + Reference interface guidance: + - include/uapi/linux/map_to_7segment.h + +What: /sys/.../map_seg14 +Date: January 2024 +KernelVersion: 6.9 +Description: + Read/write binary blob representing the ASCII-to-14-segment + display conversion table used by the linedisp driver, as defined + by struct seg14_conversion_map in . + + Only visible on displays with 14-segment capability. + + This attribute is not human-readable. Writes must match the + struct size exactly, else -EINVAL is returned; reads return the + entire mapping as a binary blob. + + This interface and its implementation match existing conventions + used by segment-mapped display drivers since 2005. + + ABI note: This style of binary sysfs attribute *is an exception* + to current "one value per file, text only" sysfs rules, for + historical compatibility and driver uniformity. New drivers are + discouraged from introducing additional binary sysfs ABIs. + + Reference interface guidance: + - include/uapi/linux/map_to_14segment.h diff --git a/Documentation/ABI/testing/sysfs-bus-cxl b/Documentation/ABI/testing/sysfs-bus-cxl index 6b4e8c7a963da..c80a1b5a03dba 100644 --- a/Documentation/ABI/testing/sysfs-bus-cxl +++ b/Documentation/ABI/testing/sysfs-bus-cxl @@ -496,8 +496,17 @@ Description: changed, only freed by writing 0. The kernel makes no guarantees that data is maintained over an address space freeing event, and there is no guarantee that a free followed by an allocate - results in the same address being allocated. + results in the same address being allocated. If extended linear + cache is present, the size indicates extended linear cache size + plus the CXL region size. +What: /sys/bus/cxl/devices/regionZ/extended_linear_cache_size +Date: October, 2025 +KernelVersion: v6.19 +Contact: linux-cxl@vger.kernel.org +Description: + (RO) The size of extended linear cache, if there is an extended + linear cache. Otherwise the attribute will not be visible. What: /sys/bus/cxl/devices/regionZ/mode Date: January, 2023 diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 89b4740dcfa14..5f87dcee78f76 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -898,6 +898,7 @@ What: /sys/.../iio:deviceX/events/in_tempY_thresh_rising_en What: /sys/.../iio:deviceX/events/in_tempY_thresh_falling_en What: /sys/.../iio:deviceX/events/in_capacitanceY_thresh_rising_en What: /sys/.../iio:deviceX/events/in_capacitanceY_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_pressure_thresh_rising_en KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -926,6 +927,7 @@ What: /sys/.../iio:deviceX/events/in_accel_y_roc_rising_en What: /sys/.../iio:deviceX/events/in_accel_y_roc_falling_en What: /sys/.../iio:deviceX/events/in_accel_z_roc_rising_en What: /sys/.../iio:deviceX/events/in_accel_z_roc_falling_en +What: /sys/.../iio:deviceX/events/in_accel_x&y&z_roc_rising_en What: /sys/.../iio:deviceX/events/in_anglvel_x_roc_rising_en What: /sys/.../iio:deviceX/events/in_anglvel_x_roc_falling_en What: /sys/.../iio:deviceX/events/in_anglvel_y_roc_rising_en @@ -1001,6 +1003,7 @@ Description: to the raw signal, allowing slow tracking to resume and the adaptive threshold event detection to function as expected. +What: /sys/.../events/in_accel_mag_adaptive_rising_value What: /sys/.../events/in_accel_thresh_rising_value What: /sys/.../events/in_accel_thresh_falling_value What: /sys/.../events/in_accel_x_raw_thresh_rising_value @@ -1045,6 +1048,7 @@ What: /sys/.../events/in_capacitanceY_thresh_rising_value What: /sys/.../events/in_capacitanceY_thresh_falling_value What: /sys/.../events/in_capacitanceY_thresh_adaptive_rising_value What: /sys/.../events/in_capacitanceY_thresh_falling_rising_value +What: /sys/.../events/in_pressure_thresh_rising_value KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -1147,6 +1151,7 @@ Description: will get activated once in_voltage0_raw goes above 1200 and will become deactivated again once the value falls below 1150. +What: /sys/.../events/in_accel_roc_rising_value What: /sys/.../events/in_accel_x_raw_roc_rising_value What: /sys/.../events/in_accel_x_raw_roc_falling_value What: /sys/.../events/in_accel_y_raw_roc_rising_value @@ -1193,6 +1198,8 @@ Description: value is in raw device units or in processed units (as _raw and _input do on sysfs direct channel read attributes). +What: /sys/.../events/in_accel_mag_adaptive_rising_period +What: /sys/.../events/in_accel_roc_rising_period What: /sys/.../events/in_accel_x_thresh_rising_period What: /sys/.../events/in_accel_x_thresh_falling_period What: /sys/.../events/in_accel_x_roc_rising_period @@ -1362,6 +1369,15 @@ Description: number or direction is not specified, applies to all channels of this type. +What: /sys/.../iio:deviceX/events/in_accel_x_mag_adaptive_rising_en +What: /sys/.../iio:deviceX/events/in_accel_y_mag_adaptive_rising_en +What: /sys/.../iio:deviceX/events/in_accel_z_mag_adaptive_rising_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Similar to in_accel_x_thresh[_rising|_falling]_en, but here the + magnitude of the channel is compared to the adaptive threshold. + What: /sys/.../iio:deviceX/events/in_accel_mag_referenced_en What: /sys/.../iio:deviceX/events/in_accel_mag_referenced_rising_en What: /sys/.../iio:deviceX/events/in_accel_mag_referenced_falling_en @@ -2422,3 +2438,23 @@ Description: Value representing the user's attention to the system expressed in units as percentage. This usually means if the user is looking at the screen or not. + +What: /sys/.../events/in_accel_value_available +KernelVersion: 6.18 +Contact: linux-iio@vger.kernel.org +Description: + List of available threshold values for acceleration event + generation. Applies to all event types on in_accel channels. + Units after application of scale and offset are m/s^2. + Expressed as: + + - a range specified as "[min step max]" + +What: /sys/.../events/in_accel_period_available +KernelVersion: 6.18 +Contact: linux-iio@vger.kernel.org +Description: + List of available periods for accelerometer event detection in + seconds, expressed as: + + - a range specified as "[min step max]" diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index 92debe879ffbf..b767db2c52cb7 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -621,3 +621,84 @@ Description: number extended capability. The file is read only and due to the possible sensitivity of accessible serial numbers, admin only. + +What: /sys/bus/pci/devices/.../tsm/ +Contact: linux-coco@lists.linux.dev +Description: + This directory only appears if a physical device function + supports authentication (PCIe CMA-SPDM), interface security + (PCIe TDISP), and is accepted for secure operation by the + platform TSM driver. This attribute directory appears + dynamically after the platform TSM driver loads. So, only after + the /sys/class/tsm/tsm0 device arrives can tools assume that + devices without a tsm/ attribute directory will never have one; + before that, the security capabilities of the device relative to + the platform TSM are unknown. See + Documentation/ABI/testing/sysfs-class-tsm. + +What: /sys/bus/pci/devices/.../tsm/connect +Contact: linux-coco@lists.linux.dev +Description: + (RW) Write the name of a TSM (TEE Security Manager) device from + /sys/class/tsm to this file to establish a connection with the + device. This typically includes an SPDM (DMTF Security + Protocols and Data Models) session over PCIe DOE (Data Object + Exchange) and may also include PCIe IDE (Integrity and Data + Encryption) establishment. Reads from this attribute return the + name of the connected TSM or the empty string if not + connected. A TSM device signals its readiness to accept PCI + connection via a KOBJ_CHANGE event. + +What: /sys/bus/pci/devices/.../tsm/disconnect +Contact: linux-coco@lists.linux.dev +Description: + (WO) Write the name of the TSM device that was specified + to 'connect' to teardown the connection. + +What: /sys/bus/pci/devices/.../tsm/dsm +Contact: linux-coco@lists.linux.dev +Description: (RO) Return PCI device name of this device's DSM (Device + Security Manager). When a device is in the connected state it + indicates that the platform TSM (TEE Security Manager) has made + a secure-session connection with a device's DSM. A DSM is always + physical function 0 and when the device supports TDISP (TEE + Device Interface Security Protocol) its managed functions also + populate this tsm/dsm attribute. The managed functions of a DSM + are SR-IOV (Single Root I/O Virtualization) virtual functions, + non-zero functions of a multi-function device, or downstream + endpoints depending on whether the DSM is an SR-IOV physical + function, function0 of a multi-function device, or an upstream + PCIe switch port. This is a "link" TSM attribute, see + Documentation/ABI/testing/sysfs-class-tsm. + +What: /sys/bus/pci/devices/.../tsm/bound +Contact: linux-coco@lists.linux.dev +Description: (RO) Return the device name of the TSM when the device is in a + TDISP (TEE Device Interface Security Protocol) operational state + (LOCKED, RUN, or ERROR, not UNLOCKED). Bound devices consume + platform TSM resources and depend on the device's configuration + (e.g. BME (Bus Master Enable) and MSE (Memory Space Enable) + among other settings) to remain stable for the duration of the + bound state. This attribute is only visible for devices that + support TDISP operation, and it is only populated after + successful connect and TSM bind. The TSM bind operation is + initiated by VFIO/IOMMUFD. This is a "link" TSM attribute, see + Documentation/ABI/testing/sysfs-class-tsm. + +What: /sys/bus/pci/devices/.../authenticated +Contact: linux-pci@vger.kernel.org +Description: + When the device's tsm/ directory is present device + authentication (PCIe CMA-SPDM) and link encryption (PCIe IDE) + are handled by the platform TSM (TEE Security Manager). When the + tsm/ directory is not present this attribute reflects only the + native CMA-SPDM authentication state with the kernel's + certificate store. + + If the attribute is not present, it indicates that + authentication is unsupported by the device, or the TSM has no + available authentication methods for the device. + + When present and the tsm/ attribute directory is present, the + authenticated attribute is an alias for the device 'connect' + state. See the 'tsm/connect' attribute for more details. diff --git a/Documentation/ABI/testing/sysfs-class-platform-profile b/Documentation/ABI/testing/sysfs-class-platform-profile index dc72adfb830a4..fcab26894ec33 100644 --- a/Documentation/ABI/testing/sysfs-class-platform-profile +++ b/Documentation/ABI/testing/sysfs-class-platform-profile @@ -23,6 +23,8 @@ Description: This file contains a space-separated list of profiles supported power consumption with a slight bias towards performance performance High performance operation + max-power Higher performance operation that may exceed + internal battery draw limits when on AC power custom Driver defined custom profile ==================== ======================================== diff --git a/Documentation/ABI/testing/sysfs-class-power-rt9756 b/Documentation/ABI/testing/sysfs-class-power-rt9756 new file mode 100644 index 0000000000000..c4d6c2b4715d3 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-power-rt9756 @@ -0,0 +1,30 @@ +What: /sys/class/power_supply/rt9756-*/watchdog_timer +Date: Dec 2025 +KernelVersion: 6.19 +Contact: ChiYuan Huang +Description: + This entry shows and sets the watchdog timer when rt9756 charger + operates in charging mode. When the timer expires, the device + will disable the charging. To prevent the timer expires, any + host communication can make the timer restarted. + + Access: Read, Write + + Valid values: + - 500, 1000, 5000, 30000, 40000, 80000, 128000 or 255000 (milliseconds), + - 0: disabled + +What: /sys/class/power_supply/rt9756-*/operation_mode +Date: Dec 2025 +KernelVersion: 6.19 +Contact: ChiYuan Huang +Description: + This entry shows and set the operation mode when rt9756 charger + operates in charging phase. If 'bypass' mode is used, internal + path will connect vbus directly to vbat. Else, default 'div2' + mode for the switch-cap charging. + + Access: Read, Write + + Valid values: + - 'bypass' or 'div2' diff --git a/Documentation/ABI/testing/sysfs-class-tsm b/Documentation/ABI/testing/sysfs-class-tsm new file mode 100644 index 0000000000000..6fc1a5ac6da1a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-tsm @@ -0,0 +1,19 @@ +What: /sys/class/tsm/tsmN +Contact: linux-coco@lists.linux.dev +Description: + "tsmN" is a device that represents the generic attributes of a + platform TEE Security Manager. It is typically a child of a + platform enumerated TSM device. /sys/class/tsm/tsmN/uevent + signals when the PCI layer is able to support establishment of + link encryption and other device-security features coordinated + through a platform tsm. + +What: /sys/class/tsm/tsmN/streamH.R.E +Contact: linux-pci@vger.kernel.org +Description: + (RO) When a host bridge has established a secure connection via + the platform TSM, symlink appears. The primary function of this + is have a system global review of TSM resource consumption + across host bridges. The link points to the endpoint PCI device + and matches the same link published by the host bridge. See + Documentation/ABI/testing/sysfs-devices-pci-host-bridge. diff --git a/Documentation/ABI/testing/sysfs-class-usb_power_delivery b/Documentation/ABI/testing/sysfs-class-usb_power_delivery index 61d233c320ea7..c754458a527e7 100644 --- a/Documentation/ABI/testing/sysfs-class-usb_power_delivery +++ b/Documentation/ABI/testing/sysfs-class-usb_power_delivery @@ -254,3 +254,31 @@ Contact: Heikki Krogerus Description: The PPS Power Limited bit indicates whether or not the source supply will exceed the rated output power if requested. + +Standard Power Range (SPR) Adjustable Voltage Supplies + +What: /sys/class/usb_power_delivery/...//:spr_adjustable_voltage_supply +Date: Oct 2025 +Contact: Badhri Jagan Sridharan +Description: + Adjustable Voltage Supply (AVS) Augmented PDO (APDO). + +What: /sys/class/usb_power_delivery/...//:spr_adjustable_voltage_supply/maximum_current_9V_to_15V +Date: Oct 2025 +Contact: Badhri Jagan Sridharan +Description: + Maximum Current for 9V to 15V range in milliamperes. + +What: /sys/class/usb_power_delivery/...//:spr_adjustable_voltage_supply/maximum_current_15V_to_20V +Date: Oct 2025 +Contact: Badhri Jagan Sridharan +Description: + Maximum Current for greater than 15V till 20V range in + milliamperes. + +What: /sys/class/usb_power_delivery/...//:spr_adjustable_voltage_supply/peak_current +Date: Oct 2025 +Contact: Badhri Jagan Sridharan +Description: + This file shows the value of the Adjustable Voltage Supply Peak Current + Capability field. diff --git a/Documentation/ABI/testing/sysfs-devices-pci-host-bridge b/Documentation/ABI/testing/sysfs-devices-pci-host-bridge new file mode 100644 index 0000000000000..b91ec34508115 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-pci-host-bridge @@ -0,0 +1,45 @@ +What: /sys/devices/pciDDDD:BB + /sys/devices/.../pciDDDD:BB +Contact: linux-pci@vger.kernel.org +Description: + A PCI host bridge device parents a PCI bus device topology. PCI + controllers may also parent host bridges. The DDDD:BB format + conveys the PCI domain (ACPI segment) number and root bus number + (in hexadecimal) of the host bridge. Note that the domain number + may be larger than the 16-bits that the "DDDD" format implies + for emulated host-bridges. + +What: pciDDDD:BB/firmware_node +Contact: linux-pci@vger.kernel.org +Description: + (RO) Symlink to the platform firmware device object "companion" + of the host bridge. For example, an ACPI device with an _HID of + PNP0A08 (/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00). See + /sys/devices/pciDDDD:BB entry for details about the DDDD:BB + format. + +What: pciDDDD:BB/streamH.R.E +Contact: linux-pci@vger.kernel.org +Description: + (RO) When a platform has established a secure connection, PCIe + IDE, between two Partner Ports, this symlink appears. A stream + consumes a Stream ID slot in each of the Host bridge (H), Root + Port (R) and Endpoint (E). The link points to the Endpoint PCI + device in the Selective IDE Stream pairing. Specifically, "R" + and "E" represent the assigned Selective IDE Stream Register + Block in the Root Port and Endpoint, and "H" represents a + platform specific pool of stream resources shared by the Root + Ports in a host bridge. See /sys/devices/pciDDDD:BB entry for + details about the DDDD:BB format. + +What: pciDDDD:BB/available_secure_streams +Contact: linux-pci@vger.kernel.org +Description: + (RO) When a host bridge has Root Ports that support PCIe IDE + (link encryption and integrity protection) there may be a + limited number of Selective IDE Streams that can be used for + establishing new end-to-end secure links. This attribute + decrements upon secure link setup, and increments upon secure + link teardown. The in-use stream count is determined by counting + stream symlinks. See /sys/devices/pciDDDD:BB entry for details + about the DDDD:BB format. diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 8aed6d94c4cd0..3a05604c21bf8 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -764,6 +764,17 @@ Description: participate in load balancing. These CPUs are set by boot parameter "isolcpus=". +What: /sys/devices/system/cpu/housekeeping +Date: Oct 2025 +Contact: Linux kernel mailing list +Description: + (RO) the list of logical CPUs that are designated by the kernel as + "housekeeping". Each CPU are responsible for handling essential + system-wide background tasks, including RCU callbacks, delayed + timer callbacks, and unbound workqueues, minimizing scheduling + jitter on low-latency, isolated CPUs. These CPUs are set when boot + parameter "isolcpus=nohz" or "nohz_full=" is specified. + What: /sys/devices/system/cpu/crash_hotplug Date: Aug 2023 Contact: Linux kernel mailing list diff --git a/Documentation/ABI/testing/sysfs-driver-intel-xe-sriov b/Documentation/ABI/testing/sysfs-driver-intel-xe-sriov new file mode 100644 index 0000000000000..2fd7e9b7bacc0 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-intel-xe-sriov @@ -0,0 +1,159 @@ +What: /sys/bus/pci/drivers/xe/.../sriov_admin/ +Date: October 2025 +KernelVersion: 6.19 +Contact: intel-xe@lists.freedesktop.org +Description: + This directory appears for the particular Intel Xe device when: + + - device supports SR-IOV, and + - device is a Physical Function (PF), and + - driver support for the SR-IOV PF is enabled on given device. + + This directory is used as a root for all attributes required to + manage both Physical Function (PF) and Virtual Functions (VFs). + + +What: /sys/bus/pci/drivers/xe/.../sriov_admin/pf/ +Date: October 2025 +KernelVersion: 6.19 +Contact: intel-xe@lists.freedesktop.org +Description: + This directory holds attributes related to the SR-IOV Physical + Function (PF). + + +What: /sys/bus/pci/drivers/xe/.../sriov_admin/vf1/ +What: /sys/bus/pci/drivers/xe/.../sriov_admin/vf2/ +What: /sys/bus/pci/drivers/xe/.../sriov_admin/vf/ +Date: October 2025 +KernelVersion: 6.19 +Contact: intel-xe@lists.freedesktop.org +Description: + These directories hold attributes related to the SR-IOV Virtual + Functions (VFs). + + Note that the VF number is 1-based as described in PCI SR-IOV + specification as the Xe driver follows that naming schema. + + There could be "vf1", "vf2" and so on, up to "vf", where + matches the value of the "sriov_totalvfs" attribute. + + +What: /sys/bus/pci/drivers/xe/.../sriov_admin/pf/profile/exec_quantum_ms +What: /sys/bus/pci/drivers/xe/.../sriov_admin/pf/profile/preempt_timeout_us +What: /sys/bus/pci/drivers/xe/.../sriov_admin/pf/profile/sched_priority +What: /sys/bus/pci/drivers/xe/.../sriov_admin/vf/profile/exec_quantum_ms +What: /sys/bus/pci/drivers/xe/.../sriov_admin/vf/profile/preempt_timeout_us +What: /sys/bus/pci/drivers/xe/.../sriov_admin/vf/profile/sched_priority +Date: October 2025 +KernelVersion: 6.19 +Contact: intel-xe@lists.freedesktop.org +Description: + These files expose scheduling parameters for the PF and its VFs, and + are visible only on Intel Xe platforms that use time-sliced GPU sharing. + They can be changed even if VFs are enabled and running and reflect the + settings of all tiles/GTs assigned to the given function. + + exec_quantum_ms: (RW) unsigned integer + The GT execution quantum (EQ) in [ms] for the given function. + Actual quantum value might be aligned per HW/FW requirements. + + Default is 0 (unlimited). + + preempt_timeout_us: (RW) unsigned integer + The GT preemption timeout in [us] of the given function. + Actual timeout value might be aligned per HW/FW requirements. + + Default is 0 (unlimited). + + sched_priority: (RW/RO) string + The GT scheduling priority of the given function. + + "low" - function will be scheduled on the GPU for its EQ/PT + only if function has any work already submitted. + + "normal" - functions will be scheduled on the GPU for its EQ/PT + irrespective of whether it has submitted a work or not. + + "high" - function will be scheduled on the GPU for its EQ/PT + in the next time-slice after the current one completes + and function has a work submitted. + + Default is "low". + + When read, this file will display the current and available + scheduling priorities. The currently active priority level will + be enclosed in square brackets, like: + + [low] normal high + + This file can be read-only if changing the priority is not + supported. + + Writes to these attributes may fail with errors like: + -EINVAL if provided input is malformed or not recognized, + -EPERM if change is not applicable on given HW/FW, + -EIO if FW refuses to change the provisioning. + + Reads from these attributes may fail with: + -EUCLEAN if value is not consistent across all tiles/GTs. + + +What: /sys/bus/pci/drivers/xe/.../sriov_admin/.bulk_profile/exec_quantum_ms +What: /sys/bus/pci/drivers/xe/.../sriov_admin/.bulk_profile/preempt_timeout_us +What: /sys/bus/pci/drivers/xe/.../sriov_admin/.bulk_profile/sched_priority +Date: October 2025 +KernelVersion: 6.19 +Contact: intel-xe@lists.freedesktop.org +Description: + These files allows bulk reconfiguration of the scheduling parameters + of the PF or VFs and are available only for Intel Xe platforms with + GPU sharing based on the time-slice basis. These scheduling parameters + can be changed even if VFs are enabled and running. + + exec_quantum_ms: (WO) unsigned integer + The GT execution quantum (EQ) in [ms] to be applied to all functions. + See sriov_admin/{pf,vf}/profile/exec_quantum_ms for more details. + + preempt_timeout_us: (WO) unsigned integer + The GT preemption timeout (PT) in [us] to be applied to all functions. + See sriov_admin/{pf,vf}/profile/preempt_timeout_us for more details. + + sched_priority: (RW/RO) string + The GT scheduling priority to be applied for all functions. + See sriov_admin/{pf,vf}/profile/sched_priority for more details. + + Writes to these attributes may fail with errors like: + -EINVAL if provided input is malformed or not recognized, + -EPERM if change is not applicable on given HW/FW, + -EIO if FW refuses to change the provisioning. + + +What: /sys/bus/pci/drivers/xe/.../sriov_admin/vf/stop +Date: October 2025 +KernelVersion: 6.19 +Contact: intel-xe@lists.freedesktop.org +Description: + This file allows to control scheduling of the VF on the Intel Xe GPU + platforms. It allows to implement custom policy mechanism in case VFs + are misbehaving or triggering adverse events above defined thresholds. + + stop: (WO) bool + All GT executions of given function shall be immediately stopped. + To allow scheduling this VF again, the VF FLR must be triggered. + + Writes to this attribute may fail with errors like: + -EINVAL if provided input is malformed or not recognized, + -EPERM if change is not applicable on given HW/FW, + -EIO if FW refuses to change the scheduling. + + +What: /sys/bus/pci/drivers/xe/.../sriov_admin/pf/device +What: /sys/bus/pci/drivers/xe/.../sriov_admin/vf/device +Date: October 2025 +KernelVersion: 6.19 +Contact: intel-xe@lists.freedesktop.org +Description: + These are symlinks to the underlying PCI device entry representing + given Xe SR-IOV function. For the PF, this link is always present. + For VFs, this link is present only for currently enabled VFs. diff --git a/Documentation/ABI/testing/sysfs-driver-uio_pci_sva-pasid b/Documentation/ABI/testing/sysfs-driver-uio_pci_sva-pasid new file mode 100644 index 0000000000000..6892fe46cea82 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-uio_pci_sva-pasid @@ -0,0 +1,29 @@ +What: /sys/bus/pci/drivers/uio_pci_sva//pasid +Date: September 2025 +Contact: Yaxing Guo +Description: + Process Address Space ID (PASID) assigned by IOMMU driver to + the device for use with Shared Virtual Addressing (SVA). + + This read-only attribute exposes the PASID (A 20-bit identifier + used in PCIe Address Translation Services and iommu table walks) + allocated by the IOMMU driver during sva device binding. + + User-space UIO applications must read this attribute to obtain + the PASID and program it into the device's configuration registers. + This enables the device to perform DMA using user-space virtual + address, with address translation handled by IOMMU. + + UIO User-space applications must: + - Opening device and Mapping the device's register space via /dev/uioX + (This triggers the IOMMU driver to allocate the PASID) + - Reading the PASID from sysfs + - Writing the PASID to a device-specific register (with example offset) + The code may be like: + + map = mmap(..., "/dev/uio0", ...); + + f = fopen("/sys/.../pasid", "r"); + fscanf(f, "%d", &pasid); + + map[REG_PASID_OFFSET] = pasid; diff --git a/Documentation/ABI/testing/sysfs-driver-uniwill-laptop b/Documentation/ABI/testing/sysfs-driver-uniwill-laptop new file mode 100644 index 0000000000000..eaeb659793d23 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-uniwill-laptop @@ -0,0 +1,53 @@ +What: /sys/bus/platform/devices/INOU0000:XX/fn_lock_toggle_enable +Date: November 2025 +KernelVersion: 6.19 +Contact: Armin Wolf +Description: + Allows userspace applications to enable/disable the FN lock feature + of the integrated keyboard by writing "1"/"0" into this file. + + Reading this file returns the current enable status of the FN lock functionality. + +What: /sys/bus/platform/devices/INOU0000:XX/super_key_toggle_enable +Date: November 2025 +KernelVersion: 6.19 +Contact: Armin Wolf +Description: + Allows userspace applications to enable/disable the super key functionality + of the integrated keyboard by writing "1"/"0" into this file. + + Reading this file returns the current enable status of the super key functionality. + +What: /sys/bus/platform/devices/INOU0000:XX/touchpad_toggle_enable +Date: November 2025 +KernelVersion: 6.19 +Contact: Armin Wolf +Description: + Allows userspace applications to enable/disable the touchpad toggle functionality + of the integrated touchpad by writing "1"/"0" into this file. + + Reading this file returns the current enable status of the touchpad toggle + functionality. + +What: /sys/bus/platform/devices/INOU0000:XX/rainbow_animation +Date: November 2025 +KernelVersion: 6.19 +Contact: Armin Wolf +Description: + Forces the integrated lightbar to display a rainbow animation when the machine + is not suspended. Writing "1"/"0" into this file enables/disables this + functionality. + + Reading this file returns the current status of the rainbow animation functionality. + +What: /sys/bus/platform/devices/INOU0000:XX/breathing_in_suspend +Date: November 2025 +KernelVersion: 6.19 +Contact: Armin Wolf +Description: + Causes the integrated lightbar to display a breathing animation when the machine + has been suspended and is running on AC power. Writing "1"/"0" into this file + enables/disables this functionality. + + Reading this file returns the current status of the breathing animation + functionality. diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index b590809869ca6..770470e0598b8 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -643,6 +643,12 @@ Contact: "Jaegeuk Kim" Description: Shows the number of unusable blocks in a section which was defined by the zone capacity reported by underlying zoned device. +What: /sys/fs/f2fs//max_open_zones +Date: November 2025 +Contact: "Yongpeng Yang" +Description: Shows the max number of zones that F2FS can write concurrently when a zoned + device is mounted. + What: /sys/fs/f2fs//current_atomic_write Date: July 2022 Contact: "Daeho Jeong" diff --git a/Documentation/ABI/testing/sysfs-kernel-kexec-kdump b/Documentation/ABI/testing/sysfs-kernel-kexec-kdump new file mode 100644 index 0000000000000..f59051b5d96d7 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-kernel-kexec-kdump @@ -0,0 +1,61 @@ +What: /sys/kernel/kexec/* +Date: Nov 2025 +Contact: kexec@lists.infradead.org +Description: + The /sys/kernel/kexec/* directory contains sysfs files + that provide information about the configuration status + of kexec and kdump. + +What: /sys/kernel/kexec/loaded +Date: Nov 2025 +Contact: kexec@lists.infradead.org +Description: read only + Indicates whether a new kernel image has been loaded + into memory using the kexec system call. It shows 1 if + a kexec image is present and ready to boot, or 0 if none + is loaded. +User: kexec tools, kdump service + +What: /sys/kernel/kexec/crash_loaded +Date: Nov 2025 +Contact: kexec@lists.infradead.org +Description: read only + Indicates whether a crash (kdump) kernel is currently + loaded into memory. It shows 1 if a crash kernel has been + successfully loaded for panic handling, or 0 if no crash + kernel is present. +User: Kexec tools, Kdump service + +What: /sys/kernel/kexec/crash_size +Date: Nov 2025 +Contact: kexec@lists.infradead.org +Description: read/write + Shows the amount of memory reserved for loading the crash + (kdump) kernel. It reports the size, in bytes, of the + crash kernel area defined by the crashkernel= parameter. + This interface also allows reducing the crashkernel + reservation by writing a smaller value, and the reclaimed + space is added back to the system RAM. +User: Kdump service + +What: /sys/kernel/kexec/crash_elfcorehdr_size +Date: Nov 2025 +Contact: kexec@lists.infradead.org +Description: read only + Indicates the preferred size of the memory buffer for the + ELF core header used by the crash (kdump) kernel. It defines + how much space is needed to hold metadata about the crashed + system, including CPU and memory information. This information + is used by the user space utility kexec to support updating the + in-kernel kdump image during hotplug operations. +User: Kexec tools + +What: /sys/kernel/kexec/crash_cma_ranges +Date: Nov 2025 +Contact: kexec@lists.infradead.org +Description: read only + Provides information about the memory ranges reserved from + the Contiguous Memory Allocator (CMA) area that are allocated + to the crash (kdump) kernel. It lists the start and end physical + addresses of CMA regions assigned for crashkernel use. +User: kdump service diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-damon b/Documentation/ABI/testing/sysfs-kernel-mm-damon index b6b71db36ca72..4fb8b7a6d625a 100644 --- a/Documentation/ABI/testing/sysfs-kernel-mm-damon +++ b/Documentation/ABI/testing/sysfs-kernel-mm-damon @@ -164,6 +164,13 @@ Description: Writing to and reading from this file sets and gets the pid of the target process if the context is for virtual address spaces monitoring, respectively. +What: /sys/kernel/mm/damon/admin/kdamonds//contexts//targets//obsolete_target +Date: Oct 2025 +Contact: SeongJae Park +Description: Writing to and reading from this file sets and gets the + obsoleteness of the matching parameters commit destination + target. + What: /sys/kernel/mm/damon/admin/kdamonds//contexts//targets//regions/nr_regions Date: Mar 2022 Contact: SeongJae Park @@ -303,6 +310,12 @@ Contact: SeongJae Park Description: Writing to and reading from this file sets and gets the nid parameter of the goal. +What: /sys/kernel/mm/damon/admin/kdamonds//contexts//schemes//quotas/goals//path +Date: Oct 2025 +Contact: SeongJae Park +Description: Writing to and reading from this file sets and gets the path + parameter of the goal. + What: /sys/kernel/mm/damon/admin/kdamonds//contexts//schemes//quotas/weights/sz_permil Date: Mar 2022 Contact: SeongJae Park diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi index 28144371a0f1a..89acb6638df8a 100644 --- a/Documentation/ABI/testing/sysfs-platform-asus-wmi +++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi @@ -63,6 +63,7 @@ Date: Aug 2022 KernelVersion: 6.1 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Switch the GPU hardware MUX mode. Laptops with this feature can can be toggled to boot with only the dGPU (discrete mode) or in standard Optimus/Hybrid mode. On switch a reboot is required: @@ -75,6 +76,7 @@ Date: Aug 2022 KernelVersion: 5.17 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Disable discrete GPU: * 0 - Enable dGPU, * 1 - Disable dGPU @@ -84,6 +86,7 @@ Date: Aug 2022 KernelVersion: 5.17 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Enable the external GPU paired with ROG X-Flow laptops. Toggling this setting will also trigger ACPI to disable the dGPU: @@ -95,6 +98,7 @@ Date: Aug 2022 KernelVersion: 5.17 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Enable an LCD response-time boost to reduce or remove ghosting: * 0 - Disable, * 1 - Enable @@ -104,6 +108,7 @@ Date: Jun 2023 KernelVersion: 6.5 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Get the current charging mode being used: * 1 - Barrel connected charger, * 2 - USB-C charging @@ -114,6 +119,7 @@ Date: Jun 2023 KernelVersion: 6.5 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Show if the egpu (XG Mobile) is correctly connected: * 0 - False, * 1 - True @@ -123,6 +129,7 @@ Date: Jun 2023 KernelVersion: 6.5 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Change the mini-LED mode: * 0 - Single-zone, * 1 - Multi-zone @@ -133,6 +140,7 @@ Date: Apr 2024 KernelVersion: 6.10 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury List the available mini-led modes. What: /sys/devices/platform//ppt_pl1_spl @@ -140,6 +148,7 @@ Date: Jun 2023 KernelVersion: 6.5 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Set the Package Power Target total of CPU: PL1 on Intel, SPL on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems: @@ -150,6 +159,7 @@ Date: Jun 2023 KernelVersion: 6.5 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT, on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems: @@ -160,6 +170,7 @@ Date: Jun 2023 KernelVersion: 6.5 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only: * min=5, max=250 @@ -168,6 +179,7 @@ Date: Jun 2023 KernelVersion: 6.5 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Set the APU SPPT limit. Shown on full AMD systems only: * min=5, max=130 @@ -176,6 +188,7 @@ Date: Jun 2023 KernelVersion: 6.5 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Set the platform SPPT limit. Shown on full AMD systems only: * min=5, max=130 @@ -184,6 +197,7 @@ Date: Jun 2023 KernelVersion: 6.5 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Set the dynamic boost limit of the Nvidia dGPU: * min=5, max=25 @@ -192,6 +206,7 @@ Date: Jun 2023 KernelVersion: 6.5 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Set the target temperature limit of the Nvidia dGPU: * min=75, max=87 @@ -200,6 +215,7 @@ Date: Apr 2024 KernelVersion: 6.10 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Set if the BIOS POST sound is played on boot. * 0 - False, * 1 - True @@ -209,6 +225,7 @@ Date: Apr 2024 KernelVersion: 6.10 Contact: "Luke Jones" Description: + DEPRECATED, WILL BE REMOVED SOON: please use asus-armoury Set if the MCU can go in to low-power mode on system sleep * 0 - False, * 1 - True diff --git a/Documentation/ABI/testing/sysfs-platform-ayaneo-ec b/Documentation/ABI/testing/sysfs-platform-ayaneo-ec new file mode 100644 index 0000000000000..4cffbf5fc7caf --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-ayaneo-ec @@ -0,0 +1,19 @@ +What: /sys/devices/platform/ayaneo-ec/controller_power +Date: Nov 2025 +KernelVersion: 6.19 +Contact: "Antheas Kapenekakis" +Description: + Current controller power state. Allows turning on and off + the controller power (e.g. for power savings). Write 1 to + turn on, 0 to turn off. File is readable and writable. + +What: /sys/devices/platform/ayaneo-ec/controller_modules +Date: Nov 2025 +KernelVersion: 6.19 +Contact: "Antheas Kapenekakis" +Description: + Shows which controller modules are currently connected to + the device. Possible values are "left", "right" and "both". + File is read-only. The Windows software for this device + will only set controller power to 1 if both module sides + are connected (i.e. this file returns "both"). diff --git a/Documentation/PCI/pci-error-recovery.rst b/Documentation/PCI/pci-error-recovery.rst index 5df481ac6193d..43bc4e3665b47 100644 --- a/Documentation/PCI/pci-error-recovery.rst +++ b/Documentation/PCI/pci-error-recovery.rst @@ -326,6 +326,21 @@ be recovered, there is nothing more that can be done; the platform will typically report a "permanent failure" in such a case. The device will be considered "dead" in this case. +Drivers typically need to call pci_restore_state() after reset to +re-initialize the device's config space registers and thereby +bring it from D0\ :sub:`uninitialized` into D0\ :sub:`active` state +(PCIe r7.0 sec 5.3.1.1). The PCI core invokes pci_save_state() +on enumeration after initializing config space to ensure that a +saved state is available for subsequent error recovery. +Drivers which modify config space on probe may need to invoke +pci_save_state() afterwards to record those changes for later +error recovery. When going into system suspend, pci_save_state() +is called for every PCI device and that state will be restored +not only on resume, but also on any subsequent error recovery. +In the unlikely event that the saved state recorded on suspend +is unsuitable for error recovery, drivers should call +pci_save_state() on resume. + Drivers for multi-function cards will need to coordinate among themselves as to which driver instance will perform any "one-shot" or global device initialization. For example, the Symbios sym53cxx2 diff --git a/Documentation/accel/qaic/aic100.rst b/Documentation/accel/qaic/aic100.rst index 273da6192fb34..41331cf580b11 100644 --- a/Documentation/accel/qaic/aic100.rst +++ b/Documentation/accel/qaic/aic100.rst @@ -487,8 +487,8 @@ one user crashes, the fallout of that should be limited to that workload and not impact other workloads. SSR accomplishes this. If a particular workload crashes, QSM notifies the host via the QAIC_SSR MHI -channel. This notification identifies the workload by it's assigned DBC. A -multi-stage recovery process is then used to cleanup both sides, and get the +channel. This notification identifies the workload by its assigned DBC. A +multi-stage recovery process is then used to cleanup both sides, and gets the DBC/NSPs into a working state. When SSR occurs, any state in the workload is lost. Any inputs that were in @@ -496,6 +496,27 @@ process, or queued by not yet serviced, are lost. The loaded artifacts will remain in on-card DDR, but the host will need to re-activate the workload if it desires to recover the workload. +When SSR occurs for a specific NSP, the assigned DBC goes through the +following state transactions in order: + +DBC_STATE_BEFORE_SHUTDOWN + Indicates that the affected NSP was found in an unrecoverable error + condition. +DBC_STATE_AFTER_SHUTDOWN + Indicates that the NSP is under reset. +DBC_STATE_BEFORE_POWER_UP + Indicates that the NSP's debug information has been collected, and is + ready to be collected by the host (if desired). At that stage the NSP + is restarted by QSM. +DBC_STATE_AFTER_POWER_UP + Indicates that the NSP has been restarted, fully operational and is + in idle state. + +SSR also has an optional crashdump collection feature. If enabled, the host can +collect the memory dump for the crashed NSP and dump it to the user space via +the dev_coredump subsystem. The host can also decline the crashdump collection +request from the device. + Reliability, Accessibility, Serviceability (RAS) ================================================ diff --git a/Documentation/accel/qaic/qaic.rst b/Documentation/accel/qaic/qaic.rst index 018d6cc173d7e..ef27e262cb914 100644 --- a/Documentation/accel/qaic/qaic.rst +++ b/Documentation/accel/qaic/qaic.rst @@ -36,7 +36,7 @@ polling mode and reenables the IRQ line. This mitigation in QAIC is very effective. The same lprnet usecase that generates 100k IRQs per second (per /proc/interrupts) is reduced to roughly 64 IRQs over 5 minutes while keeping the host system stable, and having the same -workload throughput performance (within run to run noise variation). +workload throughput performance (within run-to-run noise variation). Single MSI Mode --------------- @@ -49,7 +49,7 @@ useful to be able to fall back to a single MSI when needed. To support this fallback, we allow the case where only one MSI is able to be allocated, and share that one MSI between MHI and the DBCs. The device detects when only one MSI has been configured and directs the interrupts for the DBCs -to the interrupt normally used for MHI. Unfortunately this means that the +to the interrupt normally used for MHI. Unfortunately, this means that the interrupt handlers for every DBC and MHI wake up for every interrupt that arrives; however, the DBC threaded irq handlers only are started when work to be done is detected (MHI will always start its threaded handler). @@ -62,9 +62,9 @@ never disabled, allowing each new entry to the FIFO to trigger a new interrupt. Neural Network Control (NNC) Protocol ===================================== -The implementation of NNC is split between the KMD (QAIC) and UMD. In general +The implementation of NNC is split between the KMD (QAIC) and UMD. In general, QAIC understands how to encode/decode NNC wire protocol, and elements of the -protocol which require kernel space knowledge to process (for example, mapping +protocol which requires kernel space knowledge to process (for example, mapping host memory to device IOVAs). QAIC understands the structure of a message, and all of the transactions. QAIC does not understand commands (the payload of a passthrough transaction). diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index 4c072e85acdfe..7f5b59d95fce5 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -1513,6 +1513,10 @@ The following nested keys are defined. oom_group_kill The number of times a group OOM has occurred. + sock_throttled + The number of times network sockets associated with + this cgroup are throttled. + memory.events.local Similar to memory.events but the fields in the file are local to the cgroup i.e. not hierarchical. The file modified event diff --git a/Documentation/admin-guide/device-mapper/dm-raid.rst b/Documentation/admin-guide/device-mapper/dm-raid.rst index bb17e26e3c1be..e11f107647709 100644 --- a/Documentation/admin-guide/device-mapper/dm-raid.rst +++ b/Documentation/admin-guide/device-mapper/dm-raid.rst @@ -20,10 +20,10 @@ The target is named "raid" and it accepts the following parameters:: raid0 RAID0 striping (no resilience) raid1 RAID1 mirroring raid4 RAID4 with dedicated last parity disk - raid5_n RAID5 with dedicated last parity disk supporting takeover + raid5_n RAID5 with dedicated last parity disk supporting takeover from/to raid1 Same as raid4 - - Transitory layout + - Transitory layout for takeover from/to raid1 raid5_la RAID5 left asymmetric - rotating parity 0 with data continuation @@ -48,8 +48,8 @@ The target is named "raid" and it accepts the following parameters:: raid6_n_6 RAID6 with dedicate parity disks - parity and Q-syndrome on the last 2 disks; - layout for takeover from/to raid4/raid5_n - raid6_la_6 Same as "raid_la" plus dedicated last Q-syndrome disk + layout for takeover from/to raid0/raid4/raid5_n + raid6_la_6 Same as "raid_la" plus dedicated last Q-syndrome disk supporting takeover from/to raid5 - layout for takeover from raid5_la from/to raid6 raid6_ra_6 Same as "raid5_ra" dedicated last Q-syndrome disk @@ -173,9 +173,9 @@ The target is named "raid" and it accepts the following parameters:: The delta_disks option value (-251 < N < +251) triggers device removal (negative value) or device addition (positive value) to any reshape supporting raid levels 4/5/6 and 10. - RAID levels 4/5/6 allow for addition of devices (metadata - and data device tuple), raid10_near and raid10_offset only - allow for device addition. raid10_far does not support any + RAID levels 4/5/6 allow for addition and removal of devices + (metadata and data device tuple), raid10_near and raid10_offset + only allow for device addition. raid10_far does not support any reshaping at all. A minimum of devices have to be kept to enforce resilience, which is 3 devices for raid4/5 and 4 devices for raid6. @@ -372,6 +372,72 @@ to safely enable discard support for RAID 4/5/6: 'devices_handle_discards_safely' +Takeover/Reshape Support +------------------------ +The target natively supports these two types of MDRAID conversions: + +o Takeover: Converts an array from one RAID level to another + +o Reshape: Changes the internal layout while maintaining the current RAID level + +Each operation is only valid under specific constraints imposed by the existing array's layout and configuration. + + +Takeover: +linear -> raid1 with N >= 2 mirrors +raid0 -> raid4 (add dedicated parity device) +raid0 -> raid5 (add dedicated parity device) +raid0 -> raid10 with near layout and N >= 2 mirror groups (raid0 stripes have to become first member within mirror groups) +raid1 -> linear +raid1 -> raid5 with 2 mirrors +raid4 -> raid5 w/ rotating parity +raid5 with dedicated parity device -> raid4 +raid5 -> raid6 (with dedicated Q-syndrome) +raid6 (with dedicated Q-syndrome) -> raid5 +raid10 with near layout and even number of disks -> raid0 (select any in-sync device from each mirror group) + +Reshape: +linear: not possible +raid0: not possible +raid1: change number of mirrors +raid4: add and remove stripes (minimum 3), change stripesize +raid5: add and remove stripes (minimum 3, special case 2 for raid1 takeover), change rotating parity algorithms, change stripesize +raid6: add and remove stripes (minimum 4), change rotating syndrome algorithms, change stripesize +raid10 near: add stripes (minimum 4), change stripesize, no stripe removal possible, change to offset layout +raid10 offset: add stripes, change stripesize, no stripe removal possible, change to near layout +raid10 far: not possible + +Table line examples: + +### raid1 -> raid5 +# +# 2 devices limitation in raid1. +# raid5 personality is able to just map 2 like raid1. +# Reshape after takeover to change to full raid5 layout + + 0 1960886272 raid raid1 3 0 region_size 2048 2 /dev/dm-0 /dev/dm-1 /dev/dm-2 /dev/dm-3 + +# dm-0 and dm-2 are e.g. 4MiB large metadata devices, dm-1 and dm-3 have to be at least 1960886272 big. +# +# Table line to takeover to raid5 + + 0 1960886272 raid raid5 3 0 region_size 2048 2 /dev/dm-0 /dev/dm-1 /dev/dm-2 /dev/dm-3 + +# Add required out-of-place reshape space to the beginniong of the given 2 data devices, +# allocate another metadata/data device tuple with the same sizes for the parity space +# and zero the first 4K of the metadata device. +# +# Example table of the out-of-place reshape space addition for one data device, e.g. dm-1 + + 0 8192 linear 8:0 0 1960903888 # <- must be free space segment + 8192 1960886272 linear 8:0 0 2048 # previous data segment + +# Mapping table for e.g. raid5_rs reshape causing the size of the raid device to double-fold once the reshape finishes. +# Check the status output (e.g. "dmsetup status $RaidDev") for progess. + + 0 $((2 * 1960886272)) raid raid5 7 0 region_size 2048 data_offset 8192 delta_disk 1 2 /dev/dm-0 /dev/dm-1 /dev/dm-2 /dev/dm-3 + + Version History --------------- diff --git a/Documentation/admin-guide/device-mapper/verity.rst b/Documentation/admin-guide/device-mapper/verity.rst index 8c3f1f967a3cd..3ecab1cff9c64 100644 --- a/Documentation/admin-guide/device-mapper/verity.rst +++ b/Documentation/admin-guide/device-mapper/verity.rst @@ -236,8 +236,10 @@ is available at the cryptsetup project's wiki page Status ====== -V (for Valid) is returned if every check performed so far was valid. -If any check failed, C (for Corruption) is returned. +1. V (for Valid) is returned if every check performed so far was valid. + If any check failed, C (for Corruption) is returned. +2. Number of corrected blocks by Forward Error Correction. + '-' if Forward Error Correction is not enabled. Example ======= diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst index 7c036590cd07c..095a63892257e 100644 --- a/Documentation/admin-guide/dynamic-debug-howto.rst +++ b/Documentation/admin-guide/dynamic-debug-howto.rst @@ -223,12 +223,13 @@ The flags are:: f Include the function name s Include the source file name l Include line number + d Include call trace For ``print_hex_dump_debug()`` and ``print_hex_dump_bytes()``, only the ``p`` flag has meaning, other flags are ignored. -Note the regexp ``^[-+=][fslmpt_]+$`` matches a flags specification. -To clear all flags at once, use ``=_`` or ``-fslmpt``. +Note the regexp ``^[-+=][fslmptd_]+$`` matches a flags specification. +To clear all flags at once, use ``=_`` or ``-fslmptd``. Debug messages during Boot Process diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 1e89d122f0841..a8d0afde7f85a 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -767,6 +767,14 @@ Kernel parameters nokmem -- Disable kernel memory accounting. nobpf -- Disable BPF memory accounting. + check_pages= [MM,EARLY] Enable sanity checking of pages after + allocations / before freeing. This adds checks to catch + double-frees, use-after-frees, and other sources of + page corruption by inspecting page internals (flags, + mapcount/refcount, memcg_data, etc.). + Format: { "0" | "1" } + Default: 0 (1 if CONFIG_DEBUG_VM is set) + checkreqprot= [SELINUX] Set initial checkreqprot flag value. Format: { "0" | "1" } See security/selinux/Kconfig help text. @@ -1111,7 +1119,7 @@ Kernel parameters It will be ignored when crashkernel=X,high is not used or memory reserved is below 4G. crashkernel=size[KMG],cma - [KNL, X86] Reserve additional crash kernel memory from + [KNL, X86, ppc] Reserve additional crash kernel memory from CMA. This reservation is usable by the first system's userspace memory and kernel movable allocations (memory balloon, zswap). Pages allocated from this memory range @@ -1211,12 +1219,8 @@ Kernel parameters debugfs= [KNL,EARLY] This parameter enables what is exposed to userspace and debugfs internal clients. - Format: { on, no-mount, off } + Format: { on, off } on: All functions are enabled. - no-mount: - Filesystem is not registered but kernel clients can - access APIs and a crashkernel can be used to read - its content. There is nothing to mount. off: Filesystem is not registered and clients get a -EPERM as result when trying to register files or directories within debugfs. @@ -2118,14 +2122,20 @@ Kernel parameters the added memory block itself do not be affected. hung_task_panic= - [KNL] Should the hung task detector generate panics. - Format: 0 | 1 + [KNL] Number of hung tasks to trigger kernel panic. + Format: - A value of 1 instructs the kernel to panic when a - hung task is detected. The default value is controlled - by the CONFIG_BOOTPARAM_HUNG_TASK_PANIC build-time - option. The value selected by this boot parameter can - be changed later by the kernel.hung_task_panic sysctl. + When set to a non-zero value, a kernel panic will be triggered if + the number of detected hung tasks reaches this value. + + 0: don't panic + 1: panic immediately on first hung task + N: panic after N hung tasks are detected in a single scan + + The default value is controlled by the + CONFIG_BOOTPARAM_HUNG_TASK_PANIC build-time option. The value + selected by this boot parameter can be changed later by the + kernel.hung_task_panic sysctl. hvc_iucv= [S390] Number of z/VM IUCV hypervisor console (HVC) terminal devices. Valid values: 0..8 @@ -7304,6 +7314,9 @@ Kernel parameters them frequently to increase the rate of SLB faults on kernel addresses. + no_slb_preload [PPC,EARLY] + Disables slb preloading for userspace. + sunrpc.min_resvport= sunrpc.max_resvport= [NFS,SUNRPC] diff --git a/Documentation/admin-guide/laptops/index.rst b/Documentation/admin-guide/laptops/index.rst index db842b629303c..6432c251dc951 100644 --- a/Documentation/admin-guide/laptops/index.rst +++ b/Documentation/admin-guide/laptops/index.rst @@ -17,3 +17,4 @@ Laptop Drivers sonypi thinkpad-acpi toshiba_haps + uniwill-laptop diff --git a/Documentation/admin-guide/laptops/uniwill-laptop.rst b/Documentation/admin-guide/laptops/uniwill-laptop.rst new file mode 100644 index 0000000000000..a16baf15516b1 --- /dev/null +++ b/Documentation/admin-guide/laptops/uniwill-laptop.rst @@ -0,0 +1,60 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Uniwill laptop extra features +============================= + +On laptops manufactured by Uniwill (either directly or as ODM), the ``uniwill-laptop`` driver +handles various platform-specific features. + +Module Loading +-------------- + +The ``uniwill-laptop`` driver relies on a DMI table to automatically load on supported devices. +When using the ``force`` module parameter, this DMI check will be omitted, allowing the driver +to be loaded on unsupported devices for testing purposes. + +Hotkeys +------- + +Usually the FN keys work without a special driver. However as soon as the ``uniwill-laptop`` driver +is loaded, the FN keys need to be handled manually. This is done automatically by the driver itself. + +Keyboard settings +----------------- + +The ``uniwill-laptop`` driver allows the user to enable/disable: + + - the FN and super key lock functionality of the integrated keyboard + - the touchpad toggle functionality of the integrated touchpad + +See Documentation/ABI/testing/sysfs-driver-uniwill-laptop for details. + +Hwmon interface +--------------- + +The ``uniwill-laptop`` driver supports reading of the CPU and GPU temperature and supports up to +two fans. Userspace applications can access sensor readings over the hwmon sysfs interface. + +Platform profile +---------------- + +Support for changing the platform performance mode is currently not implemented. + +Battery Charging Control +------------------------ + +The ``uniwill-laptop`` driver supports controlling the battery charge limit. This happens over +the standard ``charge_control_end_threshold`` power supply sysfs attribute. All values +between 1 and 100 percent are supported. + +Additionally the driver signals the presence of battery charging issues through the standard +``health`` power supply sysfs attribute. + +Lightbar +-------- + +The ``uniwill-laptop`` driver exposes the lightbar found on some models as a standard multicolor +LED class device. The default name of this LED class device is ``uniwill:multicolor:status``. + +See Documentation/ABI/testing/sysfs-driver-uniwill-laptop for details on how to control the various +animation modes of the lightbar. diff --git a/Documentation/admin-guide/media/mali-c55-graph.dot b/Documentation/admin-guide/media/mali-c55-graph.dot new file mode 100644 index 0000000000000..0775ba42bf4cf --- /dev/null +++ b/Documentation/admin-guide/media/mali-c55-graph.dot @@ -0,0 +1,19 @@ +digraph board { + rankdir=TB + n00000001 [label="{{} | mali-c55 tpg\n/dev/v4l-subdev0 | { 0}}", shape=Mrecord, style=filled, fillcolor=green] + n00000001:port0 -> n00000003:port0 [style=dashed] + n00000003 [label="{{ 0} | mali-c55 isp\n/dev/v4l-subdev1 | { 1 | 2}}", shape=Mrecord, style=filled, fillcolor=green] + n00000003:port1 -> n00000007:port0 [style=bold] + n00000003:port2 -> n00000007:port2 [style=bold] + n00000003:port1 -> n0000000b:port0 [style=bold] + n00000007 [label="{{ 0 | 2} | mali-c55 resizer fr\n/dev/v4l-subdev2 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000007:port1 -> n0000000e [style=bold] + n0000000b [label="{{ 0} | mali-c55 resizer ds\n/dev/v4l-subdev3 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n0000000b:port1 -> n00000012 [style=bold] + n0000000e [label="mali-c55 fr\n/dev/video0", shape=box, style=filled, fillcolor=yellow] + n00000012 [label="mali-c55 ds\n/dev/video1", shape=box, style=filled, fillcolor=yellow] + n00000022 [label="{{ 0} | csi2-rx\n/dev/v4l-subdev4 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000022:port1 -> n00000003:port0 + n00000027 [label="{{} | imx415 1-001a\n/dev/v4l-subdev5 | { 0}}", shape=Mrecord, style=filled, fillcolor=green] + n00000027:port0 -> n00000022:port0 [style=bold] +} \ No newline at end of file diff --git a/Documentation/admin-guide/media/mali-c55.rst b/Documentation/admin-guide/media/mali-c55.rst new file mode 100644 index 0000000000000..315f982000c48 --- /dev/null +++ b/Documentation/admin-guide/media/mali-c55.rst @@ -0,0 +1,413 @@ +.. SPDX-License-Identifier: GPL-2.0 + +========================================== +ARM Mali-C55 Image Signal Processor driver +========================================== + +Introduction +============ + +This file documents the driver for ARM's Mali-C55 Image Signal Processor. The +driver is located under drivers/media/platform/arm/mali-c55. + +The Mali-C55 ISP receives data in either raw Bayer format or RGB/YUV format from +sensors through either a parallel interface or a memory bus before processing it +and outputting it through an internal DMA engine. Two output pipelines are +possible (though one may not be fitted, depending on the implementation). These +are referred to as "Full resolution" and "Downscale", but the naming is historic +and both pipes are capable of cropping/scaling operations. The full resolution +pipe is also capable of outputting RAW data, bypassing much of the ISP's +processing. The downscale pipe cannot output RAW data. An integrated test +pattern generator can be used to drive the ISP and produce image data in the +absence of a connected camera sensor. The driver module is named mali_c55, and +is enabled through the CONFIG_VIDEO_MALI_C55 config option. + +The driver implements V4L2, Media Controller and V4L2 Subdevice interfaces and +expects camera sensors connected to the ISP to have V4L2 subdevice interfaces. + +Mali-C55 ISP hardware +===================== + +A high level functional view of the Mali-C55 ISP is presented below. The ISP +takes input from either a live source or through a DMA engine for memory input, +depending on the SoC integration.:: + + +---------+ +----------+ +--------+ + | Sensor |--->| CSI-2 Rx | "Full Resolution" | DMA | + +---------+ +----------+ |\ Output +--->| Writer | + | | \ | +--------+ + | | \ +----------+ +------+---> Streaming I/O + +------------+ +------->| | | | | + | | | |-->| Mali-C55 |--+ + | DMA Reader |--------------->| | | ISP | | + | | | / | | | +---> Streaming I/O + +------------+ | / +----------+ | | + |/ +------+ + | +--------+ + +--->| DMA | + "Downscaled" | Writer | + Output +--------+ + +Media Controller Topology +========================= + +An example of the ISP's topology (as implemented in a system with an IMX415 +camera sensor and generic CSI-2 receiver) is below: + + +.. kernel-figure:: mali-c55-graph.dot + :alt: mali-c55-graph.dot + :align: center + +The driver has 4 V4L2 subdevices: + +- `mali_c55 isp`: Responsible for configuring input crop and color space + conversion +- `mali_c55 tpg`: The test pattern generator, emulating a camera sensor. +- `mali_c55 resizer fr`: The Full-Resolution pipe resizer +- `mali_c55 resizer ds`: The Downscale pipe resizer + +The driver has 3 V4L2 video devices: + +- `mali-c55 fr`: The full-resolution pipe's capture device +- `mali-c55 ds`: The downscale pipe's capture device +- `mali-c55 3a stats`: The 3A statistics capture device + +Frame sequences are synchronised across to two capture devices, meaning if one +pipe is started later than the other the sequence numbers returned in its +buffers will match those of the other pipe rather than starting from zero. + +Idiosyncrasies +-------------- + +**mali-c55 isp** +The `mali-c55 isp` subdevice has a single sink pad to which all sources of data +should be connected. The active source is selected by enabling the appropriate +media link and disabling all others. The ISP has two source pads, reflecting the +different paths through which it can internally route data. Tap points within +the ISP allow users to divert data to avoid processing by some or all of the +hardware's processing steps. The diagram below is intended only to highlight how +the bypassing works and is not a true reflection of those processing steps; for +a high-level functional block diagram see ARM's developer page for the +ISP [3]_:: + + +--------------------------------------------------------------+ + | Possible Internal ISP Data Routes | + | +------------+ +----------+ +------------+ | + +---+ | | | | | Colour | +---+ + | 0 |--+-->| Processing |->| Demosaic |->| Space |--->| 1 | + +---+ | | | | | | Conversion | +---+ + | | +------------+ +----------+ +------------+ | + | | +---+ + | +---------------------------------------------------| 2 | + | +---+ + | | + +--------------------------------------------------------------+ + + +.. flat-table:: + :header-rows: 1 + + * - Pad + - Direction + - Purpose + + * - 0 + - sink + - Data input, connected to the TPG and camera sensors + + * - 1 + - source + - RGB/YUV data, connected to the FR and DS V4L2 subdevices + + * - 2 + - source + - RAW bayer data, connected to the FR V4L2 subdevices + +The ISP is limited to both input and output resolutions between 640x480 and +8192x8192, and this is reflected in the ISP and resizer subdevice's .set_fmt() +operations. + +**mali-c55 resizer fr** +The `mali-c55 resizer fr` subdevice has two _sink_ pads to reflect the different +insertion points in the hardware (either RAW or demosaiced data): + +.. flat-table:: + :header-rows: 1 + + * - Pad + - Direction + - Purpose + + * - 0 + - sink + - Data input connected to the ISP's demosaiced stream. + + * - 1 + - source + - Data output connected to the capture video device + + * - 2 + - sink + - Data input connected to the ISP's raw data stream + +The data source in use is selected through the routing API; two routes each of a +single stream are available: + +.. flat-table:: + :header-rows: 1 + + * - Sink Pad + - Source Pad + - Purpose + + * - 0 + - 1 + - Demosaiced data route + + * - 2 + - 1 + - Raw data route + + +If the demosaiced route is active then the FR pipe is only capable of output +in RGB/YUV formats. If the raw route is active then the output reflects the +input (which may be either Bayer or RGB/YUV data). + +Using the driver to capture video +================================= + +Using the media controller APIs we can configure the input source and ISP to +capture images in a variety of formats. In the examples below, configuring the +media graph is done with the v4l-utils [1]_ package's media-ctl utility. +Capturing the images is done with yavta [2]_. + +Configuring the input source +---------------------------- + +The first step is to set the input source that we wish by enabling the correct +media link. Using the example topology above, we can select the TPG as follows: + +.. code-block:: none + + media-ctl -l "'lte-csi2-rx':1->'mali-c55 isp':0[0]" + media-ctl -l "'mali-c55 tpg':0->'mali-c55 isp':0[1]" + +Configuring which video devices will stream data +------------------------------------------------ + +The driver will wait for all video devices to have their VIDIOC_STREAMON ioctl +called before it tells the sensor to start streaming. To facilitate this we need +to enable links to the video devices that we want to use. In the example below +we enable the links to both of the image capture video devices + +.. code-block:: none + + media-ctl -l "'mali-c55 resizer fr':1->'mali-c55 fr':0[1]" + media-ctl -l "'mali-c55 resizer ds':1->'mali-c55 ds':0[1]" + +Capturing bayer data from the source and processing to RGB/YUV +-------------------------------------------------------------- + +To capture 1920x1080 bayer data from the source and push it through the ISP's +full processing pipeline, we configure the data formats appropriately on the +source, ISP and resizer subdevices and set the FR resizer's routing to select +processed data. The media bus format on the resizer's source pad will be either +RGB121212_1X36 or YUV10_1X30, depending on whether you want to capture RGB or +YUV. The ISP's debayering block outputs RGB data natively, setting the source +pad format to YUV10_1X30 enables the colour space conversion block. + +In this example we target RGB565 output, so select RGB121212_1X36 as the resizer +source pad's format: + +.. code-block:: none + + # Set formats on the TPG and ISP + media-ctl -V "'mali-c55 tpg':0[fmt:SRGGB20_1X20/1920x1080]" + media-ctl -V "'mali-c55 isp':0[fmt:SRGGB20_1X20/1920x1080]" + media-ctl -V "'mali-c55 isp':1[fmt:SRGGB20_1X20/1920x1080]" + + # Set routing on the FR resizer + media-ctl -R "'mali-c55 resizer fr'[0/0->1/0[1],2/0->1/0[0]]" + + # Set format on the resizer, must be done AFTER the routing. + media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/1920x1080]" + +The downscale output can also be used to stream data at the same time. In this +case since only processed data can be captured through the downscale output no +routing need be set: + +.. code-block:: none + + # Set format on the resizer + media-ctl -V "'mali-c55 resizer ds':1[fmt:RGB121212_1X36/1920x1080]" + +Following which images can be captured from both the FR and DS output's video +devices (simultaneously, if desired): + +.. code-block:: none + + yavta -f RGB565 -s 1920x1080 -c10 /dev/video0 + yavta -f RGB565 -s 1920x1080 -c10 /dev/video1 + +Cropping the image +~~~~~~~~~~~~~~~~~~ + +Both the full resolution and downscale pipes can crop to a minimum resolution of +640x480. To crop the image simply configure the resizer's sink pad's crop and +compose rectangles and set the format on the video device: + +.. code-block:: none + + media-ctl -V "'mali-c55 resizer fr':0[fmt:RGB121212_1X36/1920x1080 crop:(480,270)/640x480 compose:(0,0)/640x480]" + media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/640x480]" + yavta -f RGB565 -s 640x480 -c10 /dev/video0 + +Downscaling the image +~~~~~~~~~~~~~~~~~~~~~ + +Both the full resolution and downscale pipes can downscale the image by up to 8x +provided the minimum 640x480 output resolution is adhered to. For the best image +result the scaling ratio for each direction should be the same. To configure +scaling we use the compose rectangle on the resizer's sink pad: + +.. code-block:: none + + media-ctl -V "'mali-c55 resizer fr':0[fmt:RGB121212_1X36/1920x1080 crop:(0,0)/1920x1080 compose:(0,0)/640x480]" + media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/640x480]" + yavta -f RGB565 -s 640x480 -c10 /dev/video0 + +Capturing images in YUV formats +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If we need to output YUV data rather than RGB the color space conversion block +needs to be active, which is achieved by setting MEDIA_BUS_FMT_YUV10_1X30 on the +resizer's source pad. We can then configure a capture format like NV12 (here in +its multi-planar variant) + +.. code-block:: none + + media-ctl -V "'mali-c55 resizer fr':1[fmt:YUV10_1X30/1920x1080]" + yavta -f NV12M -s 1920x1080 -c10 /dev/video0 + +Capturing RGB data from the source and processing it with the resizers +---------------------------------------------------------------------- + +The Mali-C55 ISP can work with sensors capable of outputting RGB data. In this +case although none of the image quality blocks would be used it can still +crop/scale the data in the usual way. For this reason RGB data input to the ISP +still goes through the ISP subdevice's pad 1 to the resizer. + +To achieve this, the ISP's sink pad's format is set to +MEDIA_BUS_FMT_RGB202020_1X60 - this reflects the format that data must be in to +work with the ISP. Converting the camera sensor's output to that format is the +responsibility of external hardware. + +In this example we ask the test pattern generator to give us RGB data instead of +bayer. + +.. code-block:: none + + media-ctl -V "'mali-c55 tpg':0[fmt:RGB202020_1X60/1920x1080]" + media-ctl -V "'mali-c55 isp':0[fmt:RGB202020_1X60/1920x1080]" + +Cropping or scaling the data can be done in exactly the same way as outlined +earlier. + +Capturing raw data from the source and outputting it unmodified +----------------------------------------------------------------- + +The ISP can additionally capture raw data from the source and output it on the +full resolution pipe only, completely unmodified. In this case the downscale +pipe can still process the data normally and be used at the same time. + +To configure raw bypass the FR resizer's subdevice's routing table needs to be +configured, followed by formats in the appropriate places: + +.. code-block:: none + + media-ctl -R "'mali-c55 resizer fr'[0/0->1/0[0],2/0->1/0[1]]" + media-ctl -V "'mali-c55 isp':0[fmt:RGB202020_1X60/1920x1080]" + media-ctl -V "'mali-c55 resizer fr':2[fmt:RGB202020_1X60/1920x1080]" + media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB202020_1X60/1920x1080]" + + # Set format on the video device and stream + yavta -f RGB565 -s 1920x1080 -c10 /dev/video0 + +.. _mali-c55-3a-stats: + +Capturing ISP Statistics +======================== + +The ISP is capable of producing statistics for consumption by image processing +algorithms running in userspace. These statistics can be captured by queueing +buffers to the `mali-c55 3a stats` V4L2 Device whilst the ISP is streaming. Only +the :ref:`V4L2_META_FMT_MALI_C55_STATS ` +format is supported, so no format-setting need be done: + +.. code-block:: none + + # We assume the media graph has been configured to support RGB565 capture + # from the mali-c55 fr V4L2 Device, which is at /dev/video0. The statistics + # V4L2 device is at /dev/video3 + + yavta -f RGB565 -s 1920x1080 -c32 /dev/video0 && \ + yavta -c10 -F /dev/video3 + +The layout of the buffer is described by :c:type:`mali_c55_stats_buffer`, +but broadly statistics are generated to support three image processing +algorithms; AEXP (Auto-Exposure), AWB (Auto-White Balance) and AF (Auto-Focus). +These stats can be drawn from various places in the Mali C55 ISP pipeline, known +as "tap points". This high-level block diagram is intended to explain where in +the processing flow the statistics can be drawn from:: + + +--> AEXP-2 +----> AEXP-1 +--> AF-0 + | +----> AF-1 | + | | | + +---------+ | +--------------+ | +--------------+ | + | Input +-+-->+ Digital Gain +---+-->+ Black Level +---+---+ + +---------+ +--------------+ +--------------+ | + +-----------------------------------------------------------------+ + | + | +--------------+ +---------+ +----------------+ + +-->| Sinter Noise +-+ White +--+--->| Lens Shading +--+---------------+ + | Reduction | | Balance | | | | | | + +--------------+ +---------+ | +----------------+ | | + +---> AEXP-0 (A) +--> AEXP-0 (B) | + +--------------------------------------------------------------------------+ + | + | +----------------+ +--------------+ +----------------+ + +-->| Tone mapping +-+--->| Demosaicing +->+ Purple Fringe +-+-----------+ + | | | +--------------+ | Correction | | | + +----------------+ +-> AEXP-IRIDIX +----------------+ +---> AWB-0 | + +----------------------------------------------------------------------------+ + | +-------------+ +-------------+ + +------------------->| Colour +---+--->| Output | + | Correction | | | Pipelines | + +-------------+ | +-------------+ + +--> AWB-1 + +By default all statistics are drawn from the 0th tap point for each algorithm; +I.E. AEXP statistics from AEXP-0 (A), AWB statistics from AWB-0 and AF +statistics from AF-0. This is configurable for AEXP and AWB statsistics through +programming the ISP's parameters. + +.. _mali-c55-3a-params: + +Programming ISP Parameters +========================== + +The ISP can be programmed with various parameters from userspace to apply to the +hardware before and during video stream. This allows userspace to dynamically +change values such as black level, white balance and lens shading gains and so +on. + +The buffer format and how to populate it are described by the +:ref:`V4L2_META_FMT_MALI_C55_PARAMS ` format, +which should be set as the data format for the `mali-c55 3a params` video node. + +References +========== +.. [1] https://git.linuxtv.org/v4l-utils.git/ +.. [2] https://git.ideasonboard.org/yavta.git +.. [3] https://developer.arm.com/Processors/Mali-C55 diff --git a/Documentation/admin-guide/media/platform-cardlist.rst b/Documentation/admin-guide/media/platform-cardlist.rst index 1230ae4037ad5..63f4b19c3628f 100644 --- a/Documentation/admin-guide/media/platform-cardlist.rst +++ b/Documentation/admin-guide/media/platform-cardlist.rst @@ -18,8 +18,6 @@ am437x-vpfe TI AM437x VPFE aspeed-video Aspeed AST2400 and AST2500 atmel-isc ATMEL Image Sensor Controller (ISC) atmel-isi ATMEL Image Sensor Interface (ISI) -c8sectpfe SDR platform devices -c8sectpfe SDR platform devices cafe_ccic Marvell 88ALP01 (Cafe) CMOS Camera Controller cdns-csi2rx Cadence MIPI-CSI2 RX Controller cdns-csi2tx Cadence MIPI-CSI2 TX Controller diff --git a/Documentation/admin-guide/media/radio-cardlist.rst b/Documentation/admin-guide/media/radio-cardlist.rst index a82a146bf9126..cec724256812e 100644 --- a/Documentation/admin-guide/media/radio-cardlist.rst +++ b/Documentation/admin-guide/media/radio-cardlist.rst @@ -30,7 +30,6 @@ radio-terratec TerraTec ActiveRadio ISA Standalone radio-timb Enable the Timberdale radio driver radio-trust Trust FM radio card radio-typhoon Typhoon Radio (a.k.a. EcoRadio) -radio-wl1273 Texas Instruments WL1273 I2C FM Radio fm_drv ISA radio devices fm_drv ISA radio devices radio-zoltrix Zoltrix Radio diff --git a/Documentation/admin-guide/media/rkcif-rk3568-vicap.dot b/Documentation/admin-guide/media/rkcif-rk3568-vicap.dot new file mode 100644 index 0000000000000..3fac59335459f --- /dev/null +++ b/Documentation/admin-guide/media/rkcif-rk3568-vicap.dot @@ -0,0 +1,8 @@ +digraph board { + rankdir=TB + n00000001 [label="{{ 0} | rkcif-dvp0\n/dev/v4l-subdev0 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000001:port1 -> n00000004 + n00000004 [label="rkcif-dvp0-id0\n/dev/video0", shape=box, style=filled, fillcolor=yellow] + n00000025 [label="{{} | it6801 2-0048\n/dev/v4l-subdev1 | { 0}}", shape=Mrecord, style=filled, fillcolor=green] + n00000025:port0 -> n00000001:port0 +} diff --git a/Documentation/admin-guide/media/rkcif.rst b/Documentation/admin-guide/media/rkcif.rst new file mode 100644 index 0000000000000..2558c121abc46 --- /dev/null +++ b/Documentation/admin-guide/media/rkcif.rst @@ -0,0 +1,79 @@ +.. SPDX-License-Identifier: GPL-2.0 + +========================================= +Rockchip Camera Interface (CIF) +========================================= + +Introduction +============ + +The Rockchip Camera Interface (CIF) is featured in many Rockchip SoCs in +different variants. +The different variants are combinations of common building blocks, such as + +* INTERFACE blocks of different types, namely + + * the Digital Video Port (DVP, a parallel data interface) + * the interface block for the MIPI CSI-2 receiver + +* CROP units + +* MIPI CSI-2 receiver (not available on all variants): This unit is referred + to as MIPI CSI HOST in the Rockchip documentation. + Technically, it is a separate hardware block, but it is strongly coupled to + the CIF and therefore included here. + +* MUX units (not available on all variants) that pass the video data to an + image signal processor (ISP) + +* SCALE units (not available on all variants) + +* DMA engines that transfer video data into system memory using a + double-buffering mechanism called ping-pong mode + +* Support for four streams per INTERFACE block (not available on all + variants), e.g., for MIPI CSI-2 Virtual Channels (VCs) + +This document describes the different variants of the CIF, their hardware +layout, as well as their representation in the media controller centric rkcif +device driver, which is located under drivers/media/platform/rockchip/rkcif. + +Variants +======== + +Rockchip PX30 Video Input Processor (VIP) +----------------------------------------- + +The PX30 Video Input Processor (VIP) features a digital video port that accepts +parallel video data or BT.656. +Since these protocols do not feature multiple streams, the VIP has one DMA +engine that transfers the input video data into system memory. + +The rkcif driver represents this hardware variant by exposing one V4L2 subdevice +(the DVP INTERFACE/CROP block) and one V4L2 device (the DVP DMA engine). + +Rockchip RK3568 Video Capture (VICAP) +------------------------------------- + +The RK3568 Video Capture (VICAP) unit features a digital video port and a MIPI +CSI-2 receiver that can receive video data independently. +The DVP accepts parallel video data, BT.656 and BT.1120. +Since the BT.1120 protocol may feature more than one stream, the RK3568 VICAP +DVP features four DMA engines that can capture different streams. +Similarly, the RK3568 VICAP MIPI CSI-2 receiver features four DMA engines to +handle different Virtual Channels (VCs). + +The rkcif driver represents this hardware variant by exposing up the following +V4L2 subdevices: + +* rkcif-dvp0: INTERFACE/CROP block for the DVP + +and the following video devices: + +* rkcif-dvp0-id0: The support for multiple streams on the DVP is not yet + implemented, as it is hard to find test hardware. Thus, this video device + represents the first DMA engine of the RK3568 DVP. + +.. kernel-figure:: rkcif-rk3568-vicap.dot + :alt: Topology of the RK3568 Video Capture (VICAP) unit + :align: center diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentation/admin-guide/media/v4l-drivers.rst index 3bac5165b1341..393f83e8dc4dd 100644 --- a/Documentation/admin-guide/media/v4l-drivers.rst +++ b/Documentation/admin-guide/media/v4l-drivers.rst @@ -19,12 +19,14 @@ Video4Linux (V4L) driver-specific documentation ipu3 ipu6-isys ivtv + mali-c55 mgb4 omap3isp philips qcom_camss raspberrypi-pisp-be rcar-fdp1 + rkcif rkisp1 raspberrypi-rp1-cfe saa7134 diff --git a/Documentation/admin-guide/mm/damon/lru_sort.rst b/Documentation/admin-guide/mm/damon/lru_sort.rst index 7b0775d281b48..72a9432026768 100644 --- a/Documentation/admin-guide/mm/damon/lru_sort.rst +++ b/Documentation/admin-guide/mm/damon/lru_sort.rst @@ -211,6 +211,28 @@ End of target memory region in physical address. The end physical address of memory region that DAMON_LRU_SORT will do work against. By default, biggest System RAM is used as the region. +addr_unit +--------- + +A scale factor for memory addresses and bytes. + +This parameter is for setting and getting the :ref:`address unit +` parameter of the DAMON instance for DAMON_RECLAIM. + +``monitor_region_start`` and ``monitor_region_end`` should be provided in this +unit. For example, let's suppose ``addr_unit``, ``monitor_region_start`` and +``monitor_region_end`` are set as ``1024``, ``0`` and ``10``, respectively. +Then DAMON_LRU_SORT will work for 10 KiB length of physical address range that +starts from address zero (``[0 * 1024, 10 * 1024)`` in bytes). + +Stat parameters having ``bytes_`` prefix are also in this unit. For example, +let's suppose values of ``addr_unit``, ``bytes_lru_sort_tried_hot_regions`` and +``bytes_lru_sorted_hot_regions`` are ``1024``, ``42``, and ``32``, +respectively. Then it means DAMON_LRU_SORT tried to LRU-sort 42 KiB of hot +memory and successfully LRU-sorted 32 KiB of the memory in total. + +If unsure, use only the default value (``1``) and forget about this. + kdamond_pid ----------- diff --git a/Documentation/admin-guide/mm/damon/reclaim.rst b/Documentation/admin-guide/mm/damon/reclaim.rst index af05ae6170184..8eba3da8dcee0 100644 --- a/Documentation/admin-guide/mm/damon/reclaim.rst +++ b/Documentation/admin-guide/mm/damon/reclaim.rst @@ -232,6 +232,28 @@ The end physical address of memory region that DAMON_RECLAIM will do work against. That is, DAMON_RECLAIM will find cold memory regions in this region and reclaims. By default, biggest System RAM is used as the region. +addr_unit +--------- + +A scale factor for memory addresses and bytes. + +This parameter is for setting and getting the :ref:`address unit +` parameter of the DAMON instance for DAMON_RECLAIM. + +``monitor_region_start`` and ``monitor_region_end`` should be provided in this +unit. For example, let's suppose ``addr_unit``, ``monitor_region_start`` and +``monitor_region_end`` are set as ``1024``, ``0`` and ``10``, respectively. +Then DAMON_RECLAIM will work for 10 KiB length of physical address range that +starts from address zero (``[0 * 1024, 10 * 1024)`` in bytes). + +``bytes_reclaim_tried_regions`` and ``bytes_reclaimed_regions`` are also in +this unit. For example, let's suppose values of ``addr_unit``, +``bytes_reclaim_tried_regions`` and ``bytes_reclaimed_regions`` are ``1024``, +``42``, and ``32``, respectively. Then it means DAMON_RECLAIM tried to reclaim +42 KiB memory and successfully reclaimed 32 KiB memory in total. + +If unsure, use only the default value (``1``) and forget about this. + skip_anon --------- diff --git a/Documentation/admin-guide/mm/damon/stat.rst b/Documentation/admin-guide/mm/damon/stat.rst index 4c517c2c219aa..e5a5a2c4f803a 100644 --- a/Documentation/admin-guide/mm/damon/stat.rst +++ b/Documentation/admin-guide/mm/damon/stat.rst @@ -10,6 +10,8 @@ on the system's entire physical memory using DAMON, and provides simplified access monitoring results statistics, namely idle time percentiles and estimated memory bandwidth. +.. _damon_stat_monitoring_accuracy_overhead: + Monitoring Accuracy and Overhead ================================ @@ -17,9 +19,11 @@ DAMON_STAT uses monitoring intervals :ref:`auto-tuning ` to make its accuracy high and overhead minimum. It auto-tunes the intervals aiming 4 % of observable access events to be captured in each snapshot, while limiting the resulting sampling -events to be 5 milliseconds in minimum and 10 seconds in maximum. On a few +interval to be 5 milliseconds in minimum and 10 seconds in maximum. On a few production server systems, it resulted in consuming only 0.x % single CPU time, -while capturing reasonable quality of access patterns. +while capturing reasonable quality of access patterns. The tuning-resulting +intervals can be retrieved via ``aggr_interval_us`` :ref:`parameter +`. Interface: Module Parameters ============================ @@ -41,6 +45,18 @@ You can enable DAMON_STAT by setting the value of this parameter as ``Y``. Setting it as ``N`` disables DAMON_STAT. The default value is set by ``CONFIG_DAMON_STAT_ENABLED_DEFAULT`` build config option. +.. _damon_stat_aggr_interval_us: + +aggr_interval_us +---------------- + +Auto-tuned aggregation time interval in microseconds. + +Users can read the aggregation interval of DAMON that is being used by the +DAMON instance for DAMON_STAT. It is :ref:`auto-tuned +` and therefore the value is +dynamically changed. + estimated_memory_bandwidth -------------------------- @@ -58,12 +74,13 @@ memory_idle_ms_percentiles Per-byte idle time (milliseconds) percentiles of the system. DAMON_STAT calculates how long each byte of the memory was not accessed until -now (idle time), based on the current DAMON results snapshot. If DAMON found a -region of access frequency (nr_accesses) larger than zero, every byte of the -region gets zero idle time. If a region has zero access frequency -(nr_accesses), how long the region was keeping the zero access frequency (age) -becomes the idle time of every byte of the region. Then, DAMON_STAT exposes -the percentiles of the idle time values via this read-only parameter. Reading -the parameter returns 101 idle time values in milliseconds, separated by comma. +now (idle time), based on the current DAMON results snapshot. For regions +having access frequency (nr_accesses) larger than zero, how long the current +access frequency level was kept multiplied by ``-1`` becomes the idlee time of +every byte of the region. If a region has zero access frequency (nr_accesses), +how long the region was keeping the zero access frequency (age) becomes the +idle time of every byte of the region. Then, DAMON_STAT exposes the +percentiles of the idle time values via this read-only parameter. Reading the +parameter returns 101 idle time values in milliseconds, separated by comma. Each value represents 0-th, 1st, 2nd, 3rd, ..., 99th and 100th percentile idle times. diff --git a/Documentation/admin-guide/mm/damon/usage.rst b/Documentation/admin-guide/mm/damon/usage.rst index eae534bc1bee4..9991dad60fcff 100644 --- a/Documentation/admin-guide/mm/damon/usage.rst +++ b/Documentation/admin-guide/mm/damon/usage.rst @@ -67,7 +67,7 @@ comma (","). │ │ │ │ │ │ │ intervals_goal/access_bp,aggrs,min_sample_us,max_sample_us │ │ │ │ │ │ nr_regions/min,max │ │ │ │ │ :ref:`targets `/nr_targets - │ │ │ │ │ │ :ref:`0 `/pid_target + │ │ │ │ │ │ :ref:`0 `/pid_target,obsolete_target │ │ │ │ │ │ │ :ref:`regions `/nr_regions │ │ │ │ │ │ │ │ :ref:`0 `/start,end │ │ │ │ │ │ │ │ ... @@ -81,7 +81,7 @@ comma (","). │ │ │ │ │ │ │ :ref:`quotas `/ms,bytes,reset_interval_ms,effective_bytes │ │ │ │ │ │ │ │ weights/sz_permil,nr_accesses_permil,age_permil │ │ │ │ │ │ │ │ :ref:`goals `/nr_goals - │ │ │ │ │ │ │ │ │ 0/target_metric,target_value,current_value,nid + │ │ │ │ │ │ │ │ │ 0/target_metric,target_value,current_value,nid,path │ │ │ │ │ │ │ :ref:`watermarks `/metric,interval_us,high,mid,low │ │ │ │ │ │ │ :ref:`{core_,ops_,}filters `/nr_filters │ │ │ │ │ │ │ │ 0/type,matching,allow,memcg_path,addr_start,addr_end,target_idx,min,max @@ -134,7 +134,8 @@ Users can write below commands for the kdamond to the ``state`` file. - ``on``: Start running. - ``off``: Stop running. - ``commit``: Read the user inputs in the sysfs files except ``state`` file - again. + again. Monitoring :ref:`target region ` inputs are also be + ignored if no target region is specified. - ``update_tuned_intervals``: Update the contents of ``sample_us`` and ``aggr_us`` files of the kdamond with the auto-tuning applied ``sampling interval`` and ``aggregation interval`` for the files. Please refer to @@ -264,13 +265,20 @@ to ``N-1``. Each directory represents each monitoring target. targets// ------------ -In each target directory, one file (``pid_target``) and one directory -(``regions``) exist. +In each target directory, two files (``pid_target`` and ``obsolete_target``) +and one directory (``regions``) exist. If you wrote ``vaddr`` to the ``contexts//operations``, each target should be a process. You can specify the process to DAMON by writing the pid of the process to the ``pid_target`` file. +Users can selectively remove targets in the middle of the targets array by +writing non-zero value to ``obsolete_target`` file and committing it (writing +``commit`` to ``state`` file). DAMON will remove the matching targets from its +internal targets array. Users are responsible to construct target directories +again, so that those correctly represent the changed internal targets array. + + .. _sysfs_regions: targets//regions @@ -289,6 +297,11 @@ In the beginning, this directory has only one file, ``nr_regions``. Writing a number (``N``) to the file creates the number of child directories named ``0`` to ``N-1``. Each directory represents each initial monitoring target region. +If ``nr_regions`` is zero when committing new DAMON parameters online (writing +``commit`` to ``state`` file of :ref:`kdamond `), the commit +logic ignores the target regions. In other words, the current monitoring +results for the target are preserved. + .. _sysfs_region: regions// @@ -402,9 +415,9 @@ number (``N``) to the file creates the number of child directories named ``0`` to ``N-1``. Each directory represents each goal and current achievement. Among the multiple feedback, the best one is used. -Each goal directory contains four files, namely ``target_metric``, -``target_value``, ``current_value`` and ``nid``. Users can set and get the -four parameters for the quota auto-tuning goals that specified on the +Each goal directory contains five files, namely ``target_metric``, +``target_value``, ``current_value`` ``nid`` and ``path``. Users can set and +get the five parameters for the quota auto-tuning goals that specified on the :ref:`design doc ` by writing to and reading from each of the files. Note that users should further write ``commit_schemes_quota_goals`` to the ``state`` file of the :ref:`kdamond diff --git a/Documentation/admin-guide/mm/index.rst b/Documentation/admin-guide/mm/index.rst index ebc83ca20fdcd..bbb563cba5d29 100644 --- a/Documentation/admin-guide/mm/index.rst +++ b/Documentation/admin-guide/mm/index.rst @@ -39,7 +39,6 @@ the Linux memory management. shrinker_debugfs slab soft-dirty - swap_numa transhuge userfaultfd zswap diff --git a/Documentation/admin-guide/mm/pagemap.rst b/Documentation/admin-guide/mm/pagemap.rst index e60e9211fd9b2..c57e61b5d8aa8 100644 --- a/Documentation/admin-guide/mm/pagemap.rst +++ b/Documentation/admin-guide/mm/pagemap.rst @@ -115,7 +115,8 @@ Short descriptions to the page flags A free memory block managed by the buddy system allocator. The buddy system organizes free memory in blocks of various orders. An order N block has 2^N physically contiguous pages, with the BUDDY flag - set for and _only_ for the first page. + set for all pages. + Before 4.6 only the first page of the block had the flag set. 15 - COMPOUND_HEAD A compound page with order N consists of 2^N physically contiguous pages. A compound page with order 2 takes the form of "HTTT", where H donates its diff --git a/Documentation/admin-guide/mm/swap_numa.rst b/Documentation/admin-guide/mm/swap_numa.rst deleted file mode 100644 index 2e630627bceec..0000000000000 --- a/Documentation/admin-guide/mm/swap_numa.rst +++ /dev/null @@ -1,78 +0,0 @@ -=========================================== -Automatically bind swap device to numa node -=========================================== - -If the system has more than one swap device and swap device has the node -information, we can make use of this information to decide which swap -device to use in get_swap_pages() to get better performance. - - -How to use this feature -======================= - -Swap device has priority and that decides the order of it to be used. To make -use of automatically binding, there is no need to manipulate priority settings -for swap devices. e.g. on a 2 node machine, assume 2 swap devices swapA and -swapB, with swapA attached to node 0 and swapB attached to node 1, are going -to be swapped on. Simply swapping them on by doing:: - - # swapon /dev/swapA - # swapon /dev/swapB - -Then node 0 will use the two swap devices in the order of swapA then swapB and -node 1 will use the two swap devices in the order of swapB then swapA. Note -that the order of them being swapped on doesn't matter. - -A more complex example on a 4 node machine. Assume 6 swap devices are going to -be swapped on: swapA and swapB are attached to node 0, swapC is attached to -node 1, swapD and swapE are attached to node 2 and swapF is attached to node3. -The way to swap them on is the same as above:: - - # swapon /dev/swapA - # swapon /dev/swapB - # swapon /dev/swapC - # swapon /dev/swapD - # swapon /dev/swapE - # swapon /dev/swapF - -Then node 0 will use them in the order of:: - - swapA/swapB -> swapC -> swapD -> swapE -> swapF - -swapA and swapB will be used in a round robin mode before any other swap device. - -node 1 will use them in the order of:: - - swapC -> swapA -> swapB -> swapD -> swapE -> swapF - -node 2 will use them in the order of:: - - swapD/swapE -> swapA -> swapB -> swapC -> swapF - -Similaly, swapD and swapE will be used in a round robin mode before any -other swap devices. - -node 3 will use them in the order of:: - - swapF -> swapA -> swapB -> swapC -> swapD -> swapE - - -Implementation details -====================== - -The current code uses a priority based list, swap_avail_list, to decide -which swap device to use and if multiple swap devices share the same -priority, they are used round robin. This change here replaces the single -global swap_avail_list with a per-numa-node list, i.e. for each numa node, -it sees its own priority based list of available swap devices. Swap -device's priority can be promoted on its matching node's swap_avail_list. - -The current swap device's priority is set as: user can set a >=0 value, -or the system will pick one starting from -1 then downwards. The priority -value in the swap_avail_list is the negated value of the swap device's -due to plist being sorted from low to high. The new policy doesn't change -the semantics for priority >=0 cases, the previous starting from -1 then -downwards now becomes starting from -2 then downwards and -1 is reserved -as the promoted value. So if multiple swap devices are attached to the same -node, they will all be promoted to priority -1 on that node's plist and will -be used round robin before any other swap devices. diff --git a/Documentation/admin-guide/mm/transhuge.rst b/Documentation/admin-guide/mm/transhuge.rst index 1654211cc6cf2..5fbc3d89bb073 100644 --- a/Documentation/admin-guide/mm/transhuge.rst +++ b/Documentation/admin-guide/mm/transhuge.rst @@ -381,6 +381,11 @@ hugepage allocation policy for the tmpfs mount by using the kernel parameter four valid policies for tmpfs (``always``, ``within_size``, ``advise``, ``never``). The tmpfs mount default policy is ``never``. +Additionally, Kconfig options are available to set the default hugepage +policies for shmem (``CONFIG_TRANSPARENT_HUGEPAGE_SHMEM_HUGE_*``) and tmpfs +(``CONFIG_TRANSPARENT_HUGEPAGE_TMPFS_HUGE_*``) at build time. Refer to the +Kconfig help for more details. + In the same manner as ``thp_anon`` controls each supported anonymous THP size, ``thp_shmem`` controls each supported shmem THP size. ``thp_shmem`` has the same format as ``thp_anon``, but also supports the policy diff --git a/Documentation/admin-guide/mm/zswap.rst b/Documentation/admin-guide/mm/zswap.rst index 283d77217c6fd..2464425c783de 100644 --- a/Documentation/admin-guide/mm/zswap.rst +++ b/Documentation/admin-guide/mm/zswap.rst @@ -59,11 +59,11 @@ returned by the allocation routine and that handle must be mapped before being accessed. The compressed memory pool grows on demand and shrinks as compressed pages are freed. The pool is not preallocated. -When a swap page is passed from swapout to zswap, zswap maintains a mapping -of the swap entry, a combination of the swap type and swap offset, to the -zsmalloc handle that references that compressed swap page. This mapping is -achieved with a red-black tree per swap type. The swap offset is the search -key for the tree nodes. +When a swap page is passed from swapout to zswap, zswap maintains a mapping of +the swap entry, a combination of the swap type and swap offset, to the zsmalloc +handle that references that compressed swap page. This mapping is achieved +with an xarray per swap type. The swap offset is the search key for the xarray +nodes. During a page fault on a PTE that is a swap entry, the swapin code calls the zswap load function to decompress the page into the page allocated by the page diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst index f3ee807b5d8b3..239da22c4e28f 100644 --- a/Documentation/admin-guide/sysctl/kernel.rst +++ b/Documentation/admin-guide/sysctl/kernel.rst @@ -397,13 +397,14 @@ a hung task is detected. hung_task_panic =============== -Controls the kernel's behavior when a hung task is detected. +When set to a non-zero value, a kernel panic will be triggered if the +number of hung tasks found during a single scan reaches this value. This file shows up if ``CONFIG_DETECT_HUNG_TASK`` is enabled. -= ================================================= += ======================================================= 0 Continue operation. This is the default behavior. -1 Panic immediately. -= ================================================= +N Panic when N hung tasks are found during a single scan. += ======================================================= hung_task_check_count @@ -421,6 +422,11 @@ the system boot. This file shows up if ``CONFIG_DETECT_HUNG_TASK`` is enabled. +hung_task_sys_info +================== +A comma separated list of extra system information to be dumped when +hung task is detected, for example, "tasks,mem,timers,locks,...". +Refer 'panic_sys_info' section below for more details. hung_task_timeout_secs ====================== @@ -515,6 +521,15 @@ default), only processes with the CAP_SYS_ADMIN capability may create io_uring instances. +kernel_sys_info +=============== +A comma separated list of extra system information to be dumped when +soft/hard lockup is detected, for example, "tasks,mem,timers,locks,...". +Refer 'panic_sys_info' section below for more details. + +It serves as the default kernel control knob, which will take effect +when a kernel module calls sys_info() with parameter==0. + kexec_load_disabled =================== @@ -576,6 +591,11 @@ if leaking kernel pointer values to unprivileged users is a concern. When ``kptr_restrict`` is set to 2, kernel pointers printed using %pK will be replaced with 0s regardless of privileges. +softlockup_sys_info & hardlockup_sys_info +========================================= +A comma separated list of extra system information to be dumped when +soft/hard lockup is detected, for example, "tasks,mem,timers,locks,...". +Refer 'panic_sys_info' section below for more details. modprobe ======== @@ -910,8 +930,8 @@ to 'panic_print'. Possible values are: ============= =================================================== tasks print all tasks info mem print system memory info -timer print timers info -lock print locks info if CONFIG_LOCKDEP is on +timers print timers info +locks print locks info if CONFIG_LOCKDEP is on ftrace print ftrace buffer all_bt print all CPUs backtrace (if available in the arch) blocked_tasks print only tasks in uninterruptible (blocked) state diff --git a/Documentation/admin-guide/thunderbolt.rst b/Documentation/admin-guide/thunderbolt.rst index 102c693c8f816..07303c1346fbd 100644 --- a/Documentation/admin-guide/thunderbolt.rst +++ b/Documentation/admin-guide/thunderbolt.rst @@ -203,10 +203,10 @@ host controller or a device, it is important that the firmware can be upgraded to the latest where possible bugs in it have been fixed. Typically OEMs provide this firmware from their support site. -There is also a central site which has links where to download firmware -for some machines: - - `Thunderbolt Updates `_ +Currently, recommended method of updating firmware is through "fwupd" tool. +It uses LVFS (Linux Vendor Firmware Service) portal by default to get the +latest firmware from hardware vendors and updates connected devices if found +compatible. For details refer to: https://github.com/fwupd/fwupd. Before you upgrade firmware on a device, host or retimer, please make sure it is a suitable upgrade. Failing to do that may render the device @@ -215,18 +215,40 @@ tools! Host NVM upgrade on Apple Macs is not supported. -Once the NVM image has been downloaded, you need to plug in a -Thunderbolt device so that the host controller appears. It does not -matter which device is connected (unless you are upgrading NVM on a -device - then you need to connect that particular device). +Fwupd is installed by default. If you don't have it on your system, simply +use your distro package manager to get it. + +To see possible updates through fwupd, you need to plug in a Thunderbolt +device so that the host controller appears. It does not matter which +device is connected (unless you are upgrading NVM on a device - then you +need to connect that particular device). Note an OEM-specific method to power the controller up ("force power") may be available for your system in which case there is no need to plug in a Thunderbolt device. -After that we can write the firmware to the non-active parts of the NVM -of the host or device. As an example here is how Intel NUC6i7KYK (Skull -Canyon) Thunderbolt controller NVM is upgraded:: +Updating firmware using fwupd is straightforward - refer to official +readme on fwupd github. + +If firmware image is written successfully, the device shortly disappears. +Once it comes back, the driver notices it and initiates a full power +cycle. After a while device appears again and this time it should be +fully functional. + +Device of interest should display new version under "Current version" +and "Update State: Success" in fwupd's interface. + +Upgrading firmware manually +--------------------------------------------------------------- +If possible, use fwupd to updated the firmware. However, if your device OEM +has not uploaded the firmware to LVFS, but it is available for download +from their side, you can use method below to directly upgrade the +firmware. + +Manual firmware update can be done with 'dd' tool. To update firmware +using this method, you need to write it to the non-active parts of NVM +of the host or device. Example on how to update Intel NUC6i7KYK +(Skull Canyon) Thunderbolt controller NVM:: # dd if=KYK_TBT_FW_0018.bin of=/sys/bus/thunderbolt/devices/0-0/nvm_non_active0/nvmem @@ -235,10 +257,8 @@ upgrade process as follows:: # echo 1 > /sys/bus/thunderbolt/devices/0-0/nvm_authenticate -If no errors are returned, the host controller shortly disappears. Once -it comes back the driver notices it and initiates a full power cycle. -After a while the host controller appears again and this time it should -be fully functional. +If no errors are returned, device should behave as described in previous +section. We can verify that the new NVM firmware is active by running the following commands:: diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst index 2f449c9b15bdd..641ec4abb9062 100644 --- a/Documentation/arch/riscv/hwprobe.rst +++ b/Documentation/arch/riscv/hwprobe.rst @@ -249,6 +249,9 @@ The following keys are defined: defined in the in the RISC-V ISA manual starting from commit e87412e621f1 ("integrate Zaamo and Zalrsc text (#1304)"). + * :c:macro:`RISCV_HWPROBE_EXT_ZALASR`: The Zalasr extension is supported as + frozen at commit 194f0094 ("Version 0.9 for freeze") of riscv-zalasr. + * :c:macro:`RISCV_HWPROBE_EXT_ZALRSC`: The Zalrsc extension is supported as defined in the in the RISC-V ISA manual starting from commit e87412e621f1 ("integrate Zaamo and Zalrsc text (#1304)"). @@ -275,6 +278,17 @@ The following keys are defined: ratified in commit 49f49c842ff9 ("Update to Rafified state") of riscv-zabha. + * :c:macro:`RISCV_HWPROBE_EXT_ZICBOP`: The Zicbop extension is supported, as + ratified in commit 3dd606f ("Create cmobase-v1.0.pdf") of riscv-CMOs. + + * :c:macro:`RISCV_HWPROBE_EXT_ZILSD`: The Zilsd extension is supported as + defined in the RISC-V ISA manual starting from commit f88abf1 ("Integrating + load/store pair for RV32 with the main manual") of the riscv-isa-manual. + + * :c:macro:`RISCV_HWPROBE_EXT_ZCLSD`: The Zclsd extension is supported as + defined in the RISC-V ISA manual starting from commit f88abf1 ("Integrating + load/store pair for RV32 with the main manual") of the riscv-isa-manual. + * :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: Deprecated. Returns similar values to :c:macro:`RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF`, but the key was mistakenly classified as a bitmask rather than a value. @@ -369,4 +383,7 @@ The following keys are defined: * :c:macro:`RISCV_HWPROBE_VENDOR_EXT_XSFVFWMACCQQQ`: The Xsfvfwmaccqqq vendor extension is supported in version 1.0 of Matrix Multiply Accumulate - Instruction Extensions Specification. \ No newline at end of file + Instruction Extensions Specification. + +* :c:macro:`RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE`: An unsigned int which + represents the size of the Zicbop block in bytes. diff --git a/Documentation/arch/x86/boot.rst b/Documentation/arch/x86/boot.rst index 32eea3d2807e1..dca3875a24351 100644 --- a/Documentation/arch/x86/boot.rst +++ b/Documentation/arch/x86/boot.rst @@ -95,26 +95,26 @@ Memory Layout The traditional memory map for the kernel loader, used for Image or zImage kernels, typically looks like:: - | | + | | 0A0000 +------------------------+ - | Reserved for BIOS | Do not use. Reserved for BIOS EBDA. + | Reserved for BIOS | Do not use. Reserved for BIOS EBDA. 09A000 +------------------------+ - | Command line | - | Stack/heap | For use by the kernel real-mode code. + | Command line | + | Stack/heap | For use by the kernel real-mode code. 098000 +------------------------+ - | Kernel setup | The kernel real-mode code. + | Kernel setup | The kernel real-mode code. 090200 +------------------------+ - | Kernel boot sector | The kernel legacy boot sector. + | Kernel boot sector | The kernel legacy boot sector. 090000 +------------------------+ - | Protected-mode kernel | The bulk of the kernel image. + | Protected-mode kernel | The bulk of the kernel image. 010000 +------------------------+ - | Boot loader | <- Boot sector entry point 0000:7C00 + | Boot loader | <- Boot sector entry point 0000:7C00 001000 +------------------------+ - | Reserved for MBR/BIOS | + | Reserved for MBR/BIOS | 000800 +------------------------+ - | Typically used by MBR | + | Typically used by MBR | 000600 +------------------------+ - | BIOS use only | + | BIOS use only | 000000 +------------------------+ When using bzImage, the protected-mode kernel was relocated to @@ -142,27 +142,27 @@ above the 0x9A000 point; too many BIOSes will break above that point. For a modern bzImage kernel with boot protocol version >= 2.02, a memory layout like the following is suggested:: - ~ ~ - | Protected-mode kernel | + ~ ~ + | Protected-mode kernel | 100000 +------------------------+ - | I/O memory hole | + | I/O memory hole | 0A0000 +------------------------+ - | Reserved for BIOS | Leave as much as possible unused - ~ ~ - | Command line | (Can also be below the X+10000 mark) + | Reserved for BIOS | Leave as much as possible unused + ~ ~ + | Command line | (Can also be below the X+10000 mark) X+10000 +------------------------+ - | Stack/heap | For use by the kernel real-mode code. + | Stack/heap | For use by the kernel real-mode code. X+08000 +------------------------+ - | Kernel setup | The kernel real-mode code. - | Kernel boot sector | The kernel legacy boot sector. + | Kernel setup | The kernel real-mode code. + | Kernel boot sector | The kernel legacy boot sector. X +------------------------+ - | Boot loader | <- Boot sector entry point 0000:7C00 + | Boot loader | <- Boot sector entry point 0000:7C00 001000 +------------------------+ - | Reserved for MBR/BIOS | + | Reserved for MBR/BIOS | 000800 +------------------------+ - | Typically used by MBR | + | Typically used by MBR | 000600 +------------------------+ - | BIOS use only | + | BIOS use only | 000000 +------------------------+ ... where the address X is as low as the design of the boot loader permits. @@ -416,7 +416,7 @@ Offset/size: 0x210/1 Protocol: 2.00+ ============ ================== - If your boot loader has an assigned id (see table below), enter + If your boot loader has an assigned ID (see table below), enter 0xTV here, where T is an identifier for the boot loader and V is a version number. Otherwise, enter 0xFF here. @@ -431,32 +431,32 @@ Protocol: 2.00+ ext_loader_type <- 0x05 ext_loader_ver <- 0x23 - Assigned boot loader ids (hexadecimal): - - == ======================================= - 0 LILO - (0x00 reserved for pre-2.00 bootloader) - 1 Loadlin - 2 bootsect-loader - (0x20, all other values reserved) - 3 Syslinux - 4 Etherboot/gPXE/iPXE - 5 ELILO - 7 GRUB - 8 U-Boot - 9 Xen - A Gujin - B Qemu - C Arcturus Networks uCbootloader - D kexec-tools - E Extended (see ext_loader_type) - F Special (0xFF = undefined) - 10 Reserved - 11 Minimal Linux Bootloader - - 12 OVMF UEFI virtualization stack - 13 barebox - == ======================================= + Assigned boot loader IDs: + + ==== ======================================= + 0x0 LILO + (0x00 reserved for pre-2.00 bootloader) + 0x1 Loadlin + 0x2 bootsect-loader + (0x20, all other values reserved) + 0x3 Syslinux + 0x4 Etherboot/gPXE/iPXE + 0x5 ELILO + 0x7 GRUB + 0x8 U-Boot + 0x9 Xen + 0xA Gujin + 0xB Qemu + 0xC Arcturus Networks uCbootloader + 0xD kexec-tools + 0xE Extended (see ext_loader_type) + 0xF Special (0xFF = undefined) + 0x10 Reserved + 0x11 Minimal Linux Bootloader + + 0x12 OVMF UEFI virtualization stack + 0x13 barebox + ==== ======================================= Please contact if you need a bootloader ID value assigned. @@ -809,12 +809,12 @@ Protocol: 2.09+ as follow:: struct setup_data { - __u64 next; - __u32 type; - __u32 len; - __u8 data[]; + __u64 next; + __u32 type; + __u32 len; + __u8 data[]; } - + Where, the next is a 64-bit physical pointer to the next node of linked list, the next field of the last node is 0; the type is used to identify the contents of data; the len is the length of data @@ -835,10 +835,10 @@ Protocol: 2.09+ protocol 2.15:: struct setup_indirect { - __u32 type; - __u32 reserved; /* Reserved, must be set to zero. */ - __u64 len; - __u64 addr; + __u32 type; + __u32 reserved; /* Reserved, must be set to zero. */ + __u64 len; + __u64 addr; }; The type member is a SETUP_INDIRECT | SETUP_* type. However, it cannot be @@ -850,15 +850,15 @@ Protocol: 2.09+ In this case setup_data and setup_indirect will look like this:: struct setup_data { - .next = 0, /* or */ - .type = SETUP_INDIRECT, - .len = sizeof(setup_indirect), - .data[sizeof(setup_indirect)] = (struct setup_indirect) { - .type = SETUP_INDIRECT | SETUP_E820_EXT, - .reserved = 0, - .len = , - .addr = , - }, + .next = 0, /* or */ + .type = SETUP_INDIRECT, + .len = sizeof(setup_indirect), + .data[sizeof(setup_indirect)] = (struct setup_indirect) { + .type = SETUP_INDIRECT | SETUP_E820_EXT, + .reserved = 0, + .len = , + .addr = , + }, } .. note:: @@ -897,11 +897,11 @@ Offset/size: 0x260/4 The kernel runtime start address is determined by the following algorithm:: if (relocatable_kernel) { - if (load_address < pref_address) - load_address = pref_address; - runtime_start = align_up(load_address, kernel_alignment); + if (load_address < pref_address) + load_address = pref_address; + runtime_start = align_up(load_address, kernel_alignment); } else { - runtime_start = pref_address; + runtime_start = pref_address; } Hence the necessary memory window location and size can be estimated by @@ -975,22 +975,22 @@ after kernel_info_var_len_data label. Each chunk of variable size data has to be prefixed with header/magic and its size, e.g.:: kernel_info: - .ascii "LToP" /* Header, Linux top (structure). */ - .long kernel_info_var_len_data - kernel_info - .long kernel_info_end - kernel_info - .long 0x01234567 /* Some fixed size data for the bootloaders. */ + .ascii "LToP" /* Header, Linux top (structure). */ + .long kernel_info_var_len_data - kernel_info + .long kernel_info_end - kernel_info + .long 0x01234567 /* Some fixed size data for the bootloaders. */ kernel_info_var_len_data: example_struct: /* Some variable size data for the bootloaders. */ - .ascii "0123" /* Header/Magic. */ - .long example_struct_end - example_struct - .ascii "Struct" - .long 0x89012345 + .ascii "0123" /* Header/Magic. */ + .long example_struct_end - example_struct + .ascii "Struct" + .long 0x89012345 example_struct_end: example_strings: /* Some variable size data for the bootloaders. */ - .ascii "ABCD" /* Header/Magic. */ - .long example_strings_end - example_strings - .asciz "String_0" - .asciz "String_1" + .ascii "ABCD" /* Header/Magic. */ + .long example_strings_end - example_strings + .asciz "String_0" + .asciz "String_1" example_strings_end: kernel_info_end: @@ -1132,53 +1132,53 @@ Such a boot loader should enter the following fields in the header:: unsigned long base_ptr; /* base address for real-mode segment */ if (setup_sects == 0) - setup_sects = 4; + setup_sects = 4; if (protocol >= 0x0200) { - type_of_loader = ; - if (loading_initrd) { - ramdisk_image = ; - ramdisk_size = ; - } - - if (protocol >= 0x0202 && loadflags & 0x01) - heap_end = 0xe000; - else - heap_end = 0x9800; - - if (protocol >= 0x0201) { - heap_end_ptr = heap_end - 0x200; - loadflags |= 0x80; /* CAN_USE_HEAP */ - } - - if (protocol >= 0x0202) { - cmd_line_ptr = base_ptr + heap_end; - strcpy(cmd_line_ptr, cmdline); - } else { - cmd_line_magic = 0xA33F; - cmd_line_offset = heap_end; - setup_move_size = heap_end + strlen(cmdline) + 1; - strcpy(base_ptr + cmd_line_offset, cmdline); - } + type_of_loader = ; + if (loading_initrd) { + ramdisk_image = ; + ramdisk_size = ; + } + + if (protocol >= 0x0202 && loadflags & 0x01) + heap_end = 0xe000; + else + heap_end = 0x9800; + + if (protocol >= 0x0201) { + heap_end_ptr = heap_end - 0x200; + loadflags |= 0x80; /* CAN_USE_HEAP */ + } + + if (protocol >= 0x0202) { + cmd_line_ptr = base_ptr + heap_end; + strcpy(cmd_line_ptr, cmdline); + } else { + cmd_line_magic = 0xA33F; + cmd_line_offset = heap_end; + setup_move_size = heap_end + strlen(cmdline) + 1; + strcpy(base_ptr + cmd_line_offset, cmdline); + } } else { - /* Very old kernel */ + /* Very old kernel */ - heap_end = 0x9800; + heap_end = 0x9800; - cmd_line_magic = 0xA33F; - cmd_line_offset = heap_end; + cmd_line_magic = 0xA33F; + cmd_line_offset = heap_end; - /* A very old kernel MUST have its real-mode code loaded at 0x90000 */ - if (base_ptr != 0x90000) { - /* Copy the real-mode kernel */ - memcpy(0x90000, base_ptr, (setup_sects + 1) * 512); - base_ptr = 0x90000; /* Relocated */ - } + /* A very old kernel MUST have its real-mode code loaded at 0x90000 */ + if (base_ptr != 0x90000) { + /* Copy the real-mode kernel */ + memcpy(0x90000, base_ptr, (setup_sects + 1) * 512); + base_ptr = 0x90000; /* Relocated */ + } - strcpy(0x90000 + cmd_line_offset, cmdline); + strcpy(0x90000 + cmd_line_offset, cmdline); - /* It is recommended to clear memory up to the 32K mark */ - memset(0x90000 + (setup_sects + 1) * 512, 0, (64 - (setup_sects + 1)) * 512); + /* It is recommended to clear memory up to the 32K mark */ + memset(0x90000 + (setup_sects + 1) * 512, 0, (64 - (setup_sects + 1)) * 512); } diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index 6cbdcbfa79c30..5eb0fbbbc323c 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -138,6 +138,7 @@ Documents that don't fit elsewhere or which have yet to be categorized. :maxdepth: 1 librs + liveupdate netlink .. only:: subproject and html diff --git a/Documentation/core-api/kho/concepts.rst b/Documentation/core-api/kho/concepts.rst index 36d5c05cfb307..d626d1dbd6784 100644 --- a/Documentation/core-api/kho/concepts.rst +++ b/Documentation/core-api/kho/concepts.rst @@ -70,5 +70,5 @@ in the FDT. That state is called the KHO finalization phase. Public API ========== -.. kernel-doc:: kernel/kexec_handover.c +.. kernel-doc:: kernel/liveupdate/kexec_handover.c :export: diff --git a/Documentation/core-api/liveupdate.rst b/Documentation/core-api/liveupdate.rst new file mode 100644 index 0000000000000..7960eb15a81f3 --- /dev/null +++ b/Documentation/core-api/liveupdate.rst @@ -0,0 +1,61 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================== +Live Update Orchestrator +======================== +:Author: Pasha Tatashin + +.. kernel-doc:: kernel/liveupdate/luo_core.c + :doc: Live Update Orchestrator (LUO) + +LUO Sessions +============ +.. kernel-doc:: kernel/liveupdate/luo_session.c + :doc: LUO Sessions + +LUO Preserving File Descriptors +=============================== +.. kernel-doc:: kernel/liveupdate/luo_file.c + :doc: LUO File Descriptors + +Live Update Orchestrator ABI +============================ +.. kernel-doc:: include/linux/kho/abi/luo.h + :doc: Live Update Orchestrator ABI + +The following types of file descriptors can be preserved + +.. toctree:: + :maxdepth: 1 + + ../mm/memfd_preservation + +Public API +========== +.. kernel-doc:: include/linux/liveupdate.h + +.. kernel-doc:: include/linux/kho/abi/luo.h + :functions: + +.. kernel-doc:: kernel/liveupdate/luo_core.c + :export: + +.. kernel-doc:: kernel/liveupdate/luo_file.c + :export: + +Internal API +============ +.. kernel-doc:: kernel/liveupdate/luo_core.c + :internal: + +.. kernel-doc:: kernel/liveupdate/luo_session.c + :internal: + +.. kernel-doc:: kernel/liveupdate/luo_file.c + :internal: + +See Also +======== + +- :doc:`Live Update uAPI ` +- :doc:`/core-api/kho/concepts` diff --git a/Documentation/dev-tools/checkpatch.rst b/Documentation/dev-tools/checkpatch.rst index dfaad0a279ff1..deb3f67a633cf 100644 --- a/Documentation/dev-tools/checkpatch.rst +++ b/Documentation/dev-tools/checkpatch.rst @@ -1002,6 +1002,29 @@ Functions and Variables return bar; + **UNINITIALIZED_PTR_WITH_FREE** + Pointers with __free attribute should be declared at the place of use + and initialized (see include/linux/cleanup.h). In this case + declarations at the top of the function rule can be relaxed. Not doing + so may lead to undefined behavior as the memory assigned (garbage, + in case not initialized) to the pointer is freed automatically when + the pointer goes out of scope. + + Also see: https://lore.kernel.org/lkml/58fd478f408a34b578ee8d949c5c4b4da4d4f41d.camel@HansenPartnership.com/ + + Example:: + + type var __free(free_func); + ... // var not used, but, in future someone might add a return here + var = malloc(var_size); + ... + + should be initialized as:: + + ... + type var __free(free_func) = malloc(var_size); + ... + Permissions ----------- @@ -1238,6 +1261,16 @@ Others The patch file does not appear to be in unified-diff format. Please regenerate the patch file before sending it to the maintainer. + **PLACEHOLDER_USE** + Detects unhandled placeholder text left in cover letters or commit headers/logs. + Common placeholders include lines like:: + + *** SUBJECT HERE *** + *** BLURB HERE *** + + These typically come from autogenerated templates. Replace them with a proper + subject and description before sending. + **PRINTF_0XDECIMAL** Prefixing 0x with decimal output is defective and should be corrected. diff --git a/Documentation/devicetree/bindings/.yamllint b/Documentation/devicetree/bindings/.yamllint index 5327995018009..8f9dd18dfe046 100644 --- a/Documentation/devicetree/bindings/.yamllint +++ b/Documentation/devicetree/bindings/.yamllint @@ -30,7 +30,7 @@ rules: document-start: present: true empty-lines: - max: 3 + max: 1 max-end: 1 empty-values: forbid-in-block-mappings: true diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index 8390d6c00030a..8d6f85f4455da 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -32,7 +32,8 @@ find_cmd = $(find_all_cmd) | \ sed 's|^$(srctree)/||' | \ grep -F -e "$(subst :," -e ",$(DT_SCHEMA_FILES))" | \ sed 's|^|$(srctree)/|' -CHK_DT_EXAMPLES := $(patsubst $(srctree)/%.yaml,%.example.dtb, $(shell $(find_cmd))) +CHK_DT_EXAMPLES := $(patsubst $(srctree)/%.yaml,%.example.dtb, \ + $(shell $(find_cmd) | xargs grep -l '^examples:')) quiet_cmd_yamllint = LINT $(src) cmd_yamllint = ($(find_cmd) | \ diff --git a/Documentation/devicetree/bindings/arm/altera.yaml b/Documentation/devicetree/bindings/arm/altera.yaml index 30c44a0e64074..db61537b71157 100644 --- a/Documentation/devicetree/bindings/arm/altera.yaml +++ b/Documentation/devicetree/bindings/arm/altera.yaml @@ -31,7 +31,9 @@ properties: - description: Mercury+ AA1 boards items: - enum: - - enclustra,mercury-pe1 + - enclustra,mercury-aa1-pe1 + - enclustra,mercury-aa1-pe3 + - enclustra,mercury-aa1-st1 - google,chameleon-v3 - const: enclustra,mercury-aa1 - const: altr,socfpga-arria10 @@ -52,6 +54,26 @@ properties: - const: altr,socfpga-cyclone5 - const: altr,socfpga + - description: Mercury SA1 boards + items: + - enum: + - enclustra,mercury-sa1-pe1 + - enclustra,mercury-sa1-pe3 + - enclustra,mercury-sa1-st1 + - const: enclustra,mercury-sa1 + - const: altr,socfpga-cyclone5 + - const: altr,socfpga + + - description: Mercury+ SA2 boards + items: + - enum: + - enclustra,mercury-sa2-pe1 + - enclustra,mercury-sa2-pe3 + - enclustra,mercury-sa2-st1 + - const: enclustra,mercury-sa2 + - const: altr,socfpga-cyclone5 + - const: altr,socfpga + - description: Stratix 10 boards items: - enum: diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-clk-manager.yaml b/Documentation/devicetree/bindings/arm/altera/socfpga-clk-manager.yaml index a758f4bb2bb31..4683bd1293faf 100644 --- a/Documentation/devicetree/bindings/arm/altera/socfpga-clk-manager.yaml +++ b/Documentation/devicetree/bindings/arm/altera/socfpga-clk-manager.yaml @@ -27,17 +27,17 @@ properties: additionalProperties: false properties: - "#address-cells": + '#address-cells': const: 1 - "#size-cells": + '#size-cells': const: 0 patternProperties: - "^osc[0-9]$": + '^osc[0-9]$': type: object - "^[a-z0-9,_]+(clk|pll|clk_gate|clk_divided)(@[a-f0-9]+)?$": + '^[a-z0-9,_]+(clk|pll|clk_gate|clk_divided)(@[a-f0-9]+)?$': type: object $ref: '#/$defs/clock-props' unevaluatedProperties: false @@ -58,14 +58,14 @@ properties: minItems: 1 maxItems: 5 - "#address-cells": + '#address-cells': const: 1 - "#size-cells": + '#size-cells': const: 0 patternProperties: - "^[a-z0-9,_]+(clk|pll)(@[a-f0-9]+)?$": + '^[a-z0-9,_]+(clk|pll)(@[a-f0-9]+)?$': type: object $ref: '#/$defs/clock-props' unevaluatedProperties: false @@ -86,11 +86,11 @@ properties: required: - compatible - clocks - - "#clock-cells" + - '#clock-cells' required: - compatible - - "#clock-cells" + - '#clock-cells' required: - compatible @@ -104,7 +104,7 @@ $defs: reg: maxItems: 1 - "#clock-cells": + '#clock-cells': const: 0 clk-gate: diff --git a/Documentation/devicetree/bindings/arm/amd,seattle.yaml b/Documentation/devicetree/bindings/arm/amd,seattle.yaml new file mode 100644 index 0000000000000..7a3fc05b19eb0 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/amd,seattle.yaml @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/amd,seattle.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: AMD Seattle SoC Platforms + +maintainers: + - Suravee Suthikulpanit + - Tom Lendacky + +properties: + $nodename: + const: "/" + compatible: + oneOf: + - description: Boards with AMD Seattle SoC + items: + - const: amd,seattle-overdrive + - const: amd,seattle + +additionalProperties: true +... diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml index 2a096e060ed3d..08d9963fe9259 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.yaml +++ b/Documentation/devicetree/bindings/arm/amlogic.yaml @@ -134,6 +134,7 @@ properties: - libretech,aml-s912-pc - minix,neo-u9h - nexbox,a1 + - oranth,tx9-pro - tronsmart,vega-s96 - ugoos,am3 - videostrong,gxm-kiii-pro diff --git a/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-gx-ao-secure.yaml b/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-gx-ao-secure.yaml index b4f6695a60152..fa7c403c874a6 100644 --- a/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-gx-ao-secure.yaml +++ b/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-gx-ao-secure.yaml @@ -34,6 +34,9 @@ properties: - amlogic,a4-ao-secure - amlogic,c3-ao-secure - amlogic,s4-ao-secure + - amlogic,s6-ao-secure + - amlogic,s7-ao-secure + - amlogic,s7d-ao-secure - amlogic,t7-ao-secure - const: amlogic,meson-gx-ao-secure - const: syscon diff --git a/Documentation/devicetree/bindings/arm/apm.yaml b/Documentation/devicetree/bindings/arm/apm.yaml new file mode 100644 index 0000000000000..ea0d362cea3ac --- /dev/null +++ b/Documentation/devicetree/bindings/arm/apm.yaml @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/apm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: APM X-Gene SoC Platforms + +maintainers: + - Khuong Dinh + +properties: + $nodename: + const: "/" + compatible: + oneOf: + - description: Boards with X-Gene1 Soc + items: + - const: apm,mustang + - const: apm,xgene-storm + + - description: Boards with X-Gene2 SoC + items: + - const: apm,merlin + - const: apm,xgene-shadowcat + +additionalProperties: true +... diff --git a/Documentation/devicetree/bindings/arm/arm,integrator.yaml b/Documentation/devicetree/bindings/arm/arm,integrator.yaml index 1bdbd1b7ee381..8fe22185a3376 100644 --- a/Documentation/devicetree/bindings/arm/arm,integrator.yaml +++ b/Documentation/devicetree/bindings/arm/arm,integrator.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM Integrator Boards maintainers: - - Linus Walleij + - Linus Walleij description: |+ These were the first ARM platforms officially supported by ARM Ltd. diff --git a/Documentation/devicetree/bindings/arm/arm,realview.yaml b/Documentation/devicetree/bindings/arm/arm,realview.yaml index 3c5f1688dbd78..0b3133ecddac1 100644 --- a/Documentation/devicetree/bindings/arm/arm,realview.yaml +++ b/Documentation/devicetree/bindings/arm/arm,realview.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM RealView Boards maintainers: - - Linus Walleij + - Linus Walleij description: |+ The ARM RealView series of reference designs were built to explore the Arm11, diff --git a/Documentation/devicetree/bindings/arm/arm,scu.yaml b/Documentation/devicetree/bindings/arm/arm,scu.yaml index dae2aa27e641b..f735b7fb8e1cc 100644 --- a/Documentation/devicetree/bindings/arm/arm,scu.yaml +++ b/Documentation/devicetree/bindings/arm/arm,scu.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM Snoop Control Unit (SCU) maintainers: - - Linus Walleij + - Linus Walleij description: | As part of the MPCore complex, Cortex-A5 and Cortex-A9 are provided diff --git a/Documentation/devicetree/bindings/arm/arm,versatile-sysreg.yaml b/Documentation/devicetree/bindings/arm/arm,versatile-sysreg.yaml index 3b060c36b90cd..e72dc45c1afa7 100644 --- a/Documentation/devicetree/bindings/arm/arm,versatile-sysreg.yaml +++ b/Documentation/devicetree/bindings/arm/arm,versatile-sysreg.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Arm Versatile system registers maintainers: - - Linus Walleij + - Linus Walleij description: This is a system control registers block, providing multiple low level diff --git a/Documentation/devicetree/bindings/arm/arm,versatile.yaml b/Documentation/devicetree/bindings/arm/arm,versatile.yaml index 7a3caf6af200a..c777e455d0388 100644 --- a/Documentation/devicetree/bindings/arm/arm,versatile.yaml +++ b/Documentation/devicetree/bindings/arm/arm,versatile.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM Versatile Boards maintainers: - - Linus Walleij + - Linus Walleij description: |+ The ARM Versatile boards are two variants of ARM926EJ-S evaluation boards diff --git a/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml b/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml index 4cdca53205444..6430218ba1cea 100644 --- a/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml +++ b/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml @@ -8,7 +8,7 @@ title: ARM Versatile Express and Juno Boards maintainers: - Sudeep Holla - - Linus Walleij + - Linus Walleij description: |+ ARM's Versatile Express platform were built as reference designs for exploring diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml index aedefca7cf4a8..9298c1a75dd13 100644 --- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml +++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml @@ -93,7 +93,10 @@ properties: - facebook,minerva-cmc - facebook,santabarbara-bmc - facebook,yosemite4-bmc + - facebook,yosemite5-bmc + - ibm,balcones-bmc - ibm,blueridge-bmc + - ibm,bonnell-bmc - ibm,everest-bmc - ibm,fuji-bmc - ibm,rainier-bmc diff --git a/Documentation/devicetree/bindings/arm/bst.yaml b/Documentation/devicetree/bindings/arm/bst.yaml new file mode 100644 index 0000000000000..a3a7f424fd57f --- /dev/null +++ b/Documentation/devicetree/bindings/arm/bst.yaml @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/bst.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: BST platforms + +description: + Black Sesame Technologies (BST) is a semiconductor company that produces + automotive-grade system-on-chips (SoCs) for intelligent driving, focusing + on computer vision and AI capabilities. The BST C1200 family includes SoCs + for ADAS (Advanced Driver Assistance Systems) and autonomous driving + applications. + +maintainers: + - Ge Gordon + +properties: + $nodename: + const: '/' + compatible: + oneOf: + - description: BST C1200 CDCU1.0 ADAS 4C2G board + items: + - const: bst,c1200-cdcu1.0-adas-4c2g + - const: bst,c1200 + +additionalProperties: true + +... diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index 00cdf490b0620..68a2d5fecc43b 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml @@ -1106,11 +1106,14 @@ properties: - gateworks,imx8mp-gw75xx-2x # i.MX8MP Gateworks Board - gateworks,imx8mp-gw82xx-2x # i.MX8MP Gateworks Board - gocontroll,moduline-display # GOcontroll Moduline Display controller + - prt,prt8ml # Protonic PRT8ML - skov,imx8mp-skov-basic # SKOV i.MX8MP baseboard without frontplate - skov,imx8mp-skov-revb-hdmi # SKOV i.MX8MP climate control without panel - skov,imx8mp-skov-revb-lt6 # SKOV i.MX8MP climate control with 7” panel - skov,imx8mp-skov-revb-mi1010ait-1cp1 # SKOV i.MX8MP climate control with 10.1" panel + - skov,imx8mp-skov-revc-hdmi # SKOV i.MX8MP climate control without panel - skov,imx8mp-skov-revc-bd500 # SKOV i.MX8MP climate control with LED frontplate + - skov,imx8mp-skov-revc-jutouch-jt101tm023 # SKOV i.MX8MP climate control with 10" JuTouch panel - skov,imx8mp-skov-revc-tian-g07017 # SKOV i.MX8MP climate control with 7" panel - ultratronik,imx8mp-ultra-mach-sbc # Ultratronik SBC i.MX8MP based board - ysoft,imx8mp-iota2-lumpy # Y Soft i.MX8MP IOTA2 Lumpy Board @@ -1430,6 +1433,7 @@ properties: - enum: - fsl,imx95-15x15-evk # i.MX95 15x15 EVK Board - fsl,imx95-19x19-evk # i.MX95 19x19 EVK Board + - toradex,verdin-imx95-19x19-evk # i.MX95 Verdin Evaluation Kit (EVK) - const: fsl,imx95 - description: PHYTEC i.MX 95 FPSC based Boards @@ -1439,6 +1443,12 @@ properties: - const: phytec,imx95-phycore-fpsc # phyCORE-i.MX 95 FPSC - const: fsl,imx95 + - description: Toradex Boards with SMARC iMX95 Modules + items: + - const: toradex,smarc-imx95-dev # Toradex SMARC iMX95 on Toradex SMARC Development Board + - const: toradex,smarc-imx95 # Toradex SMARC iMX95 Module + - const: fsl,imx95 + - description: i.MXRT1050 based Boards items: - enum: @@ -1492,6 +1502,13 @@ properties: - const: tq,imx93-tqma9352 # TQ-Systems GmbH i.MX93 TQMa93xxCA/LA SOM - const: fsl,imx93 + - description: PHYTEC phyCORE-i.MX91 SoM based boards + items: + - enum: + - phytec,imx91-phyboard-segin # phyBOARD-Segin with i.MX91 + - const: phytec,imx91-phycore-som # phyCORE-i.MX91 SoM + - const: fsl,imx91 + - description: PHYTEC phyCORE-i.MX93 SoM based boards items: - enum: diff --git a/Documentation/devicetree/bindings/arm/gemini.yaml b/Documentation/devicetree/bindings/arm/gemini.yaml index f6a0b675830fb..fc092962ab565 100644 --- a/Documentation/devicetree/bindings/arm/gemini.yaml +++ b/Documentation/devicetree/bindings/arm/gemini.yaml @@ -20,7 +20,7 @@ description: | Many of the IP blocks used in the SoC comes from Faraday Technology. maintainers: - - Linus Walleij + - Linus Walleij properties: $nodename: diff --git a/Documentation/devicetree/bindings/arm/intel,socfpga.yaml b/Documentation/devicetree/bindings/arm/intel,socfpga.yaml index c75cd7d29f1aa..c918837bd41c0 100644 --- a/Documentation/devicetree/bindings/arm/intel,socfpga.yaml +++ b/Documentation/devicetree/bindings/arm/intel,socfpga.yaml @@ -21,10 +21,17 @@ properties: - intel,socfpga-agilex-n6000 - intel,socfpga-agilex-socdk - const: intel,socfpga-agilex + - description: Agilex3 boards + items: + - enum: + - intel,socfpga-agilex3-socdk + - const: intel,socfpga-agilex3 + - const: intel,socfpga-agilex5 - description: Agilex5 boards items: - enum: - intel,socfpga-agilex5-socdk + - intel,socfpga-agilex5-socdk-013b - intel,socfpga-agilex5-socdk-nand - const: intel,socfpga-agilex5 diff --git a/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml b/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml index b7b430896596a..0f1bf634a98a1 100644 --- a/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml +++ b/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Intel IXP4xx maintainers: - - Linus Walleij + - Linus Walleij properties: $nodename: diff --git a/Documentation/devicetree/bindings/arm/lge.yaml b/Documentation/devicetree/bindings/arm/lge.yaml new file mode 100644 index 0000000000000..d983ef7fcbd63 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/lge.yaml @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/lge.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: LG Electronics SoC Platforms + +maintainers: + - Chanho Min + +properties: + $nodename: + const: "/" + compatible: + oneOf: + - description: Boards with LG1312 Soc + items: + - const: lge,lg1312-ref + - const: lge,lg1312 + + - description: Boards with LG1313 SoC + items: + - const: lge,lg1313-ref + - const: lge,lg1313 + +additionalProperties: true +... diff --git a/Documentation/devicetree/bindings/arm/marvell/ap80x-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap80x-system-controller.txt deleted file mode 100644 index 72de11bd2ef02..0000000000000 --- a/Documentation/devicetree/bindings/arm/marvell/ap80x-system-controller.txt +++ /dev/null @@ -1,146 +0,0 @@ -Marvell Armada AP80x System Controller -====================================== - -The AP806/AP807 is one of the two core HW blocks of the Marvell Armada -7K/8K/931x SoCs. It contains system controllers, which provide several -registers giving access to numerous features: clocks, pin-muxing and -many other SoC configuration items. This DT binding allows to describe -these system controllers. - -For the top level node: - - compatible: must be: "syscon", "simple-mfd"; - - reg: register area of the AP80x system controller - -SYSTEM CONTROLLER 0 -=================== - -Clocks: -------- - - -The Device Tree node representing the AP806/AP807 system controller -provides a number of clocks: - - - 0: reference clock of CPU cluster 0 - - 1: reference clock of CPU cluster 1 - - 2: fixed PLL at 1200 Mhz - - 3: MSS clock, derived from the fixed PLL - -Required properties: - - - compatible: must be one of: - * "marvell,ap806-clock" - * "marvell,ap807-clock" - - #clock-cells: must be set to 1 - -Pinctrl: --------- - -For common binding part and usage, refer to -Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt. - -Required properties: -- compatible must be "marvell,ap806-pinctrl", - -Available mpp pins/groups and functions: -Note: brackets (x) are not part of the mpp name for marvell,function and given -only for more detailed description in this document. - -name pins functions -================================================================================ -mpp0 0 gpio, sdio(clk), spi0(clk) -mpp1 1 gpio, sdio(cmd), spi0(miso) -mpp2 2 gpio, sdio(d0), spi0(mosi) -mpp3 3 gpio, sdio(d1), spi0(cs0n) -mpp4 4 gpio, sdio(d2), i2c0(sda) -mpp5 5 gpio, sdio(d3), i2c0(sdk) -mpp6 6 gpio, sdio(ds) -mpp7 7 gpio, sdio(d4), uart1(rxd) -mpp8 8 gpio, sdio(d5), uart1(txd) -mpp9 9 gpio, sdio(d6), spi0(cs1n) -mpp10 10 gpio, sdio(d7) -mpp11 11 gpio, uart0(txd) -mpp12 12 gpio, sdio(pw_off), sdio(hw_rst) -mpp13 13 gpio -mpp14 14 gpio -mpp15 15 gpio -mpp16 16 gpio -mpp17 17 gpio -mpp18 18 gpio -mpp19 19 gpio, uart0(rxd), sdio(pw_off) - -GPIO: ------ -For common binding part and usage, refer to -Documentation/devicetree/bindings/gpio/gpio-mvebu.yaml. - -Required properties: - -- compatible: "marvell,armada-8k-gpio" - -- offset: offset address inside the syscon block - -Optional properties: - -- marvell,pwm-offset: offset address of PWM duration control registers inside - the syscon block - -Example: -ap_syscon: system-controller@6f4000 { - compatible = "syscon", "simple-mfd"; - reg = <0x6f4000 0x1000>; - - ap_clk: clock { - compatible = "marvell,ap806-clock"; - #clock-cells = <1>; - }; - - ap_pinctrl: pinctrl { - compatible = "marvell,ap806-pinctrl"; - }; - - ap_gpio: gpio { - compatible = "marvell,armada-8k-gpio"; - offset = <0x1040>; - ngpios = <19>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&ap_pinctrl 0 0 19>; - marvell,pwm-offset = <0x10c0>; - #pwm-cells = <2>; - clocks = <&ap_clk 3>; - }; -}; - -SYSTEM CONTROLLER 1 -=================== - -Cluster clocks: ---------------- - -Device Tree Clock bindings for cluster clock of Marvell -AP806/AP807. Each cluster contain up to 2 CPUs running at the same -frequency. - -Required properties: - - compatible: must be one of: - * "marvell,ap806-cpu-clock" - * "marvell,ap807-cpu-clock" -- #clock-cells : should be set to 1. - -- clocks : shall be the input parent clock(s) phandle for the clock - (one per cluster) - -- reg: register range associated with the cluster clocks - -ap_syscon1: system-controller@6f8000 { - compatible = "marvell,armada-ap806-syscon1", "syscon", "simple-mfd"; - reg = <0x6f8000 0x1000>; - - cpu_clk: clock-cpu@278 { - compatible = "marvell,ap806-cpu-clock"; - clocks = <&ap_clk 0>, <&ap_clk 1>; - #clock-cells = <1>; - reg = <0x278 0xa30>; - }; -}; diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt deleted file mode 100644 index 54ff9f2183286..0000000000000 --- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt +++ /dev/null @@ -1,191 +0,0 @@ -Marvell Armada CP110 System Controller -====================================== - -The CP110 is one of the two core HW blocks of the Marvell Armada 7K/8K -SoCs. It contains system controllers, which provide several registers -giving access to numerous features: clocks, pin-muxing and many other -SoC configuration items. This DT binding allows to describe these -system controllers. - -For the top level node: - - compatible: must be: "syscon", "simple-mfd"; - - reg: register area of the CP110 system controller - -SYSTEM CONTROLLER 0 -=================== - -Clocks: -------- - -The Device Tree node representing this System Controller 0 provides a -number of clocks: - - - a set of core clocks - - a set of gateable clocks - -Those clocks can be referenced by other Device Tree nodes using two -cells: - - The first cell must be 0 or 1. 0 for the core clocks and 1 for the - gateable clocks. - - The second cell identifies the particular core clock or gateable - clocks. - -The following clocks are available: - - Core clocks - - 0 0 APLL - - 0 1 PPv2 core - - 0 2 EIP - - 0 3 Core - - 0 4 NAND core - - 0 5 SDIO core - - Gateable clocks - - 1 0 Audio - - 1 1 Comm Unit - - 1 2 NAND - - 1 3 PPv2 - - 1 4 SDIO - - 1 5 MG Domain - - 1 6 MG Core - - 1 7 XOR1 - - 1 8 XOR0 - - 1 9 GOP DP - - 1 11 PCIe x1 0 - - 1 12 PCIe x1 1 - - 1 13 PCIe x4 - - 1 14 PCIe / XOR - - 1 15 SATA - - 1 16 SATA USB - - 1 17 Main - - 1 18 SD/MMC/GOP - - 1 21 Slow IO (SPI, NOR, BootROM, I2C, UART) - - 1 22 USB3H0 - - 1 23 USB3H1 - - 1 24 USB3 Device - - 1 25 EIP150 - - 1 26 EIP197 - -Required properties: - - - compatible: must be: - "marvell,cp110-clock" - - #clock-cells: must be set to 2 - -Pinctrl: --------- - -For common binding part and usage, refer to the file -Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt. - -Required properties: - -- compatible: "marvell,armada-7k-pinctrl", "marvell,armada-8k-cpm-pinctrl", - "marvell,armada-8k-cps-pinctrl" or "marvell,cp115-standalone-pinctrl" - depending on the specific variant of the SoC being used. - -Available mpp pins/groups and functions: -Note: brackets (x) are not part of the mpp name for marvell,function and given -only for more detailed description in this document. - -name pins functions -================================================================================ -mpp0 0 gpio, dev(ale1), au(i2smclk), ge0(rxd3), tdm(pclk), ptp(pulse), mss_i2c(sda), uart0(rxd), sata0(present_act), ge(mdio) -mpp1 1 gpio, dev(ale0), au(i2sdo_spdifo), ge0(rxd2), tdm(drx), ptp(clk), mss_i2c(sck), uart0(txd), sata1(present_act), ge(mdc) -mpp2 2 gpio, dev(ad15), au(i2sextclk), ge0(rxd1), tdm(dtx), mss_uart(rxd), ptp(pclk_out), i2c1(sck), uart1(rxd), sata0(present_act), xg(mdc) -mpp3 3 gpio, dev(ad14), au(i2slrclk), ge0(rxd0), tdm(fsync), mss_uart(txd), pcie(rstoutn), i2c1(sda), uart1(txd), sata1(present_act), xg(mdio) -mpp4 4 gpio, dev(ad13), au(i2sbclk), ge0(rxctl), tdm(rstn), mss_uart(rxd), uart1(cts), pcie0(clkreq), uart3(rxd), ge(mdc) -mpp5 5 gpio, dev(ad12), au(i2sdi), ge0(rxclk), tdm(intn), mss_uart(txd), uart1(rts), pcie1(clkreq), uart3(txd), ge(mdio) -mpp6 6 gpio, dev(ad11), ge0(txd3), spi0(csn2), au(i2sextclk), sata1(present_act), pcie2(clkreq), uart0(rxd), ptp(pulse) -mpp7 7 gpio, dev(ad10), ge0(txd2), spi0(csn1), spi1(csn1), sata0(present_act), led(data), uart0(txd), ptp(clk) -mpp8 8 gpio, dev(ad9), ge0(txd1), spi0(csn0), spi1(csn0), uart0(cts), led(stb), uart2(rxd), ptp(pclk_out), synce1(clk) -mpp9 9 gpio, dev(ad8), ge0(txd0), spi0(mosi), spi1(mosi), pcie(rstoutn), synce2(clk) -mpp10 10 gpio, dev(readyn), ge0(txctl), spi0(miso), spi1(miso), uart0(cts), sata1(present_act) -mpp11 11 gpio, dev(wen1), ge0(txclkout), spi0(clk), spi1(clk), uart0(rts), led(clk), uart2(txd), sata0(present_act) -mpp12 12 gpio, dev(clk_out), nf(rbn1), spi1(csn1), ge0(rxclk) -mpp13 13 gpio, dev(burstn), nf(rbn0), spi1(miso), ge0(rxctl), mss_spi(miso) -mpp14 14 gpio, dev(bootcsn), dev(csn0), spi1(csn0), spi0(csn3), au(i2sextclk), spi0(miso), sata0(present_act), mss_spi(csn) -mpp15 15 gpio, dev(ad7), spi1(mosi), spi0(mosi), mss_spi(mosi), ptp(pulse_cp2cp) -mpp16 16 gpio, dev(ad6), spi1(clk), mss_spi(clk) -mpp17 17 gpio, dev(ad5), ge0(txd3) -mpp18 18 gpio, dev(ad4), ge0(txd2), ptp(clk_cp2cp) -mpp19 19 gpio, dev(ad3), ge0(txd1), wakeup(out_cp2cp) -mpp20 20 gpio, dev(ad2), ge0(txd0) -mpp21 21 gpio, dev(ad1), ge0(txctl), sei(in_cp2cp) -mpp22 22 gpio, dev(ad0), ge0(txclkout), wakeup(in_cp2cp) -mpp23 23 gpio, dev(a1), au(i2smclk), link(rd_in_cp2cp) -mpp24 24 gpio, dev(a0), au(i2slrclk) -mpp25 25 gpio, dev(oen), au(i2sdo_spdifo) -mpp26 26 gpio, dev(wen0), au(i2sbclk) -mpp27 27 gpio, dev(csn0), spi1(miso), mss_gpio4, ge0(rxd3), spi0(csn4), ge(mdio), sata0(present_act), uart0(rts), rei(in_cp2cp) -mpp28 28 gpio, dev(csn1), spi1(csn0), mss_gpio5, ge0(rxd2), spi0(csn5), pcie2(clkreq), ptp(pulse), ge(mdc), sata1(present_act), uart0(cts), led(data) -mpp29 29 gpio, dev(csn2), spi1(mosi), mss_gpio6, ge0(rxd1), spi0(csn6), pcie1(clkreq), ptp(clk), mss_i2c(sda), sata0(present_act), uart0(rxd), led(stb) -mpp30 30 gpio, dev(csn3), spi1(clk), mss_gpio7, ge0(rxd0), spi0(csn7), pcie0(clkreq), ptp(pclk_out), mss_i2c(sck), sata1(present_act), uart0(txd), led(clk) -mpp31 31 gpio, dev(a2), mss_gpio4, pcie(rstoutn), ge(mdc) -mpp32 32 gpio, mii(col), mii(txerr), mss_spi(miso), tdm(drx), au(i2sextclk), au(i2sdi), ge(mdio), sdio(v18_en), pcie1(clkreq), mss_gpio0 -mpp33 33 gpio, mii(txclk), sdio(pwr10), mss_spi(csn), tdm(fsync), au(i2smclk), sdio(bus_pwr), xg(mdio), pcie2(clkreq), mss_gpio1 -mpp34 34 gpio, mii(rxerr), sdio(pwr11), mss_spi(mosi), tdm(dtx), au(i2slrclk), sdio(wr_protect), ge(mdc), pcie0(clkreq), mss_gpio2 -mpp35 35 gpio, sata1(present_act), i2c1(sda), mss_spi(clk), tdm(pclk), au(i2sdo_spdifo), sdio(card_detect), xg(mdio), ge(mdio), pcie(rstoutn), mss_gpio3 -mpp36 36 gpio, synce2(clk), i2c1(sck), ptp(clk), synce1(clk), au(i2sbclk), sata0(present_act), xg(mdc), ge(mdc), pcie2(clkreq), mss_gpio5 -mpp37 37 gpio, uart2(rxd), i2c0(sck), ptp(pclk_out), tdm(intn), mss_i2c(sck), sata1(present_act), ge(mdc), xg(mdc), pcie1(clkreq), mss_gpio6, link(rd_out_cp2cp) -mpp38 38 gpio, uart2(txd), i2c0(sda), ptp(pulse), tdm(rstn), mss_i2c(sda), sata0(present_act), ge(mdio), xg(mdio), au(i2sextclk), mss_gpio7, ptp(pulse_cp2cp) -mpp39 39 gpio, sdio(wr_protect), au(i2sbclk), ptp(clk), spi0(csn1), sata1(present_act), mss_gpio0 -mpp40 40 gpio, sdio(pwr11), synce1(clk), mss_i2c(sda), au(i2sdo_spdifo), ptp(pclk_out), spi0(clk), uart1(txd), ge(mdio), sata0(present_act), mss_gpio1 -mpp41 41 gpio, sdio(pwr10), sdio(bus_pwr), mss_i2c(sck), au(i2slrclk), ptp(pulse), spi0(mosi), uart1(rxd), ge(mdc), sata1(present_act), mss_gpio2, rei(out_cp2cp) -mpp42 42 gpio, sdio(v18_en), sdio(wr_protect), synce2(clk), au(i2smclk), mss_uart(txd), spi0(miso), uart1(cts), xg(mdc), sata0(present_act), mss_gpio4 -mpp43 43 gpio, sdio(card_detect), synce1(clk), au(i2sextclk), mss_uart(rxd), spi0(csn0), uart1(rts), xg(mdio), sata1(present_act), mss_gpio5, wakeup(out_cp2cp) -mpp44 44 gpio, ge1(txd2), uart0(rts), ptp(clk_cp2cp) -mpp45 45 gpio, ge1(txd3), uart0(txd), pcie(rstoutn) -mpp46 46 gpio, ge1(txd1), uart1(rts) -mpp47 47 gpio, ge1(txd0), spi1(clk), uart1(txd), ge(mdc) -mpp48 48 gpio, ge1(txctl_txen), spi1(mosi), xg(mdc), wakeup(in_cp2cp) -mpp49 49 gpio, ge1(txclkout), mii(crs), spi1(miso), uart1(rxd), ge(mdio), pcie0(clkreq), sdio(v18_en), sei(out_cp2cp) -mpp50 50 gpio, ge1(rxclk), mss_i2c(sda), spi1(csn0), uart2(txd), uart0(rxd), xg(mdio), sdio(pwr11) -mpp51 51 gpio, ge1(rxd0), mss_i2c(sck), spi1(csn1), uart2(rxd), uart0(cts), sdio(pwr10) -mpp52 52 gpio, ge1(rxd1), synce1(clk), synce2(clk), spi1(csn2), uart1(cts), led(clk), pcie(rstoutn), pcie0(clkreq) -mpp53 53 gpio, ge1(rxd2), ptp(clk), spi1(csn3), uart1(rxd), led(stb), sdio(led) -mpp54 54 gpio, ge1(rxd3), synce2(clk), ptp(pclk_out), synce1(clk), led(data), sdio(hw_rst), sdio_wp(wr_protect) -mpp55 55 gpio, ge1(rxctl_rxdv), ptp(pulse), sdio(led), sdio_cd(card_detect) -mpp56 56 gpio, tdm(drx), au(i2sdo_spdifo), spi0(clk), uart1(rxd), sata1(present_act), sdio(clk) -mpp57 57 gpio, mss_i2c(sda), ptp(pclk_out), tdm(intn), au(i2sbclk), spi0(mosi), uart1(txd), sata0(present_act), sdio(cmd) -mpp58 58 gpio, mss_i2c(sck), ptp(clk), tdm(rstn), au(i2sdi), spi0(miso), uart1(cts), led(clk), sdio(d0) -mpp59 59 gpio, mss_gpio7, synce2(clk), tdm(fsync), au(i2slrclk), spi0(csn0), uart0(cts), led(stb), uart1(txd), sdio(d1) -mpp60 60 gpio, mss_gpio6, ptp(pulse), tdm(dtx), au(i2smclk), spi0(csn1), uart0(rts), led(data), uart1(rxd), sdio(d2) -mpp61 61 gpio, mss_gpio5, ptp(clk), tdm(pclk), au(i2sextclk), spi0(csn2), uart0(txd), uart2(txd), sata1(present_act), ge(mdio), sdio(d3) -mpp62 62 gpio, mss_gpio4, synce1(clk), ptp(pclk_out), sata1(present_act), spi0(csn3), uart0(rxd), uart2(rxd), sata0(present_act), ge(mdc) - -GPIO: ------ - -For common binding part and usage, refer to -Documentation/devicetree/bindings/gpio/gpio-mvebu.yaml. - -Required properties: - -- compatible: "marvell,armada-8k-gpio" - -- offset: offset address inside the syscon block - -Example: - -CP110_LABEL(syscon0): system-controller@440000 { - compatible = "syscon", "simple-mfd"; - reg = <0x440000 0x1000>; - - CP110_LABEL(clk): clock { - compatible = "marvell,cp110-clock"; - #clock-cells = <2>; - }; - - CP110_LABEL(pinctrl): pinctrl { - compatible = "marvell,armada-8k-cpm-pinctrl"; - }; - - CP110_LABEL(gpio1): gpio@100 { - compatible = "marvell,armada-8k-gpio"; - offset = <0x100>; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&CP110_LABEL(pinctrl) 0 0 32>; - }; - -}; diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml index f042778736948..718d732174b9e 100644 --- a/Documentation/devicetree/bindings/arm/mediatek.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml @@ -38,6 +38,7 @@ properties: - const: mediatek,mt6580 - items: - enum: + - alcatel,yarisxl - prestigio,pmt5008-3g - const: mediatek,mt6582 - items: @@ -113,6 +114,12 @@ properties: - const: bananapi,bpi-r4-2g5 - const: bananapi,bpi-r4 - const: mediatek,mt7988a + - items: + - enum: + - bananapi,bpi-r4-pro-4e + - bananapi,bpi-r4-pro-8x + - const: bananapi,bpi-r4-pro + - const: mediatek,mt7988a - items: - enum: - mediatek,mt8127-moose @@ -445,6 +452,7 @@ properties: - enum: - kontron,3-5-sbc-i1200 - mediatek,mt8395-evk + - mediatek,mt8395-evk-ufs - radxa,nio-12l - const: mediatek,mt8395 - const: mediatek,mt8195 diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml index 7360a2849b5bd..6e2e0c5518411 100644 --- a/Documentation/devicetree/bindings/arm/psci.yaml +++ b/Documentation/devicetree/bindings/arm/psci.yaml @@ -163,7 +163,6 @@ examples: method = "smc"; }; - - |+ // Case 3: PSCI v0.2 and PSCI v0.1. diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml index 4edc47483851f..c349306f0d520 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml @@ -36,9 +36,12 @@ properties: $nodename: pattern: "^tpdm(@[0-9a-f]+)$" compatible: - items: - - const: qcom,coresight-tpdm - - const: arm,primecell + oneOf: + - items: + - const: qcom,coresight-static-tpdm + - items: + - const: qcom,coresight-tpdm + - const: arm,primecell reg: maxItems: 1 @@ -147,4 +150,18 @@ examples: }; }; }; + + turing-llm-tpdm { + compatible = "qcom,coresight-static-tpdm"; + + qcom,cmb-element-bits = <32>; + + out-ports { + port { + turing_llm_tpdm_out: endpoint { + remote-endpoint = <&turing0_funnel_in1>; + }; + }; + }; + }; ... diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index 18b5ed044f9fc..d84bd3bca2010 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -88,6 +88,7 @@ properties: - items: - enum: + - asus,z00t - huawei,kiwi - longcheer,l9100 - samsung,a7 @@ -191,6 +192,11 @@ properties: - xiaomi,riva - const: qcom,msm8917 + - items: + - enum: + - xiaomi,land + - const: qcom,msm8937 + - items: - enum: - flipkart,rimob @@ -340,6 +346,7 @@ properties: - particle,tachyon - qcom,qcm6490-idp - qcom,qcs6490-rb3gen2 + - radxa,dragon-q6a - shift,otter - const: qcom,qcm6490 @@ -893,6 +900,7 @@ properties: - items: - enum: + - huawei,planck - lenovo,yoga-c630 - lg,judyln - lg,judyp @@ -1083,7 +1091,13 @@ properties: - items: - enum: - - asus,zenbook-a14-ux3407qa + - asus,zenbook-a14-ux3407qa-lcd + - asus,zenbook-a14-ux3407qa-oled + - const: asus,zenbook-a14-ux3407qa + - const: qcom,x1p42100 + + - items: + - enum: - hp,omnibook-x14-fe1 - lenovo,thinkbook-16 - qcom,x1p42100-crd @@ -1167,6 +1181,7 @@ allOf: - qcom,apq8094 - qcom,apq8096 - qcom,msm8917 + - qcom,msm8937 - qcom,msm8939 - qcom,msm8953 - qcom,msm8956 diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml index 6aceaa8acbb25..d496421dbd87e 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.yaml +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml @@ -15,6 +15,11 @@ properties: compatible: oneOf: + - description: 100ASK DshanPi A1 board + items: + - const: 100ask,dshanpi-a1 + - const: rockchip,rk3576 + - description: 96boards RK3399 Ficus (ROCK960 Enterprise Edition) items: - const: vamrs,ficus @@ -25,6 +30,12 @@ properties: - const: vamrs,rock960 - const: rockchip,rk3399 + - description: 9Tripod X3568 series board + items: + - enum: + - 9tripod,x3568-v4 + - const: rockchip,rk3568 + - description: Amarula Vyasa RK3288 items: - const: amarula,vyasa-rk3288 @@ -78,13 +89,17 @@ properties: - description: Asus Tinker board items: - - const: asus,rk3288-tinker + - enum: + - asus,rk3288-tinker + - asus,rk3288-tinker-s - const: rockchip,rk3288 - - description: Asus Tinker board S + - description: Asus Tinker Board 3/3S items: - - const: asus,rk3288-tinker-s - - const: rockchip,rk3288 + - enum: + - asus,rk3566-tinker-board-3 + - asus,rk3566-tinker-board-3s + - const: rockchip,rk3566 - description: Beelink A1 items: @@ -330,6 +345,11 @@ properties: - friendlyarm,nanopi-r6s - const: rockchip,rk3588s + - description: FriendlyElec NanoPi R76S + items: + - const: friendlyarm,nanopi-r76s + - const: rockchip,rk3576 + - description: FriendlyElec NanoPi Zero2 items: - const: friendlyarm,nanopi-zero2 @@ -748,6 +768,11 @@ properties: - const: lckfb,tspi-rk3566 - const: rockchip,rk3566 + - description: LinkEase EasePi R1 + items: + - const: linkease,easepi-r1 + - const: rockchip,rk3568 + - description: Luckfox Core3576 Module based boards items: - enum: @@ -868,9 +893,11 @@ properties: - const: prt,mecsbc - const: rockchip,rk3568 - - description: QNAP TS-433-4G 4-Bay NAS + - description: QNAP TS-x33 NAS devices items: - - const: qnap,ts433 + - enum: + - qnap,ts233 + - qnap,ts433 - const: rockchip,rk3568 - description: Radxa Compute Module 3 (CM3) diff --git a/Documentation/devicetree/bindings/arm/tegra.yaml b/Documentation/devicetree/bindings/arm/tegra.yaml index 6139407c2cbf7..50a31dba7becd 100644 --- a/Documentation/devicetree/bindings/arm/tegra.yaml +++ b/Documentation/devicetree/bindings/arm/tegra.yaml @@ -189,6 +189,11 @@ properties: - nvidia,p2371-2180 - nvidia,p2571 - nvidia,p2894-0050-a08 + - nvidia,p3450-0000 + - const: nvidia,tegra210 + - items: + - const: nvidia,p3541-0000 + - const: nvidia,p3450-0000 - const: nvidia,tegra210 - description: Jetson TX2 Developer Kit items: diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml index 0105dcda6e04d..85deda6d42920 100644 --- a/Documentation/devicetree/bindings/arm/ti/k3.yaml +++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml @@ -37,6 +37,12 @@ properties: - const: phytec,am62a-phycore-som - const: ti,am62a7 + - description: K3 AM62L3 SoC and Boards + items: + - enum: + - ti,am62l3-evm + - const: ti,am62l3 + - description: K3 AM62P5 SoC and Boards items: - enum: @@ -158,6 +164,14 @@ properties: - ti,am654-evm - const: ti,am654 + - description: K3 AM69 SoC Toradex Aquila Modules and Carrier Boards + items: + - enum: + - toradex,aquila-am69-clover # Aquila AM69 Module on Clover Board + - toradex,aquila-am69-dev # Aquila AM69 Module on Aquila Development Board + - const: toradex,aquila-am69 # Aquila AM69 Module + - const: ti,j784s4 + - description: K3 J7200 SoC oneOf: - const: ti,j7200 @@ -194,6 +208,7 @@ properties: items: - enum: - beagle,am67a-beagley-ai + - kontron,sa67 # Kontron SMARC-sAM67 board - ti,j722s-evm - const: ti,j722s diff --git a/Documentation/devicetree/bindings/arm/ti/omap.yaml b/Documentation/devicetree/bindings/arm/ti/omap.yaml index aa5df4692e372..14f1b9d8f59d9 100644 --- a/Documentation/devicetree/bindings/arm/ti/omap.yaml +++ b/Documentation/devicetree/bindings/arm/ti/omap.yaml @@ -129,6 +129,13 @@ properties: - const: phytec,am335x-phycore-som - const: ti,am33xx + - description: TQ-Systems TQMa335x[L] SoM + items: + - enum: + - tq,tqma3359-mba335x # MBa335x carrier board + - const: tq,tqma3359 + - const: ti,am33xx + - description: TI OMAP4430 SoC based platforms items: - enum: diff --git a/Documentation/devicetree/bindings/arm/ux500.yaml b/Documentation/devicetree/bindings/arm/ux500.yaml index b42d20fa43596..3a8611e5786e5 100644 --- a/Documentation/devicetree/bindings/arm/ux500.yaml +++ b/Documentation/devicetree/bindings/arm/ux500.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Ux500 platforms maintainers: - - Linus Walleij + - Linus Walleij properties: $nodename: diff --git a/Documentation/devicetree/bindings/ata/ata-generic.yaml b/Documentation/devicetree/bindings/ata/ata-generic.yaml index 0697927f3d7e6..9da341ea091e2 100644 --- a/Documentation/devicetree/bindings/ata/ata-generic.yaml +++ b/Documentation/devicetree/bindings/ata/ata-generic.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Generic Parallel ATA Controller maintainers: - - Linus Walleij + - Linus Walleij description: Generic Parallel ATA controllers supporting PIO modes only. diff --git a/Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.yaml b/Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.yaml index 5290936665084..66de6d4769c12 100644 --- a/Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.yaml +++ b/Documentation/devicetree/bindings/ata/cortina,gemini-sata-bridge.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Cortina Systems Gemini SATA Bridge maintainers: - - Linus Walleij + - Linus Walleij description: | The Gemini SATA bridge in a SoC-internal PATA to SATA bridge that diff --git a/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml b/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml new file mode 100644 index 0000000000000..6554e30018b3c --- /dev/null +++ b/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ata/eswin,eic7700-ahci.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Eswin EIC7700 SoC SATA Controller + +maintainers: + - Yulin Lu + - Huan He + +description: + AHCI SATA controller embedded into the EIC7700 SoC is based on the DWC AHCI + SATA v5.00a IP core. + +select: + properties: + compatible: + const: eswin,eic7700-ahci + required: + - compatible + +allOf: + - $ref: snps,dwc-ahci-common.yaml# + +properties: + compatible: + items: + - const: eswin,eic7700-ahci + - const: snps,dwc-ahci + + clocks: + minItems: 2 + maxItems: 2 + + clock-names: + items: + - const: pclk + - const: aclk + + resets: + maxItems: 1 + + reset-names: + const: arst + + ports-implemented: + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - resets + - reset-names + - phys + - phy-names + - ports-implemented + +unevaluatedProperties: false + +examples: + - | + sata@50420000 { + compatible = "eswin,eic7700-ahci", "snps,dwc-ahci"; + reg = <0x50420000 0x10000>; + interrupt-parent = <&plic>; + interrupts = <58>; + clocks = <&clock 171>, <&clock 186>; + clock-names = "pclk", "aclk"; + phys = <&sata_phy>; + phy-names = "sata-phy"; + ports-implemented = <0x1>; + resets = <&reset 96>; + reset-names = "arst"; + }; diff --git a/Documentation/devicetree/bindings/ata/faraday,ftide010.yaml b/Documentation/devicetree/bindings/ata/faraday,ftide010.yaml index fa16f3767c6a5..32e11d8a0a3b0 100644 --- a/Documentation/devicetree/bindings/ata/faraday,ftide010.yaml +++ b/Documentation/devicetree/bindings/ata/faraday,ftide010.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Faraday Technology FTIDE010 PATA controller maintainers: - - Linus Walleij + - Linus Walleij description: | This controller is the first Faraday IDE interface block, used in the diff --git a/Documentation/devicetree/bindings/ata/intel,ixp4xx-compact-flash.yaml b/Documentation/devicetree/bindings/ata/intel,ixp4xx-compact-flash.yaml index 378692010c561..894a8b9eb910b 100644 --- a/Documentation/devicetree/bindings/ata/intel,ixp4xx-compact-flash.yaml +++ b/Documentation/devicetree/bindings/ata/intel,ixp4xx-compact-flash.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Intel IXP4xx CompactFlash Card Controller maintainers: - - Linus Walleij + - Linus Walleij description: | The IXP4xx network processors have a CompactFlash interface that presents diff --git a/Documentation/devicetree/bindings/ata/pata-common.yaml b/Documentation/devicetree/bindings/ata/pata-common.yaml index 4e867dd4d402b..cee4bb7eb0b9c 100644 --- a/Documentation/devicetree/bindings/ata/pata-common.yaml +++ b/Documentation/devicetree/bindings/ata/pata-common.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Common Properties for Parallel AT attachment (PATA) controllers maintainers: - - Linus Walleij + - Linus Walleij description: | This document defines device tree properties common to most Parallel diff --git a/Documentation/devicetree/bindings/ata/sata-common.yaml b/Documentation/devicetree/bindings/ata/sata-common.yaml index 58c9342b99255..667f48c331959 100644 --- a/Documentation/devicetree/bindings/ata/sata-common.yaml +++ b/Documentation/devicetree/bindings/ata/sata-common.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Common Properties for Serial AT attachment (SATA) controllers maintainers: - - Linus Walleij + - Linus Walleij description: | This document defines device tree properties common to most Serial diff --git a/Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml b/Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml index 4c848fcb5a5d2..7707cbed22600 100644 --- a/Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml +++ b/Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml @@ -33,6 +33,10 @@ properties: - description: SPEAr1340 AHCI SATA device const: snps,spear-ahci + iommus: + minItems: 1 + maxItems: 3 + patternProperties: "^sata-port@[0-9a-e]$": $ref: /schemas/ata/snps,dwc-ahci-common.yaml#/$defs/dwc-ahci-port diff --git a/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml b/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml index 439f7b811a94a..51d68a778b5cb 100644 --- a/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml +++ b/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM Versatile Character LCD maintainers: - - Linus Walleij + - Linus Walleij - Rob Herring description: diff --git a/Documentation/devicetree/bindings/board/fsl,fpga-qixis-i2c.yaml b/Documentation/devicetree/bindings/board/fsl,fpga-qixis-i2c.yaml index 28b37772fb656..e889dac052e76 100644 --- a/Documentation/devicetree/bindings/board/fsl,fpga-qixis-i2c.yaml +++ b/Documentation/devicetree/bindings/board/fsl,fpga-qixis-i2c.yaml @@ -22,6 +22,13 @@ properties: - fsl,lx2160aqds-fpga - const: fsl,fpga-qixis-i2c - const: simple-mfd + - const: fsl,lx2160ardb-fpga + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 interrupts: maxItems: 1 @@ -32,10 +39,37 @@ properties: mux-controller: $ref: /schemas/mux/reg-mux.yaml +patternProperties: + "^gpio@[0-9a-f]+$": + type: object + additionalProperties: true + + properties: + compatible: + contains: + enum: + - fsl,lx2160ardb-fpga-gpio-sfp + required: - compatible - reg +allOf: + - if: + properties: + compatible: + contains: + enum: + - fsl,lx2160ardb-fpga + then: + required: + - "#address-cells" + - "#size-cells" + else: + properties: + "#address-cells": false + "#size-cells": false + additionalProperties: false examples: @@ -68,3 +102,27 @@ examples: }; }; + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + board-control@66 { + compatible = "fsl,lx2160ardb-fpga"; + reg = <0x66>; + #address-cells = <1>; + #size-cells = <0>; + + gpio@19 { + compatible = "fsl,lx2160ardb-fpga-gpio-sfp"; + reg = <0x19>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "SFP2_TX_EN", "", + "", "", + "SFP2_RX_LOS", "SFP2_TX_FAULT", + "", "SFP2_MOD_ABS"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/board/fsl,fpga-qixis.yaml b/Documentation/devicetree/bindings/board/fsl,fpga-qixis.yaml index 5a3cd431ef6e6..2eacb581b9fdd 100644 --- a/Documentation/devicetree/bindings/board/fsl,fpga-qixis.yaml +++ b/Documentation/devicetree/bindings/board/fsl,fpga-qixis.yaml @@ -57,6 +57,16 @@ patternProperties: '^mdio-mux@[a-f0-9,]+$': $ref: /schemas/net/mdio-mux-mmioreg.yaml + '^gpio@[0-9a-f]+$': + type: object + additionalProperties: true + + properties: + compatible: + contains: + enum: + - fsl,ls1046aqds-fpga-gpio-stat-pres2 + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml b/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml index 24c939f590910..cd5c2a532a922 100644 --- a/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml +++ b/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml @@ -43,7 +43,7 @@ properties: maximum: 20000000 patternProperties: - "^.*@[0-9a-fA-F]+$": + "@[0-9a-f]+$": type: object additionalProperties: true properties: diff --git a/Documentation/devicetree/bindings/bus/cznic,moxtet.yaml b/Documentation/devicetree/bindings/bus/cznic,moxtet.yaml new file mode 100644 index 0000000000000..d340899ca5f12 --- /dev/null +++ b/Documentation/devicetree/bindings/bus/cznic,moxtet.yaml @@ -0,0 +1,94 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/bus/cznic,moxtet.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Turris Moxtet SPI bus + +maintainers: + - Marek Behún + +description: > + Turris Mox module status and configuration bus (over SPI) + + The driver finds the devices connected to the bus by itself, but it may be + needed to reference some of them from other parts of the device tree. In that + case the devices can be defined as subnodes of the moxtet node. + +properties: + compatible: + const: cznic,moxtet + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + spi-cpol: true + + spi-cpha: true + + spi-max-frequency: true + + interrupt-controller: true + + "#interrupt-cells": + const: 1 + + interrupts: + maxItems: 1 + + reset-gpios: + maxItems: 1 + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + - spi-cpol + - spi-cpha + - interrupts + - interrupt-controller + - "#interrupt-cells" + +additionalProperties: + type: object + + required: + - reg + +examples: + - | + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + moxtet@1 { + compatible = "cznic,moxtet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + spi-max-frequency = <10000000>; + spi-cpol; + spi-cpha; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&gpiosb>; + interrupts = <5 IRQ_TYPE_EDGE_FALLING>; + + gpio@0 { + compatible = "cznic,moxtet-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/bus/fsl,imx8qxp-pixel-link-msi-bus.yaml b/Documentation/devicetree/bindings/bus/fsl,imx8qxp-pixel-link-msi-bus.yaml index 4adbb7afa889d..6645352c7f6b4 100644 --- a/Documentation/devicetree/bindings/bus/fsl,imx8qxp-pixel-link-msi-bus.yaml +++ b/Documentation/devicetree/bindings/bus/fsl,imx8qxp-pixel-link-msi-bus.yaml @@ -70,7 +70,7 @@ properties: - const: ahb patternProperties: - "^.*@[0-9a-f]+$": + "@[0-9a-f]+$": description: Devices attached to the bus type: object diff --git a/Documentation/devicetree/bindings/bus/moxtet.txt b/Documentation/devicetree/bindings/bus/moxtet.txt deleted file mode 100644 index fb50fc8653368..0000000000000 --- a/Documentation/devicetree/bindings/bus/moxtet.txt +++ /dev/null @@ -1,46 +0,0 @@ -Turris Mox module status and configuration bus (over SPI) - -Required properties: - - compatible : Should be "cznic,moxtet" - - #address-cells : Has to be 1 - - #size-cells : Has to be 0 - - spi-cpol : Required inverted clock polarity - - spi-cpha : Required shifted clock phase - - interrupts : Must contain reference to the shared interrupt line - - interrupt-controller : Required - - #interrupt-cells : Has to be 1 - -For other required and optional properties of SPI slave nodes please refer to -../spi/spi-bus.txt. - -Required properties of subnodes: - - reg : Should be position on the Moxtet bus (how many Moxtet - modules are between this module and CPU module, so - either 0 or a positive integer) - -The driver finds the devices connected to the bus by itself, but it may be -needed to reference some of them from other parts of the device tree. In that -case the devices can be defined as subnodes of the moxtet node. - -Example: - - moxtet@1 { - compatible = "cznic,moxtet"; - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - spi-max-frequency = <10000000>; - spi-cpol; - spi-cpha; - interrupt-controller; - #interrupt-cells = <1>; - interrupt-parent = <&gpiosb>; - interrupts = <5 IRQ_TYPE_EDGE_FALLING>; - - moxtet_sfp: gpio@0 { - compatible = "cznic,moxtet-gpio"; - gpio-controller; - #gpio-cells = <2>; - reg = <0>; - } - }; diff --git a/Documentation/devicetree/bindings/bus/st,stm32-etzpc.yaml b/Documentation/devicetree/bindings/bus/st,stm32-etzpc.yaml index d12b62a3a5a88..bf0af3424c9af 100644 --- a/Documentation/devicetree/bindings/bus/st,stm32-etzpc.yaml +++ b/Documentation/devicetree/bindings/bus/st,stm32-etzpc.yaml @@ -44,7 +44,7 @@ properties: Contains the firewall ID associated to the peripheral. patternProperties: - "^.*@[0-9a-f]+$": + "@[0-9a-f]+$": description: Peripherals type: object diff --git a/Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml b/Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml index 20acd1a6b1736..4d19917ad2c30 100644 --- a/Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml +++ b/Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml @@ -33,14 +33,18 @@ select: properties: compatible: contains: - const: st,stm32mp25-rifsc + enum: + - st,stm32mp21-rifsc + - st,stm32mp25-rifsc required: - compatible properties: compatible: items: - - const: st,stm32mp25-rifsc + - enum: + - st,stm32mp21-rifsc + - st,stm32mp25-rifsc - const: simple-bus reg: @@ -60,7 +64,7 @@ properties: Contains the firewall ID associated to the peripheral. patternProperties: - "^.*@[0-9a-f]+$": + "@[0-9a-f]+$": description: Peripherals type: object diff --git a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml index 37e3ebd554874..a620a2ff5c568 100644 --- a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml +++ b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml @@ -21,6 +21,7 @@ properties: compatible: enum: - qcom,ipq5424-llcc + - qcom,kaanapali-llcc - qcom,qcs615-llcc - qcom,qcs8300-llcc - qcom,qdu1000-llcc @@ -272,6 +273,7 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-llcc - qcom,sm8450-llcc - qcom,sm8550-llcc - qcom,sm8650-llcc diff --git a/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml b/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml index 579bacb66f348..c0e5ebb1fa4c7 100644 --- a/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml +++ b/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml @@ -48,6 +48,11 @@ properties: - const: microchip,mpfs-ccache - const: sifive,fu540-c000-ccache - const: cache + - items: + - const: microchip,pic64gx-ccache + - const: microchip,mpfs-ccache + - const: sifive,fu540-c000-ccache + - const: cache cache-block-size: const: 64 diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml index fe2c5c1baf433..a8471367175b1 100644 --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml @@ -64,8 +64,6 @@ allOf: reg: minItems: 2 - '#reset-cells': false - - if: properties: compatible: @@ -85,6 +83,7 @@ examples: reg = <0x1fa20000 0x400>, <0x1fb00000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; - | diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-gates-clk.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-gates-clk.yaml index c4714d0fbe077..e588a7e8f260e 100644 --- a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-gates-clk.yaml +++ b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-gates-clk.yaml @@ -132,7 +132,6 @@ examples: "ahb_mp", "ahb_mali400"; }; - - | clk@1c20068 { #clock-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt deleted file mode 100644 index 4c0807f28cfaa..0000000000000 --- a/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt +++ /dev/null @@ -1,29 +0,0 @@ -* Xtal Clock bindings for Marvell Armada 37xx SoCs - -Marvell Armada 37xx SoCs allow to determine the xtal clock frequencies by -reading the gpio latch register. - -This node must be a subnode of the node exposing the register address -of the GPIO block where the gpio latch is located. -See Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt - -Required properties: -- compatible : shall be one of the following: - "marvell,armada-3700-xtal-clock" -- #clock-cells : from common clock binding; shall be set to 0 - -Optional properties: -- clock-output-names : from common clock binding; allows overwrite default clock - output names ("xtal") - -Example: -pinctrl_nb: pinctrl-nb@13800 { - compatible = "armada3710-nb-pinctrl", "syscon", "simple-mfd"; - reg = <0x13800 0x100>, <0x13C00 0x20>; - - xtalclk: xtal-clk { - compatible = "marvell,armada-3700-xtal-clock"; - clock-output-names = "xtal"; - #clock-cells = <0>; - }; -}; diff --git a/Documentation/devicetree/bindings/clock/fsl,imx8ulp-sim-lpav.yaml b/Documentation/devicetree/bindings/clock/fsl,imx8ulp-sim-lpav.yaml new file mode 100644 index 0000000000000..662e07528d768 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/fsl,imx8ulp-sim-lpav.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/fsl,imx8ulp-sim-lpav.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP i.MX8ULP LPAV System Integration Module (SIM) + +maintainers: + - Laurentiu Mihalcea + +description: + The i.MX8ULP LPAV subsystem contains a block control module known as + SIM LPAV, which offers functionalities such as clock gating or reset + line assertion/de-assertion. + +properties: + compatible: + const: fsl,imx8ulp-sim-lpav + + reg: + maxItems: 1 + + clocks: + maxItems: 3 + + clock-names: + items: + - const: bus + - const: core + - const: plat + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + + mux-controller: + $ref: /schemas/mux/reg-mux.yaml# + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + - mux-controller + +additionalProperties: false + +examples: + - | + #include + + clock-controller@2da50000 { + compatible = "fsl,imx8ulp-sim-lpav"; + reg = <0x2da50000 0x10000>; + clocks = <&cgc2 IMX8ULP_CLK_LPAV_BUS_DIV>, + <&cgc2 IMX8ULP_CLK_HIFI_DIVCORE>, + <&cgc2 IMX8ULP_CLK_HIFI_DIVPLAT>; + clock-names = "bus", "core", "plat"; + #clock-cells = <1>; + #reset-cells = <1>; + + mux-controller { + compatible = "reg-mux"; + #mux-control-cells = <1>; + mux-reg-masks = <0x8 0x00000200>; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml b/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml index caf442ead24bd..31e106ef913de 100644 --- a/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml +++ b/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml @@ -46,6 +46,9 @@ properties: "#clock-cells": const: 1 + power-domains: + maxItems: 1 + reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/clock/marvell,ap80x-clock.yaml b/Documentation/devicetree/bindings/clock/marvell,ap80x-clock.yaml new file mode 100644 index 0000000000000..43b0631ba167d --- /dev/null +++ b/Documentation/devicetree/bindings/clock/marvell,ap80x-clock.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/marvell,ap80x-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Marvell Armada AP80x System Controller Clocks + +maintainers: + - Gregory Clement + - Miquel Raynal + +description: > + The AP806/AP807 is one of the two core HW blocks of the Marvell Armada + 7K/8K/931x SoCs. It contains system controllers, which provide several + registers giving access to numerous features: clocks, pin-muxing and many + other SoC configuration items. + +properties: + compatible: + enum: + - marvell,ap806-clock + - marvell,ap806-cpu-clock + - marvell,ap807-clock + - marvell,ap807-cpu-clock + + reg: + maxItems: 1 + + "#clock-cells": + const: 1 + + clocks: + items: + - description: cluster 0 parent clock phandle + - description: cluster 1 parent clock phandle + +required: + - compatible + - "#clock-cells" + +additionalProperties: false + +allOf: + - if: + properties: + compatible: + contains: + enum: + - marvell,ap806-cpu-clock + - marvell,ap807-cpu-clock + then: + required: + - clocks diff --git a/Documentation/devicetree/bindings/clock/marvell,cp110-clock.yaml b/Documentation/devicetree/bindings/clock/marvell,cp110-clock.yaml new file mode 100644 index 0000000000000..ad0bc79b24c6e --- /dev/null +++ b/Documentation/devicetree/bindings/clock/marvell,cp110-clock.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/marvell,cp110-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Marvell Armada CP110 System Controller Clocks + +maintainers: + - Gregory Clement + - Miquel Raynal + +description: > + The CP110 is one of the two core HW blocks of the Marvell Armada 7K/8K/931x + SoCs. It contains system controllers, which provide several registers giving + access to numerous features: clocks, pin-muxing and many other SoC + configuration items. + +properties: + compatible: + const: marvell,cp110-clock + + "#clock-cells": + const: 2 + description: > + The first cell must be 0 or 1. 0 for the core clocks and 1 for the + gateable clocks. The second cell identifies the particular core clock or + gateable clocks. + + The following clocks are available: + + - Core clocks + - 0 0 APLL + - 0 1 PPv2 core + - 0 2 EIP + - 0 3 Core + - 0 4 NAND core + - 0 5 SDIO core + + - Gateable clocks + - 1 0 Audio + - 1 1 Comm Unit + - 1 2 NAND + - 1 3 PPv2 + - 1 4 SDIO + - 1 5 MG Domain + - 1 6 MG Core + - 1 7 XOR1 + - 1 8 XOR0 + - 1 9 GOP DP + - 1 11 PCIe x1 0 + - 1 12 PCIe x1 1 + - 1 13 PCIe x4 + - 1 14 PCIe / XOR + - 1 15 SATA + - 1 16 SATA USB + - 1 17 Main + - 1 18 SD/MMC/GOP + - 1 21 Slow IO (SPI, NOR, BootROM, I2C, UART) + - 1 22 USB3H0 + - 1 23 USB3H1 + - 1 24 USB3 Device + - 1 25 EIP150 + - 1 26 EIP197 + +required: + - compatible + - "#clock-cells" + +additionalProperties: false diff --git a/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml b/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml index e4e1c31267d2a..ee4f31596d978 100644 --- a/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml +++ b/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml @@ -22,16 +22,23 @@ properties: const: microchip,mpfs-clkcfg reg: - items: - - description: | - clock config registers: - These registers contain enable, reset & divider tables for the, cpu, - axi, ahb and rtc/mtimer reference clocks as well as enable and reset - for the peripheral clocks. - - description: | - mss pll dri registers: - Block of registers responsible for dynamic reconfiguration of the mss - pll + oneOf: + - items: + - description: | + clock config registers: + These registers contain enable, reset & divider tables for the, cpu, + axi, ahb and rtc/mtimer reference clocks as well as enable and reset + for the peripheral clocks. + - description: | + mss pll dri registers: + Block of registers responsible for dynamic reconfiguration of the mss + pll + deprecated: true + - items: + - description: | + mss pll dri registers: + Block of registers responsible for dynamic reconfiguration of the mss + pll clocks: maxItems: 1 @@ -69,11 +76,12 @@ examples: - | #include soc { - #address-cells = <2>; - #size-cells = <2>; - clkcfg: clock-controller@20002000 { + #address-cells = <1>; + #size-cells = <1>; + + clkcfg: clock-controller@3E001000 { compatible = "microchip,mpfs-clkcfg"; - reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>; + reg = <0x3E001000 0x1000>; clocks = <&ref>; #clock-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.yaml b/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.yaml index a9ba21144a568..13bb616249a16 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.yaml +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.yaml @@ -37,7 +37,7 @@ properties: '#clock-cells': const: 1 - "#reset-cells": + '#reset-cells': const: 1 nvidia,external-memory-controller: @@ -46,7 +46,7 @@ properties: phandle of the external memory controller node patternProperties: - "^emc-timings-[0-9]+$": + '^emc-timings-[0-9]+$': type: object properties: nvidia,ram-code: @@ -56,7 +56,7 @@ patternProperties: this timing set is used for patternProperties: - "^timing-[0-9]+$": + '^timing-[0-9]+$': type: object properties: clock-frequency: @@ -94,7 +94,7 @@ required: - compatible - reg - '#clock-cells' - - "#reset-cells" + - '#reset-cells' additionalProperties: false diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml index bee2dd4b29bfe..73cccc0df424d 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml @@ -39,11 +39,11 @@ properties: '#clock-cells': const: 1 - "#reset-cells": + '#reset-cells': const: 1 patternProperties: - "^(sclk)|(pll-[cem])$": + '^(sclk)|(pll-[cem])$': type: object properties: compatible: @@ -76,7 +76,7 @@ required: - compatible - reg - '#clock-cells' - - "#reset-cells" + - '#reset-cells' additionalProperties: false diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq9574-nsscc.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq9574-nsscc.yaml index 17252b6ea3bec..7ff4ff3587cad 100644 --- a/Documentation/devicetree/bindings/clock/qcom,ipq9574-nsscc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-nsscc.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/clock/qcom,ipq9574-nsscc.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Qualcomm Networking Sub System Clock & Reset Controller on IPQ9574 +title: Qualcomm Networking Sub System Clock & Reset Controller on IPQ9574 and IPQ5424 maintainers: - Bjorn Andersson @@ -12,21 +12,29 @@ maintainers: description: | Qualcomm networking sub system clock control module provides the clocks, - resets on IPQ9574 + resets on IPQ9574 and IPQ5424 - See also:: + See also: + include/dt-bindings/clock/qcom,ipq5424-nsscc.h include/dt-bindings/clock/qcom,ipq9574-nsscc.h + include/dt-bindings/reset/qcom,ipq5424-nsscc.h include/dt-bindings/reset/qcom,ipq9574-nsscc.h properties: compatible: - const: qcom,ipq9574-nsscc + enum: + - qcom,ipq5424-nsscc + - qcom,ipq9574-nsscc clocks: items: - description: Board XO source - - description: CMN_PLL NSS 1200MHz (Bias PLL cc) clock source - - description: CMN_PLL PPE 353MHz (Bias PLL ubi nc) clock source + - description: CMN_PLL NSS (Bias PLL cc) clock source. This clock rate + can vary for different IPQ SoCs. For example, it is 1200 MHz on the + IPQ9574 and 300 MHz on the IPQ5424. + - description: CMN_PLL PPE (Bias PLL ubi nc) clock source. The clock + rate can vary for different IPQ SoCs. For example, it is 353 MHz + on the IPQ9574 and 375 MHz on the IPQ5424. - description: GCC GPLL0 OUT AUX clock source - description: Uniphy0 NSS Rx clock source - description: Uniphy0 NSS Tx clock source @@ -42,8 +50,12 @@ properties: clock-names: items: - const: xo - - const: nss_1200 - - const: ppe_353 + - enum: + - nss_1200 + - nss + - enum: + - ppe_353 + - ppe - const: gpll0_out - const: uniphy0_rx - const: uniphy0_tx @@ -60,6 +72,40 @@ required: allOf: - $ref: qcom,gcc.yaml# + - if: + properties: + compatible: + const: qcom,ipq9574-nsscc + then: + properties: + clock-names: + items: + - const: xo + - const: nss_1200 + - const: ppe_353 + - const: gpll0_out + - const: uniphy0_rx + - const: uniphy0_tx + - const: uniphy1_rx + - const: uniphy1_tx + - const: uniphy2_rx + - const: uniphy2_tx + - const: bus + else: + properties: + clock-names: + items: + - const: xo + - const: nss + - const: ppe + - const: gpll0_out + - const: uniphy0_rx + - const: uniphy0_tx + - const: uniphy1_rx + - const: uniphy1_tx + - const: uniphy2_rx + - const: uniphy2_tx + - const: bus unevaluatedProperties: false @@ -94,5 +140,6 @@ examples: "bus"; #clock-cells = <1>; #reset-cells = <1>; + #interconnect-cells = <1>; }; ... diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml index 90cd3feab5fa0..ab97d4b7dba8b 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml @@ -8,7 +8,7 @@ title: Qualcomm RPM Clock Controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: | The clock enumerators are defined in and diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml index 78fa057266857..3f5f1336262ee 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml @@ -18,6 +18,7 @@ properties: compatible: enum: - qcom,glymur-rpmh-clk + - qcom,kaanapali-rpmh-clk - qcom,milos-rpmh-clk - qcom,qcs615-rpmh-clk - qcom,qdu1000-rpmh-clk diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml index fcd2727dae467..b31bd83355293 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Video Clock & Reset Controller on SM8450 maintainers: - - Taniya Das + - Taniya Das - Jagadeesh Kona description: | @@ -17,6 +17,7 @@ description: | See also: include/dt-bindings/clock/qcom,sm8450-videocc.h include/dt-bindings/clock/qcom,sm8650-videocc.h + include/dt-bindings/clock/qcom,sm8750-videocc.h properties: compatible: @@ -25,6 +26,7 @@ properties: - qcom,sm8475-videocc - qcom,sm8550-videocc - qcom,sm8650-videocc + - qcom,sm8750-videocc - qcom,x1e80100-videocc clocks: @@ -61,6 +63,7 @@ allOf: enum: - qcom,sm8450-videocc - qcom,sm8550-videocc + - qcom,sm8750-videocc then: required: - required-opps diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml index 2c992b3437f29..784fef8306812 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml @@ -25,6 +25,7 @@ properties: items: - enum: - qcom,glymur-tcsr + - qcom,kaanapali-tcsr - qcom,milos-tcsr - qcom,sar2130p-tcsr - qcom,sm8550-tcsr diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml index aab7039fd28db..0114d347b26ff 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml @@ -13,11 +13,15 @@ description: | Qualcomm global clock control module provides the clocks, resets and power domains on SM8750 - See also: include/dt-bindings/clock/qcom,sm8750-gcc.h + See also: + include/dt-bindings/clock/qcom,kaanapali-gcc.h + include/dt-bindings/clock/qcom,sm8750-gcc.h properties: compatible: - const: qcom,sm8750-gcc + enum: + - qcom,kaanapali-gcc + - qcom,sm8750-gcc clocks: items: diff --git a/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml index 68dde0720c711..1b15b50709545 100644 --- a/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml @@ -32,9 +32,36 @@ properties: - description: PCIe 5 pipe clock - description: PCIe 6a pipe clock - description: PCIe 6b pipe clock - - description: USB QMP Phy 0 clock source - - description: USB QMP Phy 1 clock source - - description: USB QMP Phy 2 clock source + - description: USB4_0 QMPPHY clock source + - description: USB4_1 QMPPHY clock source + - description: USB4_2 QMPPHY clock source + - description: USB4_0 PHY DP0 GMUX clock source + - description: USB4_0 PHY DP1 GMUX clock source + - description: USB4_0 PHY PCIE PIPEGMUX clock source + - description: USB4_0 PHY PIPEGMUX clock source + - description: USB4_0 PHY SYS PCIE PIPEGMUX clock source + - description: USB4_1 PHY DP0 GMUX 2 clock source + - description: USB4_1 PHY DP1 GMUX 2 clock source + - description: USB4_1 PHY PCIE PIPEGMUX clock source + - description: USB4_1 PHY PIPEGMUX clock source + - description: USB4_1 PHY SYS PCIE PIPEGMUX clock source + - description: USB4_2 PHY DP0 GMUX 2 clock source + - description: USB4_2 PHY DP1 GMUX 2 clock source + - description: USB4_2 PHY PCIE PIPEGMUX clock source + - description: USB4_2 PHY PIPEGMUX clock source + - description: USB4_2 PHY SYS PCIE PIPEGMUX clock source + - description: USB4_0 PHY RX 0 clock source + - description: USB4_0 PHY RX 1 clock source + - description: USB4_1 PHY RX 0 clock source + - description: USB4_1 PHY RX 1 clock source + - description: USB4_2 PHY RX 0 clock source + - description: USB4_2 PHY RX 1 clock source + - description: USB4_0 PHY PCIE PIPE clock source + - description: USB4_0 PHY max PIPE clock source + - description: USB4_1 PHY PCIE PIPE clock source + - description: USB4_1 PHY max PIPE clock source + - description: USB4_2 PHY PCIE PIPE clock source + - description: USB4_2 PHY max PIPE clock source power-domains: description: @@ -67,7 +94,34 @@ examples: <&pcie6b_phy>, <&usb_1_ss0_qmpphy 0>, <&usb_1_ss1_qmpphy 1>, - <&usb_1_ss2_qmpphy 2>; + <&usb_1_ss2_qmpphy 2>, + <&usb4_0_phy_dp0_gmux_clk>, + <&usb4_0_phy_dp1_gmux_clk>, + <&usb4_0_phy_pcie_pipegmux_clk>, + <&usb4_0_phy_pipegmux_clk>, + <&usb4_0_phy_sys_pcie_pipegmux_clk>, + <&usb4_1_phy_dp0_gmux_2_clk>, + <&usb4_1_phy_dp1_gmux_2_clk>, + <&usb4_1_phy_pcie_pipegmux_clk>, + <&usb4_1_phy_pipegmux_clk>, + <&usb4_1_phy_sys_pcie_pipegmux_clk>, + <&usb4_2_phy_dp0_gmux_2_clk>, + <&usb4_2_phy_dp1_gmux_2_clk>, + <&usb4_2_phy_pcie_pipegmux_clk>, + <&usb4_2_phy_pipegmux_clk>, + <&usb4_2_phy_sys_pcie_pipegmux_clk>, + <&usb4_0_phy_rx_0_clk>, + <&usb4_0_phy_rx_1_clk>, + <&usb4_1_phy_rx_0_clk>, + <&usb4_1_phy_rx_1_clk>, + <&usb4_2_phy_rx_0_clk>, + <&usb4_2_phy_rx_1_clk>, + <&usb4_0_phy_pcie_pipe_clk>, + <&usb4_0_phy_max_pipe_clk>, + <&usb4_1_phy_pcie_pipe_clk>, + <&usb4_1_phy_max_pipe_clk>, + <&usb4_2_phy_pcie_pipe_clk>, + <&usb4_2_phy_max_pipe_clk>; power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml index bc2fd3761328c..655154534c0f1 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml @@ -99,7 +99,6 @@ properties: the datasheet. const: 1 - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml new file mode 100644 index 0000000000000..ca940475336ce --- /dev/null +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip RK3506 Clock and Reset Unit (CRU) + +maintainers: + - Finley Xiao + - Heiko Stuebner + +description: + The RK3506 CRU generates the clock and also implements reset for SoC + peripherals. + +properties: + compatible: + const: rockchip,rk3506-cru + + reg: + maxItems: 1 + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + + clocks: + maxItems: 1 + + clock-names: + const: xin + +required: + - compatible + - reg + - "#clock-cells" + - "#reset-cells" + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + clock-controller@ff9a0000 { + compatible = "rockchip,rk3506-cru"; + reg = <0xff9a0000 0x20000>; + #clock-cells = <1>; + #reset-cells = <1>; + clocks = <&xin24m>; + clock-names = "xin"; + }; diff --git a/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml new file mode 100644 index 0000000000000..04b0a5c51e4e0 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/rockchip,rv1126b-cru.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip RV1126B Clock and Reset Unit + +maintainers: + - Elaine Zhang + - Heiko Stuebner + +description: + The rv1126b clock controller generates the clock and also implements a + reset controller for SoC peripherals. + +properties: + compatible: + enum: + - rockchip,rv1126b-cru + + reg: + maxItems: 1 + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + + clocks: + maxItems: 1 + + clock-names: + const: xin24m + +required: + - compatible + - reg + - "#clock-cells" + - "#reset-cells" + +additionalProperties: false + +examples: + - | + clock-controller@20000000 { + compatible = "rockchip,rv1126b-cru"; + reg = <0x20000000 0xc0000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml index 72f59db73f76c..5bf905f88a1ac 100644 --- a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml +++ b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml @@ -38,6 +38,8 @@ properties: - samsung,exynosautov920-cmu-hsi0 - samsung,exynosautov920-cmu-hsi1 - samsung,exynosautov920-cmu-hsi2 + - samsung,exynosautov920-cmu-m2m + - samsung,exynosautov920-cmu-mfc - samsung,exynosautov920-cmu-misc - samsung,exynosautov920-cmu-peric0 - samsung,exynosautov920-cmu-peric1 @@ -226,6 +228,46 @@ allOf: - const: embd - const: ethernet + - if: + properties: + compatible: + contains: + const: samsung,exynosautov920-cmu-m2m + + then: + properties: + clocks: + items: + - description: External reference clock (38.4 MHz) + - description: CMU_M2M NOC clock (from CMU_TOP) + - description: CMU_M2M JPEG clock (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: noc + - const: jpeg + + - if: + properties: + compatible: + contains: + const: samsung,exynosautov920-cmu-mfc + + then: + properties: + clocks: + items: + - description: External reference clock (38.4 MHz) + - description: CMU_MFC MFC clock (from CMU_TOP) + - description: CMU_MFC WFD clock (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: mfc + - const: wfd + required: - compatible - "#clock-cells" diff --git a/Documentation/devicetree/bindings/clock/sprd,sc9860-clk.yaml b/Documentation/devicetree/bindings/clock/sprd,sc9860-clk.yaml index 502cd723511fa..b131390207d6d 100644 --- a/Documentation/devicetree/bindings/clock/sprd,sc9860-clk.yaml +++ b/Documentation/devicetree/bindings/clock/sprd,sc9860-clk.yaml @@ -114,25 +114,6 @@ allOf: - reg properties: sprd,syscon: false - - if: - properties: - compatible: - contains: - enum: - - sprd,sc9860-agcp-gate - - sprd,sc9860-aon-gate - - sprd,sc9860-apahb-gate - - sprd,sc9860-apapb-gate - - sprd,sc9860-cam-gate - - sprd,sc9860-disp-gate - - sprd,sc9860-pll - - sprd,sc9860-pmu-gate - - sprd,sc9860-vsp-gate - then: - required: - - sprd,syscon - properties: - reg: false additionalProperties: false @@ -142,13 +123,6 @@ examples: #address-cells = <2>; #size-cells = <2>; - pmu-gate { - compatible = "sprd,sc9860-pmu-gate"; - clocks = <&ext_26m>; - #clock-cells = <1>; - sprd,syscon = <&pmu_regs>; - }; - clock-controller@20000000 { compatible = "sprd,sc9860-ap-clk"; reg = <0 0x20000000 0 0x400>; diff --git a/Documentation/devicetree/bindings/clock/stericsson,u8500-clks.yaml b/Documentation/devicetree/bindings/clock/stericsson,u8500-clks.yaml index 2150307219a0c..4ebfa5a8d5242 100644 --- a/Documentation/devicetree/bindings/clock/stericsson,u8500-clks.yaml +++ b/Documentation/devicetree/bindings/clock/stericsson,u8500-clks.yaml @@ -8,7 +8,7 @@ title: ST-Ericsson DB8500 (U8500) clocks maintainers: - Ulf Hansson - - Linus Walleij + - Linus Walleij description: While named "U8500 clocks" these clocks are inside the DB8500 digital baseband system-on-chip and its siblings such as diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml index b44a76a958f4e..b497c28e8094f 100644 --- a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml +++ b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml @@ -22,7 +22,6 @@ properties: - xlnx,clocking-wizard-v6.0 - xlnx,versal-clk-wizard - reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/crypto/intel,ixp4xx-crypto.yaml b/Documentation/devicetree/bindings/crypto/intel,ixp4xx-crypto.yaml index a4006237aa89f..fd20b8197207a 100644 --- a/Documentation/devicetree/bindings/crypto/intel,ixp4xx-crypto.yaml +++ b/Documentation/devicetree/bindings/crypto/intel,ixp4xx-crypto.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Intel IXP4xx cryptographic engine maintainers: - - Linus Walleij + - Linus Walleij description: | The Intel IXP4xx cryptographic engine makes use of the IXP4xx NPE diff --git a/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml b/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml index e3379d1067283..ea1dc86bc31f6 100644 --- a/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml +++ b/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml @@ -19,11 +19,14 @@ description: | properties: compatible: - enum: - - nvidia,tegra30-actmon - - nvidia,tegra114-actmon - - nvidia,tegra124-actmon - - nvidia,tegra210-actmon + oneOf: + - enum: + - nvidia,tegra30-actmon + - nvidia,tegra114-actmon + - nvidia,tegra124-actmon + - items: + - const: nvidia,tegra210-actmon + - const: nvidia,tegra124-actmon reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-frontend.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-frontend.yaml index 98e8240a05bd9..995b3ef408b79 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-frontend.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-display-frontend.yaml @@ -121,5 +121,4 @@ examples: }; }; - ... diff --git a/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-drc.yaml b/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-drc.yaml index 895506d93f4cf..85a6086cc10e6 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-drc.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-drc.yaml @@ -121,5 +121,4 @@ examples: }; }; - ... diff --git a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml index 60fd927b5a066..c43b02ec884fe 100644 --- a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml @@ -142,7 +142,6 @@ then: reset-names: minItems: 2 - additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml index cb0a90f023219..3ae45db85ea79 100644 --- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml +++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml @@ -25,7 +25,6 @@ description: | M |-------|______|----|____________| |________________| | | ___|__________________________________________________________|_______________| - VIU: Video Input Unit --------------------- diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml index 6d11f5955b51a..c1cefd547391b 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml @@ -56,22 +56,12 @@ properties: - const: cec interrupts: - items: - - description: CEC TX interrupt - - description: CEC RX interrupt - - description: CEC stuck at low interrupt - - description: Wake-up interrupt - - description: Hotplug connected interrupt - - description: Hotplug removed interrupt + minItems: 5 + maxItems: 6 interrupt-names: - items: - - const: cec-tx - - const: cec-rx - - const: cec-low - - const: wakeup - - const: hpd-connected - - const: hpd-removed + minItems: 5 + maxItems: 6 ddc: $ref: /schemas/types.yaml#/definitions/phandle @@ -112,6 +102,61 @@ required: additionalProperties: false +allOf: + - if: + properties: + compatible: + contains: + enum: + - brcm,bcm2711-hdmi0 + - brcm,bcm2711-hdmi1 + then: + properties: + interrupts: + items: + - description: CEC TX interrupt + - description: CEC RX interrupt + - description: CEC stuck at low interrupt + - description: Wake-up interrupt + - description: Hotplug connected interrupt + - description: Hotplug removed interrupt + interrupt-names: + items: + - const: cec-tx + - const: cec-rx + - const: cec-low + - const: wakeup + - const: hpd-connected + - const: hpd-removed + + - if: + properties: + compatible: + contains: + enum: + - brcm,bcm2712-hdmi0 + - brcm,bcm2712-hdmi1 + then: + properties: + interrupts: + items: + - description: CEC TX interrupt + - description: CEC RX interrupt + - description: CEC stuck at low interrupt + - description: Hotplug connected interrupt + - description: Hotplug removed interrupt + interrupts-names: + items: + - const: cec-tx + - const: cec-rx + - const: cec-low + - const: hpd-connected + - const: hpd-removed + + required: + - interrupts + - interrupt-names + examples: - | hdmi0: hdmi@7ef00700 { @@ -136,6 +181,9 @@ examples: "hd"; clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>; clock-names = "hdmi", "bvb", "audio", "cec"; + interrupts = <0>, <1>, <2>, <3>, <4>, <5>; + interrupt-names = "cec-tx", "cec-rx", "cec-low", "wakeup", + "hpd-connected", "hpd-removed"; resets = <&dvp 0>; ddc = <&ddc0>; }; diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml index f91c9dce2a44d..9aca38a58a162 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml @@ -20,11 +20,20 @@ properties: maxItems: 1 interrupts: - maxItems: 1 + minItems: 1 + maxItems: 3 + + interrupt-names: + minItems: 1 + maxItems: 3 clocks: - maxItems: 1 - description: Core Clock + minItems: 1 + maxItems: 2 + + clock-names: + minItems: 1 + maxItems: 2 required: - compatible @@ -33,17 +42,68 @@ required: additionalProperties: false -if: - properties: - compatible: - contains: - enum: - - brcm,bcm2711-hvs - - brcm,bcm2712-hvs - -then: - required: - - clocks +allOf: + - if: + properties: + compatible: + contains: + const: brcm,bcm2711-hvs + + then: + properties: + clocks: + items: + - description: Core Clock + interrupts: + maxItems: 1 + clock-names: false + interrupt-names: false + + required: + - clocks + + - if: + properties: + compatible: + contains: + const: brcm,bcm2712-hvs + + then: + properties: + clocks: + minItems: 2 + maxItems: 2 + clock-names: + items: + - const: core + - const: disp + interrupts: + items: + - description: Channel 0 End of frame + - description: Channel 1 End of frame + - description: Channel 2 End of frame + interrupt-names: + items: + - const: ch0-eof + - const: ch1-eof + - const: ch2-eof + required: + - clocks + - clock-names + - interrupt-names + + - if: + properties: + compatible: + contains: + const: brcm,bcm2835-hvs + + then: + properties: + interrupts: + maxItems: 1 + clock-names: false + interrupt-names: false examples: - | diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml index 5bbe81862c8f9..d29a0d06187e8 100644 --- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml +++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml @@ -156,7 +156,6 @@ else: adi,input-style: false adi,input-justification: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml index 05442d4377552..6211ab8bbb0e5 100644 --- a/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml +++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml @@ -49,6 +49,10 @@ properties: $ref: /schemas/graph.yaml#/properties/port description: HDMI output port + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: Parallel audio input port + required: - port@0 - port@1 @@ -98,5 +102,13 @@ examples: remote-endpoint = <&hdmi0_con>; }; }; + + port@2 { + reg = <2>; + + endpoint { + remote-endpoint = <&pai_to_hdmi_tx>; + }; + }; }; }; diff --git a/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml b/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml index ba644c30dcf41..17d1f97ce8c28 100644 --- a/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml +++ b/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml @@ -19,6 +19,7 @@ properties: compatible: enum: - ite,it66121 + - ite,it66122 - ite,it6610 reg: diff --git a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml index 0487bbffd7f7c..4f7d3e9cf0c22 100644 --- a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml +++ b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml @@ -131,7 +131,6 @@ required: additionalProperties: false - examples: - | lvds-encoder { diff --git a/Documentation/devicetree/bindings/display/bridge/parade,ps8622.yaml b/Documentation/devicetree/bindings/display/bridge/parade,ps8622.yaml index e6397ac2048b1..235018a81e85d 100644 --- a/Documentation/devicetree/bindings/display/bridge/parade,ps8622.yaml +++ b/Documentation/devicetree/bindings/display/bridge/parade,ps8622.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Parade PS8622/PS8625 DisplayPort to LVDS Converter maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski properties: compatible: diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,dsi-csi2-tx.yaml b/Documentation/devicetree/bindings/display/bridge/renesas,dsi-csi2-tx.yaml index c167795c63f64..b95f10edd3a29 100644 --- a/Documentation/devicetree/bindings/display/bridge/renesas,dsi-csi2-tx.yaml +++ b/Documentation/devicetree/bindings/display/bridge/renesas,dsi-csi2-tx.yaml @@ -14,6 +14,9 @@ description: | R-Car Gen4 SoCs. The encoder can operate in either DSI or CSI-2 mode, with up to four data lanes. +allOf: + - $ref: /schemas/display/dsi-controller.yaml# + properties: compatible: enum: @@ -80,14 +83,14 @@ required: - resets - ports -additionalProperties: false +unevaluatedProperties: false examples: - | #include #include - dsi0: dsi-encoder@fed80000 { + dsi@fed80000 { compatible = "renesas,r8a779a0-dsi-csi2-tx"; reg = <0xfed80000 0x10000>; power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>; @@ -117,4 +120,51 @@ examples: }; }; }; + + - | + #include + #include + + dsi@fed80000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,r8a779g0-dsi-csi2-tx"; + reg = <0xfed80000 0x10000>; + clocks = <&cpg CPG_MOD 415>, + <&cpg CPG_CORE R8A779G0_CLK_DSIEXT>, + <&cpg CPG_CORE R8A779G0_CLK_DSIREF>; + clock-names = "fck", "dsi", "pll"; + power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; + resets = <&cpg 415>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + }; + + port@1 { + reg = <1>; + + dsi0port1_out: endpoint { + remote-endpoint = <&panel_in>; + data-lanes = <1 2>; + }; + }; + }; + + panel@0 { + reg = <0>; + compatible = "raspberrypi,dsi-7inch", "ilitek,ili9881c"; + power-supply = <&vcc_lcd_reg>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi0port1_out>; + }; + }; + }; + }; ... diff --git a/Documentation/devicetree/bindings/display/bridge/sil,sii8620.yaml b/Documentation/devicetree/bindings/display/bridge/sil,sii8620.yaml index 6d1a36b76fcb2..a5fe46de3535e 100644 --- a/Documentation/devicetree/bindings/display/bridge/sil,sii8620.yaml +++ b/Documentation/devicetree/bindings/display/bridge/sil,sii8620.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Silicon Image SiI8620 HDMI/MHL bridge maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski properties: compatible: diff --git a/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml b/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml index 9ef587d465060..20c7e0a77802f 100644 --- a/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml +++ b/Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml @@ -27,7 +27,9 @@ properties: - const: adi,adv7123 - enum: - adi,adv7123 + - asl-tek,cs5263 - dumb-vga-dac + - parade,ps185hdm - radxa,ra620 - realtek,rtd2171 - ti,opa362 diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml index b78f64c9c5f44..70f229dc4e0c4 100644 --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml @@ -123,7 +123,6 @@ properties: - required: - port@1 - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/dsi-controller.yaml b/Documentation/devicetree/bindings/display/dsi-controller.yaml index bb4d6e9e7d0ca..850b86fe03ccb 100644 --- a/Documentation/devicetree/bindings/display/dsi-controller.yaml +++ b/Documentation/devicetree/bindings/display/dsi-controller.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Common Properties for DSI Display Panels maintainers: - - Linus Walleij + - Linus Walleij description: | This document defines device tree properties common to DSI, Display diff --git a/Documentation/devicetree/bindings/display/faraday,tve200.yaml b/Documentation/devicetree/bindings/display/faraday,tve200.yaml index e2ee777673211..b09628b69177c 100644 --- a/Documentation/devicetree/bindings/display/faraday,tve200.yaml +++ b/Documentation/devicetree/bindings/display/faraday,tve200.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Faraday TV Encoder TVE200 maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/display/ilitek,ili9486.yaml b/Documentation/devicetree/bindings/display/ilitek,ili9486.yaml index 9cc1fd0751cdb..7d78edc403dce 100644 --- a/Documentation/devicetree/bindings/display/ilitek,ili9486.yaml +++ b/Documentation/devicetree/bindings/display/ilitek,ili9486.yaml @@ -54,7 +54,6 @@ examples: #address-cells = <1>; #size-cells = <0>; - display@0{ compatible = "waveshare,rpi-lcd-35", "ilitek,ili9486"; reg = <0>; diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pai.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pai.yaml new file mode 100644 index 0000000000000..4f99682a308db --- /dev/null +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pai.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/imx/fsl,imx8mp-hdmi-pai.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale i.MX8MP HDMI Parallel Audio Interface + +maintainers: + - Shengjiu Wang + +description: + The HDMI TX Parallel Audio Interface (HTX_PAI) is a bridge between the + Audio Subsystem to the HDMI TX Controller. + +properties: + compatible: + const: fsl,imx8mp-hdmi-pai + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: apb + + power-domains: + maxItems: 1 + + port: + $ref: /schemas/graph.yaml#/properties/port + description: Output to the HDMI TX controller. + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - power-domains + - port + +additionalProperties: false + +examples: + - | + #include + #include + + audio-bridge@32fc4800 { + compatible = "fsl,imx8mp-hdmi-pai"; + reg = <0x32fc4800 0x800>; + interrupt-parent = <&irqsteer_hdmi>; + interrupts = <14>; + clocks = <&clk IMX8MP_CLK_HDMI_APB>; + clock-names = "apb"; + power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PAI>; + + port { + pai_to_hdmi_tx: endpoint { + remote-endpoint = <&hdmi_tx_from_pai>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml index aeb4e4f36044a..ebda78db87a68 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -18,6 +18,7 @@ properties: compatible: oneOf: - enum: + - qcom,glymur-dp - qcom,sa8775p-dp - qcom,sc7180-dp - qcom,sc7280-dp @@ -31,6 +32,11 @@ properties: - qcom,sm8650-dp - qcom,x1e80100-dp + - items: + - enum: + - qcom,qcs8300-dp + - const: qcom,sa8775p-dp + - items: - enum: - qcom,sm6350-dp @@ -53,6 +59,12 @@ properties: - qcom,sm8550-dp - const: qcom,sm8350-dp + - items: + - enum: + - qcom,sm6150-dp + - const: qcom,sm8150-dp + - const: qcom,sm8350-dp + - items: - enum: - qcom,sm8750-dp @@ -195,9 +207,11 @@ allOf: compatible: contains: enum: + - qcom,glymur-dp - qcom,sa8775p-dp - qcom,x1e80100-dp then: + $ref: /schemas/sound/dai-common.yaml# oneOf: - required: - aux-bus @@ -239,6 +253,7 @@ allOf: enum: # these platforms support 2 streams MST on some interfaces, # others are SST only + - qcom,glymur-dp - qcom,sc8280xp-dp - qcom,x1e80100-dp then: @@ -295,7 +310,7 @@ allOf: minItems: 6 maxItems: 8 -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml b/Documentation/devicetree/bindings/display/msm/gmu.yaml index afc1879357440..e32056ae0f5d3 100644 --- a/Documentation/devicetree/bindings/display/msm/gmu.yaml +++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml @@ -21,7 +21,7 @@ properties: compatible: oneOf: - items: - - pattern: '^qcom,adreno-gmu-[67][0-9][0-9]\.[0-9]$' + - pattern: '^qcom,adreno-gmu-[6-8][0-9][0-9]\.[0-9]$' - const: qcom,adreno-gmu - items: - pattern: '^qcom,adreno-gmu-x[1-9][0-9][0-9]\.[0-9]$' @@ -299,6 +299,64 @@ allOf: required: - qcom,qmp + - if: + properties: + compatible: + contains: + const: qcom,adreno-gmu-840.1 + then: + properties: + reg: + items: + - description: Core GMU registers + reg-names: + items: + - const: gmu + clocks: + items: + - description: GPU AHB clock + - description: GMU clock + - description: GPU CX clock + - description: GPU MEMNOC clock + - description: GMU HUB clock + clock-names: + items: + - const: ahb + - const: gmu + - const: cxo + - const: memnoc + - const: hub + + - if: + properties: + compatible: + contains: + const: qcom,adreno-gmu-x285.1 + then: + properties: + reg: + items: + - description: Core GMU registers + reg-names: + items: + - const: gmu + clocks: + items: + - description: GPU AHB clock + - description: GMU clock + - description: GPU CX clock + - description: GPU MEMNOC clock + - description: GMU HUB clock + - description: GMU RSCC HUB clock + clock-names: + items: + - const: ahb + - const: gmu + - const: cxo + - const: memnoc + - const: hub + - const: rscc + - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml b/Documentation/devicetree/bindings/display/msm/gpu.yaml index 3696b083e3530..826aafdcc20be 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml @@ -133,7 +133,6 @@ properties: For GMU attached devices a phandle to the GMU device that will control the power for the GPU. - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/display/msm/qcom,glymur-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,glymur-mdss.yaml new file mode 100644 index 0000000000000..2329ed96e6cb3 --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/qcom,glymur-mdss.yaml @@ -0,0 +1,264 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/msm/qcom,glymur-mdss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Glymur Display MDSS + +maintainers: + - Abel Vesa + +description: + Glymur MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like + DPU display controller, DP interfaces, etc. + +$ref: /schemas/display/msm/mdss-common.yaml# + +properties: + compatible: + const: qcom,glymur-mdss + + clocks: + items: + - description: Display AHB + - description: Display hf AXI + - description: Display core + + iommus: + maxItems: 1 + + interconnects: + items: + - description: Interconnect path from mdp0 port to the data bus + - description: Interconnect path from CPU to the reg bus + + interconnect-names: + items: + - const: mdp0-mem + - const: cpu-cfg + +patternProperties: + "^display-controller@[0-9a-f]+$": + type: object + additionalProperties: true + properties: + compatible: + const: qcom,glymur-dpu + + "^displayport-controller@[0-9a-f]+$": + type: object + additionalProperties: true + properties: + compatible: + const: qcom,glymur-dp + + "^phy@[0-9a-f]+$": + type: object + additionalProperties: true + properties: + compatible: + const: qcom,glymur-dp-phy + +required: + - compatible + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + #include + #include + #include + + display-subsystem@ae00000 { + compatible = "qcom,glymur-mdss"; + reg = <0x0ae00000 0x1000>; + reg-names = "mdss"; + + interrupts = ; + + clocks = <&dispcc_ahb_clk>, + <&gcc_disp_hf_axi_clk>, + <&dispcc_mdp_clk>; + clock-names = "bus", "nrt_bus", "core"; + + interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "mdp0-mem", + "cpu-cfg"; + + resets = <&disp_cc_mdss_core_bcr>; + + power-domains = <&mdss_gdsc>; + + iommus = <&apps_smmu 0x1c00 0x2>; + + interrupt-controller; + #interrupt-cells = <1>; + + #address-cells = <1>; + #size-cells = <1>; + ranges; + + display-controller@ae01000 { + compatible = "qcom,glymur-dpu"; + reg = <0x0ae01000 0x8f000>, + <0x0aeb0000 0x2008>; + reg-names = "mdp", "vbif"; + + clocks = <&gcc_axi_clk>, + <&dispcc_ahb_clk>, + <&dispcc_mdp_lut_clk>, + <&dispcc_mdp_clk>, + <&dispcc_mdp_vsync_clk>; + clock-names = "nrt_bus", + "iface", + "lut", + "core", + "vsync"; + + assigned-clocks = <&dispcc_mdp_vsync_clk>; + assigned-clock-rates = <19200000>; + + operating-points-v2 = <&mdp_opp_table>; + power-domains = <&rpmhpd RPMHPD_MMCX>; + + interrupt-parent = <&mdss>; + interrupts = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dpu_intf1_out: endpoint { + remote-endpoint = <&dsi0_in>; + }; + }; + + port@1 { + reg = <1>; + dpu_intf2_out: endpoint { + remote-endpoint = <&dsi1_in>; + }; + }; + }; + + mdp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-325000000 { + opp-hz = /bits/ 64 <325000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-375000000 { + opp-hz = /bits/ 64 <375000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-514000000 { + opp-hz = /bits/ 64 <514000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + displayport-controller@ae90000 { + compatible = "qcom,glymur-dp"; + reg = <0xae90000 0x200>, + <0xae90200 0x200>, + <0xae90400 0x600>, + <0xae91000 0x400>, + <0xae91400 0x400>; + + interrupt-parent = <&mdss>; + interrupts = <12>; + + clocks = <&dispcc_mdss_ahb_clk>, + <&dispcc_dptx0_aux_clk>, + <&dispcc_dptx0_link_clk>, + <&dispcc_dptx0_link_intf_clk>, + <&dispcc_dptx0_pixel0_clk>, + <&dispcc_dptx0_pixel1_clk>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel", + "stream_1_pixel"; + + assigned-clocks = <&dispcc_mdss_dptx0_link_clk_src>, + <&dispcc_mdss_dptx0_pixel0_clk_src>, + <&dispcc_mdss_dptx0_pixel1_clk_src>; + assigned-clock-parents = <&usb_1_ss0_qmpphy QMP_USB43DP_DP_LINK_CLK>, + <&usb_1_ss0_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>, + <&usb_1_ss0_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>; + + operating-points-v2 = <&mdss_dp0_opp_table>; + + power-domains = <&rpmhpd RPMHPD_MMCX>; + + phys = <&usb_1_ss0_qmpphy QMP_USB43DP_DP_PHY>; + phy-names = "dp"; + + #sound-dai-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss_dp0_in: endpoint { + remote-endpoint = <&mdss_intf0_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dp0_out: endpoint { + }; + }; + }; + + mdss_dp0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-160000000 { + opp-hz = /bits/ 64 <160000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-270000000 { + opp-hz = /bits/ 64 <270000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-810000000 { + opp-hz = /bits/ 64 <810000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/msm/qcom,qcs8300-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,qcs8300-mdss.yaml new file mode 100644 index 0000000000000..e96baaae9ba9e --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/qcom,qcs8300-mdss.yaml @@ -0,0 +1,286 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/msm/qcom,qcs8300-mdss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. QCS8300 Display MDSS + +maintainers: + - Yongxing Mou + +description: + QCS8300 MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like + DPU display controller, DP interfaces and EDP etc. + +$ref: /schemas/display/msm/mdss-common.yaml# + +properties: + compatible: + const: qcom,qcs8300-mdss + + clocks: + items: + - description: Display AHB + - description: Display hf AXI + - description: Display core + + iommus: + maxItems: 1 + + interconnects: + maxItems: 3 + + interconnect-names: + maxItems: 3 + +patternProperties: + "^display-controller@[0-9a-f]+$": + type: object + additionalProperties: true + + properties: + compatible: + contains: + const: qcom,qcs8300-dpu + + "^displayport-controller@[0-9a-f]+$": + type: object + additionalProperties: true + + properties: + compatible: + contains: + const: qcom,qcs8300-dp + + "^phy@[0-9a-f]+$": + type: object + additionalProperties: true + properties: + compatible: + contains: + const: qcom,qcs8300-edp-phy + +required: + - compatible + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + #include + #include + #include + #include + + mdss: display-subsystem@ae00000 { + compatible = "qcom,qcs8300-mdss"; + reg = <0x0ae00000 0x1000>; + reg-names = "mdss"; + + interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&mmss_noc MASTER_MDP1 QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "mdp0-mem", + "mdp1-mem", + "cpu-cfg"; + + resets = <&dispcc_core_bcr>; + power-domains = <&dispcc_gdsc>; + + clocks = <&dispcc_ahb_clk>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc_mdp_clk>; + + interrupts = ; + interrupt-controller; + #interrupt-cells = <1>; + + iommus = <&apps_smmu 0x1000 0x402>; + + #address-cells = <1>; + #size-cells = <1>; + ranges; + + display-controller@ae01000 { + compatible = "qcom,qcs8300-dpu", "qcom,sa8775p-dpu"; + reg = <0x0ae01000 0x8f000>, + <0x0aeb0000 0x2008>; + reg-names = "mdp", "vbif"; + + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_MDP_LUT_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_MDP_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "nrt_bus", + "iface", + "lut", + "core", + "vsync"; + + assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_VSYNC_CLK>; + assigned-clock-rates = <19200000>; + operating-points-v2 = <&mdp_opp_table>; + power-domains = <&rpmhpd RPMHPD_MMCX>; + + interrupt-parent = <&mdss>; + interrupts = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + + dpu_intf0_out: endpoint { + remote-endpoint = <&mdss_dp0_in>; + }; + }; + }; + + mdp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-375000000 { + opp-hz = /bits/ 64 <375000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-575000000 { + opp-hz = /bits/ 64 <575000000>; + required-opps = <&rpmhpd_opp_turbo>; + }; + + opp-650000000 { + opp-hz = /bits/ 64 <650000000>; + required-opps = <&rpmhpd_opp_turbo_l1>; + }; + }; + }; + + mdss_dp0_phy: phy@aec2a00 { + compatible = "qcom,qcs8300-edp-phy", "qcom,sa8775p-edp-phy"; + + reg = <0x0aec2a00 0x200>, + <0x0aec2200 0xd0>, + <0x0aec2600 0xd0>, + <0x0aec2000 0x1c8>; + + clocks = <&dispcc MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>, + <&dispcc MDSS_DISP_CC_MDSS_AHB_CLK>; + clock-names = "aux", + "cfg_ahb"; + + #clock-cells = <1>; + #phy-cells = <0>; + + vdda-phy-supply = <&vreg_l1c>; + vdda-pll-supply = <&vreg_l4a>; + }; + + displayport-controller@af54000 { + compatible = "qcom,qcs8300-dp", "qcom,sa8775p-dp"; + + pinctrl-0 = <&dp_hot_plug_det>; + pinctrl-names = "default"; + + reg = <0xaf54000 0x104>, + <0xaf54200 0x0c0>, + <0xaf55000 0x770>, + <0xaf56000 0x09c>, + <0xaf57000 0x09c>, + <0xaf58000 0x09c>, + <0xaf59000 0x09c>, + <0xaf5a000 0x23c>, + <0xaf5b000 0x23c>; + + interrupt-parent = <&mdss>; + interrupts = <12>; + clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_LINK_INTF_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel", + "stream_1_pixel", + "stream_2_pixel", + "stream_3_pixel"; + assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK_SRC>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK_SRC>, + <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK_SRC>; + assigned-clock-parents = <&mdss_dp0_phy 0>, + <&mdss_dp0_phy 1>, + <&mdss_dp0_phy 1>, + <&mdss_dp0_phy 1>; + phys = <&mdss_dp0_phy>; + phy-names = "dp"; + operating-points-v2 = <&dp_opp_table>; + power-domains = <&rpmhpd RPMHPD_MMCX>; + + #sound-dai-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss_dp0_in: endpoint { + remote-endpoint = <&dpu_intf0_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dp_out: endpoint { }; + }; + }; + + dp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-160000000 { + opp-hz = /bits/ 64 <160000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-270000000 { + opp-hz = /bits/ 64 <270000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-540000000 { + opp-hz = /bits/ 64 <540000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-810000000 { + opp-hz = /bits/ 64 <810000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm6150-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm6150-mdss.yaml index 9ac24f99d3ada..46e9335f849fe 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm6150-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm6150-mdss.yaml @@ -51,6 +51,14 @@ patternProperties: compatible: const: qcom,sm6150-dpu + "^displayport-controller@[0-9a-f]+$": + type: object + additionalProperties: true + properties: + compatible: + contains: + const: qcom,sm6150-dp + "^dsi@[0-9a-f]+$": type: object additionalProperties: true @@ -130,35 +138,37 @@ examples: #size-cells = <0>; port@0 { - reg = <0>; - dpu_intf0_out: endpoint { - }; + reg = <0>; + + dpu_intf0_out: endpoint { + }; }; port@1 { - reg = <1>; - dpu_intf1_out: endpoint { - remote-endpoint = <&mdss_dsi0_in>; - }; + reg = <1>; + + dpu_intf1_out: endpoint { + remote-endpoint = <&mdss_dsi0_in>; + }; }; }; mdp_opp_table: opp-table { compatible = "operating-points-v2"; - opp-19200000 { - opp-hz = /bits/ 64 <19200000>; - required-opps = <&rpmhpd_opp_low_svs>; + opp-192000000 { + opp-hz = /bits/ 64 <192000000>; + required-opps = <&rpmhpd_opp_low_svs>; }; - opp-25600000 { - opp-hz = /bits/ 64 <25600000>; - required-opps = <&rpmhpd_opp_svs>; + opp-256000000 { + opp-hz = /bits/ 64 <256000000>; + required-opps = <&rpmhpd_opp_svs>; }; opp-307200000 { - opp-hz = /bits/ 64 <307200000>; - required-opps = <&rpmhpd_opp_nom>; + opp-hz = /bits/ 64 <307200000>; + required-opps = <&rpmhpd_opp_nom>; }; }; }; diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml index 0a46120dd8680..fe296e3186d0e 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml @@ -13,11 +13,17 @@ $ref: /schemas/display/msm/dpu-common.yaml# properties: compatible: - enum: - - qcom,sa8775p-dpu - - qcom,sm8650-dpu - - qcom,sm8750-dpu - - qcom,x1e80100-dpu + oneOf: + - enum: + - qcom,glymur-dpu + - qcom,sa8775p-dpu + - qcom,sm8650-dpu + - qcom,sm8750-dpu + - qcom,x1e80100-dpu + - items: + - enum: + - qcom,qcs8300-dpu + - const: qcom,sa8775p-dpu reg: items: diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8750-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm8750-mdss.yaml index 4151f475f3bc3..d55fda9a523e2 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm8750-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8750-mdss.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm SM8750 Display MDSS maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: SM8650 MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like diff --git a/Documentation/devicetree/bindings/display/panel/arm,rtsm-display.yaml b/Documentation/devicetree/bindings/display/panel/arm,rtsm-display.yaml index 4ad484f09ba3a..fc04558fcc8dd 100644 --- a/Documentation/devicetree/bindings/display/panel/arm,rtsm-display.yaml +++ b/Documentation/devicetree/bindings/display/panel/arm,rtsm-display.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Arm RTSM Virtual Platforms Display maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: panel-common.yaml# diff --git a/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml b/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml index c9958f824d9ab..b6c18e7283cd9 100644 --- a/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml +++ b/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM Versatile TFT Panels maintainers: - - Linus Walleij + - Linus Walleij description: | These panels are connected to the daughterboards found on the diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,il79900a.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,il79900a.yaml new file mode 100644 index 0000000000000..02f7fb1f16dc7 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/ilitek,il79900a.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/ilitek,il79900a.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ilitek IL79900a based MIPI-DSI panels + +maintainers: + - Langyan Ye + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + items: + - enum: + - tianma,tl121bvms07-00 + - const: ilitek,il79900a + + reg: + maxItems: 1 + description: DSI virtual channel used by the panel + + enable-gpios: + maxItems: 1 + description: GPIO specifier for the enable pin + + avdd-supply: + description: Positive analog voltage supply (AVDD) + + avee-supply: + description: Negative analog voltage supply (AVEE) + + pp1800-supply: + description: 1.8V logic voltage supply + + backlight: true + +required: + - compatible + - reg + - enable-gpios + - avdd-supply + - avee-supply + - pp1800-supply + +additionalProperties: false + +examples: + - | + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "tianma,tl121bvms07-00", "ilitek,il79900a"; + reg = <0>; + enable-gpios = <&pio 25 0>; + avdd-supply = <®_avdd>; + avee-supply = <®_avee>; + pp1800-supply = <®_pp1800>; + backlight = <&backlight>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml index 44423465f6e35..4bdc33d12306b 100644 --- a/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml +++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Ilitek ILI9322 TFT panel driver with SPI control bus maintainers: - - Linus Walleij + - Linus Walleij description: | This is a driver for 320x240 TFT panels, accepting a variety of input diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml index 434cc6af9c954..d979701a00a8a 100644 --- a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml +++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml @@ -20,9 +20,11 @@ properties: - bananapi,lhr050h41 - bestar,bsd1218-a101kl68 - feixin,k101-im2byl02 + - raspberrypi,dsi-5inch - raspberrypi,dsi-7inch - startek,kd050hdfia020 - tdo,tl050hdv35 + - wanchanglong,w552946aaa - wanchanglong,w552946aba - const: ilitek,ili9881c @@ -30,6 +32,7 @@ properties: maxItems: 1 backlight: true + port: true power-supply: true reset-gpios: true rotation: true diff --git a/Documentation/devicetree/bindings/display/panel/lg,ld070wx3-sl01.yaml b/Documentation/devicetree/bindings/display/panel/lg,ld070wx3-sl01.yaml new file mode 100644 index 0000000000000..0f0b9079f199b --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/lg,ld070wx3-sl01.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/lg,ld070wx3-sl01.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: LG Corporation 7" WXGA TFT LCD panel + +maintainers: + - Svyatoslav Ryhel + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + items: + - const: lg,ld070wx3-sl01 + + reg: + maxItems: 1 + + vdd-supply: true + vcc-supply: true + + backlight: true + port: true + +required: + - compatible + - vdd-supply + - vcc-supply + +additionalProperties: false + +examples: + - | + #include + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "lg,ld070wx3-sl01"; + reg = <0>; + + vdd-supply = <&vdd_3v3_lcd>; + vcc-supply = <&vcc_1v8_lcd>; + + backlight = <&backlight>; + + port { + endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml index bb50fd5506c3d..b39fd0c5a48ad 100644 --- a/Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Novatek NT35510-based display panels maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: panel-common.yaml# diff --git a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml index 4388d5375851a..dbc01e6408958 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml @@ -59,6 +59,8 @@ properties: # Jenson Display BL-JT60050-01A 7" WSVGA (1024x600) color TFT LCD LVDS panel - jenson,bl-jt60050-01a - tbs,a711-panel + # Winstar WF70A8SYJHLNGA 7" WSVGA (1024x600) color TFT LCD LVDS panel + - winstar,wf70a8syjhlnga - const: panel-lvds diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml index 9b92a05791ccf..8d668979b62df 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml @@ -19,6 +19,9 @@ description: | If the panel is more advanced a dedicated binding file is required. +allOf: + - $ref: panel-common.yaml# + properties: compatible: @@ -42,8 +45,6 @@ properties: - kingdisplay,kd097d04 # LG ACX467AKM-7 4.95" 1080×1920 LCD Panel - lg,acx467akm-7 - # LG Corporation 7" WXGA TFT LCD panel - - lg,ld070wx3-sl01 # LG Corporation 5" HD TFT LCD panel - lg,lh500wx1-sd03 # Lincoln LCD197 5" 1080x1920 LCD panel @@ -56,10 +57,6 @@ properties: - panasonic,vvx10f034n00 # Samsung s6e3fa7 1080x2220 based AMS559NK06 AMOLED panel - samsung,s6e3fa7-ams559nk06 - # Samsung s6e3fc2x01 1080x2340 AMOLED panel - - samsung,s6e3fc2x01 - # Samsung sofef00 1080x2280 AMOLED panel - - samsung,sofef00 # Shangai Top Display Optoelectronics 7" TL070WSH30 1024x600 TFT LCD panel - tdo,tl070wsh30 @@ -72,31 +69,12 @@ properties: reset-gpios: true port: true power-supply: true - vddio-supply: true - -allOf: - - $ref: panel-common.yaml# - - if: - properties: - compatible: - enum: - - samsung,s6e3fc2x01 - - samsung,sofef00 - then: - properties: - power-supply: false - required: - - vddio-supply - else: - properties: - vddio-supply: false - required: - - power-supply additionalProperties: false required: - compatible + - power-supply - reg examples: diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 2017428d8828e..24e277b190941 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -184,6 +184,8 @@ properties: - innolux,n156bge-l21 # Innolux Corporation 7.0" WSVGA (1024x600) TFT LCD panel - innolux,zj070na-01p + # JuTouch Technology Co.. 10" JT101TM023 WXGA (1280 x 800) LVDS panel + - jutouch,jt101tm023 # Kaohsiung Opto-Electronics Inc. 5.7" QVGA (320 x 240) TFT LCD panel - koe,tx14d24vm1bpa # Kaohsiung Opto-Electronics. TX31D200VM0BAA 12.3" HSXGA LVDS panel @@ -268,6 +270,8 @@ properties: - qiaodian,qd43003c0-40 # Shenzhen QiShenglong Industrialist Co., Ltd. Gopher 2b 4.3" 480(RGB)x272 TFT LCD panel - qishenglong,gopher2b-lcd + # Raystar Optronics, Inc. RFF500F-AWH-DNN 5.0" TFT 840x480 + - raystar,rff500f-awh-dnn # Rocktech Displays Ltd. RK101II01D-CT 10.1" TFT 1280x800 - rocktech,rk101ii01d-ct # Rocktech Display Ltd. RK070ER9427 800(RGB)x480 TFT LCD panel @@ -276,6 +280,8 @@ properties: - rocktech,rk043fn48h # Samsung Electronics 10.1" WXGA (1280x800) TFT LCD panel - samsung,ltl101al01 + # Samsung Electronics 10.6" FWXGA (1366x768) TFT LCD panel + - samsung,ltl106al01 # Samsung Electronics 10.1" WSVGA TFT LCD panel - samsung,ltn101nt05 # Satoz SAT050AT40H12R2 5.0" WVGA TFT LCD panel diff --git a/Documentation/devicetree/bindings/display/panel/panel-timing.yaml b/Documentation/devicetree/bindings/display/panel/panel-timing.yaml index aea69b84ca5d8..8c97744587773 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-timing.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-timing.yaml @@ -41,7 +41,6 @@ description: | | | | v | | +-------+----------+-------------------------------------+----------+ - The following is the panel timings shown with time on the x-axis. This matches the timing diagrams often found in data sheets. diff --git a/Documentation/devicetree/bindings/display/panel/ronbo,rb070d30.yaml b/Documentation/devicetree/bindings/display/panel/ronbo,rb070d30.yaml index 04f86e0cbac91..6940373015833 100644 --- a/Documentation/devicetree/bindings/display/panel/ronbo,rb070d30.yaml +++ b/Documentation/devicetree/bindings/display/panel/ronbo,rb070d30.yaml @@ -9,6 +9,9 @@ title: Ronbo RB070D30 DSI Display Panel maintainers: - Maxime Ripard +allOf: + - $ref: panel-common.yaml# + properties: compatible: const: ronbo,rb070d30 @@ -20,10 +23,6 @@ properties: description: GPIO used for the power pin maxItems: 1 - reset-gpios: - description: GPIO used for the reset pin - maxItems: 1 - shlr-gpios: description: GPIO used for the shlr pin (horizontal flip) maxItems: 1 @@ -35,10 +34,6 @@ properties: vcc-lcd-supply: description: Power regulator - backlight: - description: Backlight used by the panel - $ref: /schemas/types.yaml#/definitions/phandle - required: - compatible - power-gpios @@ -47,5 +42,6 @@ required: - shlr-gpios - updn-gpios - vcc-lcd-supply + - port -additionalProperties: false +unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/display/panel/samsung,atna33xc20.yaml b/Documentation/devicetree/bindings/display/panel/samsung,atna33xc20.yaml index ccb574caed283..f1723e9102525 100644 --- a/Documentation/devicetree/bindings/display/panel/samsung,atna33xc20.yaml +++ b/Documentation/devicetree/bindings/display/panel/samsung,atna33xc20.yaml @@ -33,6 +33,8 @@ properties: - samsung,atna45dc02 # Samsung 15.6" 3K (2880x1620 pixels) eDP AMOLED panel - samsung,atna56ac03 + # Samsung 16.0" 3K (2880x1800 pixels) eDP AMOLED panel + - samsung,atna60cl08 - const: samsung,atna33xc20 enable-gpios: true diff --git a/Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml b/Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml index 7ce8540551f9e..74c2a617c2ff3 100644 --- a/Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml +++ b/Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml @@ -11,7 +11,7 @@ description: The LMS380KF01 is a 480x800 DPI display panel from Samsung Mobile used with internal or external backlight control. maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: panel-common.yaml# diff --git a/Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml b/Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml index 9363032883de4..4cecf502a1506 100644 --- a/Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml +++ b/Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml @@ -10,7 +10,7 @@ description: The datasheet claims this is based around a display controller named DB7430 with a separate backlight controller. maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: panel-common.yaml# diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.yaml b/Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.yaml index 2af5bc47323f5..0872476a8ac9a 100644 --- a/Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.yaml +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Samsung S6D16D0 4" 864x480 AMOLED panel maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: panel-common.yaml# diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e3fc2x01.yaml b/Documentation/devicetree/bindings/display/panel/samsung,s6e3fc2x01.yaml new file mode 100644 index 0000000000000..d48354fb52ea0 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e3fc2x01.yaml @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,s6e3fc2x01.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung S6E3FC2X01 AMOLED DDIC + +description: The S6E3FC2X01 is display driver IC with connected panel. + +maintainers: + - David Heidelberg + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + items: + - enum: + # Samsung 6.41 inch, 1080x2340 pixels, 19.5:9 ratio + - samsung,s6e3fc2x01-ams641rw + - const: samsung,s6e3fc2x01 + + reg: + maxItems: 1 + + reset-gpios: true + + port: true + + vddio-supply: + description: VDD regulator + + vci-supply: + description: VCI regulator + + poc-supply: + description: POC regulator + +required: + - compatible + - reset-gpios + - vddio-supply + - vci-supply + - poc-supply + +unevaluatedProperties: false + +examples: + - | + #include + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "samsung,s6e3fc2x01-ams641rw", "samsung,s6e3fc2x01"; + reg = <0>; + + vddio-supply = <&vreg_l14a_1p88>; + vci-supply = <&s2dos05_buck1>; + poc-supply = <&s2dos05_ldo1>; + + te-gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>; + reset-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&sde_dsi_active &sde_te_active_sleep>; + pinctrl-1 = <&sde_dsi_suspend &sde_te_active_sleep>; + pinctrl-names = "default", "sleep"; + + port { + panel_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/display/panel/samsung,sofef00.yaml b/Documentation/devicetree/bindings/display/panel/samsung,sofef00.yaml new file mode 100644 index 0000000000000..eeee3cac72e31 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,sofef00.yaml @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,sofef00.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung SOFEF00 AMOLED DDIC + +description: The SOFEF00 is display driver IC with connected panel. + +maintainers: + - David Heidelberg + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + items: + - enum: + # Samsung 6.01 inch, 1080x2160 pixels, 18:9 ratio + - samsung,sofef00-ams601nt22 + # Samsung 6.28 inch, 1080x2280 pixels, 19:9 ratio + - samsung,sofef00-ams628nw01 + - const: samsung,sofef00 + + reg: + maxItems: 1 + + poc-supply: + description: POC regulator + + vci-supply: + description: VCI regulator + + vddio-supply: + description: VDD regulator + +required: + - compatible + - reset-gpios + - poc-supply + - vci-supply + - vddio-supply + +unevaluatedProperties: false + +examples: + - | + #include + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "samsung,sofef00-ams628nw01", "samsung,sofef00"; + reg = <0>; + + vddio-supply = <&vreg_l14a_1p88>; + vci-supply = <&s2dos05_buck1>; + poc-supply = <&s2dos05_ldo1>; + + te-gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>; + reset-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&panel_active>; + pinctrl-1 = <&panel_suspend>; + pinctrl-names = "default", "sleep"; + + port { + panel_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/display/panel/sharp,lq079l1sx01.yaml b/Documentation/devicetree/bindings/display/panel/sharp,lq079l1sx01.yaml new file mode 100644 index 0000000000000..08a35ebbbb3cb --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/sharp,lq079l1sx01.yaml @@ -0,0 +1,99 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/sharp,lq079l1sx01.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sharp Microelectronics 7.9" WQXGA TFT LCD panel + +maintainers: + - Svyatoslav Ryhel + +description: > + This panel requires a dual-channel DSI host to operate and it supports + only left-right split mode, where each channel drives the left or right + half of the screen and only video mode. + + Each of the DSI channels controls a separate DSI peripheral. + The peripheral driven by the first link (DSI-LINK1), left one, is + considered the primary peripheral and controls the device. + +allOf: + - $ref: panel-common-dual.yaml# + +properties: + compatible: + const: sharp,lq079l1sx01 + + reg: + maxItems: 1 + + avdd-supply: + description: regulator that supplies the analog voltage + + vddio-supply: + description: regulator that supplies the I/O voltage + + vsp-supply: + description: positive boost supply regulator + + vsn-supply: + description: negative boost supply regulator + + reset-gpios: + maxItems: 1 + + backlight: true + ports: true + +required: + - compatible + - reg + - avdd-supply + - vddio-supply + - ports + +additionalProperties: false + +examples: + - | + #include + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "sharp,lq079l1sx01"; + reg = <0>; + + reset-gpios = <&gpio 59 GPIO_ACTIVE_LOW>; + + avdd-supply = <&avdd_lcd>; + vddio-supply = <&vdd_lcd_io>; + vsp-supply = <&vsp_5v5_lcd>; + vsn-supply = <&vsn_5v5_lcd>; + + backlight = <&backlight>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + panel_in0: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + panel_in1: endpoint { + remote-endpoint = <&dsi1_out>; + }; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml b/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml index fd778a20f7609..64fa086730b05 100644 --- a/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml +++ b/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml @@ -12,7 +12,7 @@ description: The Sony ACX424AKP and ACX424AKM are panels built around AKP. maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: panel-common.yaml# diff --git a/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml b/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml new file mode 100644 index 0000000000000..152d94367130e --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/synaptics,td4300-panel.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/synaptics,td4300-panel.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synaptics TDDI Display Panel Controller + +maintainers: + - Kaustabh Chakraborty + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + enum: + - syna,td4101-panel + - syna,td4300-panel + + reg: + maxItems: 1 + + vio-supply: + description: core I/O voltage supply + + vsn-supply: + description: negative voltage supply for analog circuits + + vsp-supply: + description: positive voltage supply for analog circuits + + backlight-gpios: + maxItems: 1 + description: backlight enable GPIO + + reset-gpios: true + width-mm: true + height-mm: true + panel-timing: true + +required: + - compatible + - reg + - width-mm + - height-mm + - panel-timing + +additionalProperties: false + +examples: + - | + #include + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "syna,td4300-panel"; + reg = <0>; + + vio-supply = <&panel_vio_reg>; + vsn-supply = <&panel_vsn_reg>; + vsp-supply = <&panel_vsp_reg>; + + backlight-gpios = <&gpd3 5 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpd3 4 GPIO_ACTIVE_LOW>; + + width-mm = <68>; + height-mm = <121>; + + panel-timing { + clock-frequency = <144389520>; + + hactive = <1080>; + hsync-len = <4>; + hfront-porch = <120>; + hback-porch = <32>; + + vactive = <1920>; + vsync-len = <2>; + vfront-porch = <21>; + vback-porch = <4>; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/display/panel/ti,nspire.yaml b/Documentation/devicetree/bindings/display/panel/ti,nspire.yaml index 5c5a3b519e314..fc722f706ad71 100644 --- a/Documentation/devicetree/bindings/display/panel/ti,nspire.yaml +++ b/Documentation/devicetree/bindings/display/panel/ti,nspire.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Texas Instruments NSPIRE Display Panels maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: panel-common.yaml# diff --git a/Documentation/devicetree/bindings/display/panel/tpo,tpg110.yaml b/Documentation/devicetree/bindings/display/panel/tpo,tpg110.yaml index 59a373728e628..e5f3108cde5a6 100644 --- a/Documentation/devicetree/bindings/display/panel/tpo,tpg110.yaml +++ b/Documentation/devicetree/bindings/display/panel/tpo,tpg110.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: TPO TPG110 Panel maintainers: - - Linus Walleij + - Linus Walleij - Thierry Reding description: |+ @@ -38,7 +38,6 @@ description: |+ The serial protocol has line names that resemble I2C but the protocol is not I2C but 3WIRE SPI. - allOf: - $ref: panel-common.yaml# - $ref: /schemas/spi/spi-peripheral-props.yaml# diff --git a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml index 1e32d14b6edb7..2cc66dcef870a 100644 --- a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml +++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml @@ -25,6 +25,9 @@ properties: - enum: - renesas,r9a07g054-du # RZ/V2L - const: renesas,r9a07g044-du # RZ/G2L fallback + - items: + - const: renesas,r9a09g056-du # RZ/V2N + - const: renesas,r9a09g057-du # RZ/V2H(P) fallback reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml index a8a0087179972..6345f0132d43d 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml @@ -125,7 +125,6 @@ examples: power-domains = <&power RK3588_PD_VO0>; #sound-dai-cells = <0>; - ports { #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml index c59df3c1a3f78..632b48bfabb94 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml @@ -17,6 +17,7 @@ properties: - rockchip,px30-mipi-dsi - rockchip,rk3128-mipi-dsi - rockchip,rk3288-mipi-dsi + - rockchip,rk3368-mipi-dsi - rockchip,rk3399-mipi-dsi - rockchip,rk3568-mipi-dsi - rockchip,rv1126-mipi-dsi @@ -73,6 +74,7 @@ allOf: enum: - rockchip,px30-mipi-dsi - rockchip,rk3128-mipi-dsi + - rockchip,rk3368-mipi-dsi - rockchip,rk3568-mipi-dsi - rockchip,rv1126-mipi-dsi diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml index 96b4b088eebee..d649808c59da8 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml @@ -113,6 +113,14 @@ properties: description: Additional HDMI QP related data is accessed through VO GRF regs. + frl-enable-gpios: + description: + Optional GPIO line to be asserted when operating in HDMI 2.1 FRL mode and + deasserted for HDMI 1.4/2.0 TMDS. It can be used to control external + voltage bias for HDMI data lines. When not present the HDMI encoder will + operate in TMDS mode only. + maxItems: 1 + required: - compatible - reg @@ -132,8 +140,10 @@ unevaluatedProperties: false examples: - | #include + #include #include #include + #include #include #include @@ -164,6 +174,7 @@ examples: rockchip,grf = <&sys_grf>; rockchip,vo-grf = <&vo1_grf>; #sound-dai-cells = <0>; + frl-enable-gpios = <&gpio4 RK_PB1 GPIO_ACTIVE_LOW>; ports { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/simple-framebuffer.yaml b/Documentation/devicetree/bindings/display/simple-framebuffer.yaml index 296500f9da05e..45ffdebc9d86b 100644 --- a/Documentation/devicetree/bindings/display/simple-framebuffer.yaml +++ b/Documentation/devicetree/bindings/display/simple-framebuffer.yaml @@ -181,7 +181,6 @@ allOf: required: - amlogic,pipeline - additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/display/ste,mcde.yaml b/Documentation/devicetree/bindings/display/ste,mcde.yaml index 564ea845c82e0..7a12d0b817e68 100644 --- a/Documentation/devicetree/bindings/display/ste,mcde.yaml +++ b/Documentation/devicetree/bindings/display/ste,mcde.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ST-Ericsson Multi Channel Display Engine MCDE maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-tsec.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-tsec.yaml new file mode 100644 index 0000000000000..2c4d519a1bb7a --- /dev/null +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra114-tsec.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra114-tsec.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVIDIA Tegra Security co-processor + +maintainers: + - Svyatoslav Ryhel + - Thierry Reding + +description: Tegra Security co-processor, an embedded security processor used + mainly to manage the HDCP encryption and keys on the HDMI link. + +properties: + compatible: + oneOf: + - enum: + - nvidia,tegra114-tsec + - nvidia,tegra124-tsec + - nvidia,tegra210-tsec + + - items: + - const: nvidia,tegra132-tsec + - const: nvidia,tegra124-tsec + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + iommus: + maxItems: 1 + + operating-points-v2: true + + power-domains: + maxItems: 1 + +additionalProperties: false + +required: + - compatible + - reg + - interrupts + - clocks + - resets + +examples: + - | + #include + #include + + tsec@54500000 { + compatible = "nvidia,tegra114-tsec"; + reg = <0x54500000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA114_CLK_TSEC>; + resets = <&tegra_car TEGRA114_CLK_TSEC>; + }; diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-csi.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-csi.yaml new file mode 100644 index 0000000000000..a1aea9590769f --- /dev/null +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-csi.yaml @@ -0,0 +1,138 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-csi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVIDIA Tegra20 CSI controller + +maintainers: + - Svyatoslav Ryhel + +properties: + compatible: + enum: + - nvidia,tegra20-csi + - nvidia,tegra30-csi + + reg: + maxItems: 1 + + clocks: + minItems: 1 + items: + - description: module clock + - description: PAD A clock + - description: PAD B clock + + clock-names: + items: + - const: csi + - const: csia-pad + - const: csib-pad + + avdd-dsi-csi-supply: + description: DSI/CSI power supply. Must supply 1.2 V. + + power-domains: + maxItems: 1 + + "#nvidia,mipi-calibrate-cells": + description: + The number of cells in a MIPI calibration specifier. Should be 1. + The single cell specifies an id of the pad that need to be + calibrated for a given device. Valid pad ids for receiver would be + 0 for CSI-A; 1 for CSI-B; 2 for DSI-A and 3 for DSI-B. + $ref: /schemas/types.yaml#/definitions/uint32 + const: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +patternProperties: + "^channel@[0-1]$": + type: object + description: channel 0 represents CSI-A and 1 represents CSI-B + additionalProperties: false + + properties: + reg: + maximum: 1 + + nvidia,mipi-calibrate: + description: Should contain a phandle and a specifier specifying + which pad is used by this CSI channel and needs to be calibrated. + $ref: /schemas/types.yaml#/definitions/phandle-array + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: port receiving the video stream from the sensor + + properties: + endpoint: + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + + required: + - data-lanes + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: port sending the video stream to the VI + + required: + - reg + - "#address-cells" + - "#size-cells" + - port@0 + - port@1 + +allOf: + - if: + properties: + compatible: + contains: + enum: + - nvidia,tegra20-csi + then: + properties: + clocks: + maxItems: 1 + + clock-names: false + + - if: + properties: + compatible: + contains: + enum: + - nvidia,tegra30-csi + then: + properties: + clocks: + minItems: 3 + + clock-names: + minItems: 3 + +additionalProperties: false + +required: + - compatible + - reg + - clocks + - power-domains + - "#address-cells" + - "#size-cells" + +# see nvidia,tegra20-vi.yaml for an example diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-epp.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-epp.yaml index 3c095a5491fec..334f5531b2433 100644 --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-epp.yaml +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-epp.yaml @@ -15,10 +15,16 @@ properties: pattern: "^epp@[0-9a-f]+$" compatible: - enum: - - nvidia,tegra20-epp - - nvidia,tegra30-epp - - nvidia,tegra114-epp + oneOf: + - enum: + - nvidia,tegra20-epp + - nvidia,tegra30-epp + - nvidia,tegra114-epp + - nvidia,tegra124-epp + + - items: + - const: nvidia,tegra132-epp + - const: nvidia,tegra124-epp reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-isp.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-isp.yaml index 3bc3b22e98e1d..ee25b5e6f1a24 100644 --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-isp.yaml +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-isp.yaml @@ -12,10 +12,17 @@ maintainers: properties: compatible: - enum: - - nvidia,tegra20-isp - - nvidia,tegra30-isp - - nvidia,tegra210-isp + oneOf: + - enum: + - nvidia,tegra20-isp + - nvidia,tegra30-isp + - nvidia,tegra114-isp + - nvidia,tegra124-isp + - nvidia,tegra210-isp + + - items: + - const: nvidia,tegra132-isp + - const: nvidia,tegra124-isp reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-mpe.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-mpe.yaml index 2cd3e60cd0a8b..36b76fa8f525b 100644 --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-mpe.yaml +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-mpe.yaml @@ -12,13 +12,21 @@ maintainers: properties: $nodename: - pattern: "^mpe@[0-9a-f]+$" + oneOf: + - pattern: "^mpe@[0-9a-f]+$" + - pattern: "^msenc@[0-9a-f]+$" compatible: - enum: - - nvidia,tegra20-mpe - - nvidia,tegra30-mpe - - nvidia,tegra114-mpe + oneOf: + - enum: + - nvidia,tegra20-mpe + - nvidia,tegra30-mpe + - nvidia,tegra114-msenc + - nvidia,tegra124-msenc + + - items: + - const: nvidia,tegra132-msenc + - const: nvidia,tegra124-msenc reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml index 361e9cae6896c..38fcee91211e8 100644 --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml @@ -84,8 +84,7 @@ properties: maxItems: 1 description: phandle to the associated power domain - dma-coherent: - type: boolean + dma-coherent: true ports: $ref: /schemas/graph.yaml#/properties/ports diff --git a/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml index fad7cba58d39a..65ae8a1c39986 100644 --- a/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml +++ b/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml @@ -103,8 +103,7 @@ properties: maxItems: 1 description: phandle to the associated power domain - dma-coherent: - type: boolean + dma-coherent: true ports: $ref: /schemas/graph.yaml#/properties/ports diff --git a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml index 0f2501f72ccac..c3e14eb6cfff9 100644 --- a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml +++ b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml @@ -29,7 +29,10 @@ properties: - const: allwinner,sun8i-r40-dma - const: allwinner,sun50i-a64-dma - items: - - const: allwinner,sun50i-h616-dma + - enum: + - allwinner,sun50i-h616-dma + - allwinner,sun55i-a523-dma + - allwinner,sun55i-a523-mcu-dma - const: allwinner,sun50i-a100-dma reg: diff --git a/Documentation/devicetree/bindings/dma/apm,xgene-storm-dma.yaml b/Documentation/devicetree/bindings/dma/apm,xgene-storm-dma.yaml new file mode 100644 index 0000000000000..9ca5f78487856 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/apm,xgene-storm-dma.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dma/apm,xgene-storm-dma.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: APM X-Gene Storm SoC DMA + +maintainers: + - Khuong Dinh + +properties: + compatible: + const: apm,xgene-storm-dma + + reg: + items: + - description: DMA control and status registers + - description: Descriptor ring control and status registers + - description: Descriptor ring command registers + - description: SoC efuse registers + + interrupts: + items: + - description: DMA error reporting interrupt + - description: DMA channel 0 completion interrupt + - description: DMA channel 1 completion interrupt + - description: DMA channel 2 completion interrupt + - description: DMA channel 3 completion interrupt + + clocks: + maxItems: 1 + + dma-coherent: true + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + dma@1f270000 { + compatible = "apm,xgene-storm-dma"; + reg = <0x1f270000 0x10000>, + <0x1f200000 0x10000>, + <0x1b000000 0x400000>, + <0x1054a000 0x100>; + interrupts = <0x0 0x82 0x4>, + <0x0 0xb8 0x4>, + <0x0 0xb9 0x4>, + <0x0 0xba 0x4>, + <0x0 0xbb 0x4>; + dma-coherent; + clocks = <&dmaclk 0>; + }; diff --git a/Documentation/devicetree/bindings/dma/apm-xgene-dma.txt b/Documentation/devicetree/bindings/dma/apm-xgene-dma.txt deleted file mode 100644 index c53e0b08032fe..0000000000000 --- a/Documentation/devicetree/bindings/dma/apm-xgene-dma.txt +++ /dev/null @@ -1,47 +0,0 @@ -Applied Micro X-Gene SoC DMA nodes - -DMA nodes are defined to describe on-chip DMA interfaces in -APM X-Gene SoC. - -Required properties for DMA interfaces: -- compatible: Should be "apm,xgene-dma". -- device_type: set to "dma". -- reg: Address and length of the register set for the device. - It contains the information of registers in the following order: - 1st - DMA control and status register address space. - 2nd - Descriptor ring control and status register address space. - 3rd - Descriptor ring command register address space. - 4th - Soc efuse register address space. -- interrupts: DMA has 5 interrupts sources. 1st interrupt is - DMA error reporting interrupt. 2nd, 3rd, 4th and 5th interrupts - are completion interrupts for each DMA channels. -- clocks: Reference to the clock entry. - -Optional properties: -- dma-coherent : Present if dma operations are coherent - -Example: - dmaclk: dmaclk@1f27c000 { - compatible = "apm,xgene-device-clock"; - #clock-cells = <1>; - clocks = <&socplldiv2 0>; - reg = <0x0 0x1f27c000 0x0 0x1000>; - reg-names = "csr-reg"; - clock-output-names = "dmaclk"; - }; - - dma: dma@1f270000 { - compatible = "apm,xgene-storm-dma"; - device_type = "dma"; - reg = <0x0 0x1f270000 0x0 0x10000>, - <0x0 0x1f200000 0x0 0x10000>, - <0x0 0x1b000000 0x0 0x400000>, - <0x0 0x1054a000 0x0 0x100>; - interrupts = <0x0 0x82 0x4>, - <0x0 0xb8 0x4>, - <0x0 0xb9 0x4>, - <0x0 0xba 0x4>, - <0x0 0xbb 0x4>; - dma-coherent; - clocks = <&dmaclk 0>; - }; diff --git a/Documentation/devicetree/bindings/dma/snps,dma-spear1340.yaml b/Documentation/devicetree/bindings/dma/snps,dma-spear1340.yaml index c21a4f073f6c8..18c0a7c18bc85 100644 --- a/Documentation/devicetree/bindings/dma/snps,dma-spear1340.yaml +++ b/Documentation/devicetree/bindings/dma/snps,dma-spear1340.yaml @@ -22,7 +22,6 @@ properties: - renesas,r9a06g032-dma - const: renesas,rzn1-dma - "#dma-cells": minimum: 3 maximum: 4 diff --git a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml index 935735a59afd4..a393a33c8908f 100644 --- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml +++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml @@ -42,6 +42,9 @@ properties: minItems: 1 maxItems: 8 + iommus: + maxItems: 1 + clocks: items: - description: Bus Clock diff --git a/Documentation/devicetree/bindings/dma/stericsson,dma40.yaml b/Documentation/devicetree/bindings/dma/stericsson,dma40.yaml index 7b94d24d5ef42..607da11e7baa9 100644 --- a/Documentation/devicetree/bindings/dma/stericsson,dma40.yaml +++ b/Documentation/devicetree/bindings/dma/stericsson,dma40.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ST-Ericsson DMA40 DMA Engine maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: dma-controller.yaml# @@ -120,7 +120,6 @@ properties: - description: LCPA memory base, deprecated, use eSRAM pool instead deprecated: true - reg-names: oneOf: - items: diff --git a/Documentation/devicetree/bindings/dma/stm32/st,stm32-dma.yaml b/Documentation/devicetree/bindings/dma/stm32/st,stm32-dma.yaml index 11a289f1d5059..5989033541962 100644 --- a/Documentation/devicetree/bindings/dma/stm32/st,stm32-dma.yaml +++ b/Documentation/devicetree/bindings/dma/stm32/st,stm32-dma.yaml @@ -48,7 +48,6 @@ description: | by transfer completion. This must only be used on channels managing transfers for STM32 USART/UART. - maintainers: - Amelie Delaunay diff --git a/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml b/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml index b5399c65a7315..2da86037ad79e 100644 --- a/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml +++ b/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml @@ -59,8 +59,7 @@ properties: power-domains: maxItems: 1 - dma-coherent: - description: present if dma operations are coherent + dma-coherent: true required: - "#dma-cells" diff --git a/Documentation/devicetree/bindings/dts-coding-style.rst b/Documentation/devicetree/bindings/dts-coding-style.rst index 202acac0507ab..4a02ea60cbbe2 100644 --- a/Documentation/devicetree/bindings/dts-coding-style.rst +++ b/Documentation/devicetree/bindings/dts-coding-style.rst @@ -120,7 +120,8 @@ The following order of properties in device nodes is preferred: 4. Standard/common properties (defined by common bindings, e.g. without vendor-prefixes) 5. Vendor-specific properties -6. "status" (if applicable) +6. "status" (if applicable), preceded by a blank line if there is content + before the property 7. Child nodes, where each node is preceded with a blank line The "status" property is by default "okay", thus it can be omitted. @@ -150,6 +151,7 @@ Example:: #address-cells = <1>; #size-cells = <1>; vendor,custom-property = <2>; + status = "disabled"; child_node: child-class@100 { @@ -165,6 +167,7 @@ Example:: vdd-1v8-supply = <&board_vreg4>; vdd-3v3-supply = <&board_vreg2>; vdd-12v-supply = <&board_vreg3>; + status = "okay"; } diff --git a/Documentation/devicetree/bindings/edac/altr,socfpga-ecc-manager.yaml b/Documentation/devicetree/bindings/edac/altr,socfpga-ecc-manager.yaml index 3d787dea0f147..136e8fccd429a 100644 --- a/Documentation/devicetree/bindings/edac/altr,socfpga-ecc-manager.yaml +++ b/Documentation/devicetree/bindings/edac/altr,socfpga-ecc-manager.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Altera SoCFPGA ECC Manager maintainers: - - Matthew Gerlach + - Niravkumar L Rabara description: This binding describes the device tree nodes required for the Altera SoCFPGA diff --git a/Documentation/devicetree/bindings/edac/apm,xgene-edac.yaml b/Documentation/devicetree/bindings/edac/apm,xgene-edac.yaml index 9afc78254cc0c..9637df7af3c87 100644 --- a/Documentation/devicetree/bindings/edac/apm,xgene-edac.yaml +++ b/Documentation/devicetree/bindings/edac/apm,xgene-edac.yaml @@ -97,7 +97,6 @@ patternProperties: - reg - memory-controller - '^edacpmd@': description: PMD subnode type: object diff --git a/Documentation/devicetree/bindings/eeprom/at24.yaml b/Documentation/devicetree/bindings/eeprom/at24.yaml index 50af7ccf6e21a..c212826347803 100644 --- a/Documentation/devicetree/bindings/eeprom/at24.yaml +++ b/Documentation/devicetree/bindings/eeprom/at24.yaml @@ -131,6 +131,7 @@ properties: - const: atmel,24c32 - items: - enum: + - belling,bl24s64 - onnn,n24s64b - puya,p24c64f - const: atmel,24c64 diff --git a/Documentation/devicetree/bindings/eeprom/at25.yaml b/Documentation/devicetree/bindings/eeprom/at25.yaml index 00e0f07b44f84..e1599ce109165 100644 --- a/Documentation/devicetree/bindings/eeprom/at25.yaml +++ b/Documentation/devicetree/bindings/eeprom/at25.yaml @@ -25,6 +25,7 @@ properties: oneOf: - items: - enum: + - anvo,anv32c81w - anvo,anv32e61w - atmel,at25256B - fujitsu,mb85rs1mt diff --git a/Documentation/devicetree/bindings/embedded-controller/traverse,ten64-controller.yaml b/Documentation/devicetree/bindings/embedded-controller/traverse,ten64-controller.yaml new file mode 100644 index 0000000000000..08d02c4df8732 --- /dev/null +++ b/Documentation/devicetree/bindings/embedded-controller/traverse,ten64-controller.yaml @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/embedded-controller/traverse,ten64-controller.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Traverse Ten64 board microcontroller + +maintainers: + - Mathew McBride + +description: | + The board microcontroller on the Ten64 board family is responsible for + management of power sources on the board, as well as signalling the SoC + to power on and reset. + +properties: + compatible: + const: traverse,ten64-controller + + reg: + const: 0x7e + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + board-controller@7e { + compatible = "traverse,ten64-controller"; + reg = <0x7e>; + }; + }; diff --git a/Documentation/devicetree/bindings/extcon/fcs,fsa880.yaml b/Documentation/devicetree/bindings/extcon/fcs,fsa880.yaml index ef6a246a13378..bff3fd5f7f4eb 100644 --- a/Documentation/devicetree/bindings/extcon/fcs,fsa880.yaml +++ b/Documentation/devicetree/bindings/extcon/fcs,fsa880.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Fairchild Semiconductor FSA880, FSA9480 and compatibles maintainers: - - Linus Walleij + - Linus Walleij description: The FSA880 and FSA9480 are USB port accessory detectors and switches. diff --git a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml index 9785aac3b5f34..d3bca6088d128 100644 --- a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml +++ b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml @@ -24,6 +24,15 @@ properties: compatible: const: google,gs101-acpm-ipc + "#clock-cells": + const: 1 + description: + Clocks that are variable and index based. These clocks don't provide + an entire range of values between the limits but only discrete points + within the range. The firmware also manages the voltage scaling + appropriately with the clock scaling. The argument is the ID of the + clock contained by the firmware messages. + mboxes: maxItems: 1 @@ -45,6 +54,7 @@ properties: required: - compatible + - "#clock-cells" - mboxes - shmem @@ -56,6 +66,7 @@ examples: power-management { compatible = "google,gs101-acpm-ipc"; + #clock-cells = <1>; mboxes = <&ap2apm_mailbox>; shmem = <&apm_sram>; diff --git a/Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml b/Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml index 50f1f08744a1d..4d66ef4835223 100644 --- a/Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml +++ b/Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Intel IXP4xx Network Processing Engine maintainers: - - Linus Walleij + - Linus Walleij description: | On the IXP4xx SoCs, the Network Processing Engine (NPE) is a small diff --git a/Documentation/devicetree/bindings/firmware/intel,stratix10-svc.yaml b/Documentation/devicetree/bindings/firmware/intel,stratix10-svc.yaml index fac1e955852e4..b42cfa78b28b5 100644 --- a/Documentation/devicetree/bindings/firmware/intel,stratix10-svc.yaml +++ b/Documentation/devicetree/bindings/firmware/intel,stratix10-svc.yaml @@ -34,6 +34,7 @@ properties: enum: - intel,stratix10-svc - intel,agilex-svc + - intel,agilex5-svc method: description: | @@ -54,6 +55,9 @@ properties: reserved memory region for the service layer driver to communicate with the secure device manager. + iommus: + maxItems: 1 + fpga-mgr: $ref: /schemas/fpga/intel,stratix10-soc-fpga-mgr.yaml description: Optional child node for fpga manager to perform fabric configuration. @@ -63,6 +67,17 @@ required: - method - memory-region +allOf: + - if: + properties: + compatible: + contains: + enum: + - intel,agilex5-svc + then: + required: + - iommus + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml index ef97faac7e47c..d66459f1d84e4 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml @@ -23,6 +23,7 @@ properties: - enum: - qcom,scm-apq8064 - qcom,scm-apq8084 + - qcom,scm-glymur - qcom,scm-ipq4019 - qcom,scm-ipq5018 - qcom,scm-ipq5332 @@ -31,6 +32,7 @@ properties: - qcom,scm-ipq806x - qcom,scm-ipq8074 - qcom,scm-ipq9574 + - qcom,scm-kaanapali - qcom,scm-mdm9607 - qcom,scm-milos - qcom,scm-msm8226 @@ -202,6 +204,7 @@ allOf: compatible: contains: enum: + - qcom,scm-kaanapali - qcom,scm-milos - qcom,scm-sm8450 - qcom,scm-sm8550 diff --git a/Documentation/devicetree/bindings/firmware/qemu,fw-cfg-mmio.yaml b/Documentation/devicetree/bindings/firmware/qemu,fw-cfg-mmio.yaml index 3faae32366656..c6fc1d6e25da7 100644 --- a/Documentation/devicetree/bindings/firmware/qemu,fw-cfg-mmio.yaml +++ b/Documentation/devicetree/bindings/firmware/qemu,fw-cfg-mmio.yaml @@ -23,7 +23,6 @@ description: | The authoritative guest-side hardware interface documentation to the fw_cfg device can be found in "docs/specs/fw_cfg.txt" in the QEMU source tree. - properties: compatible: const: qemu,fw-cfg-mmio diff --git a/Documentation/devicetree/bindings/fpga/fpga-region.yaml b/Documentation/devicetree/bindings/fpga/fpga-region.yaml index 7d2d3b7aa4b7e..55acf0ecfa3fd 100644 --- a/Documentation/devicetree/bindings/fpga/fpga-region.yaml +++ b/Documentation/devicetree/bindings/fpga/fpga-region.yaml @@ -18,7 +18,6 @@ description: | - Supported Use Models - Constraints - Introduction ============ @@ -31,7 +30,6 @@ description: | document isn't a replacement for any manufacturers specifications for FPGA usage. - Terminology =========== @@ -108,7 +106,6 @@ description: | 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 ======== @@ -124,7 +121,6 @@ description: | When the overlay is removed, the child nodes will be removed and the FPGA Region will disable the bridges. - FPGA Region =========== @@ -170,7 +166,6 @@ description: | hardware bridges remain enabled. The PR regions' bridges will be FPGA bridges within the static image of the FPGA. - Supported Use Models ==================== @@ -215,9 +210,9 @@ description: | 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 + [1] https://www.intel.com/programmable/technical-pdfs/683404.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 + [3] https://docs.amd.com/v/u/en-US/ug702 properties: $nodename: diff --git a/Documentation/devicetree/bindings/fpga/lattice,ice40-fpga-mgr.yaml b/Documentation/devicetree/bindings/fpga/lattice,ice40-fpga-mgr.yaml new file mode 100644 index 0000000000000..5121c61207857 --- /dev/null +++ b/Documentation/devicetree/bindings/fpga/lattice,ice40-fpga-mgr.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/fpga/lattice,ice40-fpga-mgr.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lattice iCE40 FPGA Manager + +maintainers: + - Joel Holdsworth + +properties: + compatible: + const: lattice,ice40-fpga-mgr + + reg: + maxItems: 1 + + spi-max-frequency: + minimum: 1000000 + maximum: 25000000 + + cdone-gpios: + maxItems: 1 + description: GPIO input connected to CDONE pin + + reset-gpios: + maxItems: 1 + description: + Active-low GPIO output connected to CRESET_B pin. Note that unless the + GPIO is held low during startup, the FPGA will enter Master SPI mode and + drive SCK with a clock signal potentially jamming other devices on the bus + until the firmware is loaded. + +required: + - compatible + - reg + - spi-max-frequency + - cdone-gpios + - reset-gpios + +additionalProperties: false + +examples: + - | + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + fpga@0 { + compatible = "lattice,ice40-fpga-mgr"; + reg = <0>; + spi-max-frequency = <1000000>; + cdone-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 22 GPIO_ACTIVE_LOW>; + }; + }; diff --git a/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt b/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt deleted file mode 100644 index 4dc412437b086..0000000000000 --- a/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt +++ /dev/null @@ -1,21 +0,0 @@ -Lattice iCE40 FPGA Manager - -Required properties: -- compatible: Should contain "lattice,ice40-fpga-mgr" -- reg: SPI chip select -- spi-max-frequency: Maximum SPI frequency (>=1000000, <=25000000) -- cdone-gpios: GPIO input connected to CDONE pin -- reset-gpios: Active-low GPIO output connected to CRESET_B pin. Note - that unless the GPIO is held low during startup, the - FPGA will enter Master SPI mode and drive SCK with a - clock signal potentially jamming other devices on the - bus until the firmware is loaded. - -Example: - fpga: fpga@0 { - compatible = "lattice,ice40-fpga-mgr"; - reg = <0>; - spi-max-frequency = <1000000>; - cdone-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio 22 GPIO_ACTIVE_LOW>; - }; diff --git a/Documentation/devicetree/bindings/gnss/brcm,bcm4751.yaml b/Documentation/devicetree/bindings/gnss/brcm,bcm4751.yaml index 089166089498d..c34b86bb7f6ff 100644 --- a/Documentation/devicetree/bindings/gnss/brcm,bcm4751.yaml +++ b/Documentation/devicetree/bindings/gnss/brcm,bcm4751.yaml @@ -8,7 +8,7 @@ title: Broadcom BCM4751 family GNSS Receiver maintainers: - Johan Hovold - - Linus Walleij + - Linus Walleij description: Broadcom GPS chips can be used over the UART or I2C bus. The UART diff --git a/Documentation/devicetree/bindings/gnss/gnss-common.yaml b/Documentation/devicetree/bindings/gnss/gnss-common.yaml index d4430d2d6855c..354c0524089cf 100644 --- a/Documentation/devicetree/bindings/gnss/gnss-common.yaml +++ b/Documentation/devicetree/bindings/gnss/gnss-common.yaml @@ -31,8 +31,7 @@ properties: maxItems: 1 timepulse-gpios: - description: When a timepulse is provided to the GNSS device using a - GPIO line, this is used. + description: Timepulse signal maxItems: 1 additionalProperties: true diff --git a/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml b/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml index c0c2bfaa606fb..b349b7bc04123 100644 --- a/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml +++ b/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/gnss/u-blox,neo-6m.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: U-blox GNSS Receiver +title: u-blox GNSS receiver allOf: - $ref: gnss-common.yaml# @@ -14,7 +14,7 @@ maintainers: - Johan Hovold description: > - The U-blox GNSS receivers can use UART, DDC (I2C), SPI and USB interfaces. + The u-blox GNSS receivers can use UART, DDC (I2C), SPI and USB interfaces. properties: compatible: @@ -36,6 +36,9 @@ properties: reset-gpios: maxItems: 1 + safeboot-gpios: + maxItems: 1 + vcc-supply: description: > Main voltage regulator @@ -64,6 +67,7 @@ examples: compatible = "u-blox,neo-8"; v-bckp-supply = <&gnss_v_bckp_reg>; vcc-supply = <&gnss_vcc_reg>; - reset-gpios = <&gpio 1 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio 1 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + safeboot-gpios = <&gpio 2 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; }; }; diff --git a/Documentation/devicetree/bindings/gpio/brcm,xgs-iproc-gpio.yaml b/Documentation/devicetree/bindings/gpio/brcm,xgs-iproc-gpio.yaml index c213cb9ddb9f0..5cfefbbea6ca7 100644 --- a/Documentation/devicetree/bindings/gpio/brcm,xgs-iproc-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/brcm,xgs-iproc-gpio.yaml @@ -66,5 +66,4 @@ examples: interrupts = ; }; - ... diff --git a/Documentation/devicetree/bindings/gpio/fairchild,74hc595.yaml b/Documentation/devicetree/bindings/gpio/fairchild,74hc595.yaml index ab35bcf981016..23410aeca3000 100644 --- a/Documentation/devicetree/bindings/gpio/fairchild,74hc595.yaml +++ b/Documentation/devicetree/bindings/gpio/fairchild,74hc595.yaml @@ -22,7 +22,6 @@ description: | ___ ________ chip select# |___________________| - maintainers: - Maxime Ripard diff --git a/Documentation/devicetree/bindings/gpio/faraday,ftgpio010.yaml b/Documentation/devicetree/bindings/gpio/faraday,ftgpio010.yaml index 640da5b9b0cc1..3a6a47f12982c 100644 --- a/Documentation/devicetree/bindings/gpio/faraday,ftgpio010.yaml +++ b/Documentation/devicetree/bindings/gpio/faraday,ftgpio010.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Faraday Technology FTGPIO010 GPIO Controller maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/gpio/gpio-consumer-common.yaml b/Documentation/devicetree/bindings/gpio/gpio-consumer-common.yaml index 40d0be31e2000..fa0148758b4b2 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-consumer-common.yaml +++ b/Documentation/devicetree/bindings/gpio/gpio-consumer-common.yaml @@ -8,7 +8,7 @@ title: Common GPIO lines maintainers: - Bartosz Golaszewski - - Linus Walleij + - Linus Walleij description: Pay attention to using proper GPIO flag (e.g. GPIO_ACTIVE_LOW) for the GPIOs diff --git a/Documentation/devicetree/bindings/gpio/gpio-ep9301.yaml b/Documentation/devicetree/bindings/gpio/gpio-ep9301.yaml index 3a1079d6ee200..ebdb7ee5b790d 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-ep9301.yaml +++ b/Documentation/devicetree/bindings/gpio/gpio-ep9301.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: EP93xx GPIO controller maintainers: - - Linus Walleij + - Linus Walleij - Bartosz Golaszewski - Nikita Shubin diff --git a/Documentation/devicetree/bindings/gpio/gpio-mmio.yaml b/Documentation/devicetree/bindings/gpio/gpio-mmio.yaml index b4d55bf6a2854..ee5d5d25ae82f 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-mmio.yaml +++ b/Documentation/devicetree/bindings/gpio/gpio-mmio.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Generic MMIO GPIO maintainers: - - Linus Walleij + - Linus Walleij - Bartosz Golaszewski description: diff --git a/Documentation/devicetree/bindings/gpio/gpio-mxs.yaml b/Documentation/devicetree/bindings/gpio/gpio-mxs.yaml index aaf97124803f4..fed1b06495ad0 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-mxs.yaml +++ b/Documentation/devicetree/bindings/gpio/gpio-mxs.yaml @@ -28,6 +28,7 @@ properties: '#address-cells': const: 1 + '#size-cells': const: 0 @@ -35,7 +36,7 @@ properties: maxItems: 1 patternProperties: - "^(?!gpio@)[^@]+@[0-9]+$": + '^(?!gpio@)[^@]+@[0-9]+$': type: object properties: fsl,pinmux-ids: @@ -93,7 +94,7 @@ patternProperties: additionalProperties: false - "^gpio@[0-9]+$": + '^gpio@[0-9]+$': type: object properties: compatible: @@ -110,10 +111,10 @@ patternProperties: interrupt-controller: true - "#interrupt-cells": + '#interrupt-cells': const: 2 - "#gpio-cells": + '#gpio-cells': const: 2 gpio-controller: true @@ -123,8 +124,8 @@ patternProperties: - reg - interrupts - interrupt-controller - - "#interrupt-cells" - - "#gpio-cells" + - '#interrupt-cells' + - '#gpio-cells' - gpio-controller additionalProperties: false diff --git a/Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.yaml b/Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.yaml index bfcb1f364c3aa..2a980c0ed86f6 100644 --- a/Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.yaml @@ -22,7 +22,7 @@ description: | and this can be enabled by a special flag. maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml b/Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml index d78da7dd2a566..184432d24ea18 100644 --- a/Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml @@ -11,7 +11,10 @@ maintainers: properties: compatible: - items: + oneOf: + - items: + - const: microchip,pic64gx-gpio + - const: microchip,mpfs-gpio - enum: - microchip,mpfs-gpio - microchip,coregpio-rtl-v3 diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.yaml b/Documentation/devicetree/bindings/gpio/mrvl-gpio.yaml index 65155bb701a9f..7f420b9c04808 100644 --- a/Documentation/devicetree/bindings/gpio/mrvl-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/mrvl-gpio.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Marvell PXA GPIO controller maintainers: - - Linus Walleij + - Linus Walleij - Bartosz Golaszewski - Rob Herring diff --git a/Documentation/devicetree/bindings/gpio/pl061-gpio.yaml b/Documentation/devicetree/bindings/gpio/pl061-gpio.yaml index c51e10680c0a5..4d970e55104bb 100644 --- a/Documentation/devicetree/bindings/gpio/pl061-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/pl061-gpio.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM PL061 GPIO controller maintainers: - - Linus Walleij + - Linus Walleij - Rob Herring # We need a select here so we don't match all nodes with 'arm,primecell' diff --git a/Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml b/Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml index ab2afc0e4153d..bba6f5b6606fd 100644 --- a/Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml @@ -111,8 +111,8 @@ additionalProperties: false required: - compatible - reg - - "#address-cells" - - "#size-cells" + - '#address-cells' + - '#size-cells' examples: - | diff --git a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml index b3e8951959b52..40b4a75514496 100644 --- a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml @@ -12,7 +12,7 @@ description: with pinctrl-nomadik. maintainers: - - Linus Walleij + - Linus Walleij properties: $nodename: diff --git a/Documentation/devicetree/bindings/gpio/st,stmpe-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,stmpe-gpio.yaml index 4555f1644a4df..66dd602e797dd 100644 --- a/Documentation/devicetree/bindings/gpio/st,stmpe-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/st,stmpe-gpio.yaml @@ -14,7 +14,7 @@ description: GPIO portions of these expanders. maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/gpio/trivial-gpio.yaml b/Documentation/devicetree/bindings/gpio/trivial-gpio.yaml index c994177de940a..3f4bbd57fc52c 100644 --- a/Documentation/devicetree/bindings/gpio/trivial-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/trivial-gpio.yaml @@ -22,6 +22,8 @@ properties: - cznic,moxtet-gpio - dlg,slg7xl45106 - fcs,fxl6408 + - fsl,ls1046aqds-fpga-gpio-stat-pres2 + - fsl,lx2160ardb-fpga-gpio-sfp - gateworks,pld-gpio - ibm,ppc4xx-gpio - loongson,ls1x-gpio diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml index be198182dbfe0..db49b8ff8c748 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml +++ b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml @@ -22,6 +22,7 @@ properties: - mediatek,mt8183-mali - mediatek,mt8183b-mali - mediatek,mt8186-mali + - mediatek,mt8365-mali - realtek,rtd1619-mali - renesas,r9a07g044-mali - renesas,r9a07g054-mali diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.yaml index a5b4e00217587..bee9faf1d3f82 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.yaml +++ b/Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.yaml @@ -18,6 +18,8 @@ properties: oneOf: - items: - enum: + - mediatek,mt8196-mali + - nxp,imx95-mali # G310 - rockchip,rk3588-mali - const: arm,mali-valhall-csf # Mali Valhall GPU model/revision is fully discoverable @@ -44,7 +46,9 @@ properties: minItems: 1 items: - const: core - - const: coregroup + - enum: + - coregroup + - stacks - const: stacks mali-supply: true @@ -91,7 +95,6 @@ required: - interrupts - interrupt-names - clocks - - mali-supply additionalProperties: false @@ -108,6 +111,29 @@ allOf: power-domains: maxItems: 1 power-domain-names: false + required: + - mali-supply + - if: + properties: + compatible: + contains: + const: mediatek,mt8196-mali + then: + properties: + mali-supply: false + sram-supply: false + operating-points-v2: false + power-domains: + maxItems: 1 + power-domain-names: false + clocks: + maxItems: 2 + clock-names: + items: + - const: core + - const: stacks + required: + - power-domains examples: - | @@ -143,5 +169,17 @@ examples: }; }; }; + - | + gpu@48000000 { + compatible = "mediatek,mt8196-mali", "arm,mali-valhall-csf"; + reg = <0x48000000 0x480000>; + clocks = <&gpufreq 0>, <&gpufreq 1>; + clock-names = "core", "stacks"; + interrupts = , + , + ; + interrupt-names = "job", "mmu", "gpu"; + power-domains = <&gpufreq>; + }; ... diff --git a/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml b/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml index c87d7bece0ecd..86ef689853177 100644 --- a/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml +++ b/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml @@ -13,6 +13,18 @@ maintainers: properties: compatible: oneOf: + - items: + - enum: + - renesas,r8a7796-gpu + - renesas,r8a77961-gpu + - const: img,img-gx6250 + - const: img,img-rogue + - items: + - enum: + - renesas,r8a77965-gpu + - renesas,r8a779a0-gpu + - const: img,img-ge7800 + - const: img,img-rogue - items: - enum: - ti,am62-gpu @@ -86,48 +98,56 @@ allOf: properties: compatible: contains: - const: img,img-axe-1-16m + enum: + - ti,am62-gpu + - ti,j721s2-gpu then: properties: - power-domains: - items: - - description: Power domain A - power-domain-names: + clocks: maxItems: 1 - required: - - power-domains - - power-domain-names - if: properties: compatible: contains: - const: thead,th1520-gpu + enum: + - img,img-ge7800 + - img,img-gx6250 + - thead,th1520-gpu then: properties: clocks: minItems: 3 clock-names: minItems: 3 + + - if: + properties: + compatible: + contains: + const: img,img-axe-1-16m + then: + properties: power-domains: - items: - - description: The single, unified power domain for the GPU on the - TH1520 SoC, integrating all internal IP power domains. - power-domain-names: false + maxItems: 1 + power-domain-names: + maxItems: 1 required: - power-domains + - power-domain-names - if: properties: compatible: contains: - const: img,img-bxs-4-64 + enum: + - img,img-bxs-4-64 + - img,img-ge7800 + - img,img-gx6250 then: properties: power-domains: - items: - - description: Power domain A - - description: Power domain B + minItems: 2 power-domain-names: minItems: 2 required: @@ -138,13 +158,16 @@ allOf: properties: compatible: contains: - enum: - - ti,am62-gpu - - ti,j721s2-gpu + const: thead,th1520-gpu then: properties: - clocks: - maxItems: 1 + power-domains: + items: + - description: The single, unified power domain for the GPU on the + TH1520 SoC, integrating all internal IP power domains. + power-domain-names: false + required: + - power-domains examples: - | diff --git a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml index 383020450d780..b9cdfe52b62ff 100644 --- a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml +++ b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml @@ -20,12 +20,14 @@ properties: - samsung,exynos5433-chipid - samsung,exynos7-chipid - samsung,exynos7870-chipid + - samsung,exynos8890-chipid - const: samsung,exynos4210-chipid - items: - enum: - samsung,exynos2200-chipid - samsung,exynos7885-chipid - samsung,exynos8895-chipid + - samsung,exynos9610-chipid - samsung,exynos9810-chipid - samsung,exynos990-chipid - samsung,exynosautov9-chipid diff --git a/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml b/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml index 152935334c76a..3e3f49cf2f52e 100644 --- a/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml +++ b/Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml @@ -81,7 +81,6 @@ required: - compatible - reg - additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/hwmon/adi,max31827.yaml b/Documentation/devicetree/bindings/hwmon/adi,max31827.yaml index f60e06ab7d0a0..c2f7c6ee1a372 100644 --- a/Documentation/devicetree/bindings/hwmon/adi,max31827.yaml +++ b/Documentation/devicetree/bindings/hwmon/adi,max31827.yaml @@ -93,7 +93,6 @@ allOf: adi,fault-q: default: 4 - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/hwmon/apm,xgene-slimpro-hwmon.yaml b/Documentation/devicetree/bindings/hwmon/apm,xgene-slimpro-hwmon.yaml new file mode 100644 index 0000000000000..58c51626a9cee --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/apm,xgene-slimpro-hwmon.yaml @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/hwmon/apm,xgene-slimpro-hwmon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: APM X-Gene SLIMpro hwmon + +maintainers: + - Khuong Dinh + +properties: + compatible: + const: apm,xgene-slimpro-hwmon + + mboxes: + maxItems: 1 + +required: + - compatible + - mboxes + +additionalProperties: false + +examples: + - | + hwmon { + compatible = "apm,xgene-slimpro-hwmon"; + mboxes = <&mailbox 7>; + }; diff --git a/Documentation/devicetree/bindings/hwmon/apm-xgene-hwmon.txt b/Documentation/devicetree/bindings/hwmon/apm-xgene-hwmon.txt deleted file mode 100644 index 59b38557f1bb6..0000000000000 --- a/Documentation/devicetree/bindings/hwmon/apm-xgene-hwmon.txt +++ /dev/null @@ -1,14 +0,0 @@ -APM X-Gene hwmon driver - -APM X-Gene SOC sensors are accessed over the "SLIMpro" mailbox. - -Required properties : - - compatible : should be "apm,xgene-slimpro-hwmon" - - mboxes : use the label reference for the mailbox as the first parameter. - The second parameter is the channel number. - -Example : - hwmonslimpro { - compatible = "apm,xgene-slimpro-hwmon"; - mboxes = <&mailbox 7>; - }; diff --git a/Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml b/Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml index 9e5ed901ae54c..851fb16ec7fa1 100644 --- a/Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml +++ b/Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml @@ -18,8 +18,11 @@ description: | properties: compatible: - enum: - - aspeed,ast2600-pwm-tach + oneOf: + - items: + - const: aspeed,ast2700-pwm-tach + - const: aspeed,ast2600-pwm-tach + - const: aspeed,ast2600-pwm-tach reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/hwmon/max31785.txt b/Documentation/devicetree/bindings/hwmon/max31785.txt deleted file mode 100644 index 106e08c56aaa9..0000000000000 --- a/Documentation/devicetree/bindings/hwmon/max31785.txt +++ /dev/null @@ -1,22 +0,0 @@ -Bindings for the Maxim MAX31785 Intelligent Fan Controller -========================================================== - -Reference: - -https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf - -The Maxim MAX31785 is a PMBus device providing closed-loop, multi-channel fan -management with temperature and remote voltage sensing. Various fan control -features are provided, including PWM frequency control, temperature hysteresis, -dual tachometer measurements, and fan health monitoring. - -Required properties: -- compatible : One of "maxim,max31785" or "maxim,max31785a" -- reg : I2C address, one of 0x52, 0x53, 0x54, 0x55. - -Example: - - fans@52 { - compatible = "maxim,max31785"; - reg = <0x52>; - }; diff --git a/Documentation/devicetree/bindings/hwmon/maxim,max31790.yaml b/Documentation/devicetree/bindings/hwmon/maxim,max31790.yaml index b1ff496f87f95..558cbd251b0fd 100644 --- a/Documentation/devicetree/bindings/hwmon/maxim,max31790.yaml +++ b/Documentation/devicetree/bindings/hwmon/maxim,max31790.yaml @@ -20,7 +20,11 @@ description: > properties: compatible: - const: maxim,max31790 + enum: + - maxim,max31785 + - maxim,max31785a + - maxim,max31785b + - maxim,max31790 reg: maxItems: 1 @@ -31,11 +35,17 @@ properties: resets: maxItems: 1 + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + "#pwm-cells": const: 1 patternProperties: - "^fan-[0-9]+$": + "^fan@[0-9]+$": $ref: fan-common.yaml# unevaluatedProperties: false @@ -56,13 +66,17 @@ examples: reg = <0x20>; clocks = <&sys_clk>; resets = <&reset 0>; + #address-cells = <1>; #pwm-cells = <1>; + #size-cells = <0>; - fan-0 { + fan@0 { + reg = <0x0>; pwms = <&pwm_provider 1>; }; - fan-1 { + fan@1 { + reg = <0x1>; pwms = <&pwm_provider 2>; }; }; diff --git a/Documentation/devicetree/bindings/hwmon/national,lm90.yaml b/Documentation/devicetree/bindings/hwmon/national,lm90.yaml index 1b871f166e791..164068ba069d7 100644 --- a/Documentation/devicetree/bindings/hwmon/national,lm90.yaml +++ b/Documentation/devicetree/bindings/hwmon/national,lm90.yaml @@ -45,7 +45,6 @@ properties: - ti,tmp461 - winbond,w83l771 - interrupts: items: - description: | diff --git a/Documentation/devicetree/bindings/hwmon/ntc-thermistor.yaml b/Documentation/devicetree/bindings/hwmon/ntc-thermistor.yaml index b8e500e6cd9f8..efd10bcfb0820 100644 --- a/Documentation/devicetree/bindings/hwmon/ntc-thermistor.yaml +++ b/Documentation/devicetree/bindings/hwmon/ntc-thermistor.yaml @@ -6,7 +6,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: NTC thermistor temperature sensors maintainers: - - Linus Walleij + - Linus Walleij description: | Thermistors with negative temperature coefficient (NTC) are resistors that @@ -75,6 +75,7 @@ properties: - const: murata,ncp15wl333 - const: murata,ncp03wf104 - const: murata,ncp15xh103 + - const: murata,ncp18wm474 - const: samsung,1404-001221 # Deprecated "ntc," compatible strings - const: ntc,ncp15wb473 diff --git a/Documentation/devicetree/bindings/hwmon/pmbus/adi,max17616.yaml b/Documentation/devicetree/bindings/hwmon/pmbus/adi,max17616.yaml new file mode 100644 index 0000000000000..fa48af81e083c --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/pmbus/adi,max17616.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/hwmon/pmbus/adi,max17616.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices MAX17616/MAX17616A Current-Limiter with PMBus Interface + +maintainers: + - Kim Seer Paller + +description: | + The MAX17616/MAX17616A is a 3V to 80V, 7A current-limiter with overvoltage, + surge, undervoltage, reverse polarity, and loss of ground protection. It allows + monitoring of input/output voltage, output current and temperature through the + PMBus serial interface. + Datasheet: + https://www.analog.com/en/products/max17616.html + +properties: + compatible: + const: adi,max17616 + + reg: + maxItems: 1 + + vcc-supply: true + + interrupts: + description: Fault condition signal provided on SMBALERT pin. + maxItems: 1 + +required: + - compatible + - reg + - vcc-supply + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + hwmon@16 { + compatible = "adi,max17616"; + reg = <0x16>; + vcc-supply = <&vcc>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/hwmon/st,tsc1641.yaml b/Documentation/devicetree/bindings/hwmon/st,tsc1641.yaml new file mode 100644 index 0000000000000..aaf244790663d --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/st,tsc1641.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/hwmon/st,tsc1641.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ST Microelectronics TSC1641 I2C power monitor + +maintainers: + - Igor Reznichenko + +description: | + TSC1641 is a 60 V, 16-bit high-precision power monitor with I2C and + MIPI I3C interface + + Datasheets: + https://www.st.com/resource/en/datasheet/tsc1641.pdf + +properties: + compatible: + const: st,tsc1641 + + reg: + maxItems: 1 + + interrupts: + description: Optional alert interrupt. + maxItems: 1 + + shunt-resistor-micro-ohms: + description: Shunt resistor value in micro-ohms. Since device has internal + 16-bit RSHUNT register with 10 uOhm LSB, the maximum value is capped at + 655.35 mOhm. + minimum: 100 + default: 1000 + maximum: 655350 + + st,alert-polarity-active-high: + $ref: /schemas/types.yaml#/definitions/flag + description: Default value is 0 which configures the normal polarity of the + ALERT pin, being active low open-drain. Setting this to 1 configures the + polarity of the ALERT pin to be inverted and active high open-drain. + Specify this property to set the alert polarity to active-high. + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + power-sensor@40 { + compatible = "st,tsc1641"; + reg = <0x40>; + shunt-resistor-micro-ohms = <1000>; + st,alert-polarity-active-high; + }; + }; diff --git a/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml b/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml index cba5b4a1b81f4..0fe6ea190f60f 100644 --- a/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml +++ b/Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml @@ -20,7 +20,6 @@ description: | https://www.ti.com/lit/gpn/tmp513 https://www.ti.com/lit/gpn/tmp512 - properties: compatible: enum: diff --git a/Documentation/devicetree/bindings/hwmon/ti,tps23861.yaml b/Documentation/devicetree/bindings/hwmon/ti,tps23861.yaml index ee7de53e19184..d57e4bf8f65ff 100644 --- a/Documentation/devicetree/bindings/hwmon/ti,tps23861.yaml +++ b/Documentation/devicetree/bindings/hwmon/ti,tps23861.yaml @@ -15,7 +15,6 @@ description: | Datasheets: https://www.ti.com/lit/gpn/tps23861 - properties: compatible: enum: diff --git a/Documentation/devicetree/bindings/hwmon/winbond,w83781d.yaml b/Documentation/devicetree/bindings/hwmon/winbond,w83781d.yaml index 6971ecb314ebc..d97b0e6984776 100644 --- a/Documentation/devicetree/bindings/hwmon/winbond,w83781d.yaml +++ b/Documentation/devicetree/bindings/hwmon/winbond,w83781d.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Winbond W83781 and compatible hardware monitor IC maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/i2c/arm,i2c-versatile.yaml b/Documentation/devicetree/bindings/i2c/arm,i2c-versatile.yaml index e58465d1b0c88..26026dfd788a4 100644 --- a/Documentation/devicetree/bindings/i2c/arm,i2c-versatile.yaml +++ b/Documentation/devicetree/bindings/i2c/arm,i2c-versatile.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: I2C Controller on ARM Ltd development platforms maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: /schemas/i2c/i2c-controller.yaml# diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-gpmux.yaml b/Documentation/devicetree/bindings/i2c/i2c-mux-gpmux.yaml index b6af924dee2e3..d8610daa10cd8 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mux-gpmux.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-mux-gpmux.yaml @@ -27,7 +27,6 @@ description: |+ | '------' | | dev | | dev | | dev | '------------' '-----' '-----' '-----' - allOf: - $ref: /schemas/i2c/i2c-mux.yaml# diff --git a/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml b/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml index 4ac5a40a3886f..91805fe8f3936 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml @@ -37,6 +37,7 @@ properties: - rockchip,px30-i2c - rockchip,rk3308-i2c - rockchip,rk3328-i2c + - rockchip,rk3506-i2c - rockchip,rk3528-i2c - rockchip,rk3562-i2c - rockchip,rk3568-i2c diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml index 9bc99d736343f..a3fe1eea6aece 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml @@ -15,6 +15,7 @@ properties: oneOf: - enum: - qcom,msm8226-cci + - qcom,msm8953-cci - qcom,msm8974-cci - qcom,msm8996-cci @@ -25,6 +26,7 @@ properties: - items: - enum: + - qcom,kaanapali-cci - qcom,qcm2290-cci - qcom,sa8775p-cci - qcom,sc7280-cci @@ -36,6 +38,7 @@ properties: - qcom,sm8450-cci - qcom,sm8550-cci - qcom,sm8650-cci + - qcom,sm8750-cci - qcom,x1e80100-cci - const: qcom,msm8996-cci # CCI v2 @@ -128,7 +131,9 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-cci - qcom,qcm2290-cci + - qcom,sm8750-cci then: properties: clocks: @@ -146,6 +151,7 @@ allOf: - contains: enum: - qcom,msm8916-cci + - qcom,msm8953-cci - const: qcom,msm8996-cci then: diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml index 758d8f6321e10..06a04db3eda2a 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml @@ -9,7 +9,7 @@ title: Qualcomm Universal Peripheral (QUP) I2C controller maintainers: - Andy Gross - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski allOf: - $ref: /schemas/i2c/i2c-controller.yaml# diff --git a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml index 17ce39c19ab15..f9a449fee2b08 100644 --- a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml @@ -64,7 +64,6 @@ patternProperties: required: - reg - allOf: - if: properties: diff --git a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml index d904191bb0c6e..9142001888095 100644 --- a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml @@ -34,8 +34,15 @@ properties: - const: snps,designware-i2c - description: Baikal-T1 SoC System I2C controller const: baikal,bt1-sys-i2c + - description: Mobileye EyeQ DesignWare I2C controller + items: + - enum: + - mobileye,eyeq7h-i2c + - const: mobileye,eyeq6lplus-i2c + - const: snps,designware-i2c - items: - enum: + - mobileye,eyeq6lplus-i2c - mscc,ocelot-i2c - sophgo,sg2044-i2c - thead,th1520-i2c diff --git a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml index 012402debfeb2..63a459c63f6a7 100644 --- a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml @@ -12,7 +12,7 @@ description: The Nomadik I2C host controller began its life in the ST DB8500 after the merge of these two companies wireless divisions. maintainers: - - Linus Walleij + - Linus Walleij # Need a custom select here or 'arm,primecell' will match on lots of nodes select: diff --git a/Documentation/devicetree/bindings/i2c/tsd,mule-i2c-mux.yaml b/Documentation/devicetree/bindings/i2c/tsd,mule-i2c-mux.yaml index 28139b6766610..19cfffb39296b 100644 --- a/Documentation/devicetree/bindings/i2c/tsd,mule-i2c-mux.yaml +++ b/Documentation/devicetree/bindings/i2c/tsd,mule-i2c-mux.yaml @@ -16,7 +16,6 @@ description: | can be selected by writing the appropriate device number to an I2C config register. - +--------------------------------------------------+ | Mule | 0x18| +---------------+ | @@ -34,7 +33,6 @@ description: | | |__/ +--------+ | +--------------------------------------------------+ - allOf: - $ref: /schemas/i2c/i2c-mux.yaml# diff --git a/Documentation/devicetree/bindings/i3c/snps,dw-i3c-master.yaml b/Documentation/devicetree/bindings/i3c/snps,dw-i3c-master.yaml index 5f64673758110..e803457d3f554 100644 --- a/Documentation/devicetree/bindings/i3c/snps,dw-i3c-master.yaml +++ b/Documentation/devicetree/bindings/i3c/snps,dw-i3c-master.yaml @@ -14,7 +14,11 @@ allOf: properties: compatible: - const: snps,dw-i3c-master-1.00a + oneOf: + - const: snps,dw-i3c-master-1.00a + - items: + - const: altr,agilex5-dw-i3c-master + - const: snps,dw-i3c-master-1.00a reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml index a23a626bfab6f..61d7ba89adc28 100644 --- a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml +++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml @@ -35,15 +35,17 @@ properties: spi-3wire: true interrupts: - maxItems: 1 + minItems: 1 + maxItems: 2 interrupt-names: + minItems: 1 items: - enum: [INT1, INT2] + - const: INT2 dependencies: interrupts: [ interrupt-names ] - interrupt-names: [ interrupts ] required: - compatible @@ -84,7 +86,8 @@ examples: spi-cpol; spi-cpha; interrupt-parent = <&gpio0>; - interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "INT2"; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>, + <1 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "INT1", "INT2"; }; }; diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl380.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adxl380.yaml index f1ff5ff4f478d..ab517720a6a79 100644 --- a/Documentation/devicetree/bindings/iio/accel/adi,adxl380.yaml +++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl380.yaml @@ -11,16 +11,19 @@ maintainers: - Antoniu Miclaus description: | - The ADXL380/ADXL382 is a low noise density, low power, 3-axis - accelerometer with selectable measurement ranges. The ADXL380 - supports the ±4 g, ±8 g, and ±16 g ranges, and the ADXL382 supports - ±15 g, ±30 g, and ±60 g ranges. + The ADXL380/ADXL382 and ADXL318/ADXL319 are low noise density, + low power, 3-axis accelerometers with selectable measurement ranges. + The ADXL380 and ADXL318 support the ±4 g, ±8 g, and ±16 g ranges, + while the ADXL382 and ADXL319 support ±15 g, ±30 g, and ±60 g ranges. + https://www.analog.com/en/products/adxl318.html https://www.analog.com/en/products/adxl380.html properties: compatible: enum: + - adi,adxl318 + - adi,adxl319 - adi,adxl380 - adi,adxl382 diff --git a/Documentation/devicetree/bindings/iio/accel/bosch,bma220.yaml b/Documentation/devicetree/bindings/iio/accel/bosch,bma220.yaml index ec643de031a34..8c820c27f781e 100644 --- a/Documentation/devicetree/bindings/iio/accel/bosch,bma220.yaml +++ b/Documentation/devicetree/bindings/iio/accel/bosch,bma220.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/iio/accel/bosch,bma220.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Bosch BMA220 Trixial Acceleration Sensor +title: Bosch BMA220 Triaxial Acceleration Sensor maintainers: - Jonathan Cameron @@ -20,6 +20,9 @@ properties: interrupts: maxItems: 1 + spi-cpha: true + spi-cpol: true + vdda-supply: true vddd-supply: true vddio-supply: true @@ -44,8 +47,10 @@ examples: compatible = "bosch,bma220"; reg = <0>; spi-max-frequency = <2500000>; + spi-cpol; + spi-cpha; interrupt-parent = <&gpio0>; - interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; }; }; ... diff --git a/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml b/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml index 85c9537f1f029..c1387e02eb826 100644 --- a/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml +++ b/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Bosch BMA255 and Similar Accelerometers maintainers: - - Linus Walleij + - Linus Walleij - Stephan Gerhold description: diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml index ed849ba1b77bc..ccd6a0ac1539e 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml @@ -26,6 +26,11 @@ properties: compatible: enum: - adi,ad4080 + - adi,ad4081 + - adi,ad4083 + - adi,ad4084 + - adi,ad4086 + - adi,ad4087 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml index 8dae89ecb64d7..b91bfb16ed6bc 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml @@ -30,7 +30,6 @@ description: | * https://www.analog.com/en/products/adaq4380-4.html * https://www.analog.com/en/products/adaq4381-4.html - $ref: /schemas/spi/spi-peripheral-props.yaml# properties: diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml index 1180d2ffbf846..73c8e9c532f39 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml @@ -166,7 +166,6 @@ properties: An example of backend can be found at http://analogdevicesinc.github.io/hdl/library/axi_ad7606x/index.html - patternProperties: "^channel@[1-8]$": type: object diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7949.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7949.yaml index 9ee4d977c5edf..238a8c9c41437 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7949.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7949.yaml @@ -48,7 +48,6 @@ properties: enum: [2500000, 4096000] default: 4096000 - '#io-channel-cells': const: 1 diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ade9000.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ade9000.yaml index bd429552d568a..f22eba0250ee5 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ade9000.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ade9000.yaml @@ -57,7 +57,6 @@ properties: description: External clock source when not using crystal maxItems: 1 - "#clock-cells": description: ADE9000 can provide clock output via CLKOUT pin with external buffer. diff --git a/Documentation/devicetree/bindings/iio/adc/adi,max14001.yaml b/Documentation/devicetree/bindings/iio/adc/adi,max14001.yaml new file mode 100644 index 0000000000000..a2dc59c9dcd86 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,max14001.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2023-2025 Analog Devices Inc. +# Copyright 2023 Kim Seer Paller +# Copyright 2025 Marilene Andrade Garcia +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,max14001.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices MAX14001-MAX14002 ADC + +maintainers: + - Kim Seer Paller + - Marilene Andrade Garcia + +description: | + Single channel 10 bit ADC with SPI interface. + Datasheet can be found here + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX14001-MAX14002.pdf + +$ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + oneOf: + - const: adi,max14002 + - items: + - const: adi,max14001 + - const: adi,max14002 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 5000000 + + vdd-supply: + description: + Isolated DC-DC power supply input voltage. + + vddl-supply: + description: + Logic power supply. + + refin-supply: + description: + ADC voltage reference supply. + + interrupts: + minItems: 1 + items: + - description: | + cout: comparator output signal that asserts high on the COUT pin + when ADC readings exceed the upper threshold and low when readings + fall below the lower threshold. + - description: | + fault: when fault reporting is enabled, the FAULT pin is asserted + low whenever one of the monitored fault conditions occurs. + + interrupt-names: + minItems: 1 + items: + - const: cout + - const: fault + +required: + - compatible + - reg + - vdd-supply + - vddl-supply + +unevaluatedProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,max14001", "adi,max14002"; + reg = <0>; + spi-max-frequency = <5000000>; + spi-lsb-first; + vdd-supply = <&vdd>; + vddl-supply = <&vddl>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml index 5c08d8b6e9951..509bfb1007c46 100644 --- a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml @@ -29,6 +29,8 @@ properties: enum: - aspeed,ast2600-adc0 - aspeed,ast2600-adc1 + - aspeed,ast2700-adc0 + - aspeed,ast2700-adc1 description: Their trimming data, which is used to calibrate internal reference volage, locates in different address of OTP. diff --git a/Documentation/devicetree/bindings/iio/adc/cosmic,10001-adc.yaml b/Documentation/devicetree/bindings/iio/adc/cosmic,10001-adc.yaml index 4e695b97d0156..9ea44ce63f258 100644 --- a/Documentation/devicetree/bindings/iio/adc/cosmic,10001-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/cosmic,10001-adc.yaml @@ -36,7 +36,6 @@ properties: "#io-channel-cells": const: 1 - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml b/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml index 14363389f30ae..d9e825e5054fe 100644 --- a/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml @@ -42,6 +42,7 @@ properties: - mediatek,mt8183-auxadc - mediatek,mt8186-auxadc - mediatek,mt8188-auxadc + - mediatek,mt8189-auxadc - mediatek,mt8195-auxadc - mediatek,mt8516-auxadc - const: mediatek,mt8173-auxadc diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,pm8018-adc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,pm8018-adc.yaml index 58ea1ca4a5ee8..c978c3a3e31af 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,pm8018-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/qcom,pm8018-adc.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm's PM8xxx voltage XOADC maintainers: - - Linus Walleij + - Linus Walleij description: | The Qualcomm PM8xxx PMICs contain a HK/XO ADC (Housekeeping/Crystal diff --git a/Documentation/devicetree/bindings/iio/adc/renesas,r9a09g077-adc.yaml b/Documentation/devicetree/bindings/iio/adc/renesas,r9a09g077-adc.yaml new file mode 100644 index 0000000000000..dc0206b282315 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/renesas,r9a09g077-adc.yaml @@ -0,0 +1,135 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/renesas,r9a09g077-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/T2H / RZ/N2H ADC12 + +maintainers: + - Cosmin Tanislav + +description: | + A/D Converter block is a successive approximation analog-to-digital converter + with a 12-bit accuracy. Up to 16 analog input channels can be selected. + Conversions can be performed in single or continuous mode. Result of the ADC + is stored in a 16-bit data register corresponding to each channel. + +properties: + compatible: + oneOf: + - items: + - const: renesas,r9a09g087-adc # RZ/N2H + - const: renesas,r9a09g077-adc # RZ/T2H + - items: + - const: renesas,r9a09g077-adc # RZ/T2H + + reg: + maxItems: 1 + + interrupts: + items: + - description: A/D scan end interrupt + - description: A/D scan end interrupt for Group B + - description: A/D scan end interrupt for Group C + - description: Window A compare match + - description: Window B compare match + - description: Compare match + - description: Compare mismatch + + interrupt-names: + items: + - const: adi + - const: gbadi + - const: gcadi + - const: cmpai + - const: cmpbi + - const: wcmpm + - const: wcmpum + + clocks: + items: + - description: Converter clock + - description: Peripheral clock + + clock-names: + items: + - const: adclk + - const: pclk + + power-domains: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + "#io-channel-cells": + const: 1 + +patternProperties: + "^channel@[0-9a-f]$": + $ref: adc.yaml + type: object + description: The external channels which are connected to the ADC. + + properties: + reg: + description: The channel number. + maximum: 15 + + required: + - reg + + additionalProperties: false + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - power-domains + +additionalProperties: false + +examples: + - | + #include + #include + + adc@80008000 { + compatible = "renesas,r9a09g077-adc"; + reg = <0x80008000 0x400>; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "adi", "gbadi", "gcadi", + "cmpai", "cmpbi", "wcmpm", "wcmpum"; + clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKL>, + <&cpg CPG_MOD 225>; + clock-names = "adclk", "pclk"; + power-domains = <&cpg>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + + channel@0 { + reg = <0x0>; + }; + channel@1 { + reg = <0x1>; + }; + channel@2 { + reg = <0x2>; + }; + channel@3 { + reg = <0x3>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/renesas,rzn1-adc.yaml b/Documentation/devicetree/bindings/iio/adc/renesas,rzn1-adc.yaml new file mode 100644 index 0000000000000..1a40352165fb0 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/renesas,rzn1-adc.yaml @@ -0,0 +1,111 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/renesas,rzn1-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/N1 Analog to Digital Converter (ADC) + +maintainers: + - Herve Codina + +description: + The Renesas RZ/N1 ADC controller available in the Renesas RZ/N1 SoCs family + can use up to two internal ADC cores (ADC1 and ADC2) those internal cores are + handled through ADC controller virtual channels. + +properties: + compatible: + items: + - const: renesas,r9a06g032-adc # RZ/N1D + - const: renesas,rzn1-adc + + reg: + maxItems: 1 + + clocks: + items: + - description: APB internal bus clock + - description: ADC clock + + clock-names: + items: + - const: pclk + - const: adc + + power-domains: + maxItems: 1 + + adc1-avdd-supply: + description: + ADC1 analog power supply. + + adc1-vref-supply: + description: + ADC1 reference voltage supply. + + adc2-avdd-supply: + description: + ADC2 analog power supply. + + adc2-vref-supply: + description: + ADC2 reference voltage supply. + + '#io-channel-cells': + const: 1 + description: | + Channels numbers available: + if ADC1 is used (i.e. adc1-{avdd,vref}-supply present): + - 0: ADC1 IN0 + - 1: ADC1 IN1 + - 2: ADC1 IN2 + - 3: ADC1 IN3 + - 4: ADC1 IN4 + - 5: ADC1 IN6 + - 6: ADC1 IN7 + - 7: ADC1 IN8 + if ADC2 is used (i.e. adc2-{avdd,vref}-supply present): + - 8: ADC2 IN0 + - 9: ADC2 IN1 + - 10: ADC2 IN2 + - 11: ADC2 IN3 + - 12: ADC2 IN4 + - 13: ADC2 IN6 + - 14: ADC2 IN7 + - 15: ADC2 IN8 + +required: + - compatible + - reg + - clocks + - clock-names + - power-domains + - '#io-channel-cells' + +# At least one of avvd/vref supplies +anyOf: + - required: + - adc1-vref-supply + - adc1-avdd-supply + - required: + - adc2-vref-supply + - adc2-avdd-supply + +additionalProperties: false + +examples: + - | + #include + + adc: adc@40065000 { + compatible = "renesas,r9a06g032-adc", "renesas,rzn1-adc"; + reg = <0x40065000 0x200>; + clocks = <&sysctrl R9A06G032_HCLK_ADC>, <&sysctrl R9A06G032_CLK_ADC>; + clock-names = "pclk", "adc"; + power-domains = <&sysctrl>; + adc1-avdd-supply = <&adc1_avdd>; + adc1-vref-supply = <&adc1_vref>; + #io-channel-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml index f776041fd08f8..6769d679c9073 100644 --- a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml @@ -16,6 +16,9 @@ properties: - const: rockchip,rk3066-tsadc - const: rockchip,rk3399-saradc - const: rockchip,rk3528-saradc + - items: + - const: rockchip,rk3506-saradc + - const: rockchip,rk3528-saradc - const: rockchip,rk3562-saradc - const: rockchip,rk3588-saradc - items: diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml index 17bb60e18a1c2..c4c4575d3fa96 100644 --- a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml @@ -456,7 +456,6 @@ patternProperties: items: minimum: 40 - - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml b/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml index 1caa896fce821..de91cb03fdc6a 100644 --- a/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/x-powers,axp209-adc.yaml @@ -57,7 +57,6 @@ description: | 4 | batt_dischrg_i 5 | ts_v - properties: compatible: oneOf: diff --git a/Documentation/devicetree/bindings/iio/afe/voltage-divider.yaml b/Documentation/devicetree/bindings/iio/afe/voltage-divider.yaml index 4151f99b42aa7..9752d14500641 100644 --- a/Documentation/devicetree/bindings/iio/afe/voltage-divider.yaml +++ b/Documentation/devicetree/bindings/iio/afe/voltage-divider.yaml @@ -29,7 +29,6 @@ description: | | GND - properties: compatible: const: voltage-divider diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5446.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5446.yaml new file mode 100644 index 0000000000000..2669d2c4948bb --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5446.yaml @@ -0,0 +1,138 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/dac/adi,ad5446.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD5446 and similar DACs + +maintainers: + - Michael Hennerich + - Nuno Sá + +description: + Digital to Analog Converter devices supporting both SPI and I2C interfaces. + These devices feature a range of resolutions from 8-bit to 16-bit. + +properties: + compatible: + oneOf: + - description: SPI DACs + enum: + - adi,ad5300 + - adi,ad5310 + - adi,ad5320 + - adi,ad5444 + - adi,ad5446 + - adi,ad5450 + - adi,ad5451 + - adi,ad5452 + - adi,ad5453 + - adi,ad5512a + - adi,ad5541a + - adi,ad5542 + - adi,ad5542a + - adi,ad5543 + - adi,ad5553 + - adi,ad5600 + - adi,ad5601 + - adi,ad5611 + - adi,ad5621 + - adi,ad5641 + - adi,ad5620-2500 + - adi,ad5620-1250 + - adi,ad5640-2500 + - adi,ad5640-1250 + - adi,ad5660-2500 + - adi,ad5660-1250 + - adi,ad5662 + - ti,dac081s101 + - ti,dac101s101 + - ti,dac121s101 + - description: I2C DACs + enum: + - adi,ad5301 + - adi,ad5311 + - adi,ad5321 + - adi,ad5602 + - adi,ad5612 + - adi,ad5622 + + reg: + maxItems: 1 + + vcc-supply: + description: + Reference voltage supply. If not supplied, devices with internal + voltage reference will use that. + +required: + - compatible + - reg + +allOf: + - if: + properties: + compatible: + contains: + enum: + - adi,ad5300 + - adi,ad5310 + - adi,ad5320 + - adi,ad5444 + - adi,ad5446 + - adi,ad5450 + - adi,ad5451 + - adi,ad5452 + - adi,ad5453 + - adi,ad5512a + - adi,ad5541a + - adi,ad5542 + - adi,ad5542a + - adi,ad5543 + - adi,ad5553 + - adi,ad5600 + - adi,ad5601 + - adi,ad5611 + - adi,ad5621 + - adi,ad5641 + - adi,ad5620-2500 + - adi,ad5620-1250 + - adi,ad5640-2500 + - adi,ad5640-1250 + - adi,ad5660-2500 + - adi,ad5660-1250 + - adi,ad5662 + - ti,dac081s101 + - ti,dac101s101 + - ti,dac121s101 + then: + allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + dac@0 { + compatible = "adi,ad5446"; + reg = <0>; + vcc-supply = <&dac_vref>; + }; + }; + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + dac@42 { + compatible = "adi,ad5622"; + reg = <0x42>; + vcc-supply = <&dac_vref>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml index 64f2352aac3d5..ca40359a3944a 100644 --- a/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml +++ b/Documentation/devicetree/bindings/iio/frequency/adi,admv4420.yaml @@ -37,7 +37,6 @@ required: - compatible - reg - allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# diff --git a/Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml b/Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml index f3242dc0e7e64..3a307ac50aa7f 100644 --- a/Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml +++ b/Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Invensense MPU-3050 Gyroscope maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml b/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml index 967778fb0ce89..d4753c85ecc3f 100644 --- a/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml +++ b/Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml @@ -27,6 +27,14 @@ properties: LED current whilst the engine is running. First indexed value is the configuration for the RED LED, and second value is for the IR LED. + maxim,pulse-width-us: + description: | + LED pulse width in microseconds. Appropriate pulse width depends on + factors such as optical window absorption, LED-to-sensor distance, + and expected reflectivity of the skin or contact surface. + enum: [200, 400, 800, 1600] + default: 1600 + additionalProperties: false required: diff --git a/Documentation/devicetree/bindings/iio/imu/bosch,smi330.yaml b/Documentation/devicetree/bindings/iio/imu/bosch,smi330.yaml new file mode 100644 index 0000000000000..0270ca456d2bc --- /dev/null +++ b/Documentation/devicetree/bindings/iio/imu/bosch,smi330.yaml @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/imu/bosch,smi330.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bosch SMI330 6-Axis IMU + +maintainers: + - Stefan Gutmann + +description: + SMI330 is a 6-axis inertial measurement unit that supports acceleration and + gyroscopic measurements with hardware fifo buffering. Sensor also provides + events information such as motion, no-motion and tilt detection. + +properties: + compatible: + const: bosch,smi330 + + reg: + maxItems: 1 + + vdd-supply: + description: provide VDD power to the sensor. + + vddio-supply: + description: provide VDD IO power to the sensor. + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + minItems: 1 + maxItems: 2 + items: + enum: + - INT1 + - INT2 + + drive-open-drain: + type: boolean + description: + set if the interrupt pin(s) should be configured as + open drain. If not set, defaults to push-pull. + +required: + - compatible + - reg + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + // Example for I2C + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + imu@68 { + compatible = "bosch,smi330"; + reg = <0x68>; + vddio-supply = <&vddio>; + vdd-supply = <&vdd>; + interrupt-parent = <&gpio>; + interrupts = <26 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "INT1"; + }; + }; + + // Example for SPI + #include + spi { + #address-cells = <1>; + #size-cells = <0>; + + imu@0 { + compatible = "bosch,smi330"; + reg = <0>; + spi-max-frequency = <10000000>; + interrupt-parent = <&gpio>; + interrupts = <26 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "INT1"; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,icm45600.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,icm45600.yaml new file mode 100644 index 0000000000000..e0b78d14420fe --- /dev/null +++ b/Documentation/devicetree/bindings/iio/imu/invensense,icm45600.yaml @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/imu/invensense,icm45600.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: InvenSense ICM-45600 Inertial Measurement Unit + +maintainers: + - Remi Buisson + +description: | + 6-axis MotionTracking device that combines a 3-axis gyroscope and a 3-axis + accelerometer. + + It has a configurable host interface that supports I3C, I2C and SPI serial + communication, features up to 8kB FIFO and 2 programmable interrupts with + ultra-low-power wake-on-motion support to minimize system power consumption. + + Other industry-leading features include InvenSense on-chip APEX Motion + Processing engine for gesture recognition, activity classification, and + pedometer, along with programmable digital filters, and an embedded + temperature sensor. + + https://invensense.tdk.com/wp-content/uploads/documentation/DS-000576_ICM-45605.pdf + +properties: + compatible: + enum: + - invensense,icm45605 + - invensense,icm45606 + - invensense,icm45608 + - invensense,icm45634 + - invensense,icm45686 + - invensense,icm45687 + - invensense,icm45688p + - invensense,icm45689 + + reg: + maxItems: 1 + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + minItems: 1 + items: + - enum: [int1, int2] + - const: int2 + description: Choose chip interrupt pin to be used as interrupt input. + + drive-open-drain: + type: boolean + + vdd-supply: true + + vddio-supply: true + + mount-matrix: true + +required: + - compatible + - reg + - vdd-supply + - vddio-supply + +unevaluatedProperties: false + +examples: + - | + #include + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + imu@68 { + compatible = "invensense,icm45605"; + reg = <0x68>; + interrupt-parent = <&gpio2>; + interrupt-names = "int1"; + interrupts = <7 IRQ_TYPE_EDGE_RISING>; + vdd-supply = <&vdd>; + vddio-supply = <&vddio>; + mount-matrix = "0", "-1", "0", + "1", "0", "0", + "0", "0", "1"; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml index 0bce71529e34c..1af0855c33e67 100644 --- a/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml +++ b/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml @@ -86,7 +86,6 @@ unevaluatedProperties: false required: - compatible - reg - - interrupts examples: - | diff --git a/Documentation/devicetree/bindings/iio/light/capella,cm3605.yaml b/Documentation/devicetree/bindings/iio/light/capella,cm3605.yaml index c63b79c3351bf..01376c386a034 100644 --- a/Documentation/devicetree/bindings/iio/light/capella,cm3605.yaml +++ b/Documentation/devicetree/bindings/iio/light/capella,cm3605.yaml @@ -8,7 +8,7 @@ title: Capella Microsystems CM3605 Ambient Light and Short Distance Proximity Sensor maintainers: - - Linus Walleij + - Linus Walleij - Kevin Tsai description: | diff --git a/Documentation/devicetree/bindings/iio/light/sharp,gp2ap002.yaml b/Documentation/devicetree/bindings/iio/light/sharp,gp2ap002.yaml index f8a932be0d103..99bddf31cbed2 100644 --- a/Documentation/devicetree/bindings/iio/light/sharp,gp2ap002.yaml +++ b/Documentation/devicetree/bindings/iio/light/sharp,gp2ap002.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Sharp GP2AP002A00F and GP2AP002S00F proximity and ambient light sensors maintainers: - - Linus Walleij + - Linus Walleij description: | Proximity and ambient light sensor with IR LED for the proximity diff --git a/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8974.yaml b/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8974.yaml index cefb70def1886..f6b4d98741904 100644 --- a/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8974.yaml +++ b/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8974.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Asahi Kasei AK8974 magnetometer sensor maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/iio/magnetometer/yamaha,yas530.yaml b/Documentation/devicetree/bindings/iio/magnetometer/yamaha,yas530.yaml index 877226e9219ba..5cbf60f3b08b5 100644 --- a/Documentation/devicetree/bindings/iio/magnetometer/yamaha,yas530.yaml +++ b/Documentation/devicetree/bindings/iio/magnetometer/yamaha,yas530.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Yamaha YAS530 family of magnetometer sensors maintainers: - - Linus Walleij + - Linus Walleij description: The Yamaha YAS530 magnetometers is a line of 3-axis magnetometers diff --git a/Documentation/devicetree/bindings/iio/pressure/aosong,adp810.yaml b/Documentation/devicetree/bindings/iio/pressure/aosong,adp810.yaml new file mode 100644 index 0000000000000..ad5f26ce50432 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/pressure/aosong,adp810.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/pressure/aosong,adp810.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: aosong adp810 differential pressure sensor + +maintainers: + - Akhilesh Patil + +description: + ADP810 is differential pressure and temperature sensor. It has I2C bus + interface with fixed address of 0x25. This sensor supports 8 bit CRC for + reliable data transfer. It can measure differential pressure in the + range -500 to 500Pa and temperate in the range -40 to +85 degree celsius. + +properties: + compatible: + enum: + - aosong,adp810 + + reg: + maxItems: 1 + + vdd-supply: true + +required: + - compatible + - reg + - vdd-supply + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + pressure-sensor@25 { + compatible = "aosong,adp810"; + reg = <0x25>; + vdd-supply = <&vdd_regulator>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/pressure/fsl,mpl3115.yaml b/Documentation/devicetree/bindings/iio/pressure/fsl,mpl3115.yaml new file mode 100644 index 0000000000000..2933c2e10695e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/pressure/fsl,mpl3115.yaml @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/pressure/fsl,mpl3115.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MPL3115 precision pressure sensor with altimetry + +maintainers: + - Antoni Pokusinski + +description: | + MPL3115 is a pressure/altitude and temperature sensor with I2C interface. + It features two programmable interrupt lines which indicate events such as + data ready or pressure/temperature threshold reached. + https://www.nxp.com/docs/en/data-sheet/MPL3115A2.pdf + +properties: + compatible: + const: fsl,mpl3115 + + reg: + maxItems: 1 + + vdd-supply: true + + vddio-supply: true + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + minItems: 1 + maxItems: 2 + items: + enum: + - INT1 + - INT2 + + drive-open-drain: + type: boolean + description: + set if the specified interrupt pins should be configured as + open drain. If not set, defaults to push-pull. + +required: + - compatible + - reg + - vdd-supply + - vddio-supply + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pressure@60 { + compatible = "fsl,mpl3115"; + reg = <0x60>; + vdd-supply = <&vdd>; + vddio-supply = <&vddio>; + interrupt-parent = <&gpio1>; + interrupts = <4 IRQ_TYPE_EDGE_FALLING>; + interrupt-names = "INT2"; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/pressure/infineon,dps310.yaml b/Documentation/devicetree/bindings/iio/pressure/infineon,dps310.yaml new file mode 100644 index 0000000000000..e5d1e6c489393 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/pressure/infineon,dps310.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/pressure/infineon,dps310.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Infineon DPS310 barometric pressure and temperature sensor + +maintainers: + - Eddie James + +description: + The DPS310 is a barometric pressure and temperature sensor with an I2C + interface. + +properties: + compatible: + enum: + - infineon,dps310 + + reg: + maxItems: 1 + + "#io-channel-cells": + const: 0 + + vdd-supply: + description: + Voltage supply for the chip's analog blocks. + + vddio-supply: + description: + Digital voltage supply for the chip's digital blocks and I/O interface. + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + dps: pressure-sensor@76 { + compatible = "infineon,dps310"; + reg = <0x76>; + #io-channel-cells = <0>; + vdd-supply = <&vref1>; + vddio-supply = <&vref2>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/pressure/murata,zpa2326.yaml b/Documentation/devicetree/bindings/iio/pressure/murata,zpa2326.yaml index c33640ddde586..886f4129c301a 100644 --- a/Documentation/devicetree/bindings/iio/pressure/murata,zpa2326.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/murata,zpa2326.yaml @@ -12,7 +12,6 @@ maintainers: description: | Pressure sensor from Murata with SPI and I2C bus interfaces. - properties: compatible: const: murata,zpa2326 diff --git a/Documentation/devicetree/bindings/iio/proximity/semtech,sx9324.yaml b/Documentation/devicetree/bindings/iio/proximity/semtech,sx9324.yaml index 48f2214631665..8fed45ee557bf 100644 --- a/Documentation/devicetree/bindings/iio/proximity/semtech,sx9324.yaml +++ b/Documentation/devicetree/bindings/iio/proximity/semtech,sx9324.yaml @@ -78,7 +78,6 @@ properties: minItems: 3 maxItems: 3 - semtech,ph01-resolution: $ref: /schemas/types.yaml#/definitions/uint32 enum: [8, 16, 32, 64, 128, 256, 512, 1024] diff --git a/Documentation/devicetree/bindings/iio/st,st-sensors.yaml b/Documentation/devicetree/bindings/iio/st,st-sensors.yaml index e955eb8e87979..a1a958215cdb7 100644 --- a/Documentation/devicetree/bindings/iio/st,st-sensors.yaml +++ b/Documentation/devicetree/bindings/iio/st,st-sensors.yaml @@ -14,7 +14,7 @@ description: The STMicroelectronics sensor devices are pretty straight-forward maintainers: - Denis Ciocca - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml index 312febeeb3bba..a22725f7619b7 100644 --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml @@ -39,7 +39,6 @@ $defs: - reg - adi,sensor-type - properties: compatible: oneOf: @@ -88,7 +87,7 @@ properties: const: 0 patternProperties: - "^thermocouple@": + '^thermocouple@': $ref: '#/$defs/sensor-node' unevaluatedProperties: false @@ -146,7 +145,7 @@ patternProperties: required: - adi,custom-thermocouple - "^diode@": + '^diode@': $ref: '#/$defs/sensor-node' unevaluatedProperties: false @@ -191,7 +190,7 @@ patternProperties: $ref: /schemas/types.yaml#/definitions/uint32 default: 0 - "^rtd@": + '^rtd@': $ref: '#/$defs/sensor-node' unevaluatedProperties: false description: RTD sensor. @@ -280,7 +279,7 @@ patternProperties: type: boolean dependencies: - adi,current-rotate: [ "adi,rsense-share" ] + adi,current-rotate: [ 'adi,rsense-share' ] - if: properties: @@ -290,7 +289,7 @@ patternProperties: required: - adi,custom-rtd - "^thermistor@": + '^thermistor@': $ref: '#/$defs/sensor-node' unevaluatedProperties: false description: Thermistor sensor. @@ -364,7 +363,7 @@ patternProperties: - adi,rsense-handle dependencies: - adi,current-rotate: [ "adi,rsense-share" ] + adi,current-rotate: [ 'adi,rsense-share' ] allOf: - if: @@ -392,7 +391,7 @@ patternProperties: required: - adi,custom-thermistor - "^adc@": + '^adc@': $ref: '#/$defs/sensor-node' unevaluatedProperties: false description: Direct ADC sensor. @@ -407,7 +406,7 @@ patternProperties: description: Whether the sensor is single-ended. type: boolean - "^temp@": + '^temp@': $ref: '#/$defs/sensor-node' unevaluatedProperties: false description: Active analog temperature sensor. @@ -437,7 +436,7 @@ patternProperties: required: - adi,custom-temp - "^rsense@": + '^rsense@': $ref: '#/$defs/sensor-node' unevaluatedProperties: false description: Sense resistor sensor. @@ -476,7 +475,7 @@ allOf: - adi,ltc2984 then: patternProperties: - "^temp@": false + '^temp@': false examples: - | diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml b/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml index d79b254f1cde4..9bf07acea5999 100644 --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml @@ -8,7 +8,7 @@ title: Atmel maXTouch touchscreen/touchpad maintainers: - Nick Dyer - - Linus Walleij + - Linus Walleij description: | Atmel maXTouch touchscreen or touchpads such as the mXT244 diff --git a/Documentation/devicetree/bindings/input/cypress,cyapa.yaml b/Documentation/devicetree/bindings/input/cypress,cyapa.yaml index 29515151abe98..da629d511da19 100644 --- a/Documentation/devicetree/bindings/input/cypress,cyapa.yaml +++ b/Documentation/devicetree/bindings/input/cypress,cyapa.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Cypress All Points Addressable (APA) I2C Touchpad / Trackpad maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski properties: compatible: diff --git a/Documentation/devicetree/bindings/input/ti,drv266x.yaml b/Documentation/devicetree/bindings/input/ti,drv266x.yaml index da18188243738..1bce389d0e5c9 100644 --- a/Documentation/devicetree/bindings/input/ti,drv266x.yaml +++ b/Documentation/devicetree/bindings/input/ti,drv266x.yaml @@ -37,7 +37,6 @@ examples: - | #include - i2c { #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/input/ti,twl4030-keypad.yaml b/Documentation/devicetree/bindings/input/ti,twl4030-keypad.yaml new file mode 100644 index 0000000000000..c69aa7f5cca78 --- /dev/null +++ b/Documentation/devicetree/bindings/input/ti,twl4030-keypad.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/ti,twl4030-keypad.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TWL4030-family Keypad Controller + +maintainers: + - Peter Ujfalusi + +description: + TWL4030's Keypad controller is used to interface a SoC with a matrix-type + keypad device. The keypad controller supports multiple row and column lines. + A key can be placed at each intersection of a unique row and a unique column. + The keypad controller can sense a key-press and key-release and report the + event using a interrupt to the cpu. + +allOf: + - $ref: matrix-keymap.yaml# + +properties: + compatible: + const: ti,twl4030-keypad + + interrupts: + maxItems: 1 + +required: + - compatible + - interrupts + - keypad,num-rows + - keypad,num-columns + - linux,keymap + +unevaluatedProperties: false + +examples: + - | + #include + + keypad { + compatible = "ti,twl4030-keypad"; + interrupts = <1>; + keypad,num-rows = <8>; + keypad,num-columns = <8>; + linux,keymap = < + /* row 0 */ + MATRIX_KEY(0, 0, KEY_1) + MATRIX_KEY(0, 1, KEY_2) + MATRIX_KEY(0, 2, KEY_3) + + /* ...and so on for a full 8x8 matrix... */ + + /* row 7 */ + MATRIX_KEY(7, 6, KEY_Y) + MATRIX_KEY(7, 7, KEY_Z) + >; + }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/ar1021.txt b/Documentation/devicetree/bindings/input/touchscreen/ar1021.txt deleted file mode 100644 index 82019bd6094ee..0000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/ar1021.txt +++ /dev/null @@ -1,15 +0,0 @@ -* Microchip AR1020 and AR1021 touchscreen interface (I2C) - -Required properties: -- compatible : "microchip,ar1021-i2c" -- reg : I2C slave address -- interrupts : touch controller interrupt - -Example: - - touchscreen@4d { - compatible = "microchip,ar1021-i2c"; - reg = <0x4d>; - interrupt-parent = <&gpio3>; - interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; - }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/azoteq,iqs5xx.yaml b/Documentation/devicetree/bindings/input/touchscreen/azoteq,iqs5xx.yaml deleted file mode 100644 index b5f377215c098..0000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/azoteq,iqs5xx.yaml +++ /dev/null @@ -1,75 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/input/touchscreen/azoteq,iqs5xx.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Azoteq IQS550/572/525 Trackpad/Touchscreen Controller - -maintainers: - - Jeff LaBundy - -description: | - The Azoteq IQS550, IQS572 and IQS525 trackpad and touchscreen controllers - employ projected-capacitance sensing and can track up to five independent - contacts. - - Link to datasheet: https://www.azoteq.com/ - -allOf: - - $ref: touchscreen.yaml# - -properties: - compatible: - enum: - - azoteq,iqs550 - - azoteq,iqs572 - - azoteq,iqs525 - - reg: - maxItems: 1 - - interrupts: - maxItems: 1 - - reset-gpios: - maxItems: 1 - - wakeup-source: true - - touchscreen-size-x: true - touchscreen-size-y: true - touchscreen-inverted-x: true - touchscreen-inverted-y: true - touchscreen-swapped-x-y: true - -required: - - compatible - - reg - - interrupts - -additionalProperties: false - -examples: - - | - #include - #include - - i2c { - #address-cells = <1>; - #size-cells = <0>; - - touchscreen@74 { - compatible = "azoteq,iqs550"; - reg = <0x74>; - interrupt-parent = <&gpio>; - interrupts = <27 IRQ_TYPE_LEVEL_HIGH>; - reset-gpios = <&gpio 22 (GPIO_ACTIVE_LOW | - GPIO_PUSH_PULL)>; - - touchscreen-size-x = <800>; - touchscreen-size-y = <480>; - }; - }; - -... diff --git a/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma140.yaml b/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma140.yaml index 86a6d18f952a0..afeab49a9544f 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma140.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma140.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Cypress CY8CTMA140 series touchscreen controller maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: touchscreen.yaml# diff --git a/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma340.yaml b/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma340.yaml index 4dfbb93678b56..a0b8c12977a19 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma340.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma340.yaml @@ -12,7 +12,7 @@ description: The Cypress CY8CTMA340 series (also known as "CYTTSP" after maintainers: - Javier Martinez Canillas - - Linus Walleij + - Linus Walleij allOf: - $ref: touchscreen.yaml# diff --git a/Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml b/Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml deleted file mode 100644 index f5cfacb5e966d..0000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml +++ /dev/null @@ -1,64 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/input/touchscreen/himax,hx83112b.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Himax hx83112b touchscreen controller - -maintainers: - - Job Noorman - -allOf: - - $ref: touchscreen.yaml# - -properties: - compatible: - enum: - - himax,hx83100a - - himax,hx83112b - - reg: - maxItems: 1 - - interrupts: - maxItems: 1 - - reset-gpios: - maxItems: 1 - - touchscreen-inverted-x: true - touchscreen-inverted-y: true - touchscreen-size-x: true - touchscreen-size-y: true - touchscreen-swapped-x-y: true - -additionalProperties: false - -required: - - compatible - - reg - - interrupts - - reset-gpios - - touchscreen-size-x - - touchscreen-size-y - -examples: - - | - #include - #include - i2c { - #address-cells = <1>; - #size-cells = <0>; - touchscreen@48 { - compatible = "himax,hx83112b"; - reg = <0x48>; - interrupt-parent = <&tlmm>; - interrupts = <65 IRQ_TYPE_LEVEL_LOW>; - touchscreen-size-x = <1080>; - touchscreen-size-y = <2160>; - reset-gpios = <&tlmm 64 GPIO_ACTIVE_LOW>; - }; - }; - -... diff --git a/Documentation/devicetree/bindings/input/touchscreen/hynitron,cstxxx.yaml b/Documentation/devicetree/bindings/input/touchscreen/hynitron,cstxxx.yaml deleted file mode 100644 index 9cb5d4af00f75..0000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/hynitron,cstxxx.yaml +++ /dev/null @@ -1,65 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/input/touchscreen/hynitron,cstxxx.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Hynitron cstxxx series touchscreen controller - -description: | - Bindings for Hynitron cstxxx series multi-touch touchscreen - controllers. - -maintainers: - - Chris Morgan - -allOf: - - $ref: touchscreen.yaml# - -properties: - compatible: - enum: - - hynitron,cst340 - - reg: - maxItems: 1 - - interrupts: - maxItems: 1 - - reset-gpios: - maxItems: 1 - - touchscreen-size-x: true - touchscreen-size-y: true - touchscreen-inverted-x: true - touchscreen-inverted-y: true - touchscreen-swapped-x-y: true - -additionalProperties: false - -required: - - compatible - - reg - - interrupts - - reset-gpios - -examples: - - | - #include - #include - i2c { - #address-cells = <1>; - #size-cells = <0>; - touchscreen@1a { - compatible = "hynitron,cst340"; - reg = <0x1a>; - interrupt-parent = <&gpio4>; - interrupts = <9 IRQ_TYPE_EDGE_FALLING>; - reset-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; - touchscreen-size-x = <640>; - touchscreen-size-y = <480>; - }; - }; - -... diff --git a/Documentation/devicetree/bindings/input/touchscreen/ilitek_ts_i2c.yaml b/Documentation/devicetree/bindings/input/touchscreen/ilitek_ts_i2c.yaml deleted file mode 100644 index 9f73289997568..0000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/ilitek_ts_i2c.yaml +++ /dev/null @@ -1,76 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/input/touchscreen/ilitek_ts_i2c.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Ilitek I2C Touchscreen Controller - -maintainers: - - Dmitry Torokhov - -allOf: - - $ref: touchscreen.yaml# - -properties: - compatible: - enum: - - ilitek,ili210x - - ilitek,ili2117 - - ilitek,ili2120 - - ilitek,ili2130 - - ilitek,ili2131 - - ilitek,ili2132 - - ilitek,ili2316 - - ilitek,ili2322 - - ilitek,ili2323 - - ilitek,ili2326 - - ilitek,ili251x - - ilitek,ili2520 - - ilitek,ili2521 - - reg: - maxItems: 1 - - interrupts: - maxItems: 1 - - reset-gpios: - maxItems: 1 - - wakeup-source: - type: boolean - description: touchscreen can be used as a wakeup source. - - touchscreen-size-x: true - touchscreen-size-y: true - touchscreen-inverted-x: true - touchscreen-inverted-y: true - touchscreen-swapped-x-y: true - -additionalProperties: false - -required: - - compatible - - reg - - interrupts - -examples: - - | - #include - #include - i2c { - #address-cells = <1>; - #size-cells = <0>; - - touchscreen@41 { - compatible = "ilitek,ili2520"; - reg = <0x41>; - - interrupt-parent = <&gpio1>; - interrupts = <7 IRQ_TYPE_LEVEL_LOW>; - reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; - touchscreen-inverted-y; - wakeup-source; - }; - }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/maxim,max11801.yaml b/Documentation/devicetree/bindings/input/touchscreen/maxim,max11801.yaml deleted file mode 100644 index 4f528d2201992..0000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/maxim,max11801.yaml +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/input/touchscreen/maxim,max11801.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: MAXI MAX11801 Resistive touch screen controller with i2c interface - -maintainers: - - Frank Li - -properties: - compatible: - const: maxim,max11801 - - reg: - maxItems: 1 - - interrupts: - maxItems: 1 - -allOf: - - $ref: touchscreen.yaml - -required: - - compatible - - reg - - interrupts - -unevaluatedProperties: false - -examples: - - | - #include - - i2c { - #address-cells = <1>; - #size-cells = <0>; - - touchscreen@48 { - compatible = "maxim,max11801"; - reg = <0x48>; - interrupt-parent = <&gpio3>; - interrupts = <31 IRQ_TYPE_EDGE_FALLING>; - }; - }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/melfas,mip4_ts.yaml b/Documentation/devicetree/bindings/input/touchscreen/melfas,mip4_ts.yaml new file mode 100644 index 0000000000000..314be65c56caa --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/melfas,mip4_ts.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/melfas,mip4_ts.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MELFAS MIP4 Touchscreen + +maintainers: + - Ariel D'Alessandro + +properties: + compatible: + const: melfas,mip4_ts + + reg: + description: I2C address of the chip (0x48 or 0x34) + maxItems: 1 + + interrupts: + maxItems: 1 + + ce-gpios: + description: + GPIO connected to the CE (chip enable) pin of the chip (active high) + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@34 { + compatible = "melfas,mip4_ts"; + reg = <0x34>; + + interrupts-extended = <&tlmm 13 IRQ_TYPE_EDGE_FALLING>; + ce-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&touchscreen_default>; + pinctrl-names = "default"; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/input/touchscreen/melfas,mms114.yaml b/Documentation/devicetree/bindings/input/touchscreen/melfas,mms114.yaml index 90ebd4f8354c2..a8a93f755458b 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/melfas,mms114.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/melfas,mms114.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Melfas MMS114 family touchscreen controller maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: touchscreen.yaml# diff --git a/Documentation/devicetree/bindings/input/touchscreen/melfas_mip4.txt b/Documentation/devicetree/bindings/input/touchscreen/melfas_mip4.txt deleted file mode 100644 index b2ab5498e5190..0000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/melfas_mip4.txt +++ /dev/null @@ -1,20 +0,0 @@ -* MELFAS MIP4 Touchscreen - -Required properties: -- compatible: must be "melfas,mip4_ts" -- reg: I2C slave address of the chip (0x48 or 0x34) -- interrupts: interrupt to which the chip is connected - -Optional properties: -- ce-gpios: GPIO connected to the CE (chip enable) pin of the chip - -Example: - i2c@00000000 { - touchscreen: melfas_mip4@48 { - compatible = "melfas,mip4_ts"; - reg = <0x48>; - interrupt-parent = <&gpio>; - interrupts = <0 IRQ_TYPE_EDGE_FALLING>; - ce-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>; - }; - }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/semtech,sx8654.yaml b/Documentation/devicetree/bindings/input/touchscreen/semtech,sx8654.yaml deleted file mode 100644 index b2554064b6888..0000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/semtech,sx8654.yaml +++ /dev/null @@ -1,52 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/input/touchscreen/semtech,sx8654.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Semtech SX8654 I2C Touchscreen Controller - -maintainers: - - Frank Li - -properties: - compatible: - enum: - - semtech,sx8650 - - semtech,sx8654 - - semtech,sx8655 - - semtech,sx8656 - - reg: - maxItems: 1 - - interrupts: - maxItems: 1 - - reset-gpios: - maxItems: 1 - -required: - - compatible - - reg - - interrupts - -additionalProperties: false - -examples: - - | - #include - #include - - i2c { - #address-cells = <1>; - #size-cells = <0>; - - touchscreen@48 { - compatible = "semtech,sx8654"; - reg = <0x48>; - interrupt-parent = <&gpio6>; - interrupts = <3 IRQ_TYPE_EDGE_FALLING>; - reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>; - }; - }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml index c593ae63d0ecc..12256ae7df90d 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ST-Microelectronics FingerTip touchscreen controller maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: The ST-Microelectronics FingerTip device provides a basic touchscreen diff --git a/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml b/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml new file mode 100644 index 0000000000000..fa27c6754ca4e --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml @@ -0,0 +1,84 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/trivial-touch.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Trivial touch screen controller with i2c interface + +maintainers: + - Frank Li + +properties: + compatible: + enum: + # The Azoteq IQS550, IQS572 and IQS525 trackpad and touchscreen controllers + - azoteq,iqs550 + - azoteq,iqs572 + - azoteq,iqs525 + # Himax hx83100a touchscreen controller + - himax,hx83100a + # Himax hx83112b touchscreen controller + - himax,hx83112b + # Hynitron cstxxx series touchscreen controller + - hynitron,cst340 + # Ilitek I2C Touchscreen Controller + - ilitek,ili210x + - ilitek,ili2117 + - ilitek,ili2120 + - ilitek,ili2130 + - ilitek,ili2131 + - ilitek,ili2132 + - ilitek,ili2316 + - ilitek,ili2322 + - ilitek,ili2323 + - ilitek,ili2326 + - ilitek,ili251x + - ilitek,ili2520 + - ilitek,ili2521 + # MAXI MAX11801 Resistive touch screen controller with i2c interface + - maxim,max11801 + # Microchip AR1020 and AR1021 touchscreen interface (I2C) + - microchip,ar1021-i2c + # Trivial touch screen controller with i2c interface + - semtech,sx8650 + - semtech,sx8654 + - semtech,sx8655 + - semtech,sx8656 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + reset-gpios: + maxItems: 1 + + wakeup-source: true + +allOf: + - $ref: touchscreen.yaml + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@48 { + compatible = "maxim,max11801"; + reg = <0x48>; + interrupt-parent = <&gpio3>; + interrupts = <31 IRQ_TYPE_EDGE_FALLING>; + }; + }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/zinitix,bt400.yaml b/Documentation/devicetree/bindings/input/touchscreen/zinitix,bt400.yaml index 3f663ce3e44ec..f1ce837b16dfa 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/zinitix,bt400.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/zinitix,bt400.yaml @@ -12,7 +12,7 @@ description: The Zinitix BT4xx and BT5xx series of touchscreen controllers maintainers: - Michael Srba - - Linus Walleij + - Linus Walleij allOf: - $ref: touchscreen.yaml# diff --git a/Documentation/devicetree/bindings/input/twl4030-keypad.txt b/Documentation/devicetree/bindings/input/twl4030-keypad.txt deleted file mode 100644 index e4be2f76a717b..0000000000000 --- a/Documentation/devicetree/bindings/input/twl4030-keypad.txt +++ /dev/null @@ -1,27 +0,0 @@ -* TWL4030's Keypad Controller device tree bindings - -TWL4030's Keypad controller is used to interface a SoC with a matrix-type -keypad device. The keypad controller supports multiple row and column lines. -A key can be placed at each intersection of a unique row and a unique column. -The keypad controller can sense a key-press and key-release and report the -event using a interrupt to the cpu. - -This binding is based on the matrix-keymap binding with the following -changes: - - * keypad,num-rows and keypad,num-columns are required. - -Required SoC Specific Properties: -- compatible: should be one of the following - - "ti,twl4030-keypad": For controllers compatible with twl4030 keypad - controller. -- interrupt: should be one of the following - - <1>: For controllers compatible with twl4030 keypad controller. - -Example: - twl_keypad: keypad { - compatible = "ti,twl4030-keypad"; - interrupts = <1>; - keypad,num-rows = <8>; - keypad,num-columns = <8>; - }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,kaanapali-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,kaanapali-rpmh.yaml new file mode 100644 index 0000000000000..2c3b2fd81a745 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,kaanapali-rpmh.yaml @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,kaanapali-rpmh.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm RPMh Network-On-Chip Interconnect on Kaanapali + +maintainers: + - Raviteja Laggyshetty + +description: | + RPMh interconnect providers support system bandwidth requirements through + RPMh hardware accelerators known as Bus Clock Manager (BCM). The provider is + able to communicate with the BCM through the Resource State Coordinator (RSC) + associated with each execution environment. Provider nodes must point to at + least one RPMh device child node pertaining to their RSC and each provider + can map to multiple RPMh resources. + + See also: include/dt-bindings/interconnect/qcom,kaanapali-rpmh.h + +properties: + compatible: + enum: + - qcom,kaanapali-aggre-noc + - qcom,kaanapali-clk-virt + - qcom,kaanapali-cnoc-main + - qcom,kaanapali-cnoc-cfg + - qcom,kaanapali-gem-noc + - qcom,kaanapali-lpass-ag-noc + - qcom,kaanapali-lpass-lpiaon-noc + - qcom,kaanapali-lpass-lpicx-noc + - qcom,kaanapali-mc-virt + - qcom,kaanapali-mmss-noc + - qcom,kaanapali-nsp-noc + - qcom,kaanapali-pcie-anoc + - qcom,kaanapali-system-noc + + reg: + maxItems: 1 + + clocks: + minItems: 2 + maxItems: 3 + +required: + - compatible + +allOf: + - $ref: qcom,rpmh-common.yaml# + - if: + properties: + compatible: + contains: + enum: + - qcom,kaanapali-clk-virt + - qcom,kaanapali-mc-virt + then: + properties: + reg: false + else: + required: + - reg + + - if: + properties: + compatible: + contains: + enum: + - qcom,kaanapali-pcie-anoc + then: + properties: + clocks: + items: + - description: aggre-NOC PCIe AXI clock + - description: cfg-NOC PCIe a-NOC AHB clock + + - if: + properties: + compatible: + contains: + enum: + - qcom,kaanapali-aggre-noc + then: + properties: + clocks: + items: + - description: aggre UFS PHY AXI clock + - description: aggre USB3 PRIM AXI clock + - description: RPMH CC IPA clock + + - if: + properties: + compatible: + contains: + enum: + - qcom,kaanapali-aggre-noc + - qcom,kaanapali-pcie-anoc + then: + required: + - clocks + else: + properties: + clocks: false + +unevaluatedProperties: false + +examples: + - | + clk_virt: interconnect-0 { + compatible = "qcom,kaanapali-clk-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre_noc: interconnect@16e0000 { + compatible = "qcom,kaanapali-aggre-noc"; + reg = <0x016e0000 0x42400>; + #interconnect-cells = <2>; + clocks = <&gcc_aggre_ufs_phy_axi_clk>, + <&gcc_aggre_usb3_prim_axi_clk>, + <&rpmhcc_ipa_clk>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml index 256de140c03dc..17b09292000e4 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Interconnect Bandwidth Monitor maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: | Bandwidth Monitor measures current throughput on buses between various NoC @@ -25,6 +25,7 @@ properties: - const: qcom,msm8998-bwmon # BWMON v4 - items: - enum: + - qcom,kaanapali-cpu-bwmon - qcom,qcm2290-cpu-bwmon - qcom,qcs615-cpu-bwmon - qcom,qcs8300-cpu-bwmon diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml index dad3ad2fd93b8..da16d8e9bdc50 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml @@ -122,7 +122,6 @@ allOf: required: - reg - unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sa8775p-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,sa8775p-rpmh.yaml index db19fd5c57086..71428d2cce181 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,sa8775p-rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,sa8775p-rpmh.yaml @@ -33,18 +33,66 @@ properties: - qcom,sa8775p-pcie-anoc - qcom,sa8775p-system-noc + reg: + maxItems: 1 + + clocks: + minItems: 2 + maxItems: 5 + required: - compatible allOf: - $ref: qcom,rpmh-common.yaml# + - if: + properties: + compatible: + contains: + enum: + - qcom,sa8775p-aggre1-noc + then: + properties: + clocks: + items: + - description: aggre UFS PHY AXI clock + - description: aggre QUP PRIM AXI clock + - description: aggre USB2 PRIM AXI clock + - description: aggre USB3 PRIM AXI clock + - description: aggre USB3 SEC AXI clock + + - if: + properties: + compatible: + contains: + enum: + - qcom,sa8775p-aggre2-noc + then: + properties: + clocks: + items: + - description: aggre UFS CARD AXI clock + - description: RPMH CC IPA clock unevaluatedProperties: false examples: - | - aggre1_noc: interconnect-aggre1-noc { + #include + clk_virt: interconnect-clk-virt { + compatible = "qcom,sa8775p-clk-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre1_noc: interconnect@16c0000 { compatible = "qcom,sa8775p-aggre1-noc"; + reg = <0x016c0000 0x18080>; #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; + clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_QUPV3_AXI_CLK>, + <&gcc GCC_AGGRE_USB2_PRIM_AXI_CLK>, + <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>, + <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>; }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sm6350-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,sm6350-rpmh.yaml index 49eb156b08e0d..2dc16e4293a9a 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,sm6350-rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,sm6350-rpmh.yaml @@ -12,9 +12,6 @@ maintainers: description: Qualcomm RPMh-based interconnect provider on SM6350. -allOf: - - $ref: qcom,rpmh-common.yaml# - properties: compatible: enum: @@ -30,7 +27,9 @@ properties: reg: maxItems: 1 - '#interconnect-cells': true + clocks: + minItems: 1 + maxItems: 2 patternProperties: '^interconnect-[a-z0-9\-]+$': @@ -46,8 +45,6 @@ patternProperties: - qcom,sm6350-clk-virt - qcom,sm6350-compute-noc - '#interconnect-cells': true - required: - compatible @@ -57,10 +54,54 @@ required: - compatible - reg +allOf: + - $ref: qcom,rpmh-common.yaml# + - if: + properties: + compatible: + contains: + enum: + - qcom,sm6350-aggre1-noc + then: + properties: + clocks: + items: + - description: aggre UFS PHY AXI clock + + - if: + properties: + compatible: + contains: + enum: + - qcom,sm6350-aggre2-noc + then: + properties: + clocks: + items: + - description: aggre USB3 PRIM AXI clock + - description: RPMH CC IPA clock + + - if: + properties: + compatible: + contains: + enum: + - qcom,sm6350-aggre1-noc + - qcom,sm6350-aggre2-noc + then: + required: + - clocks + else: + properties: + clocks: false + unevaluatedProperties: false examples: - | + #include + #include + config_noc: interconnect@1500000 { compatible = "qcom,sm6350-config-noc"; reg = <0x01500000 0x28000>; @@ -68,14 +109,16 @@ examples: qcom,bcm-voters = <&apps_bcm_voter>; }; - system_noc: interconnect@1620000 { - compatible = "qcom,sm6350-system-noc"; - reg = <0x01620000 0x17080>; + aggre2_noc: interconnect@1700000 { + compatible = "qcom,sm6350-aggre2-noc"; + reg = <0x01700000 0x1f880>; #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; + clocks = <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>, + <&rpmhcc RPMH_IPA_CLK>; - clk_virt: interconnect-clk-virt { - compatible = "qcom,sm6350-clk-virt"; + compute_noc: interconnect-compute-noc { + compatible = "qcom,sm6350-compute-noc"; #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml index f3247a47f9eed..bfd30aae682bf 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml @@ -305,7 +305,6 @@ examples: }; }; - device@0 { reg = <0 4>; interrupts = <1 1 4 &part0>; diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,versatile-fpga-irq.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,versatile-fpga-irq.yaml index 8d581b3aac3a1..42ab873665e1e 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/arm,versatile-fpga-irq.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,versatile-fpga-irq.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM Versatile FPGA IRQ Controller maintainers: - - Linus Walleij + - Linus Walleij description: One or more FPGA IRQ controllers can be synthesized in an ARM reference board diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml index 999df5b905c5c..258d21fe6e359 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml @@ -54,7 +54,6 @@ properties: | |---... +---------+---module31 - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml index 5fda626c80ce3..2ff390c1705b8 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml @@ -34,8 +34,6 @@ properties: required: - compatible - reg - - interrupt-controller - - '#interrupt-cells' additionalProperties: false diff --git a/Documentation/devicetree/bindings/interrupt-controller/faraday,ftintc010.yaml b/Documentation/devicetree/bindings/interrupt-controller/faraday,ftintc010.yaml index 980e5c45f25b1..e6495acea038f 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/faraday,ftintc010.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/faraday,ftintc010.yaml @@ -6,7 +6,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Faraday Technology FTINTC010 interrupt controller maintainers: - - Linus Walleij + - Linus Walleij description: This interrupt controller is a stock IP block from Faraday Technology found diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml index c49688be10581..5c768c1e159c1 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml @@ -20,6 +20,7 @@ properties: - fsl,imx8qm-irqsteer - fsl,imx8qxp-irqsteer - fsl,imx94-irqsteer + - fsl,imx95-irqsteer - const: fsl,imx-irqsteer reg: @@ -87,6 +88,7 @@ allOf: - fsl,imx8mp-irqsteer - fsl,imx8qm-irqsteer - fsl,imx8qxp-irqsteer + - fsl,imx95-irqsteer then: required: - power-domains diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,vf610-mscm-ir.yaml b/Documentation/devicetree/bindings/interrupt-controller/fsl,vf610-mscm-ir.yaml index fdc254f8d013c..55b1ae863b911 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/fsl,vf610-mscm-ir.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,vf610-mscm-ir.yaml @@ -14,7 +14,6 @@ description: Vybrid SoC's but is only really useful in dual core configurations (VF6xx which comes with a Cortex-A5/Cortex-M4 combination). - maintainers: - Frank Li diff --git a/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml b/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml index a02a6b5af2056..c375e08ba4104 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Intel IXP4xx XScale Networking Processors Interrupt Controller maintainers: - - Linus Walleij + - Linus Walleij description: | This interrupt controller is found in the Intel IXP4xx processors. diff --git a/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml b/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml index 60441f0c5d721..f63b23f48d8e9 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml @@ -78,7 +78,6 @@ required: - '#interrupt-cells' - loongson,parent_int_map - unevaluatedProperties: false if: diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,mtk-cirq.yaml b/Documentation/devicetree/bindings/interrupt-controller/mediatek,mtk-cirq.yaml index fdcb4d8db8185..20dfffb34f0c6 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,mtk-cirq.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,mtk-cirq.yaml @@ -18,7 +18,6 @@ description: flush command is executed. With CIRQ, MCUSYS can be completely turned off to improve the system power consumption without losing interrupts. - properties: compatible: items: diff --git a/Documentation/devicetree/bindings/interrupt-controller/mscc,ocelot-icpu-intr.yaml b/Documentation/devicetree/bindings/interrupt-controller/mscc,ocelot-icpu-intr.yaml index 4ff609faba325..d943ea820cdd1 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/mscc,ocelot-icpu-intr.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/mscc,ocelot-icpu-intr.yaml @@ -26,7 +26,6 @@ properties: - mscc,ocelot-icpu-intr - mscc,serval-icpu-intr - '#interrupt-cells': const: 1 diff --git a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml index 6fdb7ae9e85aa..388fc2c620c0b 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml @@ -61,10 +61,12 @@ properties: - anlogic,dr1v90-plic - canaan,k210-plic - eswin,eic7700-plic + - microchip,pic64gx-plic - sifive,fu540-c000-plic - spacemit,k1-plic - starfive,jh7100-plic - starfive,jh7110-plic + - tenstorrent,blackhole-plic - const: sifive,plic-1.0.0 - items: - enum: diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu.yaml b/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu.yaml index 6e3d6e6d9e073..61b30a7732ec0 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: TI OMAP4 Wake-up Generator maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: > All TI OMAP4/5 (and their derivatives) are interrupt controllers that route diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml index 89495f094d52b..cdbd23b5c08c1 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml @@ -35,6 +35,8 @@ properties: - description: Qcom SoCs implementing "qcom,smmu-500" and "arm,mmu-500" items: - enum: + - qcom,glymur-smmu-500 + - qcom,kaanapali-smmu-500 - qcom,milos-smmu-500 - qcom,qcm2290-smmu-500 - qcom,qcs615-smmu-500 @@ -89,6 +91,8 @@ properties: - description: Qcom Adreno GPUs implementing "qcom,smmu-500" and "arm,mmu-500" items: - enum: + - qcom,glymur-smmu-500 + - qcom,kaanapali-smmu-500 - qcom,milos-smmu-500 - qcom,qcm2290-smmu-500 - qcom,qcs615-smmu-500 @@ -638,7 +642,6 @@ examples: <&smmu1 7>; }; - /* SMMU with stream matching */ smmu2: iommu@ba5f0000 { compatible = "arm,smmu-v1"; @@ -664,7 +667,6 @@ examples: iommus = <&smmu2 1 0x30>; }; - /* ARM MMU-500 with 10-bit stream ID input configuration */ smmu3: iommu@ba600000 { compatible = "arm,mmu-500", "arm,smmu-v2"; @@ -685,8 +687,6 @@ examples: /* bus whose child devices emit one unique 10-bit stream ID each, but may master through multiple SMMU TBUs */ iommu-map = <0 &smmu3 0 0x400>; - - }; - |+ diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml index f49ed8ac4776e..79c573c47b08e 100644 --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml @@ -82,6 +82,9 @@ properties: - mediatek,mt8188-iommu-vdo # generation two - mediatek,mt8188-iommu-vpp # generation two - mediatek,mt8188-iommu-infra # generation two + - mediatek,mt8189-iommu-apu # generation two + - mediatek,mt8189-iommu-infra # generation two + - mediatek,mt8189-iommu-mm # generation two - mediatek,mt8192-m4u # generation two - mediatek,mt8195-iommu-vdo # generation two - mediatek,mt8195-iommu-vpp # generation two @@ -128,6 +131,7 @@ properties: This is the mtk_m4u_id according to the HW. Specifies the mtk_m4u_id as defined in dt-binding/memory/mediatek,mt8188-memory-port.h for mt8188, + dt-binding/memory/mediatek,mt8189-memory-port.h for mt8189, dt-binding/memory/mt2701-larb-port.h for mt2701 and mt7623, dt-binding/memory/mt2712-larb-port.h for mt2712, dt-binding/memory/mt6779-larb-port.h for mt6779, @@ -164,6 +168,7 @@ allOf: - mediatek,mt8186-iommu-mm - mediatek,mt8188-iommu-vdo - mediatek,mt8188-iommu-vpp + - mediatek,mt8189-iommu-mm - mediatek,mt8192-m4u - mediatek,mt8195-iommu-vdo - mediatek,mt8195-iommu-vpp @@ -180,6 +185,7 @@ allOf: - mediatek,mt8186-iommu-mm - mediatek,mt8188-iommu-vdo - mediatek,mt8188-iommu-vpp + - mediatek,mt8189-iommu-mm - mediatek,mt8192-m4u - mediatek,mt8195-iommu-vdo - mediatek,mt8195-iommu-vpp @@ -208,6 +214,8 @@ allOf: contains: enum: - mediatek,mt8188-iommu-infra + - mediatek,mt8189-iommu-apu + - mediatek,mt8189-iommu-infra - mediatek,mt8195-iommu-infra then: diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml b/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml index 3e5623edd207a..93a4890253170 100644 --- a/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml +++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml @@ -32,14 +32,18 @@ properties: - const: qcom,msm-iommu-v2 clocks: + minItems: 2 items: - description: Clock required for IOMMU register group access - description: Clock required for underlying bus access + - description: Clock required for Translation Buffer Unit access clock-names: + minItems: 2 items: - const: iface - const: bus + - const: tbu power-domains: maxItems: 1 diff --git a/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.txt b/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.txt deleted file mode 100644 index 25f86da804b72..0000000000000 --- a/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.txt +++ /dev/null @@ -1,28 +0,0 @@ -* Aspeed BT (Block Transfer) IPMI interface - -The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs -(BaseBoard Management Controllers) and the BT interface can be used to -perform in-band IPMI communication with their host. - -Required properties: - -- compatible : should be one of - "aspeed,ast2400-ibt-bmc" - "aspeed,ast2500-ibt-bmc" - "aspeed,ast2600-ibt-bmc" -- reg: physical address and size of the registers -- clocks: clock for the device - -Optional properties: - -- interrupts: interrupt generated by the BT interface. without an - interrupt, the driver will operate in poll mode. - -Example: - - ibt@1e789140 { - compatible = "aspeed,ast2400-ibt-bmc"; - reg = <0x1e789140 0x18>; - interrupts = <8>; - clocks = <&syscon ASPEED_CLK_GATE_LCLK>; - }; diff --git a/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.yaml b/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.yaml new file mode 100644 index 0000000000000..c4f7cdbbe16be --- /dev/null +++ b/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.yaml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ipmi/aspeed,ast2400-ibt-bmc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Aspeed Block Transfer (BT) IPMI interface + +maintainers: + - Joel Stanley + +properties: + compatible: + enum: + - aspeed,ast2400-ibt-bmc + - aspeed,ast2500-ibt-bmc + - aspeed,ast2600-ibt-bmc + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - clocks + +additionalProperties: false + +examples: + - | + #include + + bt@1e789140 { + compatible = "aspeed,ast2400-ibt-bmc"; + reg = <0x1e789140 0x18>; + interrupts = <8>; + clocks = <&syscon ASPEED_CLK_GATE_LCLK>; + }; diff --git a/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt b/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt deleted file mode 100644 index 4fda76e63396a..0000000000000 --- a/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt +++ /dev/null @@ -1,40 +0,0 @@ -* Nuvoton NPCM KCS (Keyboard Controller Style) IPMI interface - -The Nuvoton SOCs (NPCM) are commonly used as BMCs -(Baseboard Management Controllers) and the KCS interface can be -used to perform in-band IPMI communication with their host. - -Required properties: -- compatible : should be one of - "nuvoton,npcm750-kcs-bmc" - "nuvoton,npcm845-kcs-bmc", "nuvoton,npcm750-kcs-bmc" -- interrupts : interrupt generated by the controller -- kcs_chan : The KCS channel number in the controller - -Example: - - lpc_kcs: lpc_kcs@f0007000 { - compatible = "nuvoton,npcm750-lpc-kcs", "simple-mfd", "syscon"; - reg = <0xf0007000 0x40>; - reg-io-width = <1>; - - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0xf0007000 0x40>; - - kcs1: kcs1@0 { - compatible = "nuvoton,npcm750-kcs-bmc"; - reg = <0x0 0x40>; - interrupts = <0 9 4>; - kcs_chan = <1>; - status = "disabled"; - }; - - kcs2: kcs2@0 { - compatible = "nuvoton,npcm750-kcs-bmc"; - reg = <0x0 0x40>; - interrupts = <0 9 4>; - kcs_chan = <2>; - status = "disabled"; - }; - }; diff --git a/Documentation/devicetree/bindings/ipmi/nuvoton,npcm750-kcs-bmc.yaml b/Documentation/devicetree/bindings/ipmi/nuvoton,npcm750-kcs-bmc.yaml new file mode 100644 index 0000000000000..fc5df1c5e3bc1 --- /dev/null +++ b/Documentation/devicetree/bindings/ipmi/nuvoton,npcm750-kcs-bmc.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ipmi/nuvoton,npcm750-kcs-bmc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton NPCM KCS BMC + +maintainers: + - Avi Fishman + - Tomer Maimon + - Tali Perry + +description: + The Nuvoton SOCs (NPCM) are commonly used as BMCs (Baseboard Management + Controllers) and the KCS interface can be used to perform in-band IPMI + communication with their host. + +properties: + compatible: + oneOf: + - const: nuvoton,npcm750-kcs-bmc + - items: + - enum: + - nuvoton,npcm845-kcs-bmc + - const: nuvoton,npcm750-kcs-bmc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + kcs_chan: + description: The KCS channel number in the controller + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 3 + +required: + - compatible + - reg + - interrupts + - kcs_chan + +additionalProperties: false + +examples: + - | + kcs@0 { + compatible = "nuvoton,npcm750-kcs-bmc"; + reg = <0x0 0x40>; + interrupts = <9 4>; + kcs_chan = <1>; + }; diff --git a/Documentation/devicetree/bindings/leds/backlight/arc,arc2c0608.yaml b/Documentation/devicetree/bindings/leds/backlight/arc,arc2c0608.yaml new file mode 100644 index 0000000000000..786beced5590b --- /dev/null +++ b/Documentation/devicetree/bindings/leds/backlight/arc,arc2c0608.yaml @@ -0,0 +1,108 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/backlight/arc,arc2c0608.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ArcticSand arc2c0608 LED driver + +description: | + The ArcticSand arc2c0608 LED driver provides ultra + efficient notebook backlighting. Optional properties not + specified will default to values in IC EPROM. + + Datasheet: + https://www.murata.com/-/media/webrenewal/products/power/power-semiconductor/overview/lineup/led-boost/arc2/arc2c0608.ashx. + +maintainers: + - Brian Dodge + +allOf: + - $ref: /schemas/leds/common.yaml + +properties: + compatible: + const: arc,arc2c0608 + + reg: + maxItems: 1 + + default-brightness: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 4095 + + led-sources: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: List of enabled channels + items: + enum: [0, 1, 2, 3, 4, 5] + minItems: 1 + uniqueItems: true + + arc,led-config-0: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Fading speed (period between intensity + steps) + + arc,led-config-1: + $ref: /schemas/types.yaml#/definitions/uint32 + description: If set, sets ILED_CONFIG register. Used for + fine tuning the maximum LED current. + + arc,dim-freq: + $ref: /schemas/types.yaml#/definitions/uint32 + description: PWM mode frequency setting (bits [3:0] used) + + arc,comp-config: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Setting for register CONFIG_COMP which + controls internal resitances, feed forward freqs, + and initial VOUT at startup. Consult the datasheet. + + arc,filter-config: + $ref: /schemas/types.yaml#/definitions/uint32 + description: RC and PWM Filter settings. + Bit Assignment + 7654 3 2 1 0 + xxxx RCF1 RCF0 PWM1 PWM0 + RCF statuses PWM Filter Statues + 00 = OFF (default) 00 = OFF (default) + 01 = LOW 01 = 2 STEPS + 10 - MEDIUM 10 = 4 STEPS + 11 = HIGH 11 = 8 STEPS + + arc,trim-config: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Sets percentage increase of Maximum LED + Current. + 0x00 = 0% increase. + 0x20 = 20.2%. + 0x3F = 41.5% + + label: true + + linux,default-trigger: true + +additionalProperties: false + +required: + - compatible + - reg + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + led-controller@30 { + compatible = "arc,arc2c0608"; + reg = <0x30>; + default-brightness = <500>; + label = "lcd-backlight"; + linux,default-trigger = "backlight"; + led-sources = <0 1 2 5>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/leds/backlight/arcxcnn_bl.txt b/Documentation/devicetree/bindings/leds/backlight/arcxcnn_bl.txt deleted file mode 100644 index 230abdefd6e7b..0000000000000 --- a/Documentation/devicetree/bindings/leds/backlight/arcxcnn_bl.txt +++ /dev/null @@ -1,33 +0,0 @@ -Binding for ArcticSand arc2c0608 LED driver - -Required properties: -- compatible: should be "arc,arc2c0608" -- reg: slave address - -Optional properties: -- default-brightness: brightness value on boot, value from: 0-4095 -- label: The name of the backlight device - See Documentation/devicetree/bindings/leds/common.txt -- led-sources: List of enabled channels from 0 to 5. - See Documentation/devicetree/bindings/leds/common.txt - -- arc,led-config-0: setting for register ILED_CONFIG_0 -- arc,led-config-1: setting for register ILED_CONFIG_1 -- arc,dim-freq: PWM mode frequence setting (bits [3:0] used) -- arc,comp-config: setting for register CONFIG_COMP -- arc,filter-config: setting for register FILTER_CONFIG -- arc,trim-config: setting for register IMAXTUNE - -Note: Optional properties not specified will default to values in IC EPROM - -Example: - -arc2c0608@30 { - compatible = "arc,arc2c0608"; - reg = <0x30>; - default-brightness = <500>; - label = "lcd-backlight"; - linux,default-trigger = "backlight"; - led-sources = <0 1 2 5>; -}; - diff --git a/Documentation/devicetree/bindings/leds/backlight/awinic,aw99706.yaml b/Documentation/devicetree/bindings/leds/backlight/awinic,aw99706.yaml new file mode 100644 index 0000000000000..f48ce7a3434da --- /dev/null +++ b/Documentation/devicetree/bindings/leds/backlight/awinic,aw99706.yaml @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/backlight/awinic,aw99706.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Awinic AW99706 6-channel WLED Backlight Driver + +maintainers: + - Junjie Cao + +allOf: + - $ref: common.yaml# + +properties: + compatible: + const: awinic,aw99706 + + reg: + maxItems: 1 + + enable-gpios: + description: GPIO to use to enable/disable the backlight (HWEN pin). + maxItems: 1 + + awinic,dim-mode: + $ref: /schemas/types.yaml#/definitions/uint32 + description: > + Select dimming mode of the device. + 0 = Bypass mode. + 1 = DC mode. + 2 = MIX mode(PWM at low brightness and DC at high brightness). + 3 = MIX-26k mode(MIX mode with different PWM frequency). + enum: [ 0, 1, 2, 3 ] + default: 1 + + awinic,sw-freq-hz: + description: Boost switching frequency in Hz. + enum: [ 300000, 400000, 500000, 600000, 660000, 750000, 850000, 1000000, + 1200000, 1330000, 1500000, 1700000 ] + default: 750000 + + awinic,sw-ilmt-microamp: + description: Switching current limitation in uA. + enum: [ 1500000, 2000000, 2500000, 3000000 ] + default: 3000000 + + awinic,iled-max-microamp: + description: Maximum LED current setting in uA. + minimum: 5000 + maximum: 50000 + multipleOf: 500 + default: 20000 + + awinic,uvlo-thres-microvolt: + description: UVLO(Under Voltage Lock Out) in uV. + enum: [ 2200000, 5000000 ] + default: 2200000 + + awinic,ramp-ctl: + $ref: /schemas/types.yaml#/definitions/uint32 + description: > + Select ramp control and filter of the device. + 0 = Fade in/fade out. + 1 = Light filter. + 2 = Medium filter. + 3 = Heavy filter. + enum: [ 0, 1, 2, 3 ] + default: 2 + +required: + - compatible + - reg + - enable-gpios + +unevaluatedProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + backlight@76 { + compatible = "awinic,aw99706"; + reg = <0x76>; + enable-gpios = <&tlmm 88 GPIO_ACTIVE_HIGH>; + default-brightness = <2047>; + max-brightness = <4095>; + awinic,dim-mode = <1>; + awinic,sw-freq-hz = <750000>; + awinic,sw-ilmt-microamp = <3000000>; + awinic,uvlo-thres-microvolt = <2200000>; + awinic,iled-max-microamp = <20000>; + awinic,ramp-ctl = <2>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/leds/backlight/kinetic,ktd253.yaml b/Documentation/devicetree/bindings/leds/backlight/kinetic,ktd253.yaml index 73fa59e621816..e7207eb265842 100644 --- a/Documentation/devicetree/bindings/leds/backlight/kinetic,ktd253.yaml +++ b/Documentation/devicetree/bindings/leds/backlight/kinetic,ktd253.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Kinetic Technologies KTD253 and KTD259 one-wire backlight maintainers: - - Linus Walleij + - Linus Walleij description: | The Kinetic Technologies KTD253 and KTD259 are white LED backlights diff --git a/Documentation/devicetree/bindings/leds/common.yaml b/Documentation/devicetree/bindings/leds/common.yaml index 274f83288a92e..f4e44b33f56d1 100644 --- a/Documentation/devicetree/bindings/leds/common.yaml +++ b/Documentation/devicetree/bindings/leds/common.yaml @@ -173,6 +173,12 @@ properties: led-max-microamp. $ref: /schemas/types.yaml#/definitions/uint32 + default-brightness: + description: + Brightness to be set if LED's default state is on. Used only during + initialization. If the option is not set then max brightness is used. + $ref: /schemas/types.yaml#/definitions/uint32 + panic-indicator: description: This property specifies that the LED should be used, if at all possible, diff --git a/Documentation/devicetree/bindings/leds/leds-pwm.yaml b/Documentation/devicetree/bindings/leds/leds-pwm.yaml index 61b97e8bc36d0..6c4fcefbe25f9 100644 --- a/Documentation/devicetree/bindings/leds/leds-pwm.yaml +++ b/Documentation/devicetree/bindings/leds/leds-pwm.yaml @@ -40,6 +40,13 @@ patternProperties: initialization. If the option is not set then max brightness is used. $ref: /schemas/types.yaml#/definitions/uint32 + enable-gpios: + description: + GPIO for LED hardware enable control. Set active when brightness is + non-zero and inactive when brightness is zero. + The GPIO default state follows the "default-state" property. + maxItems: 1 + required: - pwms - max-brightness diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml index 841a0229c472a..c4b7e57b25184 100644 --- a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml +++ b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml @@ -13,6 +13,11 @@ description: > The Qualcomm Light Pulse Generator consists of three different hardware blocks; a ramp generator with lookup table (LUT), the light pulse generator and a three channel current sink. These blocks are found in a wide range of Qualcomm PMICs. + The light pulse generator (LPG) can also be used independently to output PWM + signal for standard PWM applications. In this scenario, the LPG output should + be routed to a specific PMIC GPIO by setting the GPIO pin mux to the special + functions indicated in the datasheet, the TRILED driver for the channel will + not be enabled in this configuration. properties: compatible: diff --git a/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml b/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml index fa03e73622d48..b409b2a8b5c5b 100644 --- a/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml +++ b/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm PM8058 PMIC LED maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: | The Qualcomm PM8058 contains an LED block for up to six LEDs:: three normal diff --git a/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml b/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml index bcf0ad4ea57ea..05250aefd3857 100644 --- a/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml +++ b/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml @@ -24,6 +24,7 @@ properties: - enum: - qcom,pm6150l-flash-led - qcom,pm660l-flash-led + - qcom,pm7550-flash-led - qcom,pm8150c-flash-led - qcom,pm8150l-flash-led - qcom,pm8350c-flash-led diff --git a/Documentation/devicetree/bindings/leds/register-bit-led.yaml b/Documentation/devicetree/bindings/leds/register-bit-led.yaml index 20930d327ae99..a6bafc96bd0c3 100644 --- a/Documentation/devicetree/bindings/leds/register-bit-led.yaml +++ b/Documentation/devicetree/bindings/leds/register-bit-led.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Register Bit LEDs maintainers: - - Linus Walleij + - Linus Walleij description: |+ Register bit leds are used with syscon multifunctional devices where single diff --git a/Documentation/devicetree/bindings/leds/regulator-led.yaml b/Documentation/devicetree/bindings/leds/regulator-led.yaml index 4ef7b96e9a086..75ee87d4a7869 100644 --- a/Documentation/devicetree/bindings/leds/regulator-led.yaml +++ b/Documentation/devicetree/bindings/leds/regulator-led.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Regulator LEDs maintainers: - - Linus Walleij + - Linus Walleij description: | Regulator LEDs are powered by a single regulator such that they can diff --git a/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml b/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml index 68c328eec03be..0356371a6b014 100644 --- a/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml +++ b/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Richtek RT8515 1.5A dual channel LED driver maintainers: - - Linus Walleij + - Linus Walleij description: | The Richtek RT8515 is a dual channel (two mode) LED driver that diff --git a/Documentation/devicetree/bindings/mailbox/apm,xgene-slimpro-mbox.yaml b/Documentation/devicetree/bindings/mailbox/apm,xgene-slimpro-mbox.yaml new file mode 100644 index 0000000000000..815f08d61de85 --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/apm,xgene-slimpro-mbox.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/apm,xgene-slimpro-mbox.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: APM X-Gene SLIMpro mailbox + +maintainers: + - Khuong Dinh + +description: + The APM X-Gene SLIMpro mailbox is used to communicate messages between + the ARM64 processors and the Cortex M3 (dubbed SLIMpro). It uses a simple + interrupt based door bell mechanism and can exchange simple messages using the + internal registers. + +properties: + compatible: + const: apm,xgene-slimpro-mbox + + reg: + maxItems: 1 + + interrupts: + items: + - description: mailbox channel 0 doorbell + - description: mailbox channel 1 doorbell + - description: mailbox channel 2 doorbell + - description: mailbox channel 3 doorbell + - description: mailbox channel 4 doorbell + - description: mailbox channel 5 doorbell + - description: mailbox channel 6 doorbell + - description: mailbox channel 7 doorbell + + '#mbox-cells': + description: Number of mailbox channel. + const: 1 + +required: + - compatible + - reg + - interrupts + - '#mbox-cells' + +additionalProperties: false + +examples: + - | + mailbox@10540000 { + compatible = "apm,xgene-slimpro-mbox"; + reg = <0x10540000 0xa000>; + #mbox-cells = <1>; + interrupts = <0x0 0x0 0x4>, + <0x0 0x1 0x4>, + <0x0 0x2 0x4>, + <0x0 0x3 0x4>, + <0x0 0x4 0x4>, + <0x0 0x5 0x4>, + <0x0 0x6 0x4>, + <0x0 0x7 0x4>; + }; diff --git a/Documentation/devicetree/bindings/mailbox/arm,mhu.yaml b/Documentation/devicetree/bindings/mailbox/arm,mhu.yaml index d9a4f4a02d7cb..e45b661e8b411 100644 --- a/Documentation/devicetree/bindings/mailbox/arm,mhu.yaml +++ b/Documentation/devicetree/bindings/mailbox/arm,mhu.yaml @@ -52,7 +52,6 @@ properties: - const: arm,mhu-doorbell - const: arm,primecell - reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml b/Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml index 02f06314d85fe..3828d77f6316f 100644 --- a/Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml +++ b/Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml @@ -127,7 +127,6 @@ properties: - minimum: 0 maximum: 124 - '#mbox-cells': description: | It is always set to 2. The first argument in the consumers 'mboxes' diff --git a/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml index 8a1369df4ecb2..4ca0d5e49c791 100644 --- a/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml @@ -26,7 +26,6 @@ properties: - mediatek,mt8188-adsp-mbox - const: mediatek,mt8186-adsp-mbox - "#mbox-cells": const: 0 diff --git a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml index 615ed103b7e6f..f40dc90483272 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml +++ b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml @@ -187,10 +187,10 @@ allOf: enum: - qcom,msm8916-apcs-kpss-global then: - $ref: "#/$defs/msm8916-apcs-clock-controller" + $ref: '#/$defs/msm8916-apcs-clock-controller' properties: clock-controller: - $ref: "#/$defs/msm8916-apcs-clock-controller" + $ref: '#/$defs/msm8916-apcs-clock-controller' - if: properties: @@ -199,10 +199,10 @@ allOf: enum: - qcom,msm8939-apcs-kpss-global then: - $ref: "#/$defs/msm8939-apcs-clock-controller" + $ref: '#/$defs/msm8939-apcs-clock-controller' properties: clock-controller: - $ref: "#/$defs/msm8939-apcs-clock-controller" + $ref: '#/$defs/msm8939-apcs-clock-controller' - if: properties: @@ -211,10 +211,10 @@ allOf: enum: - qcom,sdx55-apcs-gcc then: - $ref: "#/$defs/sdx55-apcs-clock-controller" + $ref: '#/$defs/sdx55-apcs-clock-controller' properties: clock-controller: - $ref: "#/$defs/sdx55-apcs-clock-controller" + $ref: '#/$defs/sdx55-apcs-clock-controller' - if: properties: @@ -223,10 +223,10 @@ allOf: enum: - qcom,ipq6018-apcs-apps-global then: - $ref: "#/$defs/ipq6018-apcs-clock-controller" + $ref: '#/$defs/ipq6018-apcs-clock-controller' properties: clock-controller: - $ref: "#/$defs/ipq6018-apcs-clock-controller" + $ref: '#/$defs/ipq6018-apcs-clock-controller' - if: properties: diff --git a/Documentation/devicetree/bindings/mailbox/xgene-slimpro-mailbox.txt b/Documentation/devicetree/bindings/mailbox/xgene-slimpro-mailbox.txt deleted file mode 100644 index e46451bb242f3..0000000000000 --- a/Documentation/devicetree/bindings/mailbox/xgene-slimpro-mailbox.txt +++ /dev/null @@ -1,35 +0,0 @@ -The APM X-Gene SLIMpro mailbox is used to communicate messages between -the ARM64 processors and the Cortex M3 (dubbed SLIMpro). It uses a simple -interrupt based door bell mechanism and can exchange simple messages using the -internal registers. - -There are total of 8 interrupts in this mailbox. Each used for an individual -door bell (or mailbox channel). - -Required properties: -- compatible: Should be as "apm,xgene-slimpro-mbox". - -- reg: Contains the mailbox register address range. - -- interrupts: 8 interrupts must be from 0 to 7, interrupt 0 define the - the interrupt for mailbox channel 0 and interrupt 1 for - mailbox channel 1 and so likewise for the reminder. - -- #mbox-cells: only one to specify the mailbox channel number. - -Example: - -Mailbox Node: - mailbox: mailbox@10540000 { - compatible = "apm,xgene-slimpro-mbox"; - reg = <0x0 0x10540000 0x0 0xa000>; - #mbox-cells = <1>; - interrupts = <0x0 0x0 0x4>, - <0x0 0x1 0x4>, - <0x0 0x2 0x4>, - <0x0 0x3 0x4>, - <0x0 0x4 0x4>, - <0x0 0x5 0x4>, - <0x0 0x6 0x4>, - <0x0 0x7 0x4>, - }; diff --git a/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml index fe83b5cb1278d..04d6473d666f3 100644 --- a/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml @@ -142,7 +142,7 @@ patternProperties: - compatible - reg - reg-names - - "#mbox-cells" + - '#mbox-cells' - xlnx,ipi-id required: diff --git a/Documentation/devicetree/bindings/media/amphion,vpu.yaml b/Documentation/devicetree/bindings/media/amphion,vpu.yaml index 5a920d9e78c73..fa18013d705d9 100644 --- a/Documentation/devicetree/bindings/media/amphion,vpu.yaml +++ b/Documentation/devicetree/bindings/media/amphion,vpu.yaml @@ -45,7 +45,6 @@ patternProperties: between driver and firmware. Implement via mailbox on driver. $ref: /schemas/mailbox/fsl,mu.yaml# - "^vpu-core@[0-9a-f]+$": description: Each core correspond a decoder or encoder, need to configure them diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml new file mode 100644 index 0000000000000..fc4fcd19922aa --- /dev/null +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ARM Mali-C55 Image Signal Processor + +maintainers: + - Daniel Scally + - Jacopo Mondi + +properties: + compatible: + const: arm,mali-c55 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: ISP Video Clock + - description: ISP AXI clock + - description: ISP AHB-lite clock + + clock-names: + items: + - const: vclk + - const: aclk + - const: hclk + + resets: + items: + - description: vclk domain reset + - description: aclk domain reset + - description: hclk domain reset + + reset-names: + items: + - const: vresetn + - const: aresetn + - const: hresetn + + port: + $ref: /schemas/graph.yaml#/properties/port + description: Input parallel video bus + + properties: + endpoint: + $ref: /schemas/graph.yaml#/properties/endpoint + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - resets + - reset-names + - port + +additionalProperties: false + +examples: + - | + #include + + isp@400000 { + compatible = "arm,mali-c55"; + reg = <0x400000 0x200000>; + clocks = <&clk 0>, <&clk 1>, <&clk 2>; + clock-names = "vclk", "aclk", "hclk"; + resets = <&resets 0>, <&resets 1>, <&resets 2>; + reset-names = "vresetn", "aresetn", "hresetn"; + interrupts = ; + + port { + isp_in: endpoint { + remote-endpoint = <&csi2_rx_out>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/media/fsl,imx6q-vdoa.yaml b/Documentation/devicetree/bindings/media/fsl,imx6q-vdoa.yaml index 511ac0d67a7f2..988a5b3a62bde 100644 --- a/Documentation/devicetree/bindings/media/fsl,imx6q-vdoa.yaml +++ b/Documentation/devicetree/bindings/media/fsl,imx6q-vdoa.yaml @@ -16,7 +16,7 @@ maintainers: properties: compatible: - const: "fsl,imx6q-vdoa" + const: fsl,imx6q-vdoa reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/media/i2c/adi,adv7604.yaml b/Documentation/devicetree/bindings/media/i2c/adi,adv7604.yaml index 2dc2829d42a03..f8d9889dbc21c 100644 --- a/Documentation/devicetree/bindings/media/i2c/adi,adv7604.yaml +++ b/Documentation/devicetree/bindings/media/i2c/adi,adv7604.yaml @@ -154,7 +154,5 @@ examples: }; }; }; - - }; }; diff --git a/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9719.yaml b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9719.yaml new file mode 100644 index 0000000000000..8e8d62436e0d0 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9719.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/dongwoon,dw9719.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Dongwoon Anatech DW9719 Voice Coil Motor (VCM) Controller + +maintainers: + - André Apitzsch + +description: + The Dongwoon DW9718S/9719/9761 is a single 10-bit digital-to-analog converter + with 100 mA output current sink capability, designed for linear control of + voice coil motors (VCM) in camera lenses. This chip provides a Smart Actuator + Control (SAC) mode intended for driving voice coil lenses in camera modules. + +properties: + compatible: + enum: + - dongwoon,dw9718s + - dongwoon,dw9719 + - dongwoon,dw9761 + - dongwoon,dw9800k + + reg: + maxItems: 1 + + vdd-supply: + description: VDD power supply + + dongwoon,sac-mode: + description: | + Slew Rate Control mode to use: direct, LSC (Linear Slope Control) or + SAC1-SAC6 (Smart Actuator Control). + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # Direct mode + - 1 # LSC mode + - 2 # SAC1 mode (operation time# 0.32 x Tvib) + - 3 # SAC2 mode (operation time# 0.48 x Tvib) + - 4 # SAC3 mode (operation time# 0.72 x Tvib) + - 5 # SAC4 mode (operation time# 1.20 x Tvib) + - 6 # SAC5 mode (operation time# 1.64 x Tvib) + - 7 # SAC6 mode (operation time# 1.88 x Tvib) + default: 4 + + dongwoon,vcm-prescale: + description: + Indication of VCM switching frequency dividing rate select. + $ref: /schemas/types.yaml#/definitions/uint32 + +required: + - compatible + - reg + - vdd-supply + +allOf: + - if: + properties: + compatible: + contains: + const: dongwoon,dw9718s + then: + properties: + dongwoon,vcm-prescale: + description: + The final frequency is 10 MHz divided by (value + 2). + maximum: 15 + default: 0 + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + actuator@c { + compatible = "dongwoon,dw9718s"; + reg = <0x0c>; + + vdd-supply = <&pm8937_l17>; + + dongwoon,sac-mode = <4>; + dongwoon,vcm-prescale = <0>; + }; + }; diff --git a/Documentation/devicetree/bindings/media/i2c/nxp,tda19971.yaml b/Documentation/devicetree/bindings/media/i2c/nxp,tda19971.yaml new file mode 100644 index 0000000000000..477e59316dfa4 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/nxp,tda19971.yaml @@ -0,0 +1,162 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/nxp,tda19971.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP TDA1997x HDMI receiver + +maintainers: + - Frank Li + +description: | + The TDA19971/73 are HDMI video receivers. + + The TDA19971 Video port output pins can be used as follows: + - RGB 8bit per color (24 bits total): R[11:4] B[11:4] G[11:4] + - YUV444 8bit per color (24 bits total): Y[11:4] Cr[11:4] Cb[11:4] + - YUV422 semi-planar 8bit per component (16 bits total): Y[11:4] CbCr[11:4] + - YUV422 semi-planar 10bit per component (20 bits total): Y[11:2] CbCr[11:2] + - YUV422 semi-planar 12bit per component (24 bits total): - Y[11:0] CbCr[11:0] + - YUV422 BT656 8bit per component (8 bits total): YCbCr[11:4] (2-cycles) + - YUV422 BT656 10bit per component (10 bits total): YCbCr[11:2] (2-cycles) + - YUV422 BT656 12bit per component (12 bits total): YCbCr[11:0] (2-cycles) + + The TDA19973 Video port output pins can be used as follows: + - RGB 12bit per color (36 bits total): R[11:0] B[11:0] G[11:0] + - YUV444 12bit per color (36 bits total): Y[11:0] Cb[11:0] Cr[11:0] + - YUV422 semi-planar 12bit per component (24 bits total): Y[11:0] CbCr[11:0] + - YUV422 BT656 12bit per component (12 bits total): YCbCr[11:0] (2-cycles) + + The Video port output pins are mapped via 4-bit 'pin groups' allowing + for a variety of connection possibilities including swapping pin order within + pin groups. The video_portcfg device-tree property consists of register mapping + pairs which map a chip-specific VP output register to a 4-bit pin group. If + the pin group needs to be bit-swapped you can use the *_S pin-group defines. + +properties: + compatible: + enum: + - nxp,tda19971 + - nxp,tda19973 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + DOVDD-supply: true + + DVDD-supply: true + + AVDD-supply: true + + '#sound-dai-cells': + const: 0 + + port: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + + properties: + endpoint: + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + + nxp,vidout-portcfg: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + minItems: 1 + maxItems: 4 + items: + items: + - description: Video Port control registers index. + maximum: 8 + minimum: 0 + - description: pin(pinswapped) groups + + description: + array of pairs mapping VP output pins to pin groups. + + nxp,audout-format: + enum: + - i2s + - spdif + + nxp,audout-width: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [8, 16, 24, 32] + description: + width of audio output data bus. + + nxp,audout-layout: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1] + description: + data layout (0=AP0 used, 1=AP0/AP1/AP2/AP3 used). + + nxp,audout-mclk-fs: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Multiplication factor between stream rate and codec mclk. + +required: + - compatible + - reg + - interrupts + - DOVDD-supply + - AVDD-supply + - DVDD-supply + +additionalProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + hdmi-receiver@48 { + compatible = "nxp,tda19971"; + reg = <0x48>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tda1997x>; + interrupt-parent = <&gpio1>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + DOVDD-supply = <®_3p3v>; + AVDD-supply = <®_1p8v>; + DVDD-supply = <®_1p8v>; + /* audio */ + #sound-dai-cells = <0>; + nxp,audout-format = "i2s"; + nxp,audout-layout = <0>; + nxp,audout-width = <16>; + nxp,audout-mclk-fs = <128>; + /* + * The 8bpp YUV422 semi-planar mode outputs CbCr[11:4] + * and Y[11:4] across 16bits in the same pixclk cycle. + */ + nxp,vidout-portcfg = + /* Y[11:8]<->VP[15:12]<->CSI_DATA[19:16] */ + < TDA1997X_VP24_V15_12 TDA1997X_G_Y_11_8 >, + /* Y[7:4]<->VP[11:08]<->CSI_DATA[15:12] */ + < TDA1997X_VP24_V11_08 TDA1997X_G_Y_7_4 >, + /* CbCc[11:8]<->VP[07:04]<->CSI_DATA[11:8] */ + < TDA1997X_VP24_V07_04 TDA1997X_R_CR_CBCR_11_8 >, + /* CbCr[7:4]<->VP[03:00]<->CSI_DATA[7:4] */ + < TDA1997X_VP24_V03_00 TDA1997X_R_CR_CBCR_7_4 >; + + port { + endpoint { + remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; + bus-width = <16>; + hsync-active = <1>; + vsync-active = <1>; + data-active = <1>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/i2c/nxp,tda1997x.txt b/Documentation/devicetree/bindings/media/i2c/nxp,tda1997x.txt deleted file mode 100644 index e76167999d76c..0000000000000 --- a/Documentation/devicetree/bindings/media/i2c/nxp,tda1997x.txt +++ /dev/null @@ -1,178 +0,0 @@ -Device-Tree bindings for the NXP TDA1997x HDMI receiver - -The TDA19971/73 are HDMI video receivers. - -The TDA19971 Video port output pins can be used as follows: - - RGB 8bit per color (24 bits total): R[11:4] B[11:4] G[11:4] - - YUV444 8bit per color (24 bits total): Y[11:4] Cr[11:4] Cb[11:4] - - YUV422 semi-planar 8bit per component (16 bits total): Y[11:4] CbCr[11:4] - - YUV422 semi-planar 10bit per component (20 bits total): Y[11:2] CbCr[11:2] - - YUV422 semi-planar 12bit per component (24 bits total): - Y[11:0] CbCr[11:0] - - YUV422 BT656 8bit per component (8 bits total): YCbCr[11:4] (2-cycles) - - YUV422 BT656 10bit per component (10 bits total): YCbCr[11:2] (2-cycles) - - YUV422 BT656 12bit per component (12 bits total): YCbCr[11:0] (2-cycles) - -The TDA19973 Video port output pins can be used as follows: - - RGB 12bit per color (36 bits total): R[11:0] B[11:0] G[11:0] - - YUV444 12bit per color (36 bits total): Y[11:0] Cb[11:0] Cr[11:0] - - YUV422 semi-planar 12bit per component (24 bits total): Y[11:0] CbCr[11:0] - - YUV422 BT656 12bit per component (12 bits total): YCbCr[11:0] (2-cycles) - -The Video port output pins are mapped via 4-bit 'pin groups' allowing -for a variety of connection possibilities including swapping pin order within -pin groups. The video_portcfg device-tree property consists of register mapping -pairs which map a chip-specific VP output register to a 4-bit pin group. If -the pin group needs to be bit-swapped you can use the *_S pin-group defines. - -Required Properties: - - compatible : - - "nxp,tda19971" for the TDA19971 - - "nxp,tda19973" for the TDA19973 - - reg : I2C slave address - - interrupts : The interrupt number - - DOVDD-supply : Digital I/O supply - - DVDD-supply : Digital Core supply - - AVDD-supply : Analog supply - - nxp,vidout-portcfg : array of pairs mapping VP output pins to pin groups. - -Optional Properties: - - nxp,audout-format : DAI bus format: "i2s" or "spdif". - - nxp,audout-width : width of audio output data bus (1-4). - - nxp,audout-layout : data layout (0=AP0 used, 1=AP0/AP1/AP2/AP3 used). - - nxp,audout-mclk-fs : Multiplication factor between stream rate and codec - mclk. - -The port node shall contain one endpoint child node for its digital -output video port, in accordance with the video interface bindings defined in -Documentation/devicetree/bindings/media/video-interfaces.txt. - -Optional Endpoint Properties: - The following three properties are defined in video-interfaces.txt and - are valid for the output parallel bus endpoint: - - hsync-active: Horizontal synchronization polarity. Defaults to active high. - - vsync-active: Vertical synchronization polarity. Defaults to active high. - - data-active: Data polarity. Defaults to active high. - -Examples: - - VP[15:0] connected to IMX6 CSI_DATA[19:4] for 16bit YUV422 - 16bit I2S layout0 with a 128*fs clock (A_WS, AP0, A_CLK pins) - hdmi-receiver@48 { - compatible = "nxp,tda19971"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_tda1997x>; - reg = <0x48>; - interrupt-parent = <&gpio1>; - interrupts = <7 IRQ_TYPE_LEVEL_LOW>; - DOVDD-supply = <®_3p3v>; - AVDD-supply = <®_1p8v>; - DVDD-supply = <®_1p8v>; - /* audio */ - #sound-dai-cells = <0>; - nxp,audout-format = "i2s"; - nxp,audout-layout = <0>; - nxp,audout-width = <16>; - nxp,audout-mclk-fs = <128>; - /* - * The 8bpp YUV422 semi-planar mode outputs CbCr[11:4] - * and Y[11:4] across 16bits in the same pixclk cycle. - */ - nxp,vidout-portcfg = - /* Y[11:8]<->VP[15:12]<->CSI_DATA[19:16] */ - < TDA1997X_VP24_V15_12 TDA1997X_G_Y_11_8 >, - /* Y[7:4]<->VP[11:08]<->CSI_DATA[15:12] */ - < TDA1997X_VP24_V11_08 TDA1997X_G_Y_7_4 >, - /* CbCc[11:8]<->VP[07:04]<->CSI_DATA[11:8] */ - < TDA1997X_VP24_V07_04 TDA1997X_R_CR_CBCR_11_8 >, - /* CbCr[7:4]<->VP[03:00]<->CSI_DATA[7:4] */ - < TDA1997X_VP24_V03_00 TDA1997X_R_CR_CBCR_7_4 >; - - port { - tda1997x_to_ipu1_csi0_mux: endpoint { - remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; - bus-width = <16>; - hsync-active = <1>; - vsync-active = <1>; - data-active = <1>; - }; - }; - }; - - VP[15:8] connected to IMX6 CSI_DATA[19:12] for 8bit BT656 - 16bit I2S layout0 with a 128*fs clock (A_WS, AP0, A_CLK pins) - hdmi-receiver@48 { - compatible = "nxp,tda19971"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_tda1997x>; - reg = <0x48>; - interrupt-parent = <&gpio1>; - interrupts = <7 IRQ_TYPE_LEVEL_LOW>; - DOVDD-supply = <®_3p3v>; - AVDD-supply = <®_1p8v>; - DVDD-supply = <®_1p8v>; - /* audio */ - #sound-dai-cells = <0>; - nxp,audout-format = "i2s"; - nxp,audout-layout = <0>; - nxp,audout-width = <16>; - nxp,audout-mclk-fs = <128>; - /* - * The 8bpp YUV422 semi-planar mode outputs CbCr[11:4] - * and Y[11:4] across 16bits in the same pixclk cycle. - */ - nxp,vidout-portcfg = - /* Y[11:8]<->VP[15:12]<->CSI_DATA[19:16] */ - < TDA1997X_VP24_V15_12 TDA1997X_G_Y_11_8 >, - /* Y[7:4]<->VP[11:08]<->CSI_DATA[15:12] */ - < TDA1997X_VP24_V11_08 TDA1997X_G_Y_7_4 >, - /* CbCc[11:8]<->VP[07:04]<->CSI_DATA[11:8] */ - < TDA1997X_VP24_V07_04 TDA1997X_R_CR_CBCR_11_8 >, - /* CbCr[7:4]<->VP[03:00]<->CSI_DATA[7:4] */ - < TDA1997X_VP24_V03_00 TDA1997X_R_CR_CBCR_7_4 >; - - port { - tda1997x_to_ipu1_csi0_mux: endpoint { - remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; - bus-width = <16>; - hsync-active = <1>; - vsync-active = <1>; - data-active = <1>; - }; - }; - }; - - VP[15:8] connected to IMX6 CSI_DATA[19:12] for 8bit BT656 - 16bit I2S layout0 with a 128*fs clock (A_WS, AP0, A_CLK pins) - hdmi-receiver@48 { - compatible = "nxp,tda19971"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_tda1997x>; - reg = <0x48>; - interrupt-parent = <&gpio1>; - interrupts = <7 IRQ_TYPE_LEVEL_LOW>; - DOVDD-supply = <®_3p3v>; - AVDD-supply = <®_1p8v>; - DVDD-supply = <®_1p8v>; - /* audio */ - #sound-dai-cells = <0>; - nxp,audout-format = "i2s"; - nxp,audout-layout = <0>; - nxp,audout-width = <16>; - nxp,audout-mclk-fs = <128>; - /* - * The 8bpp BT656 mode outputs YCbCr[11:4] across 8bits over - * 2 pixclk cycles. - */ - nxp,vidout-portcfg = - /* YCbCr[11:8]<->VP[15:12]<->CSI_DATA[19:16] */ - < TDA1997X_VP24_V15_12 TDA1997X_R_CR_CBCR_11_8 >, - /* YCbCr[7:4]<->VP[11:08]<->CSI_DATA[15:12] */ - < TDA1997X_VP24_V11_08 TDA1997X_R_CR_CBCR_7_4 >, - - port { - tda1997x_to_ipu1_csi0_mux: endpoint { - remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; - bus-width = <16>; - hsync-active = <1>; - vsync-active = <1>; - data-active = <1>; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/media/i2c/samsung,s5k5baf.yaml b/Documentation/devicetree/bindings/media/i2c/samsung,s5k5baf.yaml index ebd95a8d9b2f1..4cb0f5aa13019 100644 --- a/Documentation/devicetree/bindings/media/i2c/samsung,s5k5baf.yaml +++ b/Documentation/devicetree/bindings/media/i2c/samsung,s5k5baf.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor with embedded SoC ISP maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski properties: compatible: diff --git a/Documentation/devicetree/bindings/media/i2c/samsung,s5k6a3.yaml b/Documentation/devicetree/bindings/media/i2c/samsung,s5k6a3.yaml index e563e35920c4a..9df1e0f872f2d 100644 --- a/Documentation/devicetree/bindings/media/i2c/samsung,s5k6a3.yaml +++ b/Documentation/devicetree/bindings/media/i2c/samsung,s5k6a3.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Samsung S5K6A3(YX) raw image sensor maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: S5K6A3(YX) is a raw image sensor with MIPI CSI-2 and CCP2 image data diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx111.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx111.yaml new file mode 100644 index 0000000000000..20f48d5e9b2d8 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx111.yaml @@ -0,0 +1,105 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/sony,imx111.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sony IMX111 8MP CMOS Digital Image Sensor + +maintainers: + - Svyatoslav Ryhel + +description: + IMX111 sensor is a Sony CMOS active pixel digital image sensor with an active + array size of 2464H x 3280V. It is programmable through I2C interface. Image + data is sent through MIPI CSI-2, through 1 or 2 lanes. + +allOf: + - $ref: /schemas/media/video-interface-devices.yaml# + - $ref: /schemas/nvmem/nvmem-consumer.yaml# + +properties: + compatible: + const: sony,imx111 + + reg: + maxItems: 1 + + clocks: + description: EXTCLK with possible frequency from 6 to 54 MHz + maxItems: 1 + + reset-gpios: + maxItems: 1 + + iovdd-supply: + description: Digital IO power supply (1.8V) + + dvdd-supply: + description: Digital power supply (1.2V) + + avdd-supply: + description: Analog power supply (2.7V) + + port: + additionalProperties: false + $ref: /schemas/graph.yaml#/$defs/port-base + + properties: + endpoint: + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + + required: + - data-lanes + - link-frequencies + + required: + - endpoint + +required: + - compatible + - reg + - clocks + - port + +unevaluatedProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + camera@10 { + compatible = "sony,imx111"; + reg = <0x10>; + + clocks = <&imx111_clk>; + + iovdd-supply = <&camera_vddio_1v8>; + dvdd-supply = <&camera_vddd_1v2>; + avdd-supply = <&camera_vdda_2v7>; + + orientation = <1>; + rotation = <90>; + + nvmem = <&eeprom>; + flash-leds = <&led>; + lens-focus = <&vcm>; + + reset-gpios = <&gpio 84 GPIO_ACTIVE_LOW>; + + port { + imx111_output: endpoint { + data-lanes = <1 2>; + link-frequencies = /bits/ 64 <542400000>; + remote-endpoint = <&csi_input>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml b/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml index 3c071e6fbea61..060ac6829b661 100644 --- a/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml +++ b/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml @@ -25,7 +25,11 @@ allOf: properties: compatible: - const: st,vd55g1 + enum: + - st,vd55g1 + - st,vd65g4 + description: + VD55G1 is the monochrome variant, while VD65G4 is the color one. reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml b/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml index c9673391afdbd..0592d0b9af926 100644 --- a/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml +++ b/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml @@ -70,7 +70,6 @@ properties: $ref: /schemas/graph.yaml#/properties/port description: Video port for the decoder output. - required: - port@0 - port@1 diff --git a/Documentation/devicetree/bindings/media/i2c/ti,tvp5150.txt b/Documentation/devicetree/bindings/media/i2c/ti,tvp5150.txt deleted file mode 100644 index 94b908ace53c8..0000000000000 --- a/Documentation/devicetree/bindings/media/i2c/ti,tvp5150.txt +++ /dev/null @@ -1,157 +0,0 @@ -* Texas Instruments TVP5150 and TVP5151 video decoders - -The TVP5150 and TVP5151 are video decoders that convert baseband NTSC and PAL -(and also SECAM in the TVP5151 case) video signals to either 8-bit 4:2:2 YUV -with discrete syncs or 8-bit ITU-R BT.656 with embedded syncs output formats. - -Required Properties: -==================== -- compatible: Value must be "ti,tvp5150". -- reg: I2C slave address. - -Optional Properties: -==================== -- pdn-gpios: Phandle for the GPIO connected to the PDN pin, if any. -- reset-gpios: Phandle for the GPIO connected to the RESETB pin, if any. - -The device node must contain one 'port' child node per device physical input -and output port, in accordance with the video interface bindings defined in -Documentation/devicetree/bindings/media/video-interfaces.txt. The port nodes -are numbered as follows - - Name Type Port - -------------------------------------- - AIP1A sink 0 - AIP1B sink 1 - Y-OUT src 2 - -The device node must contain at least one sink port and the src port. Each input -port must be linked to an endpoint defined in [1]. The port/connector layout is -as follows - -tvp-5150 port@0 (AIP1A) - endpoint@0 -----------> Comp0-Con port - endpoint@1 ------+----> Svideo-Con port -tvp-5150 port@1 (AIP1B) | - endpoint@1 ------+ - endpoint@0 -----------> Comp1-Con port -tvp-5150 port@2 - endpoint (video bitstream output at YOUT[0-7] parallel bus) - -Required Endpoint Properties for parallel synchronization on output port: -========================================================================= - -- hsync-active: Active state of the HSYNC signal. Must be <1> (HIGH). -- vsync-active: Active state of the VSYNC signal. Must be <1> (HIGH). -- field-even-active: Field signal level during the even field data - transmission. Must be <0>. - -Note: Do not specify any of these properties if you want to use the embedded - BT.656 synchronization. - -Optional Connector Properties: -============================== - -- sdtv-standards: Set the possible signals to which the hardware tries to lock - instead of using the autodetection mechanism. Please look at - [1] for more information. - -[1] Documentation/devicetree/bindings/display/connector/analog-tv-connector.yaml. - -Example - three input sources: -#include - -comp_connector_0 { - compatible = "composite-video-connector"; - label = "Composite0"; - sdtv-standards = ; /* limit to pal-m signals */ - - port { - composite0_to_tvp5150: endpoint { - remote-endpoint = <&tvp5150_to_composite0>; - }; - }; -}; - -comp_connector_1 { - compatible = "composite-video-connector"; - label = "Composite1"; - sdtv-standards = ; /* limit to ntsc-m signals */ - - port { - composite1_to_tvp5150: endpoint { - remote-endpoint = <&tvp5150_to_composite1>; - }; - }; -}; - -svideo_connector { - compatible = "svideo-connector"; - label = "S-Video"; - - port { - #address-cells = <1>; - #size-cells = <0>; - - svideo_luma_to_tvp5150: endpoint@0 { - reg = <0>; - remote-endpoint = <&tvp5150_to_svideo_luma>; - }; - - svideo_chroma_to_tvp5150: endpoint@1 { - reg = <1>; - remote-endpoint = <&tvp5150_to_svideo_chroma>; - }; - }; -}; - -&i2c2 { - tvp5150@5c { - compatible = "ti,tvp5150"; - reg = <0x5c>; - pdn-gpios = <&gpio4 30 GPIO_ACTIVE_LOW>; - reset-gpios = <&gpio6 7 GPIO_ACTIVE_LOW>; - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - - tvp5150_to_composite0: endpoint@0 { - reg = <0>; - remote-endpoint = <&composite0_to_tvp5150>; - }; - - tvp5150_to_svideo_luma: endpoint@1 { - reg = <1>; - remote-endpoint = <&svideo_luma_to_tvp5150>; - }; - }; - - port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - - tvp5150_to_composite1: endpoint@0 { - reg = <0>; - remote-endpoint = <&composite1_to_tvp5150>; - }; - - tvp5150_to_svideo_chroma: endpoint@1 { - reg = <1>; - remote-endpoint = <&svideo_chroma_to_tvp5150>; - }; - }; - - port@2 { - reg = <2>; - - tvp5150_1: endpoint { - remote-endpoint = <&ccdc_ep>; - }; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/media/i2c/ti,tvp5150.yaml b/Documentation/devicetree/bindings/media/i2c/ti,tvp5150.yaml new file mode 100644 index 0000000000000..382a29652a05d --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ti,tvp5150.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/i2c/ti,tvp5150.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TVP5150 and TVP5151 video decoders + +maintainers: + - Frank Li + +description: + The TVP5150 and TVP5151 are video decoders that convert baseband NTSC and PAL + (and also SECAM in the TVP5151 case) video signals to either 8-bit 4:2:2 YUV + with discrete syncs or 8-bit ITU-R BT.656 with embedded syncs output formats. + +properties: + compatible: + const: ti,tvp5150 + + reg: + maxItems: 1 + + pdn-gpios: + maxItems: 1 + + reset-gpios: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + sink port node, AIP1A + + properties: + endpoint: + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + + port@1: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + sink port node, AIP1B + + properties: + endpoint: + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + + port@2: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + source port node, Y-OUT + + properties: + endpoint: + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + +required: + - compatible + - reg + - port@2 + +additionalProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + bridge@5c { + compatible = "ti,tvp5150"; + reg = <0x5c>; + pdn-gpios = <&gpio4 30 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio6 7 GPIO_ACTIVE_LOW>; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + endpoint@0 { + reg = <0>; + remote-endpoint = <&composite0_to_tvp5150>; + }; + + endpoint@1 { + reg = <1>; + remote-endpoint = <&svideo_luma_to_tvp5150>; + }; + }; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + endpoint@0 { + reg = <0>; + remote-endpoint = <&composite1_to_tvp5150>; + }; + + endpoint@1 { + reg = <1>; + remote-endpoint = <&svideo_chroma_to_tvp5150>; + }; + }; + + port@2 { + reg = <2>; + + endpoint { + remote-endpoint = <&ccdc_ep>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/mediatek,mt8173-mdp.yaml b/Documentation/devicetree/bindings/media/mediatek,mt8173-mdp.yaml new file mode 100644 index 0000000000000..8ca33a733c478 --- /dev/null +++ b/Documentation/devicetree/bindings/media/mediatek,mt8173-mdp.yaml @@ -0,0 +1,169 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/mediatek,mt8173-mdp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT8173 Media Data Path + +maintainers: + - Ariel D'Alessandro + +description: + Media Data Path is used for scaling and color space conversion. + +properties: + compatible: + oneOf: + - enum: + - mediatek,mt8173-mdp-rdma + - mediatek,mt8173-mdp-rsz + - mediatek,mt8173-mdp-wdma + - mediatek,mt8173-mdp-wrot + - items: + - const: mediatek,mt8173-mdp-rdma + - const: mediatek,mt8173-mdp + + reg: + maxItems: 1 + + clocks: + minItems: 1 + maxItems: 2 + + power-domains: + maxItems: 1 + + iommus: + maxItems: 1 + + mediatek,vpu: + $ref: /schemas/types.yaml#/definitions/phandle + description: + phandle to Mediatek Video Processor Unit for HW Codec encode/decode and + image processing. + +required: + - compatible + - reg + - clocks + - power-domains + +allOf: + - if: + properties: + compatible: + contains: + const: mediatek,mt8173-mdp-rdma + then: + properties: + clocks: + items: + - description: Main clock + - description: Mutex clock + else: + properties: + clocks: + items: + - description: Main clock + + - if: + properties: + compatible: + contains: + enum: + - mediatek,mt8173-mdp-rdma + - mediatek,mt8173-mdp-wdma + - mediatek,mt8173-mdp-wrot + then: + required: + - iommus + + - if: + properties: + compatible: + contains: + const: mediatek,mt8173-mdp + then: + required: + - mediatek,vpu + +additionalProperties: false + +examples: + - | + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + mdp_rdma0: rdma@14001000 { + compatible = "mediatek,mt8173-mdp-rdma", + "mediatek,mt8173-mdp"; + reg = <0 0x14001000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RDMA0>, + <&mmsys CLK_MM_MUTEX_32K>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_RDMA0>; + mediatek,vpu = <&vpu>; + }; + + mdp_rdma1: rdma@14002000 { + compatible = "mediatek,mt8173-mdp-rdma"; + reg = <0 0x14002000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RDMA1>, + <&mmsys CLK_MM_MUTEX_32K>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_RDMA1>; + }; + + mdp_rsz0: rsz@14003000 { + compatible = "mediatek,mt8173-mdp-rsz"; + reg = <0 0x14003000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RSZ0>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; + }; + + mdp_rsz1: rsz@14004000 { + compatible = "mediatek,mt8173-mdp-rsz"; + reg = <0 0x14004000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RSZ1>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; + }; + + mdp_rsz2: rsz@14005000 { + compatible = "mediatek,mt8173-mdp-rsz"; + reg = <0 0x14005000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_RSZ2>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; + }; + + mdp_wdma0: wdma@14006000 { + compatible = "mediatek,mt8173-mdp-wdma"; + reg = <0 0x14006000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_WDMA>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_WDMA>; + }; + + mdp_wrot0: wrot@14007000 { + compatible = "mediatek,mt8173-mdp-wrot"; + reg = <0 0x14007000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_WROT0>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_WROT0>; + }; + + mdp_wrot1: wrot@14008000 { + compatible = "mediatek,mt8173-mdp-wrot"; + reg = <0 0x14008000 0 0x1000>; + clocks = <&mmsys CLK_MM_MDP_WROT1>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; + iommus = <&iommu M4U_PORT_MDP_WROT1>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt deleted file mode 100644 index 253a93eabb5e5..0000000000000 --- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt +++ /dev/null @@ -1,96 +0,0 @@ -* Mediatek Media Data Path - -Media Data Path is used for scaling and color space conversion. - -Required properties (controller node): -- compatible: "mediatek,mt8173-mdp" -- mediatek,vpu: the node of video processor unit, see - Documentation/devicetree/bindings/media/mediatek,mt8173-vpu.yaml for - details. - -Required properties (all function blocks, child node): -- compatible: Should be one of - "mediatek,mt8173-mdp-rdma" - read DMA - "mediatek,mt8173-mdp-rsz" - resizer - "mediatek,mt8173-mdp-wdma" - write DMA - "mediatek,mt8173-mdp-wrot" - write DMA with rotation -- reg: Physical base address and length of the function block register space -- clocks: device clocks, see - Documentation/devicetree/bindings/clock/clock-bindings.txt for details. -- power-domains: a phandle to the power domain, see - Documentation/devicetree/bindings/power/power_domain.txt for details. - -Required properties (DMA function blocks, child node): -- compatible: Should be one of - "mediatek,mt8173-mdp-rdma" - "mediatek,mt8173-mdp-wdma" - "mediatek,mt8173-mdp-wrot" -- iommus: should point to the respective IOMMU block with master port as - argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml - for details. - -Example: - mdp_rdma0: rdma@14001000 { - compatible = "mediatek,mt8173-mdp-rdma"; - "mediatek,mt8173-mdp"; - reg = <0 0x14001000 0 0x1000>; - clocks = <&mmsys CLK_MM_MDP_RDMA0>, - <&mmsys CLK_MM_MUTEX_32K>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; - iommus = <&iommu M4U_PORT_MDP_RDMA0>; - mediatek,vpu = <&vpu>; - }; - - mdp_rdma1: rdma@14002000 { - compatible = "mediatek,mt8173-mdp-rdma"; - reg = <0 0x14002000 0 0x1000>; - clocks = <&mmsys CLK_MM_MDP_RDMA1>, - <&mmsys CLK_MM_MUTEX_32K>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; - iommus = <&iommu M4U_PORT_MDP_RDMA1>; - }; - - mdp_rsz0: rsz@14003000 { - compatible = "mediatek,mt8173-mdp-rsz"; - reg = <0 0x14003000 0 0x1000>; - clocks = <&mmsys CLK_MM_MDP_RSZ0>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; - }; - - mdp_rsz1: rsz@14004000 { - compatible = "mediatek,mt8173-mdp-rsz"; - reg = <0 0x14004000 0 0x1000>; - clocks = <&mmsys CLK_MM_MDP_RSZ1>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; - }; - - mdp_rsz2: rsz@14005000 { - compatible = "mediatek,mt8173-mdp-rsz"; - reg = <0 0x14005000 0 0x1000>; - clocks = <&mmsys CLK_MM_MDP_RSZ2>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; - }; - - mdp_wdma0: wdma@14006000 { - compatible = "mediatek,mt8173-mdp-wdma"; - reg = <0 0x14006000 0 0x1000>; - clocks = <&mmsys CLK_MM_MDP_WDMA>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; - iommus = <&iommu M4U_PORT_MDP_WDMA>; - }; - - mdp_wrot0: wrot@14007000 { - compatible = "mediatek,mt8173-mdp-wrot"; - reg = <0 0x14007000 0 0x1000>; - clocks = <&mmsys CLK_MM_MDP_WROT0>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; - iommus = <&iommu M4U_PORT_MDP_WROT0>; - }; - - mdp_wrot1: wrot@14008000 { - compatible = "mediatek,mt8173-mdp-wrot"; - reg = <0 0x14008000 0 0x1000>; - clocks = <&mmsys CLK_MM_MDP_WROT1>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; - iommus = <&iommu M4U_PORT_MDP_WROT1>; - }; diff --git a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml index f43b91984f015..001a0d9b71e09 100644 --- a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml +++ b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml @@ -22,6 +22,7 @@ properties: - fsl,imx8mn-isi - fsl,imx8mp-isi - fsl,imx8ulp-isi + - fsl,imx91-isi - fsl,imx93-isi reg: @@ -66,7 +67,6 @@ required: - interrupts - clocks - clock-names - - fsl,blk-ctrl - ports allOf: @@ -77,6 +77,7 @@ allOf: enum: - fsl,imx8mn-isi - fsl,imx8ulp-isi + - fsl,imx91-isi - fsl,imx93-isi then: properties: @@ -109,6 +110,16 @@ allOf: - port@0 - port@1 + - if: + properties: + compatible: + not: + contains: + const: fsl,imx91-isi + then: + required: + - fsl,blk-ctrl + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml b/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml index 4cba42ba7cf72..b5aca3d2cc5c2 100644 --- a/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml +++ b/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml @@ -79,7 +79,6 @@ allOf: power-domains: minItems: 2 # Wrapper and 1 slot - additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/media/qcom,msm8939-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8939-camss.yaml new file mode 100644 index 0000000000000..77b389d76a437 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,msm8939-camss.yaml @@ -0,0 +1,254 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/qcom,msm8939-camss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm MSM8939 Camera Subsystem (CAMSS) + +maintainers: + - Vincent Knecht + +description: + The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms + +properties: + compatible: + const: qcom,msm8939-camss + + reg: + maxItems: 11 + + reg-names: + items: + - const: csiphy0 + - const: csiphy0_clk_mux + - const: csiphy1 + - const: csiphy1_clk_mux + - const: csid0 + - const: csid1 + - const: ispif + - const: csi_clk_mux + - const: vfe0 + - const: csid2 + - const: vfe0_vbif + + clocks: + maxItems: 24 + + clock-names: + items: + - const: top_ahb + - const: ispif_ahb + - const: csiphy0_timer + - const: csiphy1_timer + - const: csi0_ahb + - const: csi0 + - const: csi0_phy + - const: csi0_pix + - const: csi0_rdi + - const: csi1_ahb + - const: csi1 + - const: csi1_phy + - const: csi1_pix + - const: csi1_rdi + - const: ahb + - const: vfe0 + - const: csi_vfe0 + - const: vfe_ahb + - const: vfe_axi + - const: csi2_ahb + - const: csi2 + - const: csi2_phy + - const: csi2_pix + - const: csi2_rdi + + interrupts: + maxItems: 7 + + interrupt-names: + items: + - const: csiphy0 + - const: csiphy1 + - const: csid0 + - const: csid1 + - const: ispif + - const: vfe0 + - const: csid2 + + iommus: + maxItems: 1 + + power-domains: + items: + - description: VFE GDSC - Video Front End, Global Distributed Switch + Controller. + + vdda-supply: + description: + Definition of the regulator used as 1.2V analog power supply. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + description: + CSI input ports. + + patternProperties: + "^port@[0-1]$": + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 4 + + bus-type: + enum: + - 4 # MEDIA_BUS_TYPE_CSI2_DPHY + + required: + - data-lanes + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - interrupts + - interrupt-names + - iommus + - power-domains + - vdda-supply + - ports + +additionalProperties: false + +examples: + - | + #include + #include + + isp@1b0ac00 { + compatible = "qcom,msm8939-camss"; + + reg = <0x01b0ac00 0x200>, + <0x01b00030 0x4>, + <0x01b0b000 0x200>, + <0x01b00038 0x4>, + <0x01b08000 0x100>, + <0x01b08400 0x100>, + <0x01b0a000 0x500>, + <0x01b00020 0x10>, + <0x01b10000 0x1000>, + <0x01b08800 0x100>, + <0x01b40000 0x200>; + + reg-names = "csiphy0", + "csiphy0_clk_mux", + "csiphy1", + "csiphy1_clk_mux", + "csid0", + "csid1", + "ispif", + "csi_clk_mux", + "vfe0", + "csid2", + "vfe0_vbif"; + + clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>, + <&gcc GCC_CAMSS_ISPIF_AHB_CLK>, + <&gcc GCC_CAMSS_CSI0PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CSI1PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CSI0_AHB_CLK>, + <&gcc GCC_CAMSS_CSI0_CLK>, + <&gcc GCC_CAMSS_CSI0PHY_CLK>, + <&gcc GCC_CAMSS_CSI0PIX_CLK>, + <&gcc GCC_CAMSS_CSI0RDI_CLK>, + <&gcc GCC_CAMSS_CSI1_AHB_CLK>, + <&gcc GCC_CAMSS_CSI1_CLK>, + <&gcc GCC_CAMSS_CSI1PHY_CLK>, + <&gcc GCC_CAMSS_CSI1PIX_CLK>, + <&gcc GCC_CAMSS_CSI1RDI_CLK>, + <&gcc GCC_CAMSS_AHB_CLK>, + <&gcc GCC_CAMSS_VFE0_CLK>, + <&gcc GCC_CAMSS_CSI_VFE0_CLK>, + <&gcc GCC_CAMSS_VFE_AHB_CLK>, + <&gcc GCC_CAMSS_VFE_AXI_CLK>, + <&gcc GCC_CAMSS_CSI2_AHB_CLK>, + <&gcc GCC_CAMSS_CSI2_CLK>, + <&gcc GCC_CAMSS_CSI2PHY_CLK>, + <&gcc GCC_CAMSS_CSI2PIX_CLK>, + <&gcc GCC_CAMSS_CSI2RDI_CLK>; + + clock-names = "top_ahb", + "ispif_ahb", + "csiphy0_timer", + "csiphy1_timer", + "csi0_ahb", + "csi0", + "csi0_phy", + "csi0_pix", + "csi0_rdi", + "csi1_ahb", + "csi1", + "csi1_phy", + "csi1_pix", + "csi1_rdi", + "ahb", + "vfe0", + "csi_vfe0", + "vfe_ahb", + "vfe_axi", + "csi2_ahb", + "csi2", + "csi2_phy", + "csi2_pix", + "csi2_rdi"; + + interrupts = , + , + , + , + , + , + ; + + interrupt-names = "csiphy0", + "csiphy1", + "csid0", + "csid1", + "ispif", + "vfe0", + "csid2"; + + iommus = <&apps_iommu 3>; + + power-domains = <&gcc VFE_GDSC>; + + vdda-supply = <®_1v2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + csiphy1_ep: endpoint { + data-lanes = <0 2>; + remote-endpoint = <&sensor_ep>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/qcom,sc8280xp-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sc8280xp-camss.yaml index d195f1bfb23d5..c99fe4106eee9 100644 --- a/Documentation/devicetree/bindings/media/qcom,sc8280xp-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,sc8280xp-camss.yaml @@ -484,7 +484,6 @@ examples: "gcc_axi_hf", "gcc_axi_sf"; - iommus = <&apps_smmu 0x2000 0x4e0>, <&apps_smmu 0x2020 0x4e0>, <&apps_smmu 0x2040 0x4e0>, diff --git a/Documentation/devicetree/bindings/media/qcom,sm8650-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sm8650-camss.yaml new file mode 100644 index 0000000000000..9c8de722601ec --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,sm8650-camss.yaml @@ -0,0 +1,375 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/qcom,sm8650-camss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SM8650 Camera Subsystem (CAMSS) + +maintainers: + - Vladimir Zapolskiy + +description: + The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms. + +properties: + compatible: + const: qcom,sm8650-camss + + reg: + maxItems: 17 + + reg-names: + items: + - const: csid_wrapper + - const: csid0 + - const: csid1 + - const: csid2 + - const: csid_lite0 + - const: csid_lite1 + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: csiphy3 + - const: csiphy4 + - const: csiphy5 + - const: vfe0 + - const: vfe1 + - const: vfe2 + - const: vfe_lite0 + - const: vfe_lite1 + + clocks: + maxItems: 33 + + clock-names: + items: + - const: camnoc_axi + - const: cpas_ahb + - const: cpas_fast_ahb + - const: cpas_vfe0 + - const: cpas_vfe1 + - const: cpas_vfe2 + - const: cpas_vfe_lite + - const: csid + - const: csiphy0 + - const: csiphy0_timer + - const: csiphy1 + - const: csiphy1_timer + - const: csiphy2 + - const: csiphy2_timer + - const: csiphy3 + - const: csiphy3_timer + - const: csiphy4 + - const: csiphy4_timer + - const: csiphy5 + - const: csiphy5_timer + - const: csiphy_rx + - const: gcc_axi_hf + - const: qdss_debug_xo + - const: vfe0 + - const: vfe0_fast_ahb + - const: vfe1 + - const: vfe1_fast_ahb + - const: vfe2 + - const: vfe2_fast_ahb + - const: vfe_lite + - const: vfe_lite_ahb + - const: vfe_lite_cphy_rx + - const: vfe_lite_csid + + interrupts: + maxItems: 16 + + interrupt-names: + items: + - const: csid0 + - const: csid1 + - const: csid2 + - const: csid_lite0 + - const: csid_lite1 + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: csiphy3 + - const: csiphy4 + - const: csiphy5 + - const: vfe0 + - const: vfe1 + - const: vfe2 + - const: vfe_lite0 + - const: vfe_lite1 + + interconnects: + maxItems: 2 + + interconnect-names: + items: + - const: ahb + - const: hf_mnoc + + iommus: + maxItems: 3 + + power-domains: + items: + - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller. + - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller. + - description: IFE2 GDSC - Image Front End, Global Distributed Switch Controller. + - description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller. + + power-domain-names: + items: + - const: ife0 + - const: ife1 + - const: ife2 + - const: top + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + description: + CSI input ports. + + patternProperties: + "^port@[0-5]$": + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + + description: + Input port for receiving CSI data from a CSIPHY. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 4 + + bus-type: + enum: + - 1 # MEDIA_BUS_TYPE_CSI2_CPHY + - 4 # MEDIA_BUS_TYPE_CSI2_DPHY + + required: + - data-lanes + + vdd-csiphy01-0p9-supply: + description: + Phandle to a 0.9V regulator supply to CSIPHY0 and CSIPHY1 IP blocks. + + vdd-csiphy01-1p2-supply: + description: + Phandle to a 1.2V regulator supply to CSIPHY0 and CSIPHY1 IP blocks. + + vdd-csiphy24-0p9-supply: + description: + Phandle to a 0.9V regulator supply to CSIPHY2 and CSIPHY4 IP blocks. + + vdd-csiphy24-1p2-supply: + description: + Phandle to a 1.2V regulator supply to CSIPHY2 and CSIPHY4 IP blocks. + + vdd-csiphy35-0p9-supply: + description: + Phandle to a 0.9V regulator supply to CSIPHY3 and CSIPHY5 IP blocks. + + vdd-csiphy35-1p2-supply: + description: + Phandle to a 1.2V regulator supply to CSIPHY3 and CSIPHY5 IP blocks. + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - interconnects + - interconnect-names + - interrupts + - interrupt-names + - iommus + - power-domains + - power-domain-names + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + isp@acb6000 { + compatible = "qcom,sm8650-camss"; + reg = <0 0x0acb6000 0 0x1000>, + <0 0x0acb8000 0 0x1000>, + <0 0x0acba000 0 0x1000>, + <0 0x0acbc000 0 0x1000>, + <0 0x0accb000 0 0x1000>, + <0 0x0acd0000 0 0x1000>, + <0 0x0ace4000 0 0x2000>, + <0 0x0ace6000 0 0x2000>, + <0 0x0ace8000 0 0x2000>, + <0 0x0acea000 0 0x2000>, + <0 0x0acec000 0 0x2000>, + <0 0x0acee000 0 0x2000>, + <0 0x0ac62000 0 0xf000>, + <0 0x0ac71000 0 0xf000>, + <0 0x0ac80000 0 0xf000>, + <0 0x0accc000 0 0x2000>, + <0 0x0acd1000 0 0x2000>; + reg-names = "csid_wrapper", + "csid0", + "csid1", + "csid2", + "csid_lite0", + "csid_lite1", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy3", + "csiphy4", + "csiphy5", + "vfe0", + "vfe1", + "vfe2", + "vfe_lite0", + "vfe_lite1"; + clocks = <&camcc CAM_CC_CAMNOC_AXI_RT_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CPAS_FAST_AHB_CLK>, + <&camcc CAM_CC_CPAS_IFE_0_CLK>, + <&camcc CAM_CC_CPAS_IFE_1_CLK>, + <&camcc CAM_CC_CPAS_IFE_2_CLK>, + <&camcc CAM_CC_CPAS_IFE_LITE_CLK>, + <&camcc CAM_CC_CSID_CLK>, + <&camcc CAM_CC_CSIPHY0_CLK>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY1_CLK>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY2_CLK>, + <&camcc CAM_CC_CSI3PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY3_CLK>, + <&camcc CAM_CC_CSI4PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY4_CLK>, + <&camcc CAM_CC_CSI5PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY5_CLK>, + <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_QDSS_DEBUG_XO_CLK>, + <&camcc CAM_CC_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_FAST_AHB_CLK>, + <&camcc CAM_CC_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_FAST_AHB_CLK>, + <&camcc CAM_CC_IFE_2_CLK>, + <&camcc CAM_CC_IFE_2_FAST_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CLK>, + <&camcc CAM_CC_IFE_LITE_AHB_CLK>, + <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_CSID_CLK>; + clock-names = "camnoc_axi", + "cpas_ahb", + "cpas_fast_ahb", + "cpas_vfe0", + "cpas_vfe1", + "cpas_vfe2", + "cpas_vfe_lite", + "csid", + "csiphy0", + "csiphy0_timer", + "csiphy1", + "csiphy1_timer", + "csiphy2", + "csiphy2_timer", + "csiphy3", + "csiphy3_timer", + "csiphy4", + "csiphy4_timer", + "csiphy5", + "csiphy5_timer", + "csiphy_rx", + "gcc_axi_hf", + "qdss_debug_xo", + "vfe0", + "vfe0_fast_ahb", + "vfe1", + "vfe1_fast_ahb", + "vfe2", + "vfe2_fast_ahb", + "vfe_lite", + "vfe_lite_ahb", + "vfe_lite_cphy_rx", + "vfe_lite_csid"; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "csid0", + "csid1", + "csid2", + "csid_lite0", + "csid_lite1", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy3", + "csiphy4", + "csiphy5", + "vfe0", + "vfe1", + "vfe2", + "vfe_lite0", + "vfe_lite1"; + interconnects = <&gem_noc MASTER_APPSS_PROC 0 + &config_noc SLAVE_CAMERA_CFG 0>, + <&mmss_noc MASTER_CAMNOC_HF 0 + &mc_virt SLAVE_EBI1 0>; + interconnect-names = "ahb", "hf_mnoc"; + iommus = <&apps_smmu 0x800 0x20>, + <&apps_smmu 0x18a0 0x40>, + <&apps_smmu 0x1860 0x00>; + power-domains = <&camcc CAM_CC_IFE_0_GDSC>, + <&camcc CAM_CC_IFE_1_GDSC>, + <&camcc CAM_CC_IFE_2_GDSC>, + <&camcc CAM_CC_TITAN_TOP_GDSC>; + power-domain-names = "ife0", "ife1", "ife2", "top"; + vdd-csiphy01-0p9-supply = <&vreg_0p9>; + vdd-csiphy01-1p2-supply = <&vreg_1p2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + csiphy1_ep: endpoint { + data-lanes = <0 1>; + remote-endpoint = <&camera_sensor>; + }; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/qcom,sm8750-iris.yaml b/Documentation/devicetree/bindings/media/qcom,sm8750-iris.yaml index c9a0fcafe53fb..c42d3470bdac7 100644 --- a/Documentation/devicetree/bindings/media/qcom,sm8750-iris.yaml +++ b/Documentation/devicetree/bindings/media/qcom,sm8750-iris.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm SM8750 SoC Iris video encoder and decoder maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: The Iris video processing unit on Qualcomm SM8750 SoC is a video encode and diff --git a/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml b/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml index b075341caafc1..b87a13479a4bf 100644 --- a/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml @@ -124,7 +124,7 @@ properties: vdd-csiphy-1p2-supply: description: - Phandle to 1.8V regulator supply to a PHY. + Phandle to 1.2V regulator supply to a PHY. ports: $ref: /schemas/graph.yaml#/properties/ports diff --git a/Documentation/devicetree/bindings/media/renesas,r9a09g057-ivc.yaml b/Documentation/devicetree/bindings/media/renesas,r9a09g057-ivc.yaml new file mode 100644 index 0000000000000..c09cbd8c9e359 --- /dev/null +++ b/Documentation/devicetree/bindings/media/renesas,r9a09g057-ivc.yaml @@ -0,0 +1,103 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/renesas,r9a09g057-ivc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/V2H(P) Input Video Control Block + +maintainers: + - Daniel Scally + +description: + The IVC block is a module that takes video frames from memory and feeds them + to the Image Signal Processor for processing. + +properties: + compatible: + const: renesas,r9a09g057-ivc # RZ/V2H(P) + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: Input Video Control block register access clock + - description: Video input data AXI bus clock + - description: ISP system clock + + clock-names: + items: + - const: reg + - const: axi + - const: isp + + power-domains: + maxItems: 1 + + resets: + items: + - description: Input Video Control block register access reset + - description: Video input data AXI bus reset + - description: ISP core reset + + reset-names: + items: + - const: reg + - const: axi + - const: isp + + port: + $ref: /schemas/graph.yaml#/properties/port + description: Output parallel video bus + + properties: + endpoint: + $ref: /schemas/graph.yaml#/properties/endpoint + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - power-domains + - resets + - reset-names + - port + +additionalProperties: false + +examples: + - | + #include + #include + + isp-input@16040000 { + compatible = "renesas,r9a09g057-ivc"; + reg = <0x16040000 0x230>; + + clocks = <&cpg CPG_MOD 0xe3>, + <&cpg CPG_MOD 0xe4>, + <&cpg CPG_MOD 0xe5>; + clock-names = "reg", "axi", "isp"; + + power-domains = <&cpg>; + + resets = <&cpg 0xd4>, + <&cpg 0xd1>, + <&cpg 0xd3>; + reset-names = "reg", "axi", "isp"; + + interrupts = ; + + port { + ivc_out: endpoint { + remote-endpoint = <&isp_in>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml new file mode 100644 index 0000000000000..cc08ce94bef70 --- /dev/null +++ b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/rockchip,px30-vip.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip PX30 Video Input Processor (VIP) + +maintainers: + - Mehdi Djait + - Michael Riesch + +description: + The Rockchip PX30 Video Input Processor (VIP) receives the data from a camera + sensor or CCIR656 encoder and transfers it into system main memory by AXI bus. + +properties: + compatible: + const: rockchip,px30-vip + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: ACLK + - description: HCLK + - description: PCLK + + clock-names: + items: + - const: aclk + - const: hclk + - const: pclk + + resets: + items: + - description: AXI + - description: AHB + - description: PCLK IN + + reset-names: + items: + - const: axi + - const: ahb + - const: pclkin + + power-domains: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: input port on the parallel interface + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + bus-type: + enum: + - 5 # MEDIA_BUS_TYPE_PARALLEL + - 6 # MEDIA_BUS_TYPE_BT656 + + required: + - bus-type + + required: + - port@0 + +required: + - compatible + - reg + - interrupts + - clocks + - ports + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + video-capture@ff490000 { + compatible = "rockchip,px30-vip"; + reg = <0x0 0xff490000 0x0 0x200>; + interrupts = ; + clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>; + clock-names = "aclk", "hclk", "pclk"; + power-domains = <&power PX30_PD_VI>; + resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>; + reset-names = "axi", "ahb", "pclkin"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + cif_in: endpoint { + remote-endpoint = <&tw9900_out>; + bus-type = ; + }; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml new file mode 100644 index 0000000000000..18cd0a5a53181 --- /dev/null +++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml @@ -0,0 +1,172 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/rockchip,rk3568-vicap.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip RK3568 Video Capture (VICAP) + +maintainers: + - Michael Riesch + +description: + The Rockchip RK3568 Video Capture (VICAP) block features a digital video + port (DVP, a parallel video interface) and a MIPI CSI-2 port. It receives + the data from camera sensors, video decoders, or other companion ICs and + transfers it into system main memory by AXI bus. + +properties: + compatible: + const: rockchip,rk3568-vicap + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: ACLK + - description: HCLK + - description: DCLK + - description: ICLK + + clock-names: + items: + - const: aclk + - const: hclk + - const: dclk + - const: iclk + + iommus: + maxItems: 1 + + resets: + items: + - description: ARST + - description: HRST + - description: DRST + - description: PRST + - description: IRST + + reset-names: + items: + - const: arst + - const: hrst + - const: drst + - const: prst + - const: irst + + rockchip,grf: + $ref: /schemas/types.yaml#/definitions/phandle + description: Phandle to general register file used for video input block control. + + power-domains: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: The digital video port (DVP, a parallel video interface). + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + bus-type: + enum: + - 5 # MEDIA_BUS_TYPE_PARALLEL + - 6 # MEDIA_BUS_TYPE_BT656 + + rockchip,dvp-clk-delay: + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + minimum: 0 + maximum: 127 + description: + Delay the DVP path clock input to align the sampling phase, + only valid in dual edge sampling mode. Delay is zero by + default and can be adjusted optionally. + + required: + - bus-type + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: Port connected to the MIPI CSI-2 receiver output. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + - clocks + - ports + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + vicap: video-capture@fdfe0000 { + compatible = "rockchip,rk3568-vicap"; + reg = <0x0 0xfdfe0000 0x0 0x200>; + interrupts = ; + assigned-clocks = <&cru DCLK_VICAP>; + assigned-clock-rates = <300000000>; + clocks = <&cru ACLK_VICAP>, <&cru HCLK_VICAP>, + <&cru DCLK_VICAP>, <&cru ICLK_VICAP_G>; + clock-names = "aclk", "hclk", "dclk", "iclk"; + iommus = <&vicap_mmu>; + power-domains = <&power RK3568_PD_VI>; + resets = <&cru SRST_A_VICAP>, <&cru SRST_H_VICAP>, + <&cru SRST_D_VICAP>, <&cru SRST_P_VICAP>, + <&cru SRST_I_VICAP>; + reset-names = "arst", "hrst", "drst", "prst", "irst"; + rockchip,grf = <&grf>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + vicap_dvp: port@0 { + reg = <0>; + + vicap_dvp_input: endpoint { + bus-type = ; + bus-width = <16>; + pclk-sample = ; + remote-endpoint = <&it6801_output>; + }; + }; + + vicap_mipi: port@1 { + reg = <1>; + + vicap_mipi_input: endpoint { + remote-endpoint = <&csi_output>; + }; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml index 96b6c89387683..809fda45b3bd6 100644 --- a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml +++ b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml @@ -16,6 +16,7 @@ description: |- properties: compatible: oneOf: + - const: rockchip,rk3288-vdec - const: rockchip,rk3399-vdec - const: rockchip,rk3576-vdec - const: rockchip,rk3588-vdec diff --git a/Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml b/Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml index dd6cc7ac1f7ca..2ddca4167b0b5 100644 --- a/Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml +++ b/Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Samsung S5P/Exynos SoC series MIPI CSI-2 receiver (MIPI CSIS) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Sylwester Nawrocki properties: diff --git a/Documentation/devicetree/bindings/media/samsung,exynos4210-fimc.yaml b/Documentation/devicetree/bindings/media/samsung,exynos4210-fimc.yaml index 2ba27b230559b..17ece4eb300c9 100644 --- a/Documentation/devicetree/bindings/media/samsung,exynos4210-fimc.yaml +++ b/Documentation/devicetree/bindings/media/samsung,exynos4210-fimc.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Samsung S5P/Exynos SoC Fully Integrated Mobile Camera maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Sylwester Nawrocki description: diff --git a/Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-is.yaml b/Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-is.yaml index 71d63bb9abb5f..c8894358c46cd 100644 --- a/Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-is.yaml +++ b/Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-is.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Samsung Exynos4212/4412 SoC Imaging Subsystem (FIMC-IS) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Sylwester Nawrocki description: @@ -111,7 +111,6 @@ patternProperties: reg: maxItems: 1 - clocks: maxItems: 1 diff --git a/Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-lite.yaml b/Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-lite.yaml index f80eca0a4f41a..bda724897293d 100644 --- a/Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-lite.yaml +++ b/Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-lite.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Samsung Exynos SoC series camera host interface (FIMC-LITE) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Sylwester Nawrocki description: diff --git a/Documentation/devicetree/bindings/media/samsung,fimc.yaml b/Documentation/devicetree/bindings/media/samsung,fimc.yaml index 2a54379d95095..1bfba84f8854f 100644 --- a/Documentation/devicetree/bindings/media/samsung,fimc.yaml +++ b/Documentation/devicetree/bindings/media/samsung,fimc.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Samsung S5P/Exynos SoC Camera Subsystem (FIMC) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Sylwester Nawrocki description: | diff --git a/Documentation/devicetree/bindings/media/samsung,s5c73m3.yaml b/Documentation/devicetree/bindings/media/samsung,s5c73m3.yaml index 1b75390fdaac7..1af5d7ac382c2 100644 --- a/Documentation/devicetree/bindings/media/samsung,s5c73m3.yaml +++ b/Documentation/devicetree/bindings/media/samsung,s5c73m3.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Samsung S5C73M3 8Mp camera ISP maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Sylwester Nawrocki description: diff --git a/Documentation/devicetree/bindings/media/samsung,s5pv210-jpeg.yaml b/Documentation/devicetree/bindings/media/samsung,s5pv210-jpeg.yaml index e28d6ec56c0b5..5c969e764d4f9 100644 --- a/Documentation/devicetree/bindings/media/samsung,s5pv210-jpeg.yaml +++ b/Documentation/devicetree/bindings/media/samsung,s5pv210-jpeg.yaml @@ -42,7 +42,6 @@ properties: reg: maxItems: 1 - required: - compatible - clocks diff --git a/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml index 510e94e9ca3a1..b7f6c87d0e06a 100644 --- a/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml +++ b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Synopsys DesignWare HDMI RX Controller maintainers: - - Shreeya Patel + - Dmitry Osipenko description: Synopsys DesignWare HDMI Input Controller preset on RK3588 SoCs diff --git a/Documentation/devicetree/bindings/media/st,stm32-dma2d.yaml b/Documentation/devicetree/bindings/media/st,stm32-dma2d.yaml index 4afa4a24b8685..b9f7d84f38c2e 100644 --- a/Documentation/devicetree/bindings/media/st,stm32-dma2d.yaml +++ b/Documentation/devicetree/bindings/media/st,stm32-dma2d.yaml @@ -21,7 +21,6 @@ description: format and copy the result into a part or the whole of a destination image with a different color format. (TODO) - maintainers: - Dillon Min diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt deleted file mode 100644 index 880d4d70c9fd7..0000000000000 --- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt +++ /dev/null @@ -1,88 +0,0 @@ -STMicroelectronics STi c8sectpfe binding -============================================ - -This document describes the c8sectpfe device bindings that is used to get transport -stream data into the SoC on the TS pins, and into DDR for further processing. - -It is typically used in conjunction with one or more demodulator and tuner devices -which converts from the RF to digital domain. Demodulators and tuners are usually -located on an external DVB frontend card connected to SoC TS input pins. - -Currently 7 TS input (tsin) channels are supported on the stih407 family SoC. - -Required properties (controller (parent) node): -- compatible : Should be "stih407-c8sectpfe" - -- reg : Address and length of register sets for each device in - "reg-names" - -- reg-names : The names of the register addresses corresponding to the - registers filled in "reg": - - c8sectpfe: c8sectpfe registers - - c8sectpfe-ram: c8sectpfe internal sram - -- clocks : phandle list of c8sectpfe clocks -- clock-names : should be "c8sectpfe" -See: Documentation/devicetree/bindings/clock/clock-bindings.txt - -- pinctrl-names : a pinctrl state named tsin%d-serial or tsin%d-parallel (where %d is tsin-num) - must be defined for each tsin child node. -- pinctrl-0 : phandle referencing pin configuration for this tsin configuration -See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt - - -Required properties (tsin (child) node): - -- tsin-num : tsin id of the InputBlock (must be between 0 to 6) -- i2c-bus : phandle to the I2C bus DT node which the demodulators & tuners on this tsin channel are connected. -- reset-gpios : reset gpio for this tsin channel. - -Optional properties (tsin (child) node): - -- invert-ts-clk : Bool property to control sense of ts input clock (data stored on falling edge of clk). -- serial-not-parallel : Bool property to configure input bus width (serial on ts_data<7>). -- async-not-sync : Bool property to control if data is received in asynchronous mode - (all bits/bytes with ts_valid or ts_packet asserted are valid). - -- dvb-card : Describes the NIM card connected to this tsin channel. - -Example: - -/* stih410 SoC b2120 + b2004a + stv0367-pll(NIMB) + stv0367-tda18212 (NIMA) DT example) */ - - c8sectpfe@8a20000 { - compatible = "st,stih407-c8sectpfe"; - reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>; - reg-names = "stfe", "stfe-ram"; - interrupts = , ; - interrupt-names = "stfe-error-irq", "stfe-idle-irq"; - pinctrl-0 = <&pinctrl_tsin0_serial>; - pinctrl-1 = <&pinctrl_tsin0_parallel>; - pinctrl-2 = <&pinctrl_tsin3_serial>; - pinctrl-3 = <&pinctrl_tsin4_serial_alt3>; - pinctrl-4 = <&pinctrl_tsin5_serial_alt1>; - pinctrl-names = "tsin0-serial", - "tsin0-parallel", - "tsin3-serial", - "tsin4-serial", - "tsin5-serial"; - clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>; - clock-names = "c8sectpfe"; - - /* tsin0 is TSA on NIMA */ - tsin0: port@0 { - tsin-num = <0>; - serial-not-parallel; - i2c-bus = <&ssc2>; - reset-gpios = <&pio15 4 GPIO_ACTIVE_HIGH>; - dvb-card = ; - }; - - tsin3: port@3 { - tsin-num = <3>; - serial-not-parallel; - i2c-bus = <&ssc3>; - reset-gpios = <&pio15 7 GPIO_ACTIVE_HIGH>; - dvb-card = ; - }; - }; diff --git a/Documentation/devicetree/bindings/media/video-interface-devices.yaml b/Documentation/devicetree/bindings/media/video-interface-devices.yaml index 3ad1590b04966..a81d2a155fe66 100644 --- a/Documentation/devicetree/bindings/media/video-interface-devices.yaml +++ b/Documentation/devicetree/bindings/media/video-interface-devices.yaml @@ -128,7 +128,6 @@ properties: 0 degrees camera rotation: - Y-Rp ^ Y-Rc ! @@ -145,7 +144,6 @@ properties: 0 +-------------------------------------> 0 X-Rc - X-Rc 0 <------------------------------------+ 0 X-Rp 0 ! @@ -228,7 +226,6 @@ properties: V X-Rc - Example one - Webcam A camera module installed on the user facing part of a laptop screen @@ -273,7 +270,6 @@ properties: optical inversion, the two reference systems will not be aligned, with 'Rp' being rotated 180 degrees relatively to 'Rc': - X-Rc 0 <------------------------------------+ 0 ! diff --git a/Documentation/devicetree/bindings/media/video-interfaces.yaml b/Documentation/devicetree/bindings/media/video-interfaces.yaml index 038e85b45befa..6ed4695cacf7e 100644 --- a/Documentation/devicetree/bindings/media/video-interfaces.yaml +++ b/Documentation/devicetree/bindings/media/video-interfaces.yaml @@ -95,7 +95,7 @@ properties: - 6 # BT.656 - 7 # DPI description: - Data bus type. + Data bus type. See include/dt-bindings/media/video-interfaces.h. bus-width: $ref: /schemas/types.yaml#/definitions/uint32 @@ -229,7 +229,7 @@ properties: Imaging. The length of the array must be the same length as the data-lanes property. If the line-orders property is omitted, the value shall be interpreted as 0 (ABC). This property is valid for CSI-2 C-PHY - busses only. + busses only. See include/dt-bindings/media/video-interfaces.h. strobe: $ref: /schemas/types.yaml#/definitions/uint32 diff --git a/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-bus-controller.yaml b/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-bus-controller.yaml index 3049d6bb0b1fe..2a4bf905a3698 100644 --- a/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-bus-controller.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-bus-controller.yaml @@ -12,7 +12,7 @@ description: | including IXP42x, IXP43x, IXP45x and IXP46x. maintainers: - - Linus Walleij + - Linus Walleij properties: $nodename: diff --git a/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-peripheral-props.yaml b/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-peripheral-props.yaml index d1479a7b9c8df..020fa49c34544 100644 --- a/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-peripheral-props.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-peripheral-props.yaml @@ -12,7 +12,7 @@ description: including IXP42x, IXP43x, IXP45x and IXP46x. maintainers: - - Linus Walleij + - Linus Walleij properties: intel,ixp4xx-eb-t1: diff --git a/Documentation/devicetree/bindings/memory-controllers/qcom,ebi2-peripheral-props.yaml b/Documentation/devicetree/bindings/memory-controllers/qcom,ebi2-peripheral-props.yaml index 29f8c30e8a88a..aec88cd2df76d 100644 --- a/Documentation/devicetree/bindings/memory-controllers/qcom,ebi2-peripheral-props.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/qcom,ebi2-peripheral-props.yaml @@ -62,7 +62,6 @@ properties: minimum: 0 maximum: 15 - # FAST chip selects qcom,xmem-address-hold-enable: $ref: /schemas/types.yaml#/definitions/uint32 diff --git a/Documentation/devicetree/bindings/mfd/apple,smc.yaml b/Documentation/devicetree/bindings/mfd/apple,smc.yaml index 5429538f7e2e9..0410e712c900a 100644 --- a/Documentation/devicetree/bindings/mfd/apple,smc.yaml +++ b/Documentation/devicetree/bindings/mfd/apple,smc.yaml @@ -46,6 +46,9 @@ properties: reboot: $ref: /schemas/power/reset/apple,smc-reboot.yaml + rtc: + $ref: /schemas/rtc/apple,smc-rtc.yaml + additionalProperties: false required: @@ -80,5 +83,11 @@ examples: nvmem-cell-names = "shutdown_flag", "boot_stage", "boot_error_count", "panic_count"; }; + + rtc { + compatible = "apple,smc-rtc"; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; }; }; diff --git a/Documentation/devicetree/bindings/mfd/arm,dev-platforms-syscon.yaml b/Documentation/devicetree/bindings/mfd/arm,dev-platforms-syscon.yaml index 46b164ae08315..7f3b1b77293c5 100644 --- a/Documentation/devicetree/bindings/mfd/arm,dev-platforms-syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/arm,dev-platforms-syscon.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Arm Ltd Developer Platforms System Controllers maintainers: - - Linus Walleij + - Linus Walleij description: The Arm Ltd Integrator, Realview, and Versatile families of developer diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.yaml b/Documentation/devicetree/bindings/mfd/aspeed-lpc.yaml index f329223cec071..cbc3a2485a2fe 100644 --- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.yaml +++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.yaml @@ -48,16 +48,16 @@ properties: reg: maxItems: 1 - "#address-cells": + '#address-cells': const: 1 - "#size-cells": + '#size-cells': const: 1 ranges: true patternProperties: - "^lpc-ctrl@[0-9a-f]+$": + '^lpc-ctrl@[0-9a-f]+$': type: object additionalProperties: false @@ -92,7 +92,7 @@ patternProperties: - compatible - clocks - "^reset-controller@[0-9a-f]+$": + '^reset-controller@[0-9a-f]+$': type: object additionalProperties: false @@ -118,7 +118,7 @@ patternProperties: - compatible - '#reset-cells' - "^lpc-snoop@[0-9a-f]+$": + '^lpc-snoop@[0-9a-f]+$': type: object additionalProperties: false @@ -152,15 +152,15 @@ patternProperties: - interrupts - snoop-ports - "^uart-routing@[0-9a-f]+$": + '^uart-routing@[0-9a-f]+$': $ref: /schemas/soc/aspeed/uart-routing.yaml# description: The UART routing control under LPC register space required: - compatible - reg - - "#address-cells" - - "#size-cells" + - '#address-cells' + - '#size-cells' - ranges additionalProperties: diff --git a/Documentation/devicetree/bindings/mfd/da9052-i2c.txt b/Documentation/devicetree/bindings/mfd/da9052-i2c.txt deleted file mode 100644 index 07c69c0c6624c..0000000000000 --- a/Documentation/devicetree/bindings/mfd/da9052-i2c.txt +++ /dev/null @@ -1,67 +0,0 @@ -* Dialog DA9052/53 Power Management Integrated Circuit (PMIC) - -Required properties: -- compatible : Should be "dlg,da9052", "dlg,da9053-aa", - "dlg,da9053-ab", or "dlg,da9053-bb" - -Optional properties: -- dlg,tsi-as-adc : Boolean, if set the X+, X-, Y+, Y- touchscreen - input lines are used as general purpose analogue - input. -- tsiref-supply: Phandle to the regulator, which provides the reference - voltage for the TSIREF pin. Must be provided when the - touchscreen pins are used for ADC purposes. - -Sub-nodes: -- regulators : Contain the regulator nodes. The DA9052/53 regulators are - bound using their names as listed below: - - buck1 : regulator BUCK CORE - buck2 : regulator BUCK PRO - buck3 : regulator BUCK MEM - buck4 : regulator BUCK PERI - ldo1 : regulator LDO1 - ldo2 : regulator LDO2 - ldo3 : regulator LDO3 - ldo4 : regulator LDO4 - ldo5 : regulator LDO5 - ldo6 : regulator LDO6 - ldo7 : regulator LDO7 - ldo8 : regulator LDO8 - ldo9 : regulator LDO9 - ldo10 : regulator LDO10 - - The bindings details of individual regulator device can be found in: - Documentation/devicetree/bindings/regulator/regulator.txt - -Examples: - -i2c@63fc8000 { /* I2C1 */ - - pmic: dialog@48 { - compatible = "dlg,da9053-aa"; - reg = <0x48>; - - regulators { - buck1 { - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <2075000>; - }; - - buck2 { - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <2075000>; - }; - - buck3 { - regulator-min-microvolt = <925000>; - regulator-max-microvolt = <2500000>; - }; - - buck4 { - regulator-min-microvolt = <925000>; - regulator-max-microvolt = <2500000>; - }; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/mfd/dlg,da9052.yaml b/Documentation/devicetree/bindings/mfd/dlg,da9052.yaml new file mode 100644 index 0000000000000..1103a8cc5cea4 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/dlg,da9052.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/dlg,da9052.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Dialog DA9052/53 Power Management Integrated Circuit (PMIC) + +maintainers: + - Frank Li + +properties: + compatible: + oneOf: + - enum: + - dlg,da9053-aa + - dlg,da9053-ab + - dlg,da9053-bb + - dlg,da9053-bc + - dlg,da9052 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + dlg,tsi-as-adc: + type: boolean + description: + if set the X+, X-, Y+, Y- touchscreen input lines are used as general + purpose analogue input. + + tsiref-supply: + description: The reference voltage for the TSIREF pin. + + regulators: + type: object + additionalProperties: false + + patternProperties: + "^(ldo([1-9]|10)|buck[1-4])$": + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + +required: + - compatible + - reg + - regulators + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@48 { + compatible = "dlg,da9053-aa"; + reg = <0x48>; + + regulators { + buck1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <2075000>; + }; + + buck2 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <2075000>; + }; + + buck3 { + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <2500000>; + }; + + buck4 { + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <2500000>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/dlg,da9063.yaml b/Documentation/devicetree/bindings/mfd/dlg,da9063.yaml index 51612dc22748f..4f08e9ac7e564 100644 --- a/Documentation/devicetree/bindings/mfd/dlg,da9063.yaml +++ b/Documentation/devicetree/bindings/mfd/dlg,da9063.yaml @@ -81,6 +81,8 @@ properties: watchdog: $ref: /schemas/watchdog/dlg,da9062-watchdog.yaml + wakeup-source: true + patternProperties: "^(.+-hog(-[0-9]+)?)$": type: object diff --git a/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml b/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml index d2886f2686a8d..cfa69f1f380ad 100644 --- a/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml +++ b/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml @@ -93,38 +93,14 @@ properties: leds: type: object - $ref: /schemas/leds/common.yaml# + additionalProperties: false properties: - reg: - description: | - One of - MC13783 LED IDs - 0: Main display - 1: AUX display - 2: Keypad - 3: Red 1 - 4: Green 1 - 5: Blue 1 - 6: Red 2 - 7: Green 2 - 8: Blue 2 - 9: Red 3 - 10: Green 3 - 11: Blue 3 - - MC13892 LED IDs - 0: Main display - 1: AUX display - 2: Keypad - 3: Red - 4: Green - 5: Blue - - MC34708 LED IDs - 0: Charger Red - 1: Charger Green - maxItems: 1 + '#address-cells': + const: 1 + + '#size-cells': + const: 0 led-control: $ref: /schemas/types.yaml#/definitions/uint32-array @@ -132,6 +108,42 @@ properties: Setting for LED-Control register array length depends on model, mc13783: 6, mc13892: 4, mc34708: 1 + patternProperties: + '^led@[0-9a-b]$': + $ref: /schemas/leds/common.yaml# + unevaluatedProperties: false + + properties: + reg: + description: | + One of + MC13783 LED IDs + 0: Main display + 1: AUX display + 2: Keypad + 3: Red 1 + 4: Green 1 + 5: Blue 1 + 6: Red 2 + 7: Green 2 + 8: Blue 2 + 9: Red 3 + 10: Green 3 + 11: Blue 3 + + MC13892 LED IDs + 0: Main display + 1: AUX display + 2: Keypad + 3: Red + 4: Green + 5: Blue + + MC34708 LED IDs + 0: Charger Red + 1: Charger Green + maxItems: 1 + regulators: type: object @@ -262,7 +274,7 @@ examples: #size-cells = <0>; led-control = <0x000 0x000 0x0e0 0x000>; - sysled@3 { + led@3 { reg = <3>; label = "system:red:live"; linux,default-trigger = "heartbeat"; diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77705.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77705.yaml index 0ec89f0adc64d..8b62aadb4213d 100644 --- a/Documentation/devicetree/bindings/mfd/maxim,max77705.yaml +++ b/Documentation/devicetree/bindings/mfd/maxim,max77705.yaml @@ -26,6 +26,18 @@ properties: interrupts: maxItems: 1 + interrupt-controller: + description: + The driver implements an interrupt controller for the sub devices. + The interrupt number mapping is as follows + 0 - charger + 1 - topsys + 2 - fuelgauge + 3 - usb type-c management block. + + '#interrupt-cells': + const: 1 + haptic: type: object additionalProperties: false @@ -118,8 +130,10 @@ examples: pmic@66 { compatible = "maxim,max77705"; reg = <0x66>; + #interrupt-cells = <1>; interrupt-parent = <&pm8998_gpios>; interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; pinctrl-0 = <&chg_int_default>; pinctrl-names = "default"; diff --git a/Documentation/devicetree/bindings/mfd/nxp,pf1550.yaml b/Documentation/devicetree/bindings/mfd/nxp,pf1550.yaml new file mode 100644 index 0000000000000..e50dc44252c60 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/nxp,pf1550.yaml @@ -0,0 +1,161 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/nxp,pf1550.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP PF1550 Power Management IC + +maintainers: + - Samuel Kayode + +description: + PF1550 PMIC provides battery charging and power supply for low power IoT and + wearable applications. This device consists of an i2c controlled MFD that + includes regulators, battery charging and an onkey/power button. + +$ref: /schemas/power/supply/power-supply.yaml + +properties: + compatible: + const: nxp,pf1550 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + wakeup-source: true + + regulators: + type: object + additionalProperties: false + + patternProperties: + "^(ldo[1-3]|sw[1-3]|vrefddr)$": + type: object + $ref: /schemas/regulator/regulator.yaml + description: + regulator configuration for ldo1-3, buck converters(sw1-3) + and DDR termination reference voltage (vrefddr) + unevaluatedProperties: false + + monitored-battery: + description: | + A phandle to a monitored battery node that contains a valid value + for: + constant-charge-voltage-max-microvolt. + + nxp,thermal-regulation-celsius: + description: + Temperature threshold for thermal regulation of charger in celsius. + enum: [ 80, 95, 110, 125 ] + + nxp,min-system-microvolt: + description: + System specific lower limit voltage. + enum: [ 3500000, 3700000, 4300000 ] + + nxp,disable-key-power: + type: boolean + description: + Disable power-down using a long key-press. The onkey driver will remove + support for the KEY_POWER key press when triggered using a long press of + the onkey. + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + #include + #include + + battery: battery-cell { + compatible = "simple-battery"; + constant-charge-voltage-max-microvolt = <4400000>; + }; + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@8 { + compatible = "nxp,pf1550"; + reg = <0x8>; + + interrupt-parent = <&gpio1>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + wakeup-source; + monitored-battery = <&battery>; + nxp,min-system-microvolt = <4300000>; + nxp,thermal-regulation-celsius = <80>; + + regulators { + sw1_reg: sw1 { + regulator-name = "sw1"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1387500>; + regulator-always-on; + regulator-ramp-delay = <6250>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-min-microvolt = <1270000>; + }; + }; + + sw2_reg: sw2 { + regulator-name = "sw2"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1387500>; + regulator-always-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + sw3_reg: sw3 { + regulator-name = "sw3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vldo1_reg: ldo1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vldo2_reg: ldo2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vldo3_reg: ldo3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index 078a6886f8b1e..65c80e3b45008 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -43,6 +43,7 @@ properties: - qcom,pm7250b - qcom,pm7550ba - qcom,pm7325 + - qcom,pm7550 - qcom,pm8004 - qcom,pm8005 - qcom,pm8009 @@ -84,6 +85,7 @@ properties: - qcom,pmi8994 - qcom,pmi8998 - qcom,pmih0108 + - qcom,pmiv0104 - qcom,pmk8002 - qcom,pmk8350 - qcom,pmk8550 diff --git a/Documentation/devicetree/bindings/mfd/renesas,r2a11302ft.yaml b/Documentation/devicetree/bindings/mfd/renesas,r2a11302ft.yaml new file mode 100644 index 0000000000000..7b96619ebd8cf --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/renesas,r2a11302ft.yaml @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/renesas,r2a11302ft.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas R2A11302FT Power Supply ICs for R-Car + +maintainers: + - Wolfram Sang + +description: | + The Renesas R2A11302FT PMIC is used with Renesas R-Car Gen1/Gen2 + based SoCs. + + FIXME: The binding is incomplete and resembles the information gathered + so far. + +properties: + compatible: + const: renesas,r2a11302ft + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 6000000 + + spi-cpol: true + + spi-cpha: true + +required: + - compatible + - reg + - spi-cpol + - spi-cpha + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + pmic@0 { + compatible = "renesas,r2a11302ft"; + reg = <0>; + spi-max-frequency = <6000000>; + spi-cpol; + spi-cpha; + }; + }; +... diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd96801-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd96801-pmic.yaml index 0e06570483ae9..adb491bcc8dcc 100644 --- a/Documentation/devicetree/bindings/mfd/rohm,bd96801-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/rohm,bd96801-pmic.yaml @@ -57,8 +57,7 @@ properties: - prstb - intb-only - timeout-sec: - maxItems: 2 + timeout-sec: true regulators: $ref: /schemas/regulator/rohm,bd96801-regulator.yaml @@ -72,7 +71,10 @@ required: - interrupt-names - regulators -additionalProperties: false +allOf: + - $ref: /schemas/watchdog/watchdog.yaml + +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml b/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml index ee0be32ac0204..4f829fe75d41d 100644 --- a/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml +++ b/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml @@ -32,6 +32,17 @@ properties: Specifying the power good GPIOs. maxItems: 1 + enable-gpios: + maxItems: 1 + + vcom-en-gpios: + maxItems: 1 + + vin-supply: + description: + Supply for the whole chip. Some vendor kernels and devicetrees + declare this as a non-existing GPIO named "pwrall". + regulators: type: object diff --git a/Documentation/devicetree/bindings/mfd/st,stmpe.yaml b/Documentation/devicetree/bindings/mfd/st,stmpe.yaml index b77cc3f3075d7..df43878fbe18f 100644 --- a/Documentation/devicetree/bindings/mfd/st,stmpe.yaml +++ b/Documentation/devicetree/bindings/mfd/st,stmpe.yaml @@ -12,7 +12,7 @@ description: STMicroelectronics Port Expander (STMPE) is a series of slow peripherals connected to SPI or I2C. maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# diff --git a/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml b/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml index b2cfa4120b8af..0fdfbfdfe88a3 100644 --- a/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml +++ b/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ST-Ericsson Analog Baseband AB8500 and AB8505 maintainers: - - Linus Walleij + - Linus Walleij description: the AB8500 "Analog Baseband" is the mixed-signals integrated circuit @@ -444,7 +444,6 @@ properties: additionalProperties: false - regulator-external: description: Node describing the AB8500 external regulators. This concerns the autonomous regulators VSMPS1, VSMPS2 and VSMPS3 diff --git a/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml b/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml index d6c13779d44e9..4edd4a3bab880 100644 --- a/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml +++ b/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ST-Ericsson DB8500 PRCMU - Power Reset and Control Management Unit maintainers: - - Linus Walleij + - Linus Walleij description: The DB8500 Power Reset and Control Management Unit is an XP70 8-bit diff --git a/Documentation/devicetree/bindings/mfd/syscon-common.yaml b/Documentation/devicetree/bindings/mfd/syscon-common.yaml index 451cbad467a3c..14a08e7bc8bdd 100644 --- a/Documentation/devicetree/bindings/mfd/syscon-common.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon-common.yaml @@ -35,9 +35,6 @@ properties: minItems: 2 maxItems: 5 # Should be enough - reg: - maxItems: 1 - reg-io-width: description: The size (in bytes) of the IO accesses that should be performed diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml index 657c38175fba2..55efb83b1495a 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml @@ -85,6 +85,7 @@ select: - mediatek,mt2701-pctl-a-syscfg - mediatek,mt2712-pctl-a-syscfg - mediatek,mt6397-pctl-pmic-syscfg + - mediatek,mt7981-topmisc - mediatek,mt7988-topmisc - mediatek,mt8135-pctl-a-syscfg - mediatek,mt8135-pctl-b-syscfg @@ -133,111 +134,126 @@ select: properties: compatible: - items: - - enum: - - airoha,en7581-pbus-csr - - al,alpine-sysfabric-service - - allwinner,sun8i-a83t-system-controller - - allwinner,sun8i-h3-system-controller - - allwinner,sun8i-v3s-system-controller - - allwinner,sun50i-a64-system-controller - - altr,l3regs - - altr,sdr-ctl - - amd,pensando-elba-syscon - - amlogic,meson-mx-assist - - amlogic,meson-mx-bootrom - - amlogic,meson8-analog-top - - amlogic,meson8b-analog-top - - amlogic,meson8-pmu - - amlogic,meson8b-pmu - - apm,merlin-poweroff-mailbox - - apm,mustang-poweroff-mailbox - - apm,xgene-csw - - apm,xgene-efuse - - apm,xgene-mcb - - apm,xgene-rb - - apm,xgene-scu - - atmel,sama5d2-sfrbu - - atmel,sama5d3-nfc-io - - atmel,sama5d3-sfrbu - - atmel,sama5d4-sfrbu - - axis,artpec6-syscon - - brcm,cru-clkset - - brcm,sr-cdru - - brcm,sr-mhb - - cirrus,ep7209-syscon1 - - cirrus,ep7209-syscon2 - - cirrus,ep7209-syscon3 - - cnxt,cx92755-uc - - freecom,fsg-cs2-system-controller - - fsl,imx93-aonmix-ns-syscfg - - fsl,imx93-wakeupmix-syscfg - - fsl,ls1088a-reset - - fsl,vf610-anatop - - fsl,vf610-mscm-cpucfg - - hisilicon,dsa-subctrl - - hisilicon,hi6220-sramctrl - - hisilicon,hip04-ppe - - hisilicon,pcie-sas-subctrl - - hisilicon,peri-subctrl - - hpe,gxp-sysreg - - loongson,ls1b-syscon - - loongson,ls1c-syscon - - lsi,axxia-syscon - - marvell,armada-3700-cpu-misc - - marvell,armada-3700-nb-pm - - marvell,armada-3700-avs - - marvell,armada-3700-usb2-host-device-misc - - marvell,armada-3700-usb2-host-misc - - marvell,dove-global-config - - mediatek,mt2701-pctl-a-syscfg - - mediatek,mt2712-pctl-a-syscfg - - mediatek,mt6397-pctl-pmic-syscfg - - mediatek,mt7988-topmisc - - mediatek,mt8135-pctl-a-syscfg - - mediatek,mt8135-pctl-b-syscfg - - mediatek,mt8173-pctl-a-syscfg - - mediatek,mt8365-infracfg-nao - - mediatek,mt8365-syscfg - - microchip,lan966x-cpu-syscon - - microchip,mpfs-control-scb - - microchip,mpfs-sysreg-scb - - microchip,sam9x60-sfr - - microchip,sama7d65-ddr3phy - - microchip,sama7d65-sfrbu - - microchip,sama7g5-ddr3phy - - mscc,ocelot-cpu-syscon - - mstar,msc313-pmsleep - - nuvoton,ma35d1-sys - - nuvoton,wpcm450-shm - - qcom,apq8064-mmss-sfpb - - qcom,apq8064-sps-sic - - rockchip,px30-qos - - rockchip,rk3036-qos - - rockchip,rk3066-qos - - rockchip,rk3128-qos - - rockchip,rk3228-qos - - rockchip,rk3288-qos - - rockchip,rk3368-qos - - rockchip,rk3399-qos - - rockchip,rk3528-qos - - rockchip,rk3562-qos - - rockchip,rk3568-qos - - rockchip,rk3576-qos - - rockchip,rk3588-qos - - rockchip,rv1126-qos - - st,spear1340-misc - - stericsson,nomadik-pmu - - starfive,jh7100-sysmain - - ti,am62-opp-efuse-table - - ti,am62-usb-phy-ctrl - - ti,am625-dss-oldi-io-ctrl - - ti,am62p-cpsw-mac-efuse - - ti,am654-dss-oldi-io-ctrl - - ti,j784s4-acspcie-proxy-ctrl - - ti,j784s4-pcie-ctrl - - ti,keystone-pllctrl - - const: syscon + oneOf: + - items: + - enum: + - airoha,en7581-pbus-csr + - al,alpine-sysfabric-service + - allwinner,sun8i-a83t-system-controller + - allwinner,sun8i-h3-system-controller + - allwinner,sun8i-v3s-system-controller + - allwinner,sun50i-a64-system-controller + - altr,l3regs + - altr,sdr-ctl + - amd,pensando-elba-syscon + - amlogic,meson-mx-assist + - amlogic,meson-mx-bootrom + - amlogic,meson8-analog-top + - amlogic,meson8b-analog-top + - amlogic,meson8-pmu + - amlogic,meson8b-pmu + - apm,merlin-poweroff-mailbox + - apm,mustang-poweroff-mailbox + - apm,xgene-csw + - apm,xgene-efuse + - apm,xgene-mcb + - apm,xgene-rb + - apm,xgene-scu + - atmel,sama5d2-sfrbu + - atmel,sama5d3-nfc-io + - atmel,sama5d3-sfrbu + - atmel,sama5d4-sfrbu + - axis,artpec6-syscon + - brcm,cru-clkset + - brcm,sr-cdru + - brcm,sr-mhb + - cirrus,ep7209-syscon1 + - cirrus,ep7209-syscon2 + - cirrus,ep7209-syscon3 + - cnxt,cx92755-uc + - freecom,fsg-cs2-system-controller + - fsl,imx93-aonmix-ns-syscfg + - fsl,imx93-wakeupmix-syscfg + - fsl,ls1088a-reset + - fsl,vf610-anatop + - fsl,vf610-mscm-cpucfg + - hisilicon,dsa-subctrl + - hisilicon,hi6220-sramctrl + - hisilicon,hip04-ppe + - hisilicon,pcie-sas-subctrl + - hisilicon,peri-subctrl + - hpe,gxp-sysreg + - loongson,ls1b-syscon + - loongson,ls1c-syscon + - lsi,axxia-syscon + - marvell,armada-3700-cpu-misc + - marvell,armada-3700-nb-pm + - marvell,armada-3700-avs + - marvell,armada-3700-usb2-host-device-misc + - marvell,armada-3700-usb2-host-misc + - marvell,dove-global-config + - mediatek,mt2701-pctl-a-syscfg + - mediatek,mt2712-pctl-a-syscfg + - mediatek,mt6397-pctl-pmic-syscfg + - mediatek,mt7988-topmisc + - mediatek,mt8135-pctl-a-syscfg + - mediatek,mt8135-pctl-b-syscfg + - mediatek,mt8173-pctl-a-syscfg + - mediatek,mt8365-infracfg-nao + - mediatek,mt8365-syscfg + - microchip,lan966x-cpu-syscon + - microchip,mpfs-control-scb + - microchip,mpfs-sysreg-scb + - microchip,sam9x60-sfr + - microchip,sama7d65-ddr3phy + - microchip,sama7d65-sfrbu + - microchip,sama7g5-ddr3phy + - mscc,ocelot-cpu-syscon + - mstar,msc313-pmsleep + - nuvoton,ma35d1-sys + - nuvoton,wpcm450-shm + - qcom,apq8064-mmss-sfpb + - qcom,apq8064-sps-sic + - rockchip,px30-qos + - rockchip,rk3036-qos + - rockchip,rk3066-qos + - rockchip,rk3128-qos + - rockchip,rk3228-qos + - rockchip,rk3288-qos + - rockchip,rk3368-qos + - rockchip,rk3399-qos + - rockchip,rk3528-qos + - rockchip,rk3562-qos + - rockchip,rk3568-qos + - rockchip,rk3576-qos + - rockchip,rk3588-qos + - rockchip,rv1126-qos + - st,spear1340-misc + - stericsson,nomadik-pmu + - starfive,jh7100-sysmain + - ti,am62-opp-efuse-table + - ti,am62-usb-phy-ctrl + - ti,am625-dss-oldi-io-ctrl + - ti,am62p-cpsw-mac-efuse + - ti,am654-dss-oldi-io-ctrl + - ti,j784s4-acspcie-proxy-ctrl + - ti,j784s4-pcie-ctrl + - ti,keystone-pllctrl + - const: syscon + - items: + - enum: + - microchip,sama7g5-sfrbu + - microchip,sama7d65-sfrbu + - const: atmel,sama5d2-sfrbu + - const: syscon + - items: + - const: microchip,pic64gx-control-scb + - const: microchip,mpfs-control-scb + - const: syscon + - items: + - const: microchip,pic64gx-sysreg-scb + - const: microchip,mpfs-sysreg-scb + - const: syscon reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml b/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml index a2668fc30a7bf..f1a76f88fc0cd 100644 --- a/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml +++ b/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml @@ -166,9 +166,6 @@ patternProperties: required: - compatible - reg - - interrupts - - interrupt-controller - - '#interrupt-cells' - gpio-controller - '#gpio-cells' - regulators diff --git a/Documentation/devicetree/bindings/mfd/ti,twl.yaml b/Documentation/devicetree/bindings/mfd/ti,twl.yaml index 776b04e182cb2..9cc3e4721612e 100644 --- a/Documentation/devicetree/bindings/mfd/ti,twl.yaml +++ b/Documentation/devicetree/bindings/mfd/ti,twl.yaml @@ -55,6 +55,15 @@ allOf: gpadc: false + pwrbutton: + properties: + compatible: + const: ti,twl4030-pwrbutton + interrupts: + items: + - items: + const: 8 + usb-comparator: false - if: @@ -95,7 +104,14 @@ allOf: compatible: const: ti,twl6030-gpadc - pwrbutton: false + pwrbutton: + properties: + compatible: + const: ti,twl6030-pwrbutton + interrupts: + items: + - items: + const: 0 madc: false @@ -146,7 +162,14 @@ allOf: compatible: const: ti,twl6032-gpadc - pwrbutton: false + pwrbutton: + properties: + compatible: + const: ti,twl6030-pwrbutton + interrupts: + items: + - items: + const: 0 madc: false @@ -226,11 +249,11 @@ properties: properties: compatible: - const: ti,twl4030-pwrbutton + enum: + - ti,twl4030-pwrbutton + - ti,twl6030-pwrbutton interrupts: - items: - - items: - const: 8 + maxItems: 1 watchdog: type: object @@ -400,7 +423,7 @@ properties: - '#pwm-cells' patternProperties: - "^regulator-": + '^regulator-': type: object unevaluatedProperties: false $ref: /schemas/regulator/regulator.yaml @@ -429,7 +452,7 @@ required: - reg - interrupts - interrupt-controller - - "#interrupt-cells" + - '#interrupt-cells' examples: - | @@ -459,6 +482,11 @@ examples: #io-channel-cells = <1>; }; + pwrbutton { + compatible = "ti,twl6030-pwrbutton"; + interrupts = <0>; + }; + rtc { compatible = "ti,twl4030-rtc"; interrupts = <8>; diff --git a/Documentation/devicetree/bindings/misc/intel,ixp4xx-ahb-queue-manager.yaml b/Documentation/devicetree/bindings/misc/intel,ixp4xx-ahb-queue-manager.yaml index aab89946b04fb..1198d87d0ab67 100644 --- a/Documentation/devicetree/bindings/misc/intel,ixp4xx-ahb-queue-manager.yaml +++ b/Documentation/devicetree/bindings/misc/intel,ixp4xx-ahb-queue-manager.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Intel IXP4xx AHB Queue Manager maintainers: - - Linus Walleij + - Linus Walleij description: | The IXP4xx AHB Queue Manager maintains queues as circular buffers in diff --git a/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml b/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml index 8f62e2c7fa641..f90fd73904a24 100644 --- a/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml +++ b/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM PrimeCell MultiMedia Card Interface (MMCI) PL180 and PL181 maintainers: - - Linus Walleij + - Linus Walleij - Ulf Hansson description: diff --git a/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml b/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml index 9fce8cd7b0b62..d24950ccea952 100644 --- a/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml @@ -41,7 +41,7 @@ properties: patternProperties: "^sdhci@[0-9a-f]+$": type: object - $ref: mmc-controller.yaml + $ref: sdhci-common.yaml unevaluatedProperties: false properties: diff --git a/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml b/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml index 493655a38b376..0936bfef8c75b 100644 --- a/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml +++ b/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml @@ -21,9 +21,11 @@ properties: - items: - enum: - brcm,bcm2712-sdhci + - brcm,bcm72116-sdhci - brcm,bcm74165b0-sdhci - brcm,bcm7445-sdhci - brcm,bcm7425-sdhci + - brcm,bcm74371-sdhci - const: brcm,sdhci-brcmstb reg: diff --git a/Documentation/devicetree/bindings/mmc/davinci_mmc.txt b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt deleted file mode 100644 index 516fb0143d4c2..0000000000000 --- a/Documentation/devicetree/bindings/mmc/davinci_mmc.txt +++ /dev/null @@ -1,32 +0,0 @@ -* TI Highspeed MMC host controller for DaVinci - -The Highspeed MMC Host Controller on TI DaVinci family -provides an interface for MMC, SD and SDIO types of memory cards. - -This file documents the properties used by the davinci_mmc driver. - -Required properties: -- compatible: - Should be "ti,da830-mmc": for da830, da850, dm365 - Should be "ti,dm355-mmc": for dm355, dm644x - -Optional properties: -- bus-width: Number of data lines, can be <1>, <4>, or <8>, default <1> -- max-frequency: Maximum operating clock frequency, default 25MHz. -- dmas: List of DMA specifiers with the controller specific format - as described in the generic DMA client binding. A tx and rx - specifier is required. -- dma-names: RX and TX DMA request names. These strings correspond - 1:1 with the DMA specifiers listed in dmas. - -Example: -mmc0: mmc@1c40000 { - compatible = "ti,da830-mmc", - reg = <0x40000 0x1000>; - interrupts = <16>; - bus-width = <4>; - max-frequency = <50000000>; - dmas = <&edma 16 - &edma 17>; - dma-names = "rx", "tx"; -}; diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml index bf273115235be..acb9fb9a92cd7 100644 --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml @@ -38,6 +38,7 @@ properties: - rockchip,rk3328-dw-mshc - rockchip,rk3368-dw-mshc - rockchip,rk3399-dw-mshc + - rockchip,rk3506-dw-mshc - rockchip,rk3528-dw-mshc - rockchip,rk3562-dw-mshc - rockchip,rk3568-dw-mshc diff --git a/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml b/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml index 676a746953893..242a3c6b925c5 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml +++ b/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml @@ -50,8 +50,7 @@ properties: - const: clk_ahb - const: clk_xin - dma-coherent: - type: boolean + dma-coherent: true # PHY output tap delays: # Used to delay the data valid window and align it to the sampling clock. diff --git a/Documentation/devicetree/bindings/mmc/sdhci-milbeaut.txt b/Documentation/devicetree/bindings/mmc/sdhci-milbeaut.txt deleted file mode 100644 index 627ee89c125b0..0000000000000 --- a/Documentation/devicetree/bindings/mmc/sdhci-milbeaut.txt +++ /dev/null @@ -1,30 +0,0 @@ -* SOCIONEXT Milbeaut SDHCI controller - -This file documents differences between the core properties in mmc.txt -and the properties used by the sdhci_milbeaut driver. - -Required properties: -- compatible: "socionext,milbeaut-m10v-sdhci-3.0" -- clocks: Must contain an entry for each entry in clock-names. It is a - list of phandles and clock-specifier pairs. - See ../clocks/clock-bindings.txt for details. -- clock-names: Should contain the following two entries: - "iface" - clock used for sdhci interface - "core" - core clock for sdhci controller - -Optional properties: -- fujitsu,cmd-dat-delay-select: boolean property indicating that this host - requires the CMD_DAT_DELAY control to be enabled. - -Example: - sdhci3: mmc@1b010000 { - compatible = "socionext,milbeaut-m10v-sdhci-3.0"; - reg = <0x1b010000 0x10000>; - interrupts = <0 265 0x4>; - voltage-ranges = <3300 3300>; - bus-width = <4>; - clocks = <&clk 7>, <&ahb_clk>; - clock-names = "core", "iface"; - cap-sdio-irq; - fujitsu,cmd-dat-delay-select; - }; diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml index 594bd174ff211..938be8228d668 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml @@ -42,6 +42,7 @@ properties: - qcom,ipq5424-sdhci - qcom,ipq6018-sdhci - qcom,ipq9574-sdhci + - qcom,kaanapali-sdhci - qcom,milos-sdhci - qcom,qcm2290-sdhci - qcom,qcs404-sdhci @@ -70,6 +71,7 @@ properties: - qcom,sm8450-sdhci - qcom,sm8550-sdhci - qcom,sm8650-sdhci + - qcom,sm8750-sdhci - qcom,x1e80100-sdhci - const: qcom,sdhci-msm-v5 # for sdcc version 5.0 diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt deleted file mode 100644 index f91e341e6b36c..0000000000000 --- a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt +++ /dev/null @@ -1,43 +0,0 @@ -* TI OMAP SDHCI Controller - -Refer to mmc.txt for standard MMC bindings. - -For UHS devices which require tuning, the device tree should have a "cpu_thermal" node which maps to the appropriate thermal zone. This is used to get the temperature of the zone during tuning. - -Required properties: -- compatible: Should be "ti,omap2430-sdhci" for omap2430 controllers - Should be "ti,omap3-sdhci" for omap3 controllers - Should be "ti,omap4-sdhci" for omap4 and ti81 controllers - Should be "ti,omap5-sdhci" for omap5 controllers - Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers - Should be "ti,k2g-sdhci" for K2G - Should be "ti,am335-sdhci" for am335x controllers - Should be "ti,am437-sdhci" for am437x controllers -- ti,hwmods: Must be "mmc", is controller instance starting 1 - (Not required for K2G). -- pinctrl-names: Should be subset of "default", "hs", "sdr12", "sdr25", "sdr50", - "ddr50-rev11", "sdr104-rev11", "ddr50", "sdr104", - "ddr_1_8v-rev11", "ddr_1_8v" or "ddr_3_3v", "hs200_1_8v-rev11", - "hs200_1_8v", -- pinctrl- : Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt - -Optional properties: -- dmas: List of DMA specifiers with the controller specific format as described - in the generic DMA client binding. A tx and rx specifier is required. -- dma-names: List of DMA request names. These strings correspond 1:1 with the - DMA specifiers listed in dmas. The string naming is to be "tx" - and "rx" for TX and RX DMA requests, respectively. - -Deprecated properties: -- ti,non-removable: Compatible with the generic non-removable property - -Example: - mmc1: mmc@4809c000 { - compatible = "ti,dra7-sdhci"; - reg = <0x4809c000 0x400>; - ti,hwmods = "mmc1"; - bus-width = <4>; - vmmc-supply = <&vmmc>; /* phandle to regulator node */ - dmas = <&sdma 61 &sdma 62>; - dma-names = "tx", "rx"; - }; diff --git a/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml b/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml index f882219a0a26a..7e7c55dc24403 100644 --- a/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml @@ -30,6 +30,7 @@ properties: - sophgo,sg2002-dwcmshc - sophgo,sg2042-dwcmshc - thead,th1520-dwcmshc + - eswin,eic7700-dwcmshc reg: maxItems: 1 @@ -52,17 +53,30 @@ properties: maxItems: 5 reset-names: - items: - - const: core - - const: bus - - const: axi - - const: block - - const: timer + maxItems: 5 rockchip,txclk-tapnum: description: Specify the number of delay for tx sampling. $ref: /schemas/types.yaml#/definitions/uint8 + eswin,hsp-sp-csr: + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: Phandle to HSP(High-Speed Peripheral) device + - description: Offset of the stability status register for internal + clock. + - description: Offset of the stability register for host regulator + voltage. + description: + HSP CSR is to control and get status of different high-speed peripherals + (such as Ethernet, USB, SATA, etc.) via register, which can tune + board-level's parameters of PHY, etc. + + eswin,drive-impedance-ohms: + description: Specifies the drive impedance in Ohm. + enum: [33, 40, 50, 66, 100] + required: - compatible - reg @@ -110,6 +124,37 @@ allOf: - const: block - const: timer + - if: + properties: + compatible: + contains: + const: eswin,eic7700-dwcmshc + then: + properties: + resets: + minItems: 4 + maxItems: 4 + reset-names: + items: + - const: axi + - const: phy + - const: prstn + - const: txrx + required: + - eswin,hsp-sp-csr + - eswin,drive-impedance-ohms + else: + properties: + resets: + maxItems: 5 + reset-names: + items: + - const: core + - const: bus + - const: axi + - const: block + - const: timer + - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/mmc/socionext,milbeaut-m10v-sdhci-3.0.yaml b/Documentation/devicetree/bindings/mmc/socionext,milbeaut-m10v-sdhci-3.0.yaml new file mode 100644 index 0000000000000..2ba53626a9598 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/socionext,milbeaut-m10v-sdhci-3.0.yaml @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mmc/socionext,milbeaut-m10v-sdhci-3.0.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SOCIONEXT Milbeaut SDHCI controller + +maintainers: + - Taichi Sugaya + - Takao Orito + +description: + The SOCIONEXT Milbeaut SDHCI controller is a specialized SD Host + Controller found in some of Socionext's Milbeaut image processing SoCs. + It features a dedicated "bridge controller." This bridge controller + implements special functions like reset control, clock management for + various SDR modes (SDR12, SDR25, SDR50) and physical pin property settings. + +allOf: + - $ref: sdhci-common.yaml# + +properties: + compatible: + const: socionext,milbeaut-m10v-sdhci-3.0 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: core + - const: iface + + fujitsu,cmd-dat-delay-select: + description: + Its presence indicates that the controller requires a specific command + and data line delay selection mechanism for proper operation, particularly + when dealing with high-speed SD/eMMC modes. + type: boolean + + voltage-ranges: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + items: + items: + - description: minimum slot voltage (mV). + - description: maximum slot voltage (mV). + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +unevaluatedProperties: false + +examples: + - | + #include + mmc@1b010000 { + compatible = "socionext,milbeaut-m10v-sdhci-3.0"; + reg = <0x1b010000 0x10000>; + interrupts = ; + voltage-ranges = <3300 3300>; + bus-width = <4>; + clocks = <&clk 7>, <&ahb_clk>; + clock-names = "core", "iface"; + cap-sdio-irq; + fujitsu,cmd-dat-delay-select; + }; +... diff --git a/Documentation/devicetree/bindings/mmc/ti,da830-mmc.yaml b/Documentation/devicetree/bindings/mmc/ti,da830-mmc.yaml new file mode 100644 index 0000000000000..36b33dde086b9 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/ti,da830-mmc.yaml @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mmc/ti,da830-mmc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI Highspeed MMC host controller for DaVinci + +description: + The Highspeed MMC Host Controller on TI DaVinci family + provides an interface for MMC, SD and SDIO types of memory cards. + +allOf: + - $ref: mmc-controller.yaml + +maintainers: + - Kishon Vijay Abraham I + +properties: + compatible: + enum: + - ti,da830-mmc + - ti,dm355-mmc + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + interrupts: + maxItems: 2 + + dmas: + maxItems: 2 + + dma-names: + items: + - const: rx + - const: tx + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + mmc@1c40000 { + compatible = "ti,da830-mmc"; + reg = <0x40000 0x1000>; + interrupts = <16 IRQ_TYPE_LEVEL_HIGH>, + <17 IRQ_TYPE_LEVEL_HIGH>; + bus-width = <4>; + max-frequency = <50000000>; + dmas = <&edma 16>, <&edma 17>; + dma-names = "rx", "tx"; + }; +... diff --git a/Documentation/devicetree/bindings/mmc/ti,omap2430-sdhci.yaml b/Documentation/devicetree/bindings/mmc/ti,omap2430-sdhci.yaml new file mode 100644 index 0000000000000..34e288f3ef135 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/ti,omap2430-sdhci.yaml @@ -0,0 +1,169 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mmc/ti,omap2430-sdhci.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI OMAP SDHCI Controller + +maintainers: + - Kishon Vijay Abraham I + +description: + For UHS devices which require tuning, the device tree should have a + cpu_thermal node which maps to the appropriate thermal zone. This + is used to get the temperature of the zone during tuning. + +properties: + compatible: + enum: + - ti,omap2430-sdhci + - ti,omap3-sdhci + - ti,omap4-sdhci + - ti,omap5-sdhci + - ti,dra7-sdhci + - ti,k2g-sdhci + - ti,am335-sdhci + - ti,am437-sdhci + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: fck + - const: mmchsdb_fck + + dmas: + maxItems: 2 + + dma-names: + items: + - const: tx + - const: rx + + pinctrl-names: + minItems: 1 + maxItems: 14 + items: + enum: + - default + - default-rev11 + - hs + - sdr12 + - sdr12-rev11 + - sdr25 + - sdr25-rev11 + - sdr50 + - ddr50-rev11 + - sdr104-rev11 + - ddr50 + - sdr104 + - ddr_1_8v-rev11 + - ddr_1_8v + - ddr_3_3v + - hs-rev11 + - hs200_1_8v-rev11 + - hs200_1_8v + - sleep + + pinctrl-0: + maxItems: 1 + + pinctrl-1: + maxItems: 1 + + pinctrl-2: + maxItems: 1 + + pinctrl-3: + maxItems: 1 + + pinctrl-4: + maxItems: 1 + + pinctrl-5: + maxItems: 1 + + pinctrl-6: + maxItems: 1 + + pinctrl-7: + maxItems: 1 + + pinctrl-8: + maxItems: 1 + + power-domains: + maxItems: 1 + + pbias-supply: + description: + It is used to specify the voltage regulator that provides the bias + voltage for certain analog or I/O pads. + + ti,non-removable: + description: + It indicates that a component is not meant to be easily removed or + replaced by the user, such as an embedded battery or a non-removable + storage slot like eMMC. + type: boolean + deprecated: true + + clock-frequency: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + It represents the speed at which a clock signal associated with a device + or bus operates, measured in Hertz (Hz). This value is crucial for configuring + hardware components that require a specific clock speed. + +required: + - compatible + - reg + - interrupts + +allOf: + - $ref: sdhci-common.yaml# + - if: + properties: + compatible: + contains: + enum: + - ti,dra7-sdhci + - ti,k2g-sdhci + then: + required: + - max-frequency + - if: + properties: + compatible: + contains: + const: ti,k2g-sdhci + then: + required: + - clocks + - clock-names + +unevaluatedProperties: false + +examples: + - | + #include + mmc@4809c000 { + compatible = "ti,dra7-sdhci"; + reg = <0x4809c000 0x400>; + interrupts = ; + max-frequency = <192000000>; + sdhci-caps-mask = <0x0 0x400000>; + bus-width = <4>; + vmmc-supply = <&vmmc>; /* phandle to regulator node */ + dmas = <&sdma 61>, <&sdma 62>; + dma-names = "tx", "rx"; + }; +... diff --git a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml index 054b6b8bf9b91..9d061e2216cbc 100644 --- a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml +++ b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml @@ -6,9 +6,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Allwinner A10 NAND Controller -allOf: - - $ref: nand-controller.yaml - maintainers: - Chen-Yu Tsai - Maxime Ripard @@ -18,6 +15,8 @@ properties: enum: - allwinner,sun4i-a10-nand - allwinner,sun8i-a23-nand-controller + - allwinner,sun50i-h616-nand-controller + reg: maxItems: 1 @@ -25,14 +24,20 @@ properties: maxItems: 1 clocks: + minItems: 2 items: - description: Bus Clock - description: Module Clock + - description: ECC Clock + - description: MBus Clock clock-names: + minItems: 2 items: - const: ahb - const: mod + - const: ecc + - const: mbus resets: maxItems: 1 @@ -85,6 +90,36 @@ required: unevaluatedProperties: false +allOf: + - $ref: nand-controller.yaml + + - if: + properties: + compatible: + contains: + enum: + - allwinner,sun4i-a10-nand + - allwinner,sun8i-a23-nand-controller + then: + properties: + clocks: + maxItems: 2 + clock-names: + maxItems: 2 + + - if: + properties: + compatible: + contains: + enum: + - allwinner,sun50i-h616-nand-controller + then: + properties: + clocks: + minItems: 4 + clock-names: + minItems: 4 + examples: - | #include diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml index 284f0f882c32d..fa2aa29be794d 100644 --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml @@ -88,7 +88,6 @@ patternProperties: amlogic,boot-pages: [nand-is-boot-medium, "amlogic,boot-page-step"] amlogic,boot-page-step: [nand-is-boot-medium, "amlogic,boot-pages"] - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/mtd/cdns,hp-nfc.yaml b/Documentation/devicetree/bindings/mtd/cdns,hp-nfc.yaml index e1f4d7c35a885..73dc69cee4d8f 100644 --- a/Documentation/devicetree/bindings/mtd/cdns,hp-nfc.yaml +++ b/Documentation/devicetree/bindings/mtd/cdns,hp-nfc.yaml @@ -40,6 +40,9 @@ properties: dmas: maxItems: 1 + iommus: + maxItems: 1 + cdns,board-delay-ps: description: | Estimated Board delay. The value includes the total round trip diff --git a/Documentation/devicetree/bindings/mtd/marvell,nand-controller.yaml b/Documentation/devicetree/bindings/mtd/marvell,nand-controller.yaml index 1ecea848e8b90..bc89cbf8193a3 100644 --- a/Documentation/devicetree/bindings/mtd/marvell,nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/marvell,nand-controller.yaml @@ -145,7 +145,6 @@ allOf: clock-names: minItems: 1 - unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml index 1b375dee83b0c..a9ec3ca002c7d 100644 --- a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml +++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml @@ -69,6 +69,16 @@ properties: minItems: 1 maxItems: 8 + clocks: + description: | + Chips may need clocks to be enabled for themselves or for transparent + bridges. + + power-domains: + description: | + Chips may need power domains to be enabled for themselves or for + transparent bridges. + bank-width: description: Width (in bytes) of the bank. Equal to the device width times the number of interleaved chips. diff --git a/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.yaml b/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.yaml index 97618847ee354..e9b1a6869910c 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM Firmware Suite (AFS) Partitions maintainers: - - Linus Walleij + - Linus Walleij select: false diff --git a/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml b/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml index ba7445cd69e8f..e3978d2bc056f 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml @@ -14,7 +14,7 @@ description: The FLASH Image System (FIS) directory is a flash description 32 KB in size. maintainers: - - Linus Walleij + - Linus Walleij select: false diff --git a/Documentation/devicetree/bindings/mtd/partitions/seama.yaml b/Documentation/devicetree/bindings/mtd/partitions/seama.yaml index 4c1cbf43e81a6..4af185204b4b9 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/seama.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/seama.yaml @@ -18,7 +18,7 @@ allOf: - $ref: partition.yaml# maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/mux/mux-controller.yaml b/Documentation/devicetree/bindings/mux/mux-controller.yaml index 571ad9e13ecfb..78340bbe4df62 100644 --- a/Documentation/devicetree/bindings/mux/mux-controller.yaml +++ b/Documentation/devicetree/bindings/mux/mux-controller.yaml @@ -20,7 +20,6 @@ description: | space is a simple zero-based enumeration. I.e. 0-1 for a 2-way multiplexer, 0-7 for an 8-way multiplexer, etc. - Mux controller nodes -------------------- diff --git a/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml index fc62fb2a68ac0..323a669fa9823 100644 --- a/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml +++ b/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml @@ -201,7 +201,6 @@ allOf: - clocks - resets - mdio@2: $ref: mdio.yaml# unevaluatedProperties: false @@ -251,7 +250,6 @@ allOf: maxItems: 1 power-domains: false - unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/net/bluetooth/brcm,bluetooth.yaml b/Documentation/devicetree/bindings/net/bluetooth/brcm,bluetooth.yaml index 3c410cadff230..95501e858e6f8 100644 --- a/Documentation/devicetree/bindings/net/bluetooth/brcm,bluetooth.yaml +++ b/Documentation/devicetree/bindings/net/bluetooth/brcm,bluetooth.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Broadcom Bluetooth Chips maintainers: - - Linus Walleij + - Linus Walleij description: This binding describes Broadcom UART-attached bluetooth chips. diff --git a/Documentation/devicetree/bindings/net/brcm,bcmgenet.yaml b/Documentation/devicetree/bindings/net/brcm,bcmgenet.yaml index 0e3fb4e42e3fb..a1119c47e29b0 100644 --- a/Documentation/devicetree/bindings/net/brcm,bcmgenet.yaml +++ b/Documentation/devicetree/bindings/net/brcm,bcmgenet.yaml @@ -31,7 +31,6 @@ properties: - description: RX and TX rings interrupt line - description: Wake-on-LAN interrupt line - clocks: minItems: 1 items: diff --git a/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.yaml b/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.yaml index 3f27746d9a563..d544f785e6b97 100644 --- a/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.yaml +++ b/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.yaml @@ -29,7 +29,6 @@ properties: maxItems: 1 description: core clock driving the MDIO block - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml index 44fd23a5fa2b3..f0b5bea2458d5 100644 --- a/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml +++ b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Cortina Systems Gemini Ethernet Controller maintainers: - - Linus Walleij + - Linus Walleij description: | This ethernet controller is found in the Gemini SoC family: @@ -100,7 +100,6 @@ examples: }; }; - ethernet@60000000 { compatible = "cortina,gemini-ethernet"; reg = <0x60000000 0x4000>, /* Global registers, queue */ diff --git a/Documentation/devicetree/bindings/net/dsa/micrel,ks8995.yaml b/Documentation/devicetree/bindings/net/dsa/micrel,ks8995.yaml index 854808ff5ad5d..e9ce360670331 100644 --- a/Documentation/devicetree/bindings/net/dsa/micrel,ks8995.yaml +++ b/Documentation/devicetree/bindings/net/dsa/micrel,ks8995.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Micrel KS8995 Family DSA Switches maintainers: - - Linus Walleij + - Linus Walleij description: The Micrel KS8995 DSA Switches are 100 Mbit switches that were produced in diff --git a/Documentation/devicetree/bindings/net/dsa/realtek.yaml b/Documentation/devicetree/bindings/net/dsa/realtek.yaml index f348e66fb5158..473facd87a622 100644 --- a/Documentation/devicetree/bindings/net/dsa/realtek.yaml +++ b/Documentation/devicetree/bindings/net/dsa/realtek.yaml @@ -10,7 +10,7 @@ allOf: - $ref: dsa.yaml#/$defs/ethernet-ports maintainers: - - Linus Walleij + - Linus Walleij description: Realtek advertises these chips as fast/gigabit switches or unmanaged diff --git a/Documentation/devicetree/bindings/net/dsa/vitesse,vsc73xx.yaml b/Documentation/devicetree/bindings/net/dsa/vitesse,vsc73xx.yaml index 51cf574249bec..c41f479bdee94 100644 --- a/Documentation/devicetree/bindings/net/dsa/vitesse,vsc73xx.yaml +++ b/Documentation/devicetree/bindings/net/dsa/vitesse,vsc73xx.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Vitesse VSC73xx DSA Switches maintainers: - - Linus Walleij + - Linus Walleij description: The Vitesse DSA Switches were produced in the early-to-mid 2000s. diff --git a/Documentation/devicetree/bindings/net/ethernet-switch.yaml b/Documentation/devicetree/bindings/net/ethernet-switch.yaml index b3b7e1a1b1278..6bb68f7dbc7f7 100644 --- a/Documentation/devicetree/bindings/net/ethernet-switch.yaml +++ b/Documentation/devicetree/bindings/net/ethernet-switch.yaml @@ -35,14 +35,14 @@ allOf: then: properties: $nodename: - pattern: "switch[0-3]@[0-3]+$" + pattern: 'switch[0-3]@[0-3]+$' else: properties: $nodename: - pattern: "^(ethernet-)?switch(@.*)?$" + pattern: '^(ethernet-)?switch(@.*)?$' patternProperties: - "^(ethernet-)?ports$": + '^(ethernet-)?ports$': type: object unevaluatedProperties: false @@ -53,13 +53,13 @@ patternProperties: const: 0 patternProperties: - "^(ethernet-)?port@[0-9a-f]+$": + '^(ethernet-)?port@[0-9a-f]+$': type: object description: Ethernet switch ports required: - - "#address-cells" - - "#size-cells" + - '#address-cells' + - '#size-cells' oneOf: - required: @@ -75,9 +75,9 @@ $defs: $ref: '#' patternProperties: - "^(ethernet-)?ports$": + '^(ethernet-)?ports$': patternProperties: - "^(ethernet-)?port@[0-9a-f]+$": + '^(ethernet-)?port@[0-9a-f]+$': description: Ethernet switch ports $ref: ethernet-switch-port.yaml# unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/net/fsl,gianfar.yaml b/Documentation/devicetree/bindings/net/fsl,gianfar.yaml index f92f284aa05b0..0d8909770ccbf 100644 --- a/Documentation/devicetree/bindings/net/fsl,gianfar.yaml +++ b/Documentation/devicetree/bindings/net/fsl,gianfar.yaml @@ -167,8 +167,6 @@ allOf: - description: Receive interrupt - description: Error interrupt - - unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/net/intel,ixp46x-ptp-timer.yaml b/Documentation/devicetree/bindings/net/intel,ixp46x-ptp-timer.yaml index f92730b1d2fad..80336b7e64ecc 100644 --- a/Documentation/devicetree/bindings/net/intel,ixp46x-ptp-timer.yaml +++ b/Documentation/devicetree/bindings/net/intel,ixp46x-ptp-timer.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Intel IXP46x PTP Timer (TSYNC) maintainers: - - Linus Walleij + - Linus Walleij description: | The Intel IXP46x PTP timer is known in the manual as IEEE1588 Hardware diff --git a/Documentation/devicetree/bindings/net/intel,ixp4xx-ethernet.yaml b/Documentation/devicetree/bindings/net/intel,ixp4xx-ethernet.yaml index 8689de1aaea15..3b8f83b7099d3 100644 --- a/Documentation/devicetree/bindings/net/intel,ixp4xx-ethernet.yaml +++ b/Documentation/devicetree/bindings/net/intel,ixp4xx-ethernet.yaml @@ -11,7 +11,7 @@ allOf: - $ref: ethernet-controller.yaml# maintainers: - - Linus Walleij + - Linus Walleij description: | The Intel IXP4xx ethernet makes use of the IXP4xx NPE (Network diff --git a/Documentation/devicetree/bindings/net/intel,ixp4xx-hss.yaml b/Documentation/devicetree/bindings/net/intel,ixp4xx-hss.yaml index 7a405e9b37b2c..1d952735c81b6 100644 --- a/Documentation/devicetree/bindings/net/intel,ixp4xx-hss.yaml +++ b/Documentation/devicetree/bindings/net/intel,ixp4xx-hss.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Intel IXP4xx V.35 WAN High Speed Serial Link (HSS) maintainers: - - Linus Walleij + - Linus Walleij description: | The Intel IXP4xx HSS makes use of the IXP4xx NPE (Network diff --git a/Documentation/devicetree/bindings/net/mdio-mux-multiplexer.yaml b/Documentation/devicetree/bindings/net/mdio-mux-multiplexer.yaml index 282987074ee4f..23947ba6aeaf1 100644 --- a/Documentation/devicetree/bindings/net/mdio-mux-multiplexer.yaml +++ b/Documentation/devicetree/bindings/net/mdio-mux-multiplexer.yaml @@ -14,7 +14,6 @@ description: |+ of a mux producer device. The mux producer can be of any type like mmio mux producer, gpio mux producer or generic register based mux producer. - allOf: - $ref: /schemas/net/mdio-mux.yaml# diff --git a/Documentation/devicetree/bindings/net/qcom,ipa.yaml b/Documentation/devicetree/bindings/net/qcom,ipa.yaml index b4a79912d4739..c7f5f2ef74521 100644 --- a/Documentation/devicetree/bindings/net/qcom,ipa.yaml +++ b/Documentation/devicetree/bindings/net/qcom,ipa.yaml @@ -24,7 +24,6 @@ description: iommu/iommu.txt and iommu/arm,smmu.yaml for more information about SMMU bindings. - - | -------- --------- | | | | diff --git a/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml b/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml index d14ca81f70e08..8b5da602a2e8d 100644 --- a/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml +++ b/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml @@ -156,7 +156,6 @@ patternProperties: CPSW MDIO bus. $ref: ti,davinci-mdio.yaml# - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore.yaml b/Documentation/devicetree/bindings/net/wireless/ti,wlcore.yaml index 75c9489f319b2..9de5fdefcbcc3 100644 --- a/Documentation/devicetree/bindings/net/wireless/ti,wlcore.yaml +++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore.yaml @@ -50,7 +50,6 @@ properties: Points to the node of the regulator that powers/enable the wl12xx/wl18xx chip. This is required when connected via SPI. - ref-clock-frequency: $ref: /schemas/types.yaml#/definitions/uint32 description: Reference clock frequency. diff --git a/Documentation/devicetree/bindings/npu/arm,ethos.yaml b/Documentation/devicetree/bindings/npu/arm,ethos.yaml new file mode 100644 index 0000000000000..716c4997f9765 --- /dev/null +++ b/Documentation/devicetree/bindings/npu/arm,ethos.yaml @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/npu/arm,ethos.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arm Ethos U65/U85 + +maintainers: + - Rob Herring + +description: > + The Arm Ethos-U NPUs are designed for IoT inference applications. The NPUs + can accelerate 8-bit and 16-bit integer quantized networks: + + Transformer networks (U85 only) + Convolutional Neural Networks (CNN) + Recurrent Neural Networks (RNN) + + Further documentation is available here: + + U65 TRM: https://developer.arm.com/documentation/102023/ + U85 TRM: https://developer.arm.com/documentation/102685/ + +properties: + compatible: + oneOf: + - items: + - enum: + - fsl,imx93-npu + - const: arm,ethos-u65 + - items: + - {} + - const: arm,ethos-u85 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: core + - const: apb + + power-domains: + maxItems: 1 + + sram: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + #include + #include + #include + + npu@4a900000 { + compatible = "fsl,imx93-npu", "arm,ethos-u65"; + reg = <0x4a900000 0x1000>; + interrupts = ; + power-domains = <&mlmix>; + clocks = <&clk IMX93_CLK_ML>, <&clk IMX93_CLK_ML_APB>; + clock-names = "core", "apb"; + sram = <&sram>; + }; +... diff --git a/Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt b/Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt deleted file mode 100644 index 0415265c215a6..0000000000000 --- a/Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt +++ /dev/null @@ -1,17 +0,0 @@ -Broadcom OTP memory controller - -Required Properties: -- compatible: "brcm,ocotp" for the first generation Broadcom OTPC which is used - in Cygnus and supports 32 bit read/write. Use "brcm,ocotp-v2" for the second - generation Broadcom OTPC which is used in SoC's such as Stingray and supports - 64-bit read/write. -- reg: Base address of the OTP controller. -- brcm,ocotp-size: Amount of memory available, in 32 bit words - -Example: - -otp: otp@301c800 { - compatible = "brcm,ocotp"; - reg = <0x0301c800 0x2c>; - brcm,ocotp-size = <2048>; -}; diff --git a/Documentation/devicetree/bindings/nvmem/brcm,ocotp.yaml b/Documentation/devicetree/bindings/nvmem/brcm,ocotp.yaml new file mode 100644 index 0000000000000..ffad284174885 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/brcm,ocotp.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/brcm,ocotp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom OTP memory controller + +maintainers: + - Ray Jui + - Scott Branden + +properties: + compatible: + enum: + - brcm,ocotp + - brcm,ocotp-v2 + + reg: + maxItems: 1 + + brcm,ocotp-size: + description: Amount of memory available, in 32-bit words + $ref: /schemas/types.yaml#/definitions/uint32 + +required: + - compatible + - reg + - brcm,ocotp-size + +additionalProperties: false + +examples: + - | + otp@301c800 { + compatible = "brcm,ocotp"; + reg = <0x0301c800 0x2c>; + brcm,ocotp-size = <2048>; + }; diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml index b2cb76cf9053a..a8076d0e2737c 100644 --- a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml +++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml @@ -14,7 +14,8 @@ maintainers: description: | This binding represents the on-chip eFuse OTP controller found on i.MX6Q/D, i.MX6DL/S, i.MX6SL, i.MX6SX, i.MX6UL, i.MX6ULL/ULZ, i.MX6SLL, - i.MX7D/S, i.MX7ULP, i.MX8MQ, i.MX8MM, i.MX8MN i.MX8MP and i.MX93/5 SoCs. + i.MX7D/S, i.MX7ULP, i.MX8MQ, i.MX8MM, i.MX8MN i.MX8MP, i.MX93, i.MX94, + and i.MX95. allOf: - $ref: nvmem.yaml# @@ -36,6 +37,7 @@ properties: - fsl,imx8mq-ocotp - fsl,imx8mm-ocotp - fsl,imx93-ocotp + - fsl,imx94-ocotp - fsl,imx95-ocotp - const: syscon - items: diff --git a/Documentation/devicetree/bindings/nvmem/layouts/u-boot,env.yaml b/Documentation/devicetree/bindings/nvmem/layouts/u-boot,env.yaml index 56a8f55d4a096..e9e75c38bd119 100644 --- a/Documentation/devicetree/bindings/nvmem/layouts/u-boot,env.yaml +++ b/Documentation/devicetree/bindings/nvmem/layouts/u-boot,env.yaml @@ -46,6 +46,12 @@ properties: type: object description: Command to use for automatic booting + env-size: + description: + Size in bytes of the environment data used by U-Boot for CRC + calculation. If omitted, the full NVMEM region size is used. + $ref: /schemas/types.yaml#/definitions/uint32 + ethaddr: type: object description: Ethernet interfaces base MAC address. @@ -104,6 +110,7 @@ examples: partition-u-boot-env { compatible = "brcm,env"; + env-size = <0x20000>; ethaddr { }; diff --git a/Documentation/devicetree/bindings/nvmem/mediatek,efuse.yaml b/Documentation/devicetree/bindings/nvmem/mediatek,efuse.yaml index 4dc0d42df3e6c..c9bf34ee0efb6 100644 --- a/Documentation/devicetree/bindings/nvmem/mediatek,efuse.yaml +++ b/Documentation/devicetree/bindings/nvmem/mediatek,efuse.yaml @@ -25,7 +25,9 @@ properties: compatible: oneOf: - items: - - const: mediatek,mt8188-efuse + - enum: + - mediatek,mt8188-efuse + - mediatek,mt8189-efuse - const: mediatek,mt8186-efuse - const: mediatek,mt8186-efuse @@ -48,6 +50,7 @@ properties: - mediatek,mt7988-efuse - mediatek,mt8173-efuse - mediatek,mt8183-efuse + - mediatek,mt8189-efuse - mediatek,mt8192-efuse - mediatek,mt8195-efuse - mediatek,mt8516-efuse diff --git a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml index 3f6dc6a3a9f1a..7d1612acca48d 100644 --- a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml +++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml @@ -39,6 +39,7 @@ properties: - qcom,qcs404-qfprom - qcom,qcs615-qfprom - qcom,qcs8300-qfprom + - qcom,sa8775p-qfprom - qcom,sar2130p-qfprom - qcom,sc7180-qfprom - qcom,sc7280-qfprom diff --git a/Documentation/devicetree/bindings/nvmem/st,stm32-romem.yaml b/Documentation/devicetree/bindings/nvmem/st,stm32-romem.yaml index 3b2aa605a5515..ab4cdc4e36148 100644 --- a/Documentation/devicetree/bindings/nvmem/st,stm32-romem.yaml +++ b/Documentation/devicetree/bindings/nvmem/st,stm32-romem.yaml @@ -31,7 +31,7 @@ properties: maxItems: 1 patternProperties: - "^.*@[0-9a-f]+$": + "@[0-9a-f]+$": type: object $ref: layouts/fixed-cell.yaml unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml b/Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml index 5d3f48a001b71..f516db47ab20f 100644 --- a/Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml +++ b/Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml @@ -93,7 +93,6 @@ allOf: reg-names: minItems: 3 - unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml index 79a21ba0f9fd6..d67cb7a850a37 100644 --- a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml @@ -20,9 +20,10 @@ allOf: select: properties: compatible: - enum: - - amlogic,axg-pcie - - amlogic,g12a-pcie + contains: + enum: + - amlogic,axg-pcie + - amlogic,g12a-pcie required: - compatible @@ -36,13 +37,13 @@ properties: reg: items: - - description: External local bus interface registers + - description: Data Bus Interface registers - description: Meson designed configuration registers - description: PCIe configuration space reg-names: items: - - const: elbi + - const: dbi - const: cfg - const: config @@ -51,15 +52,15 @@ properties: clocks: items: + - description: PCIe PHY clock - description: PCIe GEN 100M PLL clock - description: PCIe RC clock gate - - description: PCIe PHY clock clock-names: items: + - const: general - const: pclk - const: port - - const: general phys: maxItems: 1 @@ -88,7 +89,7 @@ required: - reg - reg-names - interrupts - - clock + - clocks - clock-names - "#address-cells" - "#size-cells" @@ -113,10 +114,10 @@ examples: pcie: pcie@f9800000 { compatible = "amlogic,axg-pcie", "snps,dw-pcie"; reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>; - reg-names = "elbi", "cfg", "config"; + reg-names = "dbi", "cfg", "config"; interrupts = ; - clocks = <&pclk>, <&clk_port>, <&clk_phy>; - clock-names = "pclk", "port", "general"; + clocks = <&clk_phy>, <&pclk>, <&clk_port>; + clock-names = "general", "pclk", "port"; resets = <&reset_pcie_port>, <&reset_pcie_apb>; reset-names = "port", "apb"; phys = <&pcie_phy>; diff --git a/Documentation/devicetree/bindings/pci/cix,sky1-pcie-host.yaml b/Documentation/devicetree/bindings/pci/cix,sky1-pcie-host.yaml new file mode 100644 index 0000000000000..b910a42e0843d --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cix,sky1-pcie-host.yaml @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pci/cix,sky1-pcie-host.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: CIX Sky1 PCIe Root Complex + +maintainers: + - Hans Zhang + +description: + PCIe root complex controller based on the Cadence PCIe core. + +allOf: + - $ref: /schemas/pci/pci-host-bridge.yaml# + +properties: + compatible: + const: cix,sky1-pcie-host + + reg: + items: + - description: PCIe controller registers. + - description: ECAM registers. + - description: Remote CIX System Unit strap registers. + - description: Remote CIX System Unit status registers. + - description: Region for sending messages registers. + + reg-names: + items: + - const: reg + - const: cfg + - const: rcsu_strap + - const: rcsu_status + - const: msg + + ranges: + maxItems: 3 + +required: + - compatible + - ranges + - bus-range + - device_type + - interrupt-map + - interrupt-map-mask + - msi-map + +unevaluatedProperties: false + +examples: + - | + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + pcie@a010000 { + compatible = "cix,sky1-pcie-host"; + reg = <0x00 0x0a010000 0x00 0x10000>, + <0x00 0x2c000000 0x00 0x4000000>, + <0x00 0x0a000300 0x00 0x100>, + <0x00 0x0a000400 0x00 0x100>, + <0x00 0x60000000 0x00 0x00100000>; + reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg"; + ranges = <0x01000000 0x00 0x60100000 0x00 0x60100000 0x00 0x00100000>, + <0x02000000 0x00 0x60200000 0x00 0x60200000 0x00 0x1fe00000>, + <0x43000000 0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0xc0 0xff>; + device_type = "pci"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &gic 0 0 GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &gic 0 0 GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &gic 0 0 GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH 0>; + msi-map = <0xc000 &gic_its 0xc000 0x4000>; + }; + }; diff --git a/Documentation/devicetree/bindings/pci/faraday,ftpci100.yaml b/Documentation/devicetree/bindings/pci/faraday,ftpci100.yaml index 378dd1c8e2ee2..fed393a895633 100644 --- a/Documentation/devicetree/bindings/pci/faraday,ftpci100.yaml +++ b/Documentation/devicetree/bindings/pci/faraday,ftpci100.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Faraday Technology FTPCI100 PCI Host Bridge maintainers: - - Linus Walleij + - Linus Walleij description: | This PCI bridge is found inside that Cortina Systems Gemini SoC platform and diff --git a/Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml b/Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml index 3cae2e0f7f5e2..c1806aef7bac4 100644 --- a/Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml +++ b/Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Intel IXP4xx PCI controller maintainers: - - Linus Walleij + - Linus Walleij description: PCI host controller found in the Intel IXP4xx SoC series. diff --git a/Documentation/devicetree/bindings/pci/loongson.yaml b/Documentation/devicetree/bindings/pci/loongson.yaml index 1988465e73a12..e5bba63aa9479 100644 --- a/Documentation/devicetree/bindings/pci/loongson.yaml +++ b/Documentation/devicetree/bindings/pci/loongson.yaml @@ -32,7 +32,6 @@ properties: minItems: 1 maxItems: 3 - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-mt7623.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-mt7623.yaml new file mode 100644 index 0000000000000..e33bcc216e30c --- /dev/null +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-mt7623.yaml @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pci/mediatek-pcie-mt7623.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: PCIe controller on MediaTek SoCs + +maintainers: + - Christian Marangi + +properties: + compatible: + enum: + - mediatek,mt2701-pcie + - mediatek,mt7623-pcie + + reg: + minItems: 4 + maxItems: 4 + + reg-names: + items: + - const: subsys + - const: port0 + - const: port1 + - const: port2 + + clocks: + minItems: 4 + maxItems: 4 + + clock-names: + items: + - const: free_ck + - const: sys_ck0 + - const: sys_ck1 + - const: sys_ck2 + + resets: + minItems: 3 + maxItems: 3 + + reset-names: + items: + - const: pcie-rst0 + - const: pcie-rst1 + - const: pcie-rst2 + + phys: + minItems: 3 + maxItems: 3 + + phy-names: + items: + - const: pcie-phy0 + - const: pcie-phy1 + - const: pcie-phy2 + + power-domains: + maxItems: 1 + +required: + - compatible + - reg + - reg-names + - ranges + - clocks + - clock-names + - '#interrupt-cells' + - resets + - reset-names + - phys + - phy-names + - power-domains + - pcie@0,0 + - pcie@1,0 + - pcie@2,0 + +allOf: + - $ref: /schemas/pci/pci-host-bridge.yaml# + +unevaluatedProperties: false + +examples: + # MT7623 + - | + #include + #include + #include + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + pcie@1a140000 { + compatible = "mediatek,mt7623-pcie"; + device_type = "pci"; + reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */ + <0 0x1a142000 0 0x1000>, /* Port0 registers */ + <0 0x1a143000 0 0x1000>, /* Port1 registers */ + <0 0x1a144000 0 0x1000>; /* Port2 registers */ + reg-names = "subsys", "port0", "port1", "port2"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xf800 0 0 0>; + interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, + <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, + <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_ETHIF_SEL>, + <&hifsys CLK_HIFSYS_PCIE0>, + <&hifsys CLK_HIFSYS_PCIE1>, + <&hifsys CLK_HIFSYS_PCIE2>; + clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; + resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, + <&hifsys MT2701_HIFSYS_PCIE1_RST>, + <&hifsys MT2701_HIFSYS_PCIE2_RST>; + reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; + phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>, + <&pcie2_phy PHY_TYPE_PCIE>; + phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; + bus-range = <0x00 0xff>; + ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000>, /* I/O space */ + <0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* memory space */ + + pcie@0,0 { + device_type = "pci"; + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; + ranges; + }; + + pcie@1,0 { + device_type = "pci"; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; + ranges; + }; + + pcie@2,0 { + device_type = "pci"; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; + ranges; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt deleted file mode 100644 index 684227522267f..0000000000000 --- a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt +++ /dev/null @@ -1,289 +0,0 @@ -MediaTek Gen2 PCIe controller - -Required properties: -- compatible: Should contain one of the following strings: - "mediatek,mt2701-pcie" - "mediatek,mt2712-pcie" - "mediatek,mt7622-pcie" - "mediatek,mt7623-pcie" - "mediatek,mt7629-pcie" - "airoha,en7523-pcie" -- device_type: Must be "pci" -- reg: Base addresses and lengths of the root ports. -- reg-names: Names of the above areas to use during resource lookup. -- #address-cells: Address representation for root ports (must be 3) -- #size-cells: Size representation for root ports (must be 2) -- clocks: Must contain an entry for each entry in clock-names. - See ../clocks/clock-bindings.txt for details. -- clock-names: - Mandatory entries: - - sys_ckN :transaction layer and data link layer clock - Required entries for MT2701/MT7623: - - free_ck :for reference clock of PCIe subsys - Required entries for MT2712/MT7622: - - ahb_ckN :AHB slave interface operating clock for CSR access and RC - initiated MMIO access - Required entries for MT7622: - - axi_ckN :application layer MMIO channel operating clock - - aux_ckN :pe2_mac_bridge and pe2_mac_core operating clock when - pcie_mac_ck/pcie_pipe_ck is turned off - - obff_ckN :OBFF functional block operating clock - - pipe_ckN :LTSSM and PHY/MAC layer operating clock - where N starting from 0 to one less than the number of root ports. -- phys: List of PHY specifiers (used by generic PHY framework). -- phy-names : Must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the - number of PHYs as specified in *phys* property. -- power-domains: A phandle and power domain specifier pair to the power domain - which is responsible for collapsing and restoring power to the peripheral. -- bus-range: Range of bus numbers associated with this controller. -- ranges: Ranges for the PCI memory and I/O regions. - -Required properties for MT7623/MT2701: -- #interrupt-cells: Size representation for interrupts (must be 1) -- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties - Please refer to the standard PCI bus binding document for a more detailed - explanation. -- resets: Must contain an entry for each entry in reset-names. - See ../reset/reset.txt for details. -- reset-names: Must be "pcie-rst0", "pcie-rst1", "pcie-rstN".. based on the - number of root ports. - -Required properties for MT2712/MT7622/MT7629: --interrupts: A list of interrupt outputs of the controller, must have one - entry for each PCIe port -- interrupt-names: Must include the following entries: - - "pcie_irq": The interrupt that is asserted when an MSI/INTX is received -- linux,pci-domain: PCI domain ID. Should be unique for each host controller - -In addition, the device tree node must have sub-nodes describing each -PCIe port interface, having the following mandatory properties: - -Required properties: -- device_type: Must be "pci" -- reg: Only the first four bytes are used to refer to the correct bus number - and device number. -- #address-cells: Must be 3 -- #size-cells: Must be 2 -- #interrupt-cells: Must be 1 -- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties - Please refer to the standard PCI bus binding document for a more detailed - explanation. -- ranges: Sub-ranges distributed from the PCIe controller node. An empty - property is sufficient. - -Examples for MT7623: - - hifsys: syscon@1a000000 { - compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", - "syscon"; - reg = <0 0x1a000000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - pcie: pcie@1a140000 { - compatible = "mediatek,mt7623-pcie"; - device_type = "pci"; - reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */ - <0 0x1a142000 0 0x1000>, /* Port0 registers */ - <0 0x1a143000 0 0x1000>, /* Port1 registers */ - <0 0x1a144000 0 0x1000>; /* Port2 registers */ - reg-names = "subsys", "port0", "port1", "port2"; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0xf800 0 0 0>; - interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, - <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, - <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; - clocks = <&topckgen CLK_TOP_ETHIF_SEL>, - <&hifsys CLK_HIFSYS_PCIE0>, - <&hifsys CLK_HIFSYS_PCIE1>, - <&hifsys CLK_HIFSYS_PCIE2>; - clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; - resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, - <&hifsys MT2701_HIFSYS_PCIE1_RST>, - <&hifsys MT2701_HIFSYS_PCIE2_RST>; - reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; - phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>, - <&pcie2_phy PHY_TYPE_PCIE>; - phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; - bus-range = <0x00 0xff>; - ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* I/O space */ - 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* memory space */ - - pcie@0,0 { - reg = <0x0000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; - ranges; - }; - - pcie@1,0 { - reg = <0x0800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; - ranges; - }; - - pcie@2,0 { - reg = <0x1000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; - ranges; - }; - }; - -Examples for MT2712: - - pcie1: pcie@112ff000 { - compatible = "mediatek,mt2712-pcie"; - device_type = "pci"; - reg = <0 0x112ff000 0 0x1000>; - reg-names = "port1"; - linux,pci-domain = <1>; - #address-cells = <3>; - #size-cells = <2>; - interrupts = ; - interrupt-names = "pcie_irq"; - clocks = <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, - <&pericfg CLK_PERI_PCIE1>; - clock-names = "sys_ck1", "ahb_ck1"; - phys = <&u3port1 PHY_TYPE_PCIE>; - phy-names = "pcie-phy1"; - bus-range = <0x00 0xff>; - ranges = <0x82000000 0 0x11400000 0x0 0x11400000 0 0x300000>; - status = "disabled"; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &pcie_intc1 0>, - <0 0 0 2 &pcie_intc1 1>, - <0 0 0 3 &pcie_intc1 2>, - <0 0 0 4 &pcie_intc1 3>; - pcie_intc1: interrupt-controller { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <1>; - }; - }; - - pcie0: pcie@11700000 { - compatible = "mediatek,mt2712-pcie"; - device_type = "pci"; - reg = <0 0x11700000 0 0x1000>; - reg-names = "port0"; - linux,pci-domain = <0>; - #address-cells = <3>; - #size-cells = <2>; - interrupts = ; - interrupt-names = "pcie_irq"; - clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, - <&pericfg CLK_PERI_PCIE0>; - clock-names = "sys_ck0", "ahb_ck0"; - phys = <&u3port0 PHY_TYPE_PCIE>; - phy-names = "pcie-phy0"; - bus-range = <0x00 0xff>; - ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; - status = "disabled"; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &pcie_intc0 0>, - <0 0 0 2 &pcie_intc0 1>, - <0 0 0 3 &pcie_intc0 2>, - <0 0 0 4 &pcie_intc0 3>; - pcie_intc0: interrupt-controller { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <1>; - }; - }; - -Examples for MT7622: - - pcie0: pcie@1a143000 { - compatible = "mediatek,mt7622-pcie"; - device_type = "pci"; - reg = <0 0x1a143000 0 0x1000>; - reg-names = "port0"; - linux,pci-domain = <0>; - #address-cells = <3>; - #size-cells = <2>; - interrupts = ; - interrupt-names = "pcie_irq"; - clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, - <&pciesys CLK_PCIE_P0_AHB_EN>, - <&pciesys CLK_PCIE_P0_AUX_EN>, - <&pciesys CLK_PCIE_P0_AXI_EN>, - <&pciesys CLK_PCIE_P0_OBFF_EN>, - <&pciesys CLK_PCIE_P0_PIPE_EN>; - clock-names = "sys_ck0", "ahb_ck0", "aux_ck0", - "axi_ck0", "obff_ck0", "pipe_ck0"; - - power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; - bus-range = <0x00 0xff>; - ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>; - status = "disabled"; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &pcie_intc0 0>, - <0 0 0 2 &pcie_intc0 1>, - <0 0 0 3 &pcie_intc0 2>, - <0 0 0 4 &pcie_intc0 3>; - pcie_intc0: interrupt-controller { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <1>; - }; - }; - - pcie1: pcie@1a145000 { - compatible = "mediatek,mt7622-pcie"; - device_type = "pci"; - reg = <0 0x1a145000 0 0x1000>; - reg-names = "port1"; - linux,pci-domain = <1>; - #address-cells = <3>; - #size-cells = <2>; - interrupts = ; - interrupt-names = "pcie_irq"; - clocks = <&pciesys CLK_PCIE_P1_MAC_EN>, - /* designer has connect RC1 with p0_ahb clock */ - <&pciesys CLK_PCIE_P0_AHB_EN>, - <&pciesys CLK_PCIE_P1_AUX_EN>, - <&pciesys CLK_PCIE_P1_AXI_EN>, - <&pciesys CLK_PCIE_P1_OBFF_EN>, - <&pciesys CLK_PCIE_P1_PIPE_EN>; - clock-names = "sys_ck1", "ahb_ck1", "aux_ck1", - "axi_ck1", "obff_ck1", "pipe_ck1"; - - power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; - bus-range = <0x00 0xff>; - ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>; - status = "disabled"; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &pcie_intc1 0>, - <0 0 0 2 &pcie_intc1 1>, - <0 0 0 3 &pcie_intc1 2>, - <0 0 0 4 &pcie_intc1 3>; - pcie_intc1: interrupt-controller { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <1>; - }; - }; diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie.yaml new file mode 100644 index 0000000000000..0b8c78ec4f91b --- /dev/null +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.yaml @@ -0,0 +1,438 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pci/mediatek-pcie.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: PCIe controller on MediaTek SoCs + +maintainers: + - Christian Marangi + +properties: + compatible: + oneOf: + - enum: + - airoha,an7583-pcie + - mediatek,mt2712-pcie + - mediatek,mt7622-pcie + - mediatek,mt7629-pcie + - items: + - const: airoha,en7523-pcie + - const: mediatek,mt7622-pcie + + reg: + maxItems: 1 + + reg-names: + enum: [ port0, port1 ] + + clocks: + minItems: 1 + maxItems: 6 + + clock-names: + minItems: 1 + items: + - enum: [ sys_ck0, sys_ck1 ] + - enum: [ ahb_ck0, ahb_ck1 ] + - enum: [ aux_ck0, aux_ck1 ] + - enum: [ axi_ck0, axi_ck1 ] + - enum: [ obff_ck0, obff_ck1 ] + - enum: [ pipe_ck0, pipe_ck1 ] + + resets: + maxItems: 1 + + reset-names: + const: pcie-rst1 + + interrupts: + maxItems: 1 + + interrupt-names: + const: pcie_irq + + phys: + maxItems: 1 + + phy-names: + enum: [ pcie-phy0, pcie-phy1 ] + + power-domains: + maxItems: 1 + + mediatek,pbus-csr: + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to pbus-csr syscon + - description: offset of pbus-csr base address register + - description: offset of pbus-csr base address mask register + description: + Phandle with two arguments to the syscon node used to detect if + a given address is accessible on PCIe controller. + + '#interrupt-cells': + const: 1 + + interrupt-controller: + description: Interrupt controller node for handling legacy PCI interrupts. + type: object + properties: + '#address-cells': + const: 0 + '#interrupt-cells': + const: 1 + interrupt-controller: true + + required: + - '#address-cells' + - '#interrupt-cells' + - interrupt-controller + + additionalProperties: false + +required: + - compatible + - reg + - reg-names + - ranges + - clocks + - clock-names + - '#interrupt-cells' + - interrupts + - interrupt-names + - interrupt-controller + +allOf: + - $ref: /schemas/pci/pci-host-bridge.yaml# + + - if: + properties: + compatible: + const: airoha,an7583-pcie + then: + properties: + reg-names: + const: port1 + + clocks: + maxItems: 1 + + clock-names: + const: sys_ck1 + + phy-names: + const: pcie-phy1 + + power-domain: false + + required: + - resets + - reset-names + - phys + - phy-names + - mediatek,pbus-csr + + - if: + properties: + compatible: + const: mediatek,mt2712-pcie + then: + properties: + clocks: + minItems: 2 + maxItems: 2 + + clock-names: + minItems: 2 + maxItems: 2 + + reset: false + + reset-names: false + + power-domains: false + + mediatek,pbus-csr: false + + required: + - phys + - phy-names + + - if: + properties: + compatible: + const: mediatek,mt7622-pcie + then: + properties: + clocks: + minItems: 6 + + reset: false + + reset-names: false + + phys: false + + phy-names: false + + mediatek,pbus-csr: false + + required: + - power-domains + + - if: + properties: + compatible: + const: mediatek,mt7629-pcie + then: + properties: + clocks: + minItems: 6 + + reset: false + + reset-names: false + + mediatek,pbus-csr: false + + required: + - power-domains + + - if: + properties: + compatible: + contains: + const: airoha,en7523-pcie + then: + properties: + clocks: + maxItems: 1 + + clock-names: + maxItems: 1 + + reset: false + + reset-names: false + + phys: false + + phy-names: false + + power-domain: false + + mediatek,pbus-csr: false + +unevaluatedProperties: false + +examples: + # MT2712 + - | + #include + #include + #include + + soc_1 { + #address-cells = <2>; + #size-cells = <2>; + + pcie@112ff000 { + compatible = "mediatek,mt2712-pcie"; + device_type = "pci"; + reg = <0 0x112ff000 0 0x1000>; + reg-names = "port1"; + linux,pci-domain = <1>; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; + interrupt-names = "pcie_irq"; + clocks = <&topckgen>, /* CLK_TOP_PE2_MAC_P1_SEL */ + <&pericfg>; /* CLK_PERI_PCIE1 */ + clock-names = "sys_ck1", "ahb_ck1"; + phys = <&u3port1 PHY_TYPE_PCIE>; + phy-names = "pcie-phy1"; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x11400000 0x0 0x11400000 0 0x300000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; + pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + pcie@11700000 { + compatible = "mediatek,mt2712-pcie"; + device_type = "pci"; + reg = <0 0x11700000 0 0x1000>; + reg-names = "port0"; + linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; + interrupt-names = "pcie_irq"; + clocks = <&topckgen>, /* CLK_TOP_PE2_MAC_P0_SEL */ + <&pericfg>; /* CLK_PERI_PCIE0 */ + clock-names = "sys_ck0", "ahb_ck0"; + phys = <&u3port0 PHY_TYPE_PCIE>; + phy-names = "pcie-phy0"; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0 0>, + <0 0 0 2 &pcie_intc0 1>, + <0 0 0 3 &pcie_intc0 2>, + <0 0 0 4 &pcie_intc0 3>; + pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + }; + + # MT7622 + - | + #include + #include + #include + + soc_2 { + #address-cells = <2>; + #size-cells = <2>; + + pcie@1a143000 { + compatible = "mediatek,mt7622-pcie"; + device_type = "pci"; + reg = <0 0x1a143000 0 0x1000>; + reg-names = "port0"; + linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; + interrupt-names = "pcie_irq"; + clocks = <&pciesys>, /* CLK_PCIE_P0_MAC_EN */ + <&pciesys>, /* CLK_PCIE_P0_AHB_EN */ + <&pciesys>, /* CLK_PCIE_P0_AUX_EN */ + <&pciesys>, /* CLK_PCIE_P0_AXI_EN */ + <&pciesys>, /* CLK_PCIE_P0_OBFF_EN */ + <&pciesys>; /* CLK_PCIE_P0_PIPE_EN */ + clock-names = "sys_ck0", "ahb_ck0", "aux_ck0", + "axi_ck0", "obff_ck0", "pipe_ck0"; + + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0_1 0>, + <0 0 0 2 &pcie_intc0_1 1>, + <0 0 0 3 &pcie_intc0_1 2>, + <0 0 0 4 &pcie_intc0_1 3>; + pcie_intc0_1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + pcie@1a145000 { + compatible = "mediatek,mt7622-pcie"; + device_type = "pci"; + reg = <0 0x1a145000 0 0x1000>; + reg-names = "port1"; + linux,pci-domain = <1>; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; + interrupt-names = "pcie_irq"; + clocks = <&pciesys>, /* CLK_PCIE_P1_MAC_EN */ + /* designer has connect RC1 with p0_ahb clock */ + <&pciesys>, /* CLK_PCIE_P0_AHB_EN */ + <&pciesys>, /* CLK_PCIE_P1_AUX_EN */ + <&pciesys>, /* CLK_PCIE_P1_AXI_EN */ + <&pciesys>, /* CLK_PCIE_P1_OBFF_EN */ + <&pciesys>; /* CLK_PCIE_P1_PIPE_EN */ + clock-names = "sys_ck1", "ahb_ck1", "aux_ck1", + "axi_ck1", "obff_ck1", "pipe_ck1"; + + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1_1 0>, + <0 0 0 2 &pcie_intc1_1 1>, + <0 0 0 3 &pcie_intc1_1 2>, + <0 0 0 4 &pcie_intc1_1 3>; + pcie_intc1_1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + }; + + # AN7583 + - | + #include + #include + #include + + soc_3 { + #address-cells = <2>; + #size-cells = <2>; + + pcie@1fa92000 { + compatible = "airoha,an7583-pcie"; + device_type = "pci"; + linux,pci-domain = <1>; + #address-cells = <3>; + #size-cells = <2>; + + reg = <0x0 0x1fa92000 0x0 0x1670>; + reg-names = "port1"; + + clocks = <&scuclk EN7523_CLK_PCIE>; + clock-names = "sys_ck1"; + + phys = <&pciephy>; + phy-names = "pcie-phy1"; + + ranges = <0x02000000 0 0x24000000 0x0 0x24000000 0 0x4000000>; + + resets = <&scuclk>; /* AN7583_PCIE1_RST */ + reset-names = "pcie-rst1"; + + mediatek,pbus-csr = <&pbus_csr 0x8 0xc>; + + interrupts = ; + interrupt-names = "pcie_irq"; + bus-range = <0x00 0xff>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; + + pcie_intc1_4: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pci/nxp,s32g-pcie.yaml b/Documentation/devicetree/bindings/pci/nxp,s32g-pcie.yaml new file mode 100644 index 0000000000000..66a050028278a --- /dev/null +++ b/Documentation/devicetree/bindings/pci/nxp,s32g-pcie.yaml @@ -0,0 +1,130 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pci/nxp,s32g-pcie.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP S32G2xxx/S32G3xxx PCIe Root Complex controller + +maintainers: + - Bogdan Hamciuc + - Ionut Vicovan + +description: + This PCIe controller is based on the Synopsys DesignWare PCIe IP. + The S32G SoC family has two PCIe controllers, which can be configured as + either Root Complex or Endpoint. + +properties: + compatible: + oneOf: + - enum: + - nxp,s32g2-pcie + - items: + - const: nxp,s32g3-pcie + - const: nxp,s32g2-pcie + + reg: + maxItems: 6 + + reg-names: + items: + - const: dbi + - const: dbi2 + - const: atu + - const: dma + - const: ctrl + - const: config + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + items: + - const: msi + - const: dma + minItems: 1 + + pcie@0: + description: + Describe the S32G Root Port. + type: object + $ref: /schemas/pci/pci-pci-bridge.yaml# + + properties: + reg: + maxItems: 1 + + phys: + maxItems: 1 + + required: + - reg + - phys + + unevaluatedProperties: false + +required: + - compatible + - reg + - reg-names + - interrupts + - interrupt-names + - ranges + - pcie@0 + +allOf: + - $ref: /schemas/pci/snps,dw-pcie.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + + bus { + #address-cells = <2>; + #size-cells = <2>; + + pcie@40400000 { + compatible = "nxp,s32g3-pcie", "nxp,s32g2-pcie"; + reg = <0x00 0x40400000 0x0 0x00001000>, /* dbi registers */ + <0x00 0x40420000 0x0 0x00001000>, /* dbi2 registers */ + <0x00 0x40460000 0x0 0x00001000>, /* atu registers */ + <0x00 0x40470000 0x0 0x00001000>, /* dma registers */ + <0x00 0x40481000 0x0 0x000000f8>, /* ctrl registers */ + <0x5f 0xffffe000 0x0 0x00002000>; /* config space */ + reg-names = "dbi", "dbi2", "atu", "dma", "ctrl", "config"; + dma-coherent; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = + <0x01000000 0x0 0x00000000 0x5f 0xfffe0000 0x0 0x00010000>, + <0x02000000 0x0 0x00000000 0x58 0x00000000 0x0 0x80000000>, + <0x02000000 0x1 0x00000000 0x59 0x00000000 0x6 0xfffe0000>; + + bus-range = <0x0 0xff>; + interrupts = , + ; + interrupt-names = "msi", "dma"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; + + pcie@0 { + reg = <0x0 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + ranges; + + device_type = "pci"; + phys = <&serdes0 PHY_TYPE_PCIE 0 0>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pci/pci-ep.yaml b/Documentation/devicetree/bindings/pci/pci-ep.yaml index 1868a10d5b10d..baeb583e0bcd7 100644 --- a/Documentation/devicetree/bindings/pci/pci-ep.yaml +++ b/Documentation/devicetree/bindings/pci/pci-ep.yaml @@ -11,7 +11,7 @@ description: | maintainers: - Kishon Vijay Abraham I - - Manivannan Sadhasivam + - Manivannan Sadhasivam properties: $nodename: diff --git a/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml index 039eecdbd6aad..fe2e8beb5babd 100644 --- a/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml +++ b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml @@ -72,7 +72,7 @@ required: - reg-names - interrupts - msi-controller - - "#interrupt-cells" + - '#interrupt-cells' - interrupt-map-mask - interrupt-map diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml index ab2509ec1c4b4..77f8faf54737e 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-common.yaml @@ -8,7 +8,7 @@ title: Qualcomm PCI Express Root Complex Common Properties maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam properties: reg: diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml index ac3414203d383..bed9a40b186bc 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm PCIe Endpoint Controller maintainers: - - Manivannan Sadhasivam + - Manivannan Sadhasivam properties: compatible: diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sa8255p.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sa8255p.yaml index bdddd4f499d18..1f2d098b86384 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sa8255p.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sa8255p.yaml @@ -8,7 +8,7 @@ title: Qualcomm SA8255p based firmware managed and ECAM compliant PCIe Root Comp maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm SA8255p SoC PCIe root complex controller is based on the Synopsys diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml index 19afe2a03409b..63630a814f287 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml @@ -8,7 +8,7 @@ title: Qualcomm SA8775p PCI Express Root Complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm SA8775p SoC PCIe root complex controller is based on the Synopsys @@ -78,6 +78,9 @@ properties: required: - interconnects - interconnect-names + - power-domains + - resets + - reset-names allOf: - $ref: qcom,pcie-common.yaml# diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sc7280.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sc7280.yaml index 4d0a915566030..1f942b3075f1c 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sc7280.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sc7280.yaml @@ -8,7 +8,7 @@ title: Qualcomm SC7280 PCI Express Root Complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm SC7280 SoC PCIe root complex controller is based on the Synopsys @@ -76,6 +76,11 @@ properties: items: - const: pci +required: + - power-domains + - resets + - reset-names + allOf: - $ref: qcom,pcie-common.yaml# diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sc8180x.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sc8180x.yaml index 34a4d7b2c8459..6a7c410c9fc30 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sc8180x.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sc8180x.yaml @@ -8,7 +8,7 @@ title: Qualcomm SC8180x PCI Express Root Complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm SC8180x SoC PCIe root complex controller is based on the Synopsys diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sc8280xp.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sc8280xp.yaml index 15ba2385eb73c..bc0e71dc06a3a 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sc8280xp.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sc8280xp.yaml @@ -8,7 +8,7 @@ title: Qualcomm SC8280XP PCI Express Root Complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm SC8280XP SoC PCIe root complex controller is based on the Synopsys @@ -61,6 +61,9 @@ properties: required: - interconnects - interconnect-names + - power-domains + - resets + - reset-names allOf: - $ref: qcom,pcie-common.yaml# diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8150.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8150.yaml index 26b247a41785f..6a5421e4f19d4 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8150.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8150.yaml @@ -8,7 +8,7 @@ title: Qualcomm SM8150 PCI Express Root Complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm SM8150 SoC PCIe root complex controller is based on the Synopsys @@ -74,6 +74,11 @@ properties: items: - const: pci +required: + - power-domains + - resets + - reset-names + allOf: - $ref: qcom,pcie-common.yaml# diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8250.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8250.yaml index af4dae68d5087..adbeaa8f2c133 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8250.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8250.yaml @@ -8,7 +8,7 @@ title: Qualcomm SM8250 PCI Express Root Complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm SM8250 SoC PCIe root complex controller is based on the Synopsys @@ -83,6 +83,11 @@ properties: items: - const: pci +required: + - power-domains + - resets + - reset-names + allOf: - $ref: qcom,pcie-common.yaml# diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8350.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8350.yaml index dde3079adbb33..5744d5e969fb9 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8350.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8350.yaml @@ -8,7 +8,7 @@ title: Qualcomm SM8350 PCI Express Root Complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm SM8350 SoC PCIe root complex controller is based on the Synopsys @@ -73,6 +73,11 @@ properties: items: - const: pci +required: + - power-domains + - resets + - reset-names + allOf: - $ref: qcom,pcie-common.yaml# diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml index 6e0a6d8f0ed07..28b8ffb74124b 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8450.yaml @@ -8,7 +8,7 @@ title: Qualcomm SM8450 PCI Express Root Complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm SM8450 SoC PCIe root complex controller is based on the Synopsys @@ -77,6 +77,11 @@ properties: items: - const: pci +required: + - power-domains + - resets + - reset-names + allOf: - $ref: qcom,pcie-common.yaml# diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml index 38b561e23c1fd..3a94a9c1bb155 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml @@ -8,7 +8,7 @@ title: Qualcomm SM8550 PCI Express Root Complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm SM8550 SoC (and compatible) PCIe root complex controller is based on @@ -20,6 +20,7 @@ properties: - const: qcom,pcie-sm8550 - items: - enum: + - qcom,kaanapali-pcie - qcom,sar2130p-pcie - qcom,pcie-sm8650 - qcom,pcie-sm8750 @@ -83,6 +84,11 @@ properties: - const: pci # PCIe core reset - const: link_down # PCIe link down reset +required: + - power-domains + - resets + - reset-names + allOf: - $ref: qcom,pcie-common.yaml# diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml index 61581ffbfb248..62c674ca0cf74 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml @@ -8,7 +8,7 @@ title: Qualcomm X1E80100 PCI Express Root Complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: Qualcomm X1E80100 SoC (and compatible) PCIe root complex controller is based on @@ -73,6 +73,11 @@ properties: - const: pci # PCIe core reset - const: link_down # PCIe link down reset +required: + - power-domains + - resets + - reset-names + allOf: - $ref: qcom,pcie-common.yaml# diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml index 0e1808105a819..c61930441be09 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml @@ -8,7 +8,7 @@ title: Qualcomm PCI express root complex maintainers: - Bjorn Andersson - - Manivannan Sadhasivam + - Manivannan Sadhasivam description: | Qualcomm PCIe root complex controller is based on the Synopsys DesignWare diff --git a/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml b/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml new file mode 100644 index 0000000000000..d668782546a23 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml @@ -0,0 +1,249 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pci/renesas,r9a08g045-pcie.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/G3S PCIe host controller + +maintainers: + - Claudiu Beznea + +description: + Renesas RZ/G3S PCIe host controller complies with PCIe Base Specification + 4.0 and supports up to 5 GT/s (Gen2). + +properties: + compatible: + const: renesas,r9a08g045-pcie # RZ/G3S + + reg: + maxItems: 1 + + interrupts: + items: + - description: System error interrupt + - description: System error on correctable error interrupt + - description: System error on non-fatal error interrupt + - description: System error on fatal error interrupt + - description: AXI error interrupt + - description: INTA interrupt + - description: INTB interrupt + - description: INTC interrupt + - description: INTD interrupt + - description: MSI interrupt + - description: Link bandwidth interrupt + - description: PME interrupt + - description: DMA interrupt + - description: PCIe event interrupt + - description: Message interrupt + - description: All interrupts + + interrupt-names: + items: + - description: serr + - description: ser_cor + - description: serr_nonfatal + - description: serr_fatal + - description: axi_err + - description: inta + - description: intb + - description: intc + - description: intd + - description: msi + - description: link_bandwidth + - description: pm_pme + - description: dma + - description: pcie_evt + - description: msg + - description: all + + interrupt-controller: true + + clocks: + items: + - description: System clock + - description: PM control clock + + clock-names: + items: + - description: aclk + - description: pm + + resets: + items: + - description: AXI2PCIe Bridge reset + - description: Data link layer/transaction layer reset + - description: Transaction layer (ACLK domain) reset + - description: Transaction layer (PCLK domain) reset + - description: Physical layer reset + - description: Configuration register reset + - description: Configuration register reset + + reset-names: + items: + - description: aresetn + - description: rst_b + - description: rst_gp_b + - description: rst_ps_b + - description: rst_rsm_b + - description: rst_cfg_b + - description: rst_load_b + + power-domains: + maxItems: 1 + + dma-ranges: + description: + A single range for the inbound memory region. + maxItems: 1 + + renesas,sysc: + description: | + System controller registers control and monitor various PCIe + functionalities. + + Control: + - transition to L1 state + - receiver termination settings + - RST_RSM_B signal + + Monitor: + - clkl1pm clock request state + - power off information in L2 state + - errors (fatal, non-fatal, correctable) + $ref: /schemas/types.yaml#/definitions/phandle + +patternProperties: + "^pcie@0,[0-0]$": + type: object + allOf: + - $ref: /schemas/pci/pci-pci-bridge.yaml# + + properties: + reg: + maxItems: 1 + + vendor-id: + const: 0x1912 + + device-id: + const: 0x0033 + + clocks: + items: + - description: Reference clock + + clock-names: + items: + - const: ref + + required: + - device_type + - vendor-id + - device-id + - clocks + - clock-names + + unevaluatedProperties: false + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - interrupts + - interrupt-names + - interrupt-map + - interrupt-map-mask + - interrupt-controller + - power-domains + - "#address-cells" + - "#size-cells" + - "#interrupt-cells" + - renesas,sysc + +allOf: + - $ref: /schemas/pci/pci-host-bridge.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + + bus { + #address-cells = <2>; + #size-cells = <2>; + + pcie@11e40000 { + compatible = "renesas,r9a08g045-pcie"; + reg = <0 0x11e40000 0 0x10000>; + ranges = <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>; + /* Map all possible DRAM ranges (4 GB). */ + dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 1 0x00000000>; + bus-range = <0x0 0xff>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "serr", "serr_cor", "serr_nonfatal", + "serr_fatal", "axi_err", "inta", + "intb", "intc", "intd", "msi", + "link_bandwidth", "pm_pme", "dma", + "pcie_evt", "msg", "all"; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie 0 0 0 0>, /* INTA */ + <0 0 0 2 &pcie 0 0 0 1>, /* INTB */ + <0 0 0 3 &pcie 0 0 0 2>, /* INTC */ + <0 0 0 4 &pcie 0 0 0 3>; /* INTD */ + clocks = <&cpg CPG_MOD R9A08G045_PCI_ACLK>, + <&cpg CPG_MOD R9A08G045_PCI_CLKL1PM>; + clock-names = "aclk", "pm"; + resets = <&cpg R9A08G045_PCI_ARESETN>, + <&cpg R9A08G045_PCI_RST_B>, + <&cpg R9A08G045_PCI_RST_GP_B>, + <&cpg R9A08G045_PCI_RST_PS_B>, + <&cpg R9A08G045_PCI_RST_RSM_B>, + <&cpg R9A08G045_PCI_RST_CFG_B>, + <&cpg R9A08G045_PCI_RST_LOAD_B>; + reset-names = "aresetn", "rst_b", "rst_gp_b", "rst_ps_b", + "rst_rsm_b", "rst_cfg_b", "rst_load_b"; + power-domains = <&cpg>; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + renesas,sysc = <&sysc>; + + pcie@0,0 { + reg = <0x0 0x0 0x0 0x0 0x0>; + ranges; + clocks = <&versa3 5>; + clock-names = "ref"; + device_type = "pci"; + vendor-id = <0x1912>; + device-id = <0x0033>; + #address-cells = <3>; + #size-cells = <2>; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml index 6c6d828ce9641..355c4a46bd316 100644 --- a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml @@ -22,6 +22,7 @@ properties: - const: rockchip,rk3568-pcie - items: - enum: + - rockchip,rk3528-pcie - rockchip,rk3562-pcie - rockchip,rk3576-pcie - rockchip,rk3588-pcie @@ -78,6 +79,7 @@ allOf: compatible: contains: enum: + - rockchip,rk3528-pcie - rockchip,rk3562-pcie - rockchip,rk3576-pcie then: @@ -89,6 +91,7 @@ allOf: compatible: contains: enum: + - rockchip,rk3528-pcie - rockchip,rk3562-pcie - rockchip,rk3576-pcie then: @@ -121,7 +124,6 @@ allOf: - const: dma2 - const: dma3 - unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml index 34594972d8dbe..6339a76499b21 100644 --- a/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml +++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml @@ -115,11 +115,11 @@ properties: above for new bindings. oneOf: - description: See native 'dbi' clock for details - enum: [ pcie, pcie_apb_sys, aclk_dbi, reg ] + enum: [ pcie, pcie_apb_sys, aclk_dbi, reg, port ] - description: See native 'mstr/slv' clock for details enum: [ pcie_bus, pcie_inbound_axi, pcie_aclk, aclk_mst, aclk_slv ] - description: See native 'pipe' clock for details - enum: [ pcie_phy, pcie_phy_ref, link ] + enum: [ pcie_phy, pcie_phy_ref, link, general ] - description: See native 'aux' clock for details enum: [ pcie_aux ] - description: See native 'ref' clock for details. @@ -176,7 +176,7 @@ properties: - description: See native 'phy' reset for details enum: [ pciephy, link ] - description: See native 'pwr' reset for details - enum: [ turnoff ] + enum: [ turnoff, port ] phys: description: diff --git a/Documentation/devicetree/bindings/pci/spacemit,k1-pcie-host.yaml b/Documentation/devicetree/bindings/pci/spacemit,k1-pcie-host.yaml new file mode 100644 index 0000000000000..c4c00b5fcdc0c --- /dev/null +++ b/Documentation/devicetree/bindings/pci/spacemit,k1-pcie-host.yaml @@ -0,0 +1,157 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pci/spacemit,k1-pcie-host.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SpacemiT K1 PCI Express Host Controller + +maintainers: + - Alex Elder + +description: > + The SpacemiT K1 SoC PCIe host controller is based on the Synopsys DesignWare + PCIe IP. The controller uses the DesignWare built-in MSI interrupt + controller, and supports 256 MSIs. + +allOf: + - $ref: /schemas/pci/snps,dw-pcie.yaml# + +properties: + compatible: + const: spacemit,k1-pcie + + reg: + items: + - description: DesignWare PCIe registers + - description: ATU address space + - description: PCIe configuration space + - description: Link control registers + + reg-names: + items: + - const: dbi + - const: atu + - const: config + - const: link + + clocks: + items: + - description: DWC PCIe Data Bus Interface (DBI) clock + - description: DWC PCIe application AXI-bus master interface clock + - description: DWC PCIe application AXI-bus slave interface clock + + clock-names: + items: + - const: dbi + - const: mstr + - const: slv + + resets: + items: + - description: DWC PCIe Data Bus Interface (DBI) reset + - description: DWC PCIe application AXI-bus master interface reset + - description: DWC PCIe application AXI-bus slave interface reset + + reset-names: + items: + - const: dbi + - const: mstr + - const: slv + + interrupts: + items: + - description: Interrupt used for MSIs + + interrupt-names: + const: msi + + spacemit,apmu: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: + A phandle that refers to the APMU system controller, whose regmap is + used in managing resets and link state, along with and offset of its + reset control register. + items: + - items: + - description: phandle to APMU system controller + - description: register offset + +patternProperties: + '^pcie@': + type: object + $ref: /schemas/pci/pci-pci-bridge.yaml# + + properties: + phys: + maxItems: 1 + + vpcie3v3-supply: + description: + A phandle for 3.3v regulator to use for PCIe + + required: + - phys + - vpcie3v3-supply + + unevaluatedProperties: false + +required: + - clocks + - clock-names + - resets + - reset-names + - interrupts + - interrupt-names + - spacemit,apmu + +unevaluatedProperties: false + +examples: + - | + #include + pcie@ca400000 { + device_type = "pci"; + compatible = "spacemit,k1-pcie"; + reg = <0xca400000 0x00001000>, + <0xca700000 0x0001ff24>, + <0x9f000000 0x00002000>, + <0xc0c20000 0x00001000>; + reg-names = "dbi", + "atu", + "config", + "link"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x9f002000 0x0 0x00100000>, + <0x02000000 0x0 0x90000000 0x90000000 0x0 0x0f000000>; + interrupts = <142>; + interrupt-names = "msi"; + clocks = <&syscon_apmu CLK_PCIE1_DBI>, + <&syscon_apmu CLK_PCIE1_MASTER>, + <&syscon_apmu CLK_PCIE1_SLAVE>; + clock-names = "dbi", + "mstr", + "slv"; + resets = <&syscon_apmu RESET_PCIE1_DBI>, + <&syscon_apmu RESET_PCIE1_MASTER>, + <&syscon_apmu RESET_PCIE1_SLAVE>; + reset-names = "dbi", + "mstr", + "slv"; + pinctrl-names = "default"; + pinctrl-0 = <&pcie1_3_cfg>; + spacemit,apmu = <&syscon_apmu 0x3d4>; + + pcie@0 { + device_type = "pci"; + compatible = "pciclass,0604"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + #address-cells = <3>; + #size-cells = <2>; + ranges; + phys = <&pcie1_phy>; + vpcie3v3-supply = <&pcie_vcc_3v3>; + }; + }; diff --git a/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml index 5f432452c815b..33c80626e8ec9 100644 --- a/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml @@ -16,7 +16,6 @@ properties: compatible: const: starfive,jh7110-pcie - reg: maxItems: 2 diff --git a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml new file mode 100644 index 0000000000000..fae4660647809 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml @@ -0,0 +1,179 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pci/toshiba,tc9563.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Toshiba TC9563 PCIe switch + +maintainers: + - Krishna Chaitanya Chundru + +description: | + Toshiba TC9563 PCIe switch has one upstream and three downstream ports. + The 3rd downstream port has integrated endpoint device of Ethernet MAC. + Other two downstream ports are supposed to connect to external device. + + The TC9563 PCIe switch can be configured through I2C interface before + PCIe link is established to change FTS, ASPM related entry delays, + tx amplitude etc for better power efficiency and functionality. + +properties: + compatible: + enum: + - pci1179,0623 + + reg: + maxItems: 1 + + resx-gpios: + maxItems: 1 + description: + GPIO controlling the RESX# pin. + + vdd18-supply: true + + vdd09-supply: true + + vddc-supply: true + + vddio1-supply: true + + vddio2-supply: true + + vddio18-supply: true + + i2c-parent: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: + A phandle to the parent I2C node and the slave address of the device + used to configure tc9563 to change FTS, tx amplitude etc. + items: + - description: Phandle to the I2C controller node + - description: I2C slave address + +patternProperties: + "^pcie@[1-3],0$": + description: + child nodes describing the internal downstream ports of + the tc9563 switch. + type: object + allOf: + - $ref: "#/$defs/tc9563-node" + - $ref: /schemas/pci/pci-pci-bridge.yaml# + unevaluatedProperties: false + +$defs: + tc9563-node: + type: object + + properties: + toshiba,tx-amplitude-microvolt: + description: + Change Tx Margin setting for low power consumption. + + toshiba,no-dfe-support: + type: boolean + description: + Disable DFE (Decision Feedback Equalizer), which mitigates + intersymbol interference and some reflections caused by + impedance mismatches. + +required: + - resx-gpios + - vdd18-supply + - vdd09-supply + - vddc-supply + - vddio1-supply + - vddio2-supply + - vddio18-supply + - i2c-parent + +allOf: + - $ref: "#/$defs/tc9563-node" + - $ref: /schemas/pci/pci-bus-common.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + + pcie { + #address-cells = <3>; + #size-cells = <2>; + + pcie@0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + bus-range = <0x01 0xff>; + + pcie@0,0 { + compatible = "pci1179,0623"; + + reg = <0x10000 0x0 0x0 0x0 0x0>; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + ranges; + bus-range = <0x02 0xff>; + + i2c-parent = <&qup_i2c 0x77>; + + vdd18-supply = <&vdd>; + vdd09-supply = <&vdd>; + vddc-supply = <&vdd>; + vddio1-supply = <&vdd>; + vddio2-supply = <&vdd>; + vddio18-supply = <&vdd>; + + resx-gpios = <&gpio 1 GPIO_ACTIVE_LOW>; + + pcie@1,0 { + compatible = "pciclass,0604"; + reg = <0x20800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x03 0xff>; + + toshiba,no-dfe-support; + }; + + pcie@2,0 { + compatible = "pciclass,0604"; + reg = <0x21000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x04 0xff>; + }; + + pcie@3,0 { + compatible = "pciclass,0604"; + reg = <0x21800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x05 0xff>; + + toshiba,tx-amplitude-microvolt = <10>; + + ethernet@0,0 { + reg = <0x50000 0x0 0x0 0x0 0x0>; + }; + + ethernet@0,1 { + reg = <0x50100 0x0 0x0 0x0 0x0>; + }; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pci/v3,v360epc-pci.yaml b/Documentation/devicetree/bindings/pci/v3,v360epc-pci.yaml index 38cac88f17bfd..0e2ac2f8faed3 100644 --- a/Documentation/devicetree/bindings/pci/v3,v360epc-pci.yaml +++ b/Documentation/devicetree/bindings/pci/v3,v360epc-pci.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: V3 Semiconductor V360 EPC PCI bridge maintainers: - - Linus Walleij + - Linus Walleij description: This bridge is found in the ARM Integrator/AP (Application Platform) diff --git a/Documentation/devicetree/bindings/pci/versatile.yaml b/Documentation/devicetree/bindings/pci/versatile.yaml index 294c7cd84b37f..d30b8849db91c 100644 --- a/Documentation/devicetree/bindings/pci/versatile.yaml +++ b/Documentation/devicetree/bindings/pci/versatile.yaml @@ -90,5 +90,4 @@ examples: <0x0000 0 0 4 &sic 28>; }; - ... diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml index f9cffbb2df07d..8a00a6c58edd4 100644 --- a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml @@ -27,11 +27,16 @@ properties: const: 0 clocks: - maxItems: 1 + minItems: 1 + items: + - description: PHY configuration clock + - description: Alternate PHY reference clock clock-names: + minItems: 1 items: - const: phy + - const: alt power-domains: maxItems: 1 diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml index b2218c1519391..ff5c77ef11765 100644 --- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml +++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml @@ -80,6 +80,7 @@ properties: - mediatek,mt2712-tphy - mediatek,mt6893-tphy - mediatek,mt7629-tphy + - mediatek,mt7981-tphy - mediatek,mt7986-tphy - mediatek,mt8183-tphy - mediatek,mt8186-tphy diff --git a/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml index 3e62b5d4da616..6e2edd43fc2ac 100644 --- a/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml +++ b/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml @@ -8,8 +8,9 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: MediaTek Universal Flash Storage (UFS) M-PHY maintainers: - - Stanley Chu - Chunfeng Yun + - Peter Wang + - Chaotian Jing description: | UFS M-PHY nodes are defined to describe on-chip UFS M-PHY hardware macro. diff --git a/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml b/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml index 0febd04a61f45..dd345cbd0a0b4 100644 --- a/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml @@ -67,8 +67,8 @@ properties: mode-gpios: description: Optional GPIOs for configuring alternate modes items: - - description: "mode selection GPIO #0" - - description: "mode selection GPIO #1" + - description: mode selection GPIO#0 + - description: mode selection GPIO#1 required: - compatible diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml index 119b4ff36dbd6..48bd11410e8c2 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml @@ -16,6 +16,7 @@ description: properties: compatible: enum: + - qcom,glymur-qmp-gen5x4-pcie-phy - qcom,qcs615-qmp-gen3x1-pcie-phy - qcom,qcs8300-qmp-gen4x2-pcie-phy - qcom,sa8775p-qmp-gen4x2-pcie-phy @@ -178,6 +179,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-gen5x4-pcie-phy - qcom,sa8775p-qmp-gen4x2-pcie-phy - qcom,sa8775p-qmp-gen4x4-pcie-phy - qcom,sc8280xp-qmp-gen3x1-pcie-phy @@ -213,17 +215,26 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-gen5x4-pcie-phy - qcom,sm8550-qmp-gen4x2-pcie-phy - qcom,sm8650-qmp-gen4x2-pcie-phy + - qcom,x1e80100-qmp-gen3x2-pcie-phy - qcom,x1e80100-qmp-gen4x2-pcie-phy - qcom,x1e80100-qmp-gen4x4-pcie-phy - qcom,x1e80100-qmp-gen4x8-pcie-phy + - qcom,x1p42100-qmp-gen4x4-pcie-phy then: properties: resets: minItems: 2 reset-names: minItems: 2 + else: + properties: + resets: + maxItems: 1 + reset-names: + maxItems: 1 - if: properties: diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml index a1b55168e0506..863a1a446739e 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml @@ -35,7 +35,6 @@ properties: - qcom,sm8350-qmp-usb3-uni-phy - qcom,x1e80100-qmp-usb3-uni-phy - reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml index c8bc512df08b5..e0ec45b96bf5d 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml @@ -78,10 +78,77 @@ properties: ports: $ref: /schemas/graph.yaml#/properties/ports + properties: port@0: - $ref: /schemas/graph.yaml#/properties/port + $ref: /schemas/graph.yaml#/$defs/port-base description: Output endpoint of the PHY + unevaluatedProperties: false + + properties: + endpoint: + $ref: /schemas/graph.yaml#/$defs/endpoint-base + unevaluatedProperties: false + + endpoint@0: + $ref: /schemas/graph.yaml#/$defs/endpoint-base + description: Display Port Output lanes of the PHY when used with static mapping, + The entry index is the DP lanes index, and the number is the PHY + signal in the order RX0, TX0, TX1, RX1. + unevaluatedProperties: false + + properties: + # Static lane mappings are mutually exclusive with typec-mux/orientation-mux + data-lanes: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 2 + maxItems: 4 + oneOf: + - items: # DisplayPort 1 lane, normal orientation + - const: 3 + - items: # DisplayPort 1 lane, flipped orientation + - const: 0 + - items: # DisplayPort 2 lanes, normal orientation + - const: 3 + - const: 2 + - items: # DisplayPort 2 lanes, flipped orientation + - const: 0 + - const: 1 + - items: # DisplayPort 4 lanes, normal orientation + - const: 3 + - const: 2 + - const: 1 + - const: 0 + - items: # DisplayPort 4 lanes, flipped orientation + - const: 0 + - const: 1 + - const: 2 + - const: 3 + required: + - data-lanes + + endpoint@1: + $ref: /schemas/graph.yaml#/$defs/endpoint-base + description: USB Output lanes of the PHY when used with static mapping. + The entry index is the USB3 lane in the order TX then RX, and the + number is the PHY signal in the order RX0, TX0, TX1, RX1. + unevaluatedProperties: false + + properties: + # Static lane mappings are mutually exclusive with typec-mux/orientation-mux + data-lanes: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 2 + oneOf: + - items: # USB3, normal orientation + - const: 1 + - const: 0 + - items: # USB3, flipped orientation + - const: 2 + - const: 3 + + required: + - data-lanes port@1: $ref: /schemas/graph.yaml#/properties/port diff --git a/Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml new file mode 100644 index 0000000000000..b86dc7a291a49 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/renesas,rzg3e-usb3-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/G3E USB 3.0 PHY + +maintainers: + - Biju Das + +properties: + compatible: + const: renesas,r9a09g047-usb3-phy + + reg: + maxItems: 1 + + clocks: + items: + - description: APB bus clock + - description: USB 2.0 PHY reference clock + - description: USB 3.0 PHY reference clock + + clock-names: + items: + - const: pclk + - const: core + - const: ref_alt_clk_p + + power-domains: + maxItems: 1 + + resets: + maxItems: 1 + + '#phy-cells': + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + - power-domains + - resets + - '#phy-cells' + +additionalProperties: false + +examples: + - | + #include + + usb-phy@15870000 { + compatible = "renesas,r9a09g047-usb3-phy"; + reg = <0x15870000 0x10000>; + clocks = <&cpg CPG_MOD 0xb0>, <&cpg CPG_CORE 13>, <&cpg CPG_CORE 12>; + clock-names = "pclk", "core", "ref_alt_clk_p"; + power-domains = <&cpg>; + resets = <&cpg 0xaa>; + #phy-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml index 179cb4bfc424c..2bbec8702a1e0 100644 --- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml @@ -118,6 +118,7 @@ allOf: contains: enum: - renesas,usb2-phy-r9a09g057 + - renesas,usb2-phy-r9a08g045 - renesas,rzg2l-usb2-phy then: properties: diff --git a/Documentation/devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml b/Documentation/devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml index 46e64fa293d50..83e7c825860cb 100644 --- a/Documentation/devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml +++ b/Documentation/devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml @@ -18,6 +18,7 @@ properties: - rockchip,px30-dsi-dphy - rockchip,rk3128-dsi-dphy - rockchip,rk3368-dsi-dphy + - rockchip,rk3506-dsi-dphy - rockchip,rk3568-dsi-dphy - rockchip,rv1126-dsi-dphy diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml index 138923ffedfee..c686d06f5f561 100644 --- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml +++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml @@ -23,16 +23,26 @@ properties: - enum: - ti,tcan1042 - ti,tcan1043 + - nxp,tja1048 + - nxp,tja1051 + - nxp,tja1057 - nxp,tjr1443 '#phy-cells': - const: 0 + enum: [0, 1] - standby-gpios: + silent-gpios: description: - gpio node to toggle standby signal on transceiver + gpio node to toggle silent signal on transceiver maxItems: 1 + standby-gpios: + description: + gpio node to toggle standby signal on transceiver. For two Items, item 1 + is for stbn1, item 2 is for stbn2. + minItems: 1 + maxItems: 2 + enable-gpios: description: gpio node to toggle enable signal on transceiver @@ -54,6 +64,59 @@ required: - compatible - '#phy-cells' +allOf: + - if: + properties: + compatible: + enum: + - nxp,tjr1443 + - ti,tcan1042 + - ti,tcan1043 + then: + properties: + '#phy-cells': + const: 0 + silent-gpios: false + standby-gpios: + maxItems: 1 + + - if: + properties: + compatible: + contains: + const: nxp,tja1048 + then: + properties: + '#phy-cells': + const: 1 + enable-gpios: false + silent-gpios: false + standby-gpios: + minItems: 2 + + - if: + properties: + compatible: + contains: + const: nxp,tja1051 + then: + properties: + '#phy-cells': + const: 0 + standby-gpios: false + + - if: + properties: + compatible: + contains: + const: nxp,tja1057 + then: + properties: + '#phy-cells': + const: 0 + enable-gpios: false + standby-gpios: false + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s700-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/actions,s700-pinctrl.txt deleted file mode 100644 index d13ff82f8518f..0000000000000 --- a/Documentation/devicetree/bindings/pinctrl/actions,s700-pinctrl.txt +++ /dev/null @@ -1,170 +0,0 @@ -Actions Semi S700 Pin Controller - -This binding describes the pin controller found in the S700 SoC. - -Required Properties: - -- compatible: Should be "actions,s700-pinctrl" -- reg: Should contain the register base address and size of - the pin controller. -- clocks: phandle of the clock feeding the pin controller -- gpio-controller: Marks the device node as a GPIO controller. -- gpio-ranges: Specifies the mapping between gpio controller and - pin-controller pins. -- #gpio-cells: Should be two. The first cell is the gpio pin number - and the second cell is used for optional parameters. -- interrupt-controller: Marks the device node as an interrupt controller. -- #interrupt-cells: Specifies the number of cells needed to encode an - interrupt. Shall be set to 2. The first cell - defines the interrupt number, the second encodes - the trigger flags described in - bindings/interrupt-controller/interrupts.txt -- interrupts: The interrupt outputs from the controller. There is one GPIO - interrupt per GPIO bank. The number of interrupts listed depends - on the number of GPIO banks on the SoC. The interrupts must be - ordered by bank, starting with bank 0. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning of the -phrase "pin configuration node". - -The pin configuration nodes act as a container for an arbitrary number of -subnodes. Each of these subnodes represents some desired configuration for a -pin, a group, or a list of pins or groups. This configuration can include the -mux function to select on those group(s), and various pin configuration -parameters, such as pull-up, drive strength, etc. - -PIN CONFIGURATION NODES: - -The name of each subnode is not important; all subnodes should be enumerated -and processed purely based on their content. - -Each subnode only affects those parameters that are explicitly listed. In -other words, a subnode that lists a mux function but no pin configuration -parameters implies no information about any pin configuration parameters. -Similarly, a pin subnode that describes a pullup parameter implies no -information about e.g. the mux function. - -Pinmux functions are available only for the pin groups while pinconf -parameters are available for both pin groups and individual pins. - -The following generic properties as defined in pinctrl-bindings.txt are valid -to specify in a pin configuration subnode: - -Required Properties: - -- pins: An array of strings, each string containing the name of a pin. - These pins are used for selecting the pull control and schmitt - trigger parameters. The following are the list of pins - available: - - eth_txd0, eth_txd1, eth_txd2, eth_txd3, eth_txen, eth_rxer, - eth_crs_dv, eth_rxd1, eth_rxd0, eth_rxd2, eth_rxd3, eth_ref_clk, - eth_mdc, eth_mdio, sirq0, sirq1, sirq2, i2s_d0, i2s_bclk0, - i2s_lrclk0, i2s_mclk0, i2s_d1, i2s_bclk1, i2s_lrclk1, i2s_mclk1, - pcm1_in, pcm1_clk, pcm1_sync, pcm1_out, ks_in0, ks_in1, ks_in2, - ks_in3, ks_out0, ks_out1, ks_out2, lvds_oep, lvds_oen, lvds_odp, - lvds_odn, lvds_ocp, lvds_ocn, lvds_obp, lvds_obn, lvds_oap, - lvds_oan, lvds_eep, lvds_een, lvds_edp, lvds_edn, lvds_ecp, - lvds_ecn, lvds_ebp, lvds_ebn, lvds_eap, lvds_ean, lcd0_d18, - lcd0_d2, dsi_dp3, dsi_dn3, dsi_dp1, dsi_dn1, dsi_cp, dsi_cn, - dsi_dp0, dsi_dn0, dsi_dp2, dsi_dn2, sd0_d0, sd0_d1, sd0_d2, - sd0_d3, sd1_d0, sd1_d1, sd1_d2, sd1_d3, sd0_cmd, sd0_clk, - sd1_cmd, sd1_clk, spi0_ss, spi0_miso, uart0_rx, uart0_tx, - uart2_rx, uart2_tx, uart2_rtsb, uart2_ctsb, uart3_rx, uart3_tx, - uart3_rtsb, uart3_ctsb, i2c0_sclk, i2c0_sdata, i2c1_sclk, - i2c1_sdata, i2c2_sdata, csi_dn0, csi_dp0, csi_dn1, csi_dp1, - csi_cn, csi_cp, csi_dn2, csi_dp2, csi_dn3, csi_dp3, - sensor0_pclk, sensor0_ckout, dnand_d0, dnand_d1, dnand_d2, - dnand_d3, dnand_d4, dnand_d5, dnand_d6, dnand_d7, dnand_wrb, - dnand_rdb, dnand_rdbn, dnand_dqs, dnand_dqsn, dnand_rb0, - dnand_ale, dnand_cle, dnand_ceb0, dnand_ceb1, dnand_ceb2, - dnand_ceb3, porb, clko_25m, bsel, pkg0, pkg1, pkg2, pkg3 - -- groups: An array of strings, each string containing the name of a pin - group. These pin groups are used for selecting the pinmux - functions. - rgmii_txd23_mfp, rgmii_rxd2_mfp, rgmii_rxd3_mfp, lcd0_d18_mfp, - rgmii_txd01_mfp, rgmii_txd0_mfp, rgmii_txd1_mfp, rgmii_txen_mfp, - rgmii_rxen_mfp, rgmii_rxd1_mfp, rgmii_rxd0_mfp, rgmii_ref_clk_mfp, - i2s_d0_mfp, i2s_pcm1_mfp, i2s0_pcm0_mfp, i2s1_pcm0_mfp, - i2s_d1_mfp, ks_in2_mfp, ks_in1_mfp, ks_in0_mfp, ks_in3_mfp, - ks_out0_mfp, ks_out1_mfp, ks_out2_mfp, lvds_o_pn_mfp, dsi_dn0_mfp, - dsi_dp2_mfp, lcd0_d2_mfp, dsi_dp3_mfp, dsi_dn3_mfp, dsi_dp0_mfp, - lvds_ee_pn_mfp, uart2_rx_tx_mfp, spi0_i2c_pcm_mfp, dsi_dnp1_cp_d2_mfp, - dsi_dnp1_cp_d17_mfp, lvds_e_pn_mfp, dsi_dn2_mfp, uart2_rtsb_mfp, - uart2_ctsb_mfp, uart3_rtsb_mfp, uart3_ctsb_mfp, sd0_d0_mfp, sd0_d1_mfp, - sd0_d2_d3_mfp, sd1_d0_d3_mfp, sd0_cmd_mfp, sd0_clk_mfp, sd1_cmd_mfp, - uart0_rx_mfp, clko_25m_mfp, csi_cn_cp_mfp, sens0_ckout_mfp, uart0_tx_mfp, - i2c0_mfp, csi_dn_dp_mfp, sen0_pclk_mfp, pcm1_in_mfp, pcm1_clk_mfp, - pcm1_sync_mfp, pcm1_out_mfp, dnand_data_wr_mfp, dnand_acle_ce0_mfp, - nand_ceb2_mfp, nand_ceb3_mfp - - These pin groups are used for selecting the drive strength - parameters. - - sirq_drv, rgmii_txd23_drv, rgmii_rxd23_drv, rgmii_txd01_txen_drv, - rgmii_rxer_drv, rgmii_crs_drv, rgmii_rxd10_drv, rgmii_ref_clk_drv, - smi_mdc_mdio_drv, i2s_d0_drv, i2s_bclk0_drv, i2s3_drv, i2s13_drv, - pcm1_drv, ks_in_drv, ks_out_drv, lvds_all_drv, lcd_d18_d2_drv, - dsi_all_drv, sd0_d0_d3_drv, sd0_cmd_drv, sd0_clk_drv, spi0_all_drv, - uart0_rx_drv, uart0_tx_drv, uart2_all_drv, i2c0_all_drv, i2c12_all_drv, - sens0_pclk_drv, sens0_ckout_drv, uart3_all_drv - -- function: An array of strings, each string containing the name of the - pinmux functions. These functions can only be selected by - the corresponding pin groups. The following are the list of - pinmux functions available: - - nor, eth_rgmii, eth_sgmii, spi0, spi1, spi2, spi3, seNs0, sens1, - uart0, uart1, uart2, uart3, uart4, uart5, uart6, i2s0, i2s1, - pcm1, pcm0, ks, jtag, pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, p0, - sd0, sd1, sd2, i2c0, i2c1, i2c2, i2c3, dsi, lvds, usb30, - clko_25m, mipi_csi, nand, spdif, sirq0, sirq1, sirq2, bt, lcd0 - -Optional Properties: - -- bias-pull-down: No arguments. The specified pins should be configured as - pull down. -- bias-pull-up: No arguments. The specified pins should be configured as - pull up. -- input-schmitt-enable: No arguments: Enable schmitt trigger for the specified - pins -- input-schmitt-disable: No arguments: Disable schmitt trigger for the specified - pins -- drive-strength: Integer. Selects the drive strength for the specified - pins in mA. - Valid values are: - <2> - <4> - <8> - <12> - -Example: - - pinctrl: pinctrl@e01b0000 { - compatible = "actions,s700-pinctrl"; - reg = <0x0 0xe01b0000 0x0 0x1000>; - clocks = <&cmu CLK_GPIO>; - gpio-controller; - gpio-ranges = <&pinctrl 0 0 136>; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = , - , - , - , - ; - - uart3-default: uart3-default { - pinmux { - groups = "uart3_rtsb_mfp", "uart3_ctsb_mfp"; - function = "uart3"; - }; - pinconf { - groups = "uart3_all_drv"; - drive-strength = <2>; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s700-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/actions,s700-pinctrl.yaml new file mode 100644 index 0000000000000..9597b983c332e --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/actions,s700-pinctrl.yaml @@ -0,0 +1,204 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/actions,s700-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Actions Semi S700 Pin Controller + +maintainers: + - Manivannan Sadhasivam + +properties: + compatible: + const: actions,s700-pinctrl + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + gpio-controller: true + + gpio-line-names: + maxItems: 136 + + gpio-ranges: true + + '#gpio-cells': + const: 2 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + + interrupts: + maxItems: 5 + description: + The interrupt outputs from the controller. There is one GPIO interrupt per + GPIO bank. The interrupts must be ordered by bank, starting with + bank 0. + +additionalProperties: + type: object + description: Pin configuration subnode + additionalProperties: false + + properties: + pinmux: + description: Configure pin multiplexing. + type: object + $ref: /schemas/pinctrl/pinmux-node.yaml# + additionalProperties: false + + properties: + groups: + items: + enum: [ + rgmii_txd23_mfp, rgmii_rxd2_mfp, rgmii_rxd3_mfp, lcd0_d18_mfp, + rgmii_txd01_mfp, rgmii_txd0_mfp, rgmii_txd1_mfp, rgmii_txen_mfp, + rgmii_rxen_mfp, rgmii_rxd1_mfp, rgmii_rxd0_mfp, rgmii_ref_clk_mfp, + i2c1_dummy, i2c2_dummy, i2s_d0_mfp, i2s_pcm1_mfp, i2s0_pcm0_mfp, i2s1_pcm0_mfp, + i2s_d1_mfp, ks_in2_mfp, ks_in1_mfp, ks_in0_mfp, ks_in3_mfp, + ks_out0_mfp, ks_out1_mfp, ks_out2_mfp, lvds_o_pn_mfp, dsi_dn0_mfp, + dsi_dp2_mfp, lcd0_d2_mfp, dsi_dp3_mfp, dsi_dn3_mfp, dsi_dp0_mfp, + lvds_ee_pn_mfp, uart2_rx_tx_mfp, spi0_i2c_pcm_mfp, + dsi_dnp1_cp_d2_mfp, dsi_dnp1_cp_d17_mfp, lvds_e_pn_mfp, + dsi_dn2_mfp, uart2_rtsb_mfp, uart2_ctsb_mfp, uart3_rtsb_mfp, + uart3_ctsb_mfp, sd0_d0_mfp, sd0_d1_mfp, sd0_d2_d3_mfp, + sd1_d0_d3_mfp, sd0_cmd_mfp, sd0_clk_mfp, sd1_cmd_mfp, + uart0_rx_mfp, clko_25m_mfp, csi_cn_cp_mfp, sens0_ckout_mfp, + uart0_tx_mfp, i2c0_mfp, csi_dn_dp_mfp, sen0_pclk_mfp, pcm1_in_mfp, + pcm1_clk_mfp, pcm1_sync_mfp, pcm1_out_mfp, dnand_data_wr_mfp, + dnand_acle_ce0_mfp, nand_ceb2_mfp, nand_ceb3_mfp + ] + + function: + items: + enum: [ + nor, eth_rgmii, eth_sgmii, spi0, spi1, spi2, spi3, seNs0, sens1, + uart0, uart1, uart2, uart3, uart4, uart5, uart6, i2s0, i2s1, pcm1, + pcm0, ks, jtag, pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, p0, sd0, sd1, + sd2, i2c0, i2c1, i2c2, i2c3, dsi, lvds, usb30, clko_25m, mipi_csi, + nand, spdif, sirq0, sirq1, sirq2, bt, lcd0 + ] + + required: + - groups + - function + + pinconf: + description: Configure pin-specific parameters. + type: object + allOf: + - $ref: /schemas/pinctrl/pincfg-node.yaml# + - $ref: /schemas/pinctrl/pinmux-node.yaml# + additionalProperties: false + + properties: + groups: + items: + enum: [ + sirq_drv, rgmii_txd23_drv, rgmii_rxd23_drv, rgmii_txd01_txen_drv, + rgmii_rxer_drv, rgmii_crs_drv, rgmii_rxd10_drv, rgmii_ref_clk_drv, + smi_mdc_mdio_drv, i2s_d0_drv, i2s_bclk0_drv, i2s3_drv, i2s13_drv, + pcm1_drv, ks_in_drv, ks_out_drv, lvds_all_drv, lcd_d18_d2_drv, + dsi_all_drv, sd0_d0_d3_drv, sd0_cmd_drv, sd0_clk_drv, + spi0_all_drv, uart0_rx_drv, uart0_tx_drv, uart2_all_drv, + i2c0_all_drv, i2c12_all_drv, sens0_pclk_drv, sens0_ckout_drv, + uart3_all_drv + ] + + pins: + items: + enum: [ + eth_txd0, eth_txd1, eth_txd2, eth_txd3, eth_txen, eth_rxer, + eth_crs_dv, eth_rxd1, eth_rxd0, eth_rxd2, eth_rxd3, eth_ref_clk, + eth_mdc, eth_mdio, sirq0, sirq1, sirq2, i2s_d0, i2s_bclk0, + i2s_lrclk0, i2s_mclk0, i2s_d1, i2s_bclk1, i2s_lrclk1, i2s_mclk1, + pcm1_in, pcm1_clk, pcm1_sync, pcm1_out, ks_in0, ks_in1, ks_in2, + ks_in3, ks_out0, ks_out1, ks_out2, lvds_oep, lvds_oen, lvds_odp, + lvds_odn, lvds_ocp, lvds_ocn, lvds_obp, lvds_obn, lvds_oap, + lvds_oan, lvds_eep, lvds_een, lvds_edp, lvds_edn, lvds_ecp, + lvds_ecn, lvds_ebp, lvds_ebn, lvds_eap, lvds_ean, lcd0_d18, + lcd0_d2, dsi_dp3, dsi_dn3, dsi_dp1, dsi_dn1, dsi_cp, dsi_cn, + dsi_dp0, dsi_dn0, dsi_dp2, dsi_dn2, sd0_d0, sd0_d1, sd0_d2, + sd0_d3, sd1_d0, sd1_d1, sd1_d2, sd1_d3, sd0_cmd, sd0_clk, sd1_cmd, + sd1_clk, spi0_ss, spi0_miso, uart0_rx, uart0_tx, uart2_rx, + uart2_tx, uart2_rtsb, uart2_ctsb, uart3_rx, uart3_tx, uart3_rtsb, + uart3_ctsb, i2c0_sclk, i2c0_sdata, i2c1_sclk, i2c1_sdata, + i2c2_sclk, i2c2_sdata, csi_dn0, csi_dp0, csi_dn1, csi_dp1, csi_cn, csi_cp, + csi_dn2, csi_dp2, csi_dn3, csi_dp3, sensor0_pclk, sensor0_ckout, + dnand_d0, dnand_d1, dnand_d2, dnand_d3, dnand_d4, dnand_d5, + dnand_d6, dnand_d7, dnand_wrb, dnand_rdb, dnand_rdbn, dnand_dqs, + dnand_dqsn, dnand_rb0, dnand_ale, dnand_cle, dnand_ceb0, + dnand_ceb1, dnand_ceb2, dnand_ceb3, porb, clko_25m, bsel, pkg0, + pkg1, pkg2, pkg3 + ] + + bias-pull-down: + type: boolean + + bias-pull-up: + type: boolean + + drive-strength: + description: Selects the drive strength for the specified pins in mA. + enum: [2, 4, 8, 12] + + input-schmitt-enable: true + input-schmitt-disable: true + + oneOf: + - required: + - groups + - required: + - pins + + anyOf: + - required: [ pinmux ] + - required: [ pinconf ] + +required: + - compatible + - reg + - clocks + - gpio-controller + - gpio-ranges + - '#gpio-cells' + - interrupt-controller + - '#interrupt-cells' + - interrupts + +examples: + - | + #include + + pinctrl: pinctrl@e01b0000 { + compatible = "actions,s700-pinctrl"; + reg = <0xe01b0000 0x1000>; + clocks = <&cmu 1>; + gpio-controller; + gpio-ranges = <&pinctrl 0 0 136>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = , + , + , + , + ; + + uart3-default { + pinmux { + groups = "uart3_rtsb_mfp", "uart3_ctsb_mfp"; + function = "uart3"; + }; + pinconf { + groups = "uart3_all_drv"; + drive-strength = <2>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt deleted file mode 100644 index 81b58dddd3edc..0000000000000 --- a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt +++ /dev/null @@ -1,204 +0,0 @@ -Actions Semi S900 Pin Controller - -This binding describes the pin controller found in the S900 SoC. - -Required Properties: - -- compatible: Should be "actions,s900-pinctrl" -- reg: Should contain the register base address and size of - the pin controller. -- clocks: phandle of the clock feeding the pin controller -- gpio-controller: Marks the device node as a GPIO controller. -- gpio-ranges: Specifies the mapping between gpio controller and - pin-controller pins. -- #gpio-cells: Should be two. The first cell is the gpio pin number - and the second cell is used for optional parameters. -- interrupt-controller: Marks the device node as an interrupt controller. -- #interrupt-cells: Specifies the number of cells needed to encode an - interrupt. Shall be set to 2. The first cell - defines the interrupt number, the second encodes - the trigger flags described in - bindings/interrupt-controller/interrupts.txt -- interrupts: The interrupt outputs from the controller. There is one GPIO - interrupt per GPIO bank. The number of interrupts listed depends - on the number of GPIO banks on the SoC. The interrupts must be - ordered by bank, starting with bank 0. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning of the -phrase "pin configuration node". - -The pin configuration nodes act as a container for an arbitrary number of -subnodes. Each of these subnodes represents some desired configuration for a -pin, a group, or a list of pins or groups. This configuration can include the -mux function to select on those group(s), and various pin configuration -parameters, such as pull-up, drive strength, etc. - -PIN CONFIGURATION NODES: - -The name of each subnode is not important; all subnodes should be enumerated -and processed purely based on their content. - -Each subnode only affects those parameters that are explicitly listed. In -other words, a subnode that lists a mux function but no pin configuration -parameters implies no information about any pin configuration parameters. -Similarly, a pin subnode that describes a pullup parameter implies no -information about e.g. the mux function. - -Pinmux functions are available only for the pin groups while pinconf -parameters are available for both pin groups and individual pins. - -The following generic properties as defined in pinctrl-bindings.txt are valid -to specify in a pin configuration subnode: - -Required Properties: - -- pins: An array of strings, each string containing the name of a pin. - These pins are used for selecting the pull control and schmitt - trigger parameters. The following are the list of pins - available: - - eth_txd0, eth_txd1, eth_txen, eth_rxer, eth_crs_dv, - eth_rxd1, eth_rxd0, eth_ref_clk, eth_mdc, eth_mdio, - sirq0, sirq1, sirq2, i2s_d0, i2s_bclk0, i2s_lrclk0, - i2s_mclk0, i2s_d1, i2s_bclk1, i2s_lrclk1, i2s_mclk1, - pcm1_in, pcm1_clk, pcm1_sync, pcm1_out, eram_a5, - eram_a6, eram_a7, eram_a8, eram_a9, eram_a10, eram_a11, - lvds_oep, lvds_oen, lvds_odp, lvds_odn, lvds_ocp, - lvds_ocn, lvds_obp, lvds_obn, lvds_oap, lvds_oan, - lvds_eep, lvds_een, lvds_edp, lvds_edn, lvds_ecp, - lvds_ecn, lvds_ebp, lvds_ebn, lvds_eap, lvds_ean, - sd0_d0, sd0_d1, sd0_d2, sd0_d3, sd1_d0, sd1_d1, - sd1_d2, sd1_d3, sd0_cmd, sd0_clk, sd1_cmd, sd1_clk, - spi0_sclk, spi0_ss, spi0_miso, spi0_mosi, uart0_rx, - uart0_tx, uart2_rx, uart2_tx, uart2_rtsb, uart2_ctsb, - uart3_rx, uart3_tx, uart3_rtsb, uart3_ctsb, uart4_rx, - uart4_tx, i2c0_sclk, i2c0_sdata, i2c1_sclk, i2c1_sdata, - i2c2_sclk, i2c2_sdata, csi0_dn0, csi0_dp0, csi0_dn1, - csi0_dp1, csi0_cn, csi0_cp, csi0_dn2, csi0_dp2, csi0_dn3, - csi0_dp3, dsi_dp3, dsi_dn3, dsi_dp1, dsi_dn1, dsi_cp, - dsi_cn, dsi_dp0, dsi_dn0, dsi_dp2, dsi_dn2, sensor0_pclk, - csi1_dn0,csi1_dp0,csi1_dn1, csi1_dp1, csi1_cn, csi1_cp, - sensor0_ckout, nand0_d0, nand0_d1, nand0_d2, nand0_d3, - nand0_d4, nand0_d5, nand0_d6, nand0_d7, nand0_dqs, - nand0_dqsn, nand0_ale, nand0_cle, nand0_ceb0, nand0_ceb1, - nand0_ceb2, nand0_ceb3, nand1_d0, nand1_d1, nand1_d2, - nand1_d3, nand1_d4, nand1_d5, nand1_d6, nand1_d7, nand1_dqs, - nand1_dqsn, nand1_ale, nand1_cle, nand1_ceb0, nand1_ceb1, - nand1_ceb2, nand1_ceb3, sgpio0, sgpio1, sgpio2, sgpio3 - -- groups: An array of strings, each string containing the name of a pin - group. These pin groups are used for selecting the pinmux - functions. - - lvds_oxx_uart4_mfp, rmii_mdc_mfp, rmii_mdio_mfp, sirq0_mfp, - sirq1_mfp, rmii_txd0_mfp, rmii_txd1_mfp, rmii_txen_mfp, - rmii_rxer_mfp, rmii_crs_dv_mfp, rmii_rxd1_mfp, rmii_rxd0_mfp, - rmii_ref_clk_mfp, i2s_d0_mfp, i2s_d1_mfp, i2s_lr_m_clk0_mfp, - i2s_bclk0_mfp, i2s_bclk1_mclk1_mfp, pcm1_in_out_mfp, - pcm1_clk_mfp, pcm1_sync_mfp, eram_a5_mfp, eram_a6_mfp, - eram_a7_mfp, eram_a8_mfp, eram_a9_mfp, eram_a10_mfp, - eram_a11_mfp, lvds_oep_odn_mfp, lvds_ocp_obn_mfp, - lvds_oap_oan_mfp, lvds_e_mfp, spi0_sclk_mosi_mfp, spi0_ss_mfp, - spi0_miso_mfp, uart2_rtsb_mfp, uart2_ctsb_mfp, uart3_rtsb_mfp, - uart3_ctsb_mfp, sd0_d0_mfp, sd0_d1_mfp, sd0_d2_d3_mfp, - sd1_d0_d3_mfp, sd0_cmd_mfp, sd0_clk_mfp, sd1_cmd_clk_mfp, - uart0_rx_mfp, nand0_d0_ceb3_mfp, uart0_tx_mfp, i2c0_mfp, - csi0_cn_cp_mfp, csi0_dn0_dp3_mfp, csi1_dn0_cp_mfp, - dsi_dp3_dn1_mfp, dsi_cp_dn0_mfp, dsi_dp2_dn2_mfp, - nand1_d0_ceb1_mfp, nand1_ceb3_mfp, nand1_ceb0_mfp, - csi1_dn0_dp0_mfp, uart4_rx_tx_mfp - - - These pin groups are used for selecting the drive strength - parameters. - - sgpio3_drv, sgpio2_drv, sgpio1_drv, sgpio0_drv, - rmii_tx_d0_d1_drv, rmii_txen_rxer_drv, rmii_crs_dv_drv, - rmii_rx_d1_d0_drv, rmii_ref_clk_drv, rmii_mdc_mdio_drv, - sirq_0_1_drv, sirq2_drv, i2s_d0_d1_drv, i2s_lr_m_clk0_drv, - i2s_blk1_mclk1_drv, pcm1_in_out_drv, lvds_oap_oan_drv, - lvds_oep_odn_drv, lvds_ocp_obn_drv, lvds_e_drv, sd0_d3_d0_drv, - sd1_d3_d0_drv, sd0_sd1_cmd_clk_drv, spi0_sclk_mosi_drv, - spi0_ss_miso_drv, uart0_rx_tx_drv, uart4_rx_tx_drv, uart2_drv, - uart3_drv, i2c0_drv, i2c1_drv, i2c2_drv, sensor0_drv - - These pin groups are used for selecting the slew rate - parameters. - - sgpio3_sr, sgpio2_sr, sgpio1_sr, sgpio0_sr, rmii_tx_d0_d1_sr, - rmii_txen_rxer_sr, rmii_crs_dv_sr, rmii_rx_d1_d0_sr, - rmii_ref_clk_sr, rmii_mdc_mdio_sr, sirq_0_1_sr, sirq2_sr, - i2s_do_d1_sr, i2s_lr_m_clk0_sr, i2s_bclk0_mclk1_sr, - pcm1_in_out_sr, sd1_d3_d0_sr, sd0_sd1_clk_cmd_sr, - spi0_sclk_mosi_sr, spi0_ss_miso_sr, uart0_rx_tx_sr, - uart4_rx_tx_sr, uart2_sr, uart3_sr, i2c0_sr, i2c1_sr, i2c2_sr, - sensor0_sr - -- function: An array of strings, each string containing the name of the - pinmux functions. These functions can only be selected by - the corresponding pin groups. The following are the list of - pinmux functions available: - - eram, eth_rmii, eth_smii, spi0, spi1, spi2, spi3, sens0, - uart0, uart1, uart2, uart3, uart4, uart5, uart6, i2s0, i2s1, - pcm0, pcm1, jtag, pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, sd0, - sd1, sd2, sd3, i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, lvds, - usb30, usb20, gpu, mipi_csi0, mipi_csi1, mipi_dsi, nand0, - nand1, spdif, sirq0, sirq1, sirq2 - -Optional Properties: - -- bias-bus-hold: No arguments. The specified pins should retain the previous - state value. -- bias-high-impedance: No arguments. The specified pins should be configured - as high impedance. -- bias-pull-down: No arguments. The specified pins should be configured as - pull down. -- bias-pull-up: No arguments. The specified pins should be configured as - pull up. -- input-schmitt-enable: No arguments: Enable schmitt trigger for the specified - pins -- input-schmitt-disable: No arguments: Disable schmitt trigger for the specified - pins -- slew-rate: Integer. Sets slew rate for the specified pins. - Valid values are: - <0> - Slow - <1> - Fast -- drive-strength: Integer. Selects the drive strength for the specified - pins in mA. - Valid values are: - <2> - <4> - <8> - <12> - -Example: - - pinctrl: pinctrl@e01b0000 { - compatible = "actions,s900-pinctrl"; - reg = <0x0 0xe01b0000 0x0 0x1000>; - clocks = <&cmu CLK_GPIO>; - gpio-controller; - gpio-ranges = <&pinctrl 0 0 146>; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = , - , - , - , - , - ; - - uart2-default: uart2-default { - pinmux { - groups = "lvds_oep_odn_mfp"; - function = "uart2"; - }; - pinconf { - groups = "lvds_oep_odn_drv"; - drive-strength = <12>; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.yaml new file mode 100644 index 0000000000000..5c7b9f13226d0 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.yaml @@ -0,0 +1,219 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/actions,s900-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Actions Semi S900 Pin Controller + +maintainers: + - Manivannan Sadhasivam + +properties: + compatible: + const: actions,s900-pinctrl + + reg: + maxItems: 1 + + interrupts: + maxItems: 6 + description: The interrupt outputs from the controller. There is one GPIO + interrupt per GPIO bank. The number of interrupts listed depends on the + number of GPIO banks on the SoC. The interrupts must be ordered by bank, + starting with bank 0. + + interrupt-controller: true + + "#interrupt-cells": + const: 2 + + clocks: + maxItems: 1 + + gpio-controller: true + + gpio-line-names: + maxItems: 146 + + gpio-ranges: true + + "#gpio-cells": + const: 2 + +required: + - compatible + - reg + - interrupts + - interrupt-controller + - "#interrupt-cells" + - clocks + - gpio-controller + - gpio-ranges + - "#gpio-cells" + +additionalProperties: + type: object + description: Pin configuration subnode + additionalProperties: false + + properties: + pinmux: + type: object + description: Pin mux configuration + $ref: /schemas/pinctrl/pinmux-node.yaml# + additionalProperties: false + + properties: + groups: + items: + enum: [ + lvds_oxx_uart4_mfp, rmii_mdc_mfp, rmii_mdio_mfp, sirq0_mfp, + sirq1_mfp, rmii_txd0_mfp, rmii_txd1_mfp, rmii_txen_mfp, + rmii_rxer_mfp, rmii_crs_dv_mfp, rmii_rxd1_mfp, rmii_rxd0_mfp, + rmii_ref_clk_mfp, i2s_d0_mfp, i2s_d1_mfp, i2s_lr_m_clk0_mfp, + i2s_bclk0_mfp, i2s_bclk1_mclk1_mfp, pcm1_in_out_mfp, pcm1_clk_mfp, + pcm1_sync_mfp, eram_a5_mfp, eram_a6_mfp, eram_a7_mfp, eram_a8_mfp, + eram_a9_mfp, eram_a10_mfp, eram_a11_mfp, lvds_oep_odn_mfp, + lvds_ocp_obn_mfp, lvds_oap_oan_mfp, lvds_e_mfp, + spi0_sclk_mosi_mfp, spi0_ss_mfp, spi0_miso_mfp, uart2_rtsb_mfp, + uart2_ctsb_mfp, uart3_rtsb_mfp, uart3_ctsb_mfp, sd0_d0_mfp, + sd0_d1_mfp, sd0_d2_d3_mfp, sd1_d0_d3_mfp, sd0_cmd_mfp, + sd0_clk_mfp, sd1_cmd_clk_mfp, uart0_rx_mfp, nand0_d0_ceb3_mfp, + uart0_tx_mfp, i2c0_mfp, csi0_cn_cp_mfp, csi0_dn0_dp3_mfp, + csi1_dn0_cp_mfp, dsi_dp3_dn1_mfp, dsi_cp_dn0_mfp, dsi_dp2_dn2_mfp, + nand1_d0_ceb1_mfp, nand1_ceb3_mfp, nand1_ceb0_mfp, + csi1_dn0_dp0_mfp, uart4_rx_tx_mfp + ] + + function: + items: + enum: [ + eram, eth_rmii, eth_smii, spi0, spi1, spi2, spi3, sens0, + uart0, uart1, uart2, uart3, uart4, uart5, uart6, i2s0, i2s1, + pcm0, pcm1, jtag, pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, sd0, + sd1, sd2, sd3, i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, lvds, + usb30, usb20, gpu, mipi_csi0, mipi_csi1, mipi_dsi, nand0, + nand1, spdif, sirq0, sirq1, sirq2 + ] + + required: + - groups + - function + + pinconf: + type: object + description: Pin configuration parameters + allOf: + - $ref: /schemas/pinctrl/pincfg-node.yaml# + - $ref: /schemas/pinctrl/pinmux-node.yaml# + + additionalProperties: false + + properties: + groups: + items: + enum: [ + # pin groups for drive strength + sgpio3_drv, sgpio2_drv, sgpio1_drv, sgpio0_drv, rmii_tx_d0_d1_drv, + rmii_txen_rxer_drv, rmii_crs_dv_drv, rmii_rx_d1_d0_drv, + rmii_ref_clk_drv, rmii_mdc_mdio_drv, sirq_0_1_drv, sirq2_drv, + i2s_d0_d1_drv, i2s_lr_m_clk0_drv, i2s_blk1_mclk1_drv, + pcm1_in_out_drv, lvds_oap_oan_drv, lvds_oep_odn_drv, + lvds_ocp_obn_drv, lvds_e_drv, sd0_d3_d0_drv, sd1_d3_d0_drv, + sd0_sd1_cmd_clk_drv, spi0_sclk_mosi_drv, spi0_ss_miso_drv, + uart0_rx_tx_drv, uart4_rx_tx_drv, uart2_drv, uart3_drv, i2c0_drv, + i2c1_drv, i2c2_drv, sensor0_drv, + # pin groups for slew rate + sgpio3_sr, sgpio2_sr, sgpio1_sr, sgpio0_sr, rmii_tx_d0_d1_sr, + rmii_txen_rxer_sr, rmii_crs_dv_sr, rmii_rx_d1_d0_sr, + rmii_ref_clk_sr, rmii_mdc_mdio_sr, sirq_0_1_sr, sirq2_sr, + i2s_do_d1_sr, i2s_lr_m_clk0_sr, i2s_bclk0_mclk1_sr, + pcm1_in_out_sr, sd1_d3_d0_sr, sd0_sd1_clk_cmd_sr, + spi0_sclk_mosi_sr, spi0_ss_miso_sr, uart0_rx_tx_sr, + uart4_rx_tx_sr, uart2_sr, uart3_sr, i2c0_sr, i2c1_sr, i2c2_sr, + sensor0_sr + ] + + pins: + items: + enum: [ + eth_txd0, eth_txd1, eth_txen, eth_rxer, eth_crs_dv, eth_rxd1, + eth_rxd0, eth_ref_clk, eth_mdc, eth_mdio, sirq0, sirq1, sirq2, + i2s_d0, i2s_bclk0, i2s_lrclk0, i2s_mclk0, i2s_d1, i2s_bclk1, + i2s_lrclk1, i2s_mclk1, pcm1_in, pcm1_clk, pcm1_sync, pcm1_out, + eram_a5, eram_a6, eram_a7, eram_a8, eram_a9, eram_a10, eram_a11, + lvds_oep, lvds_oen, lvds_odp, lvds_odn, lvds_ocp, lvds_ocn, + lvds_obp, lvds_obn, lvds_oap, lvds_oan, lvds_eep, lvds_een, + lvds_edp, lvds_edn, lvds_ecp, lvds_ecn, lvds_ebp, lvds_ebn, + lvds_eap, lvds_ean, sd0_d0, sd0_d1, sd0_d2, sd0_d3, sd1_d0, + sd1_d1, sd1_d2, sd1_d3, sd0_cmd, sd0_clk, sd1_cmd, sd1_clk, + spi0_sclk, spi0_ss, spi0_miso, spi0_mosi, uart0_rx, uart0_tx, + uart2_rx, uart2_tx, uart2_rtsb, uart2_ctsb, uart3_rx, uart3_tx, + uart3_rtsb, uart3_ctsb, uart4_rx, uart4_tx, i2c0_sclk, i2c0_sdata, + i2c1_sclk, i2c1_sdata, i2c2_sclk, i2c2_sdata, csi0_dn0, csi0_dp0, + csi0_dn1, csi0_dp1, csi0_cn, csi0_cp, csi0_dn2, csi0_dp2, + csi0_dn3, csi0_dp3, dsi_dp3, dsi_dn3, dsi_dp1, dsi_dn1, dsi_cp, + dsi_cn, dsi_dp0, dsi_dn0, dsi_dp2, dsi_dn2, sensor0_pclk, + csi1_dn0, csi1_dp0, csi1_dn1, csi1_dp1, csi1_cn, csi1_cp, + sensor0_ckout, nand0_d0, nand0_d1, nand0_d2, nand0_d3, nand0_d4, + nand0_d5, nand0_d6, nand0_d7, nand0_dqs, nand0_dqsn, nand0_ale, + nand0_cle, nand0_ceb0, nand0_ceb1, nand0_ceb2, nand0_ceb3, + nand1_d0, nand1_d1, nand1_d2, nand1_d3, nand1_d4, nand1_d5, + nand1_d6, nand1_d7, nand1_dqs, nand1_dqsn, nand1_ale, nand1_cle, + nand1_ceb0, nand1_ceb1, nand1_ceb2, nand1_ceb3, sgpio0, sgpio1, + sgpio2, sgpio3 + ] + + bias-bus-hold: true + bias-high-impedance: true + + bias-pull-down: + type: boolean + + bias-pull-up: + type: boolean + + input-schmitt-enable: true + input-schmitt-disable: true + slew-rate: true + drive-strength: true + + oneOf: + - required: + - groups + - required: + - pins + +examples: + - | + #include + + pinctrl: pinctrl@e01b0000 { + compatible = "actions,s900-pinctrl"; + reg = <0xe01b0000 0x1000>; + clocks = <&cmu 1>; + gpio-controller; + gpio-ranges = <&pinctrl 0 0 146>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = , + , + , + , + , + ; + + uart2-default { + pinmux { + groups = "lvds_oep_odn_mfp"; + function = "uart2"; + }; + + pinconf { + groups = "lvds_oep_odn_drv"; + drive-strength = <12>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/airoha,an7583-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/airoha,an7583-pinctrl.yaml new file mode 100644 index 0000000000000..79910214d9b5c --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/airoha,an7583-pinctrl.yaml @@ -0,0 +1,402 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/airoha,an7583-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Airoha AN7583 Pin Controller + +maintainers: + - Lorenzo Bianconi + +description: + The Airoha's AN7583 Pin controller is used to control SoC pins. + +properties: + compatible: + const: airoha,an7583-pinctrl + + interrupts: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + + gpio-ranges: + maxItems: 1 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + +allOf: + - $ref: pinctrl.yaml# + +required: + - compatible + - interrupts + - gpio-controller + - "#gpio-cells" + - interrupt-controller + - "#interrupt-cells" + +patternProperties: + '-pins$': + type: object + + patternProperties: + '^mux(-|$)': + type: object + + description: + pinmux configuration nodes. + + $ref: /schemas/pinctrl/pinmux-node.yaml + + properties: + function: + description: + A string containing the name of the function to mux to the group. + enum: [pon, tod_1pps, sipo, mdio, uart, i2c, jtag, pcm, spi, + pcm_spi, i2s, emmc, pnand, pcie_reset, pwm, phy1_led0, + phy2_led0, phy3_led0, phy4_led0, phy1_led1, phy2_led1, + phy3_led1, phy4_led1] + + groups: + description: + An array of strings. Each string contains the name of a group. + + required: + - function + - groups + + allOf: + - if: + properties: + function: + const: pon + then: + properties: + groups: + enum: [pon] + - if: + properties: + function: + const: tod_1pps + then: + properties: + groups: + enum: [pon_tod_1pps, gsw_tod_1pps] + - if: + properties: + function: + const: sipo + then: + properties: + groups: + enum: [sipo, sipo_rclk] + - if: + properties: + function: + const: mdio + then: + properties: + groups: + enum: [mdio] + - if: + properties: + function: + const: uart + then: + properties: + groups: + items: + enum: [uart2, uart2_cts_rts, hsuart, hsuart_cts_rts, + uart4, uart5] + maxItems: 2 + - if: + properties: + function: + const: i2c + then: + properties: + groups: + enum: [i2c1] + - if: + properties: + function: + const: jtag + then: + properties: + groups: + enum: [jtag_udi, jtag_dfd] + - if: + properties: + function: + const: pcm + then: + properties: + groups: + enum: [pcm1, pcm2] + - if: + properties: + function: + const: spi + then: + properties: + groups: + items: + enum: [spi_quad, spi_cs1] + maxItems: 2 + - if: + properties: + function: + const: pcm_spi + then: + properties: + groups: + items: + enum: [pcm_spi, pcm_spi_int, pcm_spi_rst, pcm_spi_cs1, + pcm_spi_cs2, pcm_spi_cs3, pcm_spi_cs4] + maxItems: 7 + - if: + properties: + function: + const: i2c + then: + properties: + groups: + enum: [i2s] + - if: + properties: + function: + const: emmc + then: + properties: + groups: + enum: [emmc] + - if: + properties: + function: + const: pnand + then: + properties: + groups: + enum: [pnand] + - if: + properties: + function: + const: pcie_reset + then: + properties: + groups: + enum: [pcie_reset0, pcie_reset1] + - if: + properties: + function: + const: pwm + then: + properties: + groups: + enum: [gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, + gpio7, gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, + gpio14, gpio15, gpio16, gpio17, gpio18, gpio19, + gpio20, gpio21, gpio22, gpio23, gpio24, gpio25, + gpio26, gpio27, gpio28, gpio29, gpio30, gpio31, + gpio36, gpio37, gpio38, gpio39, gpio40, gpio41, + gpio42, gpio43, gpio44, gpio45, gpio46, gpio47] + - if: + properties: + function: + const: phy1_led0 + then: + properties: + groups: + enum: [gpio1, gpio2, gpio3, gpio4] + - if: + properties: + function: + const: phy2_led0 + then: + properties: + groups: + enum: [gpio1, gpio2, gpio3, gpio4] + - if: + properties: + function: + const: phy3_led0 + then: + properties: + groups: + enum: [gpio1, gpio2, gpio3, gpio4] + - if: + properties: + function: + const: phy4_led0 + then: + properties: + groups: + enum: [gpio1, gpio2, gpio3, gpio4] + - if: + properties: + function: + const: phy1_led1 + then: + properties: + groups: + enum: [gpio8, gpio9, gpio10, gpio11] + - if: + properties: + function: + const: phy2_led1 + then: + properties: + groups: + enum: [gpio8, gpio9, gpio10, gpio11] + - if: + properties: + function: + const: phy3_led1 + then: + properties: + groups: + enum: [gpio8, gpio9, gpio10, gpio11] + - if: + properties: + function: + const: phy4_led1 + then: + properties: + groups: + enum: [gpio8, gpio9, gpio10, gpio11] + + additionalProperties: false + + '^conf(-|$)': + type: object + + description: + pinconf configuration nodes. + + $ref: /schemas/pinctrl/pincfg-node.yaml + + properties: + pins: + description: + An array of strings. Each string contains the name of a pin. + items: + enum: [uart1_txd, uart1_rxd, i2c_scl, i2c_sda, spi_cs0, spi_clk, + spi_mosi, spi_miso, gpio0, gpio1, gpio2, gpio3, gpio4, + gpio5, gpio6, gpio7, gpio8, gpio9, gpio10, gpio11, gpio12, + gpio13, gpio14, gpio15, gpio16, gpio17, gpio18, gpio19, + gpio20, gpio21, gpio22, gpio23, gpio24, gpio25, gpio26, + gpio27, gpio28, gpio29, gpio30, gpio31, gpio32, gpio33, + gpio34, gpio35, gpio36, gpio37, gpio38, gpio39, gpio40, + gpio41, gpio42, gpio43, gpio44, gpio45, gpio46, + pcie_reset0, pcie_reset1, pcie_reset2] + minItems: 1 + maxItems: 58 + + bias-disable: true + + bias-pull-up: true + + bias-pull-down: true + + input-enable: true + + output-enable: true + + output-low: true + + output-high: true + + drive-open-drain: true + + drive-strength: + description: + Selects the drive strength for MIO pins, in mA. + enum: [2, 4, 6, 8] + + required: + - pins + + additionalProperties: false + + additionalProperties: false + +additionalProperties: false + +examples: + - | + #include + + pinctrl { + compatible = "airoha,an7583-pinctrl"; + + interrupt-parent = <&gic>; + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + pcie1-rst-pins { + conf { + pins = "pcie_reset1"; + drive-open-drain = <1>; + }; + }; + + pwm-pins { + mux { + function = "pwm"; + groups = "gpio18"; + }; + }; + + spi-pins { + mux { + function = "spi"; + groups = "spi_quad", "spi_cs1"; + }; + }; + + uart2-pins { + mux { + function = "uart"; + groups = "uart2", "uart2_cts_rts"; + }; + }; + + uar5-pins { + mux { + function = "uart"; + groups = "uart5"; + }; + }; + + mmc-pins { + mux { + function = "emmc"; + groups = "emmc"; + }; + }; + + mdio-pins { + mux { + function = "mdio"; + groups = "mdio"; + }; + + conf { + pins = "gpio2"; + output-enable; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml index 80974c46f3ef9..af8979af9b45b 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml @@ -141,6 +141,7 @@ additionalProperties: - NRTS3 - NRTS4 - OSCCLK + - PCIERC1 - PEWAKE - PWM0 - PWM1 @@ -369,6 +370,7 @@ additionalProperties: - NRTS3 - NRTS4 - OSCCLK + - PCIERC1 - PEWAKE - PWM0 - PWM1 diff --git a/Documentation/devicetree/bindings/pinctrl/berlin,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/berlin,pinctrl.txt deleted file mode 100644 index 0a2d5516e1f39..0000000000000 --- a/Documentation/devicetree/bindings/pinctrl/berlin,pinctrl.txt +++ /dev/null @@ -1,47 +0,0 @@ -* Pin-controller driver for the Marvell Berlin SoCs - -Pin control registers are part of both chip controller and system -controller register sets. Pin controller nodes should be a sub-node of -either the chip controller or system controller node. The pins -controlled are organized in groups, so no actual pin information is -needed. - -A pin-controller node should contain subnodes representing the pin group -configurations, one per function. Each subnode has the group name and -the muxing function used. - -Be aware the Marvell Berlin datasheets use the keyword 'mode' for what -is called a 'function' in the pin-controller subsystem. - -Required properties: -- compatible: should be one of: - "marvell,berlin2-soc-pinctrl", - "marvell,berlin2-system-pinctrl", - "marvell,berlin2cd-soc-pinctrl", - "marvell,berlin2cd-system-pinctrl", - "marvell,berlin2q-soc-pinctrl", - "marvell,berlin2q-system-pinctrl", - "marvell,berlin4ct-avio-pinctrl", - "marvell,berlin4ct-soc-pinctrl", - "marvell,berlin4ct-system-pinctrl", - "syna,as370-soc-pinctrl" - -Required subnode-properties: -- groups: a list of strings describing the group names. -- function: a string describing the function used to mux the groups. - -Example: - -sys_pinctrl: pin-controller { - compatible = "marvell,berlin2q-system-pinctrl"; - - uart0_pmux: uart0-pmux { - groups = "GSM12"; - function = "uart0"; - }; -}; - -&uart0 { - pinctrl-0 = <&uart0_pmux>; - pinctrl-names = "default"; -}; diff --git a/Documentation/devicetree/bindings/pinctrl/bitmain,bm1880-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/bitmain,bm1880-pinctrl.txt deleted file mode 100644 index 4980776122ccc..0000000000000 --- a/Documentation/devicetree/bindings/pinctrl/bitmain,bm1880-pinctrl.txt +++ /dev/null @@ -1,126 +0,0 @@ -Bitmain BM1880 Pin Controller - -This binding describes the pin controller found in the BM1880 SoC. - -Required Properties: - -- compatible: Should be "bitmain,bm1880-pinctrl" -- reg: Offset and length of pinctrl space in SCTRL. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning of the -phrase "pin configuration node". - -The pin configuration nodes act as a container for an arbitrary number of -subnodes. Each of these subnodes represents some desired configuration for a -pin, a group, or a list of pins or groups. This configuration for BM1880 SoC -includes pinmux and various pin configuration parameters, such as pull-up, -slew rate etc... - -Each configuration node can consist of multiple nodes describing the pinmux -options. The name of each subnode is not important; all subnodes should be -enumerated and processed purely based on their content. - -The following generic properties as defined in pinctrl-bindings.txt are valid -to specify in a pinmux subnode: - -Required Properties: - -- pins: An array of strings, each string containing the name of a pin. - Valid values for pins are: - - MIO0 - MIO111 - -- groups: An array of strings, each string containing the name of a pin - group. Valid values for groups are: - - nand_grp, spi_grp, emmc_grp, sdio_grp, eth0_grp, pwm0_grp, - pwm1_grp, pwm2_grp, pwm3_grp, pwm4_grp, pwm5_grp, pwm6_grp, - pwm7_grp, pwm8_grp, pwm9_grp, pwm10_grp, pwm11_grp, pwm12_grp, - pwm13_grp, pwm14_grp, pwm15_grp, pwm16_grp, pwm17_grp, - pwm18_grp, pwm19_grp, pwm20_grp, pwm21_grp, pwm22_grp, - pwm23_grp, pwm24_grp, pwm25_grp, pwm26_grp, pwm27_grp, - pwm28_grp, pwm29_grp, pwm30_grp, pwm31_grp, pwm32_grp, - pwm33_grp, pwm34_grp, pwm35_grp, pwm36_grp, i2c0_grp, - i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp, uart0_grp, uart1_grp, - uart2_grp, uart3_grp, uart4_grp, uart5_grp, uart6_grp, - uart7_grp, uart8_grp, uart9_grp, uart10_grp, uart11_grp, - uart12_grp, uart13_grp, uart14_grp, uart15_grp, gpio0_grp, - gpio1_grp, gpio2_grp, gpio3_grp, gpio4_grp, gpio5_grp, - gpio6_grp, gpio7_grp, gpio8_grp, gpio9_grp, gpio10_grp, - gpio11_grp, gpio12_grp, gpio13_grp, gpio14_grp, gpio15_grp, - gpio16_grp, gpio17_grp, gpio18_grp, gpio19_grp, gpio20_grp, - gpio21_grp, gpio22_grp, gpio23_grp, gpio24_grp, gpio25_grp, - gpio26_grp, gpio27_grp, gpio28_grp, gpio29_grp, gpio30_grp, - gpio31_grp, gpio32_grp, gpio33_grp, gpio34_grp, gpio35_grp, - gpio36_grp, gpio37_grp, gpio38_grp, gpio39_grp, gpio40_grp, - gpio41_grp, gpio42_grp, gpio43_grp, gpio44_grp, gpio45_grp, - gpio46_grp, gpio47_grp, gpio48_grp, gpio49_grp, gpio50_grp, - gpio51_grp, gpio52_grp, gpio53_grp, gpio54_grp, gpio55_grp, - gpio56_grp, gpio57_grp, gpio58_grp, gpio59_grp, gpio60_grp, - gpio61_grp, gpio62_grp, gpio63_grp, gpio64_grp, gpio65_grp, - gpio66_grp, gpio67_grp, eth1_grp, i2s0_grp, i2s0_mclkin_grp, - i2s1_grp, i2s1_mclkin_grp, spi0_grp - -- function: An array of strings, each string containing the name of the - pinmux functions. The following are the list of pinmux - functions available: - - nand, spi, emmc, sdio, eth0, pwm0, pwm1, pwm2, pwm3, pwm4, - pwm5, pwm6, pwm7, pwm8, pwm9, pwm10, pwm11, pwm12, pwm13, - pwm14, pwm15, pwm16, pwm17, pwm18, pwm19, pwm20, pwm21, pwm22, - pwm23, pwm24, pwm25, pwm26, pwm27, pwm28, pwm29, pwm30, pwm31, - pwm32, pwm33, pwm34, pwm35, pwm36, i2c0, i2c1, i2c2, i2c3, - i2c4, uart0, uart1, uart2, uart3, uart4, uart5, uart6, uart7, - uart8, uart9, uart10, uart11, uart12, uart13, uart14, uart15, - gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, gpio8, - gpio9, gpio10, gpio11, gpio12, gpio13, gpio14, gpio15, gpio16, - gpio17, gpio18, gpio19, gpio20, gpio21, gpio22, gpio23, - gpio24, gpio25, gpio26, gpio27, gpio28, gpio29, gpio30, - gpio31, gpio32, gpio33, gpio34, gpio35, gpio36, gpio37, - gpio38, gpio39, gpio40, gpio41, gpio42, gpio43, gpio44, - gpio45, gpio46, gpio47, gpio48, gpio49, gpio50, gpio51, - gpio52, gpio53, gpio54, gpio55, gpio56, gpio57, gpio58, - gpio59, gpio60, gpio61, gpio62, gpio63, gpio64, gpio65, - gpio66, gpio67, eth1, i2s0, i2s0_mclkin, i2s1, i2s1_mclkin, - spi0 - -Optional Properties: - -- bias-disable: No arguments. Disable pin bias. -- bias-pull-down: No arguments. The specified pins should be configured as - pull down. -- bias-pull-up: No arguments. The specified pins should be configured as - pull up. -- input-schmitt-enable: No arguments: Enable schmitt trigger for the specified - pins -- input-schmitt-disable: No arguments: Disable schmitt trigger for the specified - pins -- slew-rate: Integer. Sets slew rate for the specified pins. - Valid values are: - <0> - Slow - <1> - Fast -- drive-strength: Integer. Selects the drive strength for the specified - pins in mA. - Valid values are: - <4> - <8> - <12> - <16> - <20> - <24> - <28> - <32> - -Example: - pinctrl: pinctrl@400 { - compatible = "bitmain,bm1880-pinctrl"; - reg = <0x400 0x120>; - - pinctrl_uart0_default: uart0-default { - pinmux { - groups = "uart0_grp"; - function = "uart0"; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/pinctrl/bitmain,bm1880-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/bitmain,bm1880-pinctrl.yaml new file mode 100644 index 0000000000000..542be98708382 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/bitmain,bm1880-pinctrl.yaml @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/bitmain,bm1880-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bitmain BM1880 Pin Controller + +maintainers: + - Manivannan Sadhasivam + +properties: + compatible: + const: bitmain,bm1880-pinctrl + + reg: + maxItems: 1 + +additionalProperties: + description: A pin configuration node. + type: object + additionalProperties: false + + properties: + pinmux: + type: object + description: Pin multiplexing parameters. + allOf: + - $ref: /schemas/pinctrl/pincfg-node.yaml# + - $ref: /schemas/pinctrl/pinmux-node.yaml# + additionalProperties: false + + properties: + pins: + items: + pattern: '^MIO[0-9]+$' + + groups: + items: + enum: [ + nand_grp, spi_grp, emmc_grp, sdio_grp, eth0_grp, pwm0_grp, + pwm1_grp, pwm2_grp, pwm3_grp, pwm4_grp, pwm5_grp, pwm6_grp, + pwm7_grp, pwm8_grp, pwm9_grp, pwm10_grp, pwm11_grp, pwm12_grp, + pwm13_grp, pwm14_grp, pwm15_grp, pwm16_grp, pwm17_grp, + pwm18_grp, pwm19_grp, pwm20_grp, pwm21_grp, pwm22_grp, + pwm23_grp, pwm24_grp, pwm25_grp, pwm26_grp, pwm27_grp, + pwm28_grp, pwm29_grp, pwm30_grp, pwm31_grp, pwm32_grp, + pwm33_grp, pwm34_grp, pwm35_grp, pwm36_grp, i2c0_grp, + i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp, uart0_grp, uart1_grp, + uart2_grp, uart3_grp, uart4_grp, uart5_grp, uart6_grp, + uart7_grp, uart8_grp, uart9_grp, uart10_grp, uart11_grp, + uart12_grp, uart13_grp, uart14_grp, uart15_grp, gpio0_grp, + gpio1_grp, gpio2_grp, gpio3_grp, gpio4_grp, gpio5_grp, + gpio6_grp, gpio7_grp, gpio8_grp, gpio9_grp, gpio10_grp, + gpio11_grp, gpio12_grp, gpio13_grp, gpio14_grp, gpio15_grp, + gpio16_grp, gpio17_grp, gpio18_grp, gpio19_grp, gpio20_grp, + gpio21_grp, gpio22_grp, gpio23_grp, gpio24_grp, gpio25_grp, + gpio26_grp, gpio27_grp, gpio28_grp, gpio29_grp, gpio30_grp, + gpio31_grp, gpio32_grp, gpio33_grp, gpio34_grp, gpio35_grp, + gpio36_grp, gpio37_grp, gpio38_grp, gpio39_grp, gpio40_grp, + gpio41_grp, gpio42_grp, gpio43_grp, gpio44_grp, gpio45_grp, + gpio46_grp, gpio47_grp, gpio48_grp, gpio49_grp, gpio50_grp, + gpio51_grp, gpio52_grp, gpio53_grp, gpio54_grp, gpio55_grp, + gpio56_grp, gpio57_grp, gpio58_grp, gpio59_grp, gpio60_grp, + gpio61_grp, gpio62_grp, gpio63_grp, gpio64_grp, gpio65_grp, + gpio66_grp, gpio67_grp, eth1_grp, i2s0_grp, i2s0_mclkin_grp, + i2s1_grp, i2s1_mclkin_grp, spi0_grp + ] + + function: + items: + enum: [ + nand, spi, emmc, sdio, eth0, pwm0, pwm1, pwm2, pwm3, pwm4, + pwm5, pwm6, pwm7, pwm8, pwm9, pwm10, pwm11, pwm12, pwm13, + pwm14, pwm15, pwm16, pwm17, pwm18, pwm19, pwm20, pwm21, pwm22, + pwm23, pwm24, pwm25, pwm26, pwm27, pwm28, pwm29, pwm30, pwm31, + pwm32, pwm33, pwm34, pwm35, pwm36, i2c0, i2c1, i2c2, i2c3, + i2c4, uart0, uart1, uart2, uart3, uart4, uart5, uart6, uart7, + uart8, uart9, uart10, uart11, uart12, uart13, uart14, uart15, + gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7, gpio8, + gpio9, gpio10, gpio11, gpio12, gpio13, gpio14, gpio15, gpio16, + gpio17, gpio18, gpio19, gpio20, gpio21, gpio22, gpio23, + gpio24, gpio25, gpio26, gpio27, gpio28, gpio29, gpio30, + gpio31, gpio32, gpio33, gpio34, gpio35, gpio36, gpio37, + gpio38, gpio39, gpio40, gpio41, gpio42, gpio43, gpio44, + gpio45, gpio46, gpio47, gpio48, gpio49, gpio50, gpio51, + gpio52, gpio53, gpio54, gpio55, gpio56, gpio57, gpio58, + gpio59, gpio60, gpio61, gpio62, gpio63, gpio64, gpio65, + gpio66, gpio67, eth1, i2s0, i2s0_mclkin, i2s1, i2s1_mclkin, + spi0 + ] + + bias-disable: true + bias-pull-down: true + bias-pull-up: true + input-schmitt-enable: true + input-schmitt-disable: true + + slew-rate: + description: > + Sets slew rate. Valid values: 0 = Slow, 1 = Fast. + enum: [0, 1] + + drive-strength: + enum: [4, 8, 12, 16, 20, 24, 28, 32] + + oneOf: + - required: + - pins + - required: + - groups + + required: + - function + +required: + - compatible + - reg + +examples: + - | + pinctrl@400 { + compatible = "bitmain,bm1880-pinctrl"; + reg = <0x400 0x120>; + + uart0-default { + pinmux { + groups = "uart0_grp"; + function = "uart0"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm21664-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm21664-pinctrl.yaml index 1283a588416d4..a2e609b066eea 100644 --- a/Documentation/devicetree/bindings/pinctrl/brcm,bcm21664-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm21664-pinctrl.yaml @@ -116,7 +116,6 @@ patternProperties: input-schmitt-enable: false input-schmitt-disable: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,ns2-pinmux.txt b/Documentation/devicetree/bindings/pinctrl/brcm,ns2-pinmux.txt deleted file mode 100644 index 40e0a9a19525b..0000000000000 --- a/Documentation/devicetree/bindings/pinctrl/brcm,ns2-pinmux.txt +++ /dev/null @@ -1,102 +0,0 @@ -Broadcom Northstar2 IOMUX Controller - -The Northstar2 IOMUX controller supports group based mux configuration. There -are some individual pins that support modifying the pinconf parameters. - -Required properties: - -- compatible: - Must be "brcm,ns2-pinmux" - -- reg: - Define the base and range of the I/O address space that contains the - Northstar2 IOMUX and pin configuration registers. - -Properties in sub nodes: - -- function: - The mux function to select - -- groups: - The list of groups to select with a given function - -- pins: - List of pin names to change configuration - -The generic properties bias-disable, bias-pull-down, bias-pull-up, -drive-strength, slew-rate, input-enable, input-disable are supported -for some individual pins listed at the end. - -For more details, refer to -Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt - -For example: - - pinctrl: pinctrl@6501d130 { - compatible = "brcm,ns2-pinmux"; - reg = <0x6501d130 0x08>, - <0x660a0028 0x04>, - <0x660009b0 0x40>; - - pinctrl-names = "default"; - pinctrl-0 = <&nand_sel>, <&uart3_rx>, <&sdio0_d4>; - - /* Select nand function */ - nand_sel: nand_sel { - function = "nand"; - groups = "nand_grp"; - }; - - /* Pull up the uart3 rx pin */ - uart3_rx: uart3_rx { - pins = "uart3_sin"; - bias-pull-up; - }; - - /* Set the drive strength of sdio d4 pin */ - sdio0_d4: sdio0_d4 { - pins = "sdio0_data4"; - drive-strength = <8>; - }; - }; - -List of supported functions and groups in Northstar2: - -"nand": "nand_grp" - -"nor": "nor_data_grp", "nor_adv_grp", "nor_addr_0_3_grp", "nor_addr_4_5_grp", - "nor_addr_6_7_grp", "nor_addr_8_9_grp", "nor_addr_10_11_grp", - "nor_addr_12_15_grp" - -"gpio": "gpio_0_1_grp", "gpio_2_5_grp", "gpio_6_7_grp", "gpio_8_9_grp", - "gpio_10_11_grp", "gpio_12_13_grp", "gpio_14_17_grp", "gpio_18_19_grp", - "gpio_20_21_grp", "gpio_22_23_grp", "gpio_24_25_grp", "gpio_26_27_grp", - "gpio_28_29_grp", "gpio_30_31_grp" - -"pcie": "pcie_ab1_clk_wak_grp", "pcie_a3_clk_wak_grp", "pcie_b3_clk_wak_grp", - "pcie_b2_clk_wak_grp", "pcie_a2_clk_wak_grp" - -"uart0": "uart0_modem_grp", "uart0_rts_cts_grp", "uart0_in_out_grp" - -"uart1": "uart1_ext_clk_grp", "uart1_dcd_dsr_grp", "uart1_ri_dtr_grp", - "uart1_rts_cts_grp", "uart1_in_out_grp" - -"uart2": "uart2_rts_cts_grp" - -"pwm": "pwm_0_grp", "pwm_1_grp", "pwm_2_grp", "pwm_3_grp" - - -List of pins that support pinconf parameters: - -"qspi_wp", "qspi_hold", "qspi_cs", "qspi_sck", "uart3_sin", "uart3_sout", -"qspi_mosi", "qspi_miso", "spi0_fss", "spi0_rxd", "spi0_txd", "spi0_sck", -"spi1_fss", "spi1_rxd", "spi1_txd", "spi1_sck", "sdio0_data7", -"sdio0_emmc_rst", "sdio0_led_on", "sdio0_wp", "sdio0_data3", "sdio0_data4", -"sdio0_data5", "sdio0_data6", "sdio0_cmd", "sdio0_data0", "sdio0_data1", -"sdio0_data2", "sdio1_led_on", "sdio1_wp", "sdio0_cd_l", "sdio0_clk", -"sdio1_data5", "sdio1_data6", "sdio1_data7", "sdio1_emmc_rst", "sdio1_data1", -"sdio1_data2", "sdio1_data3", "sdio1_data4", "sdio1_cd_l", "sdio1_clk", -"sdio1_cmd", "sdio1_data0", "ext_mdio_0", "ext_mdc_0", "usb3_p1_vbus_ppc", -"usb3_p1_overcurrent", "usb3_p0_vbus_ppc", "usb3_p0_overcurrent", -"usb2_presence_indication", "usb2_vbus_present", "usb2_vbus_ppc", -"usb2_overcurrent", "sata_led1", "sata_led0" diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,ns2-pinmux.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,ns2-pinmux.yaml new file mode 100644 index 0000000000000..1de23c06fa49b --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,ns2-pinmux.yaml @@ -0,0 +1,111 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/brcm,ns2-pinmux.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom Northstar2 IOMUX Controller + +maintainers: + - Ray Jui + - Scott Branden + +properties: + compatible: + const: brcm,ns2-pinmux + + reg: + maxItems: 3 + +additionalProperties: + description: Pin group node properties + type: object + allOf: + - $ref: /schemas/pinctrl/pincfg-node.yaml# + - $ref: /schemas/pinctrl/pinmux-node.yaml# + additionalProperties: false + + properties: + function: + description: The mux function to select + $ref: /schemas/types.yaml#/definitions/string + + groups: + items: + enum: [ + nand_grp, nor_data_grp, nor_adv_grp, nor_addr_0_3_grp, + nor_addr_4_5_grp, nor_addr_6_7_grp, nor_addr_8_9_grp, + nor_addr_10_11_grp, nor_addr_12_15_grp, gpio_0_1_grp, gpio_2_5_grp, + gpio_6_7_grp, gpio_8_9_grp, gpio_10_11_grp, gpio_12_13_grp, + gpio_14_17_grp, gpio_18_19_grp, gpio_20_21_grp, gpio_22_23_grp, + gpio_24_25_grp, gpio_26_27_grp, gpio_28_29_grp, gpio_30_31_grp, + pcie_ab1_clk_wak_grp, pcie_a3_clk_wak_grp, pcie_b3_clk_wak_grp, + pcie_b2_clk_wak_grp, pcie_a2_clk_wak_grp, uart0_modem_grp, + uart0_rts_cts_grp, uart0_in_out_grp, uart1_ext_clk_grp, + uart1_dcd_dsr_grp, uart1_ri_dtr_grp, uart1_rts_cts_grp, + uart1_in_out_grp, uart2_rts_cts_grp, pwm_0_grp, pwm_1_grp, pwm_2_grp, + pwm_3_grp + ] + + pins: + items: + enum: [ + qspi_wp, qspi_hold, qspi_cs, qspi_sck, uart3_sin, uart3_sout, + qspi_mosi, qspi_miso, spi0_fss, spi0_rxd, spi0_txd, spi0_sck, + spi1_fss, spi1_rxd, spi1_txd, spi1_sck, sdio0_data7, sdio0_emmc_rst, + sdio0_led_on, sdio0_wp, sdio0_data3, sdio0_data4, sdio0_data5, + sdio0_data6, sdio0_cmd, sdio0_data0, sdio0_data1, sdio0_data2, + sdio1_led_on, sdio1_wp, sdio0_cd_l, sdio0_clk, sdio1_data5, + sdio1_data6, sdio1_data7, sdio1_emmc_rst, sdio1_data1, sdio1_data2, + sdio1_data3, sdio1_data4, sdio1_cd_l, sdio1_clk, sdio1_cmd, + sdio1_data0, ext_mdio_0, ext_mdc_0, usb3_p1_vbus_ppc, + usb3_p1_overcurrent, usb3_p0_vbus_ppc, usb3_p0_overcurrent, + usb2_presence_indication, usb2_vbus_present, usb2_vbus_ppc, + usb2_overcurrent, sata_led1, sata_led0 + ] + + bias-disable: true + bias-pull-down: true + bias-pull-up: true + drive-strength: true + slew-rate: true + input-enable: true + input-disable: true + + oneOf: + - required: + - groups + - function + - required: + - pins + +required: + - compatible + - reg + +examples: + - | + pinctrl@6501d130 { + compatible = "brcm,ns2-pinmux"; + reg = <0x6501d130 0x08>, + <0x660a0028 0x04>, + <0x660009b0 0x40>; + + /* Select nand function */ + nand-sel { + function = "nand"; + groups = "nand_grp"; + }; + + /* Pull up the uart3 rx pin */ + uart3-rx { + pins = "uart3_sin"; + bias-pull-up; + }; + + /* Set the drive strength of sdio d4 pin */ + sdio0-d4 { + pins = "sdio0_data4"; + drive-strength = <8>; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/cix,sky1-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/cix,sky1-pinctrl.yaml new file mode 100644 index 0000000000000..8ed53496c386f --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/cix,sky1-pinctrl.yaml @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/cix,sky1-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cix Sky1 Soc Pin Controller + +maintainers: + - Gary Yang + +description: + The pin-controller is used to control Soc pins. There are two pin-controllers + on Cix Sky1 platform. one is used under S0 state, the other one is used under + S0 and S5 state. + +properties: + compatible: + enum: + - cix,sky1-pinctrl + - cix,sky1-pinctrl-s5 + + reg: + items: + - description: gpio base + +patternProperties: + '-cfg$': + type: object + additionalProperties: false + + description: + A pinctrl node should contain at least one subnode representing the + pinctrl groups available on the machine. + + patternProperties: + 'pins$': + type: object + additionalProperties: false + + description: + Each subnode will list the pins it needs, and how they should + be configured, with regard to muxer configuration, bias pull, + and drive strength. + + allOf: + - $ref: pincfg-node.yaml# + - $ref: pinmux-node.yaml# + + properties: + pinmux: + description: + Values are constructed from pin number and mux setting, pin + number is left shifted by 8 bits, then ORed with mux setting + + bias-disable: true + + bias-pull-up: true + + bias-pull-down: true + + drive-strength: + description: + typical current when output high level. + enum: [ 2, 3, 5, 6, 8, 9, 11, 12, 13, 14, 17, 18, 20, 21, 23, + 24 ] + + required: + - pinmux + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #define CIX_PAD_GPIO012_FUNC_GPIO012 (11 << 8 | 0x0) + pinctrl@4170000 { + compatible = "cix,sky1-pinctrl"; + reg = <0x4170000 0x1000>; + + wifi_vbat_gpio: wifi-vbat-gpio-cfg { + pins { + pinmux = ; + bias-pull-up; + drive-strength = <8>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx9-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx9-pinctrl.yaml index a438db8884f2d..96e7b69952737 100644 --- a/Documentation/devicetree/bindings/pinctrl/fsl,imx9-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx9-pinctrl.yaml @@ -58,7 +58,6 @@ patternProperties: - description: | "pad_setting" indicates the pad configuration value to be applied. - required: - fsl,pins diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,ap806-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/marvell,ap806-pinctrl.yaml new file mode 100644 index 0000000000000..00a7e358a8c97 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/marvell,ap806-pinctrl.yaml @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/marvell,ap806-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Marvell AP806 pin controller + +maintainers: + - Gregory Clement + - Miquel Raynal + +properties: + compatible: + const: marvell,ap806-pinctrl + + reg: + maxItems: 1 + +patternProperties: + '-pins$': + type: object + additionalProperties: false + + properties: + marvell,function: + $ref: /schemas/types.yaml#/definitions/string + description: + Indicates the function to select. + enum: [ gpio, i2c0, sdio, spi0, uart0, uart1 ] + + marvell,pins: + $ref: /schemas/types.yaml#/definitions/string-array + description: + Array of MPP pins to be used for the given function. + minItems: 1 + maxItems: 20 + items: + enum: [ + mpp0, mpp1, mpp2, mpp3, mpp4, mpp5, mpp6, mpp7, mpp8, mpp9, mpp10, + mpp11, mpp12, mpp13, mpp14, mpp15, mpp16, mpp17, mpp18, mpp19 + ] + +allOf: + - $ref: pinctrl.yaml# + +required: + - compatible + +additionalProperties: false + +examples: + - | + pinctrl { + compatible = "marvell,ap806-pinctrl"; + + uart0_pins: uart0-pins { + marvell,pins = "mpp11", "mpp19"; + marvell,function = "uart0"; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt deleted file mode 100644 index ecec514b31550..0000000000000 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt +++ /dev/null @@ -1,195 +0,0 @@ -* Marvell Armada 37xx SoC pin and gpio controller - -Each Armada 37xx SoC come with two pin and gpio controller one for the -south bridge and the other for the north bridge. - -Inside this set of register the gpio latch allows exposing some -configuration of the SoC and especially the clock frequency of the -xtal. Hence, this node is a represent as syscon allowing sharing the -register between multiple hardware block. - -GPIO and pin controller: ------------------------- - -Main node: - -Refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning -of the phrase "pin configuration node". - -Required properties for pinctrl driver: - -- compatible: "marvell,armada3710-sb-pinctrl", "syscon, "simple-mfd" - for the south bridge - "marvell,armada3710-nb-pinctrl", "syscon, "simple-mfd" - for the north bridge -- reg: The first set of register are for pinctrl/gpio and the second - set for the interrupt controller -- interrupts: list of the interrupt use by the gpio - -Available groups and functions for the North bridge: - -group: jtag - - pins 20-24 - - functions jtag, gpio - -group sdio0 - - pins 8-10 - - functions sdio, gpio - -group emmc_nb - - pins 27-35 - - functions emmc, gpio - -group pwm0 - - pin 11 (GPIO1-11) - - functions pwm, led, gpio - -group pwm1 - - pin 12 - - functions pwm, led, gpio - -group pwm2 - - pin 13 - - functions pwm, led, gpio - -group pwm3 - - pin 14 - - functions pwm, led, gpio - -group pmic1 - - pin 7 - - functions pmic, gpio - -group pmic0 - - pin 6 - - functions pmic, gpio - -group i2c2 - - pins 2-3 - - functions i2c, gpio - -group i2c1 - - pins 0-1 - - functions i2c, gpio - -group spi_cs1 - - pin 17 - - functions spi, gpio - -group spi_cs2 - - pin 18 - - functions spi, gpio - -group spi_cs3 - - pin 19 - - functions spi, gpio - -group onewire - - pin 4 - - functions onewire, gpio - -group uart1 - - pins 25-26 - - functions uart, gpio - -group spi_quad - - pins 15-16 - - functions spi, gpio - -group uart2 - - pins 9-10 and 18-19 - - functions uart, gpio - -Available groups and functions for the South bridge: - -group usb32_drvvbus0 - - pin 36 - - functions drvbus, gpio - -group usb2_drvvbus1 - - pin 37 - - functions drvbus, gpio - -group sdio_sb - - pins 60-65 - - functions sdio, gpio - -group rgmii - - pins 42-53 - - functions mii, gpio - -group pcie1 - - pins 39 - - functions pcie, gpio - -group pcie1_clkreq - - pins 40 - - functions pcie, gpio - -group pcie1_wakeup - - pins 41 - - functions pcie, gpio - -group smi - - pins 54-55 - - functions smi, gpio - -group ptp - - pins 56 - - functions ptp, gpio - -group ptp_clk - - pin 57 - - functions ptp, mii - -group ptp_trig - - pin 58 - - functions ptp, mii - -group mii_col - - pin 59 - - functions mii, mii_err - -GPIO subnode: - -Please refer to gpio.txt in this directory for details of gpio-ranges property -and the common GPIO bindings used by client devices. - -Required properties for gpio driver under the gpio subnode: -- interrupts: List of interrupt specifier for the controllers interrupt. -- gpio-controller: Marks the device node as a gpio controller. -- #gpio-cells: Should be 2. The first cell is the GPIO number and the - second cell specifies GPIO flags, as defined in - . Only the GPIO_ACTIVE_HIGH and - GPIO_ACTIVE_LOW flags are supported. -- gpio-ranges: Range of pins managed by the GPIO controller. - -Xtal Clock bindings for Marvell Armada 37xx SoCs ------------------------------------------------- - -see Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt - - -Example: -pinctrl_sb: pinctrl-sb@18800 { - compatible = "marvell,armada3710-sb-pinctrl", "syscon", "simple-mfd"; - reg = <0x18800 0x100>, <0x18C00 0x20>; - gpio { - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_sb 0 0 29>; - gpio-controller; - interrupts = - , - , - , - , - ; - }; - - rgmii_pins: mii-pins { - groups = "rgmii"; - function = "mii"; - }; - -}; diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-7k-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/marvell,armada-7k-pinctrl.yaml new file mode 100644 index 0000000000000..88910ad170e55 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-7k-pinctrl.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/marvell,armada-7k-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Marvell Armada 7K/8K pin controller + +maintainers: + - Gregory Clement + - Miquel Raynal + +properties: + compatible: + enum: + - marvell,armada-7k-pinctrl + - marvell,armada-8k-cpm-pinctrl + - marvell,armada-8k-cps-pinctrl + - marvell,cp115-standalone-pinctrl + + reg: + maxItems: 1 + +patternProperties: + '-pins(-.+)?$': + type: object + additionalProperties: false + + properties: + marvell,function: + $ref: /schemas/types.yaml#/definitions/string + description: + Indicates the function to select. + enum: [ + au, dev, ge, ge0, ge1, gpio, i2c0, i2c1, led, link, mii, mss_gpio0, + mss_gpio1, mss_gpio2, mss_gpio3, mss_gpio4, mss_gpio5, mss_gpio6, + mss_gpio7, mss_i2c, mss_spi, mss_uart, nf, pcie, pcie0, pcie1, pcie2, + ptp, rei, sata0, sata1, sdio, sdio_cd, sdio_wp, sei, spi0, spi1, + synce1, synce2, tdm, uart0, uart1, uart2, uart3, wakeup, xg + ] + + marvell,pins: + $ref: /schemas/types.yaml#/definitions/string-array + description: + Array of MPP pins to be used for the given function. + minItems: 1 + maxItems: 63 + items: + pattern: '^mpp([1-5]?[0-9]|6[0-2])$' + +allOf: + - $ref: pinctrl.yaml# + +required: + - compatible + +additionalProperties: false + +examples: + - | + pinctrl { + compatible = "marvell,armada-7k-pinctrl"; + + nand_pins: nand-pins { + marvell,pins = + "mpp15", "mpp16", "mpp17", "mpp18", + "mpp19", "mpp20", "mpp21", "mpp22", + "mpp23", "mpp24", "mpp25", "mpp26", + "mpp27"; + marvell,function = "dev"; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada3710-xb-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/marvell,armada3710-xb-pinctrl.yaml new file mode 100644 index 0000000000000..51bad2e8d6f1f --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada3710-xb-pinctrl.yaml @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/marvell,armada3710-xb-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Marvell Armada 37xx SoC pin and gpio controller + +maintainers: + - Gregory CLEMENT + - Marek Behún + - Miquel Raynal + +description: > + Each Armada 37xx SoC come with two pin and gpio controller one for the south + bridge and the other for the north bridge. + + Inside this set of register the gpio latch allows exposing some configuration + of the SoC and especially the clock frequency of the xtal. Hence, this node is + a represent as syscon allowing sharing the register between multiple hardware + block. + +properties: + compatible: + items: + - enum: + - marvell,armada3710-sb-pinctrl + - marvell,armada3710-nb-pinctrl + - const: syscon + - const: simple-mfd + + reg: + items: + - description: pinctrl and GPIO controller registers + - description: interrupt controller registers + + gpio: + description: GPIO controller subnode + type: object + additionalProperties: false + + properties: + '#gpio-cells': + const: 2 + + gpio-controller: true + + gpio-ranges: + description: Range of pins managed by the GPIO controller + + '#interrupt-cells': + const: 2 + + interrupt-controller: true + + interrupts: + description: List of interrupt specifiers for the GPIO controller + + required: + - '#gpio-cells' + - gpio-ranges + - gpio-controller + - '#interrupt-cells' + - interrupt-controller + - interrupts + + xtal-clk: + type: object + additionalProperties: false + + properties: + compatible: + const: marvell,armada-3700-xtal-clock + + '#clock-cells': + const: 0 + + clock-output-names: true + +patternProperties: + '-pins$': + $ref: pinmux-node.yaml# + additionalProperties: false + + properties: + groups: + enum: [ emmc_nb, i2c1, i2c2, jtag, mii_col, onewire, pcie1, + pcie1_clkreq, pcie1_wakeup, pmic0, pmic1, ptp, ptp_clk, + ptp_trig, pwm0, pwm1, pwm2, pwm3, rgmii, sdio0, sdio_sb, smi, + spi_cs1, spi_cs2, spi_cs3, spi_quad, uart1, uart2, + usb2_drvvbus1, usb32_drvvbus ] + + function: + enum: [ drvbus, emmc, gpio, i2c, jtag, led, mii, mii_err, onewire, + pcie, pmic, ptp, pwm, sdio, smi, spi, uart ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + + pinctrl_sb: pinctrl@18800 { + compatible = "marvell,armada3710-sb-pinctrl", "syscon", "simple-mfd"; + reg = <0x18800 0x100>, <0x18C00 0x20>; + + gpio { + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_sb 0 0 29>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts = + , + , + , + , + ; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,berlin2-soc-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/marvell,berlin2-soc-pinctrl.yaml new file mode 100644 index 0000000000000..6ace3bf5433bd --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/marvell,berlin2-soc-pinctrl.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/marvell,berlin2-soc-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Marvell Berlin pin-controller driver + +maintainers: + - Antoine Tenart + - Jisheng Zhang + +description: > + Pin control registers are part of both chip controller and system controller + register sets. Pin controller nodes should be a sub-node of either the chip + controller or system controller node. The pins controlled are organized in + groups, so no actual pin information is needed. + + A pin-controller node should contain subnodes representing the pin group + configurations, one per function. Each subnode has the group name and the + muxing function used. + + Be aware the Marvell Berlin datasheets use the keyword 'mode' for what is + called a 'function' in the pin-controller subsystem. + +properties: + compatible: + items: + - enum: + - marvell,berlin2-soc-pinctrl + - marvell,berlin2-system-pinctrl + - marvell,berlin2cd-soc-pinctrl + - marvell,berlin2cd-system-pinctrl + - marvell,berlin2q-soc-pinctrl + - marvell,berlin2q-system-pinctrl + - marvell,berlin4ct-avio-pinctrl + - marvell,berlin4ct-soc-pinctrl + - marvell,berlin4ct-system-pinctrl + - syna,as370-soc-pinctrl + + reg: + maxItems: 1 + +additionalProperties: + description: Pin group configuration subnodes. + type: object + $ref: /schemas/pinctrl/pinmux-node.yaml# + additionalProperties: false + + properties: + groups: + description: List of pin group names. + $ref: /schemas/types.yaml#/definitions/string-array + + function: + description: Function used to mux the group. + $ref: /schemas/types.yaml#/definitions/string + + required: + - groups + - function + +allOf: + - if: + properties: + compatible: + contains: + enum: + - marvell,berlin4ct-avio-pinctrl + - marvell,berlin4ct-soc-pinctrl + - marvell,berlin4ct-system-pinctrl + - syna,as370-soc-pinctrl + then: + required: + - reg + +examples: + - | + pinctrl { + compatible = "marvell,berlin2q-system-pinctrl"; + + uart0-pmux { + groups = "GSM12"; + function = "uart0"; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6878-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6878-pinctrl.yaml new file mode 100644 index 0000000000000..8d44194a79389 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6878-pinctrl.yaml @@ -0,0 +1,211 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt6878-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT6878 Pin Controller + +maintainers: + - AngeloGioacchino Del Regno + - Igor Belwon + +description: + The MediaTek MT6878 Pin controller is used to control SoC pins. + +properties: + compatible: + const: mediatek,mt6878-pinctrl + + reg: + items: + - description: pin controller base + - description: bl group IO + - description: bm group IO + - description: br group IO + - description: bl1 group IO + - description: br1 group IO + - description: lm group IO + - description: lt group IO + - description: rm group IO + - description: rt group IO + - description: EINT controller E block + - description: EINT controller S block + - description: EINT controller W block + - description: EINT controller C block + + reg-names: + items: + - const: base + - const: bl + - const: bm + - const: br + - const: bl1 + - const: br1 + - const: lm + - const: lt + - const: rm + - const: rt + - const: eint-e + - const: eint-s + - const: eint-w + - const: eint-c + + gpio-controller: true + + '#gpio-cells': + description: + Number of cells in GPIO specifier. Since the generic GPIO binding is used, + the amount of cells must be specified as 2. See the below mentioned gpio + binding representation for description of particular cells. + const: 2 + + gpio-ranges: + maxItems: 1 + + gpio-line-names: + maxItems: 216 + + interrupts: + description: The interrupt outputs to sysirq + maxItems: 1 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + +# PIN CONFIGURATION NODES +patternProperties: + '-pins$': + type: object + additionalProperties: false + + patternProperties: + '^pins': + type: object + allOf: + - $ref: /schemas/pinctrl/pincfg-node.yaml + - $ref: /schemas/pinctrl/pinmux-node.yaml + description: + A pinctrl node should contain at least one subnodes representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to muxer + configuration, pullups, drive strength, input enable/disable and input + schmitt. + + properties: + pinmux: + description: + Integer array, represents gpio pin number and mux setting. + Supported pin number and mux are defined as macros in + arch/arm64/boot/dts/mediatek/mt8196-pinfunc.h for this SoC. + + drive-strength: + enum: [2, 4, 6, 8, 10, 12, 14, 16] + + drive-strength-microamp: + enum: [125, 250, 500, 1000] + + bias-pull-down: + oneOf: + - type: boolean + - enum: [75000, 5000] + description: Pull down RSEL type resistance values (in ohms) + description: + For normal pull down type there is no need to specify a resistance + value, hence this can be specified as a boolean property. + For RSEL pull down type a resistance value (in ohms) can be added. + + bias-pull-up: + oneOf: + - type: boolean + - enum: [10000, 5000, 4000, 3000] + description: Pull up RSEL type resistance values (in ohms) + description: + For normal pull up type there is no need to specify a resistance + value, hence this can be specified as a boolean property. + For RSEL pull up type a resistance value (in ohms) can be added. + + bias-disable: true + + output-high: true + + output-low: true + + input-enable: true + + input-disable: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + required: + - pinmux + + additionalProperties: false + +required: + - compatible + - reg + - interrupts + - interrupt-controller + - '#interrupt-cells' + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +additionalProperties: false + +examples: + - | + #include + #include + #define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) + #define PINMUX_GPIO99__FUNC_SCL0 (MTK_PIN_NO(99) | 1) + #define PINMUX_GPIO100__FUNC_SDA0 (MTK_PIN_NO(100) | 1) + + pio: pinctrl@10005000 { + compatible = "mediatek,mt6878-pinctrl"; + reg = <0x10005000 0x1000>, + <0x11d10000 0x1000>, + <0x11d30000 0x1000>, + <0x11d40000 0x1000>, + <0x11d50000 0x1000>, + <0x11d60000 0x1000>, + <0x11e20000 0x1000>, + <0x11e30000 0x1000>, + <0x11eb0000 0x1000>, + <0x11ec0000 0x1000>, + <0x11ce0000 0x1000>, + <0x11de0000 0x1000>, + <0x11e60000 0x1000>, + <0x1c01e000 0x1000>; + reg-names = "base", "bl", "bm", "br", "bl1", "br1", + "lm", "lt", "rm", "rt", "eint-e", "eint-s", + "eint-w", "eint-c"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pio 0 0 220>; + interrupt-controller; + interrupts = ; + #interrupt-cells = <2>; + + gpio-pins { + pins { + pinmux = ; + bias-pull-up = <4000>; + drive-strength = <6>; + }; + }; + + i2c0-pins { + pins-bus { + pinmux = , + ; + bias-pull-down = <75000>; + drive-strength-microamp = <1000>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml index 26dfe7e7735a9..1f31b520cb439 100644 --- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml @@ -61,6 +61,11 @@ required: - "#gpio-cells" patternProperties: + "-hog(-[0-9]+)?$": + type: object + required: + - gpio-hog + '-pins$': type: object additionalProperties: false diff --git a/Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml b/Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml new file mode 100644 index 0000000000000..3c98eb35fb821 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip PolarFire SoC iomux0 + +maintainers: + - Conor Dooley + +description: + iomux0 is responsible for routing some functions to either the FPGA fabric, + or to MSSIOs. It only performs muxing, and has no IO configuration role, as + fabric IOs are configured separately and just routing a function to MSSIOs is + not sufficient for it to actually get mapped to an MSSIO, just makes it + possible. + +properties: + compatible: + oneOf: + - const: microchip,mpfs-pinctrl-iomux0 + - items: + - const: microchip,pic64gx-pinctrl-iomux0 + - const: microchip,mpfs-pinctrl-iomux0 + + reg: + maxItems: 1 + + pinctrl-use-default: true + +patternProperties: + '^mux-': + type: object + $ref: pinmux-node.yaml + additionalProperties: false + + properties: + function: + description: + A string containing the name of the function to mux to the group. + enum: [ spi0, spi1, i2c0, i2c1, can0, can1, qspi, uart0, uart1, uart2, + uart3, uart4, mdio0, mdio1 ] + + groups: + description: + An array of strings. Each string contains the name of a group. + items: + enum: [ spi0_fabric, spi0_mssio, spi1_fabric, spi1_mssio, i2c0_fabric, + i2c0_mssio, i2c1_fabric, i2c1_mssio, can0_fabric, can0_mssio, + can1_fabric, can1_mssio, qspi_fabric, qspi_mssio, + uart0_fabric, uart0_mssio, uart1_fabric, uart1_mssio, + uart2_fabric, uart2_mssio, uart3_fabric, uart3_mssio, + uart4_fabric, uart4_mssio, mdio0_fabric, mdio0_mssio, + mdio1_fabric, mdio1_mssio ] + + required: + - function + - groups + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + soc { + #size-cells = <1>; + #address-cells = <1>; + + pinctrl@200 { + compatible = "microchip,mpfs-pinctrl-iomux0"; + reg = <0x200 0x4>; + + mux-spi0-fabric { + function = "spi0"; + groups = "spi0_fabric"; + }; + + mux-spi1-mssio { + function = "spi1"; + groups = "spi1_mssio"; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml b/Documentation/devicetree/bindings/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml new file mode 100644 index 0000000000000..e3792679de587 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip PIC64GX GPIO2 Mux + +maintainers: + - Conor Dooley + +description: + The "GPIO2 Mux" determines whether GPIO2 or select other functions are + available on package pins on PIC64GX. Some of these functions must be + mapped to this mux via iomux0 for settings here to have any impact. + +properties: + compatible: + const: microchip,pic64gx-pinctrl-gpio2 + + reg: + maxItems: 1 + + pinctrl-use-default: true + +patternProperties: + '^mux-': + type: object + $ref: pinmux-node.yaml + additionalProperties: false + + properties: + function: + description: + A string containing the name of the function to mux to the group. + enum: [ mdio0, mdio1, spi0, can0, pcie, qspi, uart3, uart4, can1, uart2, gpio ] + + groups: + description: + An array of strings. Each string contains the name of a group. + items: + enum: [ mdio0, mdio1, spi0, can0, pcie, qspi, uart3, uart4, can1, uart2, + gpio_mdio0, gpio_mdio1, gpio_spi0, gpio_can0, gpio_pcie, + gpio_qspi, gpio_uart3, gpio_uart4, gpio_can1, gpio_uart2 ] + + required: + - function + - groups + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@41000000 { + compatible = "microchip,pic64gx-pinctrl-gpio2"; + reg = <0x41000000 0x4>; + pinctrl-use-default; + pinctrl-names = "default"; + pinctrl-0 = <&mdio0_gpio2>, <&mdio1_gpio2>, <&spi0_gpio2>, <&qspi_gpio2>, + <&uart3_gpio2>, <&uart4_gpio2>, <&can1_gpio2>, <&can0_gpio2>, + <&uart2_gpio2>; + + mux-gpio2 { + function = "gpio"; + groups = "gpio_mdio1", "gpio_spi0", "gpio_can0", "gpio_pcie", + "gpio_qspi", "gpio_uart3", "gpio_uart4", "gpio_can1"; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml b/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml index 0df4e114fdd69..fa47732d7cef8 100644 --- a/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml @@ -18,7 +18,7 @@ description: | properties: $nodename: - pattern: "^gpio@[0-9a-f]+$" + pattern: '^gpio@[0-9a-f]+$' compatible: enum: @@ -26,10 +26,10 @@ properties: - mscc,ocelot-sgpio - mscc,luton-sgpio - "#address-cells": + '#address-cells': const: 1 - "#size-cells": + '#size-cells': const: 0 reg: @@ -76,7 +76,7 @@ properties: - const: switch patternProperties: - "^gpio@[0-1]$": + '^gpio@[0-1]$': type: object properties: compatible: @@ -132,8 +132,8 @@ required: - reg - clocks - microchip,sgpio-port-ranges - - "#address-cells" - - "#size-cells" + - '#address-cells' + - '#size-cells' examples: - | diff --git a/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml b/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml index cbfcf215e571d..a916d0fc79a99 100644 --- a/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml +++ b/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Generic Pin Configuration Node maintainers: - - Linus Walleij + - Linus Walleij description: Many data items that are represented in a pin configuration node are common @@ -153,4 +153,21 @@ properties: pin. Typically indicates how many double-inverters are used to delay the signal. + skew-delay-input-ps: + description: + this affects the expected clock skew in ps on an input pin. + + skew-delay-output-ps: + description: + this affects the expected delay in ps before latching a value to + an output pin. + +if: + required: + - skew-delay +then: + properties: + skew-delay-input-ps: false + skew-delay-output-ps: false + additionalProperties: true diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.yaml index f83dbf32ad183..9135788cf62ec 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.yaml +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.yaml @@ -24,6 +24,7 @@ properties: - items: - enum: - ti,am437-padconf + - ti,am62l-padconf - ti,am654-padconf - ti,dra7-padconf - ti,omap2420-padconf diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl.yaml index d471563119a98..290438826c507 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Pin controller device maintainers: - - Linus Walleij + - Linus Walleij - Rafał Miłecki description: | diff --git a/Documentation/devicetree/bindings/pinctrl/pinmux-node.yaml b/Documentation/devicetree/bindings/pinctrl/pinmux-node.yaml index ca9d246d46fe4..7ba26271c4d65 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinmux-node.yaml +++ b/Documentation/devicetree/bindings/pinctrl/pinmux-node.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Generic Pin Multiplexing Node maintainers: - - Linus Walleij + - Linus Walleij description: | The contents of the pin configuration child nodes are defined by the binding diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq5018-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,ipq5018-tlmm.yaml index 23300606547c5..96635b2f6a279 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,ipq5018-tlmm.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq5018-tlmm.yaml @@ -8,7 +8,7 @@ title: Qualcomm IPQ5018 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm IPQ5018 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq5332-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,ipq5332-tlmm.yaml index e571cd64418f2..22685c4799838 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,ipq5332-tlmm.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq5332-tlmm.yaml @@ -8,7 +8,7 @@ title: Qualcomm IPQ5332 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: | Top Level Mode Multiplexer pin controller in Qualcomm IPQ5332 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.yaml index 6f90dbbdbdcce..40def3ac3bf71 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8074-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm IPQ8074 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm IPQ8074 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq9574-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,ipq9574-tlmm.yaml index bca903b5da6d0..7afec315b63ef 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,ipq9574-tlmm.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq9574-tlmm.yaml @@ -8,7 +8,7 @@ title: Qualcomm Technologies, Inc. IPQ9574 TLMM block maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm IPQ9574 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,kaanapali-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,kaanapali-tlmm.yaml new file mode 100644 index 0000000000000..53534a07a1f0e --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,kaanapali-tlmm.yaml @@ -0,0 +1,127 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,kaanapali-tlmm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. Kaanapali TLMM block + +maintainers: + - Jingyi Wang + +description: + Top Level Mode Multiplexer pin controller in Qualcomm Kaanapali SoC. + +allOf: + - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml# + +properties: + compatible: + const: qcom,kaanapali-tlmm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + gpio-reserved-ranges: + minItems: 1 + maxItems: 109 + + gpio-line-names: + maxItems: 217 + +patternProperties: + "-state$": + oneOf: + - $ref: "#/$defs/qcom-kaanapali-tlmm-state" + - patternProperties: + "-pins$": + $ref: "#/$defs/qcom-kaanapali-tlmm-state" + additionalProperties: false + +$defs: + qcom-kaanapali-tlmm-state: + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state + unevaluatedProperties: false + + properties: + pins: + description: + List of gpio pins affected by the properties specified in this + subnode. + items: + oneOf: + - pattern: "^gpio([0-9]|[1-9][0-9]|1[0-9][0-9]|20[0-9]|21[0-6])$" + - enum: [ ufs_reset, sdc2_clk, sdc2_cmd, sdc2_data ] + minItems: 1 + maxItems: 36 + + function: + description: + Specify the alternative function to be configured for the specified + pins. + enum: [ gpio, aoss_cti, atest_char, atest_usb, audio_ext_mclk0, + audio_ext_mclk1, audio_ref_clk, cam_asc_mclk2, cam_asc_mclk4, + cam_mclk, cci_async_in, cci_i2c_scl, cci_i2c_sda, cci_timer, + cmu_rng, coex_uart1_rx, coex_uart1_tx, coex_uart2_rx, + coex_uart2_tx, dbg_out_clk, ddr_bist_complete, ddr_bist_fail, + ddr_bist_start, ddr_bist_stop, ddr_pxi0, ddr_pxi1, ddr_pxi2, + ddr_pxi3, dp_hot, egpio, gcc_gp1, gcc_gp2, gcc_gp3, gnss_adc0, + gnss_adc1, i2chub0_se0, i2chub0_se1, i2chub0_se2, i2chub0_se3, + i2chub0_se4, i2s0_data0, i2s0_data1, i2s0_sck, i2s0_ws, + i2s1_data0, i2s1_data1, i2s1_sck, i2s1_ws, ibi_i3c, jitter_bist, + mdp_esync0_out, mdp_esync1_out, mdp_vsync, mdp_vsync0_out, + mdp_vsync1_out, mdp_vsync2_out, mdp_vsync3_out, mdp_vsync5_out, + mdp_vsync_e, nav_gpio0, nav_gpio1, nav_gpio2, nav_gpio3, + pcie0_clk_req_n, phase_flag, pll_bist_sync, pll_clk_aux, + prng_rosc0, prng_rosc1, prng_rosc2, prng_rosc3, qdss_cti, + qdss_gpio_traceclk, qdss_gpio_tracectl, qdss_gpio_tracedata, + qlink_big_enable, qlink_big_request, qlink_little_enable, + qlink_little_request, qlink_wmss, qspi0, qspi1, qspi2, qspi3, + qspi_clk, qspi_cs, qup1_se0, qup1_se1, qup1_se2, qup1_se3, + qup1_se4, qup1_se5, qup1_se6, qup1_se7, qup2_se0, qup2_se1, + qup2_se2, qup2_se3, qup2_se4, qup3_se0, qup3_se1, qup3_se2, + qup3_se3, qup3_se4, qup3_se5, qup4_se0, qup4_se1, qup4_se2, + qup4_se3, qup4_se4, sd_write_protect, sdc40, sdc41, sdc42, sdc43, + sdc4_clk, sdc4_cmd, sys_throttle, tb_trig_sdc2, tb_trig_sdc4, + tmess_prng0, tmess_prng1, tmess_prng2, tmess_prng3, tsense_pwm1, + tsense_pwm2, tsense_pwm3, tsense_pwm4, tsense_pwm5, tsense_pwm6, + tsense_pwm7, uim0_clk, uim0_data, uim0_present, uim0_reset, uim1_clk, + uim1_data, uim1_present, uim1_reset, usb0_hs, usb_phy, vfr_0, vfr_1, + vsense_trigger_mirnat, wcn_sw, wcn_sw_ctrl ] + + required: + - pins + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + tlmm: pinctrl@f100000 { + compatible = "qcom,kaanapali-tlmm"; + reg = <0x0f100000 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&tlmm 0 0 218>; + interrupt-controller; + #interrupt-cells = <2>; + + qup-uart7-state { + pins = "gpio62", "gpio63"; + function = "qup1_se7"; + }; + }; +... diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,lpass-lpi-common.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,lpass-lpi-common.yaml index 3b5045730471f..619341dd637c3 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,lpass-lpi-common.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,lpass-lpi-common.yaml @@ -9,7 +9,7 @@ title: Qualcomm SoC LPASS LPI TLMM Common Properties maintainers: - Bjorn Andersson - Srinivas Kandagatla - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Common properties for the Top Level Mode Multiplexer pin controllers in the diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8660-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,msm8660-pinctrl.yaml index 61f5be21f30cc..203ad69e99e85 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8660-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8660-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm MSM8660 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm MSM8660 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8916-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,msm8916-pinctrl.yaml index 904af87f9eaff..9bf098cf18eed 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8916-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8916-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm MSM8916 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm MSM8916 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.yaml index 46618740bd312..7301318094c78 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm MSM8960 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm MSM8960 SoC. @@ -107,12 +107,12 @@ examples: - | #include - msmgpio: pinctrl@800000 { + tlmm: pinctrl@800000 { compatible = "qcom,msm8960-pinctrl"; reg = <0x800000 0x4000>; #gpio-cells = <2>; gpio-controller; - gpio-ranges = <&msmgpio 0 0 152>; + gpio-ranges = <&tlmm 0 0 152>; interrupts = ; interrupt-controller; #interrupt-cells = <2>; diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.yaml index 840fdaabde127..a9aff442824cf 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm MSM8974 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm MSM8974 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8976-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,msm8976-pinctrl.yaml index d4391c194ff7c..501329bff905d 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8976-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8976-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm MSM8976 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm MSM8976 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8994-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,msm8994-pinctrl.yaml index fa90981db40b3..2ec10908d556e 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8994-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8994-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm MSM8994 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm MSM8994 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.yaml index c5010c175b238..496f38009c7d1 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm MSM8996 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm MSM8996 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.yaml index bcaa231adaf78..3b098a226a67b 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm MSM8998 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm MSM8998 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml index 5e6dfcc3fe9b3..386c31e9c52b8 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml @@ -59,7 +59,11 @@ properties: - qcom,pmc8180-gpio - qcom,pmc8180c-gpio - qcom,pmc8380-gpio + - qcom,pmcx0102-gpio - qcom,pmd8028-gpio + - qcom,pmh0101-gpio + - qcom,pmh0104-gpio + - qcom,pmh0110-gpio - qcom,pmi632-gpio - qcom,pmi8950-gpio - qcom,pmi8994-gpio @@ -68,6 +72,7 @@ properties: - qcom,pmiv0104-gpio - qcom,pmk8350-gpio - qcom,pmk8550-gpio + - qcom,pmk8850-gpio - qcom,pmm8155au-gpio - qcom,pmm8654au-gpio - qcom,pmp8074-gpio @@ -191,6 +196,8 @@ allOf: - qcom,pm8950-gpio - qcom,pm8953-gpio - qcom,pmi632-gpio + - qcom,pmh0104-gpio + - qcom,pmk8850-gpio then: properties: gpio-line-names: @@ -303,6 +310,8 @@ allOf: compatible: contains: enum: + - qcom,pmcx0102-gpio + - qcom,pmh0110-gpio - qcom,pmi8998-gpio then: properties: @@ -318,6 +327,7 @@ allOf: compatible: contains: enum: + - qcom,pmh0101-gpio - qcom,pmih0108-gpio then: properties: @@ -424,13 +434,13 @@ allOf: patternProperties: '-state$': oneOf: - - $ref: "#/$defs/qcom-pmic-gpio-state" + - $ref: '#/$defs/qcom-pmic-gpio-state' - patternProperties: - "(pinconf|-pins)$": - $ref: "#/$defs/qcom-pmic-gpio-state" + '(pinconf|-pins)$': + $ref: '#/$defs/qcom-pmic-gpio-state' additionalProperties: false - "-hog(-[0-9]+)?$": + '-hog(-[0-9]+)?$': type: object required: - gpio-hog @@ -481,13 +491,18 @@ $defs: - gpio1-gpio22 for pm8994 - gpio1-gpio26 for pm8998 - gpio1-gpio22 for pma8084 + - gpio1-gpio14 for pmcx0102 - gpio1-gpio4 for pmd8028 + - gpio1-gpio18 for pmh0101 + - gpio1-gpio8 for pmh0104 + - gpio1-gpio14 for pmh0110 - gpio1-gpio8 for pmi632 - gpio1-gpio2 for pmi8950 - gpio1-gpio10 for pmi8994 - gpio1-gpio18 for pmih0108 - gpio1-gpio4 for pmk8350 - gpio1-gpio6 for pmk8550 + - gpio1-gpio8 for pmk8850 - gpio1-gpio10 for pmm8155au - gpio1-gpio12 for pmm8654au - gpio1-gpio12 for pmp8074 (holes on gpio1 and gpio12) @@ -503,7 +518,7 @@ $defs: - gpio1-gpio12 for pmxr2230 items: - pattern: "^gpio([0-9]+)$" + pattern: '^gpio([0-9]+)$' function: items: diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.yaml index 9364ae05f3e68..daf4c1c03712c 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.yaml @@ -74,10 +74,10 @@ required: patternProperties: '-state$': oneOf: - - $ref: "#/$defs/qcom-pmic-mpp-state" + - $ref: '#/$defs/qcom-pmic-mpp-state' - patternProperties: '-pins$': - $ref: "#/$defs/qcom-pmic-mpp-state" + $ref: '#/$defs/qcom-pmic-mpp-state' additionalProperties: false $defs: @@ -100,7 +100,7 @@ $defs: - mpp1-mpp4 for pma8084 items: - pattern: "^mpp([0-9]+)$" + pattern: '^mpp([0-9]+)$' function: items: diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,qcs404-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,qcs404-pinctrl.yaml index 4009501b3414f..91b8dcec3f082 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,qcs404-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,qcs404-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm QCS404 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm QCS404 SoC. @@ -142,7 +142,6 @@ examples: interrupt-controller; #interrupt-cells = <2>; - blsp1-i2c1-default-state { pins = "gpio24", "gpio25"; function = "blsp_i2c1"; diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc7180-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc7180-pinctrl.yaml index 5606f2136ad10..ec0bf4fdfa4f1 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc7180-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc7180-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm SC7180 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm SC7180 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sdm630-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sdm630-pinctrl.yaml index a00cb43df144b..80627a1ad663c 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sdm630-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sdm630-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm SDM630 and SDM660 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm SDM630 and SDM660 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sdm845-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sdm845-pinctrl.yaml index 0f331844608c6..4fcac2e55b554 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sdm845-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sdm845-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm SDM845 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm SDM845 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-lpass-lpi-pinctrl.yaml index f4cf2ce86fcd4..d2a036ead846f 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-lpass-lpi-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-lpass-lpi-pinctrl.yaml @@ -16,7 +16,13 @@ description: properties: compatible: - const: qcom,sm6115-lpass-lpi-pinctrl + oneOf: + - enum: + - qcom,sm6115-lpass-lpi-pinctrl + - items: + - enum: + - qcom,qcm2290-lpass-lpi-pinctrl + - const: qcom,sm6115-lpass-lpi-pinctrl reg: items: @@ -66,7 +72,6 @@ $defs: Specify the alternative function to be configured for the specified pins. - allOf: - $ref: qcom,lpass-lpi-common.yaml# diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-tlmm.yaml index ddeaeaa9a450a..5a57a59cc1e57 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-tlmm.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-tlmm.yaml @@ -88,7 +88,6 @@ $defs: uim2_present, uim2_reset, unused1, unused2, usb_phy, vfr_1, vsense_trigger, wlan1_adc0, wlan1_adc1, wlan2_adc0, wlan2_adc1, wsa_clk, wsa_data ] - required: - pins diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl.yaml index bdb7ed4be0267..c4542e2d71083 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl.yaml @@ -8,7 +8,7 @@ title: Qualcomm SM8150 TLMM pin controller maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Top Level Mode Multiplexer pin controller in Qualcomm SM8150 SoC. diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-lpass-lpi-pinctrl.yaml index 9d782f910b318..46aec0713775e 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-lpass-lpi-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-lpass-lpi-pinctrl.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm SM8350 SoC LPASS LPI TLMM maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla description: diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8550-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8550-lpass-lpi-pinctrl.yaml index bf4a72facae1d..89821871c6062 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8550-lpass-lpi-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8550-lpass-lpi-pinctrl.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm SM8550 SoC LPASS LPI TLMM maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla description: diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8650-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8650-lpass-lpi-pinctrl.yaml index e90a5274647df..74df912e60ade 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8650-lpass-lpi-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8650-lpass-lpi-pinctrl.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm SM8650 SoC LPASS LPI TLMM maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla description: diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml index cfe0045733661..075f3abdfbec4 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc.yaml @@ -129,7 +129,7 @@ additionalProperties: - type: object additionalProperties: - $ref: "#/additionalProperties/anyOf/0" + $ref: '#/additionalProperties/anyOf/0' examples: - | diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rza1-ports.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rza1-ports.yaml index 2bd7d47d0fdb9..8203c3c46cc7b 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,rza1-ports.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rza1-ports.yaml @@ -65,7 +65,6 @@ patternProperties: - '#gpio-cells' - gpio-ranges - additionalProperties: anyOf: - type: object @@ -118,7 +117,7 @@ additionalProperties: - type: object additionalProperties: - $ref: "#/additionalProperties/anyOf/0" + $ref: '#/additionalProperties/anyOf/0' examples: - | @@ -150,7 +149,6 @@ examples: pinmux = , ; }; - /* * I2c master: both SDA and SCL pins need bi-directional operations * Pin #4 on port #1 is configured as alternate function #1. @@ -162,7 +160,6 @@ examples: pinmux = , ; }; - /* * Multi-function timer input and output compare pins. */ diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml index 5156d54b240b1..00c05243b9a47 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml @@ -135,7 +135,7 @@ additionalProperties: - type: object additionalProperties: - $ref: "#/additionalProperties/anyOf/0" + $ref: '#/additionalProperties/anyOf/0' allOf: - $ref: pinctrl.yaml# diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzv2m-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzv2m-pinctrl.yaml index 5fa5d31f8866b..88b2fa5e684d8 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,rzv2m-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzv2m-pinctrl.yaml @@ -88,7 +88,7 @@ additionalProperties: - type: object additionalProperties: - $ref: "#/additionalProperties/anyOf/0" + $ref: '#/additionalProperties/anyOf/0' allOf: - $ref: pinctrl.yaml# diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml index 125af766b9929..76e6072817160 100644 --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml @@ -44,6 +44,7 @@ properties: - rockchip,rk3328-pinctrl - rockchip,rk3368-pinctrl - rockchip,rk3399-pinctrl + - rockchip,rk3506-pinctrl - rockchip,rk3528-pinctrl - rockchip,rk3562-pinctrl - rockchip,rk3568-pinctrl diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml index dd11c73a55da3..f3c433015b125 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml @@ -41,6 +41,7 @@ properties: - samsung,exynos7870-wakeup-eint - samsung,exynos7885-wakeup-eint - samsung,exynos850-wakeup-eint + - samsung,exynos8890-wakeup-eint - samsung,exynos8895-wakeup-eint - const: samsung,exynos7-wakeup-eint - items: diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml index f1094d65e8460..ddc5e2efff21f 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml @@ -36,6 +36,7 @@ properties: compatible: enum: - axis,artpec8-pinctrl + - axis,artpec9-pinctrl - google,gs101-pinctrl - samsung,s3c64xx-pinctrl - samsung,s5pv210-pinctrl @@ -52,6 +53,7 @@ properties: - samsung,exynos7870-pinctrl - samsung,exynos7885-pinctrl - samsung,exynos850-pinctrl + - samsung,exynos8890-pinctrl - samsung,exynos8895-pinctrl - samsung,exynos9810-pinctrl - samsung,exynos990-pinctrl @@ -133,7 +135,9 @@ allOf: properties: compatible: contains: - const: google,gs101-pinctrl + enum: + - google,gs101-pinctrl + - samsung,exynos8890-pinctrl then: required: - clocks diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt deleted file mode 100644 index 779b8ef0f6e66..0000000000000 --- a/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt +++ /dev/null @@ -1,83 +0,0 @@ -* Spreadtrum Pin Controller - -The Spreadtrum pin controller are organized in 3 blocks (types). - -The first block comprises some global control registers, and each -register contains several bit fields with one bit or several bits -to configure for some global common configuration, such as domain -pad driving level, system control select and so on ("domain pad -driving level": One pin can output 3.0v or 1.8v, depending on the -related domain pad driving selection, if the related domain pad -select 3.0v, then the pin can output 3.0v. "system control" is used -to choose one function (like: UART0) for which system, since we -have several systems (AP/CP/CM4) on one SoC.). - -There are too much various configuration that we can not list all -of them, so we can not make every Spreadtrum-special configuration -as one generic configuration, and maybe it will add more strange -global configuration in future. Then we add one "sprd,control" to -set these various global control configuration, and we need use -magic number for this property. - -Moreover we recognise every fields comprising one bit or several -bits in one global control register as one pin, thus we should -record every pin's bit offset, bit width and register offset to -configure this field (pin). - -The second block comprises some common registers which have unified -register definition, and each register described one pin is used -to configure the pin sleep mode, function select and sleep related -configuration. - -Now we have 4 systems for sleep mode on SC9860 SoC: AP system, -PUBCP system, TGLDSP system and AGDSP system. And the pin sleep -related configuration are: -- input-enable -- input-disable -- output-high -- output-low -- bias-pull-up -- bias-pull-down - -In some situation we need set the pin sleep mode and pin sleep related -configuration, to set the pin sleep related configuration automatically -by hardware when the system specified by sleep mode goes into deep -sleep mode. For example, if we set the pin sleep mode as PUBCP_SLEEP -and set the pin sleep related configuration as "input-enable", which -means when PUBCP system goes into deep sleep mode, this pin will be set -input enable automatically. - -Moreover we can not use the "sleep" state, since some systems (like: -PUBCP system) do not run linux kernel OS (only AP system run linux -kernel on SC9860 platform), then we can not select "sleep" state -when the PUBCP system goes into deep sleep mode. Thus we introduce -"sprd,sleep-mode" property to set pin sleep mode. - -The last block comprises some misc registers which also have unified -register definition, and each register described one pin is used to -configure drive strength, pull up/down and so on. Especially for pull -up, we have two kind pull up resistor: 20K and 4.7K. - -Required properties for Spreadtrum pin controller: -- compatible: "sprd,-pinctrl" - Please refer to each sprd,-pinctrl.txt binding doc for supported SoCs. -- reg: The register address of pin controller device. -- pins : An array of pin names. - -Optional properties: -- function: Specified the function name. -- drive-strength: Drive strength in mA. -- input-schmitt-disable: Enable schmitt-trigger mode. -- input-schmitt-enable: Disable schmitt-trigger mode. -- bias-disable: Disable pin bias. -- bias-pull-down: Pull down on pin. -- bias-pull-up: Pull up on pin. -- input-enable: Enable pin input. -- input-disable: Enable pin output. -- output-high: Set the pin as an output level high. -- output-low: Set the pin as an output level low. -- sleep-hardware-state: Indicate these configs in this state are sleep related. -- sprd,control: Control values referring to databook for global control pins. -- sprd,sleep-mode: Sleep mode selection. - -Please refer to each sprd,-pinctrl.txt binding doc for supported values. diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt deleted file mode 100644 index 5a628333d52f2..0000000000000 --- a/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt +++ /dev/null @@ -1,70 +0,0 @@ -* Spreadtrum SC9860 Pin Controller - -Please refer to sprd,pinctrl.txt in this directory for common binding part -and usage. - -Required properties: -- compatible: Must be "sprd,sc9860-pinctrl". -- reg: The register address of pin controller device. -- pins : An array of strings, each string containing the name of a pin. - -Optional properties: -- function: A string containing the name of the function, values must be - one of: "func1", "func2", "func3" and "func4". -- drive-strength: Drive strength in mA. Supported values: 2, 4, 6, 8, 10, - 12, 14, 16, 20, 21, 24, 25, 27, 29, 31 and 33. -- input-schmitt-disable: Enable schmitt-trigger mode. -- input-schmitt-enable: Disable schmitt-trigger mode. -- bias-disable: Disable pin bias. -- bias-pull-down: Pull down on pin. -- bias-pull-up: Pull up on pin. Supported values: 20000 for pull-up resistor - is 20K and 4700 for pull-up resistor is 4.7K. -- input-enable: Enable pin input. -- input-disable: Enable pin output. -- output-high: Set the pin as an output level high. -- output-low: Set the pin as an output level low. -- sleep-hardware-state: Indicate these configs in this state are sleep related. -- sprd,control: Control values referring to databook for global control pins. -- sprd,sleep-mode: Choose the pin sleep mode, and supported values are: - AP_SLEEP, PUBCP_SLEEP, TGLDSP_SLEEP and AGDSP_SLEEP. - -Pin sleep mode definition: -enum pin_sleep_mode { - AP_SLEEP = BIT(0), - PUBCP_SLEEP = BIT(1), - TGLDSP_SLEEP = BIT(2), - AGDSP_SLEEP = BIT(3), -}; - -Example: -pin_controller: pinctrl@402a0000 { - compatible = "sprd,sc9860-pinctrl"; - reg = <0x402a0000 0x10000>; - - grp1: sd0 { - pins = "SC9860_VIO_SD2_IRTE", "SC9860_VIO_SD0_IRTE"; - sprd,control = <0x1>; - }; - - grp2: rfctl_33 { - pins = "SC9860_RFCTL33"; - function = "func2"; - sprd,sleep-mode = ; - grp2_sleep_mode: rfctl_33_sleep { - pins = "SC9860_RFCTL33"; - sleep-hardware-state; - output-low; - } - }; - - grp3: rfctl_misc_20 { - pins = "SC9860_RFCTL20_MISC"; - drive-strength = <10>; - bias-pull-up = <4700>; - grp3_sleep_mode: rfctl_misc_sleep { - pins = "SC9860_RFCTL20_MISC"; - sleep-hardware-state; - bias-pull-up; - } - }; -}; diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.yaml new file mode 100644 index 0000000000000..59d23eb8aa973 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.yaml @@ -0,0 +1,199 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/sprd,sc9860-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Spreadtrum SC9860 Pin Controller + +maintainers: + - Baolin Wang + +description: > + The Spreadtrum pin controller are organized in 3 blocks (types). + + The first block comprises some global control registers, and each + register contains several bit fields with one bit or several bits + to configure for some global common configuration, such as domain + pad driving level, system control select and so on ("domain pad + driving level": One pin can output 3.0v or 1.8v, depending on the + related domain pad driving selection, if the related domain pad + select 3.0v, then the pin can output 3.0v. "system control" is used + to choose one function (like: UART0) for which system, since we + have several systems (AP/CP/CM4) on one SoC.). + + There are too much various configuration that we can not list all + of them, so we can not make every Spreadtrum-special configuration + as one generic configuration, and maybe it will add more strange + global configuration in future. Then we add one "sprd,control" to + set these various global control configuration, and we need use + magic number for this property. + + Moreover we recognize every fields comprising one bit or several + bits in one global control register as one pin, thus we should + record every pin's bit offset, bit width and register offset to + configure this field (pin). + + The second block comprises some common registers which have unified + register definition, and each register described one pin is used + to configure the pin sleep mode, function select and sleep related + configuration. + + Now we have 4 systems for sleep mode on SC9860 SoC: AP system, + PUBCP system, TGLDSP system and AGDSP system. And the pin sleep + related configuration are: + - input-enable + - input-disable + - output-high + - output-low + - bias-pull-up + - bias-pull-down + + In some situation we need set the pin sleep mode and pin sleep related + configuration, to set the pin sleep related configuration automatically + by hardware when the system specified by sleep mode goes into deep + sleep mode. For example, if we set the pin sleep mode as PUBCP_SLEEP + and set the pin sleep related configuration as "input-enable", which + means when PUBCP system goes into deep sleep mode, this pin will be set + input enable automatically. + + Moreover we can not use the "sleep" state, since some systems (like: + PUBCP system) do not run linux kernel OS (only AP system run linux + kernel on SC9860 platform), then we can not select "sleep" state + when the PUBCP system goes into deep sleep mode. Thus we introduce + "sprd,sleep-mode" property to set pin sleep mode. + + The last block comprises some misc registers which also have unified + register definition, and each register described one pin is used to + configure drive strength, pull up/down and so on. Especially for pull + up, we have two kind pull up resistor: 20K and 4.7K. + +properties: + compatible: + const: sprd,sc9860-pinctrl + + reg: + maxItems: 1 + +additionalProperties: + $ref: '#/$defs/pin-node' + unevaluatedProperties: false + + properties: + function: + description: Function to assign to the pins. + enum: + - func1 + - func2 + - func3 + - func4 + + drive-strength: + description: Drive strength in mA. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [2, 4, 6, 8, 10, 12, 14, 16, 20, 21, 24, 25, 27, 29, 31, 33] + + input-schmitt-disable: true + + input-schmitt-enable: true + + bias-pull-up: + enum: [20000, 4700] + + sprd,sleep-mode: + description: Pin sleep mode selection. + $ref: /schemas/types.yaml#/definitions/uint32 + maximum: 0x1f + + sprd,control: + description: Control values referring to databook for global control pins. + $ref: /schemas/types.yaml#/definitions/uint32 + + patternProperties: + 'sleep$': + $ref: '#/$defs/pin-node' + unevaluatedProperties: false + + properties: + bias-pull-up: + type: boolean + + sleep-hardware-state: + description: Indicate these configs in sleep related state. + type: boolean + +$defs: + pin-node: + type: object + allOf: + - $ref: /schemas/pinctrl/pincfg-node.yaml# + - $ref: /schemas/pinctrl/pinmux-node.yaml# + + properties: + pins: + description: Names of pins to configure. + $ref: /schemas/types.yaml#/definitions/string-array + + bias-disable: + description: Disable pin bias. + type: boolean + + bias-pull-down: + description: Pull down on pin. + type: boolean + + bias-pull-up: true + + input-enable: + description: Enable pin input. + type: boolean + + input-disable: + description: Enable pin output. + type: boolean + + output-high: + description: Set the pin as an output level high. + type: boolean + + output-low: + description: Set the pin as an output level low. + type: boolean + +required: + - compatible + - reg + +examples: + - | + pin_controller: pinctrl@402a0000 { + compatible = "sprd,sc9860-pinctrl"; + reg = <0x402a0000 0x10000>; + + grp1: sd0 { + pins = "SC9860_VIO_SD2_IRTE", "SC9860_VIO_SD0_IRTE"; + sprd,control = <0x1>; + }; + + grp2: rfctl_33 { + pins = "SC9860_RFCTL33"; + function = "func2"; + sprd,sleep-mode = <3>; + grp2_sleep_mode: rfctl_33_sleep { + pins = "SC9860_RFCTL33"; + sleep-hardware-state; + output-low; + }; + }; + + grp3: rfctl_misc_20 { + pins = "SC9860_RFCTL20_MISC"; + drive-strength = <10>; + bias-pull-up = <4700>; + grp3_sleep_mode: rfctl_misc_sleep { + pins = "SC9860_RFCTL20_MISC"; + sleep-hardware-state; + bias-pull-up; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml index 961161c2ab62b..76d956b4a5372 100644 --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml @@ -151,6 +151,8 @@ patternProperties: pinctrl group available on the machine. Each subnode will list the pins it needs, and how they should be configured, with regard to muxer configuration, pullups, drive, output high/low and output speed. + $ref: /schemas/pinctrl/pincfg-node.yaml + properties: pinmux: $ref: /schemas/types.yaml#/definitions/uint32-array @@ -195,26 +197,19 @@ patternProperties: pinmux = ; }; - bias-disable: - type: boolean + bias-disable: true - bias-pull-down: - type: boolean + bias-pull-down: true - bias-pull-up: - type: boolean + bias-pull-up: true - drive-push-pull: - type: boolean + drive-push-pull: true - drive-open-drain: - type: boolean + drive-open-drain: true - output-low: - type: boolean + output-low: true - output-high: - type: boolean + output-high: true slew-rate: description: | @@ -222,15 +217,68 @@ patternProperties: 1: Medium speed 2: Fast speed 3: High speed - $ref: /schemas/types.yaml#/definitions/uint32 - enum: [0, 1, 2, 3] + minimum: 0 + maximum: 3 + + skew-delay-input-ps: + description: | + IO synchronization skew rate applied to the input path + enum: [0, 300, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000, 3250] + + skew-delay-output-ps: + description: | + IO synchronization latch delay applied to the output path + enum: [0, 300, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000, 3250] + + st,io-sync: + $ref: /schemas/types.yaml#/definitions/string + enum: + - pass-through + - clock inverted + - data on rising edge + - data on falling edge + - data on both edges + description: | + IO synchronization through re-sampling or inversion + "pass-through" - data or clock GPIO pass-through + "clock inverted" - clock GPIO inverted + "data on rising edge" - data GPIO re-sampled on clock rising edge + "data on falling edge" - data GPIO re-sampled on clock falling edge + "data on both edges" - data GPIO re-sampled on both clock edges + default: pass-through required: - pinmux + # Not allowed both skew-delay-input-ps and skew-delay-output-ps + if: + required: + - skew-delay-input-ps + then: + properties: + skew-delay-output-ps: false + allOf: - $ref: pinctrl.yaml# + - if: + not: + properties: + compatible: + contains: + enum: + - st,stm32mp257-pinctrl + - st,stm32mp257-z-pinctrl + then: + patternProperties: + '-[0-9]*$': + patternProperties: + '^pins': + properties: + skew-delay-input-ps: false + skew-delay-output-ps: false + st,io-sync: false + required: - compatible - '#address-cells' @@ -311,4 +359,25 @@ examples: pinctrl-names = "default"; }; + - | + #include + //Example 4 skew-delay and st,io-sync + pinctrl: pinctrl@44240000 { + compatible = "st,stm32mp257-pinctrl"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x44240000 0xa0400>; + + eth3_rgmii_pins_a: eth3-rgmii-0 { + pins1 { + pinmux = ; + st,io-sync = "data on both edges"; + }; + pins2 { + pinmux = ; + skew-delay-output-ps = <500>; + }; + }; + }; + ... diff --git a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml index f3258f2fd3a48..3f14eab01c54b 100644 --- a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml @@ -32,7 +32,6 @@ description: | | | | | | | ------- UART0 UART1 -- - The big MUX in the diagram only has 7 different ways of mapping peripherals on the left to pins on the right. StarFive calls the 7 configurations "signal groups". diff --git a/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml index ce04d2eadec9d..0eff0a0ee9e9d 100644 --- a/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml @@ -42,7 +42,6 @@ patternProperties: function: description: Function to mux. - $ref: /schemas/types.yaml#/definitions/string enum: [i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c8, spi0, spi1, spi2, spi3, spi4, spi5, spi6, uart0, uart1, uart2, uart3, pwm, pcmif_out, pcmif_in] diff --git a/Documentation/devicetree/bindings/power/actions,owl-sps.txt b/Documentation/devicetree/bindings/power/actions,owl-sps.txt deleted file mode 100644 index a3571937b0195..0000000000000 --- a/Documentation/devicetree/bindings/power/actions,owl-sps.txt +++ /dev/null @@ -1,21 +0,0 @@ -Actions Semi Owl Smart Power System (SPS) - -Required properties: -- compatible : "actions,s500-sps" for S500 - "actions,s700-sps" for S700 - "actions,s900-sps" for S900 -- reg : Offset and length of the register set for the device. -- #power-domain-cells : Must be 1. - See macros in: - include/dt-bindings/power/owl-s500-powergate.h for S500 - include/dt-bindings/power/owl-s700-powergate.h for S700 - include/dt-bindings/power/owl-s900-powergate.h for S900 - - -Example: - - sps: power-controller@b01b0100 { - compatible = "actions,s500-sps"; - reg = <0xb01b0100 0x100>; - #power-domain-cells = <1>; - }; diff --git a/Documentation/devicetree/bindings/power/actions,s500-sps.yaml b/Documentation/devicetree/bindings/power/actions,s500-sps.yaml new file mode 100644 index 0000000000000..bb942817b3dbf --- /dev/null +++ b/Documentation/devicetree/bindings/power/actions,s500-sps.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/actions,s500-sps.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Actions Semi Owl Smart Power System (SPS) + +maintainers: + - Andreas Färber + - Manivannan Sadhasivam + +properties: + compatible: + enum: + - actions,s500-sps + - actions,s700-sps + - actions,s900-sps + + reg: + maxItems: 1 + + '#power-domain-cells': + const: 1 + +required: + - compatible + - reg + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | + power-controller@b01b0100 { + compatible = "actions,s500-sps"; + reg = <0xb01b0100 0x100>; + #power-domain-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/power/mediatek,mt8196-gpufreq.yaml b/Documentation/devicetree/bindings/power/mediatek,mt8196-gpufreq.yaml new file mode 100644 index 0000000000000..b9e43abaf8a42 --- /dev/null +++ b/Documentation/devicetree/bindings/power/mediatek,mt8196-gpufreq.yaml @@ -0,0 +1,117 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/mediatek,mt8196-gpufreq.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MFlexGraphics Power and Frequency Controller + +maintainers: + - Nicolas Frattaroli + +description: + A special-purpose embedded MCU to control power and frequency of GPU devices + using MediaTek Flexible Graphics integration hardware. + +properties: + $nodename: + pattern: '^power-controller@[a-f0-9]+$' + + compatible: + enum: + - mediatek,mt8196-gpufreq + + reg: + items: + - description: GPR memory area + - description: RPC memory area + - description: SoC variant ID register + + reg-names: + items: + - const: gpr + - const: rpc + - const: hw-revision + + clocks: + items: + - description: main clock of the embedded controller (EB) + - description: core PLL + - description: stack 0 PLL + - description: stack 1 PLL + + clock-names: + items: + - const: eb + - const: core + - const: stack0 + - const: stack1 + + mboxes: + items: + - description: FastDVFS events + - description: frequency control + - description: sleep control + - description: timer control + - description: frequency hopping control + - description: hardware voter control + - description: FastDVFS control + + mbox-names: + items: + - const: fast-dvfs-event + - const: gpufreq + - const: sleep + - const: timer + - const: fhctl + - const: ccf + - const: fast-dvfs + + memory-region: + items: + - description: phandle to the GPUEB shared memory + + "#clock-cells": + const: 1 + + "#power-domain-cells": + const: 0 + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - mboxes + - mbox-names + - memory-region + - "#clock-cells" + - "#power-domain-cells" + +additionalProperties: false + +examples: + - | + #include + + power-controller@4b09fd00 { + compatible = "mediatek,mt8196-gpufreq"; + reg = <0x4b09fd00 0x80>, + <0x4b800000 0x1000>, + <0x4b860128 0x4>; + reg-names = "gpr", "rpc", "hw-revision"; + clocks = <&topckgen CLK_TOP_MFG_EB>, + <&mfgpll CLK_MFG_AO_MFGPLL>, + <&mfgpll_sc0 CLK_MFGSC0_AO_MFGPLL_SC0>, + <&mfgpll_sc1 CLK_MFGSC1_AO_MFGPLL_SC1>; + clock-names = "eb", "core", "stack0", "stack1"; + mboxes = <&gpueb_mbox 0>, <&gpueb_mbox 1>, <&gpueb_mbox 2>, + <&gpueb_mbox 3>, <&gpueb_mbox 4>, <&gpueb_mbox 5>, + <&gpueb_mbox 7>; + mbox-names = "fast-dvfs-event", "gpufreq", "sleep", "timer", "fhctl", + "ccf", "fast-dvfs"; + memory-region = <&gpueb_shared_memory>; + #clock-cells = <1>; + #power-domain-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml index 500d98921581a..f8a13928f615b 100644 --- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml +++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml @@ -33,6 +33,9 @@ properties: - mediatek,mt8188-power-controller - mediatek,mt8192-power-controller - mediatek,mt8195-power-controller + - mediatek,mt8196-hwv-hfrp-power-controller + - mediatek,mt8196-hwv-scp-power-controller + - mediatek,mt8196-power-controller - mediatek,mt8365-power-controller '#power-domain-cells': @@ -157,6 +160,7 @@ allOf: contains: enum: - mediatek,mt8183-power-controller + - mediatek,mt8196-power-controller then: properties: access-controllers: diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index af5fef872529b..27af5b8aa1340 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -18,6 +18,7 @@ properties: oneOf: - enum: - qcom,glymur-rpmhpd + - qcom,kaanapali-rpmhpd - qcom,mdm9607-rpmpd - qcom,milos-rpmhpd - qcom,msm8226-rpmpd diff --git a/Documentation/devicetree/bindings/power/renesas,sysc-rmobile.yaml b/Documentation/devicetree/bindings/power/renesas,sysc-rmobile.yaml index fba6914ec40d8..948a9da111dfa 100644 --- a/Documentation/devicetree/bindings/power/renesas,sysc-rmobile.yaml +++ b/Documentation/devicetree/bindings/power/renesas,sysc-rmobile.yaml @@ -45,7 +45,7 @@ properties: const: 0 additionalProperties: - $ref: "#/$defs/pd-node" + $ref: '#/$defs/pd-node' required: - compatible @@ -83,7 +83,7 @@ $defs: - '#power-domain-cells' additionalProperties: - $ref: "#/$defs/pd-node" + $ref: '#/$defs/pd-node' examples: - | diff --git a/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml b/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml index a884e49c995fb..b41db576f95de 100644 --- a/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml +++ b/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml @@ -46,6 +46,7 @@ properties: - rockchip,rk3576-power-controller - rockchip,rk3588-power-controller - rockchip,rv1126-power-controller + - rockchip,rv1126b-power-controller "#power-domain-cells": const: 1 @@ -126,6 +127,7 @@ $defs: "include/dt-bindings/power/rk3568-power.h" "include/dt-bindings/power/rk3588-power.h" "include/dt-bindings/power/rockchip,rv1126-power.h" + "include/dt-bindings/power/rockchip,rv1126b-power-controller.h" clocks: minItems: 1 diff --git a/Documentation/devicetree/bindings/power/supply/mt6360_charger.yaml b/Documentation/devicetree/bindings/power/supply/mt6360_charger.yaml index 4c74cc78729e7..3e8689019251d 100644 --- a/Documentation/devicetree/bindings/power/supply/mt6360_charger.yaml +++ b/Documentation/devicetree/bindings/power/supply/mt6360_charger.yaml @@ -21,7 +21,6 @@ properties: description: Maximum CHGIN regulation voltage in uV. enum: [ 5500000, 6500000, 11000000, 14500000 ] - usb-otg-vbus-regulator: type: object description: OTG boost regulator. diff --git a/Documentation/devicetree/bindings/power/supply/richtek,rt9756.yaml b/Documentation/devicetree/bindings/power/supply/richtek,rt9756.yaml new file mode 100644 index 0000000000000..a88bf6cd1927a --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/richtek,rt9756.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/supply/richtek,rt9756.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Richtek RT9756 Smart Cap Divider Charger + +maintainers: + - ChiYuan Huang + +description: | + The RT9756/RT9757 is a high efficiency and high charge current charger. + + The efficiency is up to 98.2% when VBAT = 4V, IBAT = 2A in DIV2 mode and 99.1% + when VBAT=4V, IBAT=1A in bypass mode. The maximum charger current is up to 8A + in DIV2 mode and 5A in bypass mode. The device integrates smart cap divider + topology, direct charging mode, external over-voltage protection control, an + input reverse blocking NFET and 2-way regulation, a dual phase charge pump + core, 8-Channel high speed ADCs and USB BC 1.2 detection. + + RT9770 is almost the same with RT9756/57, only BC 1.2 detection function is + removed to shrink the die size. + +allOf: + - $ref: power-supply.yaml# + +properties: + compatible: + oneOf: + - enum: + - richtek,rt9756 + - richtek,rt9770 + - items: + - enum: + - richtek,rt9757 + - const: richtek,rt9756 + + reg: + maxItems: 1 + + wakeup-source: true + + interrupts: + maxItems: 1 + + shunt-resistor-micro-ohms: + description: Battery current sense resistor mounted. + default: 2000 + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + charger@6f { + compatible = "richtek,rt9756"; + reg = <0x6f>; + wakeup-source; + interrupts-extended = <&gpio_intc 32 IRQ_TYPE_EDGE_FALLING>; + shunt-resistor-micro-ohms = <5000>; + }; + }; diff --git a/Documentation/devicetree/bindings/power/supply/samsung,battery.yaml b/Documentation/devicetree/bindings/power/supply/samsung,battery.yaml index 40292d581b105..fa1ccff043bed 100644 --- a/Documentation/devicetree/bindings/power/supply/samsung,battery.yaml +++ b/Documentation/devicetree/bindings/power/supply/samsung,battery.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Samsung SDI Batteries maintainers: - - Linus Walleij + - Linus Walleij description: | Samsung SDI (Samsung Digital Interface) batteries are all different versions diff --git a/Documentation/devicetree/bindings/power/supply/stericsson,ab8500-charger.yaml b/Documentation/devicetree/bindings/power/supply/stericsson,ab8500-charger.yaml index 994fac12c8da0..4f19744844e9c 100644 --- a/Documentation/devicetree/bindings/power/supply/stericsson,ab8500-charger.yaml +++ b/Documentation/devicetree/bindings/power/supply/stericsson,ab8500-charger.yaml @@ -65,7 +65,6 @@ properties: - const: vbus_v - const: usb_charger_c - required: - compatible - monitored-battery diff --git a/Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml b/Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml index 1b192e197b114..1197858e431f2 100644 --- a/Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml +++ b/Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml @@ -55,7 +55,6 @@ properties: resets: maxItems: 1 - allOf: - $ref: pwm.yaml# diff --git a/Documentation/devicetree/bindings/pwm/thead,th1520-pwm.yaml b/Documentation/devicetree/bindings/pwm/thead,th1520-pwm.yaml new file mode 100644 index 0000000000000..855aec59ac53c --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/thead,th1520-pwm.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pwm/thead,th1520-pwm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: T-HEAD TH1520 PWM controller + +maintainers: + - Michal Wilczynski + +allOf: + - $ref: pwm.yaml# + +properties: + compatible: + const: thead,th1520-pwm + + reg: + maxItems: 1 + + clocks: + items: + - description: SoC PWM clock + + "#pwm-cells": + const: 3 + +required: + - compatible + - reg + - clocks + +unevaluatedProperties: false + +examples: + - | + #include + soc { + #address-cells = <2>; + #size-cells = <2>; + pwm@ffec01c000 { + compatible = "thead,th1520-pwm"; + reg = <0xff 0xec01c000 0x0 0x4000>; + clocks = <&clk CLK_PWM>; + #pwm-cells = <3>; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/da9211.txt b/Documentation/devicetree/bindings/regulator/da9211.txt deleted file mode 100644 index eb871447d5082..0000000000000 --- a/Documentation/devicetree/bindings/regulator/da9211.txt +++ /dev/null @@ -1,205 +0,0 @@ -* Dialog Semiconductor DA9211/DA9212/DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 - Voltage Regulator - -Required properties: -- compatible: "dlg,da9211" or "dlg,da9212" or "dlg,da9213" or "dlg,da9223" - or "dlg,da9214" or "dlg,da9224" or "dlg,da9215" or "dlg,da9225" -- reg: I2C slave address, usually 0x68. -- interrupts: the interrupt outputs of the controller -- regulators: A node that houses a sub-node for each regulator within the - device. Each sub-node is identified using the node's name, with valid - values listed below. The content of each sub-node is defined by the - standard binding for regulators; see regulator.txt. - BUCKA and BUCKB. - -Optional properties: -- enable-gpios: platform gpio for control of BUCKA/BUCKB. -- Any optional property defined in regulator.txt - - regulator-initial-mode and regulator-allowed-modes may be specified using - mode values from dt-bindings/regulator/dlg,da9211-regulator.h - -Example 1) DA9211 - pmic: da9211@68 { - compatible = "dlg,da9211"; - reg = <0x68>; - interrupts = <3 27>; - - regulators { - BUCKA { - regulator-name = "VBUCKA"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <2000000>; - regulator-max-microamp = <5000000>; - enable-gpios = <&gpio 27 0>; - regulator-allowed-modes = ; - }; - }; - }; - -Example 2) DA9212 - pmic: da9212@68 { - compatible = "dlg,da9212"; - reg = <0x68>; - interrupts = <3 27>; - - regulators { - BUCKA { - regulator-name = "VBUCKA"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <2000000>; - regulator-max-microamp = <5000000>; - enable-gpios = <&gpio 27 0>; - }; - BUCKB { - regulator-name = "VBUCKB"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <2000000>; - regulator-max-microamp = <5000000>; - enable-gpios = <&gpio 17 0>; - }; - }; - }; - -Example 3) DA9213 - pmic: da9213@68 { - compatible = "dlg,da9213"; - reg = <0x68>; - interrupts = <3 27>; - - regulators { - BUCKA { - regulator-name = "VBUCKA"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <3000000>; - regulator-max-microamp = <6000000>; - enable-gpios = <&gpio 27 0>; - }; - }; - }; - -Example 4) DA9223 - pmic: da9223@68 { - compatible = "dlg,da9223"; - reg = <0x68>; - interrupts = <3 27>; - - regulators { - BUCKA { - regulator-name = "VBUCKA"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <3000000>; - regulator-max-microamp = <6000000>; - enable-gpios = <&gpio 27 0>; - }; - }; - }; - -Example 5) DA9214 - pmic: da9214@68 { - compatible = "dlg,da9214"; - reg = <0x68>; - interrupts = <3 27>; - - regulators { - BUCKA { - regulator-name = "VBUCKA"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <3000000>; - regulator-max-microamp = <6000000>; - enable-gpios = <&gpio 27 0>; - }; - BUCKB { - regulator-name = "VBUCKB"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <3000000>; - regulator-max-microamp = <6000000>; - enable-gpios = <&gpio 17 0>; - }; - }; - }; - -Example 6) DA9224 - pmic: da9224@68 { - compatible = "dlg,da9224"; - reg = <0x68>; - interrupts = <3 27>; - - regulators { - BUCKA { - regulator-name = "VBUCKA"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <3000000>; - regulator-max-microamp = <6000000>; - enable-gpios = <&gpio 27 0>; - }; - BUCKB { - regulator-name = "VBUCKB"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <3000000>; - regulator-max-microamp = <6000000>; - enable-gpios = <&gpio 17 0>; - }; - }; - }; - -Example 7) DA9215 - pmic: da9215@68 { - compatible = "dlg,da9215"; - reg = <0x68>; - interrupts = <3 27>; - - regulators { - BUCKA { - regulator-name = "VBUCKA"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <4000000>; - regulator-max-microamp = <7000000>; - enable-gpios = <&gpio 27 0>; - }; - BUCKB { - regulator-name = "VBUCKB"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <4000000>; - regulator-max-microamp = <7000000>; - enable-gpios = <&gpio 17 0>; - }; - }; - }; - -Example 8) DA9225 - pmic: da9225@68 { - compatible = "dlg,da9225"; - reg = <0x68>; - interrupts = <3 27>; - - regulators { - BUCKA { - regulator-name = "VBUCKA"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <4000000>; - regulator-max-microamp = <7000000>; - enable-gpios = <&gpio 27 0>; - }; - BUCKB { - regulator-name = "VBUCKB"; - regulator-min-microvolt = < 300000>; - regulator-max-microvolt = <1570000>; - regulator-min-microamp = <4000000>; - regulator-max-microamp = <7000000>; - enable-gpios = <&gpio 17 0>; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/regulator/dlg,da9211.yaml b/Documentation/devicetree/bindings/regulator/dlg,da9211.yaml new file mode 100644 index 0000000000000..4d7e495a6f599 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/dlg,da9211.yaml @@ -0,0 +1,103 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/dlg,da9211.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: + Dialog Semiconductor DA9211-9215, DA9223-9225 Voltage Regulators + +maintainers: + - Ariel D'Alessandro + +properties: + compatible: + enum: + - dlg,da9211 + - dlg,da9212 + - dlg,da9213 + - dlg,da9214 + - dlg,da9215 + - dlg,da9223 + - dlg,da9224 + - dlg,da9225 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + regulators: + type: object + additionalProperties: false + description: + List of regulators provided by the device + + patternProperties: + "^BUCK([AB])$": + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + description: + Properties for a single BUCK regulator + + properties: + regulator-initial-mode: + items: + enum: [ 1, 2, 3 ] + description: + Defined in include/dt-bindings/regulator/dlg,da9211-regulator.h + + regulator-allowed-modes: + items: + enum: [ 1, 2, 3 ] + description: + Defined in include/dt-bindings/regulator/dlg,da9211-regulator.h + + enable-gpios: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - regulators + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + regulator@68 { + compatible = "dlg,da9212"; + reg = <0x68>; + interrupts = <3 27>; + + regulators { + BUCKA { + regulator-name = "VBUCKA"; + regulator-min-microvolt = < 300000>; + regulator-max-microvolt = <1570000>; + regulator-min-microamp = <2000000>; + regulator-max-microamp = <5000000>; + enable-gpios = <&gpio 27 0>; + }; + BUCKB { + regulator-name = "VBUCKB"; + regulator-min-microvolt = < 300000>; + regulator-max-microvolt = <1570000>; + regulator-min-microamp = <2000000>; + regulator-max-microamp = <5000000>; + enable-gpios = <&gpio 17 0>; + }; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/regulator/fitipower,fp9931.yaml b/Documentation/devicetree/bindings/regulator/fitipower,fp9931.yaml new file mode 100644 index 0000000000000..c6585e3bacbec --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/fitipower,fp9931.yaml @@ -0,0 +1,110 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/fitipower,fp9931.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: FitiPower FP9931/JD9930 Power Management Integrated Circuit + +maintainers: + - Andreas Kemnade + +description: + FP9931 is a Power Management IC to provide Power for EPDs with one 3.3V + switch, 2 symmetric LDOs behind 2 DC/DC converters, and one unsymmetric + regulator for a compensation voltage. + JD9930 has in addition some kind of night mode. + +properties: + compatible: + oneOf: + - const: fitipower,fp9931 + + - items: + - const: fitipower,jd9930 + - const: fitipower,fp9931 + + reg: + maxItems: 1 + + enable-gpios: + maxItems: 1 + + pg-gpios: + maxItems: 1 + + en-ts-gpios: + maxItems: 1 + + xon-gpios: + maxItems: 1 + + vin-supply: + description: + Supply for the whole chip. Some vendor kernels and devicetrees + declare this as a non-existing GPIO named "pwrall". + + fitipower,tdly-ms: + description: + Power up soft start delay settings tDLY1-4 bitfields in the + POWERON_DELAY register + items: + - enum: [0, 1, 2, 4] + - enum: [0, 1, 2, 4] + - enum: [0, 1, 2, 4] + - enum: [0, 1, 2, 4] + + regulators: + type: object + additionalProperties: false + patternProperties: + "^(vcom|vposneg|v3p3)$": + unevaluatedProperties: false + type: object + $ref: /schemas/regulator/regulator.yaml + +required: + - compatible + - reg + - pg-gpios + - enable-gpios + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@18 { + compatible = "fitipower,fp9931"; + reg = <0x18>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fp9931_gpio>; + vin-supply = <&epd_pmic_supply>; + pg-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>; + en-ts-gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; + fitipower,tdly-ms = <2 2 4 4>; + + regulators { + vcom { + regulator-name = "vcom"; + regulator-min-microvolt = <2352840>; + regulator-max-microvolt = <2352840>; + }; + + vposneg { + regulator-name = "vposneg"; + regulator-min-microvolt = <15060000>; + regulator-max-microvolt = <15060000>; + }; + + v3p3 { + regulator-name = "v3p3"; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/mediatek,mt6316b-regulator.yaml b/Documentation/devicetree/bindings/regulator/mediatek,mt6316b-regulator.yaml new file mode 100644 index 0000000000000..ea595935f4c4d --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/mediatek,mt6316b-regulator.yaml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/mediatek,mt6316b-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT6316 BP/VP SPMI PMIC Regulators + +maintainers: + - AngeloGioacchino Del Regno + +description: + The MediaTek MT6316BP/VP PMICs are fully controlled by SPMI interface, both + feature four step-down DC/DC (buck) converters, and provides 2+2 Phases, + joining Buck 1+2 for the first phase, and Buck 3+4 for the second phase. + +properties: + compatible: + const: mediatek,mt6316b-regulator + + reg: + maxItems: 1 + +patternProperties: + "^vbuck(12|34)$": + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + properties: + regulator-allowed-modes: + description: | + Allowed Buck regulator operating modes allowed. Valid values below. + 0 - Normal mode with automatic power saving, reducing the switching + frequency when light load conditions are detected + 1 - Forced Continuous Conduction mode (FCCM) for improved voltage + regulation accuracy with constant switching frequency but lower + regulator efficiency + 2 - Forced Low Power mode for improved regulator efficiency, used + when no heavy load is expected, will shut down unnecessary IP + blocks and secondary phases to reduce quiescent current. + This mode does not limit the maximum output current but unless + only a light load is applied, there will be regulation accuracy + and efficiency losses. + minItems: 1 + maxItems: 3 + items: + enum: [ 0, 1, 2 ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + + spmi { + #address-cells = <2>; + #size-cells = <0>; + + pmic@8 { + compatible = "mediatek,mt6316b-regulator"; + reg = <0x8 SPMI_USID>; + + vbuck12 { + regulator-name = "dvdd_core"; + regulator-min-microvolt = <450000>; + regulator-max-microvolt = <965000>; + regulator-allowed-modes = <0 1 2>; + regulator-enable-ramp-delay = <256>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/regulator/mediatek,mt6316c-regulator.yaml b/Documentation/devicetree/bindings/regulator/mediatek,mt6316c-regulator.yaml new file mode 100644 index 0000000000000..186dcd3f11ed0 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/mediatek,mt6316c-regulator.yaml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/mediatek,mt6316c-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT6316 CP/HP/KP SPMI PMIC Regulators + +maintainers: + - AngeloGioacchino Del Regno + +description: + The MediaTek MT6316CP/HP/KP PMICs are fully controlled by SPMI interface, + features four step-down DC/DC (buck) converters, and provides 3+1 Phases, + joining Buck 1+2+4 for the first phase, and uses Buck 3 for the second. + +properties: + compatible: + const: mediatek,mt6316c-regulator + + reg: + maxItems: 1 + +patternProperties: + "^vbuck(124|3)$": + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + properties: + regulator-allowed-modes: + description: | + Allowed Buck regulator operating modes allowed. Valid values below. + 0 - Normal mode with automatic power saving, reducing the switching + frequency when light load conditions are detected + 1 - Forced Continuous Conduction mode (FCCM) for improved voltage + regulation accuracy with constant switching frequency but lower + regulator efficiency + 2 - Forced Low Power mode for improved regulator efficiency, used + when no heavy load is expected, will shut down unnecessary IP + blocks and secondary phases to reduce quiescent current. + This mode does not limit the maximum output current but unless + only a light load is applied, there will be regulation accuracy + and efficiency losses. + minItems: 1 + maxItems: 3 + items: + enum: [ 0, 1, 2 ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + + spmi { + #address-cells = <2>; + #size-cells = <0>; + + pmic@6 { + compatible = "mediatek,mt6316c-regulator"; + reg = <0x6 SPMI_USID>; + + vbuck124 { + regulator-name = "dvdd_proc_m"; + regulator-min-microvolt = <450000>; + regulator-max-microvolt = <1277500>; + regulator-allowed-modes = <0 1 2>; + regulator-enable-ramp-delay = <256>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/regulator/mediatek,mt6316d-regulator.yaml b/Documentation/devicetree/bindings/regulator/mediatek,mt6316d-regulator.yaml new file mode 100644 index 0000000000000..aa9e9ef3b52d9 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/mediatek,mt6316d-regulator.yaml @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/mediatek,mt6316d-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT6316 DP/TP SPMI PMIC Regulators + +maintainers: + - AngeloGioacchino Del Regno + +description: + The MediaTek MT6316DP/TP PMICs are fully controlled by SPMI interface, both + feature four step-down DC/DC (buck) converters, and provides a single Phase, + joining Buck 1+2+3+4. + +properties: + compatible: + const: mediatek,mt6316d-regulator + + reg: + maxItems: 1 + + vbuck1234: + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + properties: + regulator-allowed-modes: + description: | + Allowed Buck regulator operating modes allowed. Valid values below. + 0 - Normal mode with automatic power saving, reducing the switching + frequency when light load conditions are detected + 1 - Forced Continuous Conduction mode (FCCM) for improved voltage + regulation accuracy with constant switching frequency but lower + regulator efficiency + 2 - Forced Low Power mode for improved regulator efficiency, used + when no heavy load is expected, will shut down unnecessary IP + blocks and secondary phases to reduce quiescent current. + This mode does not limit the maximum output current but unless + only a light load is applied, there will be regulation accuracy + and efficiency losses. + minItems: 1 + maxItems: 3 + items: + enum: [ 0, 1, 2 ] + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + + spmi { + #address-cells = <2>; + #size-cells = <0>; + + pmic@7 { + compatible = "mediatek,mt6316d-regulator"; + reg = <0x7 SPMI_USID>; + + vbuck1234 { + regulator-name = "dvdd_gpustack"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1277500>; + regulator-allowed-modes = <0 1 2>; + regulator-enable-ramp-delay = <256>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/regulator/mediatek,mt6363-regulator.yaml b/Documentation/devicetree/bindings/regulator/mediatek,mt6363-regulator.yaml new file mode 100644 index 0000000000000..4f79d4f81d499 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/mediatek,mt6363-regulator.yaml @@ -0,0 +1,146 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/mediatek,mt6363-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT6363 PMIC Regulators + +maintainers: + - AngeloGioacchino Del Regno + +description: + The MT6363 SPMI PMIC provides 10 BUCK and 25 LDO (Low DropOut) regulators + and can optionally provide overcurrent warnings with one ocp interrupt + for each voltage regulator. + +properties: + compatible: + const: mediatek,mt6363-regulator + + reg: + maxItems: 1 + + vsys-vbuck1-supply: + description: Input supply for vbuck1 + + vsys-vbuck2-supply: + description: Input supply for vbuck2 + + vsys-vbuck3-supply: + description: Input supply for vbuck3 + + vsys-vbuck4-supply: + description: Input supply for vbuck4 + + vsys-vbuck5-supply: + description: Input supply for vbuck5 + + vsys-vbuck6-supply: + description: Input supply for vbuck6 + + vsys-vbuck7-supply: + description: Input supply for vbuck7 + + vsys-vs1-supply: + description: Input supply for vs1 + + vsys-vs2-supply: + description: Input supply for vs2 + + vsys-vs3-supply: + description: Input supply for vs3 + + vs1-ldo1-supply: + description: Input supply for va15, vio0p75, vm18, vrf18, vrf-io18 + + vs1-ldo2-supply: + description: Input supply for vcn15, vio18, vufs18 + + vs2-ldo1-supply: + description: Input supply for vsram-cpub, vsram-cpum, vrf12, vrf13, vufs12 + + vs2-ldo2-supply: + description: Input supply for va12-1, va12-2, vcn13, vsram-cpul + + vs3-ldo1-supply: + description: Input supply for vsram-apu, vsram-digrf, vsram-mdfe + + vs3-ldo2-supply: + description: Input supply for vsram-modem, vrf0p9 + + vsys-ldo1-supply: + description: Input supply for vaux18, vemc, vtref18 + +patternProperties: + "^v(buck[1-7]|s[1-3])$": + description: Buck regulators + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + properties: + regulator-allowed-modes: + description: | + Allowed Buck regulator operating modes allowed. Valid values below. + 0 - Normal mode with automatic power saving, reducing the switching + frequency when light load conditions are detected + 1 - Forced Continuous Conduction mode (FCCM) for improved voltage + regulation accuracy with constant switching frequency but lower + regulator efficiency + 2 - Forced Low Power mode for improved regulator efficiency, used + when no heavy load is expected, does not limit the maximum out + current but unless only a light load is applied, there will be + regulation accuracy and efficiency losses. + 3 - Forced Ultra Low Power mode for ultra low load, this greatly + reduces the maximum output power, makes the regulator to be + efficient only for ultra light load, and greatly reduces the + quiescent current (Iq) of the buck. + maxItems: 3 + items: + enum: [ 0, 1, 2, 3 ] + + "^va(12-1|12-2|15)$": + $ref: "#/$defs/ldo-common" + + "^v(aux|m|rf-io|tref)18$": + $ref: "#/$defs/ldo-common" + + "^v(cn13|cn15|emc)$": + $ref: "#/$defs/ldo-common" + + "^vio(0p75|18)$": + $ref: "#/$defs/ldo-common" + + "^vrf(0p9|12|13|18)$": + $ref: "#/$defs/ldo-common" + + "^vsram-(apu|cpub|cpum|cpul|digrf|mdfe|modem)$": + $ref: "#/$defs/ldo-common" + + "^vufs(12|18)$": + $ref: "#/$defs/ldo-common" + +$defs: + ldo-common: + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + properties: + regulator-allowed-modes: + description: | + Allowed LDO regulator operating modes allowed. Valid values below. + 0 - Normal mode with automatic power saving, reducing the switching + frequency when light load conditions are detected + 2 - Forced Low Power mode for improved regulator efficiency, used + when no heavy load is expected, does not limit the maximum out + current but unless only a light load is applied, there will be + regulation accuracy and efficiency losses. + maxItems: 2 + items: + enum: [ 0, 2 ] + +required: + - compatible + - reg + +additionalProperties: false diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml index a5486c36830f0..ec04adfb9d1cb 100644 --- a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml @@ -41,6 +41,21 @@ properties: interrupts: maxItems: 1 + inl1-supply: + description: Regulator supply for the INL1 pin group, powering LDOx + + inb13-supply: + description: + Regulator supply for the INB13 pin group, powering BUCK1 and BUCK3. + + inb26-supply: + description: + Regulator supply for the INB26 pin group, powering BUCK2 and BUCK6. + + inb45-supply: + description: + Regulator supply for the INB45 pin group, powering BUCK4 and BUCK5. + regulators: type: object description: | @@ -124,6 +139,30 @@ properties: When WDOG_B signal is asserted a warm reset will be done instead of cold reset. + nxp,pmic-on-req-on-debounce-us: + enum: [ 120, 20000, 100000, 750000 ] + description: Debounce time for PMIC_ON_REQ high. + + nxp,pmic-on-req-off-debounce-us: + enum: [ 120, 2000 ] + description: Debounce time for PMIC_ON_REQ is asserted low + + nxp,power-on-step-ms: + enum: [ 1, 2, 4, 8] + description: Time step configuration during power on sequence + + nxp,power-down-step-ms: + enum: [ 2, 4, 8, 16 ] + description: Time step configuration during power down sequence + + nxp,restart-ms: + enum: [ 250, 500 ] + description: Time to stay off regulators during Cold reset + + npx,pmic-rst-b-debounce-ms: + enum: [ 10, 50, 100, 500, 1000, 2000, 4000, 8000 ] + description: PMIC_RST_B debounce time + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml index 4c5b0629aa3e6..58bb0ad5dda44 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml @@ -8,7 +8,7 @@ title: Qualcomm Technologies, Inc. RPMh Regulators maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: | rpmh-regulator devices support PMIC regulator management via the Voltage @@ -51,10 +51,15 @@ description: | For PM8450, smps1 - smps6, ldo1 - ldo4 For PM8550, smps1 - smps6, ldo1 - ldo17, bob1 - bob2 For PM8998, smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2 + For PMH0101, ldo1 - ldo18, bob1 - bob2 + For PMH0104, smps1 - smps4 + For PMH0110, smps1 - smps10, ldo1 - ldo4 For PMI8998, bob For PMC8380, smps1 - smps8, ldo1 - lodo3 + For PMCX0102, smps1 - smps10, ldo1 - ldo4 For PMR735A, smps1 - smps3, ldo1 - ldo7 For PMR735B, ldo1 - ldo12 + For PMR735D, ldo1 - ldo7 For PMX55, smps1 - smps7, ldo1 - ldo16 For PMX65, smps1 - smps8, ldo1 - ldo21 For PMX75, smps1 - smps10, ldo1 - ldo21 @@ -85,12 +90,17 @@ properties: - qcom,pmc8180-rpmh-regulators - qcom,pmc8180c-rpmh-regulators - qcom,pmc8380-rpmh-regulators + - qcom,pmcx0102-rpmh-regulators - qcom,pmg1110-rpmh-regulators + - qcom,pmh0101-rpmh-regulators + - qcom,pmh0104-rpmh-regulators + - qcom,pmh0110-rpmh-regulators - qcom,pmi8998-rpmh-regulators - qcom,pmm8155au-rpmh-regulators - qcom,pmm8654au-rpmh-regulators - qcom,pmr735a-rpmh-regulators - qcom,pmr735b-rpmh-regulators + - qcom,pmr735d-rpmh-regulators - qcom,pmx55-rpmh-regulators - qcom,pmx65-rpmh-regulators - qcom,pmx75-rpmh-regulators @@ -100,7 +110,7 @@ properties: RPMh resource name suffix used for the regulators found on this PMIC. $ref: /schemas/types.yaml#/definitions/string - enum: [a, b, c, d, e, f, g, h, i, j, k, l, m, n] + pattern: "^[a-n]|[A-N]_E[0-3]+$" qcom,always-wait-for-ack: description: | @@ -246,6 +256,7 @@ allOf: compatible: enum: - qcom,pm8005-rpmh-regulators + - qcom,pmh0104-rpmh-regulators then: patternProperties: "^vdd-s[1-4]-supply$": true @@ -422,6 +433,34 @@ allOf: properties: vdd-s1-supply: true + - if: + properties: + compatible: + enum: + - qcom,pmh0101-rpmh-regulators + then: + properties: + vdd-l1-l4-l10-supply: true + vdd-l2-l13-l14-supply: true + vdd-l3-l11-supply: true + vdd-l5-l16-supply: true + vdd-l6-l7-supply: true + vdd-l8-l9-supply: true + patternProperties: + "^vdd-l(1[2578])-supply$": true + "^vdd-bob[1-2]-supply$": true + + - if: + properties: + compatible: + enum: + - qcom,pmcx0102-rpmh-regulators + - qcom,pmh0110-rpmh-regulators + then: + patternProperties: + "^vdd-l[1-4]-supply$": true + "^vdd-s([1-9]|10)-supply$": true + - if: properties: compatible: @@ -459,6 +498,18 @@ allOf: patternProperties: "^vdd-l([3-6]|9|1[0-2])-supply$": true + - if: + properties: + compatible: + enum: + - qcom,pmr735d-rpmh-regulators + then: + properties: + vdd-l1-l2-l5-supply: true + vdd-l3-l4-supply: true + patternProperties: + "^vdd-l[6-7]-supply$": true + - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/regulator/richtek,rt6245-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rt6245-regulator.yaml index b73762e151bbd..84546fec3b185 100644 --- a/Documentation/devicetree/bindings/regulator/richtek,rt6245-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/richtek,rt6245-regulator.yaml @@ -55,7 +55,6 @@ properties: delay time 0us, 10us, 20us, 40us. If this property is missing then keep in chip default. - richtek,switch-freq-select: $ref: /schemas/types.yaml#/definitions/uint8 enum: [0, 1, 2] diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml index 661c2b425da35..137f950283133 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml @@ -24,6 +24,7 @@ properties: - qcom,msm8998-adsp-pas - qcom,msm8998-slpi-pas - qcom,sdm660-adsp-pas + - qcom,sdm660-cdsp-pas - qcom,sdm845-adsp-pas - qcom,sdm845-cdsp-pas - qcom,sdm845-slpi-pas @@ -31,9 +32,6 @@ properties: reg: maxItems: 1 - cx-supply: - description: Phandle to the CX regulator - px-supply: description: Phandle to the PX regulator @@ -69,6 +67,8 @@ allOf: - qcom,msm8996-slpi-pil - qcom,msm8998-adsp-pas - qcom,msm8998-slpi-pas + - qcom,sdm660-adsp-pas + - qcom,sdm660-cdsp-pas - qcom,sdm845-adsp-pas - qcom,sdm845-cdsp-pas - qcom,sdm845-slpi-pas @@ -93,6 +93,8 @@ allOf: - qcom,msm8996-slpi-pil - qcom,msm8998-adsp-pas - qcom,msm8998-slpi-pas + - qcom,sdm660-adsp-pas + - qcom,sdm660-cdsp-pas - qcom,sdm845-adsp-pas - qcom,sdm845-cdsp-pas - qcom,sdm845-slpi-pas @@ -103,16 +105,6 @@ allOf: interrupt-names: maxItems: 5 - - if: - properties: - compatible: - contains: - enum: - - qcom,msm8974-adsp-pil - then: - required: - - cx-supply - - if: properties: compatible: @@ -120,8 +112,11 @@ allOf: enum: - qcom,msm8226-adsp-pil - qcom,msm8953-adsp-pil + - qcom,msm8974-adsp-pil - qcom,msm8996-adsp-pil - qcom,msm8998-adsp-pas + - qcom,sdm660-adsp-pas + - qcom,sdm660-cdsp-pas then: properties: power-domains: @@ -178,6 +173,7 @@ allOf: - qcom,msm8998-adsp-pas - qcom,msm8998-slpi-pas - qcom,sdm660-adsp-pas + - qcom,sdm660-cdsp-pas then: properties: qcom,qmp: false @@ -187,6 +183,7 @@ examples: #include #include #include + #include adsp { compatible = "qcom,msm8974-adsp-pil"; @@ -204,7 +201,8 @@ examples: clocks = <&rpmcc RPM_CXO_CLK>; clock-names = "xo"; - cx-supply = <&pm8841_s2>; + power-domains = <&rpmpd MSM8974_VDDCX>; + power-domain-names = "cx"; memory-region = <&adsp_region>; diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sc8280xp-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sc8280xp-pas.yaml index 96d53baf6e007..5dbda3a550477 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sc8280xp-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sc8280xp-pas.yaml @@ -91,9 +91,13 @@ allOf: power-domains: items: - description: NSP power domain + - description: CX power domain + - description: MXC power domain power-domain-names: items: - const: nsp + - const: cx + - const: mxc unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml index a492f74a86081..a927551356e69 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml @@ -79,7 +79,6 @@ properties: It should be set as 3 (Single-Core mode) which is also the default if omitted. - # R5F Processor Child Nodes: # ========================== @@ -167,7 +166,6 @@ patternProperties: - description: region reserved for firmware image sections additionalItems: true - # Optional properties: # -------------------- # The following properties are optional properties for each of the R5F cores: diff --git a/Documentation/devicetree/bindings/reset/eswin,eic7700-reset.yaml b/Documentation/devicetree/bindings/reset/eswin,eic7700-reset.yaml new file mode 100644 index 0000000000000..cf2fdb9075710 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/eswin,eic7700-reset.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/eswin,eic7700-reset.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ESWIN EIC7700 SoC reset controller + +maintainers: + - Yifeng Huang + - Xuyang Dong + +description: + The system reset controller can be used to reset various peripheral + controllers in ESWIN eic7700 SoC. + +properties: + compatible: + const: eswin,eic7700-reset + + reg: + maxItems: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + - '#reset-cells' + +additionalProperties: false + +examples: + - | + #include + + reset-controller@51828300 { + compatible = "eswin,eic7700-reset"; + reg = <0x51828300 0x200>; + #reset-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/reset/microchip,rst.yaml b/Documentation/devicetree/bindings/reset/microchip,rst.yaml index f2da0693b05a0..e190e526f3e9a 100644 --- a/Documentation/devicetree/bindings/reset/microchip,rst.yaml +++ b/Documentation/devicetree/bindings/reset/microchip,rst.yaml @@ -20,9 +20,14 @@ properties: pattern: "^reset-controller@[0-9a-f]+$" compatible: - enum: - - microchip,sparx5-switch-reset - - microchip,lan966x-switch-reset + oneOf: + - enum: + - microchip,sparx5-switch-reset + - microchip,lan966x-switch-reset + - items: + - enum: + - microchip,lan9691-switch-reset + - const: microchip,lan966x-switch-reset reg: items: diff --git a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml index b0b20af15313b..c83469a1b379a 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml +++ b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml @@ -15,12 +15,14 @@ description: properties: compatible: - items: - - enum: - - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five - - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC} - - renesas,r9a07g054-usbphy-ctrl # RZ/V2L - - const: renesas,rzg2l-usbphy-ctrl + oneOf: + - items: + - enum: + - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five + - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC} + - renesas,r9a07g054-usbphy-ctrl # RZ/V2L + - const: renesas,rzg2l-usbphy-ctrl + - const: renesas,r9a08g045-usbphy-ctrl # RZ/G3S reg: maxItems: 1 @@ -48,6 +50,20 @@ properties: $ref: /schemas/regulator/regulator.yaml# unevaluatedProperties: false + renesas,sysc-pwrrdy: + description: + The system controller PWRRDY indicates to the USB PHY if the power supply + is ready. PWRRDY needs to be set during power-on before applying any + other settings. It also needs to be set before powering off the USB. + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: + System controller phandle required by USB PHY CTRL driver to set + PWRRDY + - description: Register offset associated with PWRRDY + - description: Register bitmask associated with PWRRDY + required: - compatible - reg @@ -57,6 +73,19 @@ required: - '#reset-cells' - regulator-vbus +allOf: + - if: + properties: + compatible: + contains: + const: renesas,r9a08g045-usbphy-ctrl + then: + required: + - renesas,sysc-pwrrdy + else: + properties: + renesas,sysc-pwrrdy: false + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml b/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml index f2e91d0add7a6..7b5053c177fe1 100644 --- a/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml +++ b/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml @@ -16,7 +16,13 @@ maintainers: properties: compatible: enum: - - thead,th1520-reset + - thead,th1520-reset # Reset controller for VO subsystem + - thead,th1520-reset-ao + - thead,th1520-reset-ap + - thead,th1520-reset-dsp + - thead,th1520-reset-misc + - thead,th1520-reset-vi + - thead,th1520-reset-vp reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/reset/ti,sci-reset.yaml b/Documentation/devicetree/bindings/reset/ti,sci-reset.yaml index 1db08ce9ae270..68640abacd954 100644 --- a/Documentation/devicetree/bindings/reset/ti,sci-reset.yaml +++ b/Documentation/devicetree/bindings/reset/ti,sci-reset.yaml @@ -40,7 +40,6 @@ properties: Please see https://software-dl.ti.com/tisci/esd/latest/index.html for protocol documentation for the values to be used for different devices. - additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/riscv/anlogic.yaml b/Documentation/devicetree/bindings/riscv/anlogic.yaml new file mode 100644 index 0000000000000..91b1526c99aa3 --- /dev/null +++ b/Documentation/devicetree/bindings/riscv/anlogic.yaml @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/riscv/anlogic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Anlogic SoC-based boards + +maintainers: + - Junhui Liu + +description: + Anlogic SoC-based boards + +properties: + $nodename: + const: '/' + compatible: + oneOf: + - items: + - enum: + - milianke,mlkpai-fs01 + - const: anlogic,dr1v90 + +additionalProperties: true + +... diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml index 153d0dac57fb3..d733c0bd534fb 100644 --- a/Documentation/devicetree/bindings/riscv/cpus.yaml +++ b/Documentation/devicetree/bindings/riscv/cpus.yaml @@ -48,6 +48,7 @@ properties: - amd,mbv64 - andestech,ax45mp - canaan,k210 + - nuclei,ux900 - sifive,bullet0 - sifive,e5 - sifive,e7 @@ -70,6 +71,7 @@ properties: - enum: - sifive,e51 - sifive,u54-mc + - sifive,x280 - const: sifive,rocket0 - const: riscv - const: riscv # Simulator only diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml index 543ac94718e8c..5bab356addc84 100644 --- a/Documentation/devicetree/bindings/riscv/extensions.yaml +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml @@ -217,6 +217,12 @@ properties: memory types as ratified in the 20191213 version of the privileged ISA specification. + - const: svrsw60t59b + description: + The Svrsw60t59b extension for providing two more bits[60:59] to + PTE/PMD entry as ratified at commit 28bde925e7a7 ("PTE Reserved + for SW bits 60:59") of riscv-non-isa/riscv-iommu. + - const: svvptc description: The standard Svvptc supervisor-level extension for @@ -242,6 +248,11 @@ properties: is supported as ratified at commit 5059e0ca641c ("update to ratified") of the riscv-zacas. + - const: zalasr + description: | + The standard Zalasr extension for load-acquire/store-release as frozen + at commit 194f0094 ("Version 0.9 for freeze") of riscv-zalasr. + - const: zalrsc description: | The standard Zalrsc extension for load-reserved/store-conditional as @@ -366,6 +377,20 @@ properties: guarantee on LR/SC sequences, as ratified in commit b1d806605f87 ("Updated to ratified state.") of the riscv profiles specification. + - const: zilsd + description: + The standard Zilsd extension which provides support for aligned + register-pair load and store operations in 32-bit instruction + encodings, as ratified in commit f88abf1 ("Integrating + load/store pair for RV32 with the main manual") of riscv-isa-manual. + + - const: zclsd + description: + The Zclsd extension implements the compressed (16-bit) version of the + Load/Store Pair for RV32. As with Zilsd, this extension was ratified + in commit f88abf1 ("Integrating load/store pair for RV32 with the + main manual") of riscv-isa-manual. + - const: zk description: The standard Zk Standard Scalar cryptography extension as ratified @@ -871,6 +896,16 @@ properties: anyOf: - const: v - const: zve32x + # Zclsd depends on Zilsd and Zca + - if: + contains: + anyOf: + - const: zclsd + then: + contains: + allOf: + - const: zilsd + - const: zca allOf: # Zcf extension does not exist on rv64 @@ -888,6 +923,18 @@ allOf: not: contains: const: zcf + # Zilsd extension does not exist on rv64 + - if: + properties: + riscv,isa-base: + contains: + const: rv64i + then: + properties: + riscv,isa-extensions: + not: + contains: + const: zilsd additionalProperties: true ... diff --git a/Documentation/devicetree/bindings/riscv/spacemit.yaml b/Documentation/devicetree/bindings/riscv/spacemit.yaml index c56b62a6299ac..9c49482002f76 100644 --- a/Documentation/devicetree/bindings/riscv/spacemit.yaml +++ b/Documentation/devicetree/bindings/riscv/spacemit.yaml @@ -22,6 +22,8 @@ properties: - enum: - bananapi,bpi-f3 - milkv,jupiter + - spacemit,musepi-pro + - xunlong,orangepi-r2s - xunlong,orangepi-rv2 - const: spacemit,k1 diff --git a/Documentation/devicetree/bindings/riscv/starfive.yaml b/Documentation/devicetree/bindings/riscv/starfive.yaml index 04510341a71e8..9253aab215188 100644 --- a/Documentation/devicetree/bindings/riscv/starfive.yaml +++ b/Documentation/devicetree/bindings/riscv/starfive.yaml @@ -33,8 +33,15 @@ properties: - pine64,star64 - starfive,visionfive-2-v1.2a - starfive,visionfive-2-v1.3b + - xunlong,orangepi-rv - const: starfive,jh7110 + - items: + - enum: + - starfive,visionfive-2-lite + - starfive,visionfive-2-lite-emmc + - const: starfive,jh7110s + additionalProperties: true ... diff --git a/Documentation/devicetree/bindings/riscv/tenstorrent.yaml b/Documentation/devicetree/bindings/riscv/tenstorrent.yaml new file mode 100644 index 0000000000000..e15359b2aab63 --- /dev/null +++ b/Documentation/devicetree/bindings/riscv/tenstorrent.yaml @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/riscv/tenstorrent.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Tenstorrent SoC-based boards + +maintainers: + - Drew Fustini + - Joel Stanley + +description: + Tenstorrent SoC-based boards + +properties: + $nodename: + const: '/' + compatible: + oneOf: + - description: Tenstorrent Blackhole PCIe card + items: + - const: tenstorrent,blackhole-card + - const: tenstorrent,blackhole + +additionalProperties: true + +... diff --git a/Documentation/devicetree/bindings/rng/inside-secure,safexcel-eip76.yaml b/Documentation/devicetree/bindings/rng/inside-secure,safexcel-eip76.yaml index 0877eb44f9edc..f501fc7691c6e 100644 --- a/Documentation/devicetree/bindings/rng/inside-secure,safexcel-eip76.yaml +++ b/Documentation/devicetree/bindings/rng/inside-secure,safexcel-eip76.yaml @@ -44,7 +44,6 @@ properties: - const: core - const: reg - allOf: - if: properties: @@ -58,7 +57,6 @@ allOf: required: - interrupts - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/rng/intel,ixp46x-rng.yaml b/Documentation/devicetree/bindings/rng/intel,ixp46x-rng.yaml index 9f7590ce6b3d6..146593a669d66 100644 --- a/Documentation/devicetree/bindings/rng/intel,ixp46x-rng.yaml +++ b/Documentation/devicetree/bindings/rng/intel,ixp46x-rng.yaml @@ -12,7 +12,7 @@ description: | 32 bit random number. maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml b/Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml new file mode 100644 index 0000000000000..ec0a736793c7e --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/andestech,atcrtc100.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Andes ATCRTC100 Real-Time Clock + +maintainers: + - CL Wang + +allOf: + - $ref: rtc.yaml# + +properties: + compatible: + enum: + - andestech,atcrtc100 + + reg: + maxItems: 1 + + interrupts: + items: + - description: Periodic timekeeping interrupt + - description: RTC alarm interrupt + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + #include + + rtc@f0300000 { + compatible = "andestech,atcrtc100"; + reg = <0xf0300000 0x100>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>, <2 IRQ_TYPE_LEVEL_HIGH>; + }; diff --git a/Documentation/devicetree/bindings/rtc/apple,smc-rtc.yaml b/Documentation/devicetree/bindings/rtc/apple,smc-rtc.yaml new file mode 100644 index 0000000000000..607b610665a28 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/apple,smc-rtc.yaml @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/apple,smc-rtc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple SMC RTC + +description: + Apple Silicon Macs (M1, etc.) have an RTC that is part of the PMU IC, + but most of the PMU functionality is abstracted out by the SMC. + An additional RTC offset stored inside NVMEM is required to compute + the current date/time. + +maintainers: + - Sven Peter + +properties: + compatible: + const: apple,smc-rtc + + nvmem-cells: + items: + - description: 48bit RTC offset, specified in 32768 (2^15) Hz clock ticks + + nvmem-cell-names: + items: + - const: rtc_offset + +required: + - compatible + - nvmem-cells + - nvmem-cell-names + +additionalProperties: false diff --git a/Documentation/devicetree/bindings/rtc/faraday,ftrtc010.yaml b/Documentation/devicetree/bindings/rtc/faraday,ftrtc010.yaml index b1c1a0e213188..2b1215b495807 100644 --- a/Documentation/devicetree/bindings/rtc/faraday,ftrtc010.yaml +++ b/Documentation/devicetree/bindings/rtc/faraday,ftrtc010.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Faraday Technology FTRTC010 Real Time Clock maintainers: - - Linus Walleij + - Linus Walleij description: | This RTC appears in for example the Storlink Gemini family of SoCs. diff --git a/Documentation/devicetree/bindings/rtc/nvidia,vrs-10.yaml b/Documentation/devicetree/bindings/rtc/nvidia,vrs-10.yaml new file mode 100644 index 0000000000000..c7dbc8b83c004 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/nvidia,vrs-10.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/nvidia,vrs-10.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVIDIA Voltage Regulator Specification Real Time Clock + +maintainers: + - Shubhi Garg + +description: + NVIDIA VRS-10 (Voltage Regulator Specification) is a Power Management IC + (PMIC) that implements a power sequencing solution with I2C interface. + The device includes a real-time clock (RTC) with 32kHz clock output and + backup battery support, alarm functionality for system wake-up from + suspend and shutdown states, OTP memory for power sequencing configuration, + and an interrupt controller for managing VRS events. + +properties: + compatible: + const: nvidia,vrs-10 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + +required: + - compatible + - reg + - interrupts + - interrupt-controller + - '#interrupt-cells' + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@3c { + compatible = "nvidia,vrs-10"; + reg = <0x3c>; + interrupt-parent = <&pmc>; + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; diff --git a/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml b/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml index e70eeb66aa648..ccb1638c35b9b 100644 --- a/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml +++ b/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml @@ -9,14 +9,12 @@ title: Renesas RTCA-3 Real Time Clock maintainers: - Claudiu Beznea -allOf: - - $ref: rtc.yaml# - properties: compatible: items: - enum: - renesas,r9a08g045-rtca3 # RZ/G3S + - renesas,r9a09g057-rtca3 # RZ/V2H - const: renesas,rz-rtca3 reg: @@ -48,8 +46,12 @@ properties: maxItems: 1 resets: - items: - - description: VBATTB module reset + minItems: 1 + maxItems: 2 + + reset-names: + minItems: 1 + maxItems: 2 required: - compatible @@ -61,6 +63,39 @@ required: - power-domains - resets +allOf: + - $ref: rtc.yaml# + + - if: + properties: + compatible: + contains: + const: renesas,r9a08g045-rtca3 + then: + properties: + resets: + items: + - description: VBATTB module reset + reset-names: + const: vbattb + - if: + properties: + compatible: + contains: + const: renesas,r9a09g057-rtca3 + then: + properties: + resets: + items: + - description: RTC reset + - description: Reset for the RTEST registers + reset-names: + items: + - const: rtc + - const: rtest + required: + - reset-names + additionalProperties: false examples: @@ -81,4 +116,5 @@ examples: clock-names = "bus", "counter"; power-domains = <&cpg>; resets = <&cpg R9A08G045_VBAT_BRESETN>; + reset-names = "vbattb"; }; diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml index b243afa69a1ae..167ddcbd88005 100644 --- a/Documentation/devicetree/bindings/serial/8250.yaml +++ b/Documentation/devicetree/bindings/serial/8250.yaml @@ -125,6 +125,8 @@ properties: - nxp,lpc1850-uart - opencores,uart16550-rtlsvn105 - ti,da830-uart + - loongson,ls2k0500-uart + - loongson,ls2k1500-uart - const: ns16550a - items: - enum: @@ -169,6 +171,18 @@ properties: - nvidia,tegra194-uart - nvidia,tegra234-uart - const: nvidia,tegra20-uart + - items: + - enum: + - loongson,ls2k1000-uart + - const: loongson,ls2k0500-uart + - const: ns16550a + - items: + - enum: + - loongson,ls3a5000-uart + - loongson,ls3a6000-uart + - loongson,ls2k2000-uart + - const: loongson,ls2k1500-uart + - const: ns16550a reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml b/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml index ea6abfe2d95e5..bc2e487548052 100644 --- a/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml @@ -8,7 +8,7 @@ title: Qualcomm MSM SoC Serial UART maintainers: - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: The MSM serial UART hardware is designed for low-speed use cases where a diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml index e0fa363ad7e2e..788ef5c1c4469 100644 --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml @@ -9,7 +9,7 @@ title: Qualcomm MSM Serial UARTDM maintainers: - Andy Gross - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: | The MSM serial UARTDM hardware is designed for high-speed use cases where the diff --git a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml index f50d8e02f4764..6b1f827a335b3 100644 --- a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml @@ -54,8 +54,6 @@ properties: power-domains: maxItems: 1 - uart-has-rtscts: false - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml index 1a1f991d53649..75ac2a08f2576 100644 --- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml +++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml @@ -48,7 +48,9 @@ properties: - const: samsung,exynos850-uart - items: - enum: + - axis,artpec9-uart - samsung,exynos7870-uart + - samsung,exynos8890-uart - const: samsung,exynos8895-uart reg: diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml index cb9da6c97afcf..6efe43089a74d 100644 --- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml +++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml @@ -51,6 +51,7 @@ properties: - const: renesas,rzn1-uart - items: - enum: + - anlogic,dr1v90-uart - brcm,bcm11351-dw-apb-uart - brcm,bcm21664-dw-apb-uart - rockchip,px30-uart @@ -64,6 +65,7 @@ properties: - rockchip,rk3328-uart - rockchip,rk3368-uart - rockchip,rk3399-uart + - rockchip,rk3506-uart - rockchip,rk3528-uart - rockchip,rk3562-uart - rockchip,rk3568-uart diff --git a/Documentation/devicetree/bindings/slimbus/qcom,slim-ngd.yaml b/Documentation/devicetree/bindings/slimbus/qcom,slim-ngd.yaml index abf61c15246eb..27a92b79c7241 100644 --- a/Documentation/devicetree/bindings/slimbus/qcom,slim-ngd.yaml +++ b/Documentation/devicetree/bindings/slimbus/qcom,slim-ngd.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm SoC SLIMBus Non Generic Device (NGD) Controller maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla description: diff --git a/Documentation/devicetree/bindings/slimbus/slimbus.yaml b/Documentation/devicetree/bindings/slimbus/slimbus.yaml index 89017d9cda109..5a941610ce4ed 100644 --- a/Documentation/devicetree/bindings/slimbus/slimbus.yaml +++ b/Documentation/devicetree/bindings/slimbus/slimbus.yaml @@ -75,16 +75,22 @@ examples: #size-cells = <1>; ranges; - slim@28080000 { + controller@28080000 { compatible = "qcom,slim-ngd-v1.5.0"; reg = <0x091c0000 0x2c000>; interrupts = ; - #address-cells = <2>; + dmas = <&slimbam 3>, <&slimbam 4>; + dma-names = "rx", "tx"; + #address-cells = <1>; #size-cells = <0>; - - audio-codec@1,0 { + slim@1 { + reg = <1>; + #address-cells = <2>; + #size-cells = <0>; + codec@1,0 { compatible = "slim217,1a0"; reg = <1 0>; + }; }; + }; }; - }; diff --git a/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-pm.yaml b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-pm.yaml index e28ef198a801c..039c8e4a4c51b 100644 --- a/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-pm.yaml +++ b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-pm.yaml @@ -13,23 +13,21 @@ description: | maintainers: - Nicolas Saenz Julienne -allOf: - - $ref: /schemas/watchdog/watchdog.yaml# - properties: compatible: items: - enum: - brcm,bcm2835-pm - brcm,bcm2711-pm + - brcm,bcm2712-pm - const: brcm,bcm2835-pm-wdt reg: - minItems: 2 + minItems: 1 maxItems: 3 reg-names: - minItems: 2 + minItems: 1 items: - const: pm - const: asb @@ -62,7 +60,35 @@ required: - reg - "#power-domain-cells" - "#reset-cells" - - clocks + +allOf: + - $ref: /schemas/watchdog/watchdog.yaml# + + - if: + properties: + compatible: + contains: + enum: + - brcm,bcm2835-pm + - brcm,bcm2711-pm + then: + required: + - clocks + + properties: + reg: + minItems: 2 + + reg-names: + minItems: 2 + + else: + properties: + reg: + maxItems: 1 + + reg-names: + maxItems: 1 additionalProperties: false diff --git a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe-muram.yaml b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe-muram.yaml index cf0f38dbbe0da..2c06d869fdb5f 100644 --- a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe-muram.yaml +++ b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe-muram.yaml @@ -30,7 +30,6 @@ properties: $ref: /schemas/types.yaml#/definitions/string enum: [host, slave] - patternProperties: '^data\-only@[a-f0-9]+$': type: object diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml index b77ce8c6a935e..721a67e84c137 100644 --- a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml @@ -51,6 +51,22 @@ properties: type: object $ref: /schemas/mux/reg-mux.yaml +patternProperties: + "^ipu[12]_csi[01]_mux$": + type: object + $ref: /schemas/media/video-mux.yaml + +allOf: + - if: + properties: + compatible: + not: + contains: + const: fsl,imx6q-iomuxc-gpr + then: + patternProperties: + '^ipu[12]_csi[01]_mux$': false + additionalProperties: false required: diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml index a10326a9683d6..5267cfe92572d 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml +++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml @@ -91,7 +91,6 @@ allOf: required: - clocks - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml index 54c0cd64d3094..e7c4a3984c601 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml +++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml @@ -52,6 +52,7 @@ properties: - items: - enum: - mediatek,mt8188-pwrap + - mediatek,mt8189-pwrap - const: mediatek,mt8195-pwrap - const: syscon diff --git a/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml b/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml index 2c7275c4503b5..668b943db1732 100644 --- a/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml +++ b/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml @@ -57,7 +57,7 @@ properties: const: 0 patternProperties: - "^timer@[0-2]$": + '^timer@[0-2]$': description: The timer block channels that are used as timers or counters. type: object additionalProperties: false @@ -80,7 +80,7 @@ patternProperties: - compatible - reg - "^pwm@[0-2]$": + '^pwm@[0-2]$': description: The timer block channels that are used as PWMs. $ref: /schemas/pwm/pwm.yaml# type: object @@ -92,7 +92,7 @@ patternProperties: TCB channel to use for this PWM. enum: [ 0, 1, 2 ] - "#pwm-cells": + '#pwm-cells': description: The only third cell flag supported by this binding is PWM_POLARITY_INVERTED. @@ -101,11 +101,10 @@ patternProperties: required: - compatible - reg - - "#pwm-cells" + - '#pwm-cells' additionalProperties: false - allOf: - if: properties: diff --git a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml new file mode 100644 index 0000000000000..39987f7224118 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip PolarFire SoC Microprocessor Subsystem (MSS) sysreg register region + +maintainers: + - Conor Dooley + +description: + An wide assortment of registers that control elements of the MSS on PolarFire + SoC, including pinmuxing, resets and clocks among others. + +properties: + compatible: + items: + - const: microchip,mpfs-mss-top-sysreg + - const: syscon + - const: simple-mfd + + reg: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 1 + + '#reset-cells': + description: + The AHB/AXI peripherals on the PolarFire SoC have reset support, so + from CLK_ENVM to CLK_CFM. The reset consumer should specify the + desired peripheral via the clock ID in its "resets" phandle cell. + See include/dt-bindings/clock/microchip,mpfs-clock.h for the full list + of PolarFire clock/reset IDs. + const: 1 + + pinctrl@200: + type: object + $ref: /schemas/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + syscon@20002000 { + compatible = "microchip,mpfs-mss-top-sysreg", "syscon", "simple-mfd"; + reg = <0x20002000 0x1000>; + #reset-cells = <1>; + }; + diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml index 851a1260f8dc8..c5c1bac2db013 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml @@ -25,6 +25,8 @@ properties: compatible: items: - enum: + - qcom,glymur-aoss-qmp + - qcom,kaanapali-aoss-qmp - qcom,milos-aoss-qmp - qcom,qcs615-aoss-qmp - qcom,qcs8300-aoss-qmp diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.yaml index c33704333e495..d9f6d34a61c64 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.yaml @@ -9,7 +9,7 @@ title: Qualcomm General Serial Bus Interface (GSBI) maintainers: - Andy Gross - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: The GSBI controller is modeled as a node with zero or more child nodes, each diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.yaml index d9fabefc8147b..b667f4afdb552 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.yaml @@ -9,7 +9,7 @@ title: Qualcomm Shared Memory Driver maintainers: - Andy Gross - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: The Qualcomm Shared Memory Driver is a FIFO based communication channel for diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.yaml index 1ba1d419e83bb..f912768228586 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.yaml @@ -9,7 +9,7 @@ title: Qualcomm Shared Memory Point 2 Point maintainers: - Andy Gross - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: The Shared Memory Point to Point (SMP2P) protocol facilitates communication diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smsm.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,smsm.yaml index 4900215f26af7..67d4a7cb9eeb3 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smsm.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smsm.yaml @@ -9,7 +9,7 @@ title: Qualcomm Shared Memory State Machine maintainers: - Andy Gross - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: The Shared Memory State Machine facilitates broadcasting of single bit state diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml index dca5e27b82330..0b8e3294c83e8 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml +++ b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml @@ -317,7 +317,6 @@ allOf: properties: clocks: false - examples: - | #include diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml index f0fb24156da9b..6de47489ee42f 100644 --- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml @@ -55,6 +55,7 @@ properties: - samsung,exynos2200-pmu - samsung,exynos7870-pmu - samsung,exynos7885-pmu + - samsung,exynos8890-pmu - samsung,exynos8895-pmu - samsung,exynos9810-pmu - samsung,exynos990-pmu @@ -172,6 +173,7 @@ allOf: - samsung,exynos5250-pmu - samsung,exynos5420-pmu - samsung,exynos5433-pmu + - samsung,exynos7870-pmu then: properties: mipi-phy: true diff --git a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml index d8b302f975474..5e1e155510b3b 100644 --- a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml @@ -15,7 +15,9 @@ properties: - items: - enum: - google,gs101-apm-sysreg + - google,gs101-hsi0-sysreg - google,gs101-hsi2-sysreg + - google,gs101-misc-sysreg - google,gs101-peric0-sysreg - google,gs101-peric1-sysreg - samsung,exynos2200-cmgp-sysreg @@ -26,10 +28,14 @@ properties: - samsung,exynos3-sysreg - samsung,exynos4-sysreg - samsung,exynos5-sysreg + - samsung,exynos7870-cam0-sysreg + - samsung,exynos7870-disp-sysreg - samsung,exynos8895-fsys0-sysreg - samsung,exynos8895-fsys1-sysreg - samsung,exynos8895-peric0-sysreg - samsung,exynos8895-peric1-sysreg + - samsung,exynos990-peric0-sysreg + - samsung,exynos990-peric1-sysreg - samsung,exynosautov920-hsi2-sysreg - samsung,exynosautov920-peric0-sysreg - samsung,exynosautov920-peric1-sysreg @@ -73,6 +79,9 @@ properties: clocks: maxItems: 1 + power-domains: + maxItems: 1 + required: - compatible - reg @@ -83,7 +92,9 @@ allOf: compatible: contains: enum: + - google,gs101-hsi0-sysreg - google,gs101-hsi2-sysreg + - google,gs101-misc-sysreg - google,gs101-peric0-sysreg - google,gs101-peric1-sysreg - samsung,exynos850-cmgp-sysreg @@ -93,6 +104,8 @@ allOf: - samsung,exynos8895-fsys1-sysreg - samsung,exynos8895-peric0-sysreg - samsung,exynos8895-peric1-sysreg + - samsung,exynos990-peric0-sysreg + - samsung,exynos990-peric1-sysreg then: required: - clocks @@ -100,6 +113,16 @@ allOf: properties: clocks: false + - if: + properties: + compatible: + not: + contains: + pattern: "^google,gs101-[^-]+-sysreg$" + then: + properties: + power-domains: false + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/soc/sophgo/sophgo,cv1800b-top-syscon.yaml b/Documentation/devicetree/bindings/soc/sophgo/sophgo,cv1800b-top-syscon.yaml new file mode 100644 index 0000000000000..b2e8e0cb4ea6f --- /dev/null +++ b/Documentation/devicetree/bindings/soc/sophgo/sophgo,cv1800b-top-syscon.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/sophgo/sophgo,cv1800b-top-syscon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sophgo CV18XX/SG200X SoC top system controller + +maintainers: + - Inochi Amaoto + +description: + The Sophgo CV18XX/SG200X SoC top misc system controller provides + register access to configure related modules. + +properties: + compatible: + oneOf: + - items: + - const: sophgo,cv1800b-top-syscon + - const: syscon + - const: simple-mfd + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + + ranges: true + + dma-router@154: + $ref: /schemas/dma/sophgo,cv1800b-dmamux.yaml# + unevaluatedProperties: false + + phy@48: + $ref: /schemas/phy/sophgo,cv1800b-usb2-phy.yaml# + unevaluatedProperties: false + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + +additionalProperties: false + +examples: + - | + #include + + syscon@3000000 { + compatible = "sophgo,cv1800b-top-syscon", "syscon", "simple-mfd"; + reg = <0x03000000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + phy@48 { + compatible = "sophgo,cv1800b-usb2-phy"; + reg = <0x48 0x4>; + #phy-cells = <0>; + clocks = <&clk CLK_USB_125M>, + <&clk CLK_USB_33K>, + <&clk CLK_USB_12M>; + clock-names = "app", "stb", "lpm"; + resets = <&rst 58>; + }; + + dma-router@154 { + compatible = "sophgo,cv1800b-dmamux"; + reg = <0x154 0x8>, <0x298 0x4>; + #dma-cells = <2>; + dma-masters = <&dmac>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml index 7140c312d8986..f516960dbbefb 100644 --- a/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml +++ b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml @@ -133,12 +133,12 @@ properties: property. The supported-hw is a bitfield indicating SoC speedo or process ID mask. - "#power-domain-cells": + '#power-domain-cells': const: 0 required: - operating-points-v2 - - "#power-domain-cells" + - '#power-domain-cells' i2c-thermtrip: type: object @@ -220,7 +220,7 @@ properties: xusbc USB Partition C Tegra114/124/210 patternProperties: - "^[a-z0-9]+$": + '^[a-z0-9]+$': type: object additionalProperties: false properties: @@ -365,9 +365,9 @@ allOf: additionalProperties: false dependencies: - nvidia,suspend-mode: ["nvidia,core-pwr-off-time", "nvidia,cpu-pwr-off-time"] - nvidia,core-pwr-off-time: ["nvidia,core-pwr-good-time"] - nvidia,cpu-pwr-off-time: ["nvidia,cpu-pwr-good-time"] + nvidia,suspend-mode: ['nvidia,core-pwr-off-time', 'nvidia,cpu-pwr-off-time'] + nvidia,core-pwr-off-time: ['nvidia,core-pwr-good-time'] + nvidia,cpu-pwr-off-time: ['nvidia,cpu-pwr-good-time'] examples: - | diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml index b5336bcbfb01a..d97e88433d2fb 100644 --- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml +++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml @@ -11,7 +11,6 @@ maintainers: - Suman Anna description: |+ - The Programmable Real-Time Unit and Industrial Communication Subsystem (PRU-ICSS a.k.a. PRUSS) is present on various TI SoCs such as AM335x, AM437x, Keystone 66AK2G, OMAP-L138/DA850 etc. A PRUSS consists of dual 32-bit RISC @@ -44,7 +43,6 @@ description: |+ integration within the IP and the SoC. These nodes are described in the following sections. - PRU-ICSS Node ============== Each PRU-ICSS instance is represented as its own node with the individual PRU @@ -54,7 +52,6 @@ description: |+ See ../../mfd/syscon.yaml for generic SysCon binding details. - properties: $nodename: pattern: "^(pruss|icssg)@[0-9a-f]+$" diff --git a/Documentation/devicetree/bindings/sound/adi,adau1372.yaml b/Documentation/devicetree/bindings/sound/adi,adau1372.yaml index ea62e51aba90b..9a7ff50a0a22d 100644 --- a/Documentation/devicetree/bindings/sound/adi,adau1372.yaml +++ b/Documentation/devicetree/bindings/sound/adi,adau1372.yaml @@ -4,7 +4,6 @@ $id: http://devicetree.org/schemas/sound/adi,adau1372.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# - title: Analog Devices ADAU1372 CODEC maintainers: diff --git a/Documentation/devicetree/bindings/sound/adi,adau7002.yaml b/Documentation/devicetree/bindings/sound/adi,adau7002.yaml index fcca0fde7d866..7858f3f8ec2f6 100644 --- a/Documentation/devicetree/bindings/sound/adi,adau7002.yaml +++ b/Documentation/devicetree/bindings/sound/adi,adau7002.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Analog Devices ADAU7002 Stereo PDM-to-I2S/TDM Converter maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski allOf: - $ref: dai-common.yaml# diff --git a/Documentation/devicetree/bindings/sound/adi,adau7118.yaml b/Documentation/devicetree/bindings/sound/adi,adau7118.yaml index 12f60507aed7d..11f59c29b5751 100644 --- a/Documentation/devicetree/bindings/sound/adi,adau7118.yaml +++ b/Documentation/devicetree/bindings/sound/adi,adau7118.yaml @@ -4,7 +4,6 @@ $id: http://devicetree.org/schemas/sound/adi,adau7118.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# - title: Analog Devices ADAU7118 8 Channel PDM to I2S/TDM Converter maintainers: diff --git a/Documentation/devicetree/bindings/sound/adi,max98363.yaml b/Documentation/devicetree/bindings/sound/adi,max98363.yaml deleted file mode 100644 index c388cda560113..0000000000000 --- a/Documentation/devicetree/bindings/sound/adi,max98363.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/adi,max98363.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Analog Devices MAX98363 SoundWire Amplifier - -maintainers: - - Ryan Lee - -description: - The MAX98363 is a SoundWire input Class D mono amplifier that - supports MIPI SoundWire v1.2-compatible digital interface for - audio and control data. - SoundWire peripheral device ID of MAX98363 is 0x3*019f836300 - where * is the peripheral device unique ID decoded from pin. - It supports up to 10 peripheral devices(0x0 to 0x9). - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: sdw3019f836300 - - reg: - maxItems: 1 - - '#sound-dai-cells': - const: 0 - -required: - - compatible - - reg - - "#sound-dai-cells" - -unevaluatedProperties: false - -examples: - - | - soundwire@3250000 { - #address-cells = <2>; - #size-cells = <0>; - reg = <0x3250000 0x2000>; - - speaker@0,0 { - compatible = "sdw3019f836300"; - reg = <0 0>; - #sound-dai-cells = <0>; - sound-name-prefix = "Speaker Left"; - }; - - speaker@0,1 { - compatible = "sdw3019f836300"; - reg = <0 1>; - #sound-dai-cells = <0>; - sound-name-prefix = "Speaker Right"; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/adi,ssm2602.txt b/Documentation/devicetree/bindings/sound/adi,ssm2602.txt deleted file mode 100644 index 3b3302fe399b9..0000000000000 --- a/Documentation/devicetree/bindings/sound/adi,ssm2602.txt +++ /dev/null @@ -1,19 +0,0 @@ -Analog Devices SSM2602, SSM2603 and SSM2604 I2S audio CODEC devices - -SSM2602 support both I2C and SPI as the configuration interface, -the selection is made by the MODE strap-in pin. -SSM2603 and SSM2604 only support I2C as the configuration interface. - -Required properties: - - - compatible : One of "adi,ssm2602", "adi,ssm2603" or "adi,ssm2604" - - - reg : the I2C address of the device for I2C, the chip select - number for SPI. - - Example: - - ssm2602: ssm2602@1a { - compatible = "adi,ssm2602"; - reg = <0x1a>; - }; diff --git a/Documentation/devicetree/bindings/sound/adi,ssm3515.yaml b/Documentation/devicetree/bindings/sound/adi,ssm3515.yaml deleted file mode 100644 index 144450df58695..0000000000000 --- a/Documentation/devicetree/bindings/sound/adi,ssm3515.yaml +++ /dev/null @@ -1,49 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/adi,ssm3515.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Analog Devices SSM3515 Audio Amplifier - -maintainers: - - Martin Povišer - -description: | - SSM3515 is a mono Class-D audio amplifier with digital input. - - https://www.analog.com/media/en/technical-documentation/data-sheets/SSM3515.pdf - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - enum: - - adi,ssm3515 - - reg: - maxItems: 1 - - '#sound-dai-cells': - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - - codec@14 { - compatible = "adi,ssm3515"; - reg = <0x14>; - #sound-dai-cells = <0>; - sound-name-prefix = "Left Tweeter"; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml index 739114fb65497..ae86cb5f0a746 100644 --- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml @@ -33,7 +33,9 @@ properties: - const: allwinner,sun50i-h6-i2s - const: allwinner,sun50i-r329-i2s - items: - - const: allwinner,sun20i-d1-i2s + - enum: + - allwinner,sun20i-d1-i2s + - allwinner,sun55i-a523-i2s - const: allwinner,sun50i-r329-i2s reg: diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml index aa32dc950e72c..1d089ba70f45e 100644 --- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml +++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml @@ -23,6 +23,7 @@ properties: - const: allwinner,sun8i-h3-spdif - const: allwinner,sun50i-h6-spdif - const: allwinner,sun50i-h616-spdif + - const: allwinner,sun55i-a523-spdif - items: - const: allwinner,sun8i-a83t-spdif - const: allwinner,sun8i-h3-spdif @@ -37,14 +38,12 @@ properties: maxItems: 1 clocks: - items: - - description: Bus Clock - - description: Module Clock + minItems: 2 + maxItems: 3 clock-names: - items: - - const: apb - - const: spdif + minItems: 2 + maxItems: 3 # Even though it only applies to subschemas under the conditionals, # not listing them here will trigger a warning because of the @@ -65,6 +64,7 @@ allOf: - allwinner,sun8i-h3-spdif - allwinner,sun50i-h6-spdif - allwinner,sun50i-h616-spdif + - allwinner,sun55i-a523-spdif then: required: @@ -98,6 +98,38 @@ allOf: - const: rx - const: tx + - if: + properties: + compatible: + contains: + enum: + - allwinner,sun55i-a523-spdif + + then: + properties: + clocks: + items: + - description: Bus Clock + - description: TX Clock + - description: RX Clock + + clock-names: + items: + - const: apb + - const: tx + - const: rx + else: + properties: + clocks: + items: + - description: Bus Clock + - description: Module Clock + + clock-names: + items: + - const: apb + - const: spdif + required: - "#sound-dai-cells" - compatible diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs4271.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs4271.yaml index 68fbf5cc208f5..d286eb1699159 100644 --- a/Documentation/devicetree/bindings/sound/cirrus,cs4271.yaml +++ b/Documentation/devicetree/bindings/sound/cirrus,cs4271.yaml @@ -25,6 +25,16 @@ properties: reg: maxItems: 1 + clocks: + items: + - description: + Master clock connected to the MCLK pin if MCLK is an input (i.e. no + crystal used). + + clock-names: + items: + - const: mclk + spi-cpha: true spi-cpol: true diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs42xx8.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs42xx8.yaml index cd47905eb20a7..7ae72bd901f4d 100644 --- a/Documentation/devicetree/bindings/sound/cirrus,cs42xx8.yaml +++ b/Documentation/devicetree/bindings/sound/cirrus,cs42xx8.yaml @@ -9,6 +9,9 @@ title: Cirrus Logic CS42448/CS42888 audio CODEC maintainers: - patches@opensource.cirrus.com +allOf: + - $ref: dai-common.yaml# + properties: compatible: enum: @@ -63,7 +66,7 @@ then: - VLC-supply - VLS-supply -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs530x.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs530x.yaml index 9582eb8eb418b..7600fff0e3b71 100644 --- a/Documentation/devicetree/bindings/sound/cirrus,cs530x.yaml +++ b/Documentation/devicetree/bindings/sound/cirrus,cs530x.yaml @@ -15,10 +15,15 @@ description: allOf: - $ref: dai-common.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# properties: compatible: enum: + - cirrus,cs4282 + - cirrus,cs4302 + - cirrus,cs4304 + - cirrus,cs4308 - cirrus,cs5302 - cirrus,cs5304 - cirrus,cs5308 @@ -26,6 +31,9 @@ properties: reg: maxItems: 1 + spi-max-frequency: + maximum: 24000000 + '#sound-dai-cells': const: 1 diff --git a/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml b/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml new file mode 100644 index 0000000000000..02ac5f1aa926c --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/cix,sky1-ipbloq-hda.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: CIX IPBLOQ HDA controller + +description: + CIX IPBLOQ High Definition Audio (HDA) Controller + +maintainers: + - Joakim Zhang + +allOf: + - $ref: sound-card-common.yaml# + +properties: + compatible: + const: cix,sky1-ipbloq-hda + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: ipg + - const: per + + resets: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - resets + +unevaluatedProperties: false + +examples: + - | + #include + + hda@70c0000 { + compatible = "cix,sky1-ipbloq-hda"; + reg = <0x70c0000 0x10000>; + interrupts = ; + clocks = <&audss_clk 7>, + <&audss_clk 8>; + clock-names = "ipg", "per"; + resets = <&audss_rst 14>; + model = "CIX SKY1 EVB HDA"; + }; diff --git a/Documentation/devicetree/bindings/sound/cs4265.txt b/Documentation/devicetree/bindings/sound/cs4265.txt deleted file mode 100644 index 380fff8e4e832..0000000000000 --- a/Documentation/devicetree/bindings/sound/cs4265.txt +++ /dev/null @@ -1,29 +0,0 @@ -CS4265 audio CODEC - -This device supports I2C only. - -Required properties: - - - compatible : "cirrus,cs4265" - - - reg : the I2C address of the device for I2C. The I2C address depends on - the state of the AD0 pin. If AD0 is high, the i2c address is 0x4f. - If it is low, the i2c address is 0x4e. - -Optional properties: - - - reset-gpios : a GPIO spec for the reset pin. If specified, it will be - deasserted before communication to the codec starts. - -Examples: - -codec_ad0_high: cs4265@4f { /* AD0 Pin is high */ - compatible = "cirrus,cs4265"; - reg = <0x4f>; -}; - - -codec_ad0_low: cs4265@4e { /* AD0 Pin is low */ - compatible = "cirrus,cs4265"; - reg = <0x4e>; -}; diff --git a/Documentation/devicetree/bindings/sound/cs4341.txt b/Documentation/devicetree/bindings/sound/cs4341.txt deleted file mode 100644 index c1d5c8ad1a36a..0000000000000 --- a/Documentation/devicetree/bindings/sound/cs4341.txt +++ /dev/null @@ -1,22 +0,0 @@ -Cirrus Logic CS4341 audio DAC - -This device supports both I2C and SPI (configured with pin strapping -on the board). - -Required properties: - - compatible: "cirrus,cs4341a" - - reg : the I2C address of the device for I2C, the chip select - number for SPI. - -For required properties on I2C-bus, please consult -dtschema schemas/i2c/i2c-controller.yaml -For required properties on SPI-bus, please consult -Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: - codec: cs4341@0 { - #sound-dai-cells = <0>; - compatible = "cirrus,cs4341a"; - reg = <0>; - spi-max-frequency = <6000000>; - }; diff --git a/Documentation/devicetree/bindings/sound/cs4349.txt b/Documentation/devicetree/bindings/sound/cs4349.txt deleted file mode 100644 index 54c117b59dba5..0000000000000 --- a/Documentation/devicetree/bindings/sound/cs4349.txt +++ /dev/null @@ -1,19 +0,0 @@ -CS4349 audio CODEC - -Required properties: - - - compatible : "cirrus,cs4349" - - - reg : the I2C address of the device for I2C - -Optional properties: - - - reset-gpios : a GPIO spec for the reset pin. - -Example: - -codec: cs4349@48 { - compatible = "cirrus,cs4349"; - reg = <0x48>; - reset-gpios = <&gpio 54 0>; -}; diff --git a/Documentation/devicetree/bindings/sound/da9055.txt b/Documentation/devicetree/bindings/sound/da9055.txt deleted file mode 100644 index 75c6338b6ae28..0000000000000 --- a/Documentation/devicetree/bindings/sound/da9055.txt +++ /dev/null @@ -1,22 +0,0 @@ -* Dialog DA9055 Audio CODEC - -DA9055 provides Audio CODEC support (I2C only). - -The Audio CODEC device in DA9055 has its own I2C address which is configurable, -so the device is instantiated separately from the PMIC (MFD) device. - -For details on accompanying PMIC I2C device, see the following: -Documentation/devicetree/bindings/mfd/da9055.txt - -Required properties: - - - compatible: "dlg,da9055-codec" - - reg: Specifies the I2C slave address - - -Example: - - codec: da9055-codec@1a { - compatible = "dlg,da9055-codec"; - reg = <0x1a>; - }; diff --git a/Documentation/devicetree/bindings/sound/maxim,max98090.yaml b/Documentation/devicetree/bindings/sound/maxim,max98090.yaml index 65e4c516912ff..9df1296aacb77 100644 --- a/Documentation/devicetree/bindings/sound/maxim,max98090.yaml +++ b/Documentation/devicetree/bindings/sound/maxim,max98090.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Maxim Integrated MAX98090/MAX98091 audio codecs maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: | Pins on the device (for linking into audio routes): diff --git a/Documentation/devicetree/bindings/sound/maxim,max98095.yaml b/Documentation/devicetree/bindings/sound/maxim,max98095.yaml index 77544a9e1587f..76ea4fe711def 100644 --- a/Documentation/devicetree/bindings/sound/maxim,max98095.yaml +++ b/Documentation/devicetree/bindings/sound/maxim,max98095.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Maxim Integrated MAX98095 audio codec maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski allOf: - $ref: dai-common.yaml# diff --git a/Documentation/devicetree/bindings/sound/maxim,max98504.yaml b/Documentation/devicetree/bindings/sound/maxim,max98504.yaml index 23f19a9d2c06e..6d33bb4a98aea 100644 --- a/Documentation/devicetree/bindings/sound/maxim,max98504.yaml +++ b/Documentation/devicetree/bindings/sound/maxim,max98504.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Maxim Integrated MAX98504 class D mono speaker amplifier maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: Maxim Integrated MAX98504 speaker amplifier supports I2C control interface diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8189-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8189-afe-pcm.yaml new file mode 100644 index 0000000000000..9c9f21652af9f --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8189-afe-pcm.yaml @@ -0,0 +1,178 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mediatek,mt8189-afe-pcm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek Audio Front End PCM controller for MT8189 + +maintainers: + - Darren Ye + - Cyril Chao + +properties: + compatible: + const: mediatek,mt8189-afe-pcm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + memory-region: + maxItems: 1 + + mediatek,apmixedsys: + $ref: /schemas/types.yaml#/definitions/phandle + description: To set up the apll12 tuner + + power-domains: + maxItems: 1 + + clocks: + items: + - description: mux for audio intbus + - description: mux for audio engen1 + - description: mux for audio engen2 + - description: mux for audio h + - description: audio apll1 clock + - description: audio apll2 clock + - description: audio apll1 divide4 + - description: audio apll2 divide4 + - description: audio apll12 divide for i2sin0 + - description: audio apll12 divide for i2sin1 + - description: audio apll12 divide for i2sout0 + - description: audio apll12 divide for i2sout1 + - description: audio apll12 divide for fmi2s + - description: audio apll12 divide for tdmout mck + - description: audio apll12 divide for tdmout bck + - description: mux for audio apll1 + - description: mux for audio apll2 + - description: mux for i2sin0 mck + - description: mux for i2sin1 mck + - description: mux for i2sout0 mck + - description: mux for i2sout1 mck + - description: mux for fmi2s mck + - description: mux for tdmout mck + - description: 26m clock + - description: audio slv clock + - description: audio mst clock + - description: audio intbus clock + + clock-names: + items: + - const: top_aud_intbus + - const: top_aud_eng1 + - const: top_aud_eng2 + - const: top_aud_h + - const: apll1 + - const: apll2 + - const: apll1_d4 + - const: apll2_d4 + - const: apll12_div_i2sin0 + - const: apll12_div_i2sin1 + - const: apll12_div_i2sout0 + - const: apll12_div_i2sout1 + - const: apll12_div_fmi2s + - const: apll12_div_tdmout_m + - const: apll12_div_tdmout_b + - const: top_apll1 + - const: top_apll2 + - const: top_i2sin0 + - const: top_i2sin1 + - const: top_i2sout0 + - const: top_i2sout1 + - const: top_fmi2s + - const: top_dptx + - const: clk26m + - const: aud_slv_ck_peri + - const: aud_mst_ck_peri + - const: aud_intbus_ck_peri + +required: + - compatible + - reg + - interrupts + - memory-region + - power-domains + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + afe@11050000 { + compatible = "mediatek,mt8189-afe-pcm"; + reg = <0 0x11050000 0 0x10000>; + interrupts = ; + memory-region = <&afe_dma_mem_reserved>; + pinctrl-names = "default"; + pinctrl-0 = <&aud_pins_default>; + power-domains = <&scpsys 1>; //MT8189_POWER_DOMAIN_AUDIO + clocks = <&topckgen_clk 23>, //CLK_TOP_AUD_INTBUS_SEL + <&topckgen_clk 39>, //CLK_TOP_AUD_ENGEN1_SEL + <&topckgen_clk 40>, //CLK_TOP_AUD_ENGEN2_SEL + <&topckgen_clk 49>, //CLK_TOP_AUDIO_H_SEL + <&topckgen_clk 146>, //CLK_TOP_APLL1 + <&topckgen_clk 151>, //CLK_TOP_APLL2 + <&topckgen_clk 148>, //CLK_TOP_APLL1_D4 + <&topckgen_clk 153>, //CLK_TOP_APLL2_D4 + <&topckgen_clk 93>, //CLK_TOP_APLL12_CK_DIV_I2SIN0 + <&topckgen_clk 94>, //CLK_TOP_APLL12_CK_DIV_I2SIN1 + <&topckgen_clk 95>, //CLK_TOP_APLL12_CK_DIV_I2SOUT0 + <&topckgen_clk 96>, //CLK_TOP_APLL12_CK_DIV_I2SOUT1 + <&topckgen_clk 97>, //CLK_TOP_APLL12_CK_DIV_FMI2S + <&topckgen_clk 98>, //CLK_TOP_APLL12_CK_DIV_TDMOUT_M + <&topckgen_clk 99>, //CLK_TOP_APLL12_CK_DIV_TDMOUT_B + <&topckgen_clk 44>, //CLK_TOP_AUD_1_SEL + <&topckgen_clk 45>, //CLK_TOP_AUD_2_SEL + <&topckgen_clk 78>, //CLK_TOP_APLL_I2SIN0_MCK_SEL + <&topckgen_clk 79>, //CLK_TOP_APLL_I2SIN1_MCK_SEL + <&topckgen_clk 84>, //CLK_TOP_APLL_I2SOUT0_MCK_SEL + <&topckgen_clk 85>, //CLK_TOP_APLL_I2SOUT1_MCK_SEL + <&topckgen_clk 90>, //CLK_TOP_APLL_FMI2S_MCK_SEL + <&topckgen_clk 91>, //CLK_TOP_APLL_TDMOUT_MCK_SEL + <&topckgen_clk 191>, //CLK_TOP_TCK_26M_MX9 + <&pericfg_ao_clk 77>, //CLK_PERAO_AUDIO0 + <&pericfg_ao_clk 78>, //CLK_PERAO_AUDIO1 + <&pericfg_ao_clk 79>; //CLK_PERAO_AUDIO2 + clock-names = "top_aud_intbus", + "top_aud_eng1", + "top_aud_eng2", + "top_aud_h", + "apll1", + "apll2", + "apll1_d4", + "apll2_d4", + "apll12_div_i2sin0", + "apll12_div_i2sin1", + "apll12_div_i2sout0", + "apll12_div_i2sout1", + "apll12_div_fmi2s", + "apll12_div_tdmout_m", + "apll12_div_tdmout_b", + "top_apll1", + "top_apll2", + "top_i2sin0", + "top_i2sin1", + "top_i2sout0", + "top_i2sout1", + "top_fmi2s", + "top_dptx", + "clk26m", + "aud_slv_ck_peri", + "aud_mst_ck_peri", + "aud_intbus_ck_peri"; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8189-nau8825.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8189-nau8825.yaml new file mode 100644 index 0000000000000..dd9ee0a3b292e --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8189-nau8825.yaml @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mediatek,mt8189-nau8825.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT8189 ASoC sound card + +maintainers: + - Darren Ye + - Cyril Chao + +allOf: + - $ref: sound-card-common.yaml# + +properties: + compatible: + enum: + - mediatek,mt8189-nau8825 + - mediatek,mt8189-rt5650 + - mediatek,mt8189-rt5682s + - mediatek,mt8189-rt5682i + - mediatek,mt8189-es8326 + + mediatek,platform: + $ref: /schemas/types.yaml#/definitions/phandle + description: The phandle of MT8189 ASoC platform. + +patternProperties: + "^dai-link-[0-9]+$": + type: object + description: + Container for dai-link level properties and CODEC sub-nodes. + + properties: + link-name: + description: + This property corresponds to the name of the BE dai-link to which + we are going to update parameters in this node. + enum: + - TDM_DPTX_BE + - I2SOUT0_BE + - I2SIN0_BE + - I2SOUT1_BE + + codec: + description: Holds subnode which indicates codec dai. + type: object + additionalProperties: false + + properties: + sound-dai: + minItems: 1 + maxItems: 2 + required: + - sound-dai + + dai-format: + description: audio format. + enum: + - i2s + - right_j + - left_j + - dsp_a + - dsp_b + + mediatek,clk-provider: + $ref: /schemas/types.yaml#/definitions/string + description: Indicates dai-link clock master. + enum: + - cpu + - codec + + additionalProperties: false + + required: + - link-name + +required: + - compatible + - mediatek,platform + +unevaluatedProperties: false + +examples: + - | + sound { + compatible = "mediatek,mt8189-nau8825"; + model = "mt8189_rt9123_8825"; + mediatek,platform = <&afe>; + dai-link-0 { + link-name = "I2SOUT1_BE"; + dai-format = "i2s"; + mediatek,clk-provider = "cpu"; + codec { + sound-dai = <&nau8825>; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/sound/nuvoton,nau8540.yaml b/Documentation/devicetree/bindings/sound/nuvoton,nau8540.yaml deleted file mode 100644 index 7ccfbb8d8b043..0000000000000 --- a/Documentation/devicetree/bindings/sound/nuvoton,nau8540.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/nuvoton,nau8540.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Nuvoton Technology Corporation NAU85L40 Audio CODEC - -maintainers: - - John Hsu - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: nuvoton,nau8540 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - codec@1c { - compatible = "nuvoton,nau8540"; - reg = <0x1c>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/nuvoton,nau8810.yaml b/Documentation/devicetree/bindings/sound/nuvoton,nau8810.yaml deleted file mode 100644 index d9696f6c75edd..0000000000000 --- a/Documentation/devicetree/bindings/sound/nuvoton,nau8810.yaml +++ /dev/null @@ -1,45 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/nuvoton,nau8810.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: NAU8810/NAU8812/NAU8814 audio CODEC - -maintainers: - - David Lin - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - enum: - - nuvoton,nau8810 - - nuvoton,nau8812 - - nuvoton,nau8814 - - reg: - maxItems: 1 - - '#sound-dai-cells': - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - - codec@1a { - #sound-dai-cells = <0>; - compatible = "nuvoton,nau8810"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml index b32f33214ba60..2ce4049f94acc 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml @@ -67,46 +67,72 @@ properties: $ref: audio-graph-port.yaml# unevaluatedProperties: false -if: - properties: - compatible: - contains: - const: nvidia,tegra210-admaif - -then: - properties: - dmas: - description: - DMA channel specifiers, equally divided for Tx and Rx. - minItems: 1 - maxItems: 20 - dma-names: - items: - pattern: "^[rt]x(10|[1-9])$" - description: - Should be "rx1", "rx2" ... "rx10" for DMA Rx channel - Should be "tx1", "tx2" ... "tx10" for DMA Tx channel - minItems: 1 - maxItems: 20 - interconnects: false - interconnect-names: false - iommus: false - -else: - properties: - dmas: - description: - DMA channel specifiers, equally divided for Tx and Rx. - minItems: 1 - maxItems: 40 - dma-names: - items: - pattern: "^[rt]x(1[0-9]|[1-9]|20)$" - description: - Should be "rx1", "rx2" ... "rx20" for DMA Rx channel - Should be "tx1", "tx2" ... "tx20" for DMA Tx channel - minItems: 1 - maxItems: 40 +allOf: + - if: + properties: + compatible: + contains: + const: nvidia,tegra210-admaif + then: + properties: + dmas: + description: + DMA channel specifiers, equally divided for Tx and Rx. + minItems: 1 + maxItems: 20 + dma-names: + items: + pattern: "^[rt]x(10|[1-9])$" + description: + Should be "rx1", "rx2" ... "rx10" for DMA Rx channel + Should be "tx1", "tx2" ... "tx10" for DMA Tx channel + minItems: 1 + maxItems: 20 + interconnects: false + interconnect-names: false + iommus: false + + - if: + properties: + compatible: + contains: + const: nvidia,tegra186-admaif + then: + properties: + dmas: + description: + DMA channel specifiers, equally divided for Tx and Rx. + minItems: 1 + maxItems: 40 + dma-names: + items: + pattern: "^[rt]x(1[0-9]|[1-9]|20)$" + description: + Should be "rx1", "rx2" ... "rx20" for DMA Rx channel + Should be "tx1", "tx2" ... "tx20" for DMA Tx channel + minItems: 1 + maxItems: 40 + + - if: + properties: + compatible: + contains: + const: nvidia,tegra264-admaif + then: + properties: + dmas: + description: + DMA channel specifiers, equally divided for Tx and Rx. + minItems: 1 + maxItems: 64 + dma-names: + items: + pattern: "^[rt]x(3[0-2]|[1-2][0-9]|[1-9])$" + description: + Should be "rx1", "rx2" ... "rx32" for DMA Rx channel + Should be "tx1", "tx2" ... "tx32" for DMA Tx channel + minItems: 1 + maxItems: 64 required: - compatible diff --git a/Documentation/devicetree/bindings/sound/nxp,tfa9879.yaml b/Documentation/devicetree/bindings/sound/nxp,tfa9879.yaml deleted file mode 100644 index df26248573ad5..0000000000000 --- a/Documentation/devicetree/bindings/sound/nxp,tfa9879.yaml +++ /dev/null @@ -1,44 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/nxp,tfa9879.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: NXP TFA9879 class-D audio amplifier - -maintainers: - - Peter Rosin - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: nxp,tfa9879 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - - '#sound-dai-cells' - -unevaluatedProperties: false - -examples: - - | - i2c1 { - #address-cells = <1>; - #size-cells = <0>; - amplifier@6c { - compatible = "nxp,tfa9879"; - reg = <0x6c>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c1>; - #sound-dai-cells = <0>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/nxp,uda1342.yaml b/Documentation/devicetree/bindings/sound/nxp,uda1342.yaml deleted file mode 100644 index 71c6a5a2f5bc0..0000000000000 --- a/Documentation/devicetree/bindings/sound/nxp,uda1342.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/nxp,uda1342.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: NXP uda1342 audio CODECs - -maintainers: - - Binbin Zhou - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: nxp,uda1342 - - reg: - maxItems: 1 - - '#sound-dai-cells': - const: 0 - -required: - - compatible - - reg - - '#sound-dai-cells' - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - codec@1a { - compatible = "nxp,uda1342"; - reg = <0x1a>; - #sound-dai-cells = <0>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/pcm1789.txt b/Documentation/devicetree/bindings/sound/pcm1789.txt deleted file mode 100644 index 3c74ed220ac25..0000000000000 --- a/Documentation/devicetree/bindings/sound/pcm1789.txt +++ /dev/null @@ -1,22 +0,0 @@ -Texas Instruments pcm1789 DT bindings - -PCM1789 is a simple audio codec that can be connected via -I2C or SPI. Currently, only I2C bus is supported. - -Required properties: - - - compatible: "ti,pcm1789" - -Required properties on I2C: - - - reg: the I2C address - - reset-gpios: GPIO to control the RESET pin - -Examples: - - audio-codec@4c { - compatible = "ti,pcm1789"; - reg = <0x4c>; - reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>; - #sound-dai-cells = <0>; - }; diff --git a/Documentation/devicetree/bindings/sound/pcm179x.txt b/Documentation/devicetree/bindings/sound/pcm179x.txt deleted file mode 100644 index 436c2b247693f..0000000000000 --- a/Documentation/devicetree/bindings/sound/pcm179x.txt +++ /dev/null @@ -1,27 +0,0 @@ -Texas Instruments pcm179x DT bindings - -This driver supports both the I2C and SPI bus. - -Required properties: - - - compatible: "ti,pcm1792a" - -For required properties on SPI, please consult -Documentation/devicetree/bindings/spi/spi-bus.txt - -Required properties on I2C: - - - reg: the I2C address - - -Examples: - - codec_spi: 1792a@0 { - compatible = "ti,pcm1792a"; - spi-max-frequency = <600000>; - }; - - codec_i2c: 1792a@4c { - compatible = "ti,pcm1792a"; - reg = <0x4c>; - }; diff --git a/Documentation/devicetree/bindings/sound/pcm186x.txt b/Documentation/devicetree/bindings/sound/pcm186x.txt deleted file mode 100644 index 1087f48559807..0000000000000 --- a/Documentation/devicetree/bindings/sound/pcm186x.txt +++ /dev/null @@ -1,42 +0,0 @@ -Texas Instruments PCM186x Universal Audio ADC - -These devices support both I2C and SPI (configured with pin strapping -on the board). - -Required properties: - - - compatible : "ti,pcm1862", - "ti,pcm1863", - "ti,pcm1864", - "ti,pcm1865" - - - reg : The I2C address of the device for I2C, the chip select - number for SPI. - - - avdd-supply: Analog core power supply (3.3v) - - dvdd-supply: Digital core power supply - - iovdd-supply: Digital IO power supply - See regulator/regulator.txt for more information - -CODEC input pins: - * VINL1 - * VINR1 - * VINL2 - * VINR2 - * VINL3 - * VINR3 - * VINL4 - * VINR4 - -The pins can be used in referring sound node's audio-routing property. - -Example: - - pcm186x: audio-codec@4a { - compatible = "ti,pcm1865"; - reg = <0x4a>; - - avdd-supply = <®_3v3_analog>; - dvdd-supply = <®_3v3>; - iovdd-supply = <®_1v8>; - }; diff --git a/Documentation/devicetree/bindings/sound/pcm5102a.txt b/Documentation/devicetree/bindings/sound/pcm5102a.txt deleted file mode 100644 index c63ab0b6ee196..0000000000000 --- a/Documentation/devicetree/bindings/sound/pcm5102a.txt +++ /dev/null @@ -1,13 +0,0 @@ -PCM5102a audio CODECs - -These devices does not use I2C or SPI. - -Required properties: - - - compatible : set as "ti,pcm5102a" - -Examples: - - pcm5102a: pcm5102a { - compatible = "ti,pcm5102a"; - }; diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml index 92f95eb74b192..2eed2277511f8 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml @@ -14,12 +14,14 @@ properties: oneOf: - enum: - qcom,sc7280-lpass-rx-macro + - qcom,sm6115-lpass-rx-macro - qcom,sm8250-lpass-rx-macro - qcom,sm8450-lpass-rx-macro - qcom,sm8550-lpass-rx-macro - qcom,sc8280xp-lpass-rx-macro - items: - enum: + - qcom,kaanapali-lpass-rx-macro - qcom,sm8650-lpass-rx-macro - qcom,sm8750-lpass-rx-macro - qcom,x1e80100-lpass-rx-macro @@ -80,6 +82,23 @@ allOf: - const: npl - const: fsgen + - if: + properties: + compatible: + enum: + - qcom,sm6115-lpass-rx-macro + then: + properties: + clocks: + minItems: 4 + maxItems: 4 + clock-names: + items: + - const: mclk + - const: npl + - const: dcodec + - const: fsgen + - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml index 914798a898781..e5e65e226a02d 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml @@ -21,6 +21,7 @@ properties: - qcom,sc8280xp-lpass-tx-macro - items: - enum: + - qcom,kaanapali-lpass-tx-macro - qcom,sm8650-lpass-tx-macro - qcom,sm8750-lpass-tx-macro - qcom,x1e80100-lpass-tx-macro diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml index 1c0d78af3c051..5c42b2b323ee4 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml @@ -14,6 +14,7 @@ properties: oneOf: - enum: - qcom,sc7280-lpass-va-macro + - qcom,sm6115-lpass-va-macro - qcom,sm8250-lpass-va-macro - qcom,sm8450-lpass-va-macro - qcom,sm8550-lpass-va-macro @@ -21,6 +22,7 @@ properties: - items: - enum: - qcom,glymur-lpass-va-macro + - qcom,kaanapali-lpass-va-macro - qcom,sm8650-lpass-va-macro - qcom,sm8750-lpass-va-macro - qcom,x1e80100-lpass-va-macro @@ -41,11 +43,7 @@ properties: clock-names: minItems: 1 - items: - - const: mclk - - const: macro - - const: dcodec - - const: npl + maxItems: 4 clock-output-names: maxItems: 1 @@ -90,29 +88,48 @@ allOf: clocks: maxItems: 1 clock-names: - maxItems: 1 + items: + - const: mclk else: properties: clocks: minItems: 3 maxItems: 3 clock-names: - minItems: 3 - maxItems: 3 - + items: + - const: mclk + - const: macro + - const: dcodec - if: properties: compatible: contains: - const: qcom,sm8250-lpass-va-macro + const: qcom,sm6115-lpass-va-macro then: properties: clocks: minItems: 3 maxItems: 3 clock-names: + items: + - const: mclk + - const: dcodec + - const: npl + - if: + properties: + compatible: + contains: + const: qcom,sm8250-lpass-va-macro + then: + properties: + clocks: minItems: 3 maxItems: 3 + clock-names: + items: + - const: mclk + - const: macro + - const: dcodec - if: properties: @@ -127,8 +144,11 @@ allOf: minItems: 4 maxItems: 4 clock-names: - minItems: 4 - maxItems: 4 + items: + - const: mclk + - const: macro + - const: dcodec + - const: npl - if: properties: @@ -142,8 +162,10 @@ allOf: minItems: 3 maxItems: 3 clock-names: - minItems: 3 - maxItems: 3 + items: + - const: mclk + - const: macro + - const: dcodec unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml index b6f5ba5d1320b..d5f22b5cf0210 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml @@ -21,6 +21,7 @@ properties: - items: - enum: - qcom,glymur-lpass-wsa-macro + - qcom,kaanapali-lpass-wsa-macro - qcom,sm8650-lpass-wsa-macro - qcom,sm8750-lpass-wsa-macro - qcom,x1e80100-lpass-wsa-macro diff --git a/Documentation/devicetree/bindings/sound/qcom,q6adm-routing.yaml b/Documentation/devicetree/bindings/sound/qcom,q6adm-routing.yaml index 3f11d2e183e17..26fe8cc66b3c7 100644 --- a/Documentation/devicetree/bindings/sound/qcom,q6adm-routing.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,q6adm-routing.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Audio Device Manager (Q6ADM) routing maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla description: diff --git a/Documentation/devicetree/bindings/sound/qcom,q6adm.yaml b/Documentation/devicetree/bindings/sound/qcom,q6adm.yaml index fe14a97ea6162..3c32c5b0fad8e 100644 --- a/Documentation/devicetree/bindings/sound/qcom,q6adm.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,q6adm.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Audio Device Manager (Q6ADM) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla allOf: diff --git a/Documentation/devicetree/bindings/sound/qcom,q6afe.yaml b/Documentation/devicetree/bindings/sound/qcom,q6afe.yaml index 268f7073d7972..4624b3d461d5d 100644 --- a/Documentation/devicetree/bindings/sound/qcom,q6afe.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,q6afe.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Audio FrontEnd (Q6AFE) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla allOf: diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml index 894e653d37d74..2fb95544db8b5 100644 --- a/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,q6apm-lpass-dais.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm DSP LPASS (Low Power Audio SubSystem) Audio Ports maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla allOf: diff --git a/Documentation/devicetree/bindings/sound/qcom,q6apm.yaml b/Documentation/devicetree/bindings/sound/qcom,q6apm.yaml index ef1965aca2548..ec06769a2b63a 100644 --- a/Documentation/devicetree/bindings/sound/qcom,q6apm.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,q6apm.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Audio Process Manager (Q6APM) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla allOf: diff --git a/Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml index ce811942a9f17..47a105a97ecf9 100644 --- a/Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Audio Stream Manager (Q6ASM) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla description: diff --git a/Documentation/devicetree/bindings/sound/qcom,q6asm.yaml b/Documentation/devicetree/bindings/sound/qcom,q6asm.yaml index cb49f9667ccaa..a6f88ce92299e 100644 --- a/Documentation/devicetree/bindings/sound/qcom,q6asm.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,q6asm.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Audio Stream Manager (Q6ASM) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla allOf: diff --git a/Documentation/devicetree/bindings/sound/qcom,q6core.yaml b/Documentation/devicetree/bindings/sound/qcom,q6core.yaml index e240712de9caf..8642ef9f9142b 100644 --- a/Documentation/devicetree/bindings/sound/qcom,q6core.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,q6core.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Audio Core (Q6Core) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla allOf: diff --git a/Documentation/devicetree/bindings/sound/qcom,q6prm.yaml b/Documentation/devicetree/bindings/sound/qcom,q6prm.yaml index f6dbb1267bfe7..3eafe189e6992 100644 --- a/Documentation/devicetree/bindings/sound/qcom,q6prm.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,q6prm.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Proxy Resource Manager (Q6PRM) maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla allOf: diff --git a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml index b49a920af7045..15f38622b98b9 100644 --- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml @@ -23,6 +23,7 @@ properties: - const: qcom,sdm845-sndcard - items: - enum: + - qcom,kaanapali-sndcard - qcom,sm8550-sndcard - qcom,sm8650-sndcard - qcom,sm8750-sndcard @@ -38,6 +39,7 @@ properties: - qcom,qcs8275-sndcard - qcom,qcs9075-sndcard - qcom,qcs9100-sndcard + - qcom,qrb2210-sndcard - qcom,qrb4210-rb2-sndcard - qcom,qrb5165-rb5-sndcard - qcom,sc7180-qdsp6-sndcard diff --git a/Documentation/devicetree/bindings/sound/qcom,wcd934x.yaml b/Documentation/devicetree/bindings/sound/qcom,wcd934x.yaml index a65b1d1d5fdd9..3a7334e41fd65 100644 --- a/Documentation/devicetree/bindings/sound/qcom,wcd934x.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,wcd934x.yaml @@ -132,7 +132,7 @@ properties: $ref: /schemas/gpio/qcom,wcd934x-gpio.yaml# patternProperties: - "^.*@[0-9a-f]+$": + "@[0-9a-f]+$": type: object additionalProperties: true description: | diff --git a/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml b/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml index 83e0360301e1d..866c5e780fb0a 100644 --- a/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm WSA8840/WSA8845/WSA8845H smart speaker amplifier maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - Srinivas Kandagatla description: diff --git a/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml index 7bb6c5dff7865..9435f395403a5 100644 --- a/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml +++ b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml @@ -135,7 +135,6 @@ properties: the direction (input/output) needs to be dynamically adjusted. type: boolean - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3328-codec.yaml b/Documentation/devicetree/bindings/sound/rockchip,rk3328-codec.yaml index 5cdb8bcc687b0..52e3f1f900c4e 100644 --- a/Documentation/devicetree/bindings/sound/rockchip,rk3328-codec.yaml +++ b/Documentation/devicetree/bindings/sound/rockchip,rk3328-codec.yaml @@ -8,10 +8,10 @@ title: Rockchip rk3328 internal codec maintainers: - Heiko Stuebner + allOf: - $ref: dai-common.yaml# - properties: compatible: const: rockchip,rk3328-codec diff --git a/Documentation/devicetree/bindings/sound/samsung,tm2.yaml b/Documentation/devicetree/bindings/sound/samsung,tm2.yaml index cbc7ba37362a9..67586ba3e0a0f 100644 --- a/Documentation/devicetree/bindings/sound/samsung,tm2.yaml +++ b/Documentation/devicetree/bindings/sound/samsung,tm2.yaml @@ -30,7 +30,6 @@ properties: - items: - description: Phandle to the HDMI transmitter node. - samsung,audio-routing: description: | List of the connections between audio components; each entry is diff --git a/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml new file mode 100644 index 0000000000000..55bd0b307d22b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/spacemit,k1-i2s.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: K1 I2S controller + +description: + The I2S bus (Inter-IC sound bus) is a serial link for digital + audio data transfer between devices in the system. + +maintainers: + - Troy Mitchell + +allOf: + - $ref: dai-common.yaml# + +properties: + compatible: + const: spacemit,k1-i2s + + reg: + maxItems: 1 + + clocks: + items: + - description: clock for I2S sysclk + - description: clock for I2S bclk + - description: clock for I2S bus + - description: clock for I2S controller + + clock-names: + items: + - const: sysclk + - const: bclk + - const: bus + - const: func + + dmas: + minItems: 1 + maxItems: 2 + + dma-names: + minItems: 1 + items: + - const: tx + - const: rx + + resets: + maxItems: 1 + + port: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + + "#sound-dai-cells": + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + - dmas + - dma-names + - resets + - "#sound-dai-cells" + +unevaluatedProperties: false + +examples: + - | + #include + i2s@d4026000 { + compatible = "spacemit,k1-i2s"; + reg = <0xd4026000 0x30>; + clocks = <&syscon_mpmu CLK_I2S_SYSCLK>, + <&syscon_mpmu CLK_I2S_BCLK>, + <&syscon_apbc CLK_SSPA0_BUS>, + <&syscon_apbc CLK_SSPA0>; + clock-names = "sysclk", "bclk", "bus", "func"; + dmas = <&pdma0 21>, <&pdma0 22>; + dma-names = "tx", "rx"; + resets = <&syscon_apbc RESET_SSPA0>; + #sound-dai-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/sound/ti,pcm1862.yaml b/Documentation/devicetree/bindings/sound/ti,pcm1862.yaml new file mode 100644 index 0000000000000..0f0e254a24209 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ti,pcm1862.yaml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/ti,pcm1862.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments PCM186x Universal Audio ADC + +maintainers: + - Ranganath V N + +description: | + The Texas Instruments PCM186x family are multi-channel audio ADCs + that support both I2C and SPI control interfaces, selected by + pin strapping. These devices include on-chip programmable gain + amplifiers and support differential or single-ended analog inputs. + + CODEC input pins: + * VINL1 + * VINR1 + * VINL2 + * VINR2 + * VINL3 + * VINR3 + * VINL4 + * VINR4 + + The pins can be used in referring sound node's audio-routing property. + +allOf: + - $ref: dai-common.yaml# + +properties: + compatible: + enum: + - ti,pcm1862 + - ti,pcm1863 + - ti,pcm1864 + - ti,pcm1865 + + reg: + maxItems: 1 + + avdd-supply: true + + dvdd-supply: true + + iovdd-supply: true + + '#sound-dai-cells': + const: 0 + +required: + - compatible + - reg + - avdd-supply + - dvdd-supply + - iovdd-supply + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + audio-codec@4a { + compatible = "ti,pcm1865"; + reg = <0x4a>; + + avdd-supply = <®_3v3_analog>; + dvdd-supply = <®_3v3>; + iovdd-supply = <®_1v8>; + }; + }; diff --git a/Documentation/devicetree/bindings/sound/ti,tas2781.yaml b/Documentation/devicetree/bindings/sound/ti,tas2781.yaml index 7f84f506013c3..f3a5638f4239c 100644 --- a/Documentation/devicetree/bindings/sound/ti,tas2781.yaml +++ b/Documentation/devicetree/bindings/sound/ti,tas2781.yaml @@ -24,21 +24,26 @@ description: | Instruments Smart Amp speaker protection algorithm. The integrated speaker voltage and current sense provides for real time monitoring of loudspeaker behavior. - The TAS5802/TAS5815/TAS5825/TAS5827/TAS5828 is a stereo, digital input - Class-D audio amplifier optimized for efficiently driving high peak - power into small loudspeakers. An integrated on-chip DSP supports - Texas Instruments Smart Amp speaker protection algorithm. + The TAS5802/TAS5815/TAS5822/TAS5825/TAS5827/TAS5828 is a stereo, + digital input Class-D audio amplifier optimized for efficiently driving + high peak power into small loudspeakers. An integrated on-chip DSP + supports Texas Instruments Smart Amp speaker protection algorithm. Specifications about the audio amplifier can be found at: https://www.ti.com/lit/gpn/tas2120 https://www.ti.com/lit/gpn/tas2320 https://www.ti.com/lit/gpn/tas2563 https://www.ti.com/lit/gpn/tas2572 + https://www.ti.com/lit/gpn/tas2574 https://www.ti.com/lit/gpn/tas2781 + https://www.ti.com/lit/gpn/tas5806m + https://www.ti.com/lit/gpn/tas5806md https://www.ti.com/lit/gpn/tas5815 + https://www.ti.com/lit/gpn/tas5822m https://www.ti.com/lit/gpn/tas5825m https://www.ti.com/lit/gpn/tas5827 https://www.ti.com/lit/gpn/tas5828m + https://www.ti.com/lit/gpn/tas5830 properties: compatible: @@ -57,12 +62,18 @@ properties: ti,tas2563: 6.1-W Boosted Class-D Audio Amplifier With Integrated DSP and IV Sense, 16/20/24/32bit stereo I2S or multichannel TDM. + ti,tas2568: 5.3-W Digital Input Smart Amp with I/V Sense and Integrated + 10.75-V Class-H Boost + ti,tas2570: 5.8-W Digital Input smart amp with I/V sense and integrated 11-V Class-H Boost ti,tas2572: 6.6-W Digital Input smart amp with I/V sense and integrated 13-V Class-H Boost + ti,tas2574: 8.5-W Digital Input smart amp with I/V sense and integrated + 15-V Class-H Boost + ti,tas2781: 24-V Class-D Amplifier with Real Time Integrated Speaker Protection and Audio Processing, 16/20/24/32bit stereo I2S or multichannel TDM. @@ -71,9 +82,20 @@ properties: Audio Amplifier with 96-Khz Extended Processing and Low Idle Power Dissipation. + ti,tas5806m: 23-W, Inductor-Less, Digital Input, Stereo, Closed-Loop + Class-D Audio Amplifier with Enhanced Processing and Low Power + Dissipation. + + ti,tas5806md: 23-W, Inductor-Less, Digital Input, Stereo, Closed-Loop + Class-D Audio Amplifier with Enhanced Processing and DirectPath(TM) + HP Driver + ti,tas5815: 30-W, Digital Input, Stereo, Closed-loop Class-D Audio Amplifier with 96 kHz Enhanced Processing + ti,tas5822: 35-W, Digital Input, Stereo, Closed-Loop Class-D Audio + Amplifier with 96 kHz Enhanced Processing + ti,tas5825: 38-W Stereo, Inductor-Less, Digital Input, Closed-Loop 4.5V to 26.4V Class-D Audio Amplifier with 192-kHz Extended Audio Processing. @@ -82,6 +104,9 @@ properties: ti,tas5828: 50-W Stereo, Digital Input, High Efficiency Closed-Loop Class-D Amplifier with Hybrid-Pro Algorithm + + ti,tas5830: 65-W Stereo, Digital Input, High Efficiency Closed-Loop + Class-D Amplifier with Class-H Algorithm oneOf: - items: - enum: @@ -90,13 +115,19 @@ properties: - ti,tas2120 - ti,tas2320 - ti,tas2563 + - ti,tas2568 - ti,tas2570 - ti,tas2572 + - ti,tas2574 - ti,tas5802 + - ti,tas5806m + - ti,tas5806md - ti,tas5815 + - ti,tas5822 - ti,tas5825 - ti,tas5827 - ti,tas5828 + - ti,tas5830 - const: ti,tas2781 - enum: - ti,tas2781 @@ -132,6 +163,8 @@ allOf: - ti,tas2118 - ti,tas2120 - ti,tas2320 + - ti,tas2568 + - ti,tas2574 then: properties: reg: @@ -207,6 +240,22 @@ allOf: minimum: 0x54 maximum: 0x57 + - if: + properties: + compatible: + contains: + enum: + - ti,tas5806m + - ti,tas5806md + - ti,tas5822 + then: + properties: + reg: + maxItems: 4 + items: + minimum: 0x2c + maximum: 0x2f + - if: properties: compatible: @@ -214,6 +263,7 @@ allOf: enum: - ti,tas5827 - ti,tas5828 + - ti,tas5830 then: properties: reg: diff --git a/Documentation/devicetree/bindings/sound/ti,tlv320dac3100.yaml b/Documentation/devicetree/bindings/sound/ti,tlv320dac3100.yaml index 85e937e34962d..10299064cbc69 100644 --- a/Documentation/devicetree/bindings/sound/ti,tlv320dac3100.yaml +++ b/Documentation/devicetree/bindings/sound/ti,tlv320dac3100.yaml @@ -84,7 +84,6 @@ properties: description: gpio pin number used for codec reset deprecated: true - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/sound/trivial-codec.yaml b/Documentation/devicetree/bindings/sound/trivial-codec.yaml new file mode 100644 index 0000000000000..9a35dfb17349a --- /dev/null +++ b/Documentation/devicetree/bindings/sound/trivial-codec.yaml @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/trivial-codec.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Trivial Audio Codec + +maintainers: + - Rob Herring + +allOf: + - $ref: dai-common.yaml# + +properties: + compatible: + enum: + # Analog Devices SSM2602 I2S audio CODEC devices + - adi,ssm2602 + - adi,ssm2603 + - adi,ssm2604 + - adi,ssm3515 + # Cirrus Logic CS4265 audio DAC + - cirrus,cs4265 + - cirrus,cs4341a + - cirrus,cs4349 + - dlg,da9055-codec + # Nuvoton Technology Corporation NAU85L40 Audio CODEC + - nuvoton,nau8540 + - nuvoton,nau8810 + - nuvoton,nau8812 + - nuvoton,nau8814 + # NXP TFA9879 class-D audio amplifier + - nxp,tfa9879 + - nxp,uda1342 + - sdw3019f836300 + - ti,pcm1789 + - ti,pcm1792a + - ti,pcm5102a + - wlf,wm8510 + - wlf,wm8523 + - wlf,wm8580 + - wlf,wm8581 + - wlf,wm8711 + - wlf,wm8728 + - wlf,wm8737 + - wlf,wm8750 + - wlf,wm8753 + - wlf,wm8770 + - wlf,wm8776 + - wlf,wm8961 + - wlf,wm8974 + - wlf,wm8987 + + reg: + maxItems: 1 + + "#sound-dai-cells": + const: 0 + + reset-gpios: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + codec@1a { + compatible = "wlf,wm8523"; + reg = <0x1a>; + }; + }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8510.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8510.yaml deleted file mode 100644 index 6d12b0ac37e28..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8510.yaml +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8510.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: WM8510 audio CODEC - -maintainers: - - patches@opensource.cirrus.com - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: wlf,wm8510 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - - codec@1a { - compatible = "wlf,wm8510"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8523.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8523.yaml deleted file mode 100644 index decc395bb8739..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8523.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8523.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: WM8523 audio CODEC - -maintainers: - - patches@opensource.cirrus.com - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: wlf,wm8523 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - codec@1a { - compatible = "wlf,wm8523"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8580.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8580.yaml deleted file mode 100644 index 2f27852cdc200..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8580.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8580.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: WM8580 and WM8581 audio CODEC - -maintainers: - - patches@opensource.cirrus.com - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - enum: - - wlf,wm8580 - - wlf,wm8581 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - codec@1a { - compatible = "wlf,wm8580"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8711.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8711.yaml deleted file mode 100644 index ecaac2818b446..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8711.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8711.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: WM8711 audio CODEC - -maintainers: - - patches@opensource.cirrus.com - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: wlf,wm8711 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - codec@1a { - compatible = "wlf,wm8711"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8728.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8728.yaml deleted file mode 100644 index fc89475a051e8..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8728.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8728.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: WM8728 audio CODEC - -maintainers: - - patches@opensource.cirrus.com - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: wlf,wm8728 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - codec@1a { - compatible = "wlf,wm8728"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8737.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8737.yaml deleted file mode 100644 index 12d8765726d8f..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8737.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8737.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: WM8737 audio CODEC - -maintainers: - - patches@opensource.cirrus.com - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: wlf,wm8737 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - codec@1a { - compatible = "wlf,wm8737"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8750.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8750.yaml deleted file mode 100644 index 96859e38315b1..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8750.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8750.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: WM8750 and WM8987 audio CODECs - -description: | - These devices support both I2C and SPI (configured with pin strapping - on the board). - -maintainers: - - Mark Brown - -properties: - compatible: - enum: - - wlf,wm8750 - - wlf,wm8987 - - reg: - description: - The I2C address of the device for I2C, the chip select number for SPI - maxItems: 1 - -additionalProperties: false - -required: - - reg - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - - codec@1a { - compatible = "wlf,wm8750"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8753.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8753.yaml deleted file mode 100644 index 9eebe7d7f0b7d..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8753.yaml +++ /dev/null @@ -1,62 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8753.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: WM8753 audio CODEC - -description: | - Pins on the device (for linking into audio routes): - * LOUT1 - * LOUT2 - * ROUT1 - * ROUT2 - * MONO1 - * MONO2 - * OUT3 - * OUT4 - * LINE1 - * LINE2 - * RXP - * RXN - * ACIN - * ACOP - * MIC1N - * MIC1 - * MIC2N - * MIC2 - * Mic Bias - -maintainers: - - patches@opensource.cirrus.com - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: wlf,wm8753 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - codec@1a { - compatible = "wlf,wm8753"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8776.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8776.yaml deleted file mode 100644 index 7bbc96ee81be3..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8776.yaml +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8776.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: WM8776 audio CODEC - -maintainers: - - patches@opensource.cirrus.com - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: wlf,wm8776 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - - codec@1a { - compatible = "wlf,wm8776"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8903.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8903.yaml index 4cfa66f626817..089b673847975 100644 --- a/Documentation/devicetree/bindings/sound/wlf,wm8903.yaml +++ b/Documentation/devicetree/bindings/sound/wlf,wm8903.yaml @@ -75,7 +75,6 @@ properties: DCVDD-supply: description: Digital core supply regulator for the DCVDD pin. - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8961.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8961.yaml deleted file mode 100644 index f580785455693..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8961.yaml +++ /dev/null @@ -1,43 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8961.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Wolfson WM8961 Ultra-Low Power Stereo CODEC - -maintainers: - - patches@opensource.cirrus.com - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: wlf,wm8961 - - reg: - maxItems: 1 - - '#sound-dai-cells': - const: 0 - -required: - - compatible - - reg - - '#sound-dai-cells' - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - - wm8961: codec@4a { - compatible = "wlf,wm8961"; - reg = <0x4a>; - #sound-dai-cells = <0>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8974.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8974.yaml deleted file mode 100644 index d27300207c67e..0000000000000 --- a/Documentation/devicetree/bindings/sound/wlf,wm8974.yaml +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/sound/wlf,wm8974.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: WM8974 audio CODEC - -maintainers: - - patches@opensource.cirrus.com - -allOf: - - $ref: dai-common.yaml# - -properties: - compatible: - const: wlf,wm8974 - - reg: - maxItems: 1 - - "#sound-dai-cells": - const: 0 - -required: - - compatible - - reg - -unevaluatedProperties: false - -examples: - - | - i2c { - #address-cells = <1>; - #size-cells = <0>; - - codec@1a { - compatible = "wlf,wm8974"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8994.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8994.yaml index 8f045de028509..0db04a90ac6b3 100644 --- a/Documentation/devicetree/bindings/sound/wlf,wm8994.yaml +++ b/Documentation/devicetree/bindings/sound/wlf,wm8994.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Wolfson WM1811/WM8994/WM8958 audio codecs maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski - patches@opensource.cirrus.com description: | diff --git a/Documentation/devicetree/bindings/sound/wm8770.txt b/Documentation/devicetree/bindings/sound/wm8770.txt deleted file mode 100644 index cac762a1105de..0000000000000 --- a/Documentation/devicetree/bindings/sound/wm8770.txt +++ /dev/null @@ -1,16 +0,0 @@ -WM8770 audio CODEC - -This device supports SPI. - -Required properties: - - - compatible : "wlf,wm8770" - - - reg : the chip select number. - -Example: - -wm8770: codec@1 { - compatible = "wlf,wm8770"; - reg = <1>; -}; diff --git a/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml b/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml index 95d947fda6a70..003023729fb8c 100644 --- a/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml +++ b/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml @@ -23,6 +23,7 @@ properties: - qcom,soundwire-v1.6.0 - qcom,soundwire-v1.7.0 - qcom,soundwire-v2.0.0 + - qcom,soundwire-v3.1.0 - items: - enum: - qcom,soundwire-v2.1.0 @@ -73,10 +74,12 @@ properties: qcom,din-ports: $ref: /schemas/types.yaml#/definitions/uint32 description: count of data in ports + deprecated: true qcom,dout-ports: $ref: /schemas/types.yaml#/definitions/uint32 description: count of data out ports + deprecated: true qcom,ports-word-length: $ref: /schemas/types.yaml#/definitions/uint8-array @@ -223,8 +226,6 @@ required: - '#sound-dai-cells' - '#address-cells' - '#size-cells' - - qcom,dout-ports - - qcom,din-ports - qcom,ports-offset1 - qcom,ports-offset2 @@ -257,9 +258,6 @@ examples: clocks = <&lpass_rx_macro>; clock-names = "iface"; - qcom,din-ports = <0>; - qcom,dout-ports = <5>; - resets = <&lpass_audiocc LPASS_AUDIO_SWR_RX_CGCR>; reset-names = "swr_audio_cgcr"; diff --git a/Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml b/Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml index b820c5613dcc1..855aa08995b96 100644 --- a/Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml +++ b/Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml @@ -14,7 +14,12 @@ allOf: properties: compatible: - const: airoha,en7581-snand + oneOf: + - const: airoha,en7581-snand + - items: + - enum: + - airoha,en7523-snand + - const: airoha,en7581-snand reg: items: diff --git a/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml b/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml index 3b47b68b92cb8..1b91d1566c953 100644 --- a/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml +++ b/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml @@ -17,6 +17,7 @@ properties: compatible: oneOf: - const: allwinner,sun50i-r329-spi + - const: allwinner,sun55i-a523-spi - const: allwinner,sun6i-a31-spi - const: allwinner,sun8i-h3-spi - items: @@ -35,6 +36,9 @@ properties: - const: allwinner,sun20i-d1-spi-dbi - const: allwinner,sun50i-r329-spi-dbi - const: allwinner,sun50i-r329-spi + - items: + - const: allwinner,sun55i-a523-spi-dbi + - const: allwinner,sun55i-a523-spi reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/spi/arm,pl022-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/arm,pl022-peripheral-props.yaml index bb8b6863b1090..f976e416395b7 100644 --- a/Documentation/devicetree/bindings/spi/arm,pl022-peripheral-props.yaml +++ b/Documentation/devicetree/bindings/spi/arm,pl022-peripheral-props.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Peripheral-specific properties for Arm PL022 SPI controller maintainers: - - Linus Walleij + - Linus Walleij select: false diff --git a/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml b/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml index 57d932af4506f..80e542624cc62 100644 --- a/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml +++ b/Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml @@ -12,7 +12,7 @@ maintainers: description: | This binding describes the Aspeed Static Memory Controllers (FMC and - SPI) of the AST2400, AST2500 and AST2600 SOCs. + SPI) of the AST2400, AST2500, AST2600 and AST2700 SOCs. allOf: - $ref: spi-controller.yaml# @@ -20,6 +20,8 @@ allOf: properties: compatible: enum: + - aspeed,ast2700-fmc + - aspeed,ast2700-spi - aspeed,ast2600-fmc - aspeed,ast2600-spi - aspeed,ast2500-fmc diff --git a/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml b/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml index f2dd20370dbb3..1d10cfbad86c7 100644 --- a/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/fsl,spi-fsl-qspi.yaml @@ -9,9 +9,6 @@ title: Freescale Quad Serial Peripheral Interface (QuadSPI) maintainers: - Han Xu -allOf: - - $ref: spi-controller.yaml# - properties: compatible: oneOf: @@ -22,6 +19,7 @@ properties: - fsl,imx6ul-qspi - fsl,ls1021a-qspi - fsl,ls2080a-qspi + - spacemit,k1-qspi - items: - enum: - fsl,ls1043a-qspi @@ -54,6 +52,11 @@ properties: - const: qspi_en - const: qspi + resets: + items: + - description: SoC QSPI reset + - description: SoC QSPI bus reset + required: - compatible - reg @@ -62,6 +65,18 @@ required: - clocks - clock-names +allOf: + - $ref: spi-controller.yaml# + - if: + properties: + compatible: + not: + contains: + const: spacemit,k1-qspi + then: + properties: + resets: false + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml b/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml index 62a568bdbfa05..636338d24bdfb 100644 --- a/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml +++ b/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml @@ -21,11 +21,13 @@ properties: - microchip,mpfs-qspi - microchip,pic64gx-qspi - const: microchip,coreqspi-rtl-v2 - - const: microchip,coreqspi-rtl-v2 # FPGA QSPI + - enum: + - microchip,coreqspi-rtl-v2 # FPGA QSPI + - microchip,corespi-rtl-v5 # FPGA CoreSPI + - microchip,mpfs-spi - items: - const: microchip,pic64gx-spi - const: microchip,mpfs-spi - - const: microchip,mpfs-spi reg: maxItems: 1 @@ -39,6 +41,45 @@ properties: clocks: maxItems: 1 + microchip,apb-datawidth: + description: APB bus data width in bits. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [8, 16, 32] + default: 8 + + microchip,frame-size: + description: | + Number of bits per SPI frame, as configured in Libero. + In Motorola and TI modes, this corresponds directly + to the requested frame size. For NSC mode this is set + to 9 + the required data frame size. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 4 + maximum: 32 + default: 8 + + microchip,protocol-configuration: + description: CoreSPI protocol selection. Determines operating mode + $ref: /schemas/types.yaml#/definitions/string + enum: + - motorola + - ti + - nsc + default: motorola + + microchip,motorola-mode: + description: Motorola SPI mode selection + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + default: 3 + + microchip,ssel-active: + description: | + Keep SSEL asserted between frames when using the Motorola protocol. + When present, the controller keeps SSEL active across contiguous + transfers and deasserts only when the overall transfer completes. + type: boolean + required: - compatible - reg @@ -71,6 +112,31 @@ allOf: num-cs: maximum: 1 + - if: + properties: + compatible: + contains: + const: microchip,corespi-rtl-v5 + then: + properties: + num-cs: + minimum: 1 + maximum: 8 + default: 8 + + fifo-depth: + minimum: 1 + maximum: 32 + default: 4 + + else: + properties: + microchip,apb-datawidth: false + microchip,frame-size: false + microchip,protocol-configuration: false + microchip,motorola-mode: false + microchip,ssel-active: false + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/spi/nuvoton,npcm-pspi.txt b/Documentation/devicetree/bindings/spi/nuvoton,npcm-pspi.txt deleted file mode 100644 index a4e72e52af592..0000000000000 --- a/Documentation/devicetree/bindings/spi/nuvoton,npcm-pspi.txt +++ /dev/null @@ -1,36 +0,0 @@ -Nuvoton NPCM Peripheral Serial Peripheral Interface(PSPI) controller driver - -Nuvoton NPCM7xx SOC support two PSPI channels. - -Required properties: - - compatible : "nuvoton,npcm750-pspi" for Poleg NPCM7XX. - "nuvoton,npcm845-pspi" for Arbel NPCM8XX. - - #address-cells : should be 1. see spi-bus.txt - - #size-cells : should be 0. see spi-bus.txt - - specifies physical base address and size of the register. - - interrupts : contain PSPI interrupt. - - clocks : phandle of PSPI reference clock. - - clock-names: Should be "clk_apb5". - - pinctrl-names : a pinctrl state named "default" must be defined. - - pinctrl-0 : phandle referencing pin configuration of the device. - - resets : phandle to the reset control for this device. - - cs-gpios: Specifies the gpio pins to be used for chipselects. - See: Documentation/devicetree/bindings/spi/spi-bus.txt - -Optional properties: -- clock-frequency : Input clock frequency to the PSPI block in Hz. - Default is 25000000 Hz. - -spi0: spi@f0200000 { - compatible = "nuvoton,npcm750-pspi"; - reg = <0xf0200000 0x1000>; - pinctrl-names = "default"; - pinctrl-0 = <&pspi1_pins>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = ; - clocks = <&clk NPCM7XX_CLK_APB5>; - clock-names = "clk_apb5"; - resets = <&rstc NPCM7XX_RESET_IPSRST2 NPCM7XX_RESET_PSPI1> - cs-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>; -}; diff --git a/Documentation/devicetree/bindings/spi/nuvoton,npcm-pspi.yaml b/Documentation/devicetree/bindings/spi/nuvoton,npcm-pspi.yaml new file mode 100644 index 0000000000000..db0fb872020a9 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/nuvoton,npcm-pspi.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/nuvoton,npcm-pspi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton NPCM Peripheral SPI (PSPI) Controller + +maintainers: + - Tomer Maimon + +allOf: + - $ref: spi-controller.yaml# + +description: + Nuvoton NPCM Peripheral Serial Peripheral Interface (PSPI) controller. + Nuvoton NPCM7xx SOC supports two PSPI channels. + Nuvoton NPCM8xx SOC support one PSPI channel. + +properties: + compatible: + enum: + - nuvoton,npcm750-pspi # Poleg NPCM7XX + - nuvoton,npcm845-pspi # Arbel NPCM8XX + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + description: PSPI reference clock. + + clock-names: + items: + - const: clk_apb5 + + resets: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - resets + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + #include "dt-bindings/gpio/gpio.h" + spi0: spi@f0200000 { + compatible = "nuvoton,npcm750-pspi"; + reg = <0xf0200000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&pspi1_pins>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + clocks = <&clk NPCM7XX_CLK_APB5>; + clock-names = "clk_apb5"; + resets = <&rstc NPCM7XX_RESET_IPSRST2 NPCM7XX_RESET_PSPI1>; + cs-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>; + }; + diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml index d12c5a060ed00..edf399681d7a9 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml @@ -9,7 +9,7 @@ title: GENI based Qualcomm Universal Peripheral (QUP) Serial Peripheral Interfac maintainers: - Andy Gross - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: The QUP v3 core is a GENI based AHB slave that provides a common data path diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qpic-snand.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-qpic-snand.yaml index cb1f15224b455..7d0571feb46d6 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qpic-snand.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qpic-snand.yaml @@ -25,6 +25,8 @@ properties: - items: - enum: - qcom,ipq5018-snand + - qcom,ipq5332-snand + - qcom,ipq5424-snand - const: qcom,ipq9574-snand - const: qcom,ipq9574-snand diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qup.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-qup.yaml index 88be132689621..7df21b15a0d47 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.yaml @@ -9,7 +9,7 @@ title: Qualcomm Universal Peripheral (QUP) Serial Peripheral Interface (SPI) maintainers: - Andy Gross - Bjorn Andersson - - Krzysztof Kozlowski + - Krzysztof Kozlowski description: The QUP core is an AHB slave that provides a common data path (an output FIFO diff --git a/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml b/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml index ab27fefc3c3a3..069557a587b57 100644 --- a/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml +++ b/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml @@ -9,12 +9,18 @@ title: Renesas RZ/V2H(P) Renesas Serial Peripheral Interface (RSPI) maintainers: - Fabrizio Castro -allOf: - - $ref: spi-controller.yaml# - properties: compatible: - const: renesas,r9a09g057-rspi # RZ/V2H(P) + oneOf: + - enum: + - renesas,r9a09g057-rspi # RZ/V2H(P) + - renesas,r9a09g077-rspi # RZ/T2H + - items: + - const: renesas,r9a09g056-rspi # RZ/V2N + - const: renesas,r9a09g057-rspi + - items: + - const: renesas,r9a09g087-rspi # RZ/N2H + - const: renesas,r9a09g077-rspi # RZ/T2H reg: maxItems: 1 @@ -36,13 +42,12 @@ properties: - const: tx clocks: + minItems: 2 maxItems: 3 clock-names: - items: - - const: pclk - - const: pclk_sfr - - const: tclk + minItems: 2 + maxItems: 3 resets: maxItems: 2 @@ -62,12 +67,52 @@ required: - interrupt-names - clocks - clock-names - - resets - - reset-names - power-domains - '#address-cells' - '#size-cells' +allOf: + - $ref: spi-controller.yaml# + - if: + properties: + compatible: + contains: + enum: + - renesas,r9a09g057-rspi + then: + properties: + clocks: + minItems: 3 + + clock-names: + items: + - const: pclk + - const: pclk_sfr + - const: tclk + + required: + - resets + - reset-names + + - if: + properties: + compatible: + contains: + enum: + - renesas,r9a09g077-rspi + then: + properties: + clocks: + maxItems: 2 + + clock-names: + items: + - const: pclk + - const: pclkspi + + resets: false + reset-names: false + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml index 0543c526b783a..81838577cf9cd 100644 --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml @@ -121,7 +121,7 @@ properties: num-cs: default: 4 minimum: 1 - maximum: 4 + maximum: 16 dmas: items: @@ -153,14 +153,14 @@ properties: provides an interface to override the native DWC SSI CS control. patternProperties: - "^.*@[0-9a-f]+$": + "@[0-9a-f]$": type: object additionalProperties: true properties: reg: minimum: 0 - maximum: 3 + maximum: 0xf unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/spi/spi-cadence.yaml b/Documentation/devicetree/bindings/spi/spi-cadence.yaml index 27414b78d61d8..347bed0c49560 100644 --- a/Documentation/devicetree/bindings/spi/spi-cadence.yaml +++ b/Documentation/devicetree/bindings/spi/spi-cadence.yaml @@ -21,6 +21,7 @@ properties: - enum: - xlnx,zynqmp-spi-r1p6 - xlnx,versal-net-spi-r1p6 + - cix,sky1-spi-r1p6 - const: cdns,spi-r1p6 reg: diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml index 82d051f7bd6e0..3b8e990e30c47 100644 --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml @@ -111,7 +111,7 @@ properties: - compatible patternProperties: - "^.*@[0-9a-f]+$": + "@[0-9a-f]+$": type: object $ref: spi-peripheral-props.yaml additionalProperties: true diff --git a/Documentation/devicetree/bindings/spi/spi-pl022.yaml b/Documentation/devicetree/bindings/spi/spi-pl022.yaml index 7f174b7d0a26f..680fdfa184d0c 100644 --- a/Documentation/devicetree/bindings/spi/spi-pl022.yaml +++ b/Documentation/devicetree/bindings/spi/spi-pl022.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ARM PL022 SPI controller maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: spi-controller.yaml# diff --git a/Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt b/Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt deleted file mode 100644 index 12fc4ef04837f..0000000000000 --- a/Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt +++ /dev/null @@ -1,33 +0,0 @@ -Amazon's Annapurna Labs Thermal Sensor - -Simple thermal device that allows temperature reading by a single MMIO -transaction. - -Required properties: -- compatible: "amazon,al-thermal". -- reg: The physical base address and length of the sensor's registers. -- #thermal-sensor-cells: Must be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description. - -Example: - thermal: thermal { - compatible = "amazon,al-thermal"; - reg = <0x0 0x05002860 0x0 0x1>; - #thermal-sensor-cells = <0x1>; - }; - - thermal-zones { - thermal-z0 { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&thermal 0>; - trips { - critical { - temperature = <105000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - }; - }; - diff --git a/Documentation/devicetree/bindings/thermal/amazon,al-thermal.yaml b/Documentation/devicetree/bindings/thermal/amazon,al-thermal.yaml new file mode 100644 index 0000000000000..6b5884d74dd6f --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/amazon,al-thermal.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/amazon,al-thermal.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amazon Annapurna Labs Thermal Sensor + +maintainers: + - Talel Shenhar + +description: + Simple thermal device that allows temperature reading by a single MMIO + transaction. + +properties: + compatible: + items: + - const: amazon,al-thermal + + reg: + maxItems: 1 + + '#thermal-sensor-cells': + const: 1 + +additionalProperties: false + +examples: + - | + thermal: thermal@5002860 { + compatible = "amazon,al-thermal"; + reg = <0x05002860 0x1>; + #thermal-sensor-cells = <0x1>; + }; + + thermal-zones { + z0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&thermal 0>; + trips { + critical { + temperature = <105000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/thermal/brcm,sr-thermal.txt b/Documentation/devicetree/bindings/thermal/brcm,sr-thermal.txt deleted file mode 100644 index 3ab330219d45e..0000000000000 --- a/Documentation/devicetree/bindings/thermal/brcm,sr-thermal.txt +++ /dev/null @@ -1,105 +0,0 @@ -* Broadcom Stingray Thermal - -This binding describes thermal sensors that is part of Stingray SoCs. - -Required properties: -- compatible : Must be "brcm,sr-thermal" -- reg : Memory where tmon data will be available. -- brcm,tmon-mask: A one cell bit mask of valid TMON sources. - Each bit represents single TMON source. -- #thermal-sensor-cells : Thermal sensor phandler -- polling-delay: Max number of milliseconds to wait between polls. -- thermal-sensors: A list of thermal sensor phandles and specifier. - specifier value is tmon ID and it should be - in correspond with brcm,tmon-mask. -- temperature: trip temperature threshold in millicelsius. - -Example: - tmons { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x0 0x8f100000 0x100>; - - tmon: tmon@0 { - compatible = "brcm,sr-thermal"; - reg = <0x0 0x40>; - brcm,tmon-mask = <0x3f>; - #thermal-sensor-cells = <1>; - }; - }; - - thermal-zones { - ihost0_thermal: ihost0-thermal { - polling-delay-passive = <0>; - polling-delay = <1000>; - thermal-sensors = <&tmon 0>; - trips { - cpu-crit { - temperature = <105000>; - hysteresis = <0>; - type = "critical"; - }; - }; - }; - ihost1_thermal: ihost1-thermal { - polling-delay-passive = <0>; - polling-delay = <1000>; - thermal-sensors = <&tmon 1>; - trips { - cpu-crit { - temperature = <105000>; - hysteresis = <0>; - type = "critical"; - }; - }; - }; - ihost2_thermal: ihost2-thermal { - polling-delay-passive = <0>; - polling-delay = <1000>; - thermal-sensors = <&tmon 2>; - trips { - cpu-crit { - temperature = <105000>; - hysteresis = <0>; - type = "critical"; - }; - }; - }; - ihost3_thermal: ihost3-thermal { - polling-delay-passive = <0>; - polling-delay = <1000>; - thermal-sensors = <&tmon 3>; - trips { - cpu-crit { - temperature = <105000>; - hysteresis = <0>; - type = "critical"; - }; - }; - }; - crmu_thermal: crmu-thermal { - polling-delay-passive = <0>; - polling-delay = <1000>; - thermal-sensors = <&tmon 4>; - trips { - cpu-crit { - temperature = <105000>; - hysteresis = <0>; - type = "critical"; - }; - }; - }; - nitro_thermal: nitro-thermal { - polling-delay-passive = <0>; - polling-delay = <1000>; - thermal-sensors = <&tmon 5>; - trips { - cpu-crit { - temperature = <105000>; - hysteresis = <0>; - type = "critical"; - }; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/thermal/brcm,sr-thermal.yaml b/Documentation/devicetree/bindings/thermal/brcm,sr-thermal.yaml new file mode 100644 index 0000000000000..576a627cd5990 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/brcm,sr-thermal.yaml @@ -0,0 +1,121 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/brcm,sr-thermal.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Broadcom Stingray Thermal Sensors + +maintainers: + - Ray Jui + - Scott Branden + +allOf: + - $ref: thermal-sensor.yaml# + +properties: + compatible: + const: brcm,sr-thermal + + reg: + maxItems: 1 + + brcm,tmon-mask: + description: + A one-cell bit mask of valid TMON sources. Each bit represents a single + TMON source. + $ref: /schemas/types.yaml#/definitions/uint32 + + '#thermal-sensor-cells': + const: 1 + +required: + - compatible + - reg + - brcm,tmon-mask + +additionalProperties: false + +examples: + - | + tmon: thermal-sensor@0 { + compatible = "brcm,sr-thermal"; + reg = <0x0 0x40>; + brcm,tmon-mask = <0x3f>; + #thermal-sensor-cells = <1>; + }; + + thermal-zones { + ihost0_thermal: ihost0-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + thermal-sensors = <&tmon 0>; + trips { + cpu-crit { + temperature = <105000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + ihost1_thermal: ihost1-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + thermal-sensors = <&tmon 1>; + trips { + cpu-crit { + temperature = <105000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + ihost2_thermal: ihost2-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + thermal-sensors = <&tmon 2>; + trips { + cpu-crit { + temperature = <105000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + ihost3_thermal: ihost3-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + thermal-sensors = <&tmon 3>; + trips { + cpu-crit { + temperature = <105000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + crmu_thermal: crmu-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + thermal-sensors = <&tmon 4>; + trips { + cpu-crit { + temperature = <105000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + nitro_thermal: nitro-thermal { + polling-delay-passive = <0>; + polling-delay = <1000>; + thermal-sensors = <&tmon 5>; + trips { + cpu-crit { + temperature = <105000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/thermal/db8500-thermal.txt b/Documentation/devicetree/bindings/thermal/db8500-thermal.txt deleted file mode 100644 index 2e1c06fad81fe..0000000000000 --- a/Documentation/devicetree/bindings/thermal/db8500-thermal.txt +++ /dev/null @@ -1,44 +0,0 @@ -* ST-Ericsson DB8500 Thermal - -** Thermal node properties: - -- compatible : "stericsson,db8500-thermal"; -- reg : address range of the thermal sensor registers; -- interrupts : interrupts generated from PRCMU; -- interrupt-names : "IRQ_HOTMON_LOW" and "IRQ_HOTMON_HIGH"; -- num-trips : number of total trip points, this is required, set it 0 if none, - if greater than 0, the following properties must be defined; -- tripN-temp : temperature of trip point N, should be in ascending order; -- tripN-type : type of trip point N, should be one of "active" "passive" "hot" - "critical"; -- tripN-cdev-num : number of the cooling devices which can be bound to trip - point N, this is required if trip point N is defined, set it 0 if none, - otherwise the following cooling device names must be defined; -- tripN-cdev-nameM : name of the No. M cooling device of trip point N; - -Usually the num-trips and tripN-*** are separated in board related dts files. - -Example: -thermal@801573c0 { - compatible = "stericsson,db8500-thermal"; - reg = <0x801573c0 0x40>; - interrupts = <21 0x4>, <22 0x4>; - interrupt-names = "IRQ_HOTMON_LOW", "IRQ_HOTMON_HIGH"; - - num-trips = <3>; - - trip0-temp = <75000>; - trip0-type = "active"; - trip0-cdev-num = <1>; - trip0-cdev-name0 = "thermal-cpufreq-0"; - - trip1-temp = <80000>; - trip1-type = "active"; - trip1-cdev-num = <2>; - trip1-cdev-name0 = "thermal-cpufreq-0"; - trip1-cdev-name1 = "thermal-fan"; - - trip2-temp = <85000>; - trip2-type = "critical"; - trip2-cdev-num = <0>; -} diff --git a/Documentation/devicetree/bindings/timer/faraday,fttmr010.yaml b/Documentation/devicetree/bindings/timer/faraday,fttmr010.yaml index 39506323556c5..e93c20243dba1 100644 --- a/Documentation/devicetree/bindings/timer/faraday,fttmr010.yaml +++ b/Documentation/devicetree/bindings/timer/faraday,fttmr010.yaml @@ -8,7 +8,7 @@ title: Faraday FTTMR010 timer maintainers: - Joel Stanley - - Linus Walleij + - Linus Walleij description: This timer is a generic IP block from Faraday Technology, embedded in the diff --git a/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml b/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml index 526b8db4d5759..c92e6b9cd5e2f 100644 --- a/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml +++ b/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Intel IXP4xx XScale Networking Processors Timers maintainers: - - Linus Walleij + - Linus Walleij description: This timer is found in the Intel IXP4xx processors. diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra-timer.yaml b/Documentation/devicetree/bindings/timer/nvidia,tegra-timer.yaml index 9ea2ea3a75990..adf208b7a5b95 100644 --- a/Documentation/devicetree/bindings/timer/nvidia,tegra-timer.yaml +++ b/Documentation/devicetree/bindings/timer/nvidia,tegra-timer.yaml @@ -100,7 +100,6 @@ properties: items: - const: timer - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra186-timer.yaml b/Documentation/devicetree/bindings/timer/nvidia,tegra186-timer.yaml index 76516e18e042c..1d0bd36907ed1 100644 --- a/Documentation/devicetree/bindings/timer/nvidia,tegra186-timer.yaml +++ b/Documentation/devicetree/bindings/timer/nvidia,tegra186-timer.yaml @@ -15,7 +15,6 @@ description: > reference generated by USEC, TSC or either clk_m or OSC. Each TMR can be programmed to generate one-shot, periodic, or watchdog interrupts. - properties: compatible: oneOf: diff --git a/Documentation/devicetree/bindings/timer/sifive,clint.yaml b/Documentation/devicetree/bindings/timer/sifive,clint.yaml index d85a1a088b35d..0d3b8dc362ba7 100644 --- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml +++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml @@ -36,6 +36,7 @@ properties: - starfive,jh7100-clint # StarFive JH7100 - starfive,jh7110-clint # StarFive JH7110 - starfive,jh8100-clint # StarFive JH8100 + - tenstorrent,blackhole-clint # Tenstorrent Blackhole - const: sifive,clint0 # SiFive CLINT v0 IP block - items: - {} diff --git a/Documentation/devicetree/bindings/timer/st,nomadik-mtu.yaml b/Documentation/devicetree/bindings/timer/st,nomadik-mtu.yaml index fa65878b35719..873a01c287f47 100644 --- a/Documentation/devicetree/bindings/timer/st,nomadik-mtu.yaml +++ b/Documentation/devicetree/bindings/timer/st,nomadik-mtu.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: ST Microelectronics Nomadik Multi-Timer Unit MTU Timer maintainers: - - Linus Walleij + - Linus Walleij description: This timer is found in the ST Microelectronics Nomadik SoCs STn8800, STn8810 and STn8815 as well as in ST-Ericsson DB8500. diff --git a/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml b/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml index 4ed30efe40525..cf7c82e980f67 100644 --- a/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml +++ b/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml @@ -4,18 +4,23 @@ $id: http://devicetree.org/schemas/timer/thead,c900-aclint-mtimer.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Sophgo CLINT Timer +title: ACLINT Machine-level Timer Device maintainers: - Inochi Amaoto properties: compatible: - items: - - enum: - - sophgo,sg2042-aclint-mtimer - - sophgo,sg2044-aclint-mtimer - - const: thead,c900-aclint-mtimer + oneOf: + - items: + - enum: + - sophgo,sg2042-aclint-mtimer + - sophgo,sg2044-aclint-mtimer + - const: thead,c900-aclint-mtimer + - items: + - enum: + - anlogic,dr1v90-aclint-mtimer + - const: nuclei,ux900-aclint-mtimer reg: items: diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 58ff948d93c96..d0f7dbf15d6f1 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -43,8 +43,14 @@ properties: - adi,ad5110 # Temperature sensor with integrated fan control - adi,adm1027 + # Analog Devices ADT7410 High Accuracy Digital Temperature Sensor + - adi,adt7410 # Analog Devices ADT7411 Temperature Sensor and 8-channel ADC - adi,adt7411 + # Analog Devices ADT7420 High Accuracy Digital Temperature Sensor + - adi,adt7420 + # Analog Devices ADT7422 High Accuracy Digital Temperature Sensor + - adi,adt7422 # Temperature sensor with integrated fan control - adi,adt7463 # Temperature sensor with integrated fan control @@ -53,6 +59,8 @@ properties: - adi,lt7182s # AMS iAQ-Core VOC Sensor - ams,iaq-core + # Arduino microcontroller interface over SPI on UnoQ board + - arduino,unoq-mcu # Temperature monitoring of Astera Labs PT5161L PCIe retimer - asteralabs,pt5161l # i2c h/w elliptic curve crypto module @@ -113,8 +121,6 @@ properties: - fsl,mma7660 # MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer - fsl,mma8450 - # MPL3115: Absolute Digital Pressure Sensor - - fsl,mpl3115 # MPR121: Proximity Capacitive Touch Sensor Controller - fsl,mpr121 # Honeywell Humidicon HIH-6130 humidity/temperature sensor @@ -127,8 +133,6 @@ properties: - ibm,cffps2 # IBM On-Chip Controller hwmon device - ibm,p8-occ-hwmon - # Infineon barometric pressure and temperature sensor - - infineon,dps310 # Infineon IR36021 digital POL buck controller - infineon,ir36021 # Infineon IRPS5401 Voltage Regulator (PMIC) @@ -297,6 +301,10 @@ properties: - mps,mp2888 # Monolithic Power Systems Inc. multi-phase controller mp2891 - mps,mp2891 + # Monolithic Power Systems Inc. multi-phase controller mp2925 + - mps,mp2925 + # Monolithic Power Systems Inc. multi-phase controller mp2929 + - mps,mp2929 # Monolithic Power Systems Inc. multi-phase controller mp29502 - mps,mp29502 # Monolithic Power Systems Inc. multi-phase controller mp29608 @@ -317,6 +325,8 @@ properties: - mps,mp5998 # Monolithic Power Systems Inc. digital step-down converter mp9941 - mps,mp9941 + # Monolithic Power Systems Inc. digital step-down converter mp9945 + - mps,mp9945 # Temperature sensor with integrated fan control - national,lm63 # Temperature sensor with integrated fan control diff --git a/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml b/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml new file mode 100644 index 0000000000000..c00ec342d5743 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml @@ -0,0 +1,61 @@ +# 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: 1 + + clock-names: + items: + - const: core + + power-domains: + maxItems: 1 + + resets: + maxItems: 2 + + reset-names: + items: + - const: host + - const: phy + +required: + - reg + - clocks + - clock-names + - resets + - reset-names + +unevaluatedProperties: false + +examples: + - | + #include + ufs@f10b0000 { + compatible = "amd,versal2-ufs"; + reg = <0xf10b0000 0x1000>; + clocks = <&ufs_core_clk>; + clock-names = "core"; + resets = <&scmi_reset 4>, <&scmi_reset 35>; + reset-names = "host", "phy"; + interrupts = ; + freq-table-hz = <0 0>; + }; diff --git a/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml b/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml index 1dec54fb00f30..15c347f5e6604 100644 --- a/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml +++ b/Documentation/devicetree/bindings/ufs/mediatek,ufs.yaml @@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Mediatek Universal Flash Storage (UFS) Controller maintainers: - - Stanley Chu + - Peter Wang + - Chaotian Jing properties: compatible: diff --git a/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml b/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml index 1dd41f6d52580..516bb61a46241 100644 --- a/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml +++ b/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml @@ -88,7 +88,6 @@ allOf: - const: ice_core_clk reg: minItems: 2 - maxItems: 2 reg-names: minItems: 2 required: @@ -117,7 +116,6 @@ allOf: - const: tx_lane0_sync_clk - const: rx_lane0_sync_clk reg: - minItems: 1 maxItems: 1 reg-names: maxItems: 1 @@ -147,7 +145,6 @@ allOf: - const: ice_core_clk reg: minItems: 2 - maxItems: 2 reg-names: minItems: 2 required: diff --git a/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml index b4e744ebffd10..a7eb7ad85a94e 100644 --- a/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml +++ b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml @@ -61,6 +61,9 @@ properties: phy-names: const: ufs-phy + power-domains: + maxItems: 1 + samsung,sysreg: $ref: /schemas/types.yaml#/definitions/phandle-array items: diff --git a/Documentation/devicetree/bindings/usb/apple,dwc3.yaml b/Documentation/devicetree/bindings/usb/apple,dwc3.yaml new file mode 100644 index 0000000000000..f70c33f32c5d6 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/apple,dwc3.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/apple,dwc3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple Silicon DWC3 USB controller + +maintainers: + - Sven Peter + +description: + Apple Silicon SoCs use a Synopsys DesignWare DWC3 based controller for each of + their Type-C ports. + +allOf: + - $ref: snps,dwc3-common.yaml# + +properties: + compatible: + oneOf: + - items: + - enum: + - apple,t6000-dwc3 + - apple,t6020-dwc3 + - apple,t8112-dwc3 + - const: apple,t8103-dwc3 + - const: apple,t8103-dwc3 + + reg: + items: + - description: Core DWC3 region + - description: Apple-specific DWC3 region + + reg-names: + items: + - const: dwc3-core + - const: dwc3-apple + + interrupts: + maxItems: 1 + + iommus: + maxItems: 2 + + resets: + maxItems: 1 + + power-domains: + maxItems: 1 + +required: + - compatible + - reg + - reg-names + - interrupts + - iommus + - resets + - power-domains + - usb-role-switch + +unevaluatedProperties: false + +examples: + - | + #include + #include + + usb@82280000 { + compatible = "apple,t8103-dwc3"; + reg = <0x82280000 0xcd00>, <0x8228cd00 0x3200>; + reg-names = "dwc3-core", "dwc3-apple"; + interrupts = ; + iommus = <&dwc3_0_dart_0 0>, <&dwc3_0_dart_1 1>; + + power-domains = <&ps_atc0_usb>; + resets = <&atcphy0>; + + usb-role-switch; + }; diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.yaml b/Documentation/devicetree/bindings/usb/dwc3-xilinx.yaml index 36f5c644d9590..d6823ef5f9a78 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.yaml +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.yaml @@ -47,6 +47,7 @@ properties: - const: ref_clk resets: + minItems: 1 description: A list of phandles for resets listed in reset-names. @@ -56,6 +57,7 @@ properties: - description: USB APB reset reset-names: + minItems: 1 items: - const: usb_crst - const: usb_hibrst @@ -95,6 +97,26 @@ required: - resets - reset-names +allOf: + - if: + properties: + compatible: + contains: + enum: + - xlnx,versal-dwc3 + then: + properties: + resets: + maxItems: 1 + reset-names: + maxItems: 1 + else: + properties: + resets: + minItems: 3 + reset-names: + minItems: 3 + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/usb/eswin,eic7700-usb.yaml b/Documentation/devicetree/bindings/usb/eswin,eic7700-usb.yaml new file mode 100644 index 0000000000000..41c3b1b989911 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/eswin,eic7700-usb.yaml @@ -0,0 +1,94 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/eswin,eic7700-usb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ESWIN EIC7700 SoC Usb Controller + +maintainers: + - Wei Yang + - Senchuan Zhang + - Hang Cao + +description: + The Usb controller on EIC7700 SoC. + +allOf: + - $ref: snps,dwc3-common.yaml# + +properties: + compatible: + const: eswin,eic7700-dwc3 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + interrupt-names: + items: + - const: peripheral + + clocks: + maxItems: 3 + + clock-names: + items: + - const: aclk + - const: cfg + - const: usb_en + + resets: + maxItems: 2 + + reset-names: + items: + - const: vaux + - const: usb_rst + + eswin,hsp-sp-csr: + description: + HSP CSR is to control and get status of different high-speed peripherals + (such as Ethernet, USB, SATA, etc.) via register, which can tune + board-level's parameters of PHY, etc. + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to HSP Register Controller hsp_sp_csr node. + - description: USB bus register offset. + - description: AXI low power register offset. + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + - interrupt-names + - resets + - reset-names + - eswin,hsp-sp-csr + +unevaluatedProperties: false + +examples: + - | + usb@50480000 { + compatible = "eswin,eic7700-dwc3"; + reg = <0x50480000 0x10000>; + clocks = <&clock 135>, + <&clock 136>, + <&hspcrg 18>; + clock-names = "aclk", "cfg", "usb_en"; + interrupt-parent = <&plic>; + interrupts = <85>; + interrupt-names = "peripheral"; + resets = <&reset 84>, <&hspcrg 2>; + reset-names = "vaux", "usb_rst"; + dr_mode = "peripheral"; + maximum-speed = "high-speed"; + phy_type = "utmi"; + eswin,hsp-sp-csr = <&hsp_sp_csr 0x800 0x818>; + }; diff --git a/Documentation/devicetree/bindings/usb/faraday,fotg210.yaml b/Documentation/devicetree/bindings/usb/faraday,fotg210.yaml index 3fe4d1564dfed..b97ba535087c9 100644 --- a/Documentation/devicetree/bindings/usb/faraday,fotg210.yaml +++ b/Documentation/devicetree/bindings/usb/faraday,fotg210.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Faraday Technology FOTG200 series HS OTG USB 2.0 controller maintainers: - - Linus Walleij + - Linus Walleij allOf: - $ref: usb-drd.yaml# diff --git a/Documentation/devicetree/bindings/usb/fsl,ls1028a.yaml b/Documentation/devicetree/bindings/usb/fsl,ls1028a.yaml index a44bdf391887f..4784f057264ac 100644 --- a/Documentation/devicetree/bindings/usb/fsl,ls1028a.yaml +++ b/Documentation/devicetree/bindings/usb/fsl,ls1028a.yaml @@ -9,21 +9,19 @@ title: Freescale layerscape SuperSpeed DWC3 USB SoC controller maintainers: - Frank Li -select: - properties: - compatible: - contains: - enum: - - fsl,ls1028a-dwc3 - required: - - compatible - properties: compatible: - items: - - enum: - - fsl,ls1028a-dwc3 - - const: snps,dwc3 + oneOf: + - items: + - enum: + - fsl,ls1012a-dwc3 + - fsl,ls1043a-dwc3 + - fsl,ls1046a-dwc3 + - fsl,ls1088a-dwc3 + - fsl,ls208xa-dwc3 + - fsl,lx2160a-dwc3 + - const: fsl,ls1028a-dwc3 + - const: fsl,ls1028a-dwc3 reg: maxItems: 1 @@ -31,6 +29,11 @@ properties: interrupts: maxItems: 1 + iommus: + maxItems: 1 + + dma-coherent: true + unevaluatedProperties: false required: @@ -39,14 +42,14 @@ required: - interrupts allOf: - - $ref: snps,dwc3.yaml# + - $ref: snps,dwc3-common.yaml# examples: - | #include usb@fe800000 { - compatible = "fsl,ls1028a-dwc3", "snps,dwc3"; + compatible = "fsl,ls1028a-dwc3"; reg = <0xfe800000 0x100000>; interrupts = ; }; diff --git a/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml b/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml index ca677d1a82749..d06efe4dbb3be 100644 --- a/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml +++ b/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml @@ -36,6 +36,7 @@ properties: - fsl,imx8mm-usbmisc - fsl,imx8mn-usbmisc - fsl,imx8ulp-usbmisc + - fsl,imx94-usbmisc - fsl,imx95-usbmisc - const: fsl,imx7d-usbmisc - const: fsl,imx6q-usbmisc diff --git a/Documentation/devicetree/bindings/usb/generic-ehci.yaml b/Documentation/devicetree/bindings/usb/generic-ehci.yaml index 508d958e698c2..4e84bead02325 100644 --- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml @@ -46,6 +46,7 @@ properties: - aspeed,ast2400-ehci - aspeed,ast2500-ehci - aspeed,ast2600-ehci + - aspeed,ast2700-ehci - brcm,bcm3384-ehci - brcm,bcm63268-ehci - brcm,bcm6328-ehci diff --git a/Documentation/devicetree/bindings/usb/generic-xhci.yaml b/Documentation/devicetree/bindings/usb/generic-xhci.yaml index a2b94a1389990..62678abd74b57 100644 --- a/Documentation/devicetree/bindings/usb/generic-xhci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-xhci.yaml @@ -14,12 +14,15 @@ properties: oneOf: - description: Generic xHCI device const: generic-xhci - - description: Armada 37xx/375/38x/8k SoCs + - description: Armada 375/38x SoCs items: - enum: - - marvell,armada3700-xhci - marvell,armada-375-xhci - marvell,armada-380-xhci + - description: Armada 37xx/8k SoCs + items: + - enum: + - marvell,armada3700-xhci - marvell,armada-8k-xhci - const: generic-xhci - description: Broadcom SoCs with power domains @@ -53,6 +56,14 @@ properties: dma-coherent: true + dr_mode: + enum: + - host + - otg + + iommus: + maxItems: 1 + power-domains: maxItems: 1 diff --git a/Documentation/devicetree/bindings/usb/intel,ixp4xx-udc.yaml b/Documentation/devicetree/bindings/usb/intel,ixp4xx-udc.yaml index 4ed6027468972..91a149ad3ad6e 100644 --- a/Documentation/devicetree/bindings/usb/intel,ixp4xx-udc.yaml +++ b/Documentation/devicetree/bindings/usb/intel,ixp4xx-udc.yaml @@ -10,7 +10,7 @@ description: The IXP4xx SoCs has a full-speed USB Device Controller with 16 endpoints and a built-in transceiver. maintainers: - - Linus Walleij + - Linus Walleij properties: compatible: diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml index 004d3ebec0919..231e6f35a986f 100644 --- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml @@ -34,6 +34,7 @@ properties: - mediatek,mt8183-xhci - mediatek,mt8186-xhci - mediatek,mt8188-xhci + - mediatek,mt8189-xhci - mediatek,mt8192-xhci - mediatek,mt8195-xhci - mediatek,mt8365-xhci @@ -168,7 +169,8 @@ properties: 104 - used by mt8195, IP1, specific 1.04; 105 - used by mt8195, IP2, specific 1.05; 106 - used by mt8195, IP3, specific 1.06; - enum: [1, 2, 101, 102, 103, 104, 105, 106] + 110 - used by mt8189, IP4, specific 1.10; + enum: [1, 2, 101, 102, 103, 104, 105, 106, 110] mediatek,u3p-dis-msk: $ref: /schemas/types.yaml#/definitions/uint32 diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra234-xusb.yaml b/Documentation/devicetree/bindings/usb/nvidia,tegra234-xusb.yaml index db761dcbf72af..ec0993497fbbd 100644 --- a/Documentation/devicetree/bindings/usb/nvidia,tegra234-xusb.yaml +++ b/Documentation/devicetree/bindings/usb/nvidia,tegra234-xusb.yaml @@ -32,9 +32,35 @@ properties: - const: bar2 interrupts: + minItems: 2 items: - description: xHCI host interrupt - description: mailbox interrupt + - description: USB wake event 0 + - description: USB wake event 1 + - description: USB wake event 2 + - description: USB wake event 3 + - description: USB wake event 4 + - description: USB wake event 5 + - description: USB wake event 6 + description: | + The first two interrupts are required for the USB host controller. The + remaining USB wake event interrupts are optional. Each USB wake event is + independent; it is not necessary to use all of these events on a + platform. The USB host controller can function even if no wake-up events + are defined. The USB wake event interrupts are handled by the Tegra PMC; + hence, the interrupt controller for these is the PMC and the interrupt + IDs correspond to the PMC wake event IDs. A complete list of wake event + IDs is provided below, and this information is also present in the Tegra + TRM document. + + PMC wake-up 76 for USB3 port 0 wakeup + PMC wake-up 77 for USB3 port 1 wakeup + PMC wake-up 78 for USB3 port 2 and port 3 wakeup + PMC wake-up 79 for USB2 port 0 wakeup + PMC wake-up 80 for USB2 port 1 wakeup + PMC wake-up 81 for USB2 port 2 wakeup + PMC wake-up 82 for USB2 port 3 wakeup clocks: items: @@ -127,8 +153,9 @@ examples: <0x03650000 0x10000>; reg-names = "hcd", "fpci", "bar2"; - interrupts = , - ; + interrupts-extended = <&gic GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, + <&gic GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, + <&pmc 76 IRQ_TYPE_LEVEL_HIGH>; clocks = <&bpmp TEGRA234_CLK_XUSB_CORE_HOST>, <&bpmp TEGRA234_CLK_XUSB_FALCON>, diff --git a/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml b/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml index 6d3ef364672e9..6d3fa2bc9ceec 100644 --- a/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml @@ -28,7 +28,6 @@ properties: - qcom,pm4125-typec - const: qcom,pmi632-typec - connector: type: object $ref: /schemas/connector/usb-connector.yaml# diff --git a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml index d49a58d5478ff..8cee7c5582f2a 100644 --- a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml @@ -24,6 +24,8 @@ properties: compatible: items: - enum: + - qcom,glymur-dwc3 + - qcom,glymur-dwc3-mp - qcom,ipq4019-dwc3 - qcom,ipq5018-dwc3 - qcom,ipq5332-dwc3 @@ -32,6 +34,7 @@ properties: - qcom,ipq8064-dwc3 - qcom,ipq8074-dwc3 - qcom,ipq9574-dwc3 + - qcom,kaanapali-dwc3 - qcom,milos-dwc3 - qcom,msm8953-dwc3 - qcom,msm8994-dwc3 @@ -67,6 +70,7 @@ properties: - qcom,sm8450-dwc3 - qcom,sm8550-dwc3 - qcom,sm8650-dwc3 + - qcom,sm8750-dwc3 - qcom,x1e80100-dwc3 - qcom,x1e80100-dwc3-mp - const: qcom,snps-dwc3 @@ -200,6 +204,7 @@ allOf: contains: enum: - qcom,ipq9574-dwc3 + - qcom,kaanapali-dwc3 - qcom,msm8953-dwc3 - qcom,msm8996-dwc3 - qcom,msm8998-dwc3 @@ -213,6 +218,7 @@ allOf: - qcom,sdx65-dwc3 - qcom,sdx75-dwc3 - qcom,sm6350-dwc3 + - qcom,sm8750-dwc3 then: properties: clocks: @@ -387,6 +393,28 @@ allOf: - const: mock_utmi - const: xo + - if: + properties: + compatible: + contains: + enum: + - qcom,glymur-dwc3 + - qcom,glymur-dwc3-mp + + then: + properties: + clocks: + maxItems: 7 + clock-names: + items: + - const: cfg_noc + - const: core + - const: iface + - const: sleep + - const: mock_utmi + - const: noc_aggr_north + - const: noc_aggr_south + - if: properties: compatible: @@ -456,6 +484,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-dwc3 - qcom,milos-dwc3 - qcom,x1e80100-dwc3 then: @@ -479,6 +508,7 @@ allOf: enum: - qcom,ipq4019-dwc3 - qcom,ipq8064-dwc3 + - qcom,kaanapali-dwc3 - qcom,msm8994-dwc3 - qcom,qcs615-dwc3 - qcom,qcs8300-dwc3 @@ -501,6 +531,7 @@ allOf: - qcom,sm8450-dwc3 - qcom,sm8550-dwc3 - qcom,sm8650-dwc3 + - qcom,sm8750-dwc3 then: properties: interrupts: @@ -521,6 +552,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-dwc3-mp - qcom,sc8180x-dwc3-mp - qcom,x1e80100-dwc3-mp then: diff --git a/Documentation/devicetree/bindings/usb/renesas,rzg3e-xhci.yaml b/Documentation/devicetree/bindings/usb/renesas,rzg3e-xhci.yaml index 98260f9fb4426..3f4b09e48ce09 100644 --- a/Documentation/devicetree/bindings/usb/renesas,rzg3e-xhci.yaml +++ b/Documentation/devicetree/bindings/usb/renesas,rzg3e-xhci.yaml @@ -4,14 +4,22 @@ $id: http://devicetree.org/schemas/usb/renesas,rzg3e-xhci.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Renesas RZ/G3E USB 3.2 Gen2 Host controller +title: Renesas USB 3.2 Gen2 Host controller maintainers: - Biju Das properties: compatible: - const: renesas,r9a09g047-xhci + oneOf: + - items: + - enum: + - renesas,r9a09g056-xhci # RZ/V2N + - renesas,r9a09g057-xhci # RZ/V2H(P) + - const: renesas,r9a09g047-xhci + + - items: + - const: renesas,r9a09g047-xhci # RZ/G3E reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/usb/samsung,exynos-dwc3.yaml b/Documentation/devicetree/bindings/usb/samsung,exynos-dwc3.yaml index 6d39e50669447..8af0143c3e471 100644 --- a/Documentation/devicetree/bindings/usb/samsung,exynos-dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/samsung,exynos-dwc3.yaml @@ -21,6 +21,9 @@ properties: - samsung,exynos7870-dwusb3 - samsung,exynos850-dwusb3 - samsung,exynosautov920-dwusb3 + - items: + - const: samsung,exynos8890-dwusb3 + - const: samsung,exynos7-dwusb3 - items: - const: samsung,exynos990-dwusb3 - const: samsung,exynos850-dwusb3 @@ -36,6 +39,9 @@ properties: minItems: 1 maxItems: 4 + power-domains: + maxItems: 1 + ranges: true '#size-cells': diff --git a/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml b/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml index bec1c8047bc05..06099e93c6c30 100644 --- a/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml +++ b/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml @@ -25,6 +25,14 @@ properties: interrupts: maxItems: 1 + id-gpios: + description: + An input gpio for USB ID pin. Upon detecting a UFP device, HD3SS3220 + will keep ID pin high if VBUS is not at VSafe0V. Once VBUS is at VSafe0V, + the HD3SS3220 will assert ID pin low. This is done to enforce Type-C + requirement that VBUS must be at VSafe0V before re-enabling VBUS. + maxItems: 1 + ports: $ref: /schemas/graph.yaml#/properties/ports description: OF graph bindings (specified in bindings/graph.txt) that model diff --git a/Documentation/devicetree/bindings/usb/usb-uhci.yaml b/Documentation/devicetree/bindings/usb/usb-uhci.yaml index d8336f72dc1fc..e050ca203945b 100644 --- a/Documentation/devicetree/bindings/usb/usb-uhci.yaml +++ b/Documentation/devicetree/bindings/usb/usb-uhci.yaml @@ -20,6 +20,7 @@ properties: - aspeed,ast2400-uhci - aspeed,ast2500-uhci - aspeed,ast2600-uhci + - aspeed,ast2700-uhci - const: generic-uhci reg: @@ -28,6 +29,9 @@ properties: interrupts: maxItems: 1 + resets: + maxItems: 1 + '#ports': $ref: /schemas/types.yaml#/definitions/uint32 @@ -50,6 +54,15 @@ allOf: required: - clocks + - if: + properties: + compatible: + contains: + const: aspeed,ast2700-uhci + then: + required: + - resets + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index beab81e462d23..c7591b2aec2a7 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -30,6 +30,8 @@ patternProperties: description: 70mai Co., Ltd. "^8dev,.*": description: 8devices, UAB + "^9tripod,.*": + description: Shenzhen 9Tripod Innovation and Development CO., LTD. "^abb,.*": description: ABB "^abilis,.*": @@ -132,6 +134,8 @@ patternProperties: description: Anbernic "^andestech,.*": description: Andes Technology Corporation + "^anlogic,.*": + description: Shanghai Anlogic Infotech Co., Ltd. "^anvo,.*": description: Anvo-Systems Dresden GmbH "^aoly,.*": @@ -176,6 +180,8 @@ patternProperties: description: All Sensors Corporation "^asix,.*": description: ASIX Electronics Corporation + "^asl-tek,.*": + description: ASL Xiamen Technology Co., Ltd. "^aspeed,.*": description: ASPEED Technology Inc. "^asrock,.*": @@ -251,6 +257,8 @@ patternProperties: description: Shanghai Broadmobi Communication Technology Co.,Ltd. "^bsh,.*": description: BSH Hausgeraete GmbH + "^bst,.*": + description: Black Sesame Technologies Co., Ltd. "^bticino,.*": description: Bticino International "^buffalo,.*": @@ -570,6 +578,8 @@ patternProperties: description: Foxconn Industrial Internet "^firefly,.*": description: Firefly + "^fitipower,.*": + description: Fitipower Integrated Technology Inc. "^flipkart,.*": description: Flipkart Inc. "^focaltech,.*": @@ -835,6 +845,8 @@ patternProperties: description: JOZ BV "^jty,.*": description: JTY + "^jutouch,.*": + description: JuTouch Technology Co., Ltd. "^kam,.*": description: Kamstrup A/S "^karo,.*": @@ -907,6 +919,8 @@ patternProperties: description: Lincoln Technology Solutions "^lineartechnology,.*": description: Linear Technology + "^linkease,.*": + description: Shenzhen LinkEase Network Technology Co., Ltd. "^linksprite,.*": description: LinkSprite Technologies, Inc. "^linksys,.*": @@ -1023,6 +1037,8 @@ patternProperties: description: MikroElektronika d.o.o. "^mikrotik,.*": description: MikroTik + "^milianke,.*": + description: Changzhou Milianke Electronic Technology Co., Ltd "^milkv,.*": description: MilkV Technology Co., Ltd "^miniand,.*": @@ -1140,6 +1156,8 @@ patternProperties: description: Novatek "^novtech,.*": description: NovTech, Inc. + "^nuclei,.*": + description: Nuclei System Technology "^numonyx,.*": description: Numonyx (deprecated, use micron) deprecated: true @@ -1323,6 +1341,8 @@ patternProperties: description: Raumfeld GmbH "^raydium,.*": description: Raydium Semiconductor Corp. + "^raystar,.*": + description: Raystar Optronics, Inc. "^rda,.*": description: Unisoc Communications, Inc. "^realtek,.*": @@ -1610,6 +1630,8 @@ patternProperties: description: Tempo Semiconductor "^tenda,.*": description: Shenzhen Tenda Technology Co., Ltd. + "^tenstorrent,.*": + description: Tenstorrent AI ULC "^terasic,.*": description: Terasic Inc. "^tesla,.*": diff --git a/Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml b/Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml index 6bbab3cb28e54..6259478bdae5b 100644 --- a/Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml @@ -14,7 +14,11 @@ allOf: properties: compatible: - const: airoha,en7581-wdt + oneOf: + - items: + - const: airoha,an7583-wdt + - const: airoha,en7581-wdt + - const: airoha,en7581-wdt reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml b/Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml index be78a9865584d..9322cb5b462a2 100644 --- a/Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml @@ -15,6 +15,7 @@ properties: - aspeed,ast2400-wdt - aspeed,ast2500-wdt - aspeed,ast2600-wdt + - aspeed,ast2700-wdt reg: maxItems: 1 @@ -87,13 +88,15 @@ properties: aspeed,reset-mask: $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 1 - maxItems: 2 + maxItems: 5 description: > A bitmask indicating which peripherals will be reset if the watchdog timer expires. On AST2500 SoCs this should be a single word defined using the AST2500_WDT_RESET_* macros; on AST2600 SoCs this should be a two-word array with the first word defined using the AST2600_WDT_RESET1_* macros, - and the second word defined using the AST2600_WDT_RESET2_* macros. + and the second word defined using the AST2600_WDT_RESET2_* macros; on + AST2700 SoCs, this should be five-word array from AST2700_WDT_RESET1_* + macros to AST2700_WDT_RESET5_* macros. required: - compatible @@ -114,6 +117,7 @@ allOf: enum: - aspeed,ast2500-wdt - aspeed,ast2600-wdt + - aspeed,ast2700-wdt - if: required: - aspeed,ext-active-high diff --git a/Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.yaml b/Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.yaml index 726dc872ad02d..3eb35f325f4c5 100644 --- a/Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.yaml +++ b/Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Faraday Technology FTWDT010 watchdog maintainers: - - Linus Walleij + - Linus Walleij - Corentin Labbe description: | diff --git a/Documentation/devicetree/bindings/watchdog/lantiq,wdt.yaml b/Documentation/devicetree/bindings/watchdog/lantiq,wdt.yaml new file mode 100644 index 0000000000000..a7edae9ca05a5 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/lantiq,wdt.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/lantiq,wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lantiq WTD watchdog + +maintainers: + - Hauke Mehrtens + +properties: + compatible: + oneOf: + - enum: + - lantiq,falcon-wdt + - lantiq,wdt + - lantiq,xrx100-wdt + - items: + - enum: + - lantiq,xrx200-wdt + - const: lantiq,xrx100-wdt + + reg: + maxItems: 1 + + lantiq,rcu: + $ref: /schemas/types.yaml#/definitions/phandle + description: Phandle to the RCU syscon node + +required: + - compatible + - reg + +allOf: + - $ref: watchdog.yaml# + - if: + properties: + compatible: + contains: + enum: + - lantiq,xrx100-wdt + - lantiq,falcon-wdt + then: + required: + - lantiq,rcu + +unevaluatedProperties: false + +examples: + - | + watchdog@803f0 { + compatible = "lantiq,xrx200-wdt", "lantiq,xrx100-wdt"; + reg = <0x803f0 0x10>; + + lantiq,rcu = <&rcu0>; + }; diff --git a/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt b/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt deleted file mode 100644 index 18d4d83027026..0000000000000 --- a/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt +++ /dev/null @@ -1,24 +0,0 @@ -Lantiq WTD watchdog binding -============================ - -This describes the binding of the Lantiq watchdog driver. - -------------------------------------------------------------------------------- -Required properties: -- compatible : Should be one of - "lantiq,wdt" - "lantiq,xrx100-wdt" - "lantiq,xrx200-wdt", "lantiq,xrx100-wdt" - "lantiq,falcon-wdt" -- reg : Address of the watchdog block -- lantiq,rcu : A phandle to the RCU syscon (required for - "lantiq,falcon-wdt" and "lantiq,xrx100-wdt") - -------------------------------------------------------------------------------- -Example for the watchdog on the xRX200 SoCs: - watchdog@803f0 { - compatible = "lantiq,xrx200-wdt", "lantiq,xrx100-wdt"; - reg = <0x803f0 0x10>; - - lantiq,rcu = <&rcu0>; - }; diff --git a/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml b/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml index 81690d4b62a64..50a9b468c4a3e 100644 --- a/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/watchdog/loongson,ls1x-wdt.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Loongson-1 Watchdog Timer +title: Loongson Watchdog Timer maintainers: - Keguang Zhang @@ -17,6 +17,7 @@ properties: enum: - loongson,ls1b-wdt - loongson,ls1c-wdt + - loongson,ls2k0300-wdt reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/watchdog/marvel.txt b/Documentation/devicetree/bindings/watchdog/marvel.txt deleted file mode 100644 index c1b67a78f00c7..0000000000000 --- a/Documentation/devicetree/bindings/watchdog/marvel.txt +++ /dev/null @@ -1,45 +0,0 @@ -* Marvell Orion Watchdog Time - -Required Properties: - -- Compatibility : "marvell,orion-wdt" - "marvell,armada-370-wdt" - "marvell,armada-xp-wdt" - "marvell,armada-375-wdt" - "marvell,armada-380-wdt" - -- reg : Should contain two entries: first one with the - timer control address, second one with the - rstout enable address. - -For "marvell,armada-375-wdt" and "marvell,armada-380-wdt": - -- reg : A third entry is mandatory and should contain the - shared mask/unmask RSTOUT address. - -Clocks required for compatibles = "marvell,orion-wdt", - "marvell,armada-370-wdt": -- clocks : Must contain a single entry describing the clock input - -Clocks required for compatibles = "marvell,armada-xp-wdt" - "marvell,armada-375-wdt" - "marvell,armada-380-wdt": -- clocks : Must contain an entry for each entry in clock-names. -- clock-names : Must include the following entries: - "nbclk" (L2/coherency fabric clock), - "fixed" (Reference 25 MHz fixed-clock). - -Optional properties: - -- interrupts : Contains the IRQ for watchdog expiration -- timeout-sec : Contains the watchdog timeout in seconds - -Example: - - wdt@20300 { - compatible = "marvell,orion-wdt"; - reg = <0x20300 0x28>, <0x20108 0x4>; - interrupts = <3>; - timeout-sec = <10>; - clocks = <&gate_clk 7>; - }; diff --git a/Documentation/devicetree/bindings/watchdog/marvell,orion-wdt.yaml b/Documentation/devicetree/bindings/watchdog/marvell,orion-wdt.yaml new file mode 100644 index 0000000000000..fdc7bc45dfdee --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/marvell,orion-wdt.yaml @@ -0,0 +1,100 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/marvell,orion-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Marvell Orion Watchdog Timer + +maintainers: + - Andrew Lunn + - Gregory Clement + +properties: + compatible: + enum: + - marvell,orion-wdt + - marvell,armada-370-wdt + - marvell,armada-xp-wdt + - marvell,armada-375-wdt + - marvell,armada-380-wdt + + reg: + minItems: 2 + items: + - description: Timer control register address + - description: RSTOUT enable register address + - description: Shared mask/unmask RSTOUT register address + + clocks: + minItems: 1 + items: + - description: L2/coherency fabric clock input + - description: Reference 25 MHz fixed-clock supply + + clock-names: + minItems: 1 + items: + - const: nbclk + - const: fixed + + interrupts: + minItems: 1 + items: + - description: timeout + - description: pre-timeout + +allOf: + - $ref: watchdog.yaml# + - if: + properties: + compatible: + contains: + enum: + - marvell,armada-375-wdt + - marvell,armada-380-wdt + then: + properties: + reg: + minItems: 3 + else: + properties: + reg: + maxItems: 2 + + - if: + properties: + compatible: + contains: + enum: + - marvell,armada-xp-wdt + - marvell,armada-375-wdt + - marvell,armada-380-wdt + then: + properties: + clocks: + minItems: 2 + clock-names: + minItems: 2 + interrupts: + minItems: 2 + + required: + - clock-names + +required: + - compatible + - reg + - clocks + +unevaluatedProperties: false + +examples: + - | + watchdog@20300 { + compatible = "marvell,orion-wdt"; + reg = <0x20300 0x28>, <0x20108 0x4>; + interrupts = <3>; + timeout-sec = <10>; + clocks = <&gate_clk 7>; + }; diff --git a/Documentation/devicetree/bindings/watchdog/maxim,max63xx.yaml b/Documentation/devicetree/bindings/watchdog/maxim,max63xx.yaml index 442c21f12a3b2..defe0401ded0b 100644 --- a/Documentation/devicetree/bindings/watchdog/maxim,max63xx.yaml +++ b/Documentation/devicetree/bindings/watchdog/maxim,max63xx.yaml @@ -8,7 +8,7 @@ title: Maxim 63xx Watchdog Timers maintainers: - Marc Zyngier - - Linus Walleij + - Linus Walleij allOf: - $ref: watchdog.yaml# diff --git a/Documentation/devicetree/bindings/watchdog/mediatek,mtk-wdt.yaml b/Documentation/devicetree/bindings/watchdog/mediatek,mtk-wdt.yaml index ba0bfd73ab62a..953629cb9558b 100644 --- a/Documentation/devicetree/bindings/watchdog/mediatek,mtk-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/mediatek,mtk-wdt.yaml @@ -41,6 +41,8 @@ properties: - mediatek,mt7623-wdt - mediatek,mt7629-wdt - mediatek,mt8173-wdt + - mediatek,mt8188-wdt + - mediatek,mt8189-wdt - mediatek,mt8365-wdt - mediatek,mt8516-wdt - const: mediatek,mt6589-wdt diff --git a/Documentation/devicetree/bindings/watchdog/omap-wdt.txt b/Documentation/devicetree/bindings/watchdog/omap-wdt.txt deleted file mode 100644 index 1fa20e453a2d0..0000000000000 --- a/Documentation/devicetree/bindings/watchdog/omap-wdt.txt +++ /dev/null @@ -1,15 +0,0 @@ -TI Watchdog Timer (WDT) Controller for OMAP - -Required properties: -- compatible : "ti,omap3-wdt" for OMAP3 or "ti,omap4-wdt" for OMAP4 -- ti,hwmods : Name of the hwmod associated to the WDT - -Optional properties: -- timeout-sec : default watchdog timeout in seconds - -Examples: - -wdt2: wdt@4a314000 { - compatible = "ti,omap4-wdt", "ti,omap3-wdt"; - ti,hwmods = "wd_timer2"; -}; diff --git a/Documentation/devicetree/bindings/watchdog/qcom,pm8916-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom,pm8916-wdt.yaml index dc6af204e8af5..a519422c371c1 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom,pm8916-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom,pm8916-wdt.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm PM8916 watchdog timer controller maintainers: - - Krzysztof Kozlowski + - Krzysztof Kozlowski allOf: - $ref: watchdog.yaml# diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index 49e2b807db0bc..54f5311ed016d 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -22,6 +22,7 @@ properties: - qcom,apss-wdt-ipq5332 - qcom,apss-wdt-ipq5424 - qcom,apss-wdt-ipq9574 + - qcom,apss-wdt-kaanapali - qcom,apss-wdt-msm8226 - qcom,apss-wdt-msm8974 - qcom,apss-wdt-msm8994 diff --git a/Documentation/devicetree/bindings/watchdog/renesas,r9a09g057-wdt.yaml b/Documentation/devicetree/bindings/watchdog/renesas,r9a09g057-wdt.yaml new file mode 100644 index 0000000000000..099200c4f1364 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/renesas,r9a09g057-wdt.yaml @@ -0,0 +1,99 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/renesas,r9a09g057-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/V2H(P) Watchdog Timer (WDT) Controller + +maintainers: + - Lad Prabhakar + +properties: + compatible: + oneOf: + - items: + - enum: + - renesas,r9a09g047-wdt # RZ/G3E + - renesas,r9a09g056-wdt # RZ/V2N + - const: renesas,r9a09g057-wdt # RZ/V2H(P) + + - items: + - const: renesas,r9a09g087-wdt # RZ/N2H + - const: renesas,r9a09g077-wdt # RZ/T2H + + - enum: + - renesas,r9a09g057-wdt # RZ/V2H(P) + - renesas,r9a09g077-wdt # RZ/T2H + + reg: + minItems: 1 + maxItems: 2 + + clocks: + minItems: 1 + items: + - description: Register access clock + - description: Main clock + + clock-names: + minItems: 1 + items: + - const: pclk + - const: oscclk + + power-domains: + maxItems: 1 + + resets: + maxItems: 1 + + timeout-sec: true + +required: + - compatible + - reg + - clocks + - clock-names + - power-domains + +allOf: + - $ref: watchdog.yaml# + + - if: + properties: + compatible: + contains: + const: renesas,r9a09g057-wdt + then: + properties: + reg: + maxItems: 1 + clocks: + minItems: 2 + clock-names: + minItems: 2 + else: + properties: + clocks: + maxItems: 1 + clock-names: + maxItems: 1 + reg: + minItems: 2 + resets: false + +additionalProperties: false + +examples: + - | + #include + + watchdog@11c00400 { + compatible = "renesas,r9a09g057-wdt"; + reg = <0x11c00400 0x400>; + clocks = <&cpg CPG_MOD 0x4b>, <&cpg CPG_MOD 0x4c>; + clock-names = "pclk", "oscclk"; + resets = <&cpg 0x75>; + power-domains = <&cpg>; + }; diff --git a/Documentation/devicetree/bindings/watchdog/renesas,rcar-gen3-wwdt.yaml b/Documentation/devicetree/bindings/watchdog/renesas,rcar-gen3-wwdt.yaml new file mode 100644 index 0000000000000..ffafe9a6d3f5c --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/renesas,rcar-gen3-wwdt.yaml @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/renesas,rcar-gen3-wwdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas Window Watchdog Timer (WWDT) Controller + +maintainers: + - Wolfram Sang + +properties: + compatible: + oneOf: + - items: + - enum: + - renesas,r8a77970-wwdt # R-Car V3M + - renesas,r8a77980-wwdt # R-Car V3H + - const: renesas,rcar-gen3-wwdt + + - items: + - enum: + - renesas,r8a779a0-wwdt # R-Car V3U + - renesas,r8a779f0-wwdt # R-Car S4 + - renesas,r8a779g0-wwdt # R-Car V4H + - renesas,r8a779h0-wwdt # R-Car V4M + - const: renesas,rcar-gen4-wwdt + + reg: + maxItems: 1 + + interrupts: + items: + - description: Pretimeout, 75% of overflow reached + - description: Error occurred + + interrupt-names: + items: + - const: pretimeout + - const: error + + clocks: + items: + - description: Counting clock + - description: Bus clock + + clock-names: + items: + - const: cnt + - const: bus + + resets: + minItems: 1 + maxItems: 2 + + reset-names: + minItems: 1 + items: + - const: cnt + - const: bus + + power-domains: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - interrupt-names + - clocks + - clock-names + - resets + - reset-names + - power-domains + +allOf: + - $ref: watchdog.yaml# + + - if: + properties: + compatible: + contains: + enum: + - renesas,r8a779a0-wwdt + - renesas,r8a779f0-wwdt + then: + properties: + resets: + minItems: 2 + reset-names: + minItems: 2 + +additionalProperties: false + +examples: + - | + #include + #include + #include + + watchdog@ffc90000 { + compatible = "renesas,r8a779g0-wwdt", + "renesas,rcar-gen4-wwdt"; + reg = <0xffc90000 0x10>; + interrupts = , + ; + interrupt-names = "pretimeout", "error"; + clocks = <&cpg CPG_CORE R8A779G0_CLK_R>, + <&cpg CPG_CORE R8A779G0_CLK_SASYNCRT>; + clock-names = "cnt", "bus"; + power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; + resets = <&cpg 1200>; + reset-names = "cnt"; + }; diff --git a/Documentation/devicetree/bindings/watchdog/renesas,rza-wdt.yaml b/Documentation/devicetree/bindings/watchdog/renesas,rza-wdt.yaml new file mode 100644 index 0000000000000..ba922c3f7b104 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/renesas,rza-wdt.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/renesas,rza-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/A Watchdog Timer (WDT) Controller + +maintainers: + - Wolfram Sang + +properties: + compatible: + items: + - enum: + - renesas,r7s72100-wdt # RZ/A1 + - renesas,r7s9210-wdt # RZ/A2 + - const: renesas,rza-wdt # RZ/A + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + timeout-sec: true + +required: + - compatible + - reg + - clocks + +allOf: + - $ref: watchdog.yaml# + +additionalProperties: false + +examples: + - | + #include + #include + + watchdog@fcfe0000 { + compatible = "renesas,r7s72100-wdt", "renesas,rza-wdt"; + reg = <0xfcfe0000 0x6>; + interrupts = ; + clocks = <&p0_clk>; + }; diff --git a/Documentation/devicetree/bindings/watchdog/renesas,rzg2l-wdt.yaml b/Documentation/devicetree/bindings/watchdog/renesas,rzg2l-wdt.yaml new file mode 100644 index 0000000000000..a4d06c9c8b86b --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/renesas,rzg2l-wdt.yaml @@ -0,0 +1,111 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/renesas,rzg2l-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/G2L Watchdog Timer (WDT) Controller + +maintainers: + - Biju Das + +properties: + compatible: + oneOf: + - items: + - enum: + - renesas,r9a07g043-wdt # RZ/G2UL and RZ/Five + - renesas,r9a07g044-wdt # RZ/G2{L,LC} + - renesas,r9a07g054-wdt # RZ/V2L + - renesas,r9a08g045-wdt # RZ/G3S + - const: renesas,rzg2l-wdt + + - items: + - const: renesas,r9a09g011-wdt # RZ/V2M + - const: renesas,rzv2m-wdt # RZ/V2M + + reg: + maxItems: 1 + + interrupts: + minItems: 1 + items: + - description: Timeout + - description: Parity error + + interrupt-names: + minItems: 1 + items: + - const: wdt + - const: perrout + + clocks: + items: + - description: Register access clock + - description: Main clock + + clock-names: + items: + - const: pclk + - const: oscclk + + power-domains: + maxItems: 1 + + resets: + maxItems: 1 + + timeout-sec: true + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - power-domains + - resets + +allOf: + - $ref: watchdog.yaml# + + - if: + properties: + compatible: + contains: + const: renesas,rzg2l-wdt + then: + properties: + interrupts: + minItems: 2 + interrupt-names: + minItems: 2 + required: + - interrupt-names + else: + properties: + interrupts: + maxItems: 1 + interrupt-names: + maxItems: 1 + +additionalProperties: false + +examples: + - | + #include + #include + + watchdog@12800800 { + compatible = "renesas,r9a07g044-wdt", + "renesas,rzg2l-wdt"; + reg = <0x12800800 0x400>; + clocks = <&cpg CPG_MOD R9A07G044_WDT0_PCLK>, + <&cpg CPG_MOD R9A07G044_WDT0_CLK>; + clock-names = "pclk", "oscclk"; + interrupts = , + ; + interrupt-names = "wdt", "perrout"; + resets = <&cpg R9A07G044_WDT0_PRESETN>; + power-domains = <&cpg>; + }; diff --git a/Documentation/devicetree/bindings/watchdog/renesas,rzn1-wdt.yaml b/Documentation/devicetree/bindings/watchdog/renesas,rzn1-wdt.yaml new file mode 100644 index 0000000000000..7e3ee533cd568 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/renesas,rzn1-wdt.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/renesas,rzn1-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/N1 Watchdog Timer (WDT) Controller + +maintainers: + - Wolfram Sang + +properties: + compatible: + items: + - const: renesas,r9a06g032-wdt # RZ/N1D + - const: renesas,rzn1-wdt # RZ/N1 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + timeout-sec: true + +required: + - compatible + - reg + - interrupts + - clocks + +allOf: + - $ref: watchdog.yaml# + +additionalProperties: false + +examples: + - | + #include + #include + + watchdog@40008000 { + compatible = "renesas,r9a06g032-wdt", "renesas,rzn1-wdt"; + reg = <0x40008000 0x1000>; + interrupts = ; + clocks = <&sysctrl R9A06G032_CLK_WATCHDOG>; + }; diff --git a/Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml b/Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml index b6e60162c263c..7aebc5a5cf17d 100644 --- a/Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml @@ -13,30 +13,6 @@ maintainers: properties: compatible: oneOf: - - items: - - enum: - - renesas,r7s72100-wdt # RZ/A1 - - renesas,r7s9210-wdt # RZ/A2 - - const: renesas,rza-wdt # RZ/A - - - items: - - enum: - - renesas,r9a06g032-wdt # RZ/N1D - - const: renesas,rzn1-wdt # RZ/N1 - - - items: - - enum: - - renesas,r9a07g043-wdt # RZ/G2UL and RZ/Five - - renesas,r9a07g044-wdt # RZ/G2{L,LC} - - renesas,r9a07g054-wdt # RZ/V2L - - renesas,r9a08g045-wdt # RZ/G3S - - const: renesas,rzg2l-wdt - - - items: - - enum: - - renesas,r9a09g011-wdt # RZ/V2M - - const: renesas,rzv2m-wdt # RZ/V2M - - items: - enum: - renesas,r8a7742-wdt # RZ/G1H @@ -75,47 +51,14 @@ properties: - renesas,r8a779h0-wdt # R-Car V4M - const: renesas,rcar-gen4-wdt # R-Car Gen4 - - items: - - enum: - - renesas,r9a09g047-wdt # RZ/G3E - - renesas,r9a09g056-wdt # RZ/V2N - - const: renesas,r9a09g057-wdt # RZ/V2H(P) - - - enum: - - renesas,r9a09g057-wdt # RZ/V2H(P) - - renesas,r9a09g077-wdt # RZ/T2H - - - items: - - const: renesas,r9a09g087-wdt # RZ/N2H - - const: renesas,r9a09g077-wdt # RZ/T2H - reg: - minItems: 1 - maxItems: 2 + maxItems: 1 interrupts: - minItems: 1 - items: - - description: Timeout - - description: Parity error - - interrupt-names: - minItems: 1 - items: - - const: wdt - - const: perrout + maxItems: 1 clocks: - minItems: 1 - items: - - description: Register access clock - - description: Main clock - - clock-names: - minItems: 1 - items: - - const: pclk - - const: oscclk + maxItems: 1 power-domains: maxItems: 1 @@ -129,6 +72,8 @@ required: - compatible - reg - clocks + - interrupts + - power-domains allOf: - $ref: watchdog.yaml# @@ -138,90 +83,11 @@ allOf: properties: compatible: contains: - enum: - - renesas,r9a09g077-wdt - - renesas,rza-wdt - - renesas,rzn1-wdt + const: renesas,r8a77980-wdt then: required: - - power-domains - resets - - if: - properties: - compatible: - contains: - enum: - - renesas,r9a09g057-wdt - - renesas,rzg2l-wdt - - renesas,rzv2m-wdt - then: - properties: - clocks: - minItems: 2 - clock-names: - minItems: 2 - required: - - clock-names - else: - properties: - clocks: - maxItems: 1 - - - if: - properties: - compatible: - contains: - enum: - - renesas,rzg2l-wdt - then: - properties: - interrupts: - minItems: 2 - interrupt-names: - minItems: 2 - required: - - interrupt-names - else: - properties: - interrupts: - maxItems: 1 - - - if: - properties: - compatible: - contains: - enum: - - renesas,r9a09g057-wdt - - renesas,r9a09g077-wdt - then: - properties: - interrupts: false - interrupt-names: false - else: - required: - - interrupts - - - if: - properties: - compatible: - contains: - const: renesas,r9a09g077-wdt - then: - properties: - resets: false - clock-names: - maxItems: 1 - reg: - minItems: 2 - required: - - clock-names - - power-domains - else: - properties: - reg: - maxItems: 1 - additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml b/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml index ef088e0f6917e..609e98cdaaffd 100644 --- a/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml @@ -28,6 +28,7 @@ properties: - rockchip,rk3328-wdt - rockchip,rk3368-wdt - rockchip,rk3399-wdt + - rockchip,rk3506-wdt - rockchip,rk3562-wdt - rockchip,rk3568-wdt - rockchip,rk3576-wdt diff --git a/Documentation/devicetree/bindings/watchdog/ti,omap2-wdt.yaml b/Documentation/devicetree/bindings/watchdog/ti,omap2-wdt.yaml new file mode 100644 index 0000000000000..913b55222f296 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/ti,omap2-wdt.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/ti,omap2-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI OMAP Watchdog Timer Controller + +maintainers: + - Aaro Koskinen + +allOf: + - $ref: watchdog.yaml# + +properties: + compatible: + oneOf: + - enum: + - ti,omap2-wdt + - ti,omap3-wdt + - items: + - enum: + - ti,am4372-wdt + - ti,omap4-wdt + - ti,omap5-wdt + - const: ti,omap3-wdt + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + ti,hwmods: + description: Name of the hardware module associated with the watchdog. + $ref: /schemas/types.yaml#/definitions/string + deprecated: true + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + watchdog@48314000 { + compatible = "ti,omap3-wdt"; + reg = <0x48314000 0x80>; + ti,hwmods = "wd_timer2"; + }; diff --git a/Documentation/devicetree/bindings/watchdog/watchdog.yaml b/Documentation/devicetree/bindings/watchdog/watchdog.yaml index f0a584af1223e..77ac23516d6d4 100644 --- a/Documentation/devicetree/bindings/watchdog/watchdog.yaml +++ b/Documentation/devicetree/bindings/watchdog/watchdog.yaml @@ -21,9 +21,10 @@ select: properties: $nodename: - pattern: "^(timer|watchdog)(@.*|-([0-9]|[1-9][0-9]+))?$" + pattern: "^(pmic|timer|watchdog)(@.*|-([0-9]|[1-9][0-9]+))?$" timeout-sec: + maxItems: 1 description: Contains the watchdog timeout in seconds. diff --git a/Documentation/driver-api/cxl/allocation/page-allocator.rst b/Documentation/driver-api/cxl/allocation/page-allocator.rst index 7b8fe1b8d5bbb..3fa584a248bdd 100644 --- a/Documentation/driver-api/cxl/allocation/page-allocator.rst +++ b/Documentation/driver-api/cxl/allocation/page-allocator.rst @@ -41,37 +41,6 @@ To simplify this, the page allocator will prefer :code:`ZONE_MOVABLE` over will fallback to allocate from :code:`ZONE_NORMAL`. -Zone and Node Quirks -==================== -Let's consider a configuration where the local DRAM capacity is largely onlined -into :code:`ZONE_NORMAL`, with no :code:`ZONE_MOVABLE` capacity present. The -CXL capacity has the opposite configuration - all onlined in -:code:`ZONE_MOVABLE`. - -Under the default allocation policy, the page allocator will completely skip -:code:`ZONE_MOVABLE` as a valid allocation target. This is because, as of -Linux v6.15, the page allocator does (approximately) the following: :: - - for (each zone in local_node): - - for (each node in fallback_order): - - attempt_allocation(gfp_flags); - -Because the local node does not have :code:`ZONE_MOVABLE`, the CXL node is -functionally unreachable for direct allocation. As a result, the only way -for CXL capacity to be used is via `demotion` in the reclaim path. - -This configuration also means that if the DRAM ndoe has :code:`ZONE_MOVABLE` -capacity - when that capacity is depleted, the page allocator will actually -prefer CXL :code:`ZONE_MOVABLE` pages over DRAM :code:`ZONE_NORMAL` pages. - -We may wish to invert this priority in future Linux versions. - -If `demotion` and `swap` are disabled, Linux will begin to cause OOM crashes -when the DRAM nodes are depleted. See the reclaim section for more details. - - CGroups and CPUSets =================== Finally, assuming CXL memory is reachable via the page allocation (i.e. onlined diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 2b36ebde9cece..0198ac65e8744 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -383,7 +383,6 @@ NET PER-CPU MEM devm_alloc_percpu() - devm_free_percpu() PCI devm_pci_alloc_host_bridge() : managed PCI host bridge allocation diff --git a/Documentation/driver-api/firmware/efi/index.rst b/Documentation/driver-api/firmware/efi/index.rst index 4fe8abba9fc6b..5a6b6229592c9 100644 --- a/Documentation/driver-api/firmware/efi/index.rst +++ b/Documentation/driver-api/firmware/efi/index.rst @@ -1,11 +1,16 @@ .. SPDX-License-Identifier: GPL-2.0 -============ -UEFI Support -============ +==================================================== +Unified Extensible Firmware Interface (UEFI) Support +==================================================== UEFI stub library functions =========================== .. kernel-doc:: drivers/firmware/efi/libstub/mem.c :internal: + +UEFI Common Platform Error Record (CPER) functions +================================================== + +.. kernel-doc:: drivers/firmware/efi/cper.c diff --git a/Documentation/driver-api/generic_pt.rst b/Documentation/driver-api/generic_pt.rst new file mode 100644 index 0000000000000..fd29d1b525e51 --- /dev/null +++ b/Documentation/driver-api/generic_pt.rst @@ -0,0 +1,137 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================== +Generic Radix Page Table +======================== + +.. kernel-doc:: include/linux/generic_pt/common.h + :doc: Generic Radix Page Table + +.. kernel-doc:: drivers/iommu/generic_pt/pt_defs.h + :doc: Generic Page Table Language + +Usage +===== + +Generic PT is structured as a multi-compilation system. Since each format +provides an API using a common set of names there can be only one format active +within a compilation unit. This design avoids function pointers around the low +level API. + +Instead the function pointers can end up at the higher level API (i.e. +map/unmap, etc.) and the per-format code can be directly inlined into the +per-format compilation unit. For something like IOMMU each format will be +compiled into a per-format IOMMU operations kernel module. + +For this to work the .c file for each compilation unit will include both the +format headers and the generic code for the implementation. For instance in an +implementation compilation unit the headers would normally be included as +follows: + +generic_pt/fmt/iommu_amdv1.c:: + + #include + #include "defs_amdv1.h" + #include "../pt_defs.h" + #include "amdv1.h" + #include "../pt_common.h" + #include "../pt_iter.h" + #include "../iommu_pt.h" /* The IOMMU implementation */ + +iommu_pt.h includes definitions that will generate the operations functions for +map/unmap/etc. using the definitions provided by AMDv1. The resulting module +will have exported symbols named like pt_iommu_amdv1_init(). + +Refer to drivers/iommu/generic_pt/fmt/iommu_template.h for an example of how the +IOMMU implementation uses multi-compilation to generate per-format ops structs +pointers. + +The format code is written so that the common names arise from #defines to +distinct format specific names. This is intended to aid debuggability by +avoiding symbol clashes across all the different formats. + +Exported symbols and other global names are mangled using a per-format string +via the NS() helper macro. + +The format uses struct pt_common as the top-level struct for the table, +and each format will have its own struct pt_xxx which embeds it to store +format-specific information. + +The implementation will further wrap struct pt_common in its own top-level +struct, such as struct pt_iommu_amdv1. + +Format functions at the struct pt_common level +---------------------------------------------- + +.. kernel-doc:: include/linux/generic_pt/common.h + :identifiers: +.. kernel-doc:: drivers/iommu/generic_pt/pt_common.h + +Iteration Helpers +----------------- + +.. kernel-doc:: drivers/iommu/generic_pt/pt_iter.h + +Writing a Format +---------------- + +It is best to start from a simple format that is similar to the target. x86_64 +is usually a good reference for something simple, and AMDv1 is something fairly +complete. + +The required inline functions need to be implemented in the format header. +These should all follow the standard pattern of:: + + static inline pt_oaddr_t amdv1pt_entry_oa(const struct pt_state *pts) + { + [..] + } + #define pt_entry_oa amdv1pt_entry_oa + +where a uniquely named per-format inline function provides the implementation +and a define maps it to the generic name. This is intended to make debug symbols +work better. inline functions should always be used as the prototypes in +pt_common.h will cause the compiler to validate the function signature to +prevent errors. + +Review pt_fmt_defaults.h to understand some of the optional inlines. + +Once the format compiles then it should be run through the generic page table +kunit test in kunit_generic_pt.h using kunit. For example:: + + $ tools/testing/kunit/kunit.py run --build_dir build_kunit_x86_64 --arch x86_64 --kunitconfig ./drivers/iommu/generic_pt/.kunitconfig amdv1_fmt_test.* + [...] + [11:15:08] Testing complete. Ran 9 tests: passed: 9 + [11:15:09] Elapsed time: 3.137s total, 0.001s configuring, 2.368s building, 0.311s running + +The generic tests are intended to prove out the format functions and give +clearer failures to speed up finding the problems. Once those pass then the +entire kunit suite should be run. + +IOMMU Invalidation Features +--------------------------- + +Invalidation is how the page table algorithms synchronize with a HW cache of the +page table memory, typically called the TLB (or IOTLB for IOMMU cases). + +The TLB can store present PTEs, non-present PTEs and table pointers, depending +on its design. Every HW has its own approach on how to describe what has changed +to have changed items removed from the TLB. + +PT_FEAT_FLUSH_RANGE +~~~~~~~~~~~~~~~~~~~ + +PT_FEAT_FLUSH_RANGE is the easiest scheme to understand. It tries to generate a +single range invalidation for each operation, over-invalidating if there are +gaps of VA that don't need invalidation. This trades off impacted VA for number +of invalidation operations. It does not keep track of what is being invalidated; +however, if pages have to be freed then page table pointers have to be cleaned +from the walk cache. The range can start/end at any page boundary. + +PT_FEAT_FLUSH_RANGE_NO_GAPS +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +PT_FEAT_FLUSH_RANGE_NO_GAPS is similar to PT_FEAT_FLUSH_RANGE; however, it tries +to minimize the amount of impacted VA by issuing extra flush operations. This is +useful if the cost of processing VA is very high, for instance because a +hypervisor is processing the page table with a shadowing algorithm. diff --git a/Documentation/driver-api/gpio/index.rst b/Documentation/driver-api/gpio/index.rst index 87929840e85a2..bee58f709b9ac 100644 --- a/Documentation/driver-api/gpio/index.rst +++ b/Documentation/driver-api/gpio/index.rst @@ -15,6 +15,7 @@ Contents: legacy-boards drivers-on-gpio bt8xxgpio + pca953x Core ==== diff --git a/Documentation/driver-api/gpio/pca953x.rst b/Documentation/driver-api/gpio/pca953x.rst new file mode 100644 index 0000000000000..4bd7cf1120cba --- /dev/null +++ b/Documentation/driver-api/gpio/pca953x.rst @@ -0,0 +1,552 @@ +============================================ +PCA953x I²C GPIO expander compatibility list +============================================ + +:Author: Levente Révész + +I went through all the datasheets and created this note listing +chip functions and register layouts. + +Overview of chips +================= + +Chips with the basic 4 registers +-------------------------------- + +These chips have 4 register banks: input, output, invert and direction. +Each of these banks contains (lines/8) registers, one for each GPIO port. + +Banks offset is always a power of 2: + +- 4 lines -> bank offset is 1 +- 8 lines -> bank offset is 1 +- 16 lines -> bank offset is 2 +- 24 lines -> bank offset is 4 +- 32 lines -> bank offset is 4 +- 40 lines -> bank offset is 8 + +For example, register layout of GPIO expander with 24 lines: + ++------+-----------------+--------+ +| addr | function | bank | ++======+=================+========+ +| 00 | input port0 | | ++------+-----------------+ | +| 01 | input port1 | bank 0 | ++------+-----------------+ | +| 02 | input port2 | | ++------+-----------------+--------+ +| 03 | n/a | | ++------+-----------------+--------+ +| 04 | output port0 | | ++------+-----------------+ | +| 05 | output port1 | bank 1 | ++------+-----------------+ | +| 06 | output port2 | | ++------+-----------------+--------+ +| 07 | n/a | | ++------+-----------------+--------+ +| 08 | invert port0 | | ++------+-----------------+ | +| 09 | invert port1 | bank 2 | ++------+-----------------+ | +| 0A | invert port2 | | ++------+-----------------+--------+ +| 0B | n/a | | ++------+-----------------+--------+ +| 0C | direction port0 | | ++------+-----------------+ | +| 0D | direction port1 | bank 3 | ++------+-----------------+ | +| 0E | direction port2 | | ++------+-----------------+--------+ +| 0F | n/a | | ++------+-----------------+--------+ + +.. note:: + This is followed by all supported chips, except by pcal6534. + +The table below shows the offsets for each of the compatible chips: + +========== ===== ========= ===== ====== ====== ========= +compatible lines interrupt input output invert direction +========== ===== ========= ===== ====== ====== ========= +pca9536 4 no 00 01 02 03 +pca9537 4 yes 00 01 02 03 +pca6408 8 yes 00 01 02 03 +tca6408 8 yes 00 01 02 03 +pca9534 8 yes 00 01 02 03 +pca9538 8 yes 00 01 02 03 +pca9554 8 yes 00 01 02 03 +tca9554 8 yes 00 01 02 03 +pca9556 8 no 00 01 02 03 +pca9557 8 no 00 01 02 03 +pca6107 8 yes 00 01 02 03 +pca6416 16 yes 00 02 04 06 +tca6416 16 yes 00 02 04 06 +pca9535 16 yes 00 02 04 06 +pca9539 16 yes 00 02 04 06 +tca9539 16 yes 00 02 04 06 +pca9555 16 yes 00 02 04 06 +max7318 16 yes 00 02 04 06 +tca6424 24 yes 00 04 08 0C +========== ===== ========= ===== ====== ====== ========= + +Chips with additional timeout_en register +----------------------------------------- + +These Maxim chips have a bus timeout function which can be enabled in +the timeout_en register. This is present in only two chips. Defaults to +timeout disabled. + +========== ===== ========= ===== ====== ====== ========= ========== +compatible lines interrupt input output invert direction timeout_en +========== ===== ========= ===== ====== ====== ========= ========== +max7310 8 no 00 01 02 03 04 +max7312 16 yes 00 02 04 06 08 +========== ===== ========= ===== ====== ====== ========= ========== + +Chips with additional int_mask register +--------------------------------------- + +These chips have an interrupt mask register in addition to the 4 basic +registers. The interrupt masks default to all interrupts disabled. To +use interrupts with these chips, the driver has to set the int_mask +register. + +========== ===== ========= ===== ====== ====== ========= ======== +compatible lines interrupt input output invert direction int_mask +========== ===== ========= ===== ====== ====== ========= ======== +pca9505 40 yes 00 08 10 18 20 +pca9506 40 yes 00 08 10 18 20 +========== ===== ========= ===== ====== ====== ========= ======== + +Chips with additional int_mask and out_conf registers +----------------------------------------------------- + +This chip has an interrupt mask register, and an output port +configuration register, which can select between push-pull and +open-drain modes. Each bit controls two lines. Both of these registers +are present in PCAL chips as well, albeit the out_conf works +differently. + +========== ===== ========= ===== ====== ====== ========= ======== ======== +compatible lines interrupt input output invert direction int_mask out_conf +========== ===== ========= ===== ====== ====== ========= ======== ======== +pca9698 40 yes 00 08 10 18 20 28 +========== ===== ========= ===== ====== ====== ========= ======== ======== + +pca9698 also has a "master output" register for setting all outputs per +port to the same value simultaneously, and a chip specific mode register +for various additional chip settings. + +========== ============= ==== +compatible master_output mode +========== ============= ==== +pca9698 29 2A +========== ============= ==== + +Chips with LED blink and intensity control +------------------------------------------ + +These Maxim chips have no invert register. + +They have two sets of output registers (output0 and output1). An internal +timer alternates the effective output between the values set in these +registers, if blink mode is enabled in the blink register. The +master_intensity register and the intensity registers together define +the PWM intensity value for each pair of outputs. + +These chips can be used as simple GPIO expanders if the driver handles the +input, output0 and direction registers. + +========== ===== ========= ===== ======= ========= ======= ================ ===== ========= +compatible lines interrupt input output0 direction output1 master_intensity blink intensity +========== ===== ========= ===== ======= ========= ======= ================ ===== ========= +max7315 8 yes 00 01 03 09 0E 0F 10 +max7313 16 yes 00 02 06 0A 0E 0F 10 +========== ===== ========= ===== ======= ========= ======= ================ ===== ========= + +Basic PCAL chips +---------------- + +========== ===== ========= ===== ====== ====== ========= +compatible lines interrupt input output invert direction +========== ===== ========= ===== ====== ====== ========= +pcal6408 8 yes 00 01 02 03 +pcal9554b 8 yes 00 01 02 03 +pcal6416 16 yes 00 02 04 06 +pcal9535 16 yes 00 02 04 06 +pcal9555a 16 yes 00 02 04 06 +========== ===== ========= ===== ====== ====== ========= + +These chips have several additional features: + + 1. output drive strength setting (out_strength) + 2. input latch (in_latch) + 3. pull-up/pull-down (pull_in, pull_sel) + 4. push-pull/open-drain outputs (out_conf) + 5. interrupt mask and interrupt status (int_mask, int_status) + +========== ============ ======== ======= ======== ======== ========== ======== +compatible out_strength in_latch pull_en pull_sel int_mask int_status out_conf +========== ============ ======== ======= ======== ======== ========== ======== +pcal6408 40 42 43 44 45 46 4F +pcal9554b 40 42 43 44 45 46 4F +pcal6416 40 44 46 48 4A 4C 4F +pcal9535 40 44 46 48 4A 4C 4F +pcal9555a 40 44 46 48 4A 4C 4F +========== ============ ======== ======= ======== ======== ========== ======== + +Currently the driver has support for the input latch, pull-up/pull-down +and uses int_mask and int_status for interrupts. + +PCAL chips with extended interrupt and output configuration functions +--------------------------------------------------------------------- + +========== ===== ========= ===== ====== ====== ========= +compatible lines interrupt input output invert direction +========== ===== ========= ===== ====== ====== ========= +pcal6524 24 yes 00 04 08 0C +pcal6534 34 yes 00 05 0A 0F +========== ===== ========= ===== ====== ====== ========= + +These chips have the full PCAL register set, plus the following functions: + + 1. interrupt event selection: level, rising, falling, any edge + 2. clear interrupt status per line + 3. read input without clearing interrupt status + 4. individual output config (push-pull/open-drain) per output line + 5. debounce inputs + +========== ============ ======== ======= ======== ======== ========== ======== +compatible out_strength in_latch pull_en pull_sel int_mask int_status out_conf +========== ============ ======== ======= ======== ======== ========== ======== +pcal6524 40 48 4C 50 54 58 5C +pcal6534 30 3A 3F 44 49 4E 53 +========== ============ ======== ======= ======== ======== ========== ======== + +========== ======== ========= ============ ============== ======== ============== +compatible int_edge int_clear input_status indiv_out_conf debounce debounce_count +========== ======== ========= ============ ============== ======== ============== +pcal6524 60 68 6C 70 74 76 +pcal6534 54 5E 63 68 6D 6F +========== ======== ========= ============ ============== ======== ============== + +As can be seen in the table above, pcal6534 does not follow the usual +bank spacing rule. Its banks are closely packed instead. + +PCA957X chips with a completely different register layout +--------------------------------------------------------- + +These chips have the basic 4 registers, but at unusual addresses. + +Additionally, they have: + + 1. pull-up/pull-down (pull_sel) + 2. a global pull enable, defaults to disabled (config) + 3. interrupt mask, interrupt status (int_mask, int_status) + +========== ===== ========= ===== ====== ====== ======== ========= ====== ======== ========== +compatible lines interrupt input invert config pull_sel direction output int_mask int_status +========== ===== ========= ===== ====== ====== ======== ========= ====== ======== ========== +pca9574 8 yes 00 01 02 03 04 05 06 07 +pca9575 16 yes 00 02 04 06 08 0A 0C 0E +========== ===== ========= ===== ====== ====== ======== ========= ====== ======== ========== + +Currently the driver supports none of the advanced features. + +XRA1202 +------- + +Basic 4 registers, plus advanced features: + + 1. interrupt mask, defaults to interrupts disabled + 2. interrupt status + 3. interrupt event selection, level, rising, falling, any edge + (int_mask, rising_mask, falling_mask) + 4. pull-up (no pull-down) + 5. tri-state + 6. debounce + +========== ===== ========= ===== ====== ====== ========= ========= +compatible lines interrupt input output invert direction pullup_en +========== ===== ========= ===== ====== ====== ========= ========= +xra1202 8 yes 00 01 02 03 04 +========== ===== ========= ===== ====== ====== ========= ========= + +========== ======== ======== ========== =========== ============ ======== +compatible int_mask tristate int_status rising_mask falling_mask debounce +========== ======== ======== ========== =========== ============ ======== +xra1202 05 06 07 08 09 0A +========== ======== ======== ========== =========== ============ ======== + +Overview of functions +===================== + +This section lists chip functions that are supported by the driver +already, or are at least common in multiple chips. + +Input, Output, Invert, Direction +-------------------------------- + +The basic 4 GPIO functions are present in all but one chip category, i.e. +`Chips with LED blink and intensity control`_ are missing the invert +register. + +3 different layouts are used for these registers: + + 1. banks 0, 1, 2, 3 with bank offsets of 2^n + - all other chips + + 2. banks 0, 1, 2, 3 with closely packed banks + - pcal6534 + + 3. banks 0, 5, 1, 4 with bank offsets of 2^n + - pca9574 + - pca9575 + +Interrupts +---------- + +Only an interrupt mask register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The same layout is used for all of these: + + 1. bank 5 with bank offsets of 2^n + - pca9505 + - pca9506 + - pca9698 + +Interrupt mask and interrupt status registers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +These work the same way in all of the chips: mask and status have +one bit per line, 1 in the mask means interrupt enabled. + +Layouts: + + 1. base offset 0x40, bank 5 and bank 6, bank offsets of 2^n + - pcal6408 + - pcal6416 + - pcal9535 + - pcal9554b + - pcal9555a + - pcal6524 + + 2. base offset 0x30, bank 5 and 6, closely packed banks + - pcal6534 + + 3. bank 6 and 7, bank offsets of 2^n + - pca9574 + - pca9575 + + 4. bank 5 and 7, bank offsets of 2^n + - xra1202 + +Interrupt on specific edges +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +`PCAL chips with extended interrupt and output configuration functions`_ +have an int_edge register. This contains 2 bits per line, one of 4 events +can be selected for each line: + + 0: level, 1: rising edge, 2: falling edge, 3: any edge + +Layouts: + + 1. base offset 0x40, bank 7, bank offsets of 2^n + + - pcal6524 + + 2. base offset 0x30, bank 7 + offset 0x01, closely packed banks + (out_conf is 1 byte, not (lines/8) bytes, hence the 0x01 offset) + + - pcal6534 + +`XRA1202`_ chips have a different mechanism for the same thing: they have +a rising mask and a falling mask, with one bit per line. + +Layout: + + 1. bank 5, bank offsets of 2^n + +Input latch +----------- + +Only `Basic PCAL chips`_ and +`PCAL chips with extended interrupt and output configuration functions`_ +have this function. When the latch is enabled, the interrupt is not cleared +until the input port is read. When the latch is disabled, the interrupt +is cleared even if the input register is not read, if the input pin returns +to the logic value it had before generating the interrupt. Defaults to latch +disabled. + +Currently the driver enables the latch for each line with interrupt +enabled. + + 1. base offset 0x40, bank 2, bank offsets of 2^n + - pcal6408 + - pcal6416 + - pcal9535 + - pcal9554b + - pcal9555a + - pcal6524 + + 2. base offset 0x30, bank 2, closely packed banks + - pcal6534 + +Pull-up and pull-down +--------------------- + +`Basic PCAL chips`_ and +`PCAL chips with extended interrupt and output configuration functions`_ +use the same mechanism: their pull_en register enables the pull-up or pull-down +function, and their pull_sel register chooses the direction. They all use one +bit per line. + + 0: pull-down, 1: pull-up + +Layouts: + + 1. base offset 0x40, bank 3 (en) and 4 (sel), bank offsets of 2^n + - pcal6408 + - pcal6416 + - pcal9535 + - pcal9554b + - pcal9555a + - pcal6524 + + 2. base offset 0x30, bank 3 (en) and 4 (sel), closely packed banks + - pcal6534 + +`PCA957X chips with a completely different register layout`_ have a pull_sel +register with one bit per line, and a global pull_en bit in their config +register. + +Layout: + + 1. bank 2 (config), bank 3 (sel), bank offsets of 2^n + - pca9574 + - pca9575 + +`XRA1202`_ chips can only pull-up. They have a pullup_en register. + +Layout: + + 1. bank 4, bank offsets of 2^n + - xra1202 + +Push-pull and open-drain +------------------------ + +`Chips with additional int_mask and out_conf registers`_ have this function, +but only for select IO ports. Register has 1 bit per 2 lines. In pca9698, +only port0 and port1 have this function. + + 0: open-drain, 1: push-pull + +Layout: + + 1. base offset 5*bankoffset + - pca9698 + +`Basic PCAL chips`_ have 1 bit per port in one single out_conf register. +Only whole ports can be configured. + + 0: push-pull, 1: open-drain + +Layout: + + 1. base offset 0x4F + - pcal6408 + - pcal6416 + - pcal9535 + - pcal9554b + - pcal9555a + +`PCAL chips with extended interrupt and output configuration functions`_ +can set this for each line individually. They have the same per-port out_conf +register as `Basic PCAL chips`_, but they also have an indiv_out_conf register +with one bit per line, which inverts the effect of the port-wise setting. + + 0: push-pull, 1: open-drain + +Layouts: + + 1. base offset 0x40 + 7*bankoffset (out_conf), + base offset 0x60, bank 4 (indiv_out_conf) with bank offset of 2^n + + - pcal6524 + + 2. base offset 0x30 + 7*banksize (out_conf), + base offset 0x54, bank 4 (indiv_out_conf), closely packed banks + + - pcal6534 + +This function is currently not supported by the driver. + +Output drive strength +--------------------- + +Only PCAL chips have this function. 2 bits per line. + +==== ============== +bits drive strength +==== ============== + 00 0.25x + 01 0.50x + 10 0.75x + 11 1.00x +==== ============== + + 1. base offset 0x40, bank 0 and 1, bank offsets of 2^n + - pcal6408 + - pcal6416 + - pcal9535 + - pcal9554b + - pcal9555a + - pcal6524 + + 2. base offset 0x30, bank 0 and 1, closely packed banks + - pcal6534 + +Currently not supported by the driver. + +Datasheets +========== + +- MAX7310: https://datasheets.maximintegrated.com/en/ds/MAX7310.pdf +- MAX7312: https://datasheets.maximintegrated.com/en/ds/MAX7312.pdf +- MAX7313: https://datasheets.maximintegrated.com/en/ds/MAX7313.pdf +- MAX7315: https://datasheets.maximintegrated.com/en/ds/MAX7315.pdf +- MAX7318: https://datasheets.maximintegrated.com/en/ds/MAX7318.pdf +- PCA6107: https://pdf1.alldatasheet.com/datasheet-pdf/view/161780/TI/PCA6107.html +- PCA6408A: https://www.nxp.com/docs/en/data-sheet/PCA6408A.pdf +- PCA6416A: https://www.nxp.com/docs/en/data-sheet/PCA6416A.pdf +- PCA9505: https://www.nxp.com/docs/en/data-sheet/PCA9505_9506.pdf +- PCA9505: https://www.nxp.com/docs/en/data-sheet/PCA9505_9506.pdf +- PCA9534: https://www.nxp.com/docs/en/data-sheet/PCA9534.pdf +- PCA9535: https://www.nxp.com/docs/en/data-sheet/PCA9535_PCA9535C.pdf +- PCA9536: https://www.nxp.com/docs/en/data-sheet/PCA9536.pdf +- PCA9537: https://www.nxp.com/docs/en/data-sheet/PCA9537.pdf +- PCA9538: https://www.nxp.com/docs/en/data-sheet/PCA9538.pdf +- PCA9539: https://www.nxp.com/docs/en/data-sheet/PCA9539_PCA9539R.pdf +- PCA9554: https://www.nxp.com/docs/en/data-sheet/PCA9554_9554A.pdf +- PCA9555: https://www.nxp.com/docs/en/data-sheet/PCA9555.pdf +- PCA9556: https://www.nxp.com/docs/en/data-sheet/PCA9556.pdf +- PCA9557: https://www.nxp.com/docs/en/data-sheet/PCA9557.pdf +- PCA9574: https://www.nxp.com/docs/en/data-sheet/PCA9574.pdf +- PCA9575: https://www.nxp.com/docs/en/data-sheet/PCA9575.pdf +- PCA9698: https://www.nxp.com/docs/en/data-sheet/PCA9698.pdf +- PCAL6408A: https://www.nxp.com/docs/en/data-sheet/PCAL6408A.pdf +- PCAL6416A: https://www.nxp.com/docs/en/data-sheet/PCAL6416A.pdf +- PCAL6524: https://www.nxp.com/docs/en/data-sheet/PCAL6524.pdf +- PCAL6534: https://www.nxp.com/docs/en/data-sheet/PCAL6534.pdf +- PCAL9535A: https://www.nxp.com/docs/en/data-sheet/PCAL9535A.pdf +- PCAL9554B: https://www.nxp.com/docs/en/data-sheet/PCAL9554B_PCAL9554C.pdf +- PCAL9555A: https://www.nxp.com/docs/en/data-sheet/PCAL9555A.pdf +- TCA6408A: https://www.ti.com/lit/gpn/tca6408a +- TCA6416: https://www.ti.com/lit/gpn/tca6416 +- TCA6424: https://www.ti.com/lit/gpn/tca6424 +- TCA9539: https://www.ti.com/lit/gpn/tca9539 +- TCA9554: https://www.ti.com/lit/gpn/tca9554 +- XRA1202: https://assets.maxlinear.com/web/documents/xra1202_1202p_101_042213.pdf diff --git a/Documentation/driver-api/hw-recoverable-errors.rst b/Documentation/driver-api/hw-recoverable-errors.rst new file mode 100644 index 0000000000000..fc526c3454bd7 --- /dev/null +++ b/Documentation/driver-api/hw-recoverable-errors.rst @@ -0,0 +1,60 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================================================= +Recoverable Hardware Error Tracking in vmcoreinfo +================================================= + +Overview +-------- + +This feature provides a generic infrastructure within the Linux kernel to track +and log recoverable hardware errors. These are hardware recoverable errors +visible that might not cause immediate panics but may influence health, mainly +because new code path will be executed in the kernel. + +By recording counts and timestamps of recoverable errors into the vmcoreinfo +crash dump notes, this infrastructure aids post-mortem crash analysis tools in +correlating hardware events with kernel failures. This enables faster triage +and better understanding of root causes, especially in large-scale cloud +environments where hardware issues are common. + +Benefits +-------- + +- Facilitates correlation of hardware recoverable errors with kernel panics or + unusual code paths that lead to system crashes. +- Provides operators and cloud providers quick insights, improving reliability + and reducing troubleshooting time. +- Complements existing full hardware diagnostics without replacing them. + +Data Exposure and Consumption +----------------------------- + +- The tracked error data consists of per-error-type counts and timestamps of + last occurrence. +- This data is stored in the `hwerror_data` array, categorized by error source + types like CPU, memory, PCI, CXL, and others. +- It is exposed via vmcoreinfo crash dump notes and can be read using tools + like `crash`, `drgn`, or other kernel crash analysis utilities. +- There is no other way to read these data other than from crash dumps. +- These errors are divided by area, which includes CPU, Memory, PCI, CXL and + others. + +Typical usage example (in drgn REPL): + +.. code-block:: python + + >>> prog['hwerror_data'] + (struct hwerror_info[HWERR_RECOV_MAX]){ + { + .count = (int)844, + .timestamp = (time64_t)1752852018, + }, + ... + } + +Enabling +-------- + +- This feature is enabled when CONFIG_VMCORE_INFO is set. + diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index 3e2a270bd8282..1833e6a0687e4 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -93,9 +93,11 @@ Subsystem-specific APIs frame-buffer aperture generic-counter + generic_pt gpio/index hsi hte/index + hw-recoverable-errors i2c iio/index infiniband diff --git a/Documentation/driver-api/media/v4l2-core.rst b/Documentation/driver-api/media/v4l2-core.rst index ad987c34ad2a8..a5f5102c64cca 100644 --- a/Documentation/driver-api/media/v4l2-core.rst +++ b/Documentation/driver-api/media/v4l2-core.rst @@ -27,3 +27,4 @@ Video4Linux devices v4l2-common v4l2-tveeprom v4l2-jpeg + v4l2-isp diff --git a/Documentation/driver-api/media/v4l2-isp.rst b/Documentation/driver-api/media/v4l2-isp.rst new file mode 100644 index 0000000000000..618ae614ff794 --- /dev/null +++ b/Documentation/driver-api/media/v4l2-isp.rst @@ -0,0 +1,49 @@ +.. SPDX-License-Identifier: GPL-2.0 + +V4L2 generic ISP parameters and statistics support +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Design rationale +================ + +ISP configuration parameters and statistics are processed and collected by +drivers and exchanged with userspace through data types that usually +reflect the ISP peripheral registers layout. + +Each ISP driver defines its own metadata output format for parameters and +a metadata capture format for statistics. The buffer layout is realized by a +set of C structures that reflects the registers layout. The number and types +of C structures is fixed by the format definition and becomes part of the Linux +kernel uAPI/uABI interface. + +Because of the hard requirement of backward compatibility when extending the +user API/ABI interface, modifying an ISP driver capture or output metadata +format after it has been accepted by mainline is very hard if not impossible. + +It generally happens, in fact, that after the first accepted revision of an ISP +driver the buffers layout need to be modified, either to support new hardware +blocks, to fix bugs or to support different revisions of the hardware. + +Each of these situations would require defining a new metadata format, making it +really hard to maintain and extend drivers and requiring userspace to use +the correct format depending on the kernel revision in use. + +V4L2 ISP configuration parameters +================================= + +For these reasons, Video4Linux2 defines generic types for ISP configuration +parameters and statistics. Drivers are still expected to define their own +formats for their metadata output and capture nodes, but the buffers layout can +be defined using the extensible and versioned types defined by +include/uapi/linux/media/v4l2-isp.h. + +Drivers are expected to provide the definitions of their supported ISP blocks +and the expected maximum size of a buffer. + +For driver developers a set of helper functions to assist them with validation +of the buffer received from userspace is available in +drivers/media/v4l2-core/v4l2-isp.c + +V4L2 ISP support driver documentation +===================================== +.. kernel-doc:: include/media/v4l2-isp.h diff --git a/Documentation/driver-api/nvdimm/btt.rst b/Documentation/driver-api/nvdimm/btt.rst index 107395c042ae0..2d8269f834bd6 100644 --- a/Documentation/driver-api/nvdimm/btt.rst +++ b/Documentation/driver-api/nvdimm/btt.rst @@ -83,7 +83,7 @@ flags, and the remaining form the internal block number. ======== ============================================================= Bit Description ======== ============================================================= -31 - 30 Error and Zero flags - Used in the following way:: +31 - 30 Error and Zero flags - Used in the following way: == == ==================================================== 31 30 Description diff --git a/Documentation/driver-api/pci/index.rst b/Documentation/driver-api/pci/index.rst index a38e475cdbe3b..9e1b801d0f747 100644 --- a/Documentation/driver-api/pci/index.rst +++ b/Documentation/driver-api/pci/index.rst @@ -10,6 +10,7 @@ The Linux PCI driver implementer's API guide pci p2pdma + tsm .. only:: subproject and html diff --git a/Documentation/driver-api/pci/p2pdma.rst b/Documentation/driver-api/pci/p2pdma.rst index d0b241628cf13..280673b50350b 100644 --- a/Documentation/driver-api/pci/p2pdma.rst +++ b/Documentation/driver-api/pci/p2pdma.rst @@ -9,22 +9,48 @@ between two devices on the bus. This type of transaction is henceforth called Peer-to-Peer (or P2P). However, there are a number of issues that make P2P transactions tricky to do in a perfectly safe way. -One of the biggest issues is that PCI doesn't require forwarding -transactions between hierarchy domains, and in PCIe, each Root Port -defines a separate hierarchy domain. To make things worse, there is no -simple way to determine if a given Root Complex supports this or not. -(See PCIe r4.0, sec 1.3.1). Therefore, as of this writing, the kernel -only supports doing P2P when the endpoints involved are all behind the -same PCI bridge, as such devices are all in the same PCI hierarchy -domain, and the spec guarantees that all transactions within the -hierarchy will be routable, but it does not require routing -between hierarchies. - -The second issue is that to make use of existing interfaces in Linux, -memory that is used for P2P transactions needs to be backed by struct -pages. However, PCI BARs are not typically cache coherent so there are -a few corner case gotchas with these pages so developers need to -be careful about what they do with them. +For PCIe the routing of Transaction Layer Packets (TLPs) is well-defined up +until they reach a host bridge or root port. If the path includes PCIe switches +then based on the ACS settings the transaction can route entirely within +the PCIe hierarchy and never reach the root port. The kernel will evaluate +the PCIe topology and always permit P2P in these well-defined cases. + +However, if the P2P transaction reaches the host bridge then it might have to +hairpin back out the same root port, be routed inside the CPU SOC to another +PCIe root port, or routed internally to the SOC. + +The PCIe specification doesn't define the forwarding of transactions between +hierarchy domains and kernel defaults to blocking such routing. There is an +allow list to allow detecting known-good HW, in which case P2P between any +two PCIe devices will be permitted. + +Since P2P inherently is doing transactions between two devices it requires two +drivers to be co-operating inside the kernel. The providing driver has to convey +its MMIO to the consuming driver. To meet the driver model lifecycle rules the +MMIO must have all DMA mapping removed, all CPU accesses prevented, all page +table mappings undone before the providing driver completes remove(). + +This requires the providing and consuming driver to actively work together to +guarantee that the consuming driver has stopped using the MMIO during a removal +cycle. This is done by either a synchronous invalidation shutdown or waiting +for all usage refcounts to reach zero. + +At the lowest level the P2P subsystem offers a naked struct p2p_provider that +delegates lifecycle management to the providing driver. It is expected that +drivers using this option will wrap their MMIO memory in DMABUF and use DMABUF +to provide an invalidation shutdown. These MMIO addresess have no struct page, and +if used with mmap() must create special PTEs. As such there are very few +kernel uAPIs that can accept pointers to them; in particular they cannot be used +with read()/write(), including O_DIRECT. + +Building on this, the subsystem offers a layer to wrap the MMIO in a ZONE_DEVICE +pgmap of MEMORY_DEVICE_PCI_P2PDMA to create struct pages. The lifecycle of +pgmap ensures that when the pgmap is destroyed all other drivers have stopped +using the MMIO. This option works with O_DIRECT flows, in some cases, if the +underlying subsystem supports handling MEMORY_DEVICE_PCI_P2PDMA through +FOLL_PCI_P2PDMA. The use of FOLL_LONGTERM is prevented. As this relies on pgmap +it also relies on architecture support along with alignment and minimum size +limitations. Driver Writer's Guide @@ -114,14 +140,39 @@ allocating scatter-gather lists with P2P memory. Struct Page Caveats ------------------- -Driver writers should be very careful about not passing these special -struct pages to code that isn't prepared for it. At this time, the kernel -interfaces do not have any checks for ensuring this. This obviously -precludes passing these pages to userspace. +While the MEMORY_DEVICE_PCI_P2PDMA pages can be installed in VMAs, +pin_user_pages() and related will not return them unless FOLL_PCI_P2PDMA is set. -P2P memory is also technically IO memory but should never have any side -effects behind it. Thus, the order of loads and stores should not be important -and ioreadX(), iowriteX() and friends should not be necessary. +The MEMORY_DEVICE_PCI_P2PDMA pages require care to support in the kernel. The +KVA is still MMIO and must still be accessed through the normal +readX()/writeX()/etc helpers. Direct CPU access (e.g. memcpy) is forbidden, just +like any other MMIO mapping. While this will actually work on some +architectures, others will experience corruption or just crash in the kernel. +Supporting FOLL_PCI_P2PDMA in a subsystem requires scrubbing it to ensure no CPU +access happens. + + +Usage With DMABUF +================= + +DMABUF provides an alternative to the above struct page-based +client/provider/orchestrator system and should be used when struct page +doesn't exist. In this mode the exporting driver will wrap +some of its MMIO in a DMABUF and give the DMABUF FD to userspace. + +Userspace can then pass the FD to an importing driver which will ask the +exporting driver to map it to the importer. + +In this case the initiator and target pci_devices are known and the P2P subsystem +is used to determine the mapping type. The phys_addr_t-based DMA API is used to +establish the dma_addr_t. + +Lifecycle is controlled by DMABUF move_notify(). When the exporting driver wants +to remove() it must deliver an invalidation shutdown to all DMABUF importing +drivers through move_notify() and synchronously DMA unmap all the MMIO. + +No importing driver can continue to have a DMA map to the MMIO after the +exporting driver has destroyed its p2p_provider. P2P DMA Support Library diff --git a/Documentation/driver-api/pci/pci.rst b/Documentation/driver-api/pci/pci.rst index 59d86e8271986..99a1bbaaec5d0 100644 --- a/Documentation/driver-api/pci/pci.rst +++ b/Documentation/driver-api/pci/pci.rst @@ -37,6 +37,9 @@ PCI Support Library .. kernel-doc:: drivers/pci/slot.c :export: +.. kernel-doc:: drivers/pci/rebar.c + :export: + .. kernel-doc:: drivers/pci/rom.c :export: diff --git a/Documentation/driver-api/pci/tsm.rst b/Documentation/driver-api/pci/tsm.rst new file mode 100644 index 0000000000000..232b92bec93f0 --- /dev/null +++ b/Documentation/driver-api/pci/tsm.rst @@ -0,0 +1,21 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: + +======================================================== +PCI Trusted Execution Environment Security Manager (TSM) +======================================================== + +Subsystem Interfaces +==================== + +.. kernel-doc:: include/linux/pci-ide.h + :internal: + +.. kernel-doc:: drivers/pci/ide.c + :export: + +.. kernel-doc:: include/linux/pci-tsm.h + :internal: + +.. kernel-doc:: drivers/pci/tsm.c + :export: diff --git a/Documentation/driver-api/reset.rst b/Documentation/driver-api/reset.rst index 84e03d7039ccb..f773100daaa41 100644 --- a/Documentation/driver-api/reset.rst +++ b/Documentation/driver-api/reset.rst @@ -218,4 +218,3 @@ devm_reset_controller_register(). reset_controller_register reset_controller_unregister devm_reset_controller_register - reset_controller_add_lookup diff --git a/Documentation/driver-api/wmi.rst b/Documentation/driver-api/wmi.rst index 4e8dbdb1fc678..db835b43c9379 100644 --- a/Documentation/driver-api/wmi.rst +++ b/Documentation/driver-api/wmi.rst @@ -16,5 +16,5 @@ which will be bound to compatible WMI devices by the driver core. .. kernel-doc:: include/linux/wmi.h :internal: -.. kernel-doc:: drivers/platform/x86/wmi.c +.. kernel-doc:: drivers/platform/wmi/core.c :export: diff --git a/Documentation/features/core/generic-idle-thread/arch-support.txt b/Documentation/features/core/generic-idle-thread/arch-support.txt index 0735cb5367b4b..425442e31fa25 100644 --- a/Documentation/features/core/generic-idle-thread/arch-support.txt +++ b/Documentation/features/core/generic-idle-thread/arch-support.txt @@ -24,7 +24,7 @@ | s390: | ok | | sh: | ok | | sparc: | ok | - | um: | TODO | + | um: | ok | | x86: | ok | | xtensa: | ok | ----------------------- diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index a8d02fe5be839..cb90d1ae82d01 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -188,34 +188,36 @@ fault_type=%d Support configuring fault injection type, should be enabled with fault_injection option, fault type value is shown below, it supports single or combined type. - =========================== ========== - Type_Name Type_Value - =========================== ========== - FAULT_KMALLOC 0x00000001 - FAULT_KVMALLOC 0x00000002 - FAULT_PAGE_ALLOC 0x00000004 - FAULT_PAGE_GET 0x00000008 - FAULT_ALLOC_BIO 0x00000010 (obsolete) - FAULT_ALLOC_NID 0x00000020 - FAULT_ORPHAN 0x00000040 - FAULT_BLOCK 0x00000080 - FAULT_DIR_DEPTH 0x00000100 - FAULT_EVICT_INODE 0x00000200 - FAULT_TRUNCATE 0x00000400 - FAULT_READ_IO 0x00000800 - FAULT_CHECKPOINT 0x00001000 - FAULT_DISCARD 0x00002000 - FAULT_WRITE_IO 0x00004000 - FAULT_SLAB_ALLOC 0x00008000 - FAULT_DQUOT_INIT 0x00010000 - FAULT_LOCK_OP 0x00020000 - FAULT_BLKADDR_VALIDITY 0x00040000 - FAULT_BLKADDR_CONSISTENCE 0x00080000 - FAULT_NO_SEGMENT 0x00100000 - FAULT_INCONSISTENT_FOOTER 0x00200000 - FAULT_TIMEOUT 0x00400000 (1000ms) - FAULT_VMALLOC 0x00800000 - =========================== ========== + .. code-block:: none + + =========================== ========== + Type_Name Type_Value + =========================== ========== + FAULT_KMALLOC 0x00000001 + FAULT_KVMALLOC 0x00000002 + FAULT_PAGE_ALLOC 0x00000004 + FAULT_PAGE_GET 0x00000008 + FAULT_ALLOC_BIO 0x00000010 (obsolete) + FAULT_ALLOC_NID 0x00000020 + FAULT_ORPHAN 0x00000040 + FAULT_BLOCK 0x00000080 + FAULT_DIR_DEPTH 0x00000100 + FAULT_EVICT_INODE 0x00000200 + FAULT_TRUNCATE 0x00000400 + FAULT_READ_IO 0x00000800 + FAULT_CHECKPOINT 0x00001000 + FAULT_DISCARD 0x00002000 + FAULT_WRITE_IO 0x00004000 + FAULT_SLAB_ALLOC 0x00008000 + FAULT_DQUOT_INIT 0x00010000 + FAULT_LOCK_OP 0x00020000 + FAULT_BLKADDR_VALIDITY 0x00040000 + FAULT_BLKADDR_CONSISTENCE 0x00080000 + FAULT_NO_SEGMENT 0x00100000 + FAULT_INCONSISTENT_FOOTER 0x00200000 + FAULT_TIMEOUT 0x00400000 (1000ms) + FAULT_VMALLOC 0x00800000 + =========================== ========== mode=%s Control block allocation mode which supports "adaptive" and "lfs". In "lfs" mode, there should be no random writes towards main area. @@ -296,14 +298,15 @@ nocheckpoint_merge Disable checkpoint merge feature. compress_algorithm=%s Control compress algorithm, currently f2fs supports "lzo", "lz4", "zstd" and "lzo-rle" algorithm. compress_algorithm=%s:%d Control compress algorithm and its compress level, now, only - "lz4" and "zstd" support compress level config. - - ========= =========== - algorithm level range - ========= =========== - lz4 3 - 16 - zstd 1 - 22 - ========= =========== + "lz4" and "zstd" support compress level config:: + + ========= =========== + algorithm level range + ========= =========== + lz4 3 - 16 + zstd 1 - 22 + ========= =========== + compress_log_size=%u Support configuring compress cluster size. The size will be 4KB * (1 << %u). The default and minimum sizes are 16KB. compress_extension=%s Support adding specified extension, so that f2fs can enable @@ -368,38 +371,42 @@ errors=%s Specify f2fs behavior on critical errors. This supports modes: the partition in read-only mode. By default it uses "continue" mode. - ====================== =============== =============== ======== - mode continue remount-ro panic - ====================== =============== =============== ======== - access ops normal normal N/A - syscall errors -EIO -EROFS N/A - mount option rw ro N/A - pending dir write keep keep N/A - pending non-dir write drop keep N/A - pending node write drop keep N/A - pending meta write keep keep N/A - ====================== =============== =============== ======== + .. code-block:: none + + ====================== =============== =============== ======== + mode continue remount-ro panic + ====================== =============== =============== ======== + access ops normal normal N/A + syscall errors -EIO -EROFS N/A + mount option rw ro N/A + pending dir write keep keep N/A + pending non-dir write drop keep N/A + pending node write drop keep N/A + pending meta write keep keep N/A + ====================== =============== =============== ======== nat_bits Enable nat_bits feature to enhance full/empty nat blocks access, by default it's disabled. lookup_mode=%s Control the directory lookup behavior for casefolded directories. This option has no effect on directories that do not have the casefold feature enabled. - ================== ======================================== - Value Description - ================== ======================================== - perf (Default) Enforces a hash-only lookup. - The linear search fallback is always - disabled, ignoring the on-disk flag. - compat Enables the linear search fallback for - compatibility with directory entries - created by older kernel that used a - different case-folding algorithm. - This mode ignores the on-disk flag. - auto F2FS determines the mode based on the - on-disk `SB_ENC_NO_COMPAT_FALLBACK_FL` - flag. - ================== ======================================== + .. code-block:: none + + ================== ======================================== + Value Description + ================== ======================================== + perf (Default) Enforces a hash-only lookup. + The linear search fallback is always + disabled, ignoring the on-disk flag. + compat Enables the linear search fallback for + compatibility with directory entries + created by older kernel that used a + different case-folding algorithm. + This mode ignores the on-disk flag. + auto F2FS determines the mode based on the + on-disk `SB_ENC_NO_COMPAT_FALLBACK_FL` + flag. + ================== ======================================== ======================== ============================================================ Debugfs Entries diff --git a/Documentation/filesystems/nfs/index.rst b/Documentation/filesystems/nfs/index.rst index 95c2c009874ce..a29a212b5b4df 100644 --- a/Documentation/filesystems/nfs/index.rst +++ b/Documentation/filesystems/nfs/index.rst @@ -13,5 +13,6 @@ NFS rpc-cache rpc-server-gss nfs41-server + nfsd-io-modes knfsd-stats reexport diff --git a/Documentation/filesystems/nfs/nfsd-io-modes.rst b/Documentation/filesystems/nfs/nfsd-io-modes.rst new file mode 100644 index 0000000000000..0fd6e82478fe6 --- /dev/null +++ b/Documentation/filesystems/nfs/nfsd-io-modes.rst @@ -0,0 +1,153 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============= +NFSD IO MODES +============= + +Overview +======== + +NFSD has historically always used buffered IO when servicing READ and +WRITE operations. BUFFERED is NFSD's default IO mode, but it is possible +to override that default to use either DONTCACHE or DIRECT IO modes. + +Experimental NFSD debugfs interfaces are available to allow the NFSD IO +mode used for READ and WRITE to be configured independently. See both: + +- /sys/kernel/debug/nfsd/io_cache_read +- /sys/kernel/debug/nfsd/io_cache_write + +The default value for both io_cache_read and io_cache_write reflects +NFSD's default IO mode (which is NFSD_IO_BUFFERED=0). + +Based on the configured settings, NFSD's IO will either be: + +- cached using page cache (NFSD_IO_BUFFERED=0) +- cached but removed from page cache on completion (NFSD_IO_DONTCACHE=1) +- not cached stable_how=NFS_UNSTABLE (NFSD_IO_DIRECT=2) + +To set an NFSD IO mode, write a supported value (0 - 2) to the +corresponding IO operation's debugfs interface, e.g.:: + + echo 2 > /sys/kernel/debug/nfsd/io_cache_read + echo 2 > /sys/kernel/debug/nfsd/io_cache_write + +To check which IO mode NFSD is using for READ or WRITE, simply read the +corresponding IO operation's debugfs interface, e.g.:: + + cat /sys/kernel/debug/nfsd/io_cache_read + cat /sys/kernel/debug/nfsd/io_cache_write + +If you experiment with NFSD's IO modes on a recent kernel and have +interesting results, please report them to linux-nfs@vger.kernel.org + +NFSD DONTCACHE +============== + +DONTCACHE offers a hybrid approach to servicing IO that aims to offer +the benefits of using DIRECT IO without any of the strict alignment +requirements that DIRECT IO imposes. To achieve this buffered IO is used +but the IO is flagged to "drop behind" (meaning associated pages are +dropped from the page cache) when IO completes. + +DONTCACHE aims to avoid what has proven to be a fairly significant +limition of Linux's memory management subsystem if/when large amounts of +data is infrequently accessed (e.g. read once _or_ written once but not +read until much later). Such use-cases are particularly problematic +because the page cache will eventually become a bottleneck to servicing +new IO requests. + +For more context on DONTCACHE, please see these Linux commit headers: + +- Overview: 9ad6344568cc3 ("mm/filemap: change filemap_create_folio() + to take a struct kiocb") +- for READ: 8026e49bff9b1 ("mm/filemap: add read support for + RWF_DONTCACHE") +- for WRITE: 974c5e6139db3 ("xfs: flag as supporting FOP_DONTCACHE") + +NFSD_IO_DONTCACHE will fall back to NFSD_IO_BUFFERED if the underlying +filesystem doesn't indicate support by setting FOP_DONTCACHE. + +NFSD DIRECT +=========== + +DIRECT IO doesn't make use of the page cache, as such it is able to +avoid the Linux memory management's page reclaim scalability problems +without resorting to the hybrid use of page cache that DONTCACHE does. + +Some workloads benefit from NFSD avoiding the page cache, particularly +those with a working set that is significantly larger than available +system memory. The pathological worst-case workload that NFSD DIRECT has +proven to help most is: NFS client issuing large sequential IO to a file +that is 2-3 times larger than the NFS server's available system memory. +The reason for such improvement is NFSD DIRECT eliminates a lot of work +that the memory management subsystem would otherwise be required to +perform (e.g. page allocation, dirty writeback, page reclaim). When +using NFSD DIRECT, kswapd and kcompactd are no longer commanding CPU +time trying to find adequate free pages so that forward IO progress can +be made. + +The performance win associated with using NFSD DIRECT was previously +discussed on linux-nfs, see: +https://lore.kernel.org/linux-nfs/aEslwqa9iMeZjjlV@kernel.org/ + +But in summary: + +- NFSD DIRECT can significantly reduce memory requirements +- NFSD DIRECT can reduce CPU load by avoiding costly page reclaim work +- NFSD DIRECT can offer more deterministic IO performance + +As always, your mileage may vary and so it is important to carefully +consider if/when it is beneficial to make use of NFSD DIRECT. When +assessing comparative performance of your workload please be sure to log +relevant performance metrics during testing (e.g. memory usage, cpu +usage, IO performance). Using perf to collect perf data that may be used +to generate a "flamegraph" for work Linux must perform on behalf of your +test is a really meaningful way to compare the relative health of the +system and how switching NFSD's IO mode changes what is observed. + +If NFSD_IO_DIRECT is specified by writing 2 (or 3 and 4 for WRITE) to +NFSD's debugfs interfaces, ideally the IO will be aligned relative to +the underlying block device's logical_block_size. Also the memory buffer +used to store the READ or WRITE payload must be aligned relative to the +underlying block device's dma_alignment. + +But NFSD DIRECT does handle misaligned IO in terms of O_DIRECT as best +it can: + +Misaligned READ: + If NFSD_IO_DIRECT is used, expand any misaligned READ to the next + DIO-aligned block (on either end of the READ). The expanded READ is + verified to have proper offset/len (logical_block_size) and + dma_alignment checking. + +Misaligned WRITE: + If NFSD_IO_DIRECT is used, split any misaligned WRITE into a start, + middle and end as needed. The large middle segment is DIO-aligned + and the start and/or end are misaligned. Buffered IO is used for the + misaligned segments and O_DIRECT is used for the middle DIO-aligned + segment. DONTCACHE buffered IO is _not_ used for the misaligned + segments because using normal buffered IO offers significant RMW + performance benefit when handling streaming misaligned WRITEs. + +Tracing: + The nfsd_read_direct trace event shows how NFSD expands any + misaligned READ to the next DIO-aligned block (on either end of the + original READ, as needed). + + This combination of trace events is useful for READs:: + + echo 1 > /sys/kernel/tracing/events/nfsd/nfsd_read_vector/enable + echo 1 > /sys/kernel/tracing/events/nfsd/nfsd_read_direct/enable + echo 1 > /sys/kernel/tracing/events/nfsd/nfsd_read_io_done/enable + echo 1 > /sys/kernel/tracing/events/xfs/xfs_file_direct_read/enable + + The nfsd_write_direct trace event shows how NFSD splits a given + misaligned WRITE into a DIO-aligned middle segment. + + This combination of trace events is useful for WRITEs:: + + echo 1 > /sys/kernel/tracing/events/nfsd/nfsd_write_opened/enable + echo 1 > /sys/kernel/tracing/events/nfsd/nfsd_write_direct/enable + echo 1 > /sys/kernel/tracing/events/nfsd/nfsd_write_io_done/enable + echo 1 > /sys/kernel/tracing/events/xfs/xfs_file_direct_write/enable diff --git a/Documentation/filesystems/nfs/nfsd-maintainer-entry-profile.rst b/Documentation/filesystems/nfs/nfsd-maintainer-entry-profile.rst new file mode 100644 index 0000000000000..4d6b57dbab2a2 --- /dev/null +++ b/Documentation/filesystems/nfs/nfsd-maintainer-entry-profile.rst @@ -0,0 +1,547 @@ +NFSD Maintainer Entry Profile +============================= + +A Maintainer Entry Profile supplements the top-level process +documents (found in Documentation/process/) with customs that are +specific to a subsystem and its maintainers. A contributor may use +this document to set their expectations and avoid common mistakes. +A maintainer may use these profiles to look across subsystems for +opportunities to converge on best common practices. + +Overview +-------- +The Network File System (NFS) is a standardized family of network +protocols that enable access to files across a set of network- +connected peer hosts. Applications on NFS clients access files that +reside on file systems that are shared by NFS servers. A single +network peer can act as both an NFS client and an NFS server. + +NFSD refers to the NFS server implementation included in the Linux +kernel. An in-kernel NFS server has fast access to files stored +in file systems local to that server. NFSD can share files stored +on most of the file system types native to Linux, including xfs, +ext4, btrfs, and tmpfs. + +Mailing list +------------ +The linux-nfs@vger.kernel.org mailing list is a public list. Its +purpose is to enable collaboration among developers working on the +Linux NFS stack, both client and server. It is not a place for +conversations that are not related directly to the Linux NFS stack. + +The linux-nfs mailing list is archived on `lore.kernel.org `_. + +The Linux NFS community does not have any chat room. + +Reporting bugs +-------------- +If you experience an NFSD-related bug on a distribution-built +kernel, please start by working with your Linux distributor. + +Bug reports against upstream Linux code bases are welcome on the +linux-nfs@vger.kernel.org mailing list, where some active triage +can be done. NFSD bugs may also be reported in the Linux kernel +community's bugzilla at: + + https://bugzilla.kernel.org + +Please file NFSD-related bugs under the "Filesystems/NFSD" +component. In general, including as much detail as possible is a +good start, including pertinent system log messages from both +the client and server. + +User space software related to NFSD, such as mountd or the exportfs +command, is contained in the nfs-utils package. Report problems +with those components to linux-nfs@vger.kernel.org. You might be +directed to move the report to a specific bug tracker. + +Contributor's Guide +------------------- + +Standards compliance +~~~~~~~~~~~~~~~~~~~~ +The priority is for NFSD to interoperate fully with the Linux NFS +client. We also test against other popular NFS client implementa- +tions regularly at NFS bake-a-thon events (also known as plug- +fests). Non-Linux NFS clients are not part of upstream NFSD CI/CD. + +The NFSD community strives to provide an NFS server implementation +that interoperates with all standards-compliant NFS client +implementations. This is done by staying as close as is sensible to +the normative mandates in the IETF's published NFS, RPC, and GSS-API +standards. + +It is always useful to reference an RFC and section number in a code +comment where behavior deviates from the standard (and even when the +behavior is compliant but the implementation is obfuscatory). + +On the rare occasion when a deviation from standard-mandated +behavior is needed, brief documentation of the use case or +deficiencies in the standard is a required part of in-code +documentation. + +Care must always be taken to avoid leaking local error codes (ie, +errnos) to clients of NFSD. A proper NFS status code is always +required in NFS protocol replies. + +NFSD administrative interfaces +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NFSD administrative interfaces include: + +- an NFSD or SUNRPC module parameter + +- export options in /etc/exports + +- files under /proc/fs/nfsd/ or /proc/sys/sunrpc/ + +- the NFSD netlink protocol + +Frequently, a request is made to introduce or modify one of NFSD's +traditional administrative interfaces. Certainly it is technically +easy to introduce a new administrative setting. However, there are +good reasons why the NFSD maintainers prefer to leave that as a last +resort: + +- As with any API, administrative interfaces are difficult to get + right. + +- Once they are documented and have a legacy of use, administrative + interfaces become difficult to modify or remove. + +- Every new administrative setting multiplies the NFSD test matrix. + +- The cost of one administrative interface is incremental, but costs + add up across all of the existing interfaces. + +It is often better for everyone if effort is made up front to +understanding the underlying requirement of the new setting, and +then trying to make it tune itself (or to become otherwise +unnecessary). + +If a new setting is indeed necessary, first consider adding it to +the NFSD netlink protocol. Or if it doesn't need to be a reliable +long term user space feature, it can be added to NFSD's menagerie of +experimental settings which reside under /sys/kernel/debug/nfsd/ . + +Field observability +~~~~~~~~~~~~~~~~~~~ +NFSD employs several different mechanisms for observing operation, +including counters, printks, WARNings, and static trace points. Each +have their strengths and weaknesses. Contributors should select the +most appropriate tool for their task. + +- BUG must be avoided if at all possible, as it will frequently + result in a full system crash. + +- WARN is appropriate only when a full stack trace is useful. + +- printk can show detailed information. These must not be used + in code paths where they can be triggered repeatedly by remote + users. + +- dprintk can show detailed information, but can be enabled only + in pre-set groups. The overhead of emitting output makes dprintk + inappropriate for frequent operations like I/O. + +- Counters are always on, but provide little information about + individual events other than how frequently they occur. + +- static trace points can be enabled individually or in groups + (via a glob). These are generally low overhead, and thus are + favored for use in hot paths. + +- dynamic tracing, such as kprobes or eBPF, are quite flexible but + cannot be used in certain environments (eg, full kernel lock- + down). + +Testing +~~~~~~~ +The kdevops project + + https://github.com/linux-kdevops/kdevops + +contains several NFS-specific workflows, as well as the community +standard fstests suite. These workflows are based on open source +testing tools such as ltp and fio. Contributors are encouraged to +use these tools without kdevops, or contributors should install and +use kdevops themselves to verify their patches before submission. + +Coding style +~~~~~~~~~~~~ +Follow the coding style preferences described in + + Documentation/process/coding-style.rst + +with the following exceptions: + +- Add new local variables to a function in reverse Christmas tree + order + +- Use the kdoc comment style for + + non-static functions + + static inline functions + + static functions that are callbacks/virtual functions + +- All new function names start with ``nfsd_`` for non-NFS-version- + specific functions. + +- New function names that are specific to NFSv2 or NFSv3, or are + used by all minor versions of NFSv4, use ``nfsdN_`` where N is + the version. + +- New function names specific to an NFSv4 minor version can be + named with ``nfsd4M_`` where M is the minor version. + +Patch preparation +~~~~~~~~~~~~~~~~~ +Read and follow all guidelines in + + Documentation/process/submitting-patches.rst + +Use tagging to identify all patch authors. However, reviewers and +testers should be added by replying to the email patch submission. +Email is extensively used in order to publicly archive review and +testing attributions. These tags are automatically inserted into +your patches when they are applied. + +The code in the body of the diff already shows /what/ is being +changed. Thus it is not necessary to repeat that in the patch +description. Instead, the description should contain one or more +of: + +- A brief problem statement ("what is this patch trying to fix?") + with a root-cause analysis. + +- End-user visible symptoms or items that a support engineer might + use to search for the patch, like stack traces. + +- A brief explanation of why the patch is the best way to address + the problem. + +- Any context that reviewers might need to understand the changes + made by the patch. + +- Any relevant benchmarking results, and/or functional test results. + +As detailed in Documentation/process/submitting-patches.rst, +identify the point in history that the issue being addressed was +introduced by using a Fixes: tag. + +Mention in the patch description if that point in history cannot be +determined -- that is, no Fixes: tag can be provided. In this case, +please make it clear to maintainers whether an LTS backport is +needed even though there is no Fixes: tag. + +The NFSD maintainers prefer to add stable tagging themselves, after +public discussion in response to the patch submission. Contributors +may suggest stable tagging, but be aware that many version +management tools add such stable Cc's when you post your patches. +Don't add "Cc: stable" unless you are absolutely sure the patch +needs to go to stable during the initial submission process. + +Patch submission +~~~~~~~~~~~~~~~~ +Patches to NFSD are submitted via the kernel's email-based review +process that is common to most other kernel subsystems. + +Just before each submission, rebase your patch or series on the +nfsd-testing branch at + + https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git + +The NFSD subsystem is maintained separately from the Linux in-kernel +NFS client. The NFSD maintainers do not normally take submissions +for client changes, nor can they respond authoritatively to bug +reports or feature requests for NFS client code. + +This means that contributors might be asked to resubmit patches if +they were emailed to the incorrect set of maintainers and reviewers. +This is not a rejection, but simply a correction of the submission +process. + +When in doubt, consult the NFSD entry in the MAINTAINERS file to +see which files and directories fall under the NFSD subsystem. + +The proper set of email addresses for NFSD patches are: + +To: the NFSD maintainers and reviewers listed in MAINTAINERS +Cc: linux-nfs@vger.kernel.org and optionally linux-kernel@ + +If there are other subsystems involved in the patches (for example +MM or RDMA) their primary mailing list address can be included in +the Cc: field. Other contributors and interested parties may be +included there as well. + +In general we prefer that contributors use common patch email tools +such as "git send-email" or "stg email format/send", which tend to +get the details right without a lot of fuss. + +A series consisting of a single patch is not required to have a +cover letter. However, a cover letter can be included if there is +substantial context that is not appropriate to include in the +patch description. + +Please note that, with an e-mail based submission process, series +cover letters are not part of the work that is committed to the +kernel source code base or its commit history. Therefore always try +to keep pertinent information in the patch descriptions. + +Design documentation is welcome, but as cover letters are not +preserved, a perhaps better option is to include a patch that adds +such documentation under Documentation/filesystems/nfs/. + +Reviewers will ask about test coverage and what use cases the +patches are expected to address. Please be prepared to answer these +questions. + +Review comments from maintainers might be politely stated, but in +general, these are not optional to address when they are actionable. +If necessary, the maintainers retain the right to not apply patches +when contributors refuse to address reasonable requests. + +Post changes to kernel source code and user space source code as +separate series. You can connect the two series with comments in +your cover letters. + +Generally the NFSD maintainers ask for a reposts even for simple +modifications in order to publicly archive the request and the +resulting repost before it is pulled into the NFSD trees. This +also enables us to rebuild a patch series quickly without missing +changes that might have been discussed via email. + +Avoid frequently reposting large series with only small changes. As +a rule of thumb, posting substantial changes more than once a week +will result in reviewer overload. + +Remember, there are only a handful of subsystem maintainers and +reviewers, but potentially many sources of contributions. The +maintainers and reviewers, therefore, are always the less scalable +resource. Be kind to your friendly neighborhood maintainer. + +Patch Acceptance +~~~~~~~~~~~~~~~~ +There isn't a formal review process for NFSD, but we like to see +at least two Reviewed-by: notices for patches that are more than +simple clean-ups. Reviews are done in public on +linux-nfs@vger.kernel.org and are archived on lore.kernel.org. + +Currently the NFSD patch queues are maintained in branches here: + + https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git + +The NFSD maintainers apply patches initially to the nfsd-testing +branch, which is always open to new submissions. Patches can be +applied while review is ongoing. nfsd-testing is a topic branch, +so it can change frequently, it will be rebased, and your patch +might get dropped if there is a problem with it. + +Generally a script-generated "thank you" email will indicate when +your patch has been added to the nfsd-testing branch. You can track +the progress of your patch using the linux-nfs patchworks instance: + + https://patchwork.kernel.org/project/linux-nfs/list/ + +While your patch is in nfsd-testing, it is exposed to a variety of +test environments, including community zero-day bots, static +analysis tools, and NFSD continuous integration testing. The soak +period is three to four weeks. + +Each patch that survives in nfsd-testing for the soak period without +changes is moved to the nfsd-next branch. + +The nfsd-next branch is automatically merged into linux-next and +fs-next on a nightly basis. + +Patches that survive in nfsd-next are included in the next NFSD +merge window pull request. These windows typically occur once every +63 days (nine weeks). + +When the upstream merge window closes, the nfsd-next branch is +renamed nfsd-fixes, and a new nfsd-next branch is created, based on +the upstream -rc1 tag. + +Fixes that are destined for an upstream -rc release also run the +nfsd-testing gauntlet, but are then applied to the nfsd-fixes +branch. That branch is made available for Linus to pull after a +short time. In order to limit the risk of introducing regressions, +we limit such fixes to emergency situations or fixes to breakage +that occurred during the most recent upstream merge. + +Please make it clear when submitting an emergency patch that +immediate action (either application to -rc or LTS backport) is +needed. + +Sensitive patch submissions and bug reports +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +CVEs are generated by specific members of the Linux kernel community +and several external entities. The Linux NFS community does not emit +or assign CVEs. CVEs are assigned after an issue and its fix are +known. + +However, the NFSD maintainers sometimes receive sensitive security +reports, and at times these are significant enough to need to be +embargoed. In such rare cases, fixes can be developed and reviewed +out of the public eye. + +Please be aware that many version management tools add the stable +Cc's when you post your patches. This is generally a nuisance, but +it can result in outing an embargoed security issue accidentally. +Don't add "Cc: stable" unless you are absolutely sure the patch +needs to go to stable@ during the initial submission process. + +Patches that are merged without ever appearing on any list, and +which carry a Reported-by: or Fixes: tag are detected as suspicious +by security-focused people. We encourage that, after any private +review, security-sensitive patches should be posted to linux-nfs@ +for the usual public review, archiving, and test period. + +LLM-generated submissions +~~~~~~~~~~~~~~~~~~~~~~~~~ +The Linux kernel community as a whole is still exploring the new +world of LLM-generated code. The NFSD maintainers will entertain +submission of patches that are partially or wholly generated by +LLM-based development tools. Such submissions are held to the +same standards as submissions created entirely by human authors: + +- The human contributor identifies themselves via a Signed-off-by: + tag. This tag counts as a DoC. + +- The human contributor is solely responsible for code provenance + and any contamination by inadvertently-included code with a + conflicting license, as usual. + +- The human contributor must be able to answer and address review + questions. A patch description such as "This fixed my problem + but I don't know why" is not acceptable. + +- The contribution is subjected to the same test regimen as all + other submissions. + +- An indication (via a Generated-by: tag or otherwise) that the + contribution is LLM-generated is not required. + +It is easy to address review comments and fix requests in LLM +generated code. So easy, in fact, that it becomes tempting to repost +refreshed code immediately. Please resist that temptation. + +As always, please avoid reposting series revisions more than once +every 24 hours. + +Clean-up patches +~~~~~~~~~~~~~~~~ +The NFSD maintainers discourage patches which perform simple clean- +ups, which are not in the context of other work. For example: + +* Addressing ``checkpatch.pl`` warnings after merge +* Addressing :ref:`Local variable ordering` issues +* Addressing long-standing whitespace damage + +This is because it is felt that the churn that such changes produce +comes at a greater cost than the value of such clean-ups. + +Conversely, spelling and grammar fixes are encouraged. + +Stable and LTS support +---------------------- +Upstream NFSD continuous integration testing runs against LTS trees +whenever they are updated. + +Please indicate when a patch containing a fix needs to be considered +for LTS kernels, either via a Fixes: tag or explicit mention. + +Feature requests +---------------- +There is no one way to make an official feature request, but +discussion about the request should eventually make its way to +the linux-nfs@vger.kernel.org mailing list for public review by +the community. + +Subsystem boundaries +~~~~~~~~~~~~~~~~~~~~ +NFSD itself is not much more than a protocol engine. This means its +primary responsibility is to translate the NFS protocol into API +calls in the Linux kernel. For example, NFSD is not responsible for +knowing exactly how bytes or file attributes are managed on a block +device. It relies on other kernel subsystems for that. + +If the subsystems on which NFSD relies do not implement a particular +feature, even if the standard NFS protocols do support that feature, +that usually means NFSD cannot provide that feature without +substantial development work in other areas of the kernel. + +Specificity +~~~~~~~~~~~ +Feature requests can come from anywhere, and thus can often be +nebulous. A requester might not understand what a "use case" or +"user story" is. These descriptive paradigms are often used by +developers and architects to understand what is required of a +design, but are terms of art in the software trade, not used in +the everyday world. + +In order to prevent contributors and maintainers from becoming +overwhelmed, we won't be afraid of saying "no" politely to +underspecified requests. + +Community roles and their authority +----------------------------------- +The purpose of Linux subsystem communities is to provide expertise +and active stewardship of a narrow set of source files in the Linux +kernel. This can include managing user space tooling as well. + +To contextualize the structure of the Linux NFS community that +is responsible for stewardship of the NFS server code base, we +define the community roles here. + +- **Contributor** : Anyone who submits a code change, bug fix, + recommendation, documentation fix, and so on. A contributor can + submit regularly or infrequently. + +- **Outside Contributor** : A contributor who is not a regular actor + in the Linux NFS community. This can mean someone who contributes + to other parts of the kernel, or someone who just noticed a + misspelling in a comment and sent a patch. + +- **Reviewer** : Someone who is named in the MAINTAINERS file as a + reviewer is an area expert who can request changes to contributed + code, and expects that contributors will address the request. + +- **External Reviewer** : Someone who is not named in the + MAINTAINERS file as a reviewer, but who is an area expert. + Examples include Linux kernel contributors with networking, + security, or persistent storage expertise, or developers who + contribute primarily to other NFS implementations. + +One or more people will take on the following roles. These people +are often generically referred to as "maintainers", and are +identified in the MAINTAINERS file with the "M:" tag under the NFSD +subsystem. + +- **Upstream Release Manager** : This role is responsible for + curating contributions into a branch, reviewing test results, and + then sending a pull request during merge windows. There is a + trust relationship between the release manager and Linus. + +- **Bug Triager** : Someone who is a first responder to bug reports + submitted to the linux-nfs mailing list or bug trackers, and helps + troubleshoot and identify next steps. + +- **Security Lead** : The security lead handles contacts from the + security community to resolve immediate issues, as well as dealing + with long-term security issues such as supply chain concerns. For + upstream, that's usually whether contributions violate licensing + or other intellectual property agreements. + +- **Testing Lead** : The testing lead builds and runs the test + infrastructure for the subsystem. The testing lead may ask for + patches to be dropped because of ongoing high defect rates. + +- **LTS Maintainer** : The LTS maintainer is responsible for managing + the Fixes: and Cc: stable annotations on patches, and seeing that + patches that cannot be automatically applied to LTS kernels get + proper manual backports as necessary. + +- **Community Manager** : This umpire role can be asked to call balls + and strikes during conflicts, but is also responsible for ensuring + the health of the relationships within the community and for + facilitating discussions on long-term topics such as how to manage + growing technical debt. diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index d33429294252b..3397937ed838e 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -1286,6 +1286,11 @@ The vm_area_desc provides the minimum required information for a filesystem to initialise state upon memory mapping of a file-backed region, and output parameters for the file system to set this state. +In nearly all cases, this is all that is required for a filesystem. However, if +a filesystem needs to perform an operation such a pre-population of page tables, +then that action can be specified in the vm_area_desc->action field, which can +be configured using the mmap_action_*() helpers. + --- **mandatory** @@ -1322,3 +1327,10 @@ When vfs_mkdir() returns an error, and so both dputs() the original dentry and doesn't provide a replacement, it also unlocks the parent. Consequently the return value from vfs_mkdir() can be passed to end_creating() and the parent will be unlocked precisely when necessary. + +--- + +**mandatory** + +kill_litter_super() is gone; convert to DCACHE_PERSISTENT use (as all +in-tree filesystems have done). diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst index 0b86a8022fa1e..8256e857e2d74 100644 --- a/Documentation/filesystems/proc.rst +++ b/Documentation/filesystems/proc.rst @@ -553,7 +553,7 @@ otherwise. kernel flags associated with the particular virtual memory area in two letter encoded manner. The codes are the following: - == ======================================= + == ============================================================= rd readable wr writeable ex executable @@ -591,7 +591,8 @@ encoded manner. The codes are the following: sl sealed lf lock on fault pages dp always lazily freeable mapping - == ======================================= + gu maybe contains guard regions (if not set, definitely doesn't) + == ============================================================= Note that there is no guarantee that every flag and associated mnemonic will be present in all further kernel releases. Things get changed, the flags may diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst index 4f13b01e42eb5..670ba66b60e49 100644 --- a/Documentation/filesystems/vfs.rst +++ b/Documentation/filesystems/vfs.rst @@ -1213,6 +1213,10 @@ otherwise noted. file-backed memory mapping, most notably establishing relevant private state and VMA callbacks. + If further action such as pre-population of page tables is required, + this can be specified by the vm_area_desc->action field and related + parameters. + Note that the file operations are implemented by the specific filesystem in which the inode resides. When opening a device node (character or block special) most filesystems will call special diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 5139705089f20..781129f78b06b 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -92,6 +92,18 @@ GEM Atomic Helper Reference .. kernel-doc:: drivers/gpu/drm/drm_gem_atomic_helper.c :export: +VBLANK Helper Reference +----------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_vblank_helper.c + :doc: overview + +.. kernel-doc:: include/drm/drm_vblank_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_vblank_helper.c + :export: + Simple KMS Helper Reference =========================== diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index abfe220764e1e..2292e65f044c3 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -413,6 +413,21 @@ Plane Panic Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_panic.c :export: +Colorop Abstraction +=================== + +.. kernel-doc:: drivers/gpu/drm/drm_colorop.c + :doc: overview + +Colorop Functions Reference +--------------------------- + +.. kernel-doc:: include/drm/drm_colorop.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_colorop.c + :export: + Display Modes Function Reference ================================ diff --git a/Documentation/gpu/nova/core/todo.rst b/Documentation/gpu/nova/core/todo.rst index 0972cb905f7ae..35cc7c31d4239 100644 --- a/Documentation/gpu/nova/core/todo.rst +++ b/Documentation/gpu/nova/core/todo.rst @@ -44,25 +44,6 @@ automatically generates the corresponding mappings between a value and a number. | Complexity: Beginner | Link: https://docs.rs/num/latest/num/trait.FromPrimitive.html -Conversion from byte slices for types implementing FromBytes [TRSM] -------------------------------------------------------------------- - -We retrieve several structures from byte streams coming from the BIOS or loaded -firmware. At the moment converting the bytes slice into the proper type require -an inelegant `unsafe` operation; this will go away once `FromBytes` implements -a proper `from_bytes` method. - -| Complexity: Beginner - -CoherentAllocation improvements [COHA] --------------------------------------- - -`CoherentAllocation` needs a safe way to write into the allocation, and to -obtain slices within the allocation. - -| Complexity: Beginner -| Contact: Abdiel Janulgue - Generic register abstraction [REGA] ----------------------------------- @@ -153,17 +134,6 @@ A `num` core kernel module is being designed to provide these operations. | Complexity: Intermediate | Contact: Alexandre Courbot -Delay / Sleep abstractions [DLAY] ---------------------------------- - -Rust abstractions for the kernel's delay() and sleep() functions. - -FUJITA Tomonori plans to work on abstractions for read_poll_timeout_atomic() -(and friends) [1]. - -| Complexity: Beginner -| Link: https://lore.kernel.org/netdev/20250228.080550.354359820929821928.fujita.tomonori@gmail.com/ [1] - IRQ abstractions ---------------- diff --git a/Documentation/gpu/rfc/color_pipeline.rst b/Documentation/gpu/rfc/color_pipeline.rst new file mode 100644 index 0000000000000..cd1cc2d0f9887 --- /dev/null +++ b/Documentation/gpu/rfc/color_pipeline.rst @@ -0,0 +1,378 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================== +Linux Color Pipeline API +======================== + +What problem are we solving? +============================ + +We would like to support pre-, and post-blending complex color +transformations in display controller hardware in order to allow for +HW-supported HDR use-cases, as well as to provide support to +color-managed applications, such as video or image editors. + +It is possible to support an HDR output on HW supporting the Colorspace +and HDR Metadata drm_connector properties, but that requires the +compositor or application to render and compose the content into one +final buffer intended for display. Doing so is costly. + +Most modern display HW offers various 1D LUTs, 3D LUTs, matrices, and other +operations to support color transformations. These operations are often +implemented in fixed-function HW and therefore much more power efficient than +performing similar operations via shaders or CPU. + +We would like to make use of this HW functionality to support complex color +transformations with no, or minimal CPU or shader load. The switch between HW +fixed-function blocks and shaders/CPU must be seamless with no visible +difference when fallback to shaders/CPU is neceesary at any time. + + +How are other OSes solving this problem? +======================================== + +The most widely supported use-cases regard HDR content, whether video or +gaming. + +Most OSes will specify the source content format (color gamut, encoding transfer +function, and other metadata, such as max and average light levels) to a driver. +Drivers will then program their fixed-function HW accordingly to map from a +source content buffer's space to a display's space. + +When fixed-function HW is not available the compositor will assemble a shader to +ask the GPU to perform the transformation from the source content format to the +display's format. + +A compositor's mapping function and a driver's mapping function are usually +entirely separate concepts. On OSes where a HW vendor has no insight into +closed-source compositor code such a vendor will tune their color management +code to visually match the compositor's. On other OSes, where both mapping +functions are open to an implementer they will ensure both mappings match. + +This results in mapping algorithm lock-in, meaning that no-one alone can +experiment with or introduce new mapping algorithms and achieve +consistent results regardless of which implementation path is taken. + +Why is Linux different? +======================= + +Unlike other OSes, where there is one compositor for one or more drivers, on +Linux we have a many-to-many relationship. Many compositors; many drivers. +In addition each compositor vendor or community has their own view of how +color management should be done. This is what makes Linux so beautiful. + +This means that a HW vendor can now no longer tune their driver to one +compositor, as tuning it to one could make it look fairly different from +another compositor's color mapping. + +We need a better solution. + + +Descriptive API +=============== + +An API that describes the source and destination colorspaces is a descriptive +API. It describes the input and output color spaces but does not describe +how precisely they should be mapped. Such a mapping includes many minute +design decision that can greatly affect the look of the final result. + +It is not feasible to describe such mapping with enough detail to ensure the +same result from each implementation. In fact, these mappings are a very active +research area. + + +Prescriptive API +================ + +A prescriptive API describes not the source and destination colorspaces. It +instead prescribes a recipe for how to manipulate pixel values to arrive at the +desired outcome. + +This recipe is generally an ordered list of straight-forward operations, +with clear mathematical definitions, such as 1D LUTs, 3D LUTs, matrices, +or other operations that can be described in a precise manner. + + +The Color Pipeline API +====================== + +HW color management pipelines can significantly differ between HW +vendors in terms of availability, ordering, and capabilities of HW +blocks. This makes a common definition of color management blocks and +their ordering nigh impossible. Instead we are defining an API that +allows user space to discover the HW capabilities in a generic manner, +agnostic of specific drivers and hardware. + + +drm_colorop Object +================== + +To support the definition of color pipelines we define the DRM core +object type drm_colorop. Individual drm_colorop objects will be chained +via the NEXT property of a drm_colorop to constitute a color pipeline. +Each drm_colorop object is unique, i.e., even if multiple color +pipelines have the same operation they won't share the same drm_colorop +object to describe that operation. + +Note that drivers are not expected to map drm_colorop objects statically +to specific HW blocks. The mapping of drm_colorop objects is entirely a +driver-internal detail and can be as dynamic or static as a driver needs +it to be. See more in the Driver Implementation Guide section below. + +Each drm_colorop has three core properties: + +TYPE: An enumeration property, defining the type of transformation, such as +* enumerated curve +* custom (uniform) 1D LUT +* 3x3 matrix +* 3x4 matrix +* 3D LUT +* etc. + +Depending on the type of transformation other properties will describe +more details. + +BYPASS: A boolean property that can be used to easily put a block into +bypass mode. The BYPASS property is not mandatory for a colorop, as long +as the entire pipeline can get bypassed by setting the COLOR_PIPELINE on +a plane to '0'. + +NEXT: The ID of the next drm_colorop in a color pipeline, or 0 if this +drm_colorop is the last in the chain. + +An example of a drm_colorop object might look like one of these:: + + /* 1D enumerated curve */ + Color operation 42 + ├─ "TYPE": immutable enum {1D enumerated curve, 1D LUT, 3x3 matrix, 3x4 matrix, 3D LUT, etc.} = 1D enumerated curve + ├─ "BYPASS": bool {true, false} + ├─ "CURVE_1D_TYPE": enum {sRGB EOTF, sRGB inverse EOTF, PQ EOTF, PQ inverse EOTF, …} + └─ "NEXT": immutable color operation ID = 43 + + /* custom 4k entry 1D LUT */ + Color operation 52 + ├─ "TYPE": immutable enum {1D enumerated curve, 1D LUT, 3x3 matrix, 3x4 matrix, 3D LUT, etc.} = 1D LUT + ├─ "BYPASS": bool {true, false} + ├─ "SIZE": immutable range = 4096 + ├─ "DATA": blob + └─ "NEXT": immutable color operation ID = 0 + + /* 17^3 3D LUT */ + Color operation 72 + ├─ "TYPE": immutable enum {1D enumerated curve, 1D LUT, 3x3 matrix, 3x4 matrix, 3D LUT, etc.} = 3D LUT + ├─ "BYPASS": bool {true, false} + ├─ "SIZE": immutable range = 17 + ├─ "DATA": blob + └─ "NEXT": immutable color operation ID = 73 + +drm_colorop extensibility +------------------------- + +Unlike existing DRM core objects, like &drm_plane, drm_colorop is not +extensible. This simplifies implementations and keeps all functionality +for managing &drm_colorop objects in the DRM core. + +If there is a need one may introduce a simple &drm_colorop_funcs +function table in the future, for example to support an IN_FORMATS +property on a &drm_colorop. + +If a driver requires the ability to create a driver-specific colorop +object they will need to add &drm_colorop func table support with +support for the usual functions, like destroy, atomic_duplicate_state, +and atomic_destroy_state. + + +COLOR_PIPELINE Plane Property +============================= + +Color Pipelines are created by a driver and advertised via a new +COLOR_PIPELINE enum property on each plane. Values of the property +always include object id 0, which is the default and means all color +processing is disabled. Additional values will be the object IDs of the +first drm_colorop in a pipeline. A driver can create and advertise none, +one, or more possible color pipelines. A DRM client will select a color +pipeline by setting the COLOR PIPELINE to the respective value. + +NOTE: Many DRM clients will set enumeration properties via the string +value, often hard-coding it. Since this enumeration is generated based +on the colorop object IDs it is important to perform the Color Pipeline +Discovery, described below, instead of hard-coding color pipeline +assignment. Drivers might generate the enum strings dynamically. +Hard-coded strings might only work for specific drivers on a specific +pieces of HW. Color Pipeline Discovery can work universally, as long as +drivers implement the required color operations. + +The COLOR_PIPELINE property is only exposed when the +DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE is set. Drivers shall ignore any +existing pre-blend color operations when this cap is set, such as +COLOR_RANGE and COLOR_ENCODING. If drivers want to support COLOR_RANGE +or COLOR_ENCODING functionality when the color pipeline client cap is +set, they are expected to expose colorops in the pipeline to allow for +the appropriate color transformation. + +Setting of the COLOR_PIPELINE plane property or drm_colorop properties +is only allowed for userspace that sets this client cap. + +An example of a COLOR_PIPELINE property on a plane might look like this:: + + Plane 10 + ├─ "TYPE": immutable enum {Overlay, Primary, Cursor} = Primary + ├─ … + └─ "COLOR_PIPELINE": enum {0, 42, 52} = 0 + + +Color Pipeline Discovery +======================== + +A DRM client wanting color management on a drm_plane will: + +1. Get the COLOR_PIPELINE property of the plane +2. iterate all COLOR_PIPELINE enum values +3. for each enum value walk the color pipeline (via the NEXT pointers) + and see if the available color operations are suitable for the + desired color management operations + +If userspace encounters an unknown or unsuitable color operation during +discovery it does not need to reject the entire color pipeline outright, +as long as the unknown or unsuitable colorop has a "BYPASS" property. +Drivers will ensure that a bypassed block does not have any effect. + +An example of chained properties to define an AMD pre-blending color +pipeline might look like this:: + + Plane 10 + ├─ "TYPE" (immutable) = Primary + └─ "COLOR_PIPELINE": enum {0, 44} = 0 + + Color operation 44 + ├─ "TYPE" (immutable) = 1D enumerated curve + ├─ "BYPASS": bool + ├─ "CURVE_1D_TYPE": enum {sRGB EOTF, PQ EOTF} = sRGB EOTF + └─ "NEXT" (immutable) = 45 + + Color operation 45 + ├─ "TYPE" (immutable) = 3x4 Matrix + ├─ "BYPASS": bool + ├─ "DATA": blob + └─ "NEXT" (immutable) = 46 + + Color operation 46 + ├─ "TYPE" (immutable) = 1D enumerated curve + ├─ "BYPASS": bool + ├─ "CURVE_1D_TYPE": enum {sRGB Inverse EOTF, PQ Inverse EOTF} = sRGB EOTF + └─ "NEXT" (immutable) = 47 + + Color operation 47 + ├─ "TYPE" (immutable) = 1D LUT + ├─ "SIZE": immutable range = 4096 + ├─ "DATA": blob + └─ "NEXT" (immutable) = 48 + + Color operation 48 + ├─ "TYPE" (immutable) = 3D LUT + ├─ "DATA": blob + └─ "NEXT" (immutable) = 49 + + Color operation 49 + ├─ "TYPE" (immutable) = 1D enumerated curve + ├─ "BYPASS": bool + ├─ "CURVE_1D_TYPE": enum {sRGB EOTF, PQ EOTF} = sRGB EOTF + └─ "NEXT" (immutable) = 0 + + +Color Pipeline Programming +========================== + +Once a DRM client has found a suitable pipeline it will: + +1. Set the COLOR_PIPELINE enum value to the one pointing at the first + drm_colorop object of the desired pipeline +2. Set the properties for all drm_colorop objects in the pipeline to the + desired values, setting BYPASS to true for unused drm_colorop blocks, + and false for enabled drm_colorop blocks +3. Perform (TEST_ONLY or not) atomic commit with all the other KMS + states it wishes to change + +To configure the pipeline for an HDR10 PQ plane and blending in linear +space, a compositor might perform an atomic commit with the following +property values:: + + Plane 10 + └─ "COLOR_PIPELINE" = 42 + + Color operation 42 + └─ "BYPASS" = true + + Color operation 44 + └─ "BYPASS" = true + + Color operation 45 + └─ "BYPASS" = true + + Color operation 46 + └─ "BYPASS" = true + + Color operation 47 + ├─ "DATA" = Gamut mapping + tone mapping + night mode + └─ "BYPASS" = false + + Color operation 48 + ├─ "CURVE_1D_TYPE" = PQ EOTF + └─ "BYPASS" = false + + +Driver Implementer's Guide +========================== + +What does this all mean for driver implementations? As noted above the +colorops can map to HW directly but don't need to do so. Here are some +suggestions on how to think about creating your color pipelines: + +- Try to expose pipelines that use already defined colorops, even if + your hardware pipeline is split differently. This allows existing + userspace to immediately take advantage of the hardware. + +- Additionally, try to expose your actual hardware blocks as colorops. + Define new colorop types where you believe it can offer significant + benefits if userspace learns to program them. + +- Avoid defining new colorops for compound operations with very narrow + scope. If you have a hardware block for a special operation that + cannot be split further, you can expose that as a new colorop type. + However, try to not define colorops for "use cases", especially if + they require you to combine multiple hardware blocks. + +- Design new colorops as prescriptive, not descriptive; by the + mathematical formula, not by the assumed input and output. + +A defined colorop type must be deterministic. The exact behavior of the +colorop must be documented entirely, whether via a mathematical formula +or some other description. Its operation can depend only on its +properties and input and nothing else, allowed error tolerance +notwithstanding. + + +Driver Forward/Backward Compatibility +===================================== + +As this is uAPI drivers can't regress color pipelines that have been +introduced for a given HW generation. New HW generations are free to +abandon color pipelines advertised for previous generations. +Nevertheless, it can be beneficial to carry support for existing color +pipelines forward as those will likely already have support in DRM +clients. + +Introducing new colorops to a pipeline is fine, as long as they can be +bypassed or are purely informational. DRM clients implementing support +for the pipeline can always skip unknown properties as long as they can +be confident that doing so will not cause unexpected results. + +If a new colorop doesn't fall into one of the above categories +(bypassable or informational) the modified pipeline would be unusable +for user space. In this case a new pipeline should be defined. + + +References +========== + +1. https://lore.kernel.org/dri-devel/QMers3awXvNCQlyhWdTtsPwkp5ie9bze_hD5nAccFW7a_RXlWjYB7MoUW_8CKLT2bSQwIXVi5H6VULYIxCdgvryZoAoJnC5lZgyK1QWn488=@emersion.fr/ \ No newline at end of file diff --git a/Documentation/gpu/rfc/index.rst b/Documentation/gpu/rfc/index.rst index 396e535377fbc..ef19b0ba2a3ea 100644 --- a/Documentation/gpu/rfc/index.rst +++ b/Documentation/gpu/rfc/index.rst @@ -35,3 +35,6 @@ host such documentation: .. toctree:: i915_vm_bind.rst + +.. toctree:: + color_pipeline.rst \ No newline at end of file diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index b5f58b4274b1d..9013ced318cb9 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -623,6 +623,43 @@ Contact: Thomas Zimmermann , Simona Vetter Level: Advanced +Implement a new DUMB_CREATE2 ioctl +---------------------------------- + +The current DUMB_CREATE ioctl is not well defined. Instead of a pixel and +framebuffer format, it only accepts a color mode of vague semantics. Assuming +a linear framebuffer, the color mode gives an idea of the supported pixel +format. But userspace effectively has to guess the correct values. It really +only works reliably with framebuffers in XRGB8888. Userspace has begun to +workaround these limitations by computing arbitrary format's buffer sizes and +calculating their sizes in terms of XRGB8888 pixels. + +One possible solution is a new ioctl DUMB_CREATE2. It should accept a DRM +format and a format modifier to resolve the color mode's ambiguity. As +framebuffers can be multi-planar, the new ioctl has to return the buffer size, +pitch and GEM handle for each individual color plane. + +In the first step, the new ioctl can be limited to the current features of +the existing DUMB_CREATE. Individual drivers can then be extended to support +multi-planar formats. Rockchip might require this and would be a good candidate. + +It might also be helpful to userspace to query information about the size of +a potential buffer, if allocated. Userspace would supply geometry and format; +the kernel would return minimal allocation sizes and scanline pitch. There is +interest to allocate that memory from another device and provide it to the +DRM driver (say via dma-buf). + +Another requested feature is the ability to allocate a buffer by size, without +format. Accelators use this for their buffer allocation and it could likely be +generalized. + +In addition to the kernel implementation, there must be user-space support +for the new ioctl. There's code in Mesa that might be able to use the new +call. + +Contact: Thomas Zimmermann + +Level: Advanced Better Testing ============== diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst index 8a8b1002931f8..1e79e62a6bc4c 100644 --- a/Documentation/gpu/vkms.rst +++ b/Documentation/gpu/vkms.rst @@ -51,6 +51,97 @@ To disable the driver, use :: sudo modprobe -r vkms +Configuring With Configfs +========================= + +It is possible to create and configure multiple VKMS instances via configfs. + +Start by mounting configfs and loading VKMS:: + + sudo mount -t configfs none /config + sudo modprobe vkms + +Once VKMS is loaded, ``/config/vkms`` is created automatically. Each directory +under ``/config/vkms`` represents a VKMS instance, create a new one:: + + sudo mkdir /config/vkms/my-vkms + +By default, the instance is disabled:: + + cat /config/vkms/my-vkms/enabled + 0 + +And directories are created for each configurable item of the display pipeline:: + + tree /config/vkms/my-vkms + ├── connectors + ├── crtcs + ├── enabled + ├── encoders + └── planes + +To add items to the display pipeline, create one or more directories under the +available paths. + +Start by creating one or more planes:: + + sudo mkdir /config/vkms/my-vkms/planes/plane0 + +Planes have 1 configurable attribute: + +- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those + exposed by the "type" property of a plane) + +Continue by creating one or more CRTCs:: + + sudo mkdir /config/vkms/my-vkms/crtcs/crtc0 + +CRTCs have 1 configurable attribute: + +- writeback: Enable or disable writeback connector support by writing 1 or 0 + +Next, create one or more encoders:: + + sudo mkdir /config/vkms/my-vkms/encoders/encoder0 + +Last but not least, create one or more connectors:: + + sudo mkdir /config/vkms/my-vkms/connectors/connector0 + +Connectors have 1 configurable attribute: + +- status: Connection status: 1 connected, 2 disconnected, 3 unknown (same values + as those exposed by the "status" property of a connector) + +To finish the configuration, link the different pipeline items:: + + sudo ln -s /config/vkms/my-vkms/crtcs/crtc0 /config/vkms/my-vkms/planes/plane0/possible_crtcs + sudo ln -s /config/vkms/my-vkms/crtcs/crtc0 /config/vkms/my-vkms/encoders/encoder0/possible_crtcs + sudo ln -s /config/vkms/my-vkms/encoders/encoder0 /config/vkms/my-vkms/connectors/connector0/possible_encoders + +Since at least one primary plane is required, make sure to set the right type:: + + echo "1" | sudo tee /config/vkms/my-vkms/planes/plane0/type + +Once you are done configuring the VKMS instance, enable it:: + + echo "1" | sudo tee /config/vkms/my-vkms/enabled + +Finally, you can remove the VKMS instance disabling it:: + + echo "0" | sudo tee /config/vkms/my-vkms/enabled + +And removing the top level directory and its subdirectories:: + + sudo rm /config/vkms/my-vkms/planes/*/possible_crtcs/* + sudo rm /config/vkms/my-vkms/encoders/*/possible_crtcs/* + sudo rm /config/vkms/my-vkms/connectors/*/possible_encoders/* + sudo rmdir /config/vkms/my-vkms/planes/* + sudo rmdir /config/vkms/my-vkms/crtcs/* + sudo rmdir /config/vkms/my-vkms/encoders/* + sudo rmdir /config/vkms/my-vkms/connectors/* + sudo rmdir /config/vkms/my-vkms + Testing With IGT ================ @@ -68,26 +159,23 @@ To return to graphical mode, do:: sudo systemctl isolate graphical.target -Once you are in text only mode, you can run tests using the --device switch -or IGT_DEVICE variable to specify the device filter for the driver we want -to test. IGT_DEVICE can also be used with the run-test.sh script to run the +Once you are in text only mode, you can run tests using the IGT_FORCE_DRIVER +variable to specify the device filter for the driver we want to test. +IGT_FORCE_DRIVER can also be used with the run-tests.sh script to run the tests for a specific driver:: - sudo ./build/tests/ --device "sys:/sys/devices/platform/vkms" - sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/ - sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./scripts/run-tests.sh -t + sudo IGT_FORCE_DRIVER="vkms" ./build/tests/ + sudo IGT_FORCE_DRIVER="vkms" ./scripts/run-tests.sh -t For example, to test the functionality of the writeback library, we can run the kms_writeback test:: - sudo ./build/tests/kms_writeback --device "sys:/sys/devices/platform/vkms" - sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_writeback - sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./scripts/run-tests.sh -t kms_writeback + sudo IGT_FORCE_DRIVER="vkms" ./build/tests/kms_writeback + sudo IGT_FORCE_DRIVER="vkms" ./scripts/run-tests.sh -t kms_writeback You can also run subtests if you do not want to run the entire test:: - sudo ./build/tests/kms_flip --run-subtest basic-plain-flip --device "sys:/sys/devices/platform/vkms" - sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_flip --run-subtest basic-plain-flip + sudo IGT_FORCE_DRIVER="vkms" ./build/tests/kms_flip --run-subtest basic-plain-flip Testing With KUnit ================== @@ -147,21 +235,14 @@ Runtime Configuration --------------------- We want to be able to reconfigure vkms instance without having to reload the -module. Use/Test-cases: +module through configfs. Use/Test-cases: - Hotplug/hotremove connectors on the fly (to be able to test DP MST handling of compositors). -- Configure planes/crtcs/connectors (we'd need some code to have more than 1 of - them first). - - Change output configuration: Plug/unplug screens, change EDID, allow changing the refresh rate. -The currently proposed solution is to expose vkms configuration through -configfs. All existing module options should be supported through configfs -too. - Writeback support ----------------- diff --git a/Documentation/gpu/xe/index.rst b/Documentation/gpu/xe/index.rst index 88b22fad880e7..bc432c95d1a35 100644 --- a/Documentation/gpu/xe/index.rst +++ b/Documentation/gpu/xe/index.rst @@ -14,6 +14,7 @@ DG2, etc is provided to prototype the driver. xe_mm xe_map xe_migrate + xe_exec_queue xe_cs xe_pm xe_gt_freq diff --git a/Documentation/gpu/xe/xe_exec_queue.rst b/Documentation/gpu/xe/xe_exec_queue.rst new file mode 100644 index 0000000000000..6076569e311cd --- /dev/null +++ b/Documentation/gpu/xe/xe_exec_queue.rst @@ -0,0 +1,20 @@ +.. SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +=============== +Execution Queue +=============== + +.. kernel-doc:: drivers/gpu/drm/xe/xe_exec_queue.c + :doc: Execution Queue + +Internal API +============ + +.. kernel-doc:: drivers/gpu/drm/xe/xe_exec_queue_types.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/xe/xe_exec_queue.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/xe/xe_exec_queue.c + :internal: diff --git a/Documentation/gpu/xe/xe_gt_freq.rst b/Documentation/gpu/xe/xe_gt_freq.rst index c0811200e3275..182d6aabeee18 100644 --- a/Documentation/gpu/xe/xe_gt_freq.rst +++ b/Documentation/gpu/xe/xe_gt_freq.rst @@ -7,6 +7,9 @@ Xe GT Frequency Management .. kernel-doc:: drivers/gpu/drm/xe/xe_gt_freq.c :doc: Xe GT Frequency Management +.. kernel-doc:: drivers/gpu/drm/xe/xe_gt_throttle.c + :doc: Xe GT Throttle + Internal API ============ diff --git a/Documentation/hid/hid-alps.rst b/Documentation/hid/hid-alps.rst index 94382bb0ada4d..4a22a357f00c0 100644 --- a/Documentation/hid/hid-alps.rst +++ b/Documentation/hid/hid-alps.rst @@ -69,6 +69,7 @@ To read/write to RAM, need to send a command to the device. The command format is as below. DataByte(SET_REPORT) +~~~~~~~~~~~~~~~~~~~~ ===== ====================== Byte1 Command Byte @@ -89,6 +90,7 @@ Value Byte is writing data when you send the write commands. When you read RAM, there is no meaning. DataByte(GET_REPORT) +~~~~~~~~~~~~~~~~~~~~ ===== ====================== Byte1 Response Byte @@ -104,8 +106,10 @@ Read value is stored in Value Byte. Packet Format +------------- + Touchpad data byte ------------------- +~~~~~~~~~~~~~~~~~~ ======= ======= ======= ======= ======= ======= ======= ======= ===== @@ -156,7 +160,7 @@ Zsn_6-0(7bit): StickPointer data byte ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ ======= ======= ======= ======= ======= ======= ======= ======= ===== - b7 b6 b5 b4 b3 b2 b1 b0 diff --git a/Documentation/hwmon/aht10.rst b/Documentation/hwmon/aht10.rst index 213644b4ecba6..7903b6434326d 100644 --- a/Documentation/hwmon/aht10.rst +++ b/Documentation/hwmon/aht10.rst @@ -20,6 +20,14 @@ Supported chips: English: http://www.aosong.com/userfiles/files/media/Data%20Sheet%20AHT20.pdf + * Aosong DHT20 + + Prefix: 'dht20' + + Addresses scanned: None + + Datasheet: https://www.digikey.co.nz/en/htmldatasheets/production/9184855/0/0/1/101020932 + Author: Johannes Cornelis Draaijer @@ -33,7 +41,7 @@ The address of this i2c device may only be 0x38 Special Features ---------------- -AHT20 has additional CRC8 support which is sent as the last byte of the sensor +AHT20, DHT20 has additional CRC8 support which is sent as the last byte of the sensor values. Usage Notes diff --git a/Documentation/hwmon/asus_ec_sensors.rst b/Documentation/hwmon/asus_ec_sensors.rst index a5a58c00c3223..232885f24430d 100644 --- a/Documentation/hwmon/asus_ec_sensors.rst +++ b/Documentation/hwmon/asus_ec_sensors.rst @@ -9,6 +9,7 @@ Supported boards: * PRIME X570-PRO * PRIME X670E-PRO WIFI * PRIME Z270-A + * Pro WS TRX50-SAGE WIFI * Pro WS X570-ACE * Pro WS WRX90E-SAGE SE * ProArt X570-CREATOR WIFI @@ -29,14 +30,17 @@ Supported boards: * ROG STRIX B550-I GAMING * ROG STRIX B650E-I GAMING WIFI * ROG STRIX B850-I GAMING WIFI + * ROG STRIX X470-I GAMING * ROG STRIX X570-E GAMING * ROG STRIX X570-E GAMING WIFI II * ROG STRIX X570-F GAMING * ROG STRIX X570-I GAMING * ROG STRIX X670E-E GAMING WIFI * ROG STRIX X670E-I GAMING WIFI + * ROG STRIX X870-F GAMING WIFI * ROG STRIX X870-I GAMING WIFI * ROG STRIX X870E-E GAMING WIFI + * ROG STRIX X870E-H GAMING WIFI7 * ROG STRIX Z390-F GAMING * ROG STRIX Z490-F GAMING * ROG STRIX Z690-A GAMING WIFI D4 diff --git a/Documentation/hwmon/ds1621.rst b/Documentation/hwmon/ds1621.rst index 552b37e9dd34d..d0808720aa07c 100644 --- a/Documentation/hwmon/ds1621.rst +++ b/Documentation/hwmon/ds1621.rst @@ -9,7 +9,7 @@ Supported chips: Addresses scanned: none - Datasheet: Publicly available from www.maximintegrated.com + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/DS1621.pdf * Dallas Semiconductor DS1625 @@ -17,7 +17,7 @@ Supported chips: Addresses scanned: none - Datasheet: Publicly available from www.datasheetarchive.com + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/DS1620.pdf * Maxim Integrated DS1631 @@ -25,7 +25,7 @@ Supported chips: Addresses scanned: none - Datasheet: Publicly available from www.maximintegrated.com + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/DS1631-DS1731.pdf * Maxim Integrated DS1721 @@ -33,7 +33,7 @@ Supported chips: Addresses scanned: none - Datasheet: Publicly available from www.maximintegrated.com + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/DS1721.pdf * Maxim Integrated DS1731 @@ -41,7 +41,7 @@ Supported chips: Addresses scanned: none - Datasheet: Publicly available from www.maximintegrated.com + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/DS1631-DS1731.pdf Authors: - Christian W. Zuckschwerdt diff --git a/Documentation/hwmon/ds620.rst b/Documentation/hwmon/ds620.rst index 2d686b17b547a..e2d915a988a24 100644 --- a/Documentation/hwmon/ds620.rst +++ b/Documentation/hwmon/ds620.rst @@ -7,9 +7,9 @@ Supported chips: Prefix: 'ds620' - Datasheet: Publicly available at the Dallas Semiconductor website + Datasheet: Publicly available at the Analog Devices website - http://www.dalsemi.com/ + https://www.analog.com/media/en/technical-documentation/data-sheets/DS620.pdf Authors: Roland Stigge diff --git a/Documentation/hwmon/g762.rst b/Documentation/hwmon/g762.rst index 0371b3365c48c..f224552a2d3cc 100644 --- a/Documentation/hwmon/g762.rst +++ b/Documentation/hwmon/g762.rst @@ -17,7 +17,7 @@ done via a userland daemon like fancontrol. Note that those entries do not provide ways to setup the specific hardware characteristics of the system (reference clock, pulses per fan revolution, ...); Those can be modified via devicetree bindings -documented in Documentation/devicetree/bindings/hwmon/g762.txt or +documented in Documentation/devicetree/bindings/hwmon/gmt,g762.yaml or using a specific platform_data structure in board initialization file (see include/linux/platform_data/g762.h). diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst index 51a5bdf75b086..85d7a686883ec 100644 --- a/Documentation/hwmon/index.rst +++ b/Documentation/hwmon/index.rst @@ -144,6 +144,7 @@ Hardware Monitoring Kernel Drivers ltc4261 ltc4282 ltc4286 + macsmc-hwmon max127 max15301 max16064 @@ -151,6 +152,7 @@ Hardware Monitoring Kernel Drivers max1619 max16601 max1668 + max17616 max197 max20730 max20751 @@ -177,6 +179,7 @@ Hardware Monitoring Kernel Drivers mp2869 mp2888 mp2891 + mp2925 mp29502 mp2975 mp2993 @@ -184,6 +187,7 @@ Hardware Monitoring Kernel Drivers mp5920 mp5990 mp9941 + mp9945 mpq8785 nct6683 nct6775 @@ -253,6 +257,7 @@ Hardware Monitoring Kernel Drivers tps40422 tps53679 tps546d24 + tsc1641 twl4030-madc-hwmon ucd9000 ucd9200 diff --git a/Documentation/hwmon/isl68137.rst b/Documentation/hwmon/isl68137.rst index 5bc029c98383d..e77f582c28505 100644 --- a/Documentation/hwmon/isl68137.rst +++ b/Documentation/hwmon/isl68137.rst @@ -414,6 +414,16 @@ Supported chips: Publicly available (after August 2020 launch) at the Renesas website + * Renesas RAA229141 + + Prefix: 'raa229141' + + Addresses scanned: - + + Datasheet: + + Provided by Renesas upon request and NDA + Authors: - Maxim Sloyko - Robert Lippert diff --git a/Documentation/hwmon/jc42.rst b/Documentation/hwmon/jc42.rst index 19d10512f6c03..3736e63db2a87 100644 --- a/Documentation/hwmon/jc42.rst +++ b/Documentation/hwmon/jc42.rst @@ -33,7 +33,7 @@ Supported chips: Datasheets: - http://datasheets.maxim-ic.com/en/ds/MAX6604.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6604.pdf * Microchip MCP9804, MCP9805, MCP9808, MCP98242, MCP98243, MCP98244, MCP9843 diff --git a/Documentation/hwmon/lm75.rst b/Documentation/hwmon/lm75.rst index 908b3a9df06e8..4269da04508ef 100644 --- a/Documentation/hwmon/lm75.rst +++ b/Documentation/hwmon/lm75.rst @@ -23,15 +23,17 @@ Supported chips: http://www.national.com/ - * Dallas Semiconductor (now Maxim) DS75, DS1775, DS7505 + * Dallas Semiconductor (now Analog Devices) DS75, DS1775, DS7505 Prefixes: 'ds75', 'ds1775', 'ds7505' Addresses scanned: none - Datasheet: Publicly available at the Maxim website + Datasheets: - https://www.maximintegrated.com/ + https://www.analog.com/media/en/technical-documentation/data-sheets/DS75.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/DS1775.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/DS7505.pdf * Maxim MAX6625, MAX6626, MAX31725, MAX31726 @@ -39,9 +41,10 @@ Supported chips: Addresses scanned: none - Datasheet: Publicly available at the Maxim website + Datasheets: - http://www.maxim-ic.com/ + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6625-MAX6626.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX31725-MAX31726.pdf * Microchip (TelCom) TCN75 diff --git a/Documentation/hwmon/lm90.rst b/Documentation/hwmon/lm90.rst index 98452eed16d52..79c023521d39f 100644 --- a/Documentation/hwmon/lm90.rst +++ b/Documentation/hwmon/lm90.rst @@ -9,7 +9,9 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheet: Publicly available at the National Semiconductor website + Datasheet: Publicly available at the TI website + + https://www.ti.com/lit/ds/symlink/lm84.pdf * National Semiconductor LM90 @@ -17,9 +19,9 @@ Supported chips: Addresses scanned: I2C 0x4c - Datasheet: Publicly available at the National Semiconductor website + Datasheet: Publicly available at the TI website - http://www.national.com/pf/LM/LM90.html + https://www.ti.com/lit/ds/symlink/lm90.pdf * National Semiconductor LM89 @@ -27,9 +29,9 @@ Supported chips: Addresses scanned: I2C 0x4c and 0x4d - Datasheet: Publicly available at the National Semiconductor website + Datasheet: Publicly available at the TI website - http://www.national.com/mpf/LM/LM89.html + https://www.ti.com/lit/ds/symlink/lm89.pdf * National Semiconductor LM99 @@ -37,9 +39,9 @@ Supported chips: Addresses scanned: I2C 0x4c and 0x4d - Datasheet: Publicly available at the National Semiconductor website + Datasheet: Publicly available at the TI website - http://www.national.com/pf/LM/LM99.html + https://www.ti.com/lit/ds/symlink/lm99.pdf * National Semiconductor LM86 @@ -47,9 +49,9 @@ Supported chips: Addresses scanned: I2C 0x4c - Datasheet: Publicly available at the National Semiconductor website + Datasheet: Publicly available at the TI website - http://www.national.com/mpf/LM/LM86.html + https://www.ti.com/lit/ds/symlink/lm86.pdf * Analog Devices ADM1020 @@ -57,7 +59,9 @@ Supported chips: Addresses scanned: I2C 0x4c - 0x4e - Datasheet: Publicly available at the Analog Devices website + Datasheet: Publicly available at the DigiKey website + + https://media.digikey.com/pdf/Data%20Sheets/Analog%20Devices%20PDFs/ADM1020.pdf * Analog Devices ADM1021 @@ -65,7 +69,9 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheet: Publicly available at the Analog Devices website + Datasheet: Publicly available at the DigiKey website + + https://media.digikey.com/pdf/Data%20Sheets/Analog%20Devices%20PDFs/ADM1021.pdf * Analog Devices ADM1021A/ADM1023 @@ -75,15 +81,18 @@ Supported chips: Datasheet: Publicly available at the Analog Devices website + https://media.digikey.com/pdf/Data%20Sheets/Analog%20Devices%20PDFs/ADM1021A.pdf + https://media.digikey.com/pdf/Data%20Sheets/Analog%20Devices%20PDFs/ADM1023.pdf + * Analog Devices ADM1032 Prefix: 'adm1032' Addresses scanned: I2C 0x4c and 0x4d - Datasheet: Publicly available at the ON Semiconductor website + Datasheet: Publicly available at the DigiKey website - https://www.onsemi.com/PowerSolutions/product.do?id=ADM1032 + https://www.digikey.com/htmldatasheets/production/53140/0/0/1/ADM1032.pdf * Analog Devices ADT7461 @@ -111,9 +120,9 @@ Supported chips: Addresses scanned: I2C 0x4b and 0x4c - Datasheet: Publicly available at the ON Semiconductor website + Datasheet: Publicly available at the DigiKey website - https://www.onsemi.com/PowerSolutions/product.do?id=ADT7481 + https://www.digikey.com/htmldatasheets/production/234607/0/0/1/ADT7481.pdf * Analog Devices ADT7482 @@ -191,7 +200,9 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website + + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX1617.pdf * Maxim MAX1617A @@ -199,7 +210,9 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website + + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX1617A.pdf * Maxim MAX6642 @@ -207,9 +220,9 @@ Supported chips: Addresses scanned: I2C 0x48-0x4f - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://datasheets.maxim-ic.com/en/ds/MAX6642.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6642.pdf * Maxim MAX6646 @@ -217,9 +230,9 @@ Supported chips: Addresses scanned: I2C 0x4d - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6646-MAX6649.pdf * Maxim MAX6647 @@ -227,9 +240,9 @@ Supported chips: Addresses scanned: I2C 0x4e - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6646-MAX6649.pdf * Maxim MAX6648 @@ -237,9 +250,9 @@ Supported chips: Addresses scanned: I2C 0x4c - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3500 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6648-MAX6692.pdf * Maxim MAX6649 @@ -247,9 +260,9 @@ Supported chips: Addresses scanned: I2C 0x4c - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX1617.pdf * Maxim MAX6654 @@ -259,9 +272,9 @@ Supported chips: 0x4c, 0x4d and 0x4e - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - https://www.maximintegrated.com/en/products/sensors/MAX6654.html + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6654.pdf * Maxim MAX6657 @@ -269,9 +282,9 @@ Supported chips: Addresses scanned: I2C 0x4c - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6657-MAX6659.pdf * Maxim MAX6658 @@ -279,9 +292,9 @@ Supported chips: Addresses scanned: I2C 0x4c - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6657-MAX6659.pdf * Maxim MAX6659 @@ -289,9 +302,9 @@ Supported chips: Addresses scanned: I2C 0x4c, 0x4d, 0x4e - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6657-MAX6659.pdf * Maxim MAX6680 @@ -301,9 +314,9 @@ Supported chips: 0x4c, 0x4d and 0x4e - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6680-MAX6681.pdf * Maxim MAX6681 @@ -313,9 +326,9 @@ Supported chips: 0x4c, 0x4d and 0x4e - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6680-MAX6681.pdf * Maxim MAX6692 @@ -323,9 +336,9 @@ Supported chips: Addresses scanned: I2C 0x4c - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3500 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6648-MAX6692.pdf * Maxim MAX6695 @@ -333,9 +346,9 @@ Supported chips: Addresses scanned: I2C 0x18 - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/datasheet/index.mvp/id/4199 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6695-MAX6696.pdf * Maxim MAX6696 @@ -345,9 +358,9 @@ Supported chips: 0x4c, 0x4d and 0x4e - Datasheet: Publicly available at the Maxim website + Datasheet: Publicly available at the Analog Devices website - http://www.maxim-ic.com/datasheet/index.mvp/id/4199 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6695-MAX6696.pdf * Winbond/Nuvoton W83L771W/G @@ -355,7 +368,9 @@ Supported chips: Addresses scanned: I2C 0x4c - Datasheet: No longer available + Datasheet: Publicly available at the DigiKey website + + https://mm.digikey.com/Volume0/opasdata/d220001/medias/docus/1128/W83L771W%2CW83L771G.pdf * Winbond/Nuvoton W83L771AWG/ASG @@ -381,7 +396,7 @@ Supported chips: Datasheet: Publicly available at Nuvoton website - https://www.nuvoton.com/resource-files/Nuvoton_NCT7717U_Datasheet_V111.pdf + https://www.nuvoton.com/resource-files/Nuvoton_NCT7717U_Datasheet_V111.pdf * Nuvoton NCT7718 @@ -391,7 +406,7 @@ Supported chips: Datasheet: Publicly available at Nuvoton website - https://www.nuvoton.com/resource-files/Nuvoton_NCT7718W_Datasheet_V11.pdf + https://www.nuvoton.com/resource-files/Nuvoton_NCT7718W_Datasheet_V11.pdf * Philips/NXP SA56004X @@ -401,7 +416,7 @@ Supported chips: Datasheet: Publicly available at NXP website - http://ics.nxp.com/products/interface/datasheet/sa56004x.pdf + https://www.nxp.com/docs/en/data-sheet/SA56004X.pdf * GMT G781 @@ -437,7 +452,9 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheets: Publicly available at the Philips website + Datasheets: Publicly available at the DigiKey website + + https://www.digikey.com/htmldatasheets/production/97606/0/0/1/ne1617.pdf * Philips NE1618 @@ -445,7 +462,9 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheets: Publicly available at the Philips website + Datasheets: Publicly available at the DigiKey website + + https://media.digikey.com/pdf/Data%20Sheets/NXP%20PDFs/NE1618.pdf * Genesys Logic GL523SM @@ -453,7 +472,7 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheet: + Datasheet: No longer available at Genesys Logic website * TI THMC10 @@ -461,7 +480,7 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheet: Publicly available at the TI website + Datasheet: No longer available at the TI website * Onsemi MC1066 @@ -469,7 +488,7 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheet: Publicly available at the Onsemi website + Datasheet: No longer available at the Onsemi website Author: Jean Delvare diff --git a/Documentation/hwmon/macsmc-hwmon.rst b/Documentation/hwmon/macsmc-hwmon.rst new file mode 100644 index 0000000000000..6903f76df62bf --- /dev/null +++ b/Documentation/hwmon/macsmc-hwmon.rst @@ -0,0 +1,71 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +Kernel driver macsmc-hwmon +========================== + +Supported hardware + + * Apple Silicon Macs (M1 and up) + +Author: James Calligeros + +Description +----------- + +macsmc-hwmon exposes the Apple System Management controller's +temperature, voltage, current and power sensors, as well as +fan speed and control capabilities, via hwmon. + +Because each Apple Silicon Mac exposes a different set of sensors +(e.g. the MacBooks expose battery telemetry that is not present on +the desktop Macs), sensors present on any given machine are described +via Devicetree. The driver picks these up and registers them with +hwmon when probed. + +Manual fan speed is supported via the fan_control module parameter. This +is disabled by default and marked as unsafe, as it cannot be proven that +the system will fail safe if overheating due to manual fan control being +used. + +sysfs interface +--------------- + +currX_input + Ammeter value + +currX_label + Ammeter label + +fanX_input + Current fan speed + +fanX_label + Fan label + +fanX_min + Minimum possible fan speed + +fanX_max + Maximum possible fan speed + +fanX_target + Current fan setpoint + +inX_input + Voltmeter value + +inX_label + Voltmeter label + +powerX_input + Power meter value + +powerX_label + Power meter label + +tempX_input + Temperature sensor value + +tempX_label + Temperature sensor label + diff --git a/Documentation/hwmon/max127.rst b/Documentation/hwmon/max127.rst index dc192dd9c37cc..09204b45f27b4 100644 --- a/Documentation/hwmon/max127.rst +++ b/Documentation/hwmon/max127.rst @@ -13,7 +13,7 @@ Supported chips: Prefix: 'max127' - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX127-MAX128.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max127-max128.pdf Description ----------- diff --git a/Documentation/hwmon/max15301.rst b/Documentation/hwmon/max15301.rst index e2222e98304fd..a0a993195cd1d 100644 --- a/Documentation/hwmon/max15301.rst +++ b/Documentation/hwmon/max15301.rst @@ -11,7 +11,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX15301.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max15301.pdf * Maxim MAX15303 diff --git a/Documentation/hwmon/max16064.rst b/Documentation/hwmon/max16064.rst index c06249292557a..2a8a76d7b2304 100644 --- a/Documentation/hwmon/max16064.rst +++ b/Documentation/hwmon/max16064.rst @@ -9,7 +9,7 @@ Supported chips: Addresses scanned: - - Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX16064.pdf + Datasheet: https://www.digikey.com/en/htmldatasheets/production/701833/0/0/1/max16064 Author: Guenter Roeck diff --git a/Documentation/hwmon/max16065.rst b/Documentation/hwmon/max16065.rst index 45f69f334f252..ac3dc6f023dde 100644 --- a/Documentation/hwmon/max16065.rst +++ b/Documentation/hwmon/max16065.rst @@ -12,7 +12,7 @@ Supported chips: Datasheet: - http://datasheets.maxim-ic.com/en/ds/MAX16065-MAX16066.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/max16065-max16066.pdf * Maxim MAX16067 @@ -22,7 +22,7 @@ Supported chips: Datasheet: - http://datasheets.maxim-ic.com/en/ds/MAX16067.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/max16067.pdf * Maxim MAX16068 @@ -32,7 +32,7 @@ Supported chips: Datasheet: - http://datasheets.maxim-ic.com/en/ds/MAX16068.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/max16068.pdf * Maxim MAX16070/MAX16071 @@ -42,7 +42,7 @@ Supported chips: Datasheet: - http://datasheets.maxim-ic.com/en/ds/MAX16070-MAX16071.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/max16070-max16071.pdf Author: Guenter Roeck diff --git a/Documentation/hwmon/max1619.rst b/Documentation/hwmon/max1619.rst index b5fc175ae18d4..f134d0fa9bfd9 100644 --- a/Documentation/hwmon/max1619.rst +++ b/Documentation/hwmon/max1619.rst @@ -9,9 +9,9 @@ Supported chips: Addresses scanned: I2C 0x18-0x1a, 0x29-0x2b, 0x4c-0x4e - Datasheet: Publicly available at the Maxim website + Datasheet: - http://pdfserv.maxim-ic.com/en/ds/MAX1619.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX1619.pdf Authors: - Oleksij Rempel , diff --git a/Documentation/hwmon/max16601.rst b/Documentation/hwmon/max16601.rst index c8c63a053e404..3b1392bf547e9 100644 --- a/Documentation/hwmon/max16601.rst +++ b/Documentation/hwmon/max16601.rst @@ -35,7 +35,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX16602.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max16602.pdf Author: Guenter Roeck diff --git a/Documentation/hwmon/max1668.rst b/Documentation/hwmon/max1668.rst index 417f17d750e68..e2b8a4056abed 100644 --- a/Documentation/hwmon/max1668.rst +++ b/Documentation/hwmon/max1668.rst @@ -9,7 +9,7 @@ Supported chips: Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e - Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX1668-MAX1989.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX1668-MAX1989.pdf Author: diff --git a/Documentation/hwmon/max17616.rst b/Documentation/hwmon/max17616.rst new file mode 100644 index 0000000000000..a3dc429048ae1 --- /dev/null +++ b/Documentation/hwmon/max17616.rst @@ -0,0 +1,62 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Kernel driver max17616 +====================== + +Supported chips: + + * Analog Devices MAX17616/MAX17616A + + Prefix: 'max17616' + + Addresses scanned: - + + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max17616-max17616a.pdf + +Author: + + - Kim Seer Paller + + +Description +----------- + +This driver supports hardware monitoring for Analog Devices MAX17616/MAX17616A +Current-Limiter with OV/Surge, UV, Reverse Polarity, Loss of Ground Protection +with PMBus Interface. + +The MAX17616/MAX17616A is a 3V to 80V, 7A current-limiter with overvoltage, +surge, undervoltage, reverse polarity, and loss of ground protection. Through +the PMBus interface, the device can monitor input/output voltages, output current +and temperature. + +The driver is a client driver to the core PMBus driver. Please see +Documentation/hwmon/pmbus.rst for details on PMBus client drivers. + +Usage Notes +----------- + +This driver does not auto-detect devices. You will have to instantiate +the devices explicitly. Please see Documentation/i2c/instantiating-devices.rst +for details. + +Platform data support +--------------------- + +The driver supports standard PMBus driver platform data. + +Sysfs entries +------------- + +================= ======================================== +in1_label "vin" +in1_input Measured input voltage +in1_alarm Input voltage alarm +in2_label "vout1" +in2_input Measured output voltage +curr1_label "iout1" +curr1_input Measured output current. +curr1_alarm Output current alarm +temp1_input Measured temperature +temp1_alarm Chip temperature alarm +================= ======================================== diff --git a/Documentation/hwmon/max197.rst b/Documentation/hwmon/max197.rst index 02fe19bc3428c..00e16056823f9 100644 --- a/Documentation/hwmon/max197.rst +++ b/Documentation/hwmon/max197.rst @@ -11,13 +11,13 @@ Supported chips: Prefix: 'max197' - Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX197.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX197.pdf * Maxim MAX199 Prefix: 'max199' - Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX199.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX199.pdf Description ----------- diff --git a/Documentation/hwmon/max20730.rst b/Documentation/hwmon/max20730.rst index cb0c95b2b1f6d..0ce473bca889b 100644 --- a/Documentation/hwmon/max20730.rst +++ b/Documentation/hwmon/max20730.rst @@ -11,7 +11,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX20710.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max20710.pdf * Maxim MAX20730 @@ -19,7 +19,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX20730.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max20730.pdf * Maxim MAX20734 @@ -27,7 +27,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX20734.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max20734.pdf * Maxim MAX20743 @@ -35,7 +35,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX20743.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max20743.pdf Author: Guenter Roeck diff --git a/Documentation/hwmon/max31722.rst b/Documentation/hwmon/max31722.rst index 0ab15c00b226f..b9d176ee7a691 100644 --- a/Documentation/hwmon/max31722.rst +++ b/Documentation/hwmon/max31722.rst @@ -11,7 +11,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX31722-MAX31723.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max31722-max31723.pdf * Maxim Integrated MAX31723 @@ -21,7 +21,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX31722-MAX31723.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max31722-max31723.pdf Author: Tiberiu Breana diff --git a/Documentation/hwmon/max31730.rst b/Documentation/hwmon/max31730.rst index def0de19dbd2b..1c5a32b641879 100644 --- a/Documentation/hwmon/max31730.rst +++ b/Documentation/hwmon/max31730.rst @@ -9,7 +9,7 @@ Supported chips: Addresses scanned: 0x1c, 0x1d, 0x1e, 0x1f, 0x4c, 0x4d, 0x4e, 0x4f - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX31730.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max31730.pdf Author: Guenter Roeck diff --git a/Documentation/hwmon/max31785.rst b/Documentation/hwmon/max31785.rst index c8c6756d0ee1e..92817436759ed 100644 --- a/Documentation/hwmon/max31785.rst +++ b/Documentation/hwmon/max31785.rst @@ -9,7 +9,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max31785.pdf Author: Andrew Jeffery diff --git a/Documentation/hwmon/max31790.rst b/Documentation/hwmon/max31790.rst index 33c5c7330efc9..b8af2d907b6e1 100644 --- a/Documentation/hwmon/max31790.rst +++ b/Documentation/hwmon/max31790.rst @@ -9,7 +9,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://pdfserv.maximintegrated.com/en/ds/MAX31790.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX31790.pdf Author: Il Han diff --git a/Documentation/hwmon/max31827.rst b/Documentation/hwmon/max31827.rst index 6cc5088b26b73..ddd0395290770 100644 --- a/Documentation/hwmon/max31827.rst +++ b/Documentation/hwmon/max31827.rst @@ -11,7 +11,7 @@ Supported chips: Addresses scanned: I2C 0x40 - 0x5f - Datasheet: Publicly available at the Analog Devices website + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX31827-MAX31829.pdf * Maxim MAX31828 @@ -19,7 +19,7 @@ Supported chips: Addresses scanned: I2C 0x40 - 0x5f - Datasheet: Publicly available at the Analog Devices website + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX31827-MAX31829.pdf * Maxim MAX31829 @@ -27,7 +27,7 @@ Supported chips: Addresses scanned: I2C 0x40 - 0x5f - Datasheet: Publicly available at the Analog Devices website + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX31827-MAX31829.pdf Authors: diff --git a/Documentation/hwmon/max34440.rst b/Documentation/hwmon/max34440.rst index 8591a7152ce58..d6d4fbc863d96 100644 --- a/Documentation/hwmon/max34440.rst +++ b/Documentation/hwmon/max34440.rst @@ -11,13 +11,21 @@ Supported chips: Datasheet: - + * ADI ADPM12200 + + Prefixes: 'adpm12200' + + Addresses scanned: - + + Datasheet: - + * Maxim MAX34440 Prefixes: 'max34440' Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX34440.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max34440.pdf * Maxim MAX34441 @@ -27,7 +35,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX34441.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max34441.pdf * Maxim MAX34446 @@ -37,7 +45,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX34446.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max34446.pdf * Maxim MAX34451 @@ -47,7 +55,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX34451.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max34451.pdf * Maxim MAX34460 @@ -57,7 +65,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX34460.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max34460.pdf * Maxim MAX34461 @@ -67,7 +75,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX34461.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max34461.pdf Author: Guenter Roeck @@ -79,10 +87,11 @@ This driver supports multiple devices: hardware monitoring for Maxim MAX34440 PMBus 6-Channel Power-Supply Manager, MAX34441 PMBus 5-Channel Power-Supply Manager and Intelligent Fan Controller, and MAX34446 PMBus Power-Supply Data Logger; PMBus Voltage Monitor and Sequencers for MAX34451, MAX34460, and -MAX34461; PMBus DC/DC Power Module ADPM12160. The MAX34451 supports monitoring -voltage or current of 12 channels based on GIN pins. The MAX34460 supports 12 -voltage channels, and the MAX34461 supports 16 voltage channels. The ADPM1260 -also monitors both input and output of voltage and current. +MAX34461; PMBus DC/DC Power Module ADPM12160, and ADPM12200. The MAX34451 +supports monitoring voltage or current of 12 channels based on GIN pins. The +MAX34460 supports 12 voltage channels, and the MAX34461 supports 16 voltage +channels. The ADPM12160, and ADPM12200 also monitors both input and output +of voltage and current. The driver is a client driver to the core PMBus driver. Please see Documentation/hwmon/pmbus.rst for details on PMBus client drivers. @@ -140,7 +149,8 @@ in[1-6]_reset_history Write any value to reset history. .. note:: - MAX34446 only supports in[1-4]. - - ADPM12160 only supports in[1-2]. Label is "vin1" and "vout1" respectively. + - ADPM12160, and ADPM12200 only supports in[1-2]. Label is "vin1" + and "vout1" respectively. Curr ~~~~ @@ -162,7 +172,8 @@ curr[1-6]_reset_history Write any value to reset history. - in6 and curr6 attributes only exist for MAX34440. - MAX34446 only supports curr[1-4]. - - For ADPM12160, curr[1] is "iin1" and curr[2-6] are "iout[1-5]. + - For ADPM12160, and ADPM12200, curr[1] is "iin1" and curr[2-6] + are "iout[1-5]". Power ~~~~~ @@ -198,7 +209,7 @@ temp[1-8]_reset_history Write any value to reset history. .. note:: - temp7 and temp8 attributes only exist for MAX34440. - MAX34446 only supports temp[1-3]. - - ADPM12160 only supports temp[1]. + - ADPM12160, and ADPM12200 only supports temp[1]. .. note:: diff --git a/Documentation/hwmon/max6639.rst b/Documentation/hwmon/max6639.rst index c85d285a3489d..492c13a5880d3 100644 --- a/Documentation/hwmon/max6639.rst +++ b/Documentation/hwmon/max6639.rst @@ -9,7 +9,7 @@ Supported chips: Addresses scanned: I2C 0x2c, 0x2e, 0x2f - Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX6639-MAX6639F.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6639-max6639f.pdf Authors: - He Changqing diff --git a/Documentation/hwmon/max6650.rst b/Documentation/hwmon/max6650.rst index 7952b6ecaa2df..427f353c5e9c8 100644 --- a/Documentation/hwmon/max6650.rst +++ b/Documentation/hwmon/max6650.rst @@ -9,7 +9,7 @@ Supported chips: Addresses scanned: none - Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6650-MAX6651.pdf * Maxim MAX6651 @@ -17,7 +17,7 @@ Supported chips: Addresses scanned: none - Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6650-MAX6651.pdf Authors: - Hans J. Koch diff --git a/Documentation/hwmon/max6697.rst b/Documentation/hwmon/max6697.rst index 90ca224c446ae..5b37ff08ff449 100644 --- a/Documentation/hwmon/max6697.rst +++ b/Documentation/hwmon/max6697.rst @@ -7,61 +7,61 @@ Supported chips: Prefix: 'max6581' - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6581.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6581.pdf * Maxim MAX6602 Prefix: 'max6602' - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6602.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6602.pdf * Maxim MAX6622 Prefix: 'max6622' - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6622.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6622.pdf * Maxim MAX6636 Prefix: 'max6636' - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6636.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6636.pdf * Maxim MAX6689 Prefix: 'max6689' - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6689.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6689.pdf * Maxim MAX6693 Prefix: 'max6693' - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6693.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6693.pdf * Maxim MAX6694 Prefix: 'max6694' - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6694.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6694.pdf * Maxim MAX6697 Prefix: 'max6697' - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6697.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6697.pdf * Maxim MAX6698 Prefix: 'max6698' - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6698.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6698.pdf * Maxim MAX6699 Prefix: 'max6699' - Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX6699.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6699.pdf Author: diff --git a/Documentation/hwmon/max77705.rst b/Documentation/hwmon/max77705.rst index 4a7680a340e1b..5202de614647c 100644 --- a/Documentation/hwmon/max77705.rst +++ b/Documentation/hwmon/max77705.rst @@ -11,7 +11,9 @@ Supported chips: Addresses scanned: none - Datasheet: Not available + Datasheet: + + https://www.analog.com/media/en/technical-documentation/data-sheets/max77505.pdf Authors: - Dzmitry Sankouski diff --git a/Documentation/hwmon/max8688.rst b/Documentation/hwmon/max8688.rst index 71e7f2cbe2e20..71b6b9ee90ab0 100644 --- a/Documentation/hwmon/max8688.rst +++ b/Documentation/hwmon/max8688.rst @@ -9,7 +9,7 @@ Supported chips: Addresses scanned: - - Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8688.pdf + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max8688.pdf Author: Guenter Roeck diff --git a/Documentation/hwmon/mp2925.rst b/Documentation/hwmon/mp2925.rst new file mode 100644 index 0000000000000..63eda215b6cb4 --- /dev/null +++ b/Documentation/hwmon/mp2925.rst @@ -0,0 +1,151 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Kernel driver mp2925 +==================== + +Supported chips: + + * MPS mp2925 + + Prefix: 'mp2925' + + * MPS mp2929 + + Prefix: 'mp2929' + +Author: + + Wensheng Wang + +Description +----------- + +This driver implements support for Monolithic Power Systems, Inc. (MPS) +MP2925 Dual Loop Digital Multi-phase Controller. + +Device compliant with: + +- PMBus rev 1.3 interface. + +The driver exports the following attributes via the 'sysfs' files +for input voltage: + +**in1_input** + +**in1_label** + +**in1_crit** + +**in1_crit_alarm** + +**in1_lcrit** + +**in1_lcrit_alarm** + +**in1_max** + +**in1_max_alarm** + +**in1_min** + +**in1_min_alarm** + +The driver provides the following attributes for output voltage: + +**in2_input** + +**in2_label** + +**in2_crit** + +**in2_crit_alarm** + +**in2_lcrit** + +**in2_lcrit_alarm** + +**in3_input** + +**in3_label** + +**in3_crit** + +**in3_crit_alarm** + +**in3_lcrit** + +**in3_lcrit_alarm** + +The driver provides the following attributes for input current: + +**curr1_input** + +**curr1_label** + +The driver provides the following attributes for output current: + +**curr2_input** + +**curr2_label** + +**curr2_crit** + +**curr2_crit_alarm** + +**curr2_max** + +**curr2_max_alarm** + +**curr3_input** + +**curr3_label** + +**curr3_crit** + +**curr3_crit_alarm** + +**curr3_max** + +**curr3_max_alarm** + +The driver provides the following attributes for input power: + +**power1_input** + +**power1_label** + +**power2_input** + +**power2_label** + +The driver provides the following attributes for output power: + +**power3_input** + +**power3_label** + +**power4_input** + +**power4_label** + +The driver provides the following attributes for temperature: + +**temp1_input** + +**temp1_crit** + +**temp1_crit_alarm** + +**temp1_max** + +**temp1_max_alarm** + +**temp2_input** + +**temp2_crit** + +**temp2_crit_alarm** + +**temp2_max** + +**temp2_max_alarm** diff --git a/Documentation/hwmon/mp9945.rst b/Documentation/hwmon/mp9945.rst new file mode 100644 index 0000000000000..f406f96efcf9a --- /dev/null +++ b/Documentation/hwmon/mp9945.rst @@ -0,0 +1,117 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Kernel driver mp9945 +===================== + +Supported chips: + + * MPS mp9945 + + Prefix: 'mp9945' + +Author: + + Cosmo Chou + +Description +----------- + +This driver implements support for Monolithic Power Systems, Inc. (MPS) +MP9945 Digital Single-phase Controller. + +Device compliant with: + +- PMBus rev 1.3 interface. + +The driver exports the following attributes via the 'sysfs' files +for input voltage: + +**in1_input** + +**in1_label** + +**in1_crit** + +**in1_crit_alarm** + +**in1_lcrit** + +**in1_lcrit_alarm** + +**in1_max** + +**in1_max_alarm** + +**in1_min** + +**in1_min_alarm** + +The driver provides the following attributes for output voltage: + +**in2_input** + +**in2_label** + +**in2_crit** + +**in2_crit_alarm** + +**in2_lcrit** + +**in2_lcrit_alarm** + +**in2_min** + +**in2_min_alarm** + +The driver provides the following attributes for input current: + +**curr1_input** + +**curr1_label** + +**curr1_max** + +**curr1_max_alarm** + +The driver provides the following attributes for output current: + +**curr2_input** + +**curr2_label** + +**curr2_crit** + +**curr2_crit_alarm** + +**curr2_max** + +**curr2_max_alarm** + +The driver provides the following attributes for input power: + +**power1_input** + +**power1_label** + +The driver provides the following attributes for output power: + +**power2_input** + +**power2_label** + +**power2_max** + +**power2_max_alarm** + +The driver provides the following attributes for temperature: + +**temp1_input** + +**temp1_crit** + +**temp1_crit_alarm** + +**temp1_max** + +**temp1_max_alarm** diff --git a/Documentation/hwmon/pmbus.rst b/Documentation/hwmon/pmbus.rst index d477124cf67fc..a8e01a5b96da3 100644 --- a/Documentation/hwmon/pmbus.rst +++ b/Documentation/hwmon/pmbus.rst @@ -74,7 +74,7 @@ Supported chips: Datasheet: - Not published + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX20796.pdf * Generic PMBus devices diff --git a/Documentation/hwmon/sy7636a-hwmon.rst b/Documentation/hwmon/sy7636a-hwmon.rst index c85db7b329415..0143ce0e5db76 100644 --- a/Documentation/hwmon/sy7636a-hwmon.rst +++ b/Documentation/hwmon/sy7636a-hwmon.rst @@ -17,10 +17,10 @@ the Silergy SY7636A PMIC. The following sensors are supported * Temperature - - SoC on-die temperature in milli-degree C + - Temperature of external NTC in milli-degree C sysfs-Interface --------------- temp0_input - - SoC on-die temperature (milli-degree C) + - Temperature of external NTC (milli-degree C) diff --git a/Documentation/hwmon/tsc1641.rst b/Documentation/hwmon/tsc1641.rst new file mode 100644 index 0000000000000..425e25f7a7d15 --- /dev/null +++ b/Documentation/hwmon/tsc1641.rst @@ -0,0 +1,87 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +Kernel driver tsc1641 +===================== + +Supported chips: + + * ST TSC1641 + + Prefix: 'tsc1641' + + Addresses scanned: - + + Datasheet: + https://www.st.com/resource/en/datasheet/tsc1641.pdf + +Author: + - Igor Reznichenko + + +Description +----------- + +The TSC1641 is a high-precision current, voltage, power, and temperature +monitoring analog front-end (AFE). It monitors bidirectional current into a +shunt resistor and load voltage up to 60 V in a synchronized way. Digital bus +interface is I2C/SMbus. The TSC1641 allows the assertion of several alerts +regarding the voltage, current, power and temperature. + +Usage Notes +----------- + +The TSC1641 driver requires the value of the external shunt resistor to +correctly compute current and power measurements. The resistor value, in +micro-ohms, should be provided either through the device tree property +"shunt-resistor-micro-ohms" or via writable sysfs attribute "shunt_resistor". +Please refer to the Documentation/devicetree/bindings/hwmon/st,tsc1641.yaml +for bindings if the device tree is used. + +Supported range of shunt resistor values is from 100 uOhm to 655.35 mOhm, in +10 uOhm steps. +When selecting the value keep in mind device maximum DC power measurement is +1600W. See datasheet p.22 for ST recommendations on selecting shunt value. + +If the shunt resistor value is not specified in the device tree, the driver +initializes it to 1000 uOhm by default. Users may configure the correct shunt +resistor value at runtime by writing to the "shunt_resistor" sysfs attribute. + +The driver only supports continuous operating mode. +Measurement ranges: + +================ =============================================================== +Current Bidirectional, dependent on shunt +Bus voltage 0-60V +Maximum DC power 1600W +Temperature -40C to +125C +================ =============================================================== + +Sysfs entries +------------- + +==================== =========================================================== +in0_input bus voltage (mV) +in0_max bus voltage max alarm limit (mV) +in0_max_alarm bus voltage max alarm limit exceeded +in0_min bus voltage min alarm limit (mV) +in0_min_alarm bus voltage min alarm limit exceeded + +curr1_input current measurement (mA) +curr1_max current max alarm limit (mA) +curr1_max_alarm current max alarm limit exceeded +curr1_min current min alarm limit (mA) +curr1_min_alarm current min alarm limit exceeded + +power1_input power measurement (uW) +power1_max power max alarm limit (uW) +power1_max_alarm power max alarm limit exceeded + +shunt_resistor shunt resistor value (uOhms) + +temp1_input temperature measurement (mdegC) +temp1_max temperature max alarm limit (mdegC) +temp1_max_alarm temperature max alarm limit exceeded + +update_interval data conversion time (1 - 33ms), longer conversion time + corresponds to higher effective resolution in bits +==================== =========================================================== \ No newline at end of file diff --git a/Documentation/hwmon/zl6100.rst b/Documentation/hwmon/zl6100.rst index d42ed9d3ac69a..1513c9d2d461a 100644 --- a/Documentation/hwmon/zl6100.rst +++ b/Documentation/hwmon/zl6100.rst @@ -9,7 +9,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://www.renesas.com/us/en/document/dst/zl2004-datasheet.pdf + Datasheet: https://www.renesas.com/us/en/document/dst/zl2004-datasheet * Renesas / Intersil / Zilker Labs ZL2005 @@ -17,7 +17,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://www.renesas.com/us/en/document/dst/zl2005-datasheet.pdf + Datasheet: https://www.renesas.com/us/en/document/dst/zl2005-datasheet * Renesas / Intersil / Zilker Labs ZL2006 @@ -25,7 +25,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://www.renesas.com/us/en/document/dst/zl2006-datasheet.pdf + Datasheet: https://www.renesas.com/us/en/document/dst/zl2006-datasheet * Renesas / Intersil / Zilker Labs ZL2008 @@ -33,7 +33,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://www.renesas.com/us/en/document/dst/zl2008-datasheet.pdf + Datasheet: https://www.renesas.com/us/en/document/dst/zl2008-datasheet * Renesas / Intersil / Zilker Labs ZL2105 @@ -41,7 +41,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://www.renesas.com/us/en/document/dst/zl2105-datasheet.pdf + Datasheet: https://www.renesas.com/us/en/document/dst/zl2105-datasheet * Renesas / Intersil / Zilker Labs ZL2106 @@ -49,7 +49,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://www.renesas.com/us/en/document/dst/zl2106-datasheet.pdf + Datasheet: https://www.renesas.com/us/en/document/dst/zl2106-datasheet * Renesas / Intersil / Zilker Labs ZL6100 @@ -57,7 +57,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://www.renesas.com/us/en/document/dst/zl6100-datasheet.pdf + Datasheet: https://www.renesas.com/us/en/document/dst/zl6100-datasheet * Renesas / Intersil / Zilker Labs ZL6105 @@ -65,7 +65,7 @@ Supported chips: Addresses scanned: - - Datasheet: https://www.renesas.com/us/en/document/dst/zl6105-datasheet.pdf + Datasheet: https://www.renesas.com/us/en/document/dst/zl6105-datasheet * Renesas / Intersil / Zilker Labs ZL8802 diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst index 36c563ad3f068..bbbce90eb7d84 100644 --- a/Documentation/i2c/busses/i2c-i801.rst +++ b/Documentation/i2c/busses/i2c-i801.rst @@ -51,6 +51,8 @@ Supported adapters: * Intel Arrow Lake (SOC) * Intel Panther Lake (SOC) * Intel Wildcat Lake (SOC) + * Intel Diamond Rapids (SOC) + * Intel Nova Lake (PCH) Datasheets: Publicly available at the Intel website diff --git a/Documentation/iio/ade9000.rst b/Documentation/iio/ade9000.rst index 43d4b8dc1cb72..c9ff702a42512 100644 --- a/Documentation/iio/ade9000.rst +++ b/Documentation/iio/ade9000.rst @@ -264,5 +264,5 @@ Configure RMS voltage event thresholds (requires interrupts): 8. IIO Interfacing Tools ======================== -See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO +See Documentation/iio/iio_tools.rst for the description of the available IIO interfacing tools. diff --git a/Documentation/iio/adis16475.rst b/Documentation/iio/adis16475.rst index 4bf0998be36ef..89a388490ab73 100644 --- a/Documentation/iio/adis16475.rst +++ b/Documentation/iio/adis16475.rst @@ -374,11 +374,11 @@ Obtain buffered data: 00001740 01 1a 00 00 ff ff fe 31 00 00 46 aa 00 03 37 f7 |.......1..F...7.| ... -See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered +See Documentation/iio/iio_devbuf.rst for more information about how buffered data is structured. 4. IIO Interfacing Tools ======================== -See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO +See Documentation/iio/iio_tools.rst for the description of the available IIO interfacing tools. diff --git a/Documentation/iio/adis16480.rst b/Documentation/iio/adis16480.rst index 4a2d40e0daa79..cce5f3e017415 100644 --- a/Documentation/iio/adis16480.rst +++ b/Documentation/iio/adis16480.rst @@ -436,11 +436,11 @@ Obtain buffered data:: 00006b60 09 63 00 00 00 00 1b 13 00 00 22 2f 00 03 23 91 |.c........"/..#.| ... -See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered +See Documentation/iio/iio_devbuf.rst for more information about how buffered data is structured. 4. IIO Interfacing Tools ======================== -See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO +See Documentation/iio/iio_tools.rst for the description of the available IIO interfacing tools. diff --git a/Documentation/iio/adis16550.rst b/Documentation/iio/adis16550.rst index 25db7b8060c42..c9bbc0a857b03 100644 --- a/Documentation/iio/adis16550.rst +++ b/Documentation/iio/adis16550.rst @@ -366,11 +366,11 @@ Obtain buffered data: 0000ceb0 00 00 0d 2f 00 00 05 25 00 00 07 8d 00 00 a2 ce |.../...%........| ... -See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered +See Documentation/iio/iio_devbuf.rst for more information about how buffered data is structured. 4. IIO Interfacing Tools ======================== -See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO +See Documentation/iio/iio_tools.rst for the description of the available IIO interfacing tools. diff --git a/Documentation/iio/adxl345.rst b/Documentation/iio/adxl345.rst index afdb35f8b72e7..bb19d64f67c3d 100644 --- a/Documentation/iio/adxl345.rst +++ b/Documentation/iio/adxl345.rst @@ -433,11 +433,11 @@ Obtain buffered data: 00000f0 00004 00014 00015 00005 00012 00011 00005 00012 ... -See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered +See Documentation/iio/iio_devbuf.rst for more information about how buffered data is structured. 4. IIO Interfacing Tools ======================== -See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO +See Documentation/iio/iio_tools.rst for the description of the available IIO interfacing tools. diff --git a/Documentation/iio/adxl380.rst b/Documentation/iio/adxl380.rst index 66c8a4d4f767e..61cafa2f98bf3 100644 --- a/Documentation/iio/adxl380.rst +++ b/Documentation/iio/adxl380.rst @@ -223,11 +223,11 @@ Obtain buffered data: 002bc3c0 f7 fd 00 cb fb 94 24 80 f7 e3 00 f2 fb b8 24 80 |......$.......$.| ... -See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered +See Documentation/iio/iio_devbuf.rst for more information about how buffered data is structured. 4. IIO Interfacing Tools ======================== -See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO +See Documentation/iio/iio_tools.rst for the description of the available IIO interfacing tools. diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst index 4424cbff251f8..77a6c9b3956d5 100644 --- a/Documentation/input/event-codes.rst +++ b/Documentation/input/event-codes.rst @@ -241,6 +241,12 @@ A few EV_ABS codes have special meanings: emitted only when the selected profile changes, indicating the newly selected profile value. +* ABS_SND_PROFILE: + + - Used to describe the state of a multi-value sound profile switch. + An event is emitted only when the selected profile changes, + indicating the newly selected profile value. + * ABS_MT_: - Used to describe multitouch input events. Please see diff --git a/Documentation/leds/leds-lp5521.rst b/Documentation/leds/leds-lp5521.rst index 0432615b083d6..4c838c88820ef 100644 --- a/Documentation/leds/leds-lp5521.rst +++ b/Documentation/leds/leds-lp5521.rst @@ -22,7 +22,7 @@ More details of the instructions can be found from the public data sheet. LP5521 has the internal program memory for running various LED patterns. There are two ways to run LED patterns. -1) Legacy interface - enginex_mode and enginex_load +1) sysfs interface - enginex_mode and enginex_load Control interface for the engines: x is 1 .. 3 diff --git a/Documentation/leds/leds-lp5523.rst b/Documentation/leds/leds-lp5523.rst index 7d7362a1dd575..f5a87b07514ac 100644 --- a/Documentation/leds/leds-lp5523.rst +++ b/Documentation/leds/leds-lp5523.rst @@ -35,7 +35,7 @@ If both fields are NULL, 'lp5523' is used by default. LP5523 has the internal program memory for running various LED patterns. There are two ways to run LED patterns. -1) Legacy interface - enginex_mode, enginex_load and enginex_leds +1) sysfs interface - enginex_mode, enginex_load and enginex_leds Control interface for the engines: diff --git a/Documentation/maintainer/maintainer-entry-profile.rst b/Documentation/maintainer/maintainer-entry-profile.rst index d36dd892a78ad..6020d188e13de 100644 --- a/Documentation/maintainer/maintainer-entry-profile.rst +++ b/Documentation/maintainer/maintainer-entry-profile.rst @@ -110,5 +110,6 @@ to do something different in the near future. ../process/maintainer-netdev ../driver-api/vfio-pci-device-specific-driver-acceptance ../nvme/feature-and-quirk-policy + ../filesystems/nfs/nfsd-maintainer-entry-profile ../filesystems/xfs/xfs-maintainer-entry-profile ../mm/damon/maintainer-profile diff --git a/Documentation/mm/damon/design.rst b/Documentation/mm/damon/design.rst index 80354f4f42bac..2d8d8ca1e0a32 100644 --- a/Documentation/mm/damon/design.rst +++ b/Documentation/mm/damon/design.rst @@ -381,8 +381,8 @@ That is, assumes 4% (20% of 20%) DAMON-observed access events ratio (source) to capture 64% (80% multipled by 80%) real access events (outcomes). To know how user-space can use this feature via :ref:`DAMON sysfs interface -`, refer to :ref:`intervals_goal ` part of -the documentation. +`, refer to :ref:`intervals_goal +` part of the documentation. .. _damon_design_damos: @@ -564,9 +564,9 @@ aggressiveness (the quota) of the corresponding scheme. For example, if DAMOS is under achieving the goal, DAMOS automatically increases the quota. If DAMOS is over achieving the goal, it decreases the quota. -The goal can be specified with four parameters, namely ``target_metric``, -``target_value``, ``current_value`` and ``nid``. The auto-tuning mechanism -tries to make ``current_value`` of ``target_metric`` be same to +The goal can be specified with five parameters, namely ``target_metric``, +``target_value``, ``current_value``, ``nid`` and ``path``. The auto-tuning +mechanism tries to make ``current_value`` of ``target_metric`` be same to ``target_value``. - ``user_input``: User-provided value. Users could use any metric that they @@ -581,9 +581,18 @@ tries to make ``current_value`` of ``target_metric`` be same to set by users at the initial time. In other words, DAMOS does self-feedback. - ``node_mem_used_bp``: Specific NUMA node's used memory ratio in bp (1/10,000). - ``node_mem_free_bp``: Specific NUMA node's free memory ratio in bp (1/10,000). - -``nid`` is optionally required for only ``node_mem_used_bp`` and -``node_mem_free_bp`` to point the specific NUMA node. +- ``node_memcg_used_bp``: Specific cgroup's node used memory ratio for a + specific NUMA node, in bp (1/10,000). +- ``node_memcg_free_bp``: Specific cgroup's node unused memory ratio for a + specific NUMA node, in bp (1/10,000). + +``nid`` is optionally required for only ``node_mem_used_bp``, +``node_mem_free_bp``, ``node_memcg_used_bp`` and ``node_memcg_free_bp`` to +point the specific NUMA node. + +``path`` is optionally required for only ``node_memcg_used_bp`` and +``node_memcg_free_bp`` to point the path to the cgroup. The value should be +the path of the memory cgroup from the cgroups mount point. To know how user-space can set the tuning goal metric, the target value, and/or the current value via :ref:`DAMON sysfs interface `, refer to diff --git a/Documentation/mm/damon/maintainer-profile.rst b/Documentation/mm/damon/maintainer-profile.rst index 58a3fb3c57626..e761edada1e9d 100644 --- a/Documentation/mm/damon/maintainer-profile.rst +++ b/Documentation/mm/damon/maintainer-profile.rst @@ -27,8 +27,8 @@ maintainer. Note again the patches for `mm-new tree `_ are queued by the memory management -subsystem maintainer. If the patches requires some patches in `damon/next tree -`_ which not yet merged in mm-new, +subsystem maintainer. If the patches require some patches in `damon/next tree +`_ which have not yet merged in mm-new, please make sure the requirement is clearly specified. Submit checklist addendum @@ -57,7 +57,7 @@ Key cycle dates Patches can be sent anytime. Key cycle dates of the `mm-new `_, `mm-unstable -`_and `mm-stable +`_ and `mm-stable `_ trees depend on the memory management subsystem maintainer. @@ -99,5 +99,5 @@ Schedules and reservation status are available at the Google `doc `_. There is also a public Google `calendar `_ -that has the events. Anyone can subscribe it. DAMON maintainer will also -provide periodic reminder to the mailing list (damon@lists.linux.dev). +that has the events. Anyone can subscribe to it. DAMON maintainer will also +provide periodic reminders to the mailing list (damon@lists.linux.dev). diff --git a/Documentation/mm/index.rst b/Documentation/mm/index.rst index ba6a8872849ba..7aa2a88869083 100644 --- a/Documentation/mm/index.rst +++ b/Documentation/mm/index.rst @@ -48,6 +48,7 @@ documentation, or deleted if it has served its purpose. hugetlbfs_reserv ksm memory-model + memfd_preservation mmu_notifier multigen_lru numa diff --git a/Documentation/mm/memfd_preservation.rst b/Documentation/mm/memfd_preservation.rst new file mode 100644 index 0000000000000..66e0fb6d5ef0e --- /dev/null +++ b/Documentation/mm/memfd_preservation.rst @@ -0,0 +1,23 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +========================== +Memfd Preservation via LUO +========================== + +.. kernel-doc:: mm/memfd_luo.c + :doc: Memfd Preservation via LUO + +Memfd Preservation ABI +====================== + +.. kernel-doc:: include/linux/kho/abi/memfd.h + :doc: DOC: memfd Live Update ABI + +.. kernel-doc:: include/linux/kho/abi/memfd.h + :internal: + +See Also +======== + +- :doc:`/core-api/liveupdate` +- :doc:`/core-api/kho/concepts` diff --git a/Documentation/mm/memory-model.rst b/Documentation/mm/memory-model.rst index 5f3eafbbc5203..7957122039e87 100644 --- a/Documentation/mm/memory-model.rst +++ b/Documentation/mm/memory-model.rst @@ -165,7 +165,7 @@ The users of `ZONE_DEVICE` are: * pmem: Map platform persistent memory to be used as a direct-I/O target via DAX mappings. -* hmm: Extend `ZONE_DEVICE` with `->page_fault()` and `->page_free()` +* hmm: Extend `ZONE_DEVICE` with `->page_fault()` and `->folio_free()` event callbacks to allow a device-driver to coordinate memory management events related to device-memory, typically GPU memory. See Documentation/mm/hmm.rst. diff --git a/Documentation/mm/page_owner.rst b/Documentation/mm/page_owner.rst index 3a45a20fc05a1..6b12f3b007ec9 100644 --- a/Documentation/mm/page_owner.rst +++ b/Documentation/mm/page_owner.rst @@ -27,7 +27,10 @@ enabled. Other usages are more than welcome. It can also be used to show all the stacks and their current number of allocated base pages, which gives us a quick overview of where the memory is going without the need to screen through all the pages and match the -allocation and free operation. +allocation and free operation. It's also possible to show only a numeric +identifier of all the stacks (without stack traces) and their number of +allocated base pages (faster to read and parse, eg, for monitoring) that +can be matched with stacks later (show_handles and show_stacks_handles). page owner is disabled by default. So, if you'd like to use it, you need to add "page_owner=on" to your boot cmdline. If the kernel is built @@ -116,6 +119,33 @@ Usage nr_base_pages: 20824 ... + cat /sys/kernel/debug/page_owner_stacks/show_handles > handles_7000.txt + cat handles_7000.txt + handle: 42 + nr_base_pages: 20824 + ... + + cat /sys/kernel/debug/page_owner_stacks/show_stacks_handles > stacks_handles.txt + cat stacks_handles.txt + post_alloc_hook+0x177/0x1a0 + get_page_from_freelist+0xd01/0xd80 + __alloc_pages+0x39e/0x7e0 + alloc_pages_mpol+0x22e/0x490 + folio_alloc+0xd5/0x110 + filemap_alloc_folio+0x78/0x230 + page_cache_ra_order+0x287/0x6f0 + filemap_get_pages+0x517/0x1160 + filemap_read+0x304/0x9f0 + xfs_file_buffered_read+0xe6/0x1d0 [xfs] + xfs_file_read_iter+0x1f0/0x380 [xfs] + __kernel_read+0x3b9/0x730 + kernel_read_file+0x309/0x4d0 + __do_sys_finit_module+0x381/0x730 + do_syscall_64+0x8d/0x150 + entry_SYSCALL_64_after_hwframe+0x62/0x6a + handle: 42 + ... + cat /sys/kernel/debug/page_owner > page_owner_full.txt ./page_owner_sort page_owner_full.txt sorted_page_owner.txt diff --git a/Documentation/mm/process_addrs.rst b/Documentation/mm/process_addrs.rst index be49e2a269e47..7f2f3e87071df 100644 --- a/Documentation/mm/process_addrs.rst +++ b/Documentation/mm/process_addrs.rst @@ -48,7 +48,8 @@ Terminology * **VMA locks** - The VMA lock is at VMA granularity (of course) which behaves as a read/write semaphore in practice. A VMA read lock is obtained via :c:func:`!lock_vma_under_rcu` (and unlocked via :c:func:`!vma_end_read`) and a - write lock via :c:func:`!vma_start_write` (all VMA write locks are unlocked + write lock via vma_start_write() or vma_start_write_killable() + (all VMA write locks are unlocked automatically when the mmap write lock is released). To take a VMA write lock you **must** have already acquired an :c:func:`!mmap_write_lock`. * **rmap locks** - When trying to access VMAs through the reverse mapping via a @@ -907,3 +908,9 @@ Stack expansion Stack expansion throws up additional complexities in that we cannot permit there to be racing page faults, as a result we invoke :c:func:`!vma_start_write` to prevent this in :c:func:`!expand_downwards` or :c:func:`!expand_upwards`. + +------------------------ +Functions and structures +------------------------ + +.. kernel-doc:: include/linux/mmap_lock.h diff --git a/Documentation/power/power_supply_class.rst b/Documentation/power/power_supply_class.rst index da8e275a14ffb..6d11f8c594a0b 100644 --- a/Documentation/power/power_supply_class.rst +++ b/Documentation/power/power_supply_class.rst @@ -7,35 +7,35 @@ Synopsis Power supply class used to represent battery, UPS, AC or DC power supply properties to user-space. -It defines core set of attributes, which should be applicable to (almost) +It defines a core set of attributes which should be applicable to (almost) every power supply out there. Attributes are available via sysfs and uevent interfaces. -Each attribute has well defined meaning, up to unit of measure used. While +Each attribute has a well-defined meaning, up to the unit of measure used. While the attributes provided are believed to be universally applicable to any power supply, specific monitoring hardware may not be able to provide them all, so any of them may be skipped. -Power supply class is extensible, and allows to define drivers own attributes. -The core attribute set is subject to the standard Linux evolution (i.e. -if it will be found that some attribute is applicable to many power supply -types or their drivers, it can be added to the core set). +The power supply class is extensible and allows drivers to define their own +attributes. The core attribute set is subject to the standard Linux evolution +(i.e., if some attribute is found to be applicable to many power +supply types or their drivers, it can be added to the core set). -It also integrates with LED framework, for the purpose of providing +It also integrates with the LED framework, for the purpose of providing typically expected feedback of battery charging/fully charged status and AC/USB power supply online status. (Note that specific details of the indication (including whether to use it at all) are fully controllable by -user and/or specific machine defaults, per design principles of LED -framework). +user and/or specific machine defaults, per design principles of the LED +framework.) Attributes/properties ~~~~~~~~~~~~~~~~~~~~~ -Power supply class has predefined set of attributes, this eliminates code -duplication across drivers. Power supply class insist on reusing its +The power supply class has a predefined set of attributes. This eliminates code +duplication across drivers. The power supply class insists on reusing its predefined attributes *and* their units. -So, userspace gets predictable set of attributes and their units for any +So, userspace gets a predictable set of attributes and their units for any kind of power supply, and can process/present them to a user in consistent manner. Results for different power supplies and machines are also directly comparable. @@ -61,7 +61,7 @@ Attributes/properties detailed | **Charge/Energy/Capacity - how to not confuse** | +--------------------------------------------------------------------------+ | **Because both "charge" (µAh) and "energy" (µWh) represents "capacity" | -| of battery, this class distinguish these terms. Don't mix them!** | +| of battery, this class distinguishes these terms. Don't mix them!** | | | | - `CHARGE_*` | | attributes represents capacity in µAh only. | @@ -81,7 +81,7 @@ _NOW STATUS this attribute represents operating status (charging, full, - discharging (i.e. powering a load), etc.). This corresponds to + discharging (i.e., powering a load), etc.). This corresponds to `BATTERY_STATUS_*` values, as defined in battery.h. CHARGE_TYPE @@ -92,10 +92,10 @@ CHARGE_TYPE AUTHENTIC indicates the power supply (battery or charger) connected - to the platform is authentic(1) or non authentic(0). + to the platform is authentic(1) or non-authentic(0). HEALTH - represents health of the battery, values corresponds to + represents health of the battery. Values corresponds to POWER_SUPPLY_HEALTH_*, defined in battery.h. VOLTAGE_OCV @@ -103,11 +103,11 @@ VOLTAGE_OCV VOLTAGE_MAX_DESIGN, VOLTAGE_MIN_DESIGN design values for maximal and minimal power supply voltages. - Maximal/minimal means values of voltages when battery considered + Maximal/minimal means values of voltages when battery is considered "full"/"empty" at normal conditions. Yes, there is no direct relation between voltage and battery capacity, but some dumb batteries use voltage for very approximated calculation of capacity. - Battery driver also can use this attribute just to inform userspace + A battery driver also can use this attribute just to inform userspace about maximal and minimal voltage thresholds of a given battery. VOLTAGE_MAX, VOLTAGE_MIN @@ -122,16 +122,16 @@ CURRENT_BOOT Reports the current measured during boot CHARGE_FULL_DESIGN, CHARGE_EMPTY_DESIGN - design charge values, when battery considered full/empty. + design charge values, when battery is considered full/empty. ENERGY_FULL_DESIGN, ENERGY_EMPTY_DESIGN same as above but for energy. CHARGE_FULL, CHARGE_EMPTY - These attributes means "last remembered value of charge when battery - became full/empty". It also could mean "value of charge when battery + These attributes mean "last remembered value of charge when battery + became full/empty". They also could mean "value of charge when battery is considered full/empty at given conditions (temperature, age)". - I.e. these attributes represents real thresholds, not design values. + I.e., these attributes represents real thresholds, not design values. ENERGY_FULL, ENERGY_EMPTY same as above but for energy. @@ -153,12 +153,12 @@ CHARGE_TERM_CURRENT CONSTANT_CHARGE_CURRENT constant charge current programmed by charger. - CONSTANT_CHARGE_CURRENT_MAX maximum charge current supported by the power supply object. CONSTANT_CHARGE_VOLTAGE constant charge voltage programmed by charger. + CONSTANT_CHARGE_VOLTAGE_MAX maximum charge voltage supported by the power supply object. @@ -208,10 +208,10 @@ TEMP_MAX TIME_TO_EMPTY seconds left for battery to be considered empty - (i.e. while battery powers a load) + (i.e., while battery powers a load) TIME_TO_FULL seconds left for battery to be considered full - (i.e. while battery is charging) + (i.e., while battery is charging) Battery <-> external power supply interaction @@ -220,13 +220,13 @@ Often power supplies are acting as supplies and supplicants at the same time. Batteries are good example. So, batteries usually care if they're externally powered or not. -For that case, power supply class implements notification mechanism for +For that case, the power supply class implements a notification mechanism for batteries. -External power supply (AC) lists supplicants (batteries) names in +An external power supply (AC) lists supplicants (batteries) names in "supplied_to" struct member, and each power_supply_changed() call -issued by external power supply will notify supplicants via -external_power_changed callback. +issued by an external power supply will notify supplicants via +the external_power_changed callback. Devicetree battery characteristics @@ -241,14 +241,14 @@ battery node have names corresponding to elements in enum power_supply_property, for naming consistency between sysfs attributes and battery node properties. -QA -~~ +Q&A +~~~ Q: Where is POWER_SUPPLY_PROP_XYZ attribute? A: - If you cannot find attribute suitable for your driver needs, feel free - to add it and send patch along with your driver. + If you cannot find an attribute suitable for your driver needs, feel free + to add it and send a patch along with your driver. The attributes available currently are the ones currently provided by the drivers written. @@ -258,18 +258,18 @@ A: Q: - I have some very specific attribute (e.g. battery color), should I add + I have some very specific attribute (e.g., battery color). Should I add this attribute to standard ones? A: Most likely, no. Such attribute can be placed in the driver itself, if - it is useful. Of course, if the attribute in question applicable to - large set of batteries, provided by many drivers, and/or comes from + it is useful. Of course, if the attribute in question is applicable to + a large set of batteries, provided by many drivers, and/or comes from some general battery specification/standard, it may be a candidate to be added to the core attribute set. Q: - Suppose, my battery monitoring chip/firmware does not provides capacity + Suppose my battery monitoring chip/firmware does not provide capacity in percents, but provides charge_{now,full,empty}. Should I calculate percentage capacity manually, inside the driver, and register CAPACITY attribute? The same question about time_to_empty/time_to_full. @@ -278,11 +278,11 @@ A: directly measurable by the specific hardware available. Inferring not available properties using some heuristics or mathematical - model is not subject of work for a battery driver. Such functionality + model is not a subject of work for a battery driver. Such functionality should be factored out, and in fact, apm_power, the driver to serve - legacy APM API on top of power supply class, uses a simple heuristic of + legacy APM API on top of the power supply class, uses a simple heuristic of approximating remaining battery capacity based on its charge, current, - voltage and so on. But full-fledged battery model is likely not subject - for kernel at all, as it would require floating point calculation to deal - with things like differential equations and Kalman filters. This is + voltage and so on. But a full-fledged battery model is likely not a subject + for the kernel at all, as it would require floating point calculations to + deal with things like differential equations and Kalman filters. This is better be handled by batteryd/libbattery, yet to be written. diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runtime_pm.rst index 8246df3cecd7e..455b9d135d855 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -443,13 +443,11 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: necessary to execute the subsystem-level resume callback for the device to satisfy that request, otherwise 0 is returned - `int pm_runtime_barrier(struct device *dev);` + `void pm_runtime_barrier(struct device *dev);` - check if there's a resume request pending for the device and resume it (synchronously) in that case, cancel any other pending runtime PM requests regarding it and wait for all runtime PM operations on it in progress to - complete; returns 1 if there was a resume request pending and it was - necessary to execute the subsystem-level resume callback for the device to - satisfy that request, otherwise 0 is returned + complete `void pm_suspend_ignore_children(struct device *dev, bool enable);` - set/unset the power.ignore_children flag of the device diff --git a/Documentation/security/landlock.rst b/Documentation/security/landlock.rst index e0fc54aff09e7..3e4d4d04cfae4 100644 --- a/Documentation/security/landlock.rst +++ b/Documentation/security/landlock.rst @@ -7,7 +7,7 @@ Landlock LSM: kernel documentation ================================== :Author: Mickaël Salaün -:Date: March 2025 +:Date: September 2025 Landlock's goal is to create scoped access-control (i.e. sandboxing). To harden a whole system, this feature should be available to any process, @@ -110,6 +110,12 @@ Filesystem .. kernel-doc:: security/landlock/fs.h :identifiers: +Process credential +------------------ + +.. kernel-doc:: security/landlock/cred.h + :identifiers: + Ruleset and domain ------------------ @@ -128,6 +134,9 @@ makes the reasoning much easier and helps avoid pitfalls. .. kernel-doc:: security/landlock/ruleset.h :identifiers: +.. kernel-doc:: security/landlock/domain.h + :identifiers: + Additional documentation ======================== diff --git a/Documentation/tools/rtla/common_options.txt b/Documentation/tools/rtla/common_options.txt index 1c4f3e663cf5b..6caa51d029347 100644 --- a/Documentation/tools/rtla/common_options.txt +++ b/Documentation/tools/rtla/common_options.txt @@ -48,7 +48,7 @@ If not set, tracer threads keep their default priority. For rtla user threads, it is set to SCHED_FIFO with priority 95. For kernel threads, see *osnoise* and *timerlat* tracer documentation for the running kernel version. -**-C**, **--cgroup**\[*=cgroup*] +**-C**, **--cgroup** \[*cgroup*] Set a *cgroup* to the tracer's threads. If the **-C** option is passed without arguments, the tracer's thread will inherit **rtla**'s *cgroup*. Otherwise, the threads will be placed on the *cgroup* passed to the option. diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst index aef674df3afdb..d1f313a5f4ad6 100644 --- a/Documentation/trace/ftrace.rst +++ b/Documentation/trace/ftrace.rst @@ -366,6 +366,14 @@ of ftrace. Here is a list of some of the key files: for each function. The displayed address is the patch-site address and can differ from /proc/kallsyms address. + syscall_user_buf_size: + + Some system call trace events will record the data from a user + space address that one of the parameters point to. The amount of + data per event is limited. This file holds the max number of bytes + that will be recorded into the ring buffer to hold this data. + The max value is currently 165. + dyn_ftrace_total_info: This file is for debugging purposes. The number of functions that diff --git a/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst b/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst index 4a2d3b27aa4d2..aaefeda0e1644 100644 --- a/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst +++ b/Documentation/translations/zh_CN/core-api/irq/irq-domain.rst @@ -109,10 +109,6 @@ irq_domain维护着从hwirq号到Linux IRQ的radix的树状映射。 当一个hw 如果hwirq号可以非常大,树状映射是一个很好的选择,因为它不需要分配一个和最大hwirq 号一样大的表。 缺点是,hwirq到IRQ号的查找取决于表中有多少条目。 -irq_domain_add_tree()和irq_domain_create_tree()在功能上是等价的,除了第一 -个参数不同——前者接受一个Open Firmware特定的 'struct device_node' ,而后者接受 -一个更通用的抽象 'struct fwnode_handle' 。 - 很少有驱动应该需要这个映射。 无映射 diff --git a/Documentation/userspace-api/dma-buf-heaps.rst b/Documentation/userspace-api/dma-buf-heaps.rst index 1dfe5e7acd5a3..05445c83b79a0 100644 --- a/Documentation/userspace-api/dma-buf-heaps.rst +++ b/Documentation/userspace-api/dma-buf-heaps.rst @@ -16,13 +16,52 @@ following heaps: - The ``system`` heap allocates virtually contiguous, cacheable, buffers. - - The ``cma`` heap allocates physically contiguous, cacheable, - buffers. Only present if a CMA region is present. Such a region is - usually created either through the kernel commandline through the - ``cma`` parameter, a memory region Device-Tree node with the - ``linux,cma-default`` property set, or through the ``CMA_SIZE_MBYTES`` or - ``CMA_SIZE_PERCENTAGE`` Kconfig options. The heap's name in devtmpfs is - ``default_cma_region``. For backwards compatibility, when the - ``DMABUF_HEAPS_CMA_LEGACY`` Kconfig option is set, a duplicate node is - created following legacy naming conventions; the legacy name might be - ``reserved``, ``linux,cma``, or ``default-pool``. + - The ``default_cma_region`` heap allocates physically contiguous, + cacheable, buffers. Only present if a CMA region is present. Such a + region is usually created either through the kernel commandline + through the ``cma`` parameter, a memory region Device-Tree node with + the ``linux,cma-default`` property set, or through the + ``CMA_SIZE_MBYTES`` or ``CMA_SIZE_PERCENTAGE`` Kconfig options. Prior + to Linux 6.17, its name wasn't stable and could be called + ``reserved``, ``linux,cma``, or ``default-pool``, depending on the + platform. + + - A heap will be created for each reusable region in the device tree + with the ``shared-dma-pool`` compatible, using the full device tree + node name as its name. The buffer semantics are identical to + ``default-cma-region``. + +Naming Convention +================= + +``dma-buf`` heaps name should meet a number of constraints: + +- The name must be stable, and must not change from one version to the other. + Userspace identifies heaps by their name, so if the names ever change, we + would be likely to introduce regressions. + +- The name must describe the memory region the heap will allocate from, and + must uniquely identify it in a given platform. Since userspace applications + use the heap name as the discriminant, it must be able to tell which heap it + wants to use reliably if there's multiple heaps. + +- The name must not mention implementation details, such as the allocator. The + heap driver will change over time, and implementation details when it was + introduced might not be relevant in the future. + +- The name should describe properties of the buffers that would be allocated. + Doing so will make heap identification easier for userspace. Such properties + are: + + - ``contiguous`` for physically contiguous buffers; + + - ``protected`` for encrypted buffers not accessible the OS; + +- The name may describe intended usage. Doing so will make heap identification + easier for userspace applications and users. + +For example, assuming a platform with a reserved memory region located +at the RAM address 0x42000000, intended to allocate video framebuffers, +physically contiguous, and backed by the CMA kernel allocator, good +names would be ``memory@42000000-contiguous`` or ``video@42000000``, but +``cma-video`` wouldn't. diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst index b8c73be4fb112..8a61ac4c1bf19 100644 --- a/Documentation/userspace-api/index.rst +++ b/Documentation/userspace-api/index.rst @@ -61,6 +61,7 @@ Everything else :maxdepth: 1 ELF + liveupdate netlink/index sysfs-platform_profile vduse diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst index 7c527a01d1cf5..7232b3544cecc 100644 --- a/Documentation/userspace-api/ioctl/ioctl-number.rst +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst @@ -385,6 +385,8 @@ Code Seq# Include File Comments 0xB8 01-02 uapi/misc/mrvl_cn10k_dpi.h Marvell CN10K DPI driver 0xB8 all uapi/linux/mshv.h Microsoft Hyper-V /dev/mshv driver +0xBA 00-0F uapi/linux/liveupdate.h Pasha Tatashin + 0xC0 00-0F linux/usb/iowarrior.h 0xCA 00-0F uapi/misc/cxl.h Dead since 6.15 0xCA 10-2F uapi/misc/ocxl.h diff --git a/Documentation/userspace-api/liveupdate.rst b/Documentation/userspace-api/liveupdate.rst new file mode 100644 index 0000000000000..41c0473e4f160 --- /dev/null +++ b/Documentation/userspace-api/liveupdate.rst @@ -0,0 +1,20 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================ +Live Update uAPI +================ +:Author: Pasha Tatashin + +ioctl interface +=============== +.. kernel-doc:: kernel/liveupdate/luo_core.c + :doc: LUO ioctl Interface + +ioctl uAPI +=========== +.. kernel-doc:: include/uapi/linux/liveupdate.h + +See Also +======== + +- :doc:`Live Update Orchestrator ` diff --git a/Documentation/userspace-api/media/drivers/index.rst b/Documentation/userspace-api/media/drivers/index.rst index d706cb47b1122..02967c9b18d6e 100644 --- a/Documentation/userspace-api/media/drivers/index.rst +++ b/Documentation/userspace-api/media/drivers/index.rst @@ -32,6 +32,7 @@ For more details see the file COPYING in the source distribution of Linux. cx2341x-uapi dw100 imx-uapi + mali-c55 max2175 npcm-video omap3isp-uapi diff --git a/Documentation/userspace-api/media/drivers/mali-c55.rst b/Documentation/userspace-api/media/drivers/mali-c55.rst new file mode 100644 index 0000000000000..21148b1878566 --- /dev/null +++ b/Documentation/userspace-api/media/drivers/mali-c55.rst @@ -0,0 +1,55 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +Arm Mali-C55 ISP driver +======================= + +The Arm Mali-C55 ISP driver implements a single driver-specific control: + +``V4L2_CID_MALI_C55_CAPABILITIES (bitmask)`` + Detail the capabilities of the ISP by giving detail about the fitted blocks. + + .. flat-table:: Bitmask meaning definitions + :header-rows: 1 + :widths: 2 4 8 + + * - Bit + - Macro + - Meaning + * - 0 + - MALI_C55_PONG + - Pong configuration space is fitted in the ISP + * - 1 + - MALI_C55_WDR + - WDR Framestitch, offset and gain is fitted in the ISP + * - 2 + - MALI_C55_COMPRESSION + - Temper compression is fitted in the ISP + * - 3 + - MALI_C55_TEMPER + - Temper is fitted in the ISP + * - 4 + - MALI_C55_SINTER_LITE + - Sinter Lite is fitted in the ISP instead of the full Sinter version + * - 5 + - MALI_C55_SINTER + - Sinter is fitted in the ISP + * - 6 + - MALI_C55_IRIDIX_LTM + - Iridix local tone mappine is fitted in the ISP + * - 7 + - MALI_C55_IRIDIX_GTM + - Iridix global tone mapping is fitted in the ISP + * - 8 + - MALI_C55_CNR + - Colour noise reduction is fitted in the ISP + * - 9 + - MALI_C55_FRSCALER + - The full resolution pipe scaler is fitted in the ISP + * - 10 + - MALI_C55_DS_PIPE + - The downscale pipe is fitted in the ISP + + The Mali-C55 ISP can be configured in a number of ways to include or exclude + blocks which may not be necessary. This control provides a way for the + driver to communicate to userspace which of the blocks are fitted in the + design. \ No newline at end of file diff --git a/Documentation/userspace-api/media/v4l/meta-formats.rst b/Documentation/userspace-api/media/v4l/meta-formats.rst index d9868ee88a071..3e0cab153f0ac 100644 --- a/Documentation/userspace-api/media/v4l/meta-formats.rst +++ b/Documentation/userspace-api/media/v4l/meta-formats.rst @@ -13,6 +13,7 @@ These formats are used for the :ref:`metadata` interface only. .. toctree:: :maxdepth: 1 + metafmt-arm-mali-c55 metafmt-c3-isp metafmt-d4xx metafmt-generic @@ -25,3 +26,4 @@ These formats are used for the :ref:`metadata` interface only. metafmt-vivid metafmt-vsp1-hgo metafmt-vsp1-hgt + v4l2-isp diff --git a/Documentation/userspace-api/media/v4l/metafmt-arm-mali-c55.rst b/Documentation/userspace-api/media/v4l/metafmt-arm-mali-c55.rst new file mode 100644 index 0000000000000..696e0a645a7e0 --- /dev/null +++ b/Documentation/userspace-api/media/v4l/metafmt-arm-mali-c55.rst @@ -0,0 +1,84 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _v4l2-meta-fmt-mali-c55-params: +.. _v4l2-meta-fmt-mali-c55-stats: + +***************************************************************************** +V4L2_META_FMT_MALI_C55_STATS ('C55S'), V4L2_META_FMT_MALI_C55_PARAMS ('C55P') +***************************************************************************** + +3A Statistics +============= + +The ISP device collects different statistics over an input bayer frame. Those +statistics can be obtained by userspace from the +:ref:`mali-c55 3a stats ` metadata capture video node, using +the :c:type:`v4l2_meta_format` interface. The buffer contains a single instance +of the C structure :c:type:`mali_c55_stats_buffer` defined in +``mali-c55-config.h``, so the structure can be obtained from the buffer by: + +.. code-block:: C + + struct mali_c55_stats_buffer *stats = + (struct mali_c55_stats_buffer *)buf; + +For details of the statistics see :c:type:`mali_c55_stats_buffer`. + +Configuration Parameters +======================== + +The configuration parameters are passed to the :ref:`mali-c55 3a params +` metadata output video node, using the +:c:type:`v4l2_meta_format` interface. Rather than a single struct containing +sub-structs for each configurable area of the ISP, parameters for the Mali-C55 +use the v4l2-isp parameters system, through which groups of parameters are +defined as distinct structs or "blocks" which may be added to the data member of +:c:type:`v4l2_isp_params_buffer`. Userspace is responsible for populating the +data member with the blocks that need to be configured by the driver. Each +block-specific struct embeds :c:type:`v4l2_isp_params_block_header` as its first +member and userspace must populate the type member with a value from +:c:type:`mali_c55_param_block_type`. + +.. code-block:: c + + struct v4l2_isp_params_buffer *params = + (struct v4l2_isp_params_buffer *)buffer; + + params->version = MALI_C55_PARAM_BUFFER_V1; + params->data_size = 0; + + void *data = (void *)params->data; + + struct mali_c55_params_awb_gains *gains = + (struct mali_c55_params_awb_gains *)data; + + gains->header.type = MALI_C55_PARAM_BLOCK_AWB_GAINS; + gains->header.flags |= V4L2_ISP_PARAMS_FL_BLOCK_ENABLE; + gains->header.size = sizeof(struct mali_c55_params_awb_gains); + + gains->gain00 = 256; + gains->gain00 = 256; + gains->gain00 = 256; + gains->gain00 = 256; + + data += sizeof(struct mali_c55_params_awb_gains); + params->data_size += sizeof(struct mali_c55_params_awb_gains); + + struct mali_c55_params_sensor_off_preshading *blc = + (struct mali_c55_params_sensor_off_preshading *)data; + + blc->header.type = MALI_C55_PARAM_BLOCK_SENSOR_OFFS; + blc->header.flags |= V4L2_ISP_PARAMS_FL_BLOCK_ENABLE; + blc->header.size = sizeof(struct mali_c55_params_sensor_off_preshading); + + blc->chan00 = 51200; + blc->chan01 = 51200; + blc->chan10 = 51200; + blc->chan11 = 51200; + + params->data_size += sizeof(struct mali_c55_params_sensor_off_preshading); + +Arm Mali-C55 uAPI data types +============================ + +.. kernel-doc:: include/uapi/linux/media/arm/mali-c55-config.h diff --git a/Documentation/userspace-api/media/v4l/subdev-formats.rst b/Documentation/userspace-api/media/v4l/subdev-formats.rst index 1904390df830c..cf970750dd4c6 100644 --- a/Documentation/userspace-api/media/v4l/subdev-formats.rst +++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst @@ -2225,6 +2225,174 @@ The following table list existing packed 48bit wide RGB formats. \endgroup +The following table list existing packed 60bit wide RGB formats. + +.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| + +.. _v4l2-mbus-pixelcode-rgb-60: + +.. raw:: latex + + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} + +.. flat-table:: 60bit RGB formats + :header-rows: 3 + :stub-columns: 0 + :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + + * - Identifier + - Code + - + - :cspan:`31` Data organization + * - + - + - Bit + - + - + - + - + - 59 + - 58 + - 57 + - 56 + - 55 + - 54 + - 53 + - 52 + - 51 + - 50 + - 49 + - 48 + - 47 + - 46 + - 45 + - 44 + - 43 + - 42 + - 41 + - 40 + - 39 + - 38 + - 37 + - 36 + - 35 + - 34 + - 33 + - 32 + * - + - + - + - 31 + - 30 + - 29 + - 28 + - 27 + - 26 + - 25 + - 24 + - 23 + - 22 + - 21 + - 20 + - 19 + - 18 + - 17 + - 16 + - 15 + - 14 + - 13 + - 12 + - 11 + - 10 + - 9 + - 8 + - 7 + - 6 + - 5 + - 4 + - 3 + - 2 + - 1 + - 0 + * .. _MEDIA-BUS-FMT-RGB202020-1X60: + + - MEDIA_BUS_FMT_RGB202020_1X60 + - 0x1026 + - + - + - + - + - + - r\ :sub:`19` + - r\ :sub:`18` + - r\ :sub:`17` + - r\ :sub:`16` + - 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` + - g\ :sub:`19` + - g\ :sub:`18` + - g\ :sub:`17` + - g\ :sub:`16` + - 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` + - b\ :sub:`19` + - b\ :sub:`18` + - b\ :sub:`17` + - b\ :sub:`16` + - 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` + +.. raw:: latex + + \endgroup + On LVDS buses, usually each sample is transferred serialized in seven time slots per pixel clock, on three (18-bit) or four (24-bit) or five (30-bit) differential data pairs at the same time. The remaining bits are used @@ -2649,7 +2817,7 @@ organization is given as an example for the first pixel only. \tiny \setlength{\tabcolsep}{2pt} -.. tabularcolumns:: |p{6.0cm}|p{0.7cm}|p{0.3cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| +.. tabularcolumns:: |p{6.0cm}|p{0.7cm}|p{0.3cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| .. _v4l2-mbus-pixelcode-bayer: @@ -2662,10 +2830,14 @@ organization is given as an example for the first pixel only. * - Identifier - Code - - - :cspan:`15` Data organization + - :cspan:`19` Data organization * - - - Bit + - 19 + - 18 + - 17 + - 16 - 15 - 14 - 13 @@ -2695,6 +2867,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -2716,6 +2892,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -2737,6 +2917,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -2758,6 +2942,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -2779,6 +2967,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -2800,6 +2992,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -2821,6 +3017,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -2842,6 +3042,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -2863,6 +3067,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -2884,6 +3092,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -2905,6 +3117,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -2926,6 +3142,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -2947,6 +3167,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - 0 - 0 - 0 @@ -2966,6 +3190,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -2987,6 +3215,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -3006,6 +3238,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - 0 - 0 - 0 @@ -3027,6 +3263,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`9` - b\ :sub:`8` - b\ :sub:`7` @@ -3046,6 +3286,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`1` - b\ :sub:`0` - 0 @@ -3067,6 +3311,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`1` - b\ :sub:`0` - 0 @@ -3086,6 +3334,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`9` - b\ :sub:`8` - b\ :sub:`7` @@ -3105,6 +3357,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`9` - b\ :sub:`8` - b\ :sub:`7` @@ -3126,6 +3382,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`9` - g\ :sub:`8` - g\ :sub:`7` @@ -3147,6 +3407,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`9` - g\ :sub:`8` - g\ :sub:`7` @@ -3168,6 +3432,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - r\ :sub:`9` - r\ :sub:`8` - r\ :sub:`7` @@ -3187,6 +3455,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`11` - b\ :sub:`10` - b\ :sub:`9` @@ -3208,6 +3480,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`11` - g\ :sub:`10` - g\ :sub:`9` @@ -3229,6 +3505,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`11` - g\ :sub:`10` - g\ :sub:`9` @@ -3250,6 +3530,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - r\ :sub:`11` - r\ :sub:`10` - r\ :sub:`9` @@ -3269,6 +3553,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - b\ :sub:`13` - b\ :sub:`12` - b\ :sub:`11` @@ -3290,6 +3578,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`13` - g\ :sub:`12` - g\ :sub:`11` @@ -3311,6 +3603,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - g\ :sub:`13` - g\ :sub:`12` - g\ :sub:`11` @@ -3332,6 +3628,10 @@ organization is given as an example for the first pixel only. - - - + - + - + - + - - r\ :sub:`13` - r\ :sub:`12` - r\ :sub:`11` @@ -3351,6 +3651,10 @@ organization is given as an example for the first pixel only. - MEDIA_BUS_FMT_SBGGR16_1X16 - 0x301d - + - + - + - + - - b\ :sub:`15` - b\ :sub:`14` - b\ :sub:`13` @@ -3372,6 +3676,10 @@ organization is given as an example for the first pixel only. - MEDIA_BUS_FMT_SGBRG16_1X16 - 0x301e - + - + - + - + - - g\ :sub:`15` - g\ :sub:`14` - g\ :sub:`13` @@ -3393,6 +3701,10 @@ organization is given as an example for the first pixel only. - MEDIA_BUS_FMT_SGRBG16_1X16 - 0x301f - + - + - + - + - - g\ :sub:`15` - g\ :sub:`14` - g\ :sub:`13` @@ -3414,6 +3726,110 @@ organization is given as an example for the first pixel only. - MEDIA_BUS_FMT_SRGGB16_1X16 - 0x3020 - + - + - + - + - + - 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` + * .. _MEDIA-BUS-FMT-SBGGR20-1X20: + + - MEDIA_BUS_FMT_SBGGR20_1X20 + - 0x3021 + - + - b\ :sub:`19` + - b\ :sub:`18` + - b\ :sub:`17` + - b\ :sub:`16` + - 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` + * .. _MEDIA-BUS-FMT-SGBRG20-1X20: + + - MEDIA_BUS_FMT_SGBRG20_1X20 + - 0x3022 + - + - g\ :sub:`19` + - g\ :sub:`18` + - g\ :sub:`17` + - g\ :sub:`16` + - 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` + * .. _MEDIA-BUS-FMT-SGRBG20-1X20: + + - MEDIA_BUS_FMT_SGRBG20_1X20 + - 0x3023 + - + - g\ :sub:`19` + - g\ :sub:`18` + - g\ :sub:`17` + - g\ :sub:`16` + - 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` + * .. _MEDIA-BUS-FMT-SRGGB20-1X20: + + - MEDIA_BUS_FMT_SRGGB20_1X20 + - 0x3024 + - + - r\ :sub:`19` + - r\ :sub:`18` + - r\ :sub:`17` + - r\ :sub:`16` - r\ :sub:`15` - r\ :sub:`14` - r\ :sub:`13` diff --git a/Documentation/userspace-api/media/v4l/v4l2-isp.rst b/Documentation/userspace-api/media/v4l/v4l2-isp.rst new file mode 100644 index 0000000000000..facf6dba1ca7f --- /dev/null +++ b/Documentation/userspace-api/media/v4l/v4l2-isp.rst @@ -0,0 +1,67 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later + +.. _v4l2-isp: + +************************ +Generic V4L2 ISP formats +************************ + +Generic ISP formats are metadata formats that define a mechanism to pass ISP +parameters and statistics between userspace and drivers in V4L2 buffers. They +are designed to allow extending them in a backward-compatible way. + +ISP parameters +============== + +The generic ISP configuration parameters format is realized by a defining a +single C structure that contains a header, followed by a binary buffer where +userspace programs a variable number of ISP configuration data block, one for +each supported ISP feature. + +The :c:type:`v4l2_isp_params_buffer` structure defines the buffer header which +is followed by a binary buffer of ISP configuration data. Userspace shall +correctly populate the buffer header with the generic parameters format version +and with the size (in bytes) of the binary data buffer where it will store the +ISP blocks configuration. + +Each *ISP configuration block* is preceded by an header implemented by the +:c:type:`v4l2_isp_params_block_header` structure, followed by the configuration +parameters for that specific block, defined by the ISP driver specific data +types. + +Userspace applications are responsible for correctly populating each block's +header fields (type, flags and size) and the block-specific parameters. + +ISP block enabling, disabling and configuration +----------------------------------------------- + +When userspace wants to configure and enable an ISP block it shall fully +populate the block configuration and set the V4L2_ISP_PARAMS_FL_BLOCK_ENABLE +bit in the block header's `flags` field. + +When userspace simply wants to disable an ISP block the +V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bit should be set in block header's `flags` +field. Drivers accept a configuration parameters block with no additional +data after the header in this case. + +If the configuration of an already active ISP block has to be updated, +userspace shall fully populate the ISP block parameters and omit setting the +V4L2_ISP_PARAMS_FL_BLOCK_ENABLE and V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bits in the +header's `flags` field. + +Setting both the V4L2_ISP_PARAMS_FL_BLOCK_ENABLE and +V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bits in the flags field is not allowed and +returns an error. + +Extension to the parameters format can be implemented by adding new blocks +definition without invalidating the existing ones. + +ISP statistics +============== + +Support for generic statistics format is not yet implemented in Video4Linux2. + +V4L2 ISP uAPI data types +======================== + +.. kernel-doc:: include/uapi/linux/media/v4l2-isp.h diff --git a/Documentation/userspace-api/media/v4l/vidioc-remove-bufs.rst b/Documentation/userspace-api/media/v4l/vidioc-remove-bufs.rst index 1995b39af9ba8..b498d60752d75 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-remove-bufs.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-remove-bufs.rst @@ -54,7 +54,7 @@ are invoked. - ``count`` - The number of buffers to be removed with indices 'index' until 'index + count - 1'. All buffers in this range must be valid and in DEQUEUED state. - :ref:`VIDIOC_REMOVE_BUFS` will always check the validity of ``type`, if it is + :ref:`VIDIOC_REMOVE_BUFS` will always check the validity of ``type``, if it is invalid it returns ``EINVAL`` error code. If count is set to 0 :ref:`VIDIOC_REMOVE_BUFS` will do nothing and return 0. * - __u32 diff --git a/Documentation/virt/hyperv/coco.rst b/Documentation/virt/hyperv/coco.rst index c15d6fe34b4e8..3231e51444dac 100644 --- a/Documentation/virt/hyperv/coco.rst +++ b/Documentation/virt/hyperv/coco.rst @@ -178,7 +178,7 @@ These Hyper-V and VMBus memory pages are marked as decrypted: * VMBus monitor pages -* Synthetic interrupt controller (synic) related pages (unless supplied by +* Synthetic interrupt controller (SynIC) related pages (unless supplied by the paravisor) * Per-cpu hypercall input and output pages (unless running with a paravisor) @@ -232,6 +232,143 @@ with arguments explicitly describing the access. See _hv_pcifront_read_config() and _hv_pcifront_write_config() and the "use_calls" flag indicating to use hypercalls. +Confidential VMBus +------------------ +The confidential VMBus enables the confidential guest not to interact with +the untrusted host partition and the untrusted hypervisor. Instead, the guest +relies on the trusted paravisor to communicate with the devices processing +sensitive data. The hardware (SNP or TDX) encrypts the guest memory and the +register state while measuring the paravisor image using the platform security +processor to ensure trusted and confidential computing. + +Confidential VMBus provides a secure communication channel between the guest +and the paravisor, ensuring that sensitive data is protected from hypervisor- +level access through memory encryption and register state isolation. + +Confidential VMBus is an extension of Confidential Computing (CoCo) VMs +(a.k.a. "Isolated" VMs in Hyper-V terminology). Without Confidential VMBus, +guest VMBus device drivers (the "VSC"s in VMBus terminology) communicate +with VMBus servers (the VSPs) running on the Hyper-V host. The +communication must be through memory that has been decrypted so the +host can access it. With Confidential VMBus, one or more of the VSPs reside +in the trusted paravisor layer in the guest VM. Since the paravisor layer also +operates in encrypted memory, the memory used for communication with +such VSPs does not need to be decrypted and thereby exposed to the +Hyper-V host. The paravisor is responsible for communicating securely +with the Hyper-V host as necessary. + +The data is transferred directly between the VM and a vPCI device (a.k.a. +a PCI pass-thru device, see :doc:`vpci`) that is directly assigned to VTL2 +and that supports encrypted memory. In such a case, neither the host partition +nor the hypervisor has any access to the data. The guest needs to establish +a VMBus connection only with the paravisor for the channels that process +sensitive data, and the paravisor abstracts the details of communicating +with the specific devices away providing the guest with the well-established +VSP (Virtual Service Provider) interface that has had support in the Hyper-V +drivers for a decade. + +In the case the device does not support encrypted memory, the paravisor +provides bounce-buffering, and although the data is not encrypted, the backing +pages aren't mapped into the host partition through SLAT. While not impossible, +it becomes much more difficult for the host partition to exfiltrate the data +than it would be with a conventional VMBus connection where the host partition +has direct access to the memory used for communication. + +Here is the data flow for a conventional VMBus connection (`C` stands for the +client or VSC, `S` for the server or VSP, the `DEVICE` is a physical one, might +be with multiple virtual functions):: + + +---- GUEST ----+ +----- DEVICE ----+ +----- HOST -----+ + | | | | | | + | | | | | | + | | | ========== | + | | | | | | + | | | | | | + | | | | | | + +----- C -------+ +-----------------+ +------- S ------+ + || || + || || + +------||------------------ VMBus --------------------------||------+ + | Interrupts, MMIO | + +-------------------------------------------------------------------+ + +and the Confidential VMBus connection:: + + +---- GUEST --------------- VTL0 ------+ +-- DEVICE --+ + | | | | + | +- PARAVISOR --------- VTL2 -----+ | | | + | | +-- VMBus Relay ------+ ====+================ | + | | | Interrupts, MMIO | | | | | + | | +-------- S ----------+ | | +------------+ + | | || | | + | +---------+ || | | + | | Linux | || OpenHCL | | + | | kernel | || | | + | +---- C --+-----||---------------+ | + | || || | + +-------++------- C -------------------+ +------------+ + || | HOST | + || +---- S -----+ + +-------||----------------- VMBus ---------------------------||-----+ + | Interrupts, MMIO | + +-------------------------------------------------------------------+ + +An implementation of the VMBus relay that offers the Confidential VMBus +channels is available in the OpenVMM project as a part of the OpenHCL +paravisor. Please refer to + + * https://openvmm.dev/, and + * https://github.com/microsoft/openvmm + +for more information about the OpenHCL paravisor. + +A guest that is running with a paravisor must determine at runtime if +Confidential VMBus is supported by the current paravisor. The x86_64-specific +approach relies on the CPUID Virtualization Stack leaf; the ARM64 implementation +is expected to support the Confidential VMBus unconditionally when running +ARM CCA guests. + +Confidential VMBus is a characteristic of the VMBus connection as a whole, +and of each VMBus channel that is created. When a Confidential VMBus +connection is established, the paravisor provides the guest the message-passing +path that is used for VMBus device creation and deletion, and it provides a +per-CPU synthetic interrupt controller (SynIC) just like the SynIC that is +offered by the Hyper-V host. Each VMBus device that is offered to the guest +indicates the degree to which it participates in Confidential VMBus. The offer +indicates if the device uses encrypted ring buffers, and if the device uses +encrypted memory for DMA that is done outside the ring buffer. These settings +may be different for different devices using the same Confidential VMBus +connection. + +Although these settings are separate, in practice it'll always be encrypted +ring buffer only, or both encrypted ring buffer and external data. If a channel +is offered by the paravisor with confidential VMBus, the ring buffer can always +be encrypted since it's strictly for communication between the VTL2 paravisor +and the VTL0 guest. However, other memory regions are often used for e.g. DMA, +so they need to be accessible by the underlying hardware, and must be +unencrypted (unless the device supports encrypted memory). Currently, there are +not any VSPs in OpenHCL that support encrypted external memory, but future +versions are expected to enable this capability. + +Because some devices on a Confidential VMBus may require decrypted ring buffers +and DMA transfers, the guest must interact with two SynICs -- the one provided +by the paravisor and the one provided by the Hyper-V host when Confidential +VMBus is not offered. Interrupts are always signaled by the paravisor SynIC, +but the guest must check for messages and for channel interrupts on both SynICs. + +In the case of a confidential VMBus, regular SynIC access by the guest is +intercepted by the paravisor (this includes various MSRs such as the SIMP and +SIEFP, as well as hypercalls like HvPostMessage and HvSignalEvent). If the +guest actually wants to communicate with the hypervisor, it has to use special +mechanisms (GHCB page on SNP, or tdcall on TDX). Messages can be of either +kind: with confidential VMBus, messages use the paravisor SynIC, and if the +guest chose to communicate directly to the hypervisor, they use the hypervisor +SynIC. For interrupt signaling, some channels may be running on the host +(non-confidential, using the VMBus relay) and use the hypervisor SynIC, and +some on the paravisor and use its SynIC. The RelIDs are coordinated by the +OpenHCL VMBus server and are guaranteed to be unique regardless of whether +the channel originated on the host or the paravisor. + load_unaligned_zeropad() ------------------------ When transitioning memory between encrypted and decrypted, the caller of diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 57061fa29e6a0..01a3abef8abb9 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -7286,6 +7286,41 @@ exit, even without calls to ``KVM_ENABLE_CAP`` or similar. In this case, it will enter with output fields already valid; in the common case, the ``unknown.ret`` field of the union will be ``TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED``. Userspace need not do anything if it does not wish to support a TDVMCALL. + +:: + + /* KVM_EXIT_ARM_SEA */ + struct { + #define KVM_EXIT_ARM_SEA_FLAG_GPA_VALID (1ULL << 0) + __u64 flags; + __u64 esr; + __u64 gva; + __u64 gpa; + } arm_sea; + +Used on arm64 systems. When the VM capability ``KVM_CAP_ARM_SEA_TO_USER`` is +enabled, a KVM exits to userspace if a guest access causes a synchronous +external abort (SEA) and the host APEI fails to handle the SEA. + +``esr`` is set to a sanitized value of ESR_EL2 from the exception taken to KVM, +consisting of the following fields: + + - ``ESR_EL2.EC`` + - ``ESR_EL2.IL`` + - ``ESR_EL2.FnV`` + - ``ESR_EL2.EA`` + - ``ESR_EL2.CM`` + - ``ESR_EL2.WNR`` + - ``ESR_EL2.FSC`` + - ``ESR_EL2.SET`` (when FEAT_RAS is implemented for the VM) + +``gva`` is set to the value of FAR_EL2 from the exception taken to KVM when +``ESR_EL2.FnV == 0``. Otherwise, the value of ``gva`` is unknown. + +``gpa`` is set to the faulting IPA from the exception taken to KVM when +the ``KVM_EXIT_ARM_SEA_FLAG_GPA_VALID`` flag is set. Otherwise, the value of +``gpa`` is unknown. + :: /* Fix the size of the union. */ @@ -7820,7 +7855,7 @@ where 0xff represents CPUs 0-7 in cluster 0. :Architectures: s390 :Parameters: none -With this capability enabled, all illegal instructions 0x0000 (2 bytes) will +With this capability enabled, the illegal instruction 0x0000 (2 bytes) will be intercepted and forwarded to user space. User space can use this mechanism e.g. to realize 2-byte software breakpoints. The kernel will not inject an operating exception for these instructions, user space has @@ -8028,7 +8063,7 @@ will be initialized to 1 when created. This also improves performance because dirty logging can be enabled gradually in small chunks on the first call to KVM_CLEAR_DIRTY_LOG. KVM_DIRTY_LOG_INITIALLY_SET depends on KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (it is also only available on -x86 and arm64 for now). +x86, arm64 and riscv for now). KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 was previously available under the name KVM_CAP_MANUAL_DIRTY_LOG_PROTECT, but the implementation had bugs that make @@ -8524,7 +8559,7 @@ Therefore, the ioctl must be called *before* reading the content of the dirty pages. The dirty ring can get full. When it happens, the KVM_RUN of the -vcpu will return with exit reason KVM_EXIT_DIRTY_LOG_FULL. +vcpu will return with exit reason KVM_EXIT_DIRTY_RING_FULL. The dirty ring interface has a major difference comparing to the KVM_GET_DIRTY_LOG interface in that, when reading the dirty ring from @@ -8692,7 +8727,7 @@ given VM. When this capability is enabled, KVM resets the VCPU when setting MP_STATE_INIT_RECEIVED through IOCTL. The original MP_STATE is preserved. -7.43 KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED +7.44 KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED ------------------------------------------- :Architectures: arm64 @@ -8703,6 +8738,33 @@ This capability indicate to the userspace whether a PFNMAP memory region can be safely mapped as cacheable. This relies on the presence of force write back (FWB) feature support on the hardware. +7.45 KVM_CAP_ARM_SEA_TO_USER +---------------------------- + +:Architecture: arm64 +:Target: VM +:Parameters: none +:Returns: 0 on success, -EINVAL if unsupported. + +When this capability is enabled, KVM may exit to userspace for SEAs taken to +EL2 resulting from a guest access. See ``KVM_EXIT_ARM_SEA`` for more +information. + +7.46 KVM_CAP_S390_USER_OPEREXEC +------------------------------- + +:Architectures: s390 +:Parameters: none + +When this capability is enabled KVM forwards all operation exceptions +that it doesn't handle itself to user space. This also includes the +0x0000 instructions managed by KVM_CAP_S390_USER_INSTR0. This is +helpful if user space wants to emulate instructions which are not +(yet) implemented in hardware. + +This capability can be enabled dynamically even if VCPUs were already +created and are running. + 8. Other capabilities. ====================== diff --git a/Documentation/virt/kvm/x86/errata.rst b/Documentation/virt/kvm/x86/errata.rst index 37c79362a48fa..a9cf0e004651a 100644 --- a/Documentation/virt/kvm/x86/errata.rst +++ b/Documentation/virt/kvm/x86/errata.rst @@ -48,7 +48,14 @@ versus "has_error_code", i.e. KVM's ABI follows AMD behavior. Nested virtualization features ------------------------------ -TBD +On AMD CPUs, when GIF is cleared, #DB exceptions or traps due to a breakpoint +register match are ignored and discarded by the CPU. The CPU relies on the VMM +to fully virtualize this behavior, even when vGIF is enabled for the guest +(i.e. vGIF=0 does not cause the CPU to drop #DBs when the guest is running). +KVM does not virtualize this behavior as the complexity is unjustified given +the rarity of the use case. One way to handle this would be for KVM to +intercept the #DB, temporarily disable the breakpoint, single-step over the +instruction, then re-enable the breakpoint. x2APIC ------ diff --git a/Documentation/wmi/devices/lenovo-wmi-gamezone.rst b/Documentation/wmi/devices/lenovo-wmi-gamezone.rst index 997263e51a7df..1769ad3d57b99 100644 --- a/Documentation/wmi/devices/lenovo-wmi-gamezone.rst +++ b/Documentation/wmi/devices/lenovo-wmi-gamezone.rst @@ -19,27 +19,26 @@ WMI GUID ``887B54E3-DDDC-4B2C-8B88-68A26A8835D0`` The Gamezone Data WMI interface provides platform-profile and fan curve settings for devices that fall under the "Gaming Series" of Lenovo devices. It uses a notifier chain to inform other Lenovo WMI interface drivers of the -current platform profile when it changes. +current platform profile when it changes. The currently set profile can be +determined by the user on the hardware by looking at the color of the power +or profile LED, depending on the model. The following platform profiles are supported: - - low-power - - balanced - - balanced-performance - - performance - - custom + - low-power, blue LED + - balanced, white LED + - performance, red LED + - max-power, purple LED + - custom, purple LED -Balanced-Performance +Extreme Mode ~~~~~~~~~~~~~~~~~~~~ Some newer Lenovo "Gaming Series" laptops have an "Extreme Mode" profile -enabled in their BIOS. For these devices, the performance platform profile -corresponds to the BIOS Extreme Mode, while the balanced-performance -platform profile corresponds to the BIOS Performance mode. For legacy -devices, the performance platform profile will correspond with the BIOS -Performance mode. - -For some newer devices the "Extreme Mode" profile is incomplete in the BIOS -and setting it will cause undefined behavior. A BIOS bug quirk table is -provided to ensure these devices cannot set "Extreme Mode" from the driver. +enabled in their BIOS. When available, this mode will be represented by the +max-power platform profile. + +For a subset of these devices the "Extreme Mode" profile is incomplete in +the BIOS and setting it will cause undefined behavior. A BIOS bug quirk table +is provided to ensure these devices cannot set "Extreme Mode" from the driver. Custom Profile ~~~~~~~~~~~~~~ diff --git a/Documentation/wmi/devices/uniwill-laptop.rst b/Documentation/wmi/devices/uniwill-laptop.rst new file mode 100644 index 0000000000000..e246bf293450b --- /dev/null +++ b/Documentation/wmi/devices/uniwill-laptop.rst @@ -0,0 +1,198 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +======================================== +Uniwill Notebook driver (uniwill-laptop) +======================================== + +Introduction +============ + +Many notebooks manufactured by Uniwill (either directly or as ODM) provide a EC interface +for controlling various platform settings like sensors and fan control. This interface is +used by the ``uniwill-laptop`` driver to map those features onto standard kernel interfaces. + +EC WMI interface description +============================ + +The EC WMI interface description can be decoded from the embedded binary MOF (bmof) +data using the `bmfdec `_ utility: + +:: + + [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), + Description("Class used to operate methods on a ULong"), + guid("{ABBC0F6F-8EA1-11d1-00A0-C90629100000}")] + class AcpiTest_MULong { + [key, read] string InstanceName; + [read] boolean Active; + + [WmiMethodId(1), Implemented, read, write, Description("Return the contents of a ULong")] + void GetULong([out, Description("Ulong Data")] uint32 Data); + + [WmiMethodId(2), Implemented, read, write, Description("Set the contents of a ULong")] + void SetULong([in, Description("Ulong Data")] uint32 Data); + + [WmiMethodId(3), Implemented, read, write, + Description("Generate an event containing ULong data")] + void FireULong([in, Description("WMI requires a parameter")] uint32 Hack); + + [WmiMethodId(4), Implemented, read, write, Description("Get and Set the contents of a ULong")] + void GetSetULong([in, Description("Ulong Data")] uint64 Data, + [out, Description("Ulong Data")] uint32 Return); + + [WmiMethodId(5), Implemented, read, write, + Description("Get and Set the contents of a ULong for Dollby button")] + void GetButton([in, Description("Ulong Data")] uint64 Data, + [out, Description("Ulong Data")] uint32 Return); + }; + +Most of the WMI-related code was copied from the Windows driver samples, which unfortunately means +that the WMI-GUID is not unique. This makes the WMI-GUID unusable for autoloading. + +WMI method GetULong() +--------------------- + +This WMI method was copied from the Windows driver samples and has no function. + +WMI method SetULong() +--------------------- + +This WMI method was copied from the Windows driver samples and has no function. + +WMI method FireULong() +---------------------- + +This WMI method allows to inject a WMI event with a 32-bit payload. Its primary purpose seems +to be debugging. + +WMI method GetSetULong() +------------------------ + +This WMI method is used to communicate with the EC. The ``Data`` argument holds the following +information (starting with the least significant byte): + +1. 16-bit address +2. 16-bit data (set to ``0x0000`` when reading) +3. 16-bit operation (``0x0100`` for reading and ``0x0000`` for writing) +4. 16-bit reserved (set to ``0x0000``) + +The first 8 bits of the ``Return`` value contain the data returned by the EC when reading. +The special value ``0xFEFEFEFE`` is used to indicate a communication failure with the EC. + +WMI method GetButton() +---------------------- + +This WMI method is not implemented on all machines and has an unknown purpose. + +Reverse-Engineering the EC WMI interface +======================================== + +.. warning:: Randomly poking the EC can potentially cause damage to the machine and other unwanted + side effects, please be careful. + +The EC behind the ``GetSetULong`` method is used by the OEM software supplied by the manufacturer. +Reverse-engineering of this software is difficult since it uses an obfuscator, however some parts +are not obfuscated. In this case `dnSpy `_ could also be helpful. + +The EC can be accessed under Windows using powershell (requires admin privileges): + +:: + + > $obj = Get-CimInstance -Namespace root/wmi -ClassName AcpiTest_MULong | Select-Object -First 1 + > Invoke-CimMethod -InputObject $obj -MethodName GetSetULong -Arguments @{Data = } + +WMI event interface description +=============================== + +The WMI interface description can also be decoded from the embedded binary MOF (bmof) +data: + +:: + + [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), + Description("Class containing event generated ULong data"), + guid("{ABBC0F72-8EA1-11d1-00A0-C90629100000}")] + class AcpiTest_EventULong : WmiEvent { + [key, read] string InstanceName; + [read] boolean Active; + + [WmiDataId(1), read, write, Description("ULong Data")] uint32 ULong; + }; + +Most of the WMI-related code was again copied from the Windows driver samples, causing this WMI +interface to suffer from the same restrictions as the EC WMI interface described above. + +WMI event data +-------------- + +The WMI event data contains a single 32-bit value which is used to indicate various platform events. + +Reverse-Engineering the Uniwill WMI event interface +=================================================== + +The driver logs debug messages when receiving a WMI event. Thus enabling debug messages will be +useful for finding unknown event codes. + +EC ACPI interface description +============================= + +The ``INOU0000`` ACPI device is a virtual device used to access various hardware registers +available on notebooks manufactured by Uniwill. Reading and writing those registers happens +by calling ACPI control methods. The ``uniwill-laptop`` driver uses this device to communicate +with the EC because the ACPI control methods are faster than the WMI methods described above. + +ACPI control methods used for reading registers take a single ACPI integer containing the address +of the register to read and return a ACPI integer containing the data inside said register. ACPI +control methods used for writing registers however take two ACPI integers, with the additional +ACPI integer containing the data to be written into the register. Such ACPI control methods return +nothing. + +System memory +------------- + +System memory can be accessed with a granularity of either a single byte (``MMRB`` for reading and +``MMWB`` for writing) or four bytes (``MMRD`` for reading and ``MMWD`` for writing). Those ACPI +control methods are unused because they provide no benefit when compared to the native memory +access functions provided by the kernel. + +EC RAM +------ + +The internal RAM of the EC can be accessed with a granularity of a single byte using the ``ECRR`` +(read) and ``ECRW`` (write) ACPI control methods, with the maximum register address being ``0xFFF``. +The OEM software waits 6 ms after calling one of those ACPI control methods, likely to avoid +overwhelming the EC when being connected over LPC. + +PCI config space +---------------- + +The PCI config space can be accessed with a granularity of four bytes using the ``PCRD`` (read) and +``PCWD`` (write) ACPI control methods. The exact address format is unknown, and poking random PCI +devices might confuse the PCI subsystem. Because of this those ACPI control methods are not used. + +IO ports +-------- + +IO ports can be accessed with a granularity of four bytes using the ``IORD`` (read) and ``IOWD`` +(write) ACPI control methods. Those ACPI control methods are unused because they provide no benefit +when compared to the native IO port access functions provided by the kernel. + +CMOS RAM +-------- + +The CMOS RAM can be accessed with a granularity of a single byte using the ``RCMS`` (read) and +``WCMS`` ACPI control methods. Using those ACPI methods might interfere with the native CMOS RAM +access functions provided by the kernel due to the usage of indexed IO, so they are unused. + +Indexed IO +---------- + +Indexed IO with IO ports with a granularity of a single byte can be performed using the ``RIOP`` +(read) and ``WIOP`` (write) ACPI control methods. Those ACPI methods are unused because they +provide no benifit when compared to the native IO port access functions provided by the kernel. + +Special thanks go to github user `pobrn` which developed the +`qc71_laptop `_ driver on which this driver is partly based. +The same is true for Tuxedo Computers, which developed the +`tuxedo-drivers `_ package +which also served as a foundation for this driver. diff --git a/LICENSES/preferred/LGPL-2.1 b/LICENSES/preferred/LGPL-2.1 index 105b9f3c5ba12..4d1d06a0e8ffe 100644 --- a/LICENSES/preferred/LGPL-2.1 +++ b/LICENSES/preferred/LGPL-2.1 @@ -9,9 +9,13 @@ Usage-Guide: guidelines in the licensing rules documentation. For 'GNU Lesser General Public License (LGPL) version 2.1 only' use: SPDX-License-Identifier: LGPL-2.1 + or: + SPDX-License-Identifier: LGPL-2.1-only For 'GNU Lesser General Public License (LGPL) version 2.1 or any later version' use: SPDX-License-Identifier: LGPL-2.1+ + or: + SPDX-License-Identifier: LGPL-2.1-or-later License-Text: GNU LESSER GENERAL PUBLIC LICENSE diff --git a/MAINTAINERS b/MAINTAINERS index e92e55447d19d..12f49de7fe036 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -195,7 +195,7 @@ F: drivers/pinctrl/pinctrl-upboard.c F: include/linux/mfd/upboard-fpga.h AB8500 BATTERY AND CHARGER DRIVERS -M: Linus Walleij +M: Linus Walleij F: Documentation/devicetree/bindings/power/supply/*ab8500* F: drivers/power/supply/*ab8500* @@ -388,7 +388,7 @@ B: https://bugzilla.kernel.org F: drivers/acpi/*thermal* ACPI VIOT DRIVER -M: Jean-Philippe Brucker +M: Jean-Philippe Brucker L: linux-acpi@vger.kernel.org L: iommu@lists.linux.dev S: Maintained @@ -402,7 +402,7 @@ S: Maintained F: Documentation/ABI/testing/sysfs-bus-wmi F: Documentation/driver-api/wmi.rst F: Documentation/wmi/ -F: drivers/platform/x86/wmi.c +F: drivers/platform/wmi/ F: include/uapi/linux/wmi.h ACRN HYPERVISOR SERVICE MODULE @@ -440,6 +440,18 @@ W: http://wiki.analog.com/AD5398 W: https://ez.analog.com/linux-software-drivers F: drivers/regulator/ad5398.c +AD5446 ANALOG DEVICES INC AD5446 DAC DRIVER +M: Michael Hennerich +M: Nuno Sá +L: linux-iio@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/dac/adi,ad5446.yaml +F: drivers/iio/dac/ad5446-i2c.c +F: drivers/iio/dac/ad5446-spi.c +F: drivers/iio/dac/ad5446.c +F: drivers/iio/dac/ad5446.h + AD714X CAPACITANCE TOUCH SENSOR DRIVER (AD7142/3/7/8/7A) M: Michael Hennerich S: Supported @@ -974,7 +986,7 @@ F: drivers/edac/al_mc_edac.c AMAZON ANNAPURNA LABS THERMAL MMIO DRIVER M: Talel Shenhar S: Maintained -F: Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt +F: Documentation/devicetree/bindings/thermal/amazon,al-thermal.yaml F: drivers/thermal/thermal_mmio.c AMAZON ETHERNET DRIVERS @@ -1081,7 +1093,7 @@ M: Austin Zheng M: Jun Lei S: Supported F: drivers/gpu/drm/amd/display/dc/dml/ -F: drivers/gpu/drm/amd/display/dc/dml2/ +F: drivers/gpu/drm/amd/display/dc/dml2_0/ AMD FAM15H PROCESSOR POWER MONITORING DRIVER M: Huang Rui @@ -1758,6 +1770,7 @@ S: Supported W: http://wiki.analog.com/ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/sound/adi,* +F: Documentation/devicetree/bindings/sound/trivial-codec.yaml F: sound/soc/codecs/ad1* F: sound/soc/codecs/ad7* F: sound/soc/codecs/adau* @@ -1808,11 +1821,9 @@ ANDROID DRIVERS M: Greg Kroah-Hartman M: Arve Hjønnevåg M: Todd Kjos -M: Martijn Coenen -M: Joel Fernandes M: Christian Brauner M: Carlos Llamas -M: Suren Baghdasaryan +M: Alice Ryhl L: linux-kernel@vger.kernel.org S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git @@ -2022,6 +2033,15 @@ F: arch/arm64/include/asm/arch_timer.h F: drivers/clocksource/arm_arch_timer.c F: drivers/clocksource/arm_arch_timer_mmio.c +ARM ETHOS-U NPU DRIVER +M: Rob Herring (Arm) +M: Tomeu Vizoso +L: dri-devel@lists.freedesktop.org +S: Supported +T: git https://gitlab.freedesktop.org/drm/misc/kernel.git +F: drivers/accel/ethosu/ +F: include/uapi/drm/ethosu_accel.h + ARM GENERIC INTERRUPT CONTROLLER DRIVERS M: Marc Zyngier L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -2050,7 +2070,7 @@ F: Documentation/devicetree/bindings/display/arm,hdlcd.yaml F: drivers/gpu/drm/arm/hdlcd_* ARM INTEGRATOR, VERSATILE AND REALVIEW SUPPORT -M: Linus Walleij +M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/arm/arm,integrator.yaml @@ -2097,7 +2117,8 @@ F: drivers/gpu/drm/arm/display/komeda/ ARM MALI PANFROST DRM DRIVER M: Boris Brezillon M: Rob Herring -R: Steven Price +M: Steven Price +M: Adrián Larumbe L: dri-devel@lists.freedesktop.org S: Supported T: git https://gitlab.freedesktop.org/drm/misc/kernel.git @@ -2106,6 +2127,20 @@ F: drivers/gpu/drm/ci/xfails/panfrost* F: drivers/gpu/drm/panfrost/ F: include/uapi/drm/panfrost_drm.h +ARM MALI-C55 ISP DRIVER +M: Daniel Scally +M: Jacopo Mondi +L: linux-media@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: Documentation/admin-guide/media/mali-c55-graph.dot +F: Documentation/admin-guide/media/mali-c55.rst +F: Documentation/devicetree/bindings/media/arm,mali-c55.yaml +F: Documentation/userspace-api/media/drivers/mali-c55.rst +F: Documentation/userspace-api/media/v4l/metafmt-arm-mali-c55.rst +F: drivers/media/platform/arm/mali-c55/ +F: include/uapi/linux/media/arm/mali-c55-config.h + ARM MALI PANTHOR DRM DRIVER M: Boris Brezillon M: Steven Price @@ -2208,7 +2243,7 @@ F: Documentation/devicetree/bindings/memory-controllers/arm,pl35x-smc.yaml F: drivers/memory/pl353-smc.c ARM PRIMECELL SSP PL022 SPI DRIVER -M: Linus Walleij +M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/spi/spi-pl022.yaml @@ -2221,7 +2256,7 @@ F: drivers/tty/serial/amba-pl01*.c F: include/linux/amba/serial.h ARM PRIMECELL VIC PL190/PL192 DRIVER -M: Linus Walleij +M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/interrupt-controller/arm,vic.yaml @@ -2244,7 +2279,7 @@ F: drivers/iommu/arm/ F: drivers/iommu/io-pgtable-arm* ARM SMMU SVA SUPPORT -R: Jean-Philippe Brucker +R: Jean-Philippe Brucker F: drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c ARM SUB-ARCHITECTURES @@ -2269,7 +2304,7 @@ F: Documentation/devicetree/bindings/interrupt-controller/actions,owl-sirq.yaml F: Documentation/devicetree/bindings/mmc/owl-mmc.yaml F: Documentation/devicetree/bindings/net/actions,owl-emac.yaml F: Documentation/devicetree/bindings/pinctrl/actions,* -F: Documentation/devicetree/bindings/power/actions,owl-sps.txt +F: Documentation/devicetree/bindings/power/actions,s500-sps.yaml F: Documentation/devicetree/bindings/timer/actions,owl-timer.yaml F: arch/arm/boot/dts/actions/ F: arch/arm/mach-actions/ @@ -2303,7 +2338,7 @@ S: Maintained F: drivers/clk/sunxi/ ARM/Allwinner sunXi SoC support -M: Chen-Yu Tsai +M: Chen-Yu Tsai M: Jernej Skrabec M: Samuel Holland L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -2397,9 +2432,9 @@ M: Martin Povišer L: asahi@lists.linux.dev L: linux-sound@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/sound/adi,ssm3515.yaml -F: Documentation/devicetree/bindings/sound/cirrus,cs42l84.yaml F: Documentation/devicetree/bindings/sound/apple,* +F: Documentation/devicetree/bindings/sound/cirrus,cs42l84.yaml +F: Documentation/devicetree/bindings/sound/trivial-codec.yaml F: sound/soc/apple/* F: sound/soc/codecs/cs42l83-i2c.c F: sound/soc/codecs/cs42l84.* @@ -2440,15 +2475,19 @@ F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml F: Documentation/devicetree/bindings/power/apple* F: Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml F: Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml +F: Documentation/devicetree/bindings/rtc/apple,smc-rtc.yaml F: Documentation/devicetree/bindings/spi/apple,spi.yaml F: Documentation/devicetree/bindings/spmi/apple,spmi.yaml +F: Documentation/devicetree/bindings/usb/apple,dwc3.yaml F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml +F: Documentation/hwmon/macsmc-hwmon.rst F: arch/arm64/boot/dts/apple/ F: drivers/bluetooth/hci_bcm4377.c F: drivers/clk/clk-apple-nco.c F: drivers/cpufreq/apple-soc-cpufreq.c F: drivers/dma/apple-admac.c F: drivers/gpio/gpio-macsmc.c +F: drivers/hwmon/macsmc-hwmon.c F: drivers/pmdomain/apple/ F: drivers/i2c/busses/i2c-pasemi-core.c F: drivers/i2c/busses/i2c-pasemi-platform.c @@ -2463,9 +2502,11 @@ F: drivers/nvmem/apple-spmi-nvmem.c F: drivers/pinctrl/pinctrl-apple-gpio.c F: drivers/power/reset/macsmc-reboot.c F: drivers/pwm/pwm-apple.c +F: drivers/rtc/rtc-macsmc.c F: drivers/soc/apple/* F: drivers/spi/spi-apple.c F: drivers/spmi/spmi-apple-controller.c +F: drivers/usb/dwc3/dwc3-apple.c F: drivers/video/backlight/apple_dwi_bl.c F: drivers/watchdog/apple_wdt.c F: include/dt-bindings/interrupt-controller/apple-aic.h @@ -2534,7 +2575,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/arm/bitmain.yaml F: Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml -F: Documentation/devicetree/bindings/pinctrl/bitmain,bm1880-pinctrl.txt +F: Documentation/devicetree/bindings/pinctrl/bitmain,bm1880-pinctrl.yaml F: arch/arm64/boot/dts/bitmain/ F: drivers/clk/clk-bm1880.c F: drivers/pinctrl/pinctrl-bm1880.c @@ -2548,6 +2589,14 @@ S: Maintained F: Documentation/devicetree/bindings/arm/blaize.yaml F: arch/arm64/boot/dts/blaize/ +ARM/BST SOC SUPPORT +M: Ge Gordon +R: BST Linux Kernel Upstream Group +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Supported +F: Documentation/devicetree/bindings/arm/bst.yaml +F: arch/arm64/boot/dts/bst/ + ARM/CALXEDA HIGHBANK ARCHITECTURE M: Andre Przywara L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -2638,7 +2687,7 @@ F: tools/perf/util/cs-etm.* ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE M: Hans Ulli Kroll -M: Linus Walleij +M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained T: git https://github.com/ulli-kroll/linux.git @@ -2661,7 +2710,7 @@ F: Documentation/ABI/testing/debugfs-moxtet F: Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu F: Documentation/ABI/testing/sysfs-bus-moxtet-devices F: Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm -F: Documentation/devicetree/bindings/bus/moxtet.txt +F: Documentation/devicetree/bindings/bus/cznic,moxtet.yaml F: Documentation/devicetree/bindings/firmware/cznic,turris-mox-rwtm.txt F: Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml F: Documentation/devicetree/bindings/interrupt-controller/marvell,mpic.yaml @@ -3040,7 +3089,7 @@ F: include/dt-bindings/clock/mstar-* F: include/dt-bindings/gpio/msc313-gpio.h ARM/NOMADIK/Ux500 ARCHITECTURES -M: Linus Walleij +M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git @@ -3137,6 +3186,15 @@ F: arch/arm64/boot/dts/freescale/s32g*.dts* F: drivers/pinctrl/nxp/ F: drivers/rtc/rtc-s32g.c +ARM/NXP S32G PCIE CONTROLLER DRIVER +M: Ciprian Marian Costea +R: NXP S32 Linux Team +L: imx@lists.linux.dev +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: Documentation/devicetree/bindings/pci/nxp,s32g-pcie.yaml +F: drivers/pci/controller/dwc/pcie-nxp-s32g* + ARM/NXP S32G/S32R DWMAC ETHERNET DRIVER M: Jan Petrous R: s32@nxp.com @@ -3408,7 +3466,7 @@ S: Maintained F: drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c ARM/SOCFPGA EDAC BINDINGS -M: Matthew Gerlach +M: Niravkumar L Rabara S: Maintained F: Documentation/devicetree/bindings/edac/altr,socfpga-ecc-manager.yaml @@ -3443,7 +3501,6 @@ F: drivers/clocksource/clksrc_st_lpc.c F: drivers/cpufreq/sti-cpufreq.c F: drivers/dma/st_fdma* F: drivers/i2c/busses/i2c-st.c -F: drivers/media/platform/st/sti/c8sectpfe/ F: drivers/media/rc/st_rc.c F: drivers/mmc/host/sdhci-st.c F: drivers/phy/st/phy-miphy28lp.c @@ -3738,7 +3795,7 @@ F: Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml F: drivers/media/i2c/ak7375.c ASAHI KASEI AK8974 DRIVER -M: Linus Walleij +M: Linus Walleij L: linux-iio@vger.kernel.org S: Supported W: http://www.akm.com/ @@ -3751,6 +3808,13 @@ S: Maintained F: Documentation/devicetree/bindings/iio/chemical/aosong,ags02ma.yaml F: drivers/iio/chemical/ags02ma.c +AOSONG ADP810 DIFFERENTIAL PRESSURE SENSOR DRIVER +M: Akhilesh Patil +L: linux-iio@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/iio/pressure/aosong,adp810.yaml +F: drivers/iio/pressure/adp810.c + ASC7621 HARDWARE MONITOR DRIVER M: George Joseph L: linux-hwmon@vger.kernel.org @@ -3953,6 +4017,12 @@ F: drivers/power/reset/atc260x-poweroff.c F: drivers/regulator/atc260x-regulator.c F: include/linux/mfd/atc260x/* +ATCRTC100 RTC DRIVER +M: CL Wang +S: Supported +F: Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml +F: drivers/rtc/rtc-atcrtc100.c + ATHEROS 71XX/9XXX GPIO DRIVER M: Alban Bedel S: Maintained @@ -4130,6 +4200,12 @@ S: Maintained F: Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml F: drivers/iio/adc/hx711.c +AWINIC AW99706 WLED BACKLIGHT DRIVER +M: Junjie Cao +S: Maintained +F: Documentation/devicetree/bindings/leds/backlight/awinic,aw99706.yaml +F: drivers/video/backlight/aw99706.c + AX.25 NETWORK LAYER L: linux-hams@vger.kernel.org S: Orphan @@ -4194,6 +4270,13 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/pwm/adi,axi-pwmgen.yaml F: drivers/pwm/pwm-axi-pwmgen.c +AYANEO PLATFORM EC DRIVER +M: Antheas Kapenekakis +L: platform-driver-x86@vger.kernel.org +S: Maintained +F: Documentation/ABI/testing/sysfs-platform-ayaneo +F: drivers/platform/x86/ayaneo-ec.c + AZ6007 DVB DRIVER M: Mauro Carvalho Chehab L: linux-media@vger.kernel.org @@ -4383,6 +4466,7 @@ F: arch/*/lib/bitops.c F: include/asm-generic/bitops F: include/asm-generic/bitops.h F: include/linux/bitops.h +F: lib/hweight.c F: lib/test_bitops.c F: tools/*/bitops* @@ -4476,6 +4560,13 @@ F: include/net/bond* F: include/uapi/linux/if_bonding.h F: tools/testing/selftests/drivers/net/bonding/ +BOSCH SENSORTEC BMA220 ACCELEROMETER IIO DRIVER +M: Petre Rodan +L: linux-iio@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/iio/accel/bosch,bma220.yaml +F: drivers/iio/accel/bma220* + BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER M: Dan Robertson L: linux-iio@vger.kernel.org @@ -4541,7 +4632,7 @@ F: drivers/net/ethernet/netronome/nfp/bpf/ BPF JIT for POWERPC (32-BIT AND 64-BIT) M: Hari Bathini -M: Christophe Leroy +M: Christophe Leroy (CS GROUP) R: Naveen N Rao L: bpf@vger.kernel.org S: Supported @@ -4834,7 +4925,9 @@ S: Maintained T: git https://github.com/broadcom/stblinux.git F: Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml F: drivers/pci/controller/pcie-brcmstb.c +F: drivers/platform/raspberrypi/vchiq-* F: drivers/staging/vc04_services +F: include/linux/raspberrypi/vchiq* N: bcm2711 N: bcm2712 N: bcm283* @@ -5202,6 +5295,13 @@ W: http://www.broadcom.com F: drivers/infiniband/hw/bnxt_re/ F: include/uapi/rdma/bnxt_re-abi.h +BROADCOM 800 GIGABIT ROCE DRIVER +M: Siva Reddy Kallam +L: linux-rdma@vger.kernel.org +S: Supported +W: http://www.broadcom.com +F: drivers/infiniband/hw/bng_re/ + BROADCOM NVRAM DRIVER M: Rafał Miłecki L: linux-mips@vger.kernel.org @@ -6768,7 +6868,7 @@ S: Maintained F: drivers/pinctrl/pinctrl-cy8c95x0.c CYPRESS CY8CTMA140 TOUCHSCREEN DRIVER -M: Linus Walleij +M: Linus Walleij L: linux-input@vger.kernel.org S: Maintained F: drivers/input/touchscreen/cy8ctma140.c @@ -6788,13 +6888,13 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ F: drivers/media/common/cypress_firmware* CYTTSP TOUCHSCREEN DRIVER -M: Linus Walleij +M: Linus Walleij L: linux-input@vger.kernel.org S: Maintained F: drivers/input/touchscreen/cyttsp* D-LINK DIR-685 TOUCHKEYS DRIVER -M: Linus Walleij +M: Linus Walleij L: linux-input@vger.kernel.org S: Supported F: drivers/input/keyboard/dlink-dir685-touchkeys.c @@ -7133,6 +7233,7 @@ DEVICE-MAPPER (LVM) M: Alasdair Kergon M: Mike Snitzer M: Mikulas Patocka +M: Benjamin Marzinski L: dm-devel@lists.linux.dev S: Maintained Q: http://patchwork.kernel.org/project/dm-devel/list/ @@ -7199,7 +7300,6 @@ F: Documentation/devicetree/bindings/input/dlg,da72??.yaml F: Documentation/devicetree/bindings/input/dlg,da9062-onkey.yaml F: Documentation/devicetree/bindings/mfd/da90*.txt F: Documentation/devicetree/bindings/mfd/dlg,da90*.yaml -F: Documentation/devicetree/bindings/regulator/da92*.txt F: Documentation/devicetree/bindings/regulator/dlg,da9*.yaml F: Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml F: Documentation/devicetree/bindings/sound/da[79]*.txt @@ -7318,6 +7418,7 @@ F: Documentation/userspace-api/dma-buf-alloc-exchange.rst F: drivers/dma-buf/ F: include/linux/*fence.h F: include/linux/dma-buf.h +F: include/linux/dma-buf/ F: include/linux/dma-resv.h K: \bdma_(?:buf|fence|resv)\b @@ -7483,7 +7584,7 @@ F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.yaml F: drivers/media/i2c/dw9714.c DONGWOON DW9719 LENS VOICE COIL DRIVER -M: Daniel Scally +M: Daniel Scally L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media.git @@ -7641,8 +7742,7 @@ F: drivers/accel/ F: include/drm/drm_accel.h DRM DRIVER FOR ALLWINNER DE2 AND DE3 ENGINE -M: Maxime Ripard -M: Chen-Yu Tsai +M: Chen-Yu Tsai R: Jernej Skrabec L: dri-devel@lists.freedesktop.org S: Supported @@ -7658,13 +7758,13 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: drivers/gpu/drm/tiny/appletbdrm.c DRM DRIVER FOR ARM PL111 CLCD -M: Linus Walleij +M: Linus Walleij S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: drivers/gpu/drm/pl111/ DRM DRIVER FOR ARM VERSATILE TFT PANELS -M: Linus Walleij +M: Linus Walleij S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml @@ -7714,7 +7814,7 @@ F: Documentation/devicetree/bindings/display/panel/ebbg,ft8719.yaml F: drivers/gpu/drm/panel/panel-ebbg-ft8719.c DRM DRIVER FOR FARADAY TVE200 TV ENCODER -M: Linus Walleij +M: Linus Walleij S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: drivers/gpu/drm/tve200/ @@ -7751,7 +7851,8 @@ F: Documentation/devicetree/bindings/display/panel/panel-edp.yaml F: drivers/gpu/drm/panel/panel-edp.c DRM DRIVER FOR GENERIC USB DISPLAY -S: Orphan +M: Ruben Wauters +S: Maintained W: https://github.com/notro/gud/wiki T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: drivers/gpu/drm/gud/ @@ -7873,6 +7974,7 @@ DRM DRIVER for Qualcomm Adreno GPUs M: Rob Clark R: Sean Paul R: Konrad Dybcio +R: Akhil P Oommen L: linux-arm-msm@vger.kernel.org L: dri-devel@lists.freedesktop.org L: freedreno@lists.freedesktop.org @@ -7892,7 +7994,7 @@ DRM DRIVER for Qualcomm display hardware M: Rob Clark M: Dmitry Baryshkov R: Abhinav Kumar -R: Jessica Zhang +R: Jessica Zhang R: Sean Paul R: Marijn Suijten L: linux-arm-msm@vger.kernel.org @@ -7908,14 +8010,14 @@ F: include/dt-bindings/clock/qcom,dsi-phy-28nm.h F: include/uapi/drm/msm_drm.h DRM DRIVER FOR NOVATEK NT35510 PANELS -M: Linus Walleij +M: Linus Walleij S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml F: drivers/gpu/drm/panel/panel-novatek-nt35510.c DRM DRIVER FOR NOVATEK NT35560 PANELS -M: Linus Walleij +M: Linus Walleij S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml @@ -8033,7 +8135,7 @@ F: Documentation/devicetree/bindings/display/panel/raydium,rm67191.yaml F: drivers/gpu/drm/panel/panel-raydium-rm67191.c DRM DRIVER FOR SAMSUNG DB7430 PANELS -M: Linus Walleij +M: Linus Walleij S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml @@ -8061,12 +8163,25 @@ S: Maintained F: Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml F: drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c +DRM DRIVER FOR SAMSUNG S6E3FC2X01 DDIC +M: David Heidelberg +S: Maintained +F: Documentation/devicetree/bindings/display/panel/samsung,s6e3fc2x01.yaml +F: drivers/gpu/drm/panel/panel-samsung-s6e3fc2x01.c + DRM DRIVER FOR SAMSUNG S6E3HA8 PANELS M: Dzmitry Sankouski S: Maintained F: Documentation/devicetree/bindings/display/panel/samsung,s6e3ha8.yaml F: drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c +DRM DRIVER FOR SAMSUNG SOFEF00 DDIC +M: David Heidelberg +M: Casey Connolly +S: Maintained +F: Documentation/devicetree/bindings/display/panel/samsung,sofef00.yaml +F: drivers/gpu/drm/panel/panel-samsung-sofef00.c + DRM DRIVER FOR SHARP MEMORY LCD M: Alex Lanzano S: Maintained @@ -8117,7 +8232,7 @@ F: Documentation/devicetree/bindings/display/solomon,ssd13*.yaml F: drivers/gpu/drm/solomon/ssd130x* DRM DRIVER FOR ST-ERICSSON MCDE -M: Linus Walleij +M: Linus Walleij S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/ste,mcde.yaml @@ -8149,7 +8264,7 @@ F: Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml F: drivers/gpu/drm/bridge/ti-sn65dsi86.c DRM DRIVER FOR TPO TPG110 PANELS -M: Linus Walleij +M: Linus Walleij S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/panel/tpo,tpg110.yaml @@ -8193,7 +8308,7 @@ F: drivers/gpu/drm/vmwgfx/ F: include/uapi/drm/vmwgfx_drm.h DRM DRIVER FOR WIDECHIPS WS2401 PANELS -M: Linus Walleij +M: Linus Walleij S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml @@ -8251,12 +8366,12 @@ S: Supported W: https://drm.pages.freedesktop.org/maintainer-tools/drm-rust.html T: git https://gitlab.freedesktop.org/drm/rust/kernel.git F: drivers/gpu/drm/nova/ +F: drivers/gpu/drm/tyr/ F: drivers/gpu/nova-core/ F: rust/kernel/drm/ DRM DRIVERS FOR ALLWINNER A10 -M: Maxime Ripard -M: Chen-Yu Tsai +M: Chen-Yu Tsai L: dri-devel@lists.freedesktop.org S: Supported T: git https://gitlab.freedesktop.org/drm/misc/kernel.git @@ -8583,6 +8698,7 @@ S: Supported T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: drivers/gpu/drm/scheduler/ F: include/drm/gpu_scheduler.h +F: include/drm/spsc_queue.h DRM GPUVM M: Danilo Krummrich @@ -8605,7 +8721,7 @@ F: drivers/gpu/drm/clients/drm_log.c DRM PANEL DRIVERS M: Neil Armstrong -R: Jessica Zhang +R: Jessica Zhang L: dri-devel@lists.freedesktop.org S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git @@ -9490,7 +9606,7 @@ F: include/linux/fanotify.h F: include/uapi/linux/fanotify.h FARADAY FOTG210 USB2 DUAL-ROLE CONTROLLER -M: Linus Walleij +M: Linus Walleij L: linux-usb@vger.kernel.org S: Maintained F: drivers/usb/fotg210/ @@ -10011,7 +10127,7 @@ F: drivers/spi/spi-fsl-qspi.c FREESCALE QUICC ENGINE LIBRARY M: Qiang Zhao -M: Christophe Leroy +M: Christophe Leroy (CS GROUP) L: linuxppc-dev@lists.ozlabs.org S: Maintained F: drivers/soc/fsl/qe/ @@ -10064,7 +10180,7 @@ S: Maintained F: drivers/tty/serial/ucc_uart.c FREESCALE SOC DRIVERS -M: Christophe Leroy +M: Christophe Leroy (CS GROUP) L: linuxppc-dev@lists.ozlabs.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained @@ -10447,7 +10563,7 @@ F: include/uapi/asm-generic/ GENERIC PHY FRAMEWORK M: Vinod Koul -M: Kishon Vijay Abraham I +R: Neil Armstrong L: linux-phy@lists.infradead.org S: Supported Q: https://patchwork.kernel.org/project/linux-phy/list/ @@ -10608,8 +10724,9 @@ F: Documentation/devicetree/bindings/clock/google,gs101-clock.yaml F: Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml F: arch/arm64/boot/dts/exynos/google/ F: drivers/clk/samsung/clk-gs101.c +F: drivers/soc/samsung/gs101-pmu.c F: drivers/phy/samsung/phy-gs101-ufs.c -F: include/dt-bindings/clock/google,gs101.h +F: include/dt-bindings/clock/google,gs101* K: [gG]oogle.?[tT]ensor GPD FAN DRIVER @@ -10628,7 +10745,9 @@ F: drivers/platform/x86/gpd-pocket-fan.c GPIB DRIVERS M: Dave Penkler S: Maintained -F: drivers/staging/gpib/ +F: drivers/gpib/ +F: include/uapi/linux/gpib.h +F: include/uapi/linux/gpib_ioctl.h GPIO ACPI SUPPORT M: Mika Westerberg @@ -10677,7 +10796,7 @@ F: drivers/gpio/gpio-sloppy-logic-analyzer.c F: tools/gpio/gpio-sloppy-logic-analyzer.sh GPIO SUBSYSTEM -M: Linus Walleij +M: Linus Walleij M: Bartosz Golaszewski L: linux-gpio@vger.kernel.org S: Maintained @@ -11541,6 +11660,8 @@ F: mm/hugetlb.c F: mm/hugetlb_cgroup.c F: mm/hugetlb_cma.c F: mm/hugetlb_cma.h +F: mm/hugetlb_sysctl.c +F: mm/hugetlb_sysfs.c F: mm/hugetlb_vmemmap.c F: mm/hugetlb_vmemmap.h F: tools/testing/selftests/cgroup/test_hugetlb_memcg.c @@ -11558,6 +11679,8 @@ M: Miaohe Lin R: Naoya Horiguchi L: linux-mm@kvack.org S: Maintained +F: include/linux/memory-failure.h +F: include/trace/events/memory-failure.h F: mm/hwpoison-inject.c F: mm/memory-failure.c @@ -11582,7 +11705,7 @@ T: git git://linuxtv.org/media.git F: drivers/media/i2c/hi556.c HYNIX HI846 SENSOR DRIVER -M: Martin Kepplinger +M: Martin Kepplinger-Novakovic L: linux-media@vger.kernel.org S: Maintained F: drivers/media/i2c/hi846.c @@ -11598,6 +11721,7 @@ M: "K. Y. Srinivasan" M: Haiyang Zhang M: Wei Liu M: Dexuan Cui +M: Long Li L: linux-hyperv@vger.kernel.org S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git @@ -11615,6 +11739,7 @@ F: arch/x86/kernel/cpu/mshyperv.c F: drivers/clocksource/hyperv_timer.c F: drivers/hid/hid-hyperv.c F: drivers/hv/ +F: drivers/infiniband/hw/mana/ F: drivers/input/serio/hyperv-keyboard.c F: drivers/iommu/hyperv-iommu.c F: drivers/net/ethernet/microsoft/ @@ -11633,6 +11758,7 @@ F: include/hyperv/hvhdk_mini.h F: include/linux/hyperv.h F: include/net/mana F: include/uapi/linux/hyperv.h +F: include/uapi/rdma/mana-abi.h F: net/vmw_vsock/hyperv_transport.c F: tools/hv/ @@ -11667,6 +11793,7 @@ HUNG TASK DETECTOR M: Andrew Morton R: Lance Yang R: Masami Hiramatsu +R: Petr Mladek L: linux-kernel@vger.kernel.org S: Maintained F: include/linux/hung_task.h @@ -11745,6 +11872,16 @@ F: include/linux/i2c.h F: include/uapi/linux/i2c-*.h F: include/uapi/linux/i2c.h +I2C SUBSYSTEM [RUST] +M: Igor Korotin +R: Danilo Krummrich +R: Daniel Almeida +L: rust-for-linux@vger.kernel.org +S: Maintained +F: rust/kernel/i2c.rs +F: samples/rust/rust_driver_i2c.rs +F: samples/rust/rust_i2c_client.rs + I2C SUBSYSTEM HOST DRIVERS M: Andi Shyti L: linux-i2c@vger.kernel.org @@ -12224,11 +12361,13 @@ L: industrypack-devel@lists.sourceforge.net S: Maintained W: http://industrypack.sourceforge.net F: drivers/ipack/ +F: include/linux/ipack.h INFINEON DPS310 Driver M: Eddie James L: linux-iio@vger.kernel.org S: Maintained +F: Documentation/devicetree/bindings/iio/pressure/infineon,dps310.yaml F: drivers/iio/pressure/dps310.c INFINEON PEB2466 ASoC CODEC @@ -12507,6 +12646,13 @@ F: drivers/gpu/drm/xe/ F: include/drm/intel/ F: include/uapi/drm/xe_drm.h +INTEL ELKHART LAKE PSE I/O DRIVER +M: Raag Jadav +L: platform-driver-x86@vger.kernel.org +S: Supported +F: drivers/platform/x86/intel/ehl_pse_io.c +F: include/linux/ehl_pse_io_aux.h + INTEL ETHERNET DRIVERS M: Tony Nguyen M: Przemek Kitszel @@ -12622,7 +12768,7 @@ INTEL IPU3 CSI-2 CIO2 DRIVER M: Yong Zhi M: Sakari Ailus M: Bingbu Cao -M: Dan Scally +M: Dan Scally R: Tianshu Qiu L: linux-media@vger.kernel.org S: Maintained @@ -12744,7 +12890,7 @@ F: drivers/mfd/intel-m10-bmc* F: include/linux/mfd/intel-m10-bmc.h INTEL MAX10 BMC SECURE UPDATES -M: Matthew Gerlach +M: Xu Yilun L: linux-fpga@vger.kernel.org S: Maintained F: Documentation/ABI/testing/sysfs-driver-intel-m10-bmc-sec-update @@ -13043,8 +13189,16 @@ F: Documentation/ABI/testing/sysfs-bus-iio-inv_icm42600 F: Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml F: drivers/iio/imu/inv_icm42600/ +INVENSENSE ICM-456xx IMU DRIVER +M: Remi Buisson +L: linux-iio@vger.kernel.org +S: Maintained +W: https://invensense.tdk.com/ +F: Documentation/devicetree/bindings/iio/imu/invensense,icm45600.yaml +F: drivers/iio/imu/inv_icm45600/ + INVENSENSE MPU-3050 GYROSCOPE DRIVER -M: Linus Walleij +M: Linus Walleij L: linux-iio@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml @@ -13560,6 +13714,7 @@ R: Dai Ngo R: Tom Talpey L: linux-nfs@vger.kernel.org S: Supported +P: Documentation/filesystems/nfs/nfsd-maintainer-entry-profile.rst B: https://bugzilla.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git F: Documentation/filesystems/nfs/ @@ -13579,6 +13734,10 @@ F: include/uapi/linux/sunrpc/ F: net/sunrpc/ F: tools/net/sunrpc/ +KERNEL NFSD BLOCK and SCSI LAYOUT DRIVER +R: Christoph Hellwig +F: fs/nfsd/blocklayout* + KERNEL PACMAN PACKAGING (in addition to generic KERNEL BUILD) M: Thomas Weißschuh R: Christian Heusel @@ -13792,14 +13951,15 @@ F: kernel/kexec* KEXEC HANDOVER (KHO) M: Alexander Graf M: Mike Rapoport -M: Changyuan Lyu +M: Pasha Tatashin +R: Pratyush Yadav L: kexec@lists.infradead.org L: linux-mm@kvack.org S: Maintained F: Documentation/admin-guide/mm/kho.rst F: Documentation/core-api/kho/* F: include/linux/kexec_handover.h -F: kernel/kexec_handover.c +F: kernel/liveupdate/kexec_handover* F: lib/test_kho.c F: tools/testing/selftests/kho/ @@ -13968,7 +14128,7 @@ F: drivers/auxdisplay/ks0108.c F: include/linux/ks0108.h KTD253 BACKLIGHT DRIVER -M: Linus Walleij +M: Linus Walleij S: Maintained F: Documentation/devicetree/bindings/leds/backlight/kinetic,ktd253.yaml F: drivers/video/backlight/ktd253-backlight.c @@ -14180,7 +14340,7 @@ F: drivers/ata/pata_arasan_cf.c F: include/linux/pata_arasan_cf_data.h LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS -M: Linus Walleij +M: Linus Walleij L: linux-ide@vger.kernel.org S: Maintained F: drivers/ata/pata_ftide010.c @@ -14317,7 +14477,7 @@ LINUX FOR POWERPC (32-BIT AND 64-BIT) M: Madhavan Srinivasan M: Michael Ellerman R: Nicholas Piggin -R: Christophe Leroy +R: Christophe Leroy (CS GROUP) L: linuxppc-dev@lists.ozlabs.org S: Supported W: https://github.com/linuxppc/wiki/wiki @@ -14373,7 +14533,7 @@ F: Documentation/devicetree/bindings/powerpc/fsl/ F: arch/powerpc/platforms/85xx/ LINUX FOR POWERPC EMBEDDED PPC8XX AND PPC83XX -M: Christophe Leroy +M: Christophe Leroy (CS GROUP) L: linuxppc-dev@lists.ozlabs.org S: Maintained F: arch/powerpc/platforms/8xx/ @@ -14468,6 +14628,22 @@ F: samples/livepatch/ F: scripts/livepatch/ F: tools/testing/selftests/livepatch/ +LIVE UPDATE +M: Pasha Tatashin +M: Mike Rapoport +R: Pratyush Yadav +L: linux-kernel@vger.kernel.org +S: Maintained +F: Documentation/core-api/liveupdate.rst +F: Documentation/mm/memfd_preservation.rst +F: Documentation/userspace-api/liveupdate.rst +F: include/linux/liveupdate.h +F: include/linux/liveupdate/ +F: include/uapi/linux/liveupdate.h +F: kernel/liveupdate/ +F: mm/memfd_luo.c +F: tools/testing/selftests/liveupdate/ + LLC (802.2) L: netdev@vger.kernel.org S: Odd fixes @@ -14684,6 +14860,7 @@ LOONGSON-2K Board Management Controller (BMC) DRIVER M: Binbin Zhou M: Chong Qiao S: Maintained +F: drivers/char/ipmi/ipmi_si_ls2k.c F: drivers/mfd/ls2k-bmc-core.c LOONGSON EDAC DRIVER @@ -15182,6 +15359,15 @@ S: Orphan F: drivers/video/fbdev/matrox/matroxfb_* F: include/uapi/linux/matroxfb.h +MAX14001/MAX14002 IIO ADC DRIVER +M: Kim Seer Paller +M: Marilene Andrade Garcia +L: linux-iio@vger.kernel.org +S: Maintained +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/adc/adi,max14001.yaml +F: drivers/iio/adc/max14001.c + MAX15301 DRIVER M: Daniel Nilsson L: linux-hwmon@vger.kernel.org @@ -15189,6 +15375,15 @@ S: Maintained F: Documentation/hwmon/max15301.rst F: drivers/hwmon/pmbus/max15301.c +MAX17616 HARDWARE MONITOR DRIVER +M: Kim Seer Paller +L: linux-hwmon@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/hwmon/pmbus/adi,max17616.yaml +F: Documentation/hwmon/max17616.rst +F: drivers/hwmon/pmbus/max17616.c + MAX2175 SDR TUNER DRIVER M: Ramesh Shanmugasundaram L: linux-media@vger.kernel.org @@ -15545,6 +15740,8 @@ F: drivers/media/pci/ddbridge/* MEDIA DRIVERS FOR FREESCALE IMX M: Steve Longerbeam M: Philipp Zabel +R: Frank Li +L: imx@lists.linux.dev L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media.git @@ -15557,8 +15754,10 @@ F: include/media/imx.h MEDIA DRIVERS FOR FREESCALE IMX7/8 M: Rui Miguel Silva M: Laurent Pinchart -M: Martin Kepplinger +M: Martin Kepplinger-Novakovic R: Purism Kernel Team +R: Frank Li +L: imx@lists.linux.dev L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media.git @@ -16263,6 +16462,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm F: include/linux/gfp.h F: include/linux/gfp_types.h F: include/linux/highmem.h +F: include/linux/leafops.h F: include/linux/memory.h F: include/linux/mm.h F: include/linux/mm_*.h @@ -16270,6 +16470,7 @@ F: include/linux/mmzone.h F: include/linux/mmdebug.h F: include/linux/mmu_notifier.h F: include/linux/pagewalk.h +F: include/linux/pgalloc.h F: include/linux/pgtable.h F: include/linux/ptdump.h F: include/linux/vmpressure.h @@ -17413,6 +17614,7 @@ M: Luis Chamberlain M: Petr Pavlu M: Daniel Gomez R: Sami Tolvanen +R: Aaron Tomlin L: linux-modules@vger.kernel.org L: linux-kernel@vger.kernel.org S: Maintained @@ -17422,6 +17624,8 @@ F: include/linux/module*.h F: kernel/module/ F: lib/test_kmod.c F: lib/tests/module/ +F: rust/kernel/module_param.rs +F: rust/macros/module.rs F: scripts/module* F: tools/testing/selftests/kmod/ F: tools/testing/selftests/module/ @@ -17502,6 +17706,13 @@ S: Maintained F: Documentation/hwmon/mp2891.rst F: drivers/hwmon/pmbus/mp2891.c +MPS MP2925 DRIVER +M: Noah Wang +L: linux-hwmon@vger.kernel.org +S: Maintained +F: Documentation/hwmon/mp2925.rst +F: drivers/hwmon/pmbus/mp2925.c + MPS MP29502 DRIVER M: Wensheng Wang L: linux-hwmon@vger.kernel.org @@ -17523,6 +17734,13 @@ S: Maintained F: Documentation/hwmon/mp9941.rst F: drivers/hwmon/pmbus/mp9941.c +MPS MP9945 DRIVER +M: Cosmo Chou +L: linux-hwmon@vger.kernel.org +S: Maintained +F: Documentation/hwmon/mp9945.rst +F: drivers/hwmon/pmbus/mp9945.c + MR800 AVERMEDIA USB FM RADIO DRIVER M: Alexey Klimov L: linux-media@vger.kernel.org @@ -17810,7 +18028,6 @@ F: drivers/net/ethernet/neterion/ NETFILTER M: Pablo Neira Ayuso -M: Jozsef Kadlecsik M: Florian Westphal R: Phil Sutter L: netfilter-devel@vger.kernel.org @@ -18288,10 +18505,11 @@ F: net/sunrpc/ NILFS2 FILESYSTEM M: Ryusuke Konishi +M: Viacheslav Dubeyko L: linux-nilfs@vger.kernel.org -S: Supported +S: Maintained W: https://nilfs.sourceforge.io/ -T: git https://github.com/konis/nilfs2.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/nilfs2.git F: Documentation/filesystems/nilfs2.rst F: fs/nilfs2/ F: include/trace/events/nilfs2.h @@ -18481,6 +18699,13 @@ S: Maintained F: drivers/video/fbdev/nvidia/ F: drivers/video/fbdev/riva/ +NVIDIA VRS RTC DRIVER +M: Shubhi Garg +L: linux-tegra@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/rtc/nvidia,vrs-10.yaml +F: drivers/rtc/rtc-nvidia-vrs10.c + NVIDIA WMI EC BACKLIGHT DRIVER M: Daniel Dadap L: platform-driver-x86@vger.kernel.org @@ -18666,6 +18891,17 @@ S: Maintained F: Documentation/devicetree/bindings/regulator/nxp,pf5300.yaml F: drivers/regulator/pf530x-regulator.c +NXP PF1550 PMIC MFD DRIVER +M: Samuel Kayode +L: imx@lists.linux.dev +S: Maintained +F: Documentation/devicetree/bindings/mfd/nxp,pf1550.yaml +F: drivers/input/misc/pf1550-onkey.c +F: drivers/mfd/pf1550.c +F: drivers/power/supply/pf1550-charger.c +F: drivers/regulator/pf1550-regulator.c +F: include/linux/mfd/pf1550.h + NXP PF8100/PF8121A/PF8200 PMIC REGULATOR DEVICE DRIVER M: Jagan Teki S: Maintained @@ -18706,7 +18942,7 @@ NXP TFA9879 DRIVER M: Peter Rosin L: linux-sound@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/sound/nxp,tfa9879.yaml +F: Documentation/devicetree/bindings/sound/trivial-codec.yaml F: sound/soc/codecs/tfa9879* NXP-NCI NFC DRIVER @@ -18784,7 +19020,7 @@ OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER M: Frederic Barrat M: Andrew Donnellan L: linuxppc-dev@lists.ozlabs.org -S: Supported +S: Odd Fixes F: Documentation/userspace-api/accelerators/ocxl.rst F: arch/powerpc/include/asm/pnv-ocxl.h F: arch/powerpc/platforms/powernv/ocxl.c @@ -19034,10 +19270,9 @@ T: git git://linuxtv.org/media.git F: drivers/media/i2c/ov08d10.c OMNIVISION OV08X40 SENSOR DRIVER -M: Jason Chen +M: Jimmy Su L: linux-media@vger.kernel.org S: Maintained -T: git git://linuxtv.org/media.git F: drivers/media/i2c/ov08x40.c F: Documentation/devicetree/bindings/media/i2c/ovti,ov08x40.yaml @@ -19130,7 +19365,7 @@ F: Documentation/devicetree/bindings/media/i2c/ovti,ov5675.yaml F: drivers/media/i2c/ov5675.c OMNIVISION OV5693 SENSOR DRIVER -M: Daniel Scally +M: Daniel Scally L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media.git @@ -19684,6 +19919,13 @@ S: Orphan F: Documentation/devicetree/bindings/pci/cdns,* F: drivers/pci/controller/cadence/*cadence* +PCI DRIVER FOR CIX Sky1 +M: Hans Zhang +L: linux-pci@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/pci/cix,sky1-pcie-*.yaml +F: drivers/pci/controller/cadence/*sky1* + PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian M: Mingkai Hu @@ -19726,7 +19968,7 @@ F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml F: drivers/pci/controller/dwc/*imx6* PCI DRIVER FOR INTEL IXP4XX -M: Linus Walleij +M: Linus Walleij S: Maintained F: Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml F: drivers/pci/controller/pci-ixp4xx.c @@ -19837,7 +20079,7 @@ F: drivers/pci/controller/cadence/pci-j721e.c F: drivers/pci/controller/dwc/pci-dra7xx.c PCI DRIVER FOR V3 SEMICONDUCTOR V360EPC -M: Linus Walleij +M: Linus Walleij L: linux-pci@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pci/v3,v360epc-pci.yaml @@ -19934,6 +20176,7 @@ F: include/linux/pci-p2pdma.h PCI POWER CONTROL M: Bartosz Golaszewski +M: Manivannan Sadhasivam L: linux-pci@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git @@ -19948,6 +20191,7 @@ Q: https://patchwork.kernel.org/project/linux-pci/list/ B: https://bugzilla.kernel.org C: irc://irc.oftc.net/linux-pci T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git +F: Documentation/ABI/testing/sysfs-devices-pci-host-bridge F: Documentation/PCI/ F: Documentation/devicetree/bindings/pci/ F: arch/x86/kernel/early-quirks.c @@ -20070,6 +20314,14 @@ S: Maintained F: drivers/pci/controller/dwc/pcie-qcom-common.c F: drivers/pci/controller/dwc/pcie-qcom.c +PCIE DRIVER FOR RENESAS RZ/G3S SERIES +M: Claudiu Beznea +L: linux-pci@vger.kernel.org +L: linux-renesas-soc@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/pci/renesas,r9a08g045-pcie.yaml +F: drivers/pci/controller/pcie-rzg3s-host.c + PCIE DRIVER FOR ROCKCHIP M: Shawn Lin L: linux-pci@vger.kernel.org @@ -20283,7 +20535,7 @@ K: (?i)clone3 K: \b(clone_args|kernel_clone_args)\b PIN CONTROL SUBSYSTEM -M: Linus Walleij +M: Linus Walleij L: linux-gpio@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git @@ -20828,6 +21080,14 @@ F: include/linux/pwm.h F: include/linux/pwm_backlight.h K: pwm_(config|apply_might_sleep|apply_atomic|ops) +PWM SUBSYSTEM BINDINGS [RUST] +M: Michal Wilczynski +L: linux-pwm@vger.kernel.org +L: rust-for-linux@vger.kernel.org +S: Maintained +F: rust/helpers/pwm.c +F: rust/kernel/pwm.rs + PXA GPIO DRIVER M: Robert Jarzmik L: linux-gpio@vger.kernel.org @@ -21671,8 +21931,12 @@ F: tools/testing/selftests/rtc/ Real-time Linux Analysis (RTLA) tools M: Steven Rostedt +M: Tomas Glozar L: linux-trace-kernel@vger.kernel.org +L: linux-kernel@vger.kernel.org S: Maintained +Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git F: Documentation/tools/rtla/ F: tools/tracing/rtla/ @@ -21698,7 +21962,7 @@ F: Documentation/devicetree/bindings/watchdog/realtek,otto-wdt.yaml F: drivers/watchdog/realtek_otto_wdt.c REALTEK RTL83xx SMI DSA ROUTER CHIPS -M: Linus Walleij +M: Linus Walleij M: Alvin Šipraga S: Maintained F: Documentation/devicetree/bindings/net/dsa/realtek.yaml @@ -21925,6 +22189,14 @@ S: Supported F: Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml F: drivers/counter/rz-mtu3-cnt.c +RENESAS RZ/T2H / RZ/N2H A/D DRIVER +M: Cosmin Tanislav +L: linux-iio@vger.kernel.org +L: linux-renesas-soc@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/iio/adc/renesas,r9a09g077-adc.yaml +F: drivers/iio/adc/rzt2h_adc.c + RENESAS RTCA-3 RTC DRIVER M: Claudiu Beznea L: linux-rtc@vger.kernel.org @@ -21946,6 +22218,13 @@ F: include/dt-bindings/net/pcs-rzn1-miic.h F: include/linux/pcs-rzn1-miic.h F: net/dsa/tag_rzn1_a5psw.c +RENESAS RZ/N1 ADC DRIVER +M: Herve Codina +L: linux-renesas-soc@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/iio/adc/renesas,rzn1-adc.yaml +F: drivers/iio/adc/rzn1-adc.c + RENESAS RZ/N1 DWMAC GLUE LAYER M: Romain Gantois S: Maintained @@ -21976,6 +22255,13 @@ S: Maintained F: Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml F: drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c +RENESAS RZ/V2H(P) INPUT VIDEO CONTROL BLOCK DRIVER +M: Daniel Scally +L: linux-media@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/media/renesas,r9a09g057-ivc.yaml +F: drivers/media/platform/renesas/rzv2h-ivc/ + RENESAS RZ/V2H(P) RSPI DRIVER M: Fabrizio Castro L: linux-spi@vger.kernel.org @@ -22127,6 +22413,14 @@ F: Documentation/devicetree/bindings/riscv/andes.yaml F: Documentation/devicetree/bindings/timer/andestech,plmt0.yaml F: arch/riscv/boot/dts/andes/ +RISC-V ANLOGIC SoC SUPPORT +M: Conor Dooley +T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ +L: linux-riscv@lists.infradead.org +S: Odd Fixes +F: Documentation/devicetree/bindings/riscv/anlogic.yaml +F: arch/riscv/boot/dts/anlogic/ + RISC-V ARCHITECTURE M: Paul Walmsley M: Palmer Dabbelt @@ -22151,16 +22445,19 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git F: Documentation/devicetree/bindings/iommu/riscv,iommu.yaml F: drivers/iommu/riscv/ -RISC-V MICROCHIP FPGA SUPPORT +RISC-V MICROCHIP SUPPORT M: Conor Dooley M: Daire McNamara L: linux-riscv@lists.infradead.org S: Supported +T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ (dts, soc, firmware) F: Documentation/devicetree/bindings/clock/microchip,mpfs*.yaml F: Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml F: Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml F: Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml F: Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml +F: Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml +F: Documentation/devicetree/bindings/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml F: Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml F: Documentation/devicetree/bindings/riscv/microchip.yaml F: Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml @@ -22174,25 +22471,26 @@ F: drivers/gpio/gpio-mpfs.c F: drivers/i2c/busses/i2c-microchip-corei2c.c F: drivers/mailbox/mailbox-mpfs.c F: drivers/pci/controller/plda/pcie-microchip-host.c +F: drivers/pinctrl/pinctrl-mpfs-iomux0.c +F: drivers/pinctrl/pinctrl-pic64gx-gpio2.c F: drivers/pwm/pwm-microchip-core.c F: drivers/reset/reset-mpfs.c F: drivers/rtc/rtc-mpfs.c +F: drivers/soc/microchip/mpfs-control-scb.c +F: drivers/soc/microchip/mpfs-mss-top-sysreg.c F: drivers/soc/microchip/mpfs-sys-controller.c F: drivers/spi/spi-microchip-core-qspi.c -F: drivers/spi/spi-microchip-core.c +F: drivers/spi/spi-mpfs.c F: drivers/usb/musb/mpfs.c F: include/soc/microchip/mpfs.h RISC-V MISC SOC SUPPORT M: Conor Dooley L: linux-riscv@lists.infradead.org -S: Maintained -Q: https://patchwork.kernel.org/project/linux-riscv/list/ +S: Odd Fixes T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ F: arch/riscv/boot/dts/canaan/ -F: arch/riscv/boot/dts/microchip/ F: arch/riscv/boot/dts/sifive/ -F: arch/riscv/boot/dts/starfive/ RISC-V PMU DRIVERS M: Atish Patra @@ -22230,6 +22528,15 @@ F: arch/riscv/boot/dts/spacemit/ N: spacemit K: spacemit +RISC-V TENSTORRENT SoC SUPPORT +M: Drew Fustini +M: Joel Stanley +L: linux-riscv@lists.infradead.org +S: Maintained +T: git https://github.com/tenstorrent/linux.git +F: Documentation/devicetree/bindings/riscv/tenstorrent.yaml +F: arch/riscv/boot/dts/tenstorrent/ + RISC-V THEAD SoC SUPPORT M: Drew Fustini M: Guo Ren @@ -22243,6 +22550,7 @@ F: Documentation/devicetree/bindings/firmware/thead,th1520-aon.yaml F: Documentation/devicetree/bindings/mailbox/thead,th1520-mbox.yaml F: Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml F: Documentation/devicetree/bindings/pinctrl/thead,th1520-pinctrl.yaml +F: Documentation/devicetree/bindings/pwm/thead,th1520-pwm.yaml F: Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml F: arch/riscv/boot/dts/thead/ F: drivers/clk/thead/clk-th1520-ap.c @@ -22253,6 +22561,7 @@ F: drivers/pinctrl/pinctrl-th1520.c F: drivers/pmdomain/thead/ F: drivers/power/reset/th1520-aon-reboot.c F: drivers/power/sequencing/pwrseq-thead-gpu.c +F: drivers/pwm/pwm_th1520.rs F: drivers/reset/reset-th1520.c F: include/dt-bindings/clock/thead,th1520-clk-ap.h F: include/dt-bindings/power/thead,th1520-power.h @@ -22282,6 +22591,16 @@ S: Maintained F: Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml F: drivers/net/can/rockchip/ +ROCKCHIP CAMERA INTERFACE (RKCIF) DRIVER +M: Mehdi Djait +M: Michael Riesch +L: linux-media@vger.kernel.org +S: Maintained +F: Documentation/admin-guide/media/rkcif* +F: Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml +F: Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml +F: drivers/media/platform/rockchip/rkcif/ + ROCKCHIP CRYPTO DRIVERS M: Corentin Labbe L: linux-crypto@vger.kernel.org @@ -22361,6 +22680,12 @@ L: linux-serial@vger.kernel.org S: Odd Fixes F: drivers/tty/serial/rp2.* +ROHM BD71828 CHARGER +M: Andreas Kemnade +M: Matti Vaittinen +S: Maintained +F: drivers/power/supply/bd71828-charger.c + ROHM BD79703 DAC M: Matti Vaittinen S: Supported @@ -22540,6 +22865,7 @@ F: Documentation/trace/rv/ F: include/linux/rv.h F: include/rv/ F: kernel/trace/rv/ +F: tools/testing/selftests/verification/ F: tools/verification/ RUST @@ -22840,6 +23166,7 @@ L: linux-kernel@vger.kernel.org L: linux-samsung-soc@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml +F: drivers/clk/samsung/clk-acpm.c F: drivers/firmware/samsung/exynos-acpm* F: include/linux/firmware/samsung/exynos-acpm-protocol.h @@ -23120,6 +23447,7 @@ F: drivers/scsi/ F: drivers/ufs/ F: include/scsi/ F: include/uapi/scsi/ +F: include/ufs/ SCSI TAPE DRIVER M: Kai Mäkisara @@ -23459,7 +23787,7 @@ S: Supported F: net/smc/ SHARP GP2AP002A00F/GP2AP002S00F SENSOR DRIVER -M: Linus Walleij +M: Linus Walleij L: linux-iio@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git @@ -24305,6 +24633,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git F: Documentation/devicetree/bindings/spi/ F: Documentation/spi/ F: drivers/spi/ +F: include/trace/events/spi* F: include/linux/spi/ F: include/uapi/linux/spi/ F: tools/spi/ @@ -24412,6 +24741,14 @@ S: Maintained F: Documentation/hwmon/stpddc60.rst F: drivers/hwmon/pmbus/stpddc60.c +ST TSC1641 DRIVER +M: Igor Reznichenko +L: linux-hwmon@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/hwmon/st,tsc1641.yaml +F: Documentation/hwmon/tsc1641.rst +F: drivers/hwmon/tsc1641.c + ST VD55G1 DRIVER M: Benjamin Mugnier M: Sylvain Petinot @@ -24496,10 +24833,13 @@ F: drivers/staging/ STANDALONE CACHE CONTROLLER DRIVERS M: Conor Dooley +M: Jonathan Cameron S: Maintained T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ F: Documentation/devicetree/bindings/cache/ F: drivers/cache +F: include/linux/cache_coherency.h +F: lib/cache_maint.c STARFIRE/DURALAN NETWORK DRIVER M: Ion Badulescu @@ -24524,7 +24864,10 @@ F: drivers/crypto/starfive/ STARFIVE DEVICETREES M: Emil Renner Berthing +M: Conor Dooley +L: linux-riscv@lists.infradead.org S: Maintained +T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ F: arch/riscv/boot/dts/starfive/ STARFIVE DWMAC GLUE LAYER @@ -24873,7 +25216,6 @@ F: drivers/regulator/sy8106a-regulator.c SYNC FILE FRAMEWORK M: Sumit Semwal -R: Gustavo Padovan L: linux-media@vger.kernel.org L: dri-devel@lists.freedesktop.org S: Maintained @@ -24973,7 +25315,7 @@ F: drivers/net/pcs/pcs-xpcs.h F: include/linux/pcs/pcs-xpcs.h SYNOPSYS DESIGNWARE HDMI RX CONTROLLER DRIVER -M: Shreeya Patel +M: Dmitry Osipenko L: linux-media@vger.kernel.org L: kernel@collabora.com S: Maintained @@ -24998,6 +25340,7 @@ F: include/linux/soc/amd/isp4_misc.h SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER M: Jaehoon Chung +M: Shawn Lin L: linux-mmc@vger.kernel.org S: Maintained F: drivers/mmc/host/dw_mmc* @@ -25166,7 +25509,7 @@ L: linux-media@vger.kernel.org S: Maintained W: https://linuxtv.org Q: http://patchwork.linuxtv.org/project/linux-media/list/ -F: Documentation/devicetree/bindings/media/i2c/nxp,tda1997x.txt +F: Documentation/devicetree/bindings/media/i2c/nxp,tda19971.yaml F: drivers/media/i2c/tda1997x.* TDA827x MEDIA DRIVER @@ -26077,7 +26420,7 @@ M: Jarkko Sakkinen R: Jason Gunthorpe L: linux-integrity@vger.kernel.org S: Maintained -W: https://codeberg.org/jarkko/linux-tpmdd-test +W: https://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd-test.git/about/ Q: https://patchwork.kernel.org/project/linux-integrity/list/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git F: Documentation/devicetree/bindings/tpm/ @@ -26120,6 +26463,7 @@ L: linux-trace-kernel@vger.kernel.org S: Maintained Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git +F: Documentation/core-api/tracepoint.rst F: Documentation/trace/* F: fs/tracefs/ F: include/linux/trace*.h @@ -26127,6 +26471,7 @@ F: include/trace/ F: kernel/trace/ F: kernel/tracepoint.c F: scripts/tracing/ +F: scripts/tracepoint-update.c F: tools/testing/selftests/ftrace/ TRACING MMIO ACCESSES (MMIOTRACE) @@ -26167,14 +26512,16 @@ M: David Lechner S: Maintained F: Documentation/devicetree/bindings/trigger-source/* -TRUSTED SECURITY MODULE (TSM) INFRASTRUCTURE +TRUSTED EXECUTION ENVIRONMENT SECURITY MANAGER (TSM) M: Dan Williams L: linux-coco@lists.linux.dev S: Maintained F: Documentation/ABI/testing/configfs-tsm-report F: Documentation/driver-api/coco/ +F: Documentation/driver-api/pci/tsm.rst +F: drivers/pci/tsm.c F: drivers/virt/coco/guest/ -F: include/linux/tsm*.h +F: include/linux/*tsm*.h F: samples/tsm-mr/ TRUSTED SERVICES TEE DRIVER @@ -26419,6 +26766,14 @@ S: Supported F: Documentation/devicetree/bindings/ufs/ F: Documentation/scsi/ufs.rst F: drivers/ufs/core/ +F: include/ufs/ + +UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER AMD VERSAL2 +M: Sai Krishna Potthuri +M: Ajay Neeli +S: Maintained +F: Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml +F: drivers/ufs/host/ufs-amd-versal2.c UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER DWC HOOKS M: Pedro Sousa @@ -26436,6 +26791,7 @@ F: drivers/ufs/host/ufs-exynos* UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER MEDIATEK HOOKS M: Peter Wang +M: Chaotian Jing R: Stanley Jhu L: linux-scsi@vger.kernel.org L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) @@ -26457,6 +26813,17 @@ L: linux-scsi@vger.kernel.org S: Maintained F: drivers/ufs/host/ufs-renesas.c +UNIWILL LAPTOP DRIVER +M: Armin Wolf +L: platform-driver-x86@vger.kernel.org +S: Maintained +F: Documentation/ABI/testing/sysfs-driver-uniwill-laptop +F: Documentation/admin-guide/laptops/uniwill-laptop.rst +F: Documentation/wmi/devices/uniwill-laptop.rst +F: drivers/platform/x86/uniwill/uniwill-acpi.c +F: drivers/platform/x86/uniwill/uniwill-wmi.c +F: drivers/platform/x86/uniwill/uniwill-wmi.h + UNSORTED BLOCK IMAGES (UBI) M: Richard Weinberger R: Zhihao Cheng @@ -26934,6 +27301,16 @@ F: drivers/media/i2c/vd55g1.c F: drivers/media/i2c/vd56g3.c F: drivers/media/i2c/vgxy61.c +V4L2 GENERIC ISP PARAMETERS AND STATISTIC FORMATS +M: Jacopo Mondi +L: linux-media@vger.kernel.org +S: Maintained +F: Documentation/driver-api/media/v4l2-isp.rst +F: Documentation/userspace-api/media/v4l/v4l2-isp.rst +F: drivers/media/v4l2-core/v4l2-isp.c +F: include/media/v4l2-isp.h +F: include/uapi/linux/media/v4l2-isp.h + VF610 NAND DRIVER M: Stefan Agner L: linux-mtd@lists.infradead.org @@ -27045,6 +27422,13 @@ L: virtualization@lists.linux.dev S: Maintained F: drivers/vfio/pci/virtio +VFIO XE PCI DRIVER +M: Michał Winiarski +L: kvm@vger.kernel.org +L: intel-xe@lists.freedesktop.org +S: Supported +F: drivers/vfio/pci/xe + VGA_SWITCHEROO R: Lukas Wunner S: Maintained @@ -27286,7 +27670,7 @@ F: drivers/virtio/virtio_input.c F: include/uapi/linux/virtio_input.h VIRTIO IOMMU DRIVER -M: Jean-Philippe Brucker +M: Jean-Philippe Brucker L: virtualization@lists.linux.dev S: Maintained F: drivers/iommu/virtio-iommu.c @@ -27536,6 +27920,7 @@ F: drivers/regulator/ F: rust/kernel/regulator.rs F: include/dt-bindings/regulator/ F: include/linux/regulator/ +F: include/uapi/regulator/ K: regulator_get_optional VOLTAGE AND CURRENT REGULATOR IRQ HELPERS @@ -27730,6 +28115,7 @@ F: Documentation/devicetree/bindings/extcon/wlf,arizona.yaml F: Documentation/devicetree/bindings/mfd/wlf,arizona.yaml F: Documentation/devicetree/bindings/mfd/wm831x.txt F: Documentation/devicetree/bindings/regulator/wlf,arizona.yaml +F: Documentation/devicetree/bindings/sound/trivial-codec.yaml F: Documentation/devicetree/bindings/sound/wlf,*.yaml F: Documentation/devicetree/bindings/sound/wm* F: Documentation/hwmon/wm83??.rst @@ -27789,7 +28175,7 @@ F: drivers/acpi/pmic/intel_pmic_xpower.c N: axp288 X-POWERS MULTIFUNCTION PMIC DEVICE DRIVERS -M: Chen-Yu Tsai +M: Chen-Yu Tsai L: linux-kernel@vger.kernel.org S: Maintained N: axp[128] @@ -27936,6 +28322,7 @@ M: Matthew Wilcox L: linux-fsdevel@vger.kernel.org L: linux-mm@kvack.org S: Supported +F: Documentation/core-api/idr.rst F: Documentation/core-api/xarray.rst F: include/linux/idr.h F: include/linux/xarray.h diff --git a/Makefile b/Makefile index e61f1300fea0d..27ce077520fe1 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 -PATCHLEVEL = 18 +PATCHLEVEL = 19 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc3 NAME = Baby Opossum Posse # *DOCUMENTATION* @@ -810,6 +810,25 @@ ifdef CONFIG_FUNCTION_TRACER CC_FLAGS_FTRACE := -pg endif +ifdef CONFIG_TRACEPOINTS +# To check for unused tracepoints (tracepoints that are defined but never +# called), run with: +# +# make UT=1 +# +# Each unused tracepoints can take up to 5KB of memory in the running kernel. +# It is best to remove any that are not used. +# +# This command line option will be removed when all current unused +# tracepoints are removed. + +ifeq ("$(origin UT)", "command line") + WARN_ON_UNUSED_TRACEPOINTS := $(UT) +endif +endif # CONFIG_TRACEPOINTS + +export WARN_ON_UNUSED_TRACEPOINTS + include $(srctree)/arch/$(SRCARCH)/Makefile ifdef need-config @@ -940,6 +959,9 @@ KBUILD_CFLAGS += $(call cc-option,-fzero-init-padding-bits=all) # for the randomize_kstack_offset feature. Disable it for all compilers. KBUILD_CFLAGS += $(call cc-option, -fno-stack-clash-protection) +# Get details on warnings generated due to GCC value tracking. +KBUILD_CFLAGS += $(call cc-option, -fdiagnostics-show-context=2) + # Clear used registers at func exit (to reduce data lifetime and ROP gadgets). ifdef CONFIG_ZERO_CALL_USED_REGS KBUILD_CFLAGS += -fzero-call-used-regs=used-gpr @@ -1784,6 +1806,8 @@ help: @echo ' c: extra checks in the configuration stage (Kconfig)' @echo ' e: warnings are being treated as errors' @echo ' Multiple levels can be combined with W=12 or W=123' + @echo ' make UT=1 [targets] Warn if a tracepoint is defined but not used.' + @echo ' [ This will be removed when all current unused tracepoints are eliminated. ]' @$(if $(dtstree), \ echo ' make CHECK_DTBS=1 [targets] Check all generated dtb files against schema'; \ echo ' This can be applied both to "dtbs" and to individual "foo.dtb" targets' ; \ diff --git a/arch/Kconfig b/arch/Kconfig index 61130b88964b9..31220f512b16d 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -232,17 +232,14 @@ config HAVE_EFFICIENT_UNALIGNED_ACCESS config ARCH_USE_BUILTIN_BSWAP bool help - Modern versions of GCC (since 4.4) have builtin functions - for handling byte-swapping. Using these, instead of the old - inline assembler that the architecture code provides in the - __arch_bswapXX() macros, allows the compiler to see what's - happening and offers more opportunity for optimisation. In - particular, the compiler will be able to combine the byteswap - with a nearby load or store and use load-and-swap or - store-and-swap instructions if the architecture has them. It - should almost *never* result in code which is worse than the - hand-coded assembler in . But just in case it - does, the use of the builtins is optional. + GCC and Clang have builtin functions for handling byte-swapping. + Using these allows the compiler to see what's happening and + offers more opportunity for optimisation. In particular, the + compiler will be able to combine the byteswap with a nearby load + or store and use load-and-swap or store-and-swap instructions if + the architecture has them. It should almost *never* result in code + which is worse than the hand-coded assembler in . + But just in case it does, the use of the builtins is optional. Any architecture with load-and-swap or store-and-swap instructions should set this. And it shouldn't hurt to set it diff --git a/arch/alpha/include/asm/console.h b/arch/alpha/include/asm/console.h index 088b7b9eb15ae..1cabdb6064bbe 100644 --- a/arch/alpha/include/asm/console.h +++ b/arch/alpha/include/asm/console.h @@ -4,7 +4,7 @@ #include -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ extern long callback_puts(long unit, const char *s, long length); extern long callback_getc(long unit); extern long callback_open_console(void); @@ -26,5 +26,5 @@ struct crb_struct; struct hwrpb_struct; extern int callback_init_done; extern void * callback_init(void *); -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __AXP_CONSOLE_H */ diff --git a/arch/alpha/include/asm/page.h b/arch/alpha/include/asm/page.h index 5ec4c77e432e0..d2c6667d73e9e 100644 --- a/arch/alpha/include/asm/page.h +++ b/arch/alpha/include/asm/page.h @@ -6,7 +6,7 @@ #include #include -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #define STRICT_MM_TYPECHECKS @@ -74,7 +74,7 @@ typedef struct page *pgtable_t; #define PAGE_OFFSET 0xfffffc0000000000 #endif -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) diff --git a/arch/alpha/include/asm/pal.h b/arch/alpha/include/asm/pal.h index db2b3b18b34c7..799a64c051984 100644 --- a/arch/alpha/include/asm/pal.h +++ b/arch/alpha/include/asm/pal.h @@ -4,7 +4,7 @@ #include -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ extern void halt(void) __attribute__((noreturn)); #define __halt() __asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt)) @@ -183,5 +183,5 @@ qemu_get_vmtime(void) return v0; } -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ #endif /* __ALPHA_PAL_H */ diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h index 4a4d00b37986e..98ccbca64984c 100644 --- a/arch/alpha/include/asm/thread_info.h +++ b/arch/alpha/include/asm/thread_info.h @@ -4,14 +4,14 @@ #ifdef __KERNEL__ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include #include #include #include #endif -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ struct thread_info { struct pcb_struct pcb; /* palcode state */ @@ -44,7 +44,7 @@ register struct thread_info *__current_thread_info __asm__("$8"); register unsigned long *current_stack_pointer __asm__ ("$30"); -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ /* Thread information allocation. */ #define THREAD_SIZE_ORDER 1 @@ -110,7 +110,7 @@ register unsigned long *current_stack_pointer __asm__ ("$30"); put_user(res, (int __user *)(value)); \ }) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ extern void __save_fpu(void); static inline void save_fpu(void) diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h index 971311605288f..a09d04b49cc65 100644 --- a/arch/alpha/include/uapi/asm/ioctls.h +++ b/arch/alpha/include/uapi/asm/ioctls.h @@ -23,10 +23,10 @@ #define TCSETSW _IOW('t', 21, struct termios) #define TCSETSF _IOW('t', 22, struct termios) -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) +#define TCGETA 0x40127417 +#define TCSETA 0x80127418 +#define TCSETAW 0x80127419 +#define TCSETAF 0x8012741c #define TCSBRK _IO('t', 29) #define TCXONC _IO('t', 30) diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index dc91de50f906d..955b6ca616276 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -224,28 +224,26 @@ static int pci_dac_dma_supported(struct pci_dev *dev, u64 mask) until either pci_unmap_single or pci_dma_sync_single is performed. */ static dma_addr_t -pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, +pci_map_single_1(struct pci_dev *pdev, phys_addr_t paddr, size_t size, int dac_allowed) { struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose; dma_addr_t max_dma = pdev ? pdev->dma_mask : ISA_DMA_MASK; + unsigned long offset = offset_in_page(paddr); struct pci_iommu_arena *arena; long npages, dma_ofs, i; - unsigned long paddr; dma_addr_t ret; unsigned int align = 0; struct device *dev = pdev ? &pdev->dev : NULL; - paddr = __pa(cpu_addr); - #if !DEBUG_NODIRECT /* First check to see if we can use the direct map window. */ if (paddr + size + __direct_map_base - 1 <= max_dma && paddr + size <= __direct_map_size) { ret = paddr + __direct_map_base; - DBGA2("pci_map_single: [%p,%zx] -> direct %llx from %ps\n", - cpu_addr, size, ret, __builtin_return_address(0)); + DBGA2("pci_map_single: [%pa,%zx] -> direct %llx from %ps\n", + &paddr, size, ret, __builtin_return_address(0)); return ret; } @@ -255,8 +253,8 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, if (dac_allowed) { ret = paddr + alpha_mv.pci_dac_offset; - DBGA2("pci_map_single: [%p,%zx] -> DAC %llx from %ps\n", - cpu_addr, size, ret, __builtin_return_address(0)); + DBGA2("pci_map_single: [%pa,%zx] -> DAC %llx from %ps\n", + &paddr, size, ret, __builtin_return_address(0)); return ret; } @@ -290,10 +288,10 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, arena->ptes[i + dma_ofs] = mk_iommu_pte(paddr); ret = arena->dma_base + dma_ofs * PAGE_SIZE; - ret += (unsigned long)cpu_addr & ~PAGE_MASK; + ret += offset; - DBGA2("pci_map_single: [%p,%zx] np %ld -> sg %llx from %ps\n", - cpu_addr, size, npages, ret, __builtin_return_address(0)); + DBGA2("pci_map_single: [%pa,%zx] np %ld -> sg %llx from %ps\n", + &paddr, size, npages, ret, __builtin_return_address(0)); return ret; } @@ -322,19 +320,18 @@ static struct pci_dev *alpha_gendev_to_pci(struct device *dev) return NULL; } -static dma_addr_t alpha_pci_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, +static dma_addr_t alpha_pci_map_phys(struct device *dev, phys_addr_t phys, + size_t size, enum dma_data_direction dir, unsigned long attrs) { struct pci_dev *pdev = alpha_gendev_to_pci(dev); int dac_allowed; - BUG_ON(dir == DMA_NONE); + if (unlikely(attrs & DMA_ATTR_MMIO)) + return DMA_MAPPING_ERROR; - dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; - return pci_map_single_1(pdev, (char *)page_address(page) + offset, - size, dac_allowed); + dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; + return pci_map_single_1(pdev, phys, size, dac_allowed); } /* Unmap a single streaming mode DMA translation. The DMA_ADDR and @@ -343,7 +340,7 @@ static dma_addr_t alpha_pci_map_page(struct device *dev, struct page *page, the cpu to the buffer are guaranteed to see whatever the device wrote there. */ -static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr, +static void alpha_pci_unmap_phys(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir, unsigned long attrs) { @@ -353,8 +350,6 @@ static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr, struct pci_iommu_arena *arena; long dma_ofs, npages; - BUG_ON(dir == DMA_NONE); - if (dma_addr >= __direct_map_base && dma_addr < __direct_map_base + __direct_map_size) { /* Nothing to do. */ @@ -429,7 +424,7 @@ static void *alpha_pci_alloc_coherent(struct device *dev, size_t size, } memset(cpu_addr, 0, size); - *dma_addrp = pci_map_single_1(pdev, cpu_addr, size, 0); + *dma_addrp = pci_map_single_1(pdev, virt_to_phys(cpu_addr), size, 0); if (*dma_addrp == DMA_MAPPING_ERROR) { free_pages((unsigned long)cpu_addr, order); if (alpha_mv.mv_pci_tbi || (gfp & GFP_DMA)) @@ -643,9 +638,8 @@ static int alpha_pci_map_sg(struct device *dev, struct scatterlist *sg, /* Fast path single entry scatterlists. */ if (nents == 1) { sg->dma_length = sg->length; - sg->dma_address - = pci_map_single_1(pdev, SG_ENT_VIRT_ADDRESS(sg), - sg->length, dac_allowed); + sg->dma_address = pci_map_single_1(pdev, sg_phys(sg), + sg->length, dac_allowed); if (sg->dma_address == DMA_MAPPING_ERROR) return -EIO; return 1; @@ -917,8 +911,8 @@ iommu_unbind(struct pci_iommu_arena *arena, long pg_start, long pg_count) const struct dma_map_ops alpha_pci_ops = { .alloc = alpha_pci_alloc_coherent, .free = alpha_pci_free_coherent, - .map_page = alpha_pci_map_page, - .unmap_page = alpha_pci_unmap_page, + .map_phys = alpha_pci_map_phys, + .unmap_phys = alpha_pci_unmap_phys, .map_sg = alpha_pci_map_sg, .unmap_sg = alpha_pci_unmap_sg, .dma_supported = alpha_pci_supported, diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4fb985b76e97f..fa83c040ee2d4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -82,7 +82,7 @@ config ARM select HAS_IOPORT select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 - select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU + select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU && (!PREEMPT_RT || !SMP) select HAVE_ARCH_KFENCE if MMU && !XIP_KERNEL select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL @@ -1161,8 +1161,6 @@ config AEABI disambiguate both ABIs and allow for backward compatibility support (selected with CONFIG_OABI_COMPAT). - To use this you need GCC version 4.0.0 or later. - config OABI_COMPAT bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)" depends on AEABI && !THUMB2_KERNEL @@ -1215,7 +1213,7 @@ config HIGHMEM config HIGHPTE bool "Allocate 2nd-level pagetables from highmem" if EXPERT - depends on HIGHMEM + depends on HIGHMEM && !PREEMPT_RT default y help The VM uses one page of physical memory for each page table. diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile index 0f0b5b7076545..9adf9278dc94f 100644 --- a/arch/arm/boot/dts/aspeed/Makefile +++ b/arch/arm/boot/dts/aspeed/Makefile @@ -39,6 +39,8 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-bmc-facebook-yamp.dtb \ aspeed-bmc-facebook-yosemitev2.dtb \ aspeed-bmc-facebook-yosemite4.dtb \ + aspeed-bmc-facebook-yosemite5.dtb \ + aspeed-bmc-ibm-balcones.dtb \ aspeed-bmc-ibm-blueridge.dtb \ aspeed-bmc-ibm-bonnell.dtb \ aspeed-bmc-ibm-everest.dtb \ diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-clemente.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-clemente.dts index ecef44d899777..450446913e36b 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-clemente.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-clemente.dts @@ -95,6 +95,11 @@ label = "bmc_ready_cpld_noled"; gpios = <&gpio0 ASPEED_GPIO(P, 5) (GPIO_ACTIVE_HIGH|GPIO_TRANSITORY)>; }; + + led-hdd { + label = "hdd_led"; + gpios = <&io_expander13 1 GPIO_ACTIVE_LOW>; + }; }; memory@80000000 { @@ -642,12 +647,14 @@ power-monitor@12 { compatible = "ti,lm5066i"; reg = <0x12>; + shunt-resistor-micro-ohms = <183>; }; // PDB power-monitor@14 { compatible = "ti,lm5066i"; reg = <0x14>; + shunt-resistor-micro-ohms = <183>; }; // Module 0 @@ -1197,7 +1204,7 @@ #gpio-cells = <2>; gpio-line-names = "rmc_en_dc_pwr_on", - "", + "HDD_LED_N", "", "", "", diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts index b733efe31e8d2..1c50e4a367b24 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts @@ -240,6 +240,14 @@ &i2c1 { status = "okay"; + mctp-controller; + multi-master; + + mctp@10 { + compatible = "mctp-i2c-controller"; + reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>; + }; + temperature-sensor@4b { compatible = "ti,tmp75"; reg = <0x4b>; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-santabarbara.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-santabarbara.dts index 72c84f31bdf64..f74f463cc8781 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-santabarbara.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-santabarbara.dts @@ -39,6 +39,38 @@ i2c37 = &i2c12mux0ch5; i2c38 = &i2c12mux0ch6; i2c39 = &i2c12mux0ch7; + i2c48 = &i2c6mux0ch0; + i2c49 = &i2c6mux0ch1; + i2c50 = &i2c6mux0ch2; + i2c51 = &i2c6mux0ch3; + i2c52 = &i2c8mux0ch0; + i2c53 = &i2c8mux0ch1; + i2c54 = &i2c8mux0ch2; + i2c55 = &i2c8mux0ch3; + i2c56 = &i2c10mux0ch0; + i2c57 = &i2c10mux0ch1; + i2c58 = &i2c10mux0ch2; + i2c59 = &i2c10mux0ch3; + i2c60 = &i2c13mux0ch0; + i2c61 = &i2c13mux0ch1; + i2c62 = &i2c13mux0ch2; + i2c63 = &i2c13mux0ch3; + i2c64 = &i2c6mux1ch0; + i2c65 = &i2c6mux1ch1; + i2c66 = &i2c6mux1ch2; + i2c67 = &i2c6mux1ch3; + i2c68 = &i2c8mux1ch0; + i2c69 = &i2c8mux1ch1; + i2c70 = &i2c8mux1ch2; + i2c71 = &i2c8mux1ch3; + i2c72 = &i2c10mux1ch0; + i2c73 = &i2c10mux1ch1; + i2c74 = &i2c10mux1ch2; + i2c75 = &i2c10mux1ch3; + i2c76 = &i2c13mux1ch0; + i2c77 = &i2c13mux1ch1; + i2c78 = &i2c13mux1ch2; + i2c79 = &i2c13mux1ch3; }; chosen { @@ -72,6 +104,11 @@ default-state = "off"; gpios = <&gpio0 ASPEED_GPIO(P, 4) GPIO_ACTIVE_HIGH>; }; + + led-3 { + label = "bmc_ready_noled"; + gpios = <&gpio0 ASPEED_GPIO(B, 3) (GPIO_ACTIVE_HIGH|GPIO_TRANSITORY)>; + }; }; memory@80000000 { @@ -171,7 +208,7 @@ "led-postcode-2","led-postcode-3", "led-postcode-4","led-postcode-5", "led-postcode-6","led-postcode-7", - /*O0-O7*/ "","","","","","","","", + /*O0-O7*/ "","","","","","","","debug-card-mux", /*P0-P7*/ "power-button","","reset-button","", "led-power","","","", /*Q0-Q7*/ "","","","","","","","", @@ -292,6 +329,20 @@ }; }; +&i2c3 { + status = "okay"; + + sbrmi@3c { + compatible = "amd,sbrmi"; + reg = <0x3c>; + }; + + sbtsi@4c { + compatible = "amd,sbtsi"; + reg = <0x4c>; + }; +}; + &i2c4 { status = "okay"; @@ -319,16 +370,19 @@ reg = <0x53>; }; }; + i2c4mux0ch1: i2c@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; }; + i2c4mux0ch2: i2c@2 { reg = <2>; #address-cells = <1>; #size-cells = <0>; }; + i2c4mux0ch3: i2c@3 { reg = <3>; #address-cells = <1>; @@ -380,16 +434,19 @@ reg = <0x4e>; }; }; + i2c4mux0ch4: i2c@4 { reg = <4>; #address-cells = <1>; #size-cells = <0>; }; + i2c4mux0ch5: i2c@5 { reg = <5>; #address-cells = <1>; #size-cells = <0>; }; + i2c4mux0ch6: i2c@6 { reg = <6>; #address-cells = <1>; @@ -424,6 +481,7 @@ reg = <0x48>; }; }; + i2c4mux0ch7: i2c@7 { reg = <7>; #address-cells = <1>; @@ -469,16 +527,19 @@ #address-cells = <1>; #size-cells = <0>; }; + i2c5mux0ch1: i2c@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; }; + i2c5mux0ch2: i2c@2 { reg = <2>; #address-cells = <1>; #size-cells = <0>; }; + i2c5mux0ch3: i2c@3 { reg = <3>; #address-cells = <1>; @@ -503,6 +564,7 @@ reg = <0x48>; }; }; + i2c5mux1ch1: i2c@1 { reg = <1>; #address-cells = <1>; @@ -513,6 +575,7 @@ reg = <0x48>; }; }; + i2c5mux1ch2: i2c@2 { reg = <2>; #address-cells = <1>; @@ -542,6 +605,7 @@ shunt-resistor = <2000>; }; }; + i2c5mux1ch3: i2c@3 { reg = <3>; #address-cells = <1>; @@ -574,6 +638,210 @@ compatible = "atmel,24c256"; reg = <0x52>; }; + + i2c-mux@71 { + compatible = "nxp,pca9546"; + reg = <0x71>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c6mux0ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + temperature-sensor@64 { + compatible = "microchip,mcp9600"; + reg = <0x64>; + }; + + temperature-sensor@65 { + compatible = "microchip,mcp9600"; + reg = <0x65>; + }; + + temperature-sensor@67 { + compatible = "microchip,mcp9600"; + reg = <0x67>; + }; + + i2c-mux@72 { + compatible = "nxp,pca9546"; + reg = <0x72>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c6mux1ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c6mux1ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + voltage-sensor@48 { + compatible = "ti,ads7830"; + reg = <0x48>; + }; + + voltage-sensor@49 { + compatible = "ti,ads7830"; + reg = <0x49>; + }; + + temperature-sensor@4a { + compatible = "ti,tmp175"; + reg = <0x4a>; + }; + + temperature-sensor@4b { + compatible = "ti,tmp175"; + reg = <0x4b>; + }; + + eeprom@56 { + compatible = "atmel,24c256"; + reg = <0x56>; + }; + }; + + i2c6mux1ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c6mux1ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + + i2c6mux0ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + potentiometer@2c { + compatible = "adi,ad5272-020"; + reg = <0x2c>; + }; + + potentiometer@2e { + compatible = "adi,ad5272-020"; + reg = <0x2e>; + }; + + potentiometer@2f { + compatible = "adi,ad5272-020"; + reg = <0x2f>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@44 { + compatible = "ti,ina238"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + }; + + i2c6mux0ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + + potentiometer@2c { + compatible = "adi,ad5272-020"; + reg = <0x2c>; + }; + + potentiometer@2e { + compatible = "adi,ad5272-020"; + reg = <0x2e>; + }; + + potentiometer@2f { + compatible = "adi,ad5272-020"; + reg = <0x2f>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@44 { + compatible = "ti,ina238"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + }; + + i2c6mux0ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + voltage-sensor@1d { + compatible = "ti,adc128d818"; + reg = <0x1d>; + ti,mode = /bits/ 8 <1>; + }; + + voltage-sensor@37 { + compatible = "ti,adc128d818"; + reg = <0x37>; + ti,mode = /bits/ 8 <1>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + + temperature-sensor@48 { + compatible = "ti,tmp175"; + reg = <0x48>; + }; + + temperature-sensor@49 { + compatible = "ti,tmp175"; + reg = <0x49>; + }; + }; + }; }; &i2c7 { @@ -588,6 +856,210 @@ compatible = "atmel,24c256"; reg = <0x52>; }; + + i2c-mux@71 { + compatible = "nxp,pca9546"; + reg = <0x71>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c8mux0ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + temperature-sensor@64 { + compatible = "microchip,mcp9600"; + reg = <0x64>; + }; + + temperature-sensor@65 { + compatible = "microchip,mcp9600"; + reg = <0x65>; + }; + + temperature-sensor@67 { + compatible = "microchip,mcp9600"; + reg = <0x67>; + }; + + i2c-mux@72 { + compatible = "nxp,pca9546"; + reg = <0x72>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c8mux1ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c8mux1ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + voltage-sensor@48 { + compatible = "ti,ads7830"; + reg = <0x48>; + }; + + voltage-sensor@49 { + compatible = "ti,ads7830"; + reg = <0x49>; + }; + + temperature-sensor@4a { + compatible = "ti,tmp175"; + reg = <0x4a>; + }; + + temperature-sensor@4b { + compatible = "ti,tmp175"; + reg = <0x4b>; + }; + + eeprom@56 { + compatible = "atmel,24c256"; + reg = <0x56>; + }; + }; + + i2c8mux1ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c8mux1ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + + i2c8mux0ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + potentiometer@2c { + compatible = "adi,ad5272-020"; + reg = <0x2c>; + }; + + potentiometer@2e { + compatible = "adi,ad5272-020"; + reg = <0x2e>; + }; + + potentiometer@2f { + compatible = "adi,ad5272-020"; + reg = <0x2f>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@44 { + compatible = "ti,ina238"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + }; + + i2c8mux0ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + + potentiometer@2c { + compatible = "adi,ad5272-020"; + reg = <0x2c>; + }; + + potentiometer@2e { + compatible = "adi,ad5272-020"; + reg = <0x2e>; + }; + + potentiometer@2f { + compatible = "adi,ad5272-020"; + reg = <0x2f>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@44 { + compatible = "ti,ina238"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + }; + + i2c8mux0ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + voltage-sensor@1d { + compatible = "ti,adc128d818"; + reg = <0x1d>; + ti,mode = /bits/ 8 <1>; + }; + + voltage-sensor@37 { + compatible = "ti,adc128d818"; + reg = <0x37>; + ti,mode = /bits/ 8 <1>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + + temperature-sensor@48 { + compatible = "ti,tmp175"; + reg = <0x48>; + }; + + temperature-sensor@49 { + compatible = "ti,tmp175"; + reg = <0x49>; + }; + }; + }; }; &i2c9 { @@ -604,6 +1076,11 @@ reg = <0x50>; }; + eeprom@51 { + compatible = "atmel,24c128"; + reg = <0x51>; + }; + // BSM FRU eeprom@56 { compatible = "atmel,24c64"; @@ -619,11 +1096,222 @@ compatible = "atmel,24c256"; reg = <0x52>; }; + + i2c-mux@71 { + compatible = "nxp,pca9546"; + reg = <0x71>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c10mux0ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + temperature-sensor@64 { + compatible = "microchip,mcp9600"; + reg = <0x64>; + }; + + temperature-sensor@65 { + compatible = "microchip,mcp9600"; + reg = <0x65>; + }; + + temperature-sensor@67 { + compatible = "microchip,mcp9600"; + reg = <0x67>; + }; + + i2c-mux@72 { + compatible = "nxp,pca9546"; + reg = <0x72>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c10mux1ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c10mux1ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + voltage-sensor@48 { + compatible = "ti,ads7830"; + reg = <0x48>; + }; + + voltage-sensor@49 { + compatible = "ti,ads7830"; + reg = <0x49>; + }; + + temperature-sensor@4a { + compatible = "ti,tmp175"; + reg = <0x4a>; + }; + + temperature-sensor@4b { + compatible = "ti,tmp175"; + reg = <0x4b>; + }; + + eeprom@56 { + compatible = "atmel,24c256"; + reg = <0x56>; + }; + }; + + i2c10mux1ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c10mux1ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + + i2c10mux0ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + potentiometer@2c { + compatible = "adi,ad5272-020"; + reg = <0x2c>; + }; + + potentiometer@2e { + compatible = "adi,ad5272-020"; + reg = <0x2e>; + }; + + potentiometer@2f { + compatible = "adi,ad5272-020"; + reg = <0x2f>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@44 { + compatible = "ti,ina238"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + }; + + i2c10mux0ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + + potentiometer@2c { + compatible = "adi,ad5272-020"; + reg = <0x2c>; + }; + + potentiometer@2e { + compatible = "adi,ad5272-020"; + reg = <0x2e>; + }; + + potentiometer@2f { + compatible = "adi,ad5272-020"; + reg = <0x2f>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@44 { + compatible = "ti,ina238"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + }; + + i2c10mux0ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + voltage-sensor@1d { + compatible = "ti,adc128d818"; + reg = <0x1d>; + ti,mode = /bits/ 8 <1>; + }; + + voltage-sensor@37 { + compatible = "ti,adc128d818"; + reg = <0x37>; + ti,mode = /bits/ 8 <1>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + + temperature-sensor@48 { + compatible = "ti,tmp175"; + reg = <0x48>; + }; + + temperature-sensor@49 { + compatible = "ti,tmp175"; + reg = <0x49>; + }; + }; + }; }; &i2c11 { + multi-master; + mctp-controller; status = "okay"; + mctp@10 { + compatible = "mctp-i2c-controller"; + reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>; + }; + // OCP NIC TEMP temperature-sensor@1f { compatible = "ti,tmp421"; @@ -663,6 +1351,7 @@ reg = <0x48>; }; }; + i2c12mux0ch1: i2c@1 { reg = <1>; #address-cells = <1>; @@ -678,6 +1367,7 @@ reg = <0x43>; }; }; + i2c12mux0ch2: i2c@2 { reg = <2>; #address-cells = <1>; @@ -695,6 +1385,7 @@ shunt-resistor = <2000>; }; }; + i2c12mux0ch3: i2c@3 { reg = <3>; #address-cells = <1>; @@ -712,6 +1403,7 @@ shunt-resistor = <2000>; }; }; + i2c12mux0ch4: i2c@4 { reg = <4>; #address-cells = <1>; @@ -722,16 +1414,19 @@ reg = <0x49>; }; }; + i2c12mux0ch5: i2c@5 { reg = <5>; #address-cells = <1>; #size-cells = <0>; }; + i2c12mux0ch6: i2c@6 { reg = <6>; #address-cells = <1>; #size-cells = <0>; }; + i2c12mux0ch7: i2c@7 { reg = <7>; #address-cells = <1>; @@ -748,6 +1443,210 @@ compatible = "atmel,24c256"; reg = <0x52>; }; + + i2c-mux@71 { + compatible = "nxp,pca9546"; + reg = <0x71>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c13mux0ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + temperature-sensor@64 { + compatible = "microchip,mcp9600"; + reg = <0x64>; + }; + + temperature-sensor@65 { + compatible = "microchip,mcp9600"; + reg = <0x65>; + }; + + temperature-sensor@67 { + compatible = "microchip,mcp9600"; + reg = <0x67>; + }; + + i2c-mux@72 { + compatible = "nxp,pca9546"; + reg = <0x72>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c13mux1ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c13mux1ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + voltage-sensor@48 { + compatible = "ti,ads7830"; + reg = <0x48>; + }; + + voltage-sensor@49 { + compatible = "ti,ads7830"; + reg = <0x49>; + }; + + temperature-sensor@4a { + compatible = "ti,tmp175"; + reg = <0x4a>; + }; + + temperature-sensor@4b { + compatible = "ti,tmp175"; + reg = <0x4b>; + }; + + eeprom@56 { + compatible = "atmel,24c256"; + reg = <0x56>; + }; + }; + + i2c13mux1ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c13mux1ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + + i2c13mux0ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + potentiometer@2c { + compatible = "adi,ad5272-020"; + reg = <0x2c>; + }; + + potentiometer@2e { + compatible = "adi,ad5272-020"; + reg = <0x2e>; + }; + + potentiometer@2f { + compatible = "adi,ad5272-020"; + reg = <0x2f>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@44 { + compatible = "ti,ina238"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + }; + + i2c13mux0ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + + potentiometer@2c { + compatible = "adi,ad5272-020"; + reg = <0x2c>; + }; + + potentiometer@2e { + compatible = "adi,ad5272-020"; + reg = <0x2e>; + }; + + potentiometer@2f { + compatible = "adi,ad5272-020"; + reg = <0x2f>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@44 { + compatible = "ti,ina238"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + }; + + i2c13mux0ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + voltage-sensor@1d { + compatible = "ti,adc128d818"; + reg = <0x1d>; + ti,mode = /bits/ 8 <1>; + }; + + voltage-sensor@37 { + compatible = "ti,adc128d818"; + reg = <0x37>; + ti,mode = /bits/ 8 <1>; + }; + + power-monitor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + power-monitor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + + temperature-sensor@48 { + compatible = "ti,tmp175"; + reg = <0x48>; + }; + + temperature-sensor@49 { + compatible = "ti,tmp175"; + reg = <0x49>; + }; + }; + }; }; &i2c14 { @@ -864,7 +1763,9 @@ "FM_IOEXP_U541_INT_N","", /*H4-H7 line 120-127*/ "FM_IOEXP_PDB2_U1003_INT_N","", - "","","","","","", + "","", + "","", + "FM_MAIN_PWREN_RMC_EN_ISO_R","", /*I0-I3 line 128-135*/ "","","","", "PDB_IRQ_PMBUS_ALERT_ISO_R_N","", @@ -873,7 +1774,7 @@ "P12V_SCM_ADC_ALERT","", "CPU0_REGS_I2C_ALERT_N","", "FM_RTC_ALERT_N","", - "APML_CPU0_ALERT_R_N","", + "P0_I3C_APML_ALERT_L","", /*J0-J3 line 144-151*/ "SMB_RJ45_FIO_TMP_ALERT","", "FM_SMB_ALERT_MCIO_0A_N","", @@ -924,11 +1825,17 @@ "PRSNT_LEAK_CABLE_1_R_N","", "PRSNT_LEAK_CABLE_2_R_N","", "PRSNT_HDT_N","", - "","", + "LEAK_SWB_COLDPLATE","", /*P0-P3 line 240-247*/ - "","","","","","","","", + "LEAK_R3_COLDPLATE","", + "LEAK_R2_COLDPLATE","", + "LEAK_R1_COLDPLATE","", + "LEAK_R0_COLDPLATE","", /*P4-P7 line 248-255*/ - "","","","","","","",""; + "LEAK_MB_COLDPLATE","", + "LEAK_PDB1_RIGHT_MANIFOLD","", + "LEAK_PDB1_LEFT_MANIFOLD","", + "LEAK_MB_MANIFOLD",""; status = "okay"; }; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts index 60b98d602e805..e4172be84e7fe 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts @@ -49,6 +49,20 @@ reg = <0x80000000 0x80000000>; }; + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + ramoops@b8dfa000 { + compatible = "ramoops"; + reg = <0xb8dfa000 0x6000>; + record-size = <0x2000>; + console-size = <0x2000>; + pmsg-size = <0x2000>; + max-reason = <1>; + }; + }; + iio-hwmon { compatible = "iio-hwmon"; io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>, diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite5.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite5.dts new file mode 100644 index 0000000000000..2486981f3d6bd --- /dev/null +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite5.dts @@ -0,0 +1,1067 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2025 Facebook Inc. + +/dts-v1/; +#include "aspeed-g6.dtsi" +#include +#include + +/ { + model = "Facebook Yosemite 5 BMC"; + compatible = "facebook,yosemite5-bmc", "aspeed,ast2600"; + + aliases { + i2c16 = &i2c5mux0ch0; + i2c17 = &i2c5mux0ch1; + i2c18 = &i2c5mux0ch2; + i2c19 = &i2c5mux0ch3; + i2c20 = &i2c5mux1ch0; + i2c21 = &i2c5mux1ch1; + i2c22 = &i2c5mux1ch2; + i2c23 = &i2c5mux1ch3; + i2c24 = &i2c6mux0ch0; + i2c25 = &i2c6mux0ch1; + i2c26 = &i2c6mux0ch2; + i2c27 = &i2c6mux0ch3; + i2c28 = &i2c8mux0ch0; + i2c29 = &i2c8mux0ch1; + i2c30 = &i2c8mux0ch2; + i2c31 = &i2c8mux0ch3; + i2c32 = &i2c30mux0ch0; + i2c33 = &i2c30mux0ch1; + i2c34 = &i2c30mux0ch2; + i2c35 = &i2c30mux0ch3; + serial0 = &uart1; + serial2 = &uart3; + serial3 = &uart4; + serial4 = &uart5; + }; + + chosen { + stdout-path = "serial4:57600n8"; + }; + + iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>, + <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>, + <&adc1 2>; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + label = "bmc_heartbeat_amber"; + gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + + led-1 { + label = "fp_id_amber"; + default-state = "off"; + gpios = <&gpio0 ASPEED_GPIO(B, 5) GPIO_ACTIVE_HIGH>; + }; + + led-2 { + label = "power_blue"; + default-state = "off"; + gpios = <&gpio0 ASPEED_GPIO(P, 4) GPIO_ACTIVE_HIGH>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; + + spi_gpio: spi { + compatible = "spi-gpio"; + #address-cells = <1>; + #size-cells = <0>; + + sck-gpios = <&gpio0 ASPEED_GPIO(Z, 3) GPIO_ACTIVE_HIGH>; + mosi-gpios = <&gpio0 ASPEED_GPIO(Z, 4) GPIO_ACTIVE_HIGH>; + miso-gpios = <&gpio0 ASPEED_GPIO(Z, 5) GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>; + num-chipselects = <1>; + status = "okay"; + + tpm@0 { + compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; + spi-max-frequency = <33000000>; + reg = <0>; + }; + }; +}; + +&adc0 { + aspeed,int-vref-microvolt = <2500000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adc0_default + &pinctrl_adc1_default + &pinctrl_adc2_default + &pinctrl_adc3_default + &pinctrl_adc4_default + &pinctrl_adc5_default + &pinctrl_adc6_default + &pinctrl_adc7_default>; + status = "okay"; +}; + +&adc1 { + aspeed,int-vref-microvolt = <2500000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adc10_default>; + status = "okay"; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&fmc { + status = "okay"; + + flash@0 { + status = "okay"; + m25p,fast-read; + label = "bmc"; + spi-max-frequency = <50000000>; +#include "openbmc-flash-layout-128.dtsi" + }; + + flash@1 { + status = "okay"; + m25p,fast-read; + label = "alt-bmc"; + spi-max-frequency = <50000000>; + }; +}; + +&gpio0 { + gpio-line-names = + /*A0-A7*/ "","","","","","","","", + /*B0-B7*/ "BATTERY_DETECT","","BMC_I2C1_FPGA_ALERT","BMC_READY", + "IOEXP_INT_3V3","FM_ID_LED","","", + /*C0-C7*/ "","","","", + "PMBUS_REQ_N","PSU_FW_UPDATE_REQ_N","","BMC_I2C_SSIF_ALERT", + /*D0-D7*/ "","","","","","","","", + /*E0-E7*/ "","","","","","","","", + /*F0-F7*/ "","","","","","","","", + /*G0-G7*/ "FM_BMC_MUX1_SEL","","","", + "","","FM_DEBUG_PORT_PRSNT_N","FM_BMC_DBP_PRESENT_N", + /*H0-H7*/ "","","","","","","","", + /*I0-I7*/ "","","","","","FLASH_WP_STATUS","BMC_JTAG_MUX_SEL","", + /*J0-J7*/ "","","","","","","","", + /*K0-K7*/ "","","","","","","","", + /*L0-L7*/ "","","","","","","","", + /*M0-M7*/ "PCIE_EP_RST_EN","BMC_FRU_WP","SCM_HPM_STBY_RST_N", + "SCM_HPM_STBY_EN","STBY_POWER_PG_3V3","TH500_SHDN_OK","","", + /*N0-N7*/ "led-postcode-0","led-postcode-1","led-postcode-2", + "led-postcode-3","led-postcode-4","led-postcode-5", + "led-postcode-6","led-postcode-7", + /*O0-O7*/ "RUN_POWER_PG","PWR_BRAKE","CHASSIS_AC_LOSS","BSM_PRSNT_N", + "PSU_SMB_ALERT","FM_TPM_PRSNT_0_N","PSU_FW_UPDATING_N","", + /*P0-P7*/ "PWR_BTN_BMC_N","IPEX_CABLE_PRSNT","ID_RST_BTN_BMC_N", + "RST_BMC_RSTBTN_OUT_N","BMC_PWR_LED","RUN_POWER_EN","SHDN_FORCE","", + /*Q0-Q7*/ "IRQ_PCH_TPM_SPI_LV3_N","USB_OC0_REAR_N","UART_MUX_SEL", + "I2C_MUX_RESET","RSVD_NV_PLT_DETECT","SPI_TPM_INT", + "CPU_JTAG_MUX_SELECT","THERM_BB_OVERT", + /*R0-R7*/ "THERM_BB_WARN","SPI_BMC_FPGA_INT","CPU_BOOT_DONE","PMBUS_GNT", + "CHASSIS_PWR_BRK","PCIE_WAKE","PDB_THERM_OVERT","SHDN_REQ", + /*S0-S7*/ "","","SYS_BMC_PWRBTN_N","FM_TPM_PRSNT_1_N", + "FM_BMC_DEBUG_SW_N","UID_LED_N","SYS_FAULT_LED_N","RUN_POWER_FAULT", + /*T0-T7*/ "","","","","","","","", + /*U0-U7*/ "FM_DBP_BMC_PRDY_N","","","","","","","", + /*V0-V7*/ "L2_RST_REQ_OUT","L0L1_RST_REQ_OUT","BMC_ID_BEEP_SEL", + "BMC_I2C0_FPGA_ALERT","SMB_BMC_TMP_ALERT","PWR_LED_N", + "SYS_RST_OUT","IRQ_TPM_SPI_N", + /*W0-W7*/ "","","","","","","IRQ_ESPI_LPC_SERIRQ_ALERT0_N","", + /*X0-X7*/ "","FM_DBP_CPU_PREQ_GF_N","","","","","","", + /*Y0-Y7*/ "","","FM_FLASH_LATCH_N","BMC_EMMC_RST_N","","","","", + /*Z0-Z7*/ "","","","","","","",""; +}; + +&gpio1 { + gpio-line-names = + /*18A0-18A7*/ "","","","","","","","", + /*18B0-18B7*/ "","","","","FM_BOARD_BMC_REV_ID0", + "FM_BOARD_BMC_REV_ID1","FM_BOARD_BMC_REV_ID2","", + /*18C0-18C7*/ "","","SPI_BMC_BIOS_ROM_IRQ0_N","","","","","", + /*18D0-18D7*/ "","","","","","","","", + /*18E0-18E3*/ "FM_BMC_PROT_LS_EN","AC_PWR_BMC_BTN_N","",""; +}; + +/* MB CPLD I2C */ +&i2c0 { + status = "okay"; +}; + +/* CPU I2C */ +&i2c1 { + status = "okay"; +}; + +/* MCIO 2A I2C */ +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; + + /* Socket 0 SBRMI */ + sbrmi@3c { + compatible = "amd,sbrmi"; + reg = <0x3c>; + }; + + /* Socket 0 SBTSI */ + sbtsi@4c { + compatible = "amd,sbtsi"; + reg = <0x4c>; + }; +}; + +&i2c4 { + multi-master; + mctp-controller; + status = "okay"; + + mctp@10 { + compatible = "mctp-i2c-controller"; + reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>; + }; + + /* OCP NIC TEMP */ + temperature-sensor@1f { + compatible = "ti,tmp421"; + reg = <0x1f>; + }; + + /* OCP NIC FRU EEPROM */ + eeprom@50 { + compatible = "atmel,24c64"; + reg = <0x50>; + }; +}; + +&i2c5 { + status = "okay"; + + /* I2C MUX for MCIO 1A */ + i2c-mux@70 { + compatible = "nxp,pca9546"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c5mux0ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c5mux0ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c5mux0ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c5mux0ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + /* I2C MUX for MCIO 0A */ + i2c-mux@77 { + compatible = "nxp,pca9546"; + reg = <0x77>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c5mux1ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c5mux1ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c5mux1ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c5mux1ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +&i2c6 { + status = "okay"; + + /* I2C MUX for PWRPIC #13 ~ #16 */ + i2c-mux@77 { + compatible = "nxp,pca9546"; + reg = <0x77>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + /* PWRPIC #13 */ + i2c6mux0ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* PWRPIC #14 */ + i2c6mux0ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* PWRPIC #16 */ + i2c6mux0ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* PWRPIC #15 */ + i2c6mux0ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +/* SCM CPLD I2C */ +&i2c7 { + status = "okay"; +}; + +&i2c8 { + status = "okay"; + + power-monitor@14 { + compatible = "infineon,xdp710"; + reg = <0x14>; + }; + + adc@1d { + compatible = "ti,adc128d818"; + reg = <0x1d>; + ti,mode = /bits/ 8 <1>; + }; + + power-sensor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + /* PADDLE BD IOEXP */ + gpio-expander@41 { + compatible = "nxp,pca9536"; + reg = <0x41>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "HSC_OC_GPIO0", "HSC_OC_GPIO1", + "HSC_OC_GPIO2", "HSC_OC_GPIO3"; + }; + + power-sensor@42 { + compatible = "ti,ina238"; + reg = <0x42>; + shunt-resistor = <1000>; + }; + + power-monitor@43 { + compatible = "lltc,ltc4287"; + reg = <0x43>; + shunt-resistor-micro-ohms = <250>; + }; + + power-sensor@44 { + compatible = "ti,ina238"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + + power-sensor@45 { + compatible = "ti,ina238"; + reg = <0x45>; + shunt-resistor = <1000>; + }; + + power-monitor@47 { + compatible = "ti,tps25990"; + reg = <0x47>; + ti,rimon-micro-ohms = <430000000>; + }; + + temperature-sensor@48 { + compatible = "ti,tmp75"; + reg = <0x48>; + }; + + temperature-sensor@49 { + compatible = "ti,tmp75"; + reg = <0x49>; + }; + + /* PDB FRU */ + eeprom@56 { + compatible = "atmel,24c128"; + reg = <0x56>; + }; + + /* Paddle BD FRU */ + eeprom@57 { + compatible = "atmel,24c128"; + reg = <0x57>; + }; + + power-monitor@58 { + compatible = "renesas,isl28022"; + reg = <0x58>; + shunt-resistor-micro-ohms = <1000>; + }; + + power-monitor@59 { + compatible = "renesas,isl28022"; + reg = <0x59>; + shunt-resistor-micro-ohms = <1000>; + }; + + power-monitor@5a { + compatible = "renesas,isl28022"; + reg = <0x5a>; + shunt-resistor-micro-ohms = <1000>; + }; + + power-monitor@5b { + compatible = "renesas,isl28022"; + reg = <0x5b>; + shunt-resistor-micro-ohms = <1000>; + }; + + psu@5c { + compatible = "renesas,raa228006"; + reg = <0x5c>; + }; + + fan-controller@5e{ + compatible = "maxim,max31790"; + reg = <0x5e>; + }; + + /* I2C MUX for PWRPIC #1, #2, #11, #12 */ + i2c-mux@77 { + compatible = "nxp,pca9546"; + reg = <0x77>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + /* PWRPIC #1 */ + i2c8mux0ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* PWRPIC #2 */ + i2c8mux0ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* PWRPIC #12 (Connector to CXL BD) */ + i2c8mux0ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + + i2c-mux@70 { + compatible = "nxp,pca9546"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c30mux0ch0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c30mux0ch1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c30mux0ch2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + + adc@1e { + compatible = "ti,adc128d818"; + reg = <0x1e>; + ti,mode = /bits/ 8 <1>; + }; + + adc@1f { + compatible = "ti,adc128d818"; + reg = <0x1f>; + ti,mode = /bits/ 8 <1>; + }; + + /* CXL BD IOEXP */ + gpio-expander@27 { + compatible = "nxp,pca9535"; + reg = <0x27>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "IRQ_TEMP_0_ALERT_N","IRQ_TEMP_1_ALERT_N", + "ALERT_PMBUS_0_N","ALERT_PMBUS_1_N", + "ALERT_PMBUS_2_N","IRQ_INA230_12V_ALERT_N", + "RST_IOX_CXL_N","DEBUG_UART_SEL_0", + "DEBUG_UART_SEL_1","BMC_REMOTEJTAG_EN_N", + "JTAG_BMC_3V3_CTL_CLR_N","DDR_CH02_I2C_MUX_SEL", + "DDR_CH13_I2C_MUX_SEL","SYS_OK", + "CXL_VRHOT_ALERT_R1_N",""; + }; + + temperature-sensor@4a { + compatible = "ti,tmp75"; + reg = <0x4a>; + }; + + temperature-sensor@4c { + compatible = "ti,tmp432"; + reg = <0x4c>; + }; + + power-sensor@4d { + compatible = "ti,ina230"; + reg = <0x4d>; + shunt-resistor = <2000>; + }; + + temperature-sensor@4e { + compatible = "ti,tmp75"; + reg = <0x4e>; + }; + + /* CXL FRU */ + eeprom@50 { + compatible = "atmel,24c64"; + reg = <0x50>; + }; + }; + + i2c30mux0ch3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + + /* PWRPIC #11 */ + i2c8mux0ch3: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + }; +}; + +&i2c9 { + status = "okay"; + + temperature-sensor@4b { + compatible = "ti,tmp75"; + reg = <0x4b>; + }; + + /* SCM FRU */ + eeprom@50 { + compatible = "atmel,24c128"; + reg = <0x50>; + }; + + /* BSM FRU */ + eeprom@56 { + compatible = "atmel,24c64"; + reg = <0x56>; + }; +}; + +/* MCIO 0A I2C */ +&i2c10 { + status = "okay"; + + /* E1S EB IOEXP0 */ + gpio-expander@21 { + compatible = "nxp,pca9535"; + interrupt-parent = <&sgpiom0>; + interrupts = <172 IRQ_TYPE_EDGE_FALLING>; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "RST_SMB_E1S_0","LED_ACTIVE_E1S_0", + "E1S_0_PRSNT_N","RST_PCIE_E1S_0_PERST", + "E1S_0_PWRDIS","ALERT_INA_0", + "","", + "RST_SMB_E1S_1","LED_ACTIVE_E1S_1", + "E1S_1_PRSNT_N","RST_PCIE_E1S_1_PERST", + "E1S_1_PWRDIS","ALERT_INA_1", + "",""; + }; + + /* E1S EB IOEXP1 */ + gpio-expander@22 { + compatible = "nxp,pca9535"; + interrupt-parent = <&sgpiom0>; + interrupts = <174 IRQ_TYPE_EDGE_FALLING>; + reg = <0x22>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "P12V_E1S_EN_0","PWRGD_P12V_E1S_0", + "P12V_E1S_FLTB_0","PWRGD_P3V3_E1S_0", + "FM_P3V3_E1S_0_FAULT","P12V_E1S_EN_1", + "PWRGD_P12V_E1S_1","P12V_E1S_FLTB_1", + "PWRGD_P3V3_E1S_1","FM_P3V3_E1S_1_FAULT", + "","", + "","", + "PWRGD_P3V3_AUX","ALERT_TEMP"; + }; + + power-sensor@40 { + compatible = "ti,ina233"; + reg = <0x40>; + shunt-resistor = <2000>; + ti,maximum-expected-current-microamp = <32768000>; + }; + + power-sensor@45 { + compatible = "ti,ina233"; + reg = <0x45>; + shunt-resistor = <2000>; + ti,maximum-expected-current-microamp = <32768000>; + }; + + adc@48 { + compatible = "ti,ads7830"; + reg = <0x48>; + }; + + temperature-sensor@49 { + compatible = "ti,tmp75"; + reg = <0x49>; + }; + + /* E1S EB FRU */ + eeprom@54 { + compatible = "atmel,24c128"; + reg = <0x54>; + }; +}; + +&i2c11 { + status = "okay"; + + /* MB IOEXP */ + gpio-expander@21 { + compatible = "nxp,pca9535"; + interrupt-parent = <&sgpiom0>; + interrupts = <170 IRQ_TYPE_EDGE_FALLING>; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "ALERT_CLKMUX_0_LOSS_N","ALERT_CLKMUX_1_LOSS_N", + "ALERT_CLKMUX_2_LOSS_N","ALERT_CLKMUX_3_LOSS_N", + "FM_CLKMUX_0_SEL","FM_CLKMUX_1_SEL", + "FM_CLKMUX_2_SEL","FM_CLKMUX_3_SEL", + "RST_USB_HUB_0_N","FM_CLKGEN_GPIO2", + "","FM_BMC_RTC_RST", + "FM_P3V_BAT_SCALED_EN","", + "FM_CLKGEN_GPIO4","RST_USB_HUB_1_N"; + }; + + power-sensor@40 { + compatible = "ti,ina230"; + reg = <0x40>; + shunt-resistor = <2000>; + }; + + power-sensor@41 { + compatible = "ti,ina230"; + reg = <0x41>; + shunt-resistor = <2000>; + }; + + power-sensor@42 { + compatible = "ti,ina230"; + reg = <0x42>; + shunt-resistor = <2000>; + }; + + power-sensor@43 { + compatible = "ti,ina230"; + reg = <0x43>; + shunt-resistor = <2000>; + }; + + power-sensor@44 { + compatible = "ti,ina230"; + reg = <0x44>; + shunt-resistor = <2000>; + }; + + power-sensor@45 { + compatible = "ti,ina230"; + reg = <0x45>; + shunt-resistor = <2000>; + }; + + adc@48 { + compatible = "ti,ads7830"; + reg = <0x48>; + }; + + adc@49 { + compatible = "ti,ads7830"; + reg = <0x49>; + }; + + adc@4b { + compatible = "ti,ads7830"; + reg = <0x4b>; + }; +}; + +/* MCIO 4A I2C */ +&i2c12 { + multi-master; + mctp-controller; + status = "okay"; + + mctp@10 { + compatible = "mctp-i2c-controller"; + reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>; + }; +}; + +&i2c13 { + status = "okay"; + + power-sensor@40 { + compatible = "ti,ina230"; + reg = <0x40>; + shunt-resistor = <2000>; + }; + + power-sensor@41 { + compatible = "ti,ina230"; + reg = <0x41>; + shunt-resistor = <2000>; + }; + + power-sensor@44 { + compatible = "ti,ina230"; + reg = <0x44>; + shunt-resistor = <2000>; + }; + + power-sensor@45 { + compatible = "ti,ina230"; + reg = <0x45>; + shunt-resistor = <2000>; + }; + + temperature-sensor@48 { + compatible = "national,lm75b"; + reg = <0x48>; + }; + + temperature-sensor@49 { + compatible = "national,lm75b"; + reg = <0x49>; + }; + + /* CLKGEN FRU */ + eeprom@50 { + compatible = "atmel,24c16"; + reg = <0x50>; + }; + + /* MB FRU */ + eeprom@51 { + compatible = "atmel,24c128"; + reg = <0x51>; + }; + + /* CPU FRU */ + eeprom@53 { + compatible = "atmel,24c128"; + reg = <0x53>; + }; + + rtc@68 { + compatible = "dallas,ds1339"; + reg = <0x68>; + }; +}; + +/* PROT reserve */ +&i2c14 { + status = "okay"; +}; + +/* MCIO 3A I2C */ +&i2c15 { + status = "okay"; +}; + +&kcs2 { + aspeed,lpc-io-reg = <0xca8>; + status = "okay"; +}; + +&kcs3 { + aspeed,lpc-io-reg = <0xca2>; + status = "okay"; +}; + +&mac2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ncsi3_default>; + use-ncsi; + status = "okay"; +}; + +&pinctrl { + pinctrl_ncsi3_default: ncsi3_default { + function = "RMII3"; + groups = "NCSI3"; + }; +}; + +&sgpiom0 { + ngpios = <128>; + bus-frequency = <2000000>; + gpio-line-names = + /*"input pin","output pin"*/ + /*bit0-bit7*/ + "PWRGD_CPU_PWROK","SGPIO_RSTBTN_OUT", + "PWRGD_CPU_PWROK_1","SGPIO_BMC_READY", + "PWRGD_CPU_PWROK_2","IBB_BMC_SRST", + "host0-ready","FM_I3C_SPD_AH_SEL_R", + "PCIe_HP_BOOT","FM_I3C_SPD_IP_SEL_R", + "PCIe_HP_DATA","FM_JTAG_BMC_MUX_S0_R", + "PCIe_HP_NIC","FM_JTAG_BMC_MUX_S1_R", + "","FM_JTAG_BMC_OE_1_R_N", + /*bit8-bit15*/ + "PWRGD_PVDDCR_CPU0_P0","FM_JTAG_BMC_OE_R_N", + "PWRGD_PVDDCR_SOC_P0","FM_REMOTEJTAG_EN_R_N", + "PWRGD_PVDDCR_CPU1_P0","FM_CPU_FORCE_SELFREFRESH_R", + "PWRGD_P3V3_STBY","FM_CPU_NMI_SYNC_FLOOD_R_N", + "PWRGD_PVDD33_S5","FM_CPU_TRIGGERTSC_OE_R_N", + "PWRGD_PVDD18_S5_P0","FM_PASSWORD_CLEAR_R_N", + "PWRGD_PVDDIO_P0","FM_BIOS_USB_RECOVERY_N", + "PWRGD_PVDDIO_MEM_S3_P0","FM_USB_MUX_OE_R_N", + /*bit16-bit23*/ + "PWRGD_P1V8_STBY","FM_USB_MUX_SEL_R", + "PWRGD_P1V0_STBY","RST_SMB_BOOT_R_N", + "PWRGD_P1V2_STBY","RST_SMB_MCIO0A_R_N", + "IBB_BMC_SRST","RST_SMB_NIC_R_N", + "PWRGD_P12V_E1S_0","FM_PPS_NIC_IN_BUF_OE_R_N", + "PWRGD_P12V_E1S_1","FM_PPS_NIC_IN_EN_R", + "RST_PCIE_BOOT_PERST_N","FM_PPS_NIC_IN_OE_R_N", + "PWRGD_P12V_NIC","FM_PPS_NIC_IN_S0_R", + /*bit24-bit31*/ + "PWRGD_P12V_SCM","FM_PPS_NIC_IN_S1_R", + "PWRGD_P12V_DIMM","FM_PPS_NIC_OUT_BUF_OE_R_N", + "PWRGD_CPU_DIMM0_AH","FM_PPS_NIC_OUT_CPU_OE_R_N", + "PWRGD_CPU_DIMM1_IP","FM_PPS_NIC_OUT_EN_R", + "PWRGD_NIC_CPLD","JTAG_CPLD_DBREQ_R_N", + "ALERT_INA230_DIMM_0_N","HDT_HDR_RESET_R_N", + "ALERT_INA230_DIMM_1_N","FM_SMB_AUTH_MUX_OE_R_N", + "ALERT_INA230_E1S_0_N","FM_SCM_LED_R_N", + /*bit32-bit39*/ + "ALERT_INA230_E1S_1_N","", + "ALERT_INA230_FAN0_N","", + "ALERT_INA230_FAN1_N","", + "ALERT_INA230_FAN2_N","", + "ALERT_INA230_FAN3_N","", + "ALERT_INA230_NIC_N","", + "ALERT_INA230_SCM_N","", + "ALERT_IRQ_PMBUS_PWR11_N","", + /*bit40-bit47*/ + "ALERT_MCIO2A_LEAK_DETECT_N","", + "ALERT_MCIO3A_LEAK_DETECT_N","", + "ALERT_MCIO4A_LEAK_DETECT_N","", + "ALERT_OC_PADDLE2_N","", + "ALERT_OC_PWR2_N","", + "ALERT_OC_PWR11_N","", + "ALERT_PADDLE2_SMB_N","", + "ALERT_PWR14_SB2_LEAK_DETECT_N","", + /*bit48-bit55*/ + "ALERT_PWR14_SB3_LEAK_DETECT_N","", + "ALERT_PWR15_SB2_LEAK_DETECT_N","", + "ALERT_PWR15_SB3_LEAK_DETECT_N","", + "ALERT_SMB_MCIO0A_N","", + "ALERT_SMB_MCIO1A_N","", + "ALERT_SMB_MCIO2A_N","", + "ALERT_SMB_MCIO2B_N","", + "ALERT_SMB_MCIO3A_N","", + /*bit56-bit63*/ + "ALERT_SMB_MCIO3B_N","", + "ALERT_SMB_MCIO4A_N","", + "ALERT_SMB_MCIO4B_N","", + "ALERT_THERMALTRIP_MCIO1A_N","", + "ALERT_THERMALTRIP_MCIO2A_N","", + "ALERT_THERMALTRIP_MCIO3A_N","", + "ALERT_THERMALTRIP_MCIO4A_N","", + "ALERT_UV_PADDLE2_N","", + /*bit64-bit71*/ + "ALERT_UV_PWR2_N","", + "ALERT_UV_PWR11_N","", + "ALERT_VR_SMB_N","", + "FAULT_FAN_0_N","", + "FAULT_FAN_1_N","", + "FAULT_FAN_2_N","", + "FAULT_FAN_3_N","", + "FAULT_P3V3_E1S_0_N","", + /*bit72-bit79*/ + "FAULT_P3V3_E1S_1_N","", + "FAULT_P3V3_NIC_N","", + "FAULT_P12V_NIC_N","", + "FAULT_P12V_SCM_N","", + "P0_I3C_APML_ALERT_L","", + "ALERT_INLET_TEMP_N","", + "FM_CPU_PROCHOT_R_N","", + "FM_CPU_THERMTRIP_N","", + /*bit80-bit87*/ + "ALERT_OUTLET_TEMP_N","", + "ALERT_RTC_N","", + "PVDDCR_CPU0_P0_OCP_N","", + "PVDDCR_CPU1_P0_OCP_N","", + "PVDDCR_SOC_P0_OCP_N","", + "MB_IOEXP_INT","", + "E1S_0_BD_IOEXP","", + "E1S_1_BD_IOEXP","", + /*bit88-bit95*/ + "PADDLE_BD_IOEXP_INT","", + "FM_BOARD_REV_ID0","", + "FM_BOARD_REV_ID1","", + "FM_BOARD_REV_ID2","", + "FM_VR_TYPE_ID0","", + "FM_VR_TYPE_ID1","", + "PRSNT_BOOT_N_IOEXP","", + "PRSNT_DATA_N_IOEXP","", + /*bit96-bit103*/ + "PRSNT_NIC_N_IOEXP","", + "PRSNT_BOOT_N_FF","", + "PRSNT_MCIO1A_N_FF","", + "NIC_PRSNT_N","", + "","", + "","", + "","", + "","", + /*bit104-bit111*/ + "","","","","","","","","","","","","","","","", + /*bit112-bit119*/ + "","","","","","","","","","","","","","","","", + /*bit120-bit127*/ + "","","","","","","","","","","","","","","",""; + status = "okay"; +}; + +/* BIOS Flash */ +&spi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi2_default>; + status = "okay"; + + flash@0 { + m25p,fast-read; + label = "pnor"; + spi-max-frequency = <12000000>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + status = "okay"; + }; +}; + +/* Host Console */ +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +/* SOL */ +&uart3 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +/* BMC Console */ +&uart5 { + status = "okay"; +}; + +&wdt1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdtrst1_default>; + aspeed,reset-type = "soc"; + aspeed,external-signal; + aspeed,ext-push-pull; + aspeed,ext-active-high; + aspeed,ext-pulse-duration = <256>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-balcones.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-balcones.dts new file mode 100644 index 0000000000000..63fcb7a7619ab --- /dev/null +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-balcones.dts @@ -0,0 +1,609 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright 2025 IBM Corp. +/dts-v1/; + +#include +#include +#include +#include "aspeed-g6.dtsi" +#include "ibm-power11-dual.dtsi" + +/ { + model = "Balcones"; + compatible = "ibm,balcones-bmc", "aspeed,ast2600"; + + aliases { + serial4 = &uart5; + i2c16 = &i2c11mux0chn0; + i2c17 = &i2c11mux0chn1; + i2c18 = &i2c11mux0chn2; + i2c19 = &i2c11mux0chn3; + }; + + chosen { + stdout-path = &uart5; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + poll-interval = <1000>; + + event-fan0-presence { + gpios = <&gpio0 ASPEED_GPIO(F, 4) GPIO_ACTIVE_LOW>; + label = "fan0-presence"; + linux,code = <6>; + }; + + event-fan1-presence { + gpios = <&gpio0 ASPEED_GPIO(F, 5) GPIO_ACTIVE_LOW>; + label = "fan1-presence"; + linux,code = <7>; + }; + }; + + iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc1 7>; + }; + + leds { + compatible = "gpio-leds"; + + led-fan0 { + gpios = <&gpio0 ASPEED_GPIO(G, 0) GPIO_ACTIVE_LOW>; + }; + + led-fan1 { + gpios = <&gpio0 ASPEED_GPIO(G, 1) GPIO_ACTIVE_LOW>; + }; + + led-rear-enc-id0 { + gpios = <&gpio0 ASPEED_GPIO(H, 2) GPIO_ACTIVE_LOW>; + }; + + led-rear-enc-fault0 { + gpios = <&gpio0 ASPEED_GPIO(H, 3) GPIO_ACTIVE_LOW>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + event_log: region@b3d00000 { + reg = <0xb3d00000 0x100000>; + no-map; + }; + + ramoops@b3e00000 { + compatible = "ramoops"; + reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */ + record-size = <0x8000>; + console-size = <0x8000>; + ftrace-size = <0x8000>; + pmsg-size = <0x8000>; + max-reason = <3>; /* KMSG_DUMP_EMERG */ + }; + + /* LPC FW cycle bridge region requires natural alignment */ + flash_memory: region@b4000000 { + reg = <0xb4000000 0x04000000>; /* 64M */ + no-map; + }; + + /* VGA region is dictated by hardware strapping */ + vga_memory: region@bf000000 { + compatible = "shared-dma-pool"; + reg = <0xbf000000 0x01000000>; /* 16M */ + no-map; + }; + }; +}; + +&adc1 { + aspeed,int-vref-microvolt = <2500000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc9_default + &pinctrl_adc10_default &pinctrl_adc11_default + &pinctrl_adc12_default &pinctrl_adc13_default + &pinctrl_adc14_default &pinctrl_adc15_default>; + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&emmc { + clk-phase-mmc-hs200 = <180>, <180>; + status = "okay"; +}; + +&emmc_controller { + status = "okay"; +}; + +&gpio0 { + gpio-line-names = + /*A0-A7*/ "","","","","","","","", + /*B0-B7*/ "","","","","","","checkstop","", + /*C0-C7*/ "","","","","","","","", + /*D0-D7*/ "","","","","","","","", + /*E0-E7*/ "","","","","","","","", + /*F0-F7*/ "","fan-ctlr-reset","rtc-battery-voltage-read-enable", + "reset-cause-pinhole","","","","", + /*G0-G7*/ "fan0","fan1","","","","","","", + /*H0-H7*/ "","","rear-enc-id0","rear-enc-fault0","","","","", + /*I0-I7*/ "","","","","","","bmc-secure-boot","", + /*J0-J7*/ "","","","","","","","", + /*K0-K7*/ "","","","","","","","", + /*L0-L7*/ "","","","","","","","", + /*M0-M7*/ "","","","","","","","", + /*N0-N7*/ "","","","","","","","", + /*O0-O7*/ "","","","usb-power","","","","", + /*P0-P7*/ "","","","","","","","", + /*Q0-Q7*/ "cfam-reset","","regulator-standby-faulted","","","","","", + /*R0-R7*/ "bmc-tpm-reset","power-chassis-control","power-chassis-good","","", + "","","", + /*S0-S7*/ "presence-ps0","presence-ps1","","","power-ffs-sync-history","","", + "", + /*T0-T7*/ "","","","","","","","", + /*U0-U7*/ "","","","","","","","", + /*V0-V7*/ "","","","","","","","", + /*W0-W7*/ "","","","","","","","", + /*X0-X7*/ "","","","","","","","", + /*Y0-Y7*/ "","","","","","","","", + /*Z0-Z7*/ "","","","","","","",""; + + usb-power-hog { + gpio-hog; + gpios = ; + output-high; + }; +}; + +&i2c0 { + status = "okay"; + + gpio@20 { + compatible = "ti,tca9554"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + + gpio-line-names = + "", + "RUSSEL_FW_I2C_ENABLE_N", + "RUSSEL_OPPANEL_PRESENCE_N", + "BLYTH_OPPANEL_PRESENCE_N", + "CPU_TPM_CARD_PRESENT_N", + "", + "", + "DASD_BP_PRESENT_N"; + }; + + eeprom@51 { + compatible = "atmel,24c64"; + reg = <0x51>; + }; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; + + pmic@64 { + compatible = "ti,ucd90160"; + reg = <0x64>; + }; +}; + +&i2c3 { + status = "okay"; + + power-supply@5a { + compatible = "acbel,fsg032"; + reg = <0x5a>; + }; + + power-supply@5b { + compatible = "acbel,fsg032"; + reg = <0x5b>; + }; +}; + +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; + + eeprom@52 { + compatible = "atmel,24c64"; + reg = <0x52>; + }; + + led-controller@62 { + compatible = "nxp,pca9551"; + reg = <0x62>; + #address-cells = <1>; + #size-cells = <0>; + gpio-controller; + #gpio-cells = <2>; + + led@0 { + reg = <0>; + default-state = "keep"; + label = "cablecard2-cxp-top"; + retain-state-shutdown; + type = ; + }; + + led@1 { + reg = <1>; + default-state = "keep"; + label = "cablecard2-cxp-bot"; + retain-state-shutdown; + type = ; + }; + }; +}; + +&i2c6 { + status = "okay"; +}; + +&i2c7 { + multi-master; + status = "okay"; + + temperature-sensor@48 { + compatible = "ti,tmp275"; + reg = <0x48>; + }; + + eeprom@50 { + compatible = "atmel,24c64"; + reg = <0x50>; + }; + + eeprom@51 { + compatible = "atmel,24c64"; + reg = <0x51>; + }; + + pwm@53 { + compatible = "maxim,max31785a"; + reg = <0x53>; + }; + + led-controller@60 { + compatible = "nxp,pca9551"; + reg = <0x60>; + #address-cells = <1>; + #size-cells = <0>; + gpio-controller; + #gpio-cells = <2>; + + led@0 { + reg = <0>; + default-state = "keep"; + label = "front-sys-id0"; + retain-state-shutdown; + type = ; + }; + + led@1 { + reg = <1>; + default-state = "keep"; + label = "front-check-log0"; + retain-state-shutdown; + type = ; + }; + + led@2 { + reg = <2>; + default-state = "keep"; + label = "front-enc-fault1"; + retain-state-shutdown; + type = ; + }; + + led@3 { + reg = <3>; + default-state = "keep"; + label = "front-sys-pwron0"; + retain-state-shutdown; + type = ; + }; + }; + + lcd-controller@62 { + compatible = "ibm,op-panel"; + reg = <(0x62 | I2C_OWN_SLAVE_ADDRESS)>; + }; + + pressure-sensor@76 { + compatible = "infineon,dps310"; + reg = <0x76>; + #io-channel-cells = <0>; + }; +}; + +&i2c8 { + status = "okay"; + + rtc@32 { + compatible = "epson,rx8900"; + reg = <0x32>; + }; + + eeprom@50 { + compatible = "atmel,24c128"; + reg = <0x50>; + }; + + led-controller@60 { + compatible = "nxp,pca9551"; + reg = <0x60>; + #address-cells = <1>; + #size-cells = <0>; + gpio-controller; + #gpio-cells = <2>; + + gpio-line-names = + "", + "APSS_RESET_N", + "", + "N_MODE_CPU_N", + "", + "", + "P10_DCM_PRESENT", + ""; + }; + + led-controller@61 { + compatible = "nxp,pca9552"; + reg = <0x61>; + #address-cells = <1>; + #size-cells = <0>; + gpio-controller; + #gpio-cells = <2>; + + gpio-line-names = + "", + "", + "SLOT2_PRSNT_EN_RSVD", + "", + "", + "", + "", + "SLOT2_EXPANDER_PRSNT_N", + "", + "", + "", + "", + "", + "", + "", + ""; + }; +}; + +&i2c9 { + status = "okay"; + + temperature-sensor@4c { + compatible = "ti,tmp423"; + reg = <0x4c>; + }; +}; + +&i2c10 { + status = "okay"; +}; + +&i2c11 { + status = "okay"; + + gpio@20 { + compatible = "ti,tca9554"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + + gpio-line-names = + "BOOT_RCVRY_TWI", + "BOOT_RCVRY_UART", + "", + "", + "", + "", + "", + "PE_SWITCH_RSTB_N"; + }; + + temperature-sensor@4c { + compatible = "ti,tmp435"; + reg = <0x4c>; + }; + + i2c-mux@75 { + compatible = "nxp,pca9849"; + reg = <0x75>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c11mux0chn0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c11mux0chn1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c11mux0chn2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c11mux0chn3: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +&i2c12 { + status = "okay"; + + tpm@2e { + compatible = "nuvoton,npct75x", "tcg,tpm-tis-i2c"; + reg = <0x2e>; + memory-region = <&event_log>; + }; + + eeprom@50 { + compatible = "atmel,24c64"; + reg = <0x50>; + }; +}; + +&i2c13 { + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c64"; + reg = <0x50>; + }; + + led-controller@60 { + compatible = "nxp,pca9551"; + reg = <0x60>; + #address-cells = <1>; + #size-cells = <0>; + gpio-controller; + #gpio-cells = <2>; + + led@0 { + reg = <0>; + default-state = "keep"; + label = "nvme3"; + retain-state-shutdown; + type = ; + }; + + led@1 { + reg = <1>; + default-state = "keep"; + label = "nvme2"; + retain-state-shutdown; + type = ; + }; + + led@2 { + reg = <2>; + default-state = "keep"; + label = "nvme1"; + retain-state-shutdown; + type = ; + }; + + led@3 { + reg = <3>; + default-state = "keep"; + label = "nvme0"; + retain-state-shutdown; + type = ; + }; + }; +}; + +&i2c14 { + status = "okay"; +}; + +&i2c15 { + status = "okay"; +}; + +&ibt { + status = "okay"; +}; + +&kcs2 { + aspeed,lpc-io-reg = <0xca8 0xcac>; + status = "okay"; +}; + +&kcs3 { + aspeed,lpc-io-reg = <0xca2>; + aspeed,lpc-interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; +}; + +&lpc_ctrl { + memory-region = <&flash_memory>; + status = "okay"; +}; + +&mac2 { + clocks = <&syscon ASPEED_CLK_GATE_MAC3CLK>, + <&syscon ASPEED_CLK_MAC3RCLK>; + clock-names = "MACCLK", "RCLK"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rmii3_default>; + use-ncsi; + status = "okay"; +}; + +&pinctrl_emmc_default { + bias-disable; +}; + +&uart2 { + status = "okay"; +}; + +&uhci { + status = "okay"; +}; + +&vuart1 { + status = "okay"; +}; + +&vuart2 { + status = "okay"; +}; + +&wdt1 { + aspeed,reset-type = "none"; + aspeed,external-signal; + aspeed,ext-push-pull; + aspeed,ext-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdtrst1_default>; +}; + +&wdt2 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts index 2f5d4075a64ad..a37399ff3cea2 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-bonnell.dts @@ -277,15 +277,11 @@ #size-cells = <0>; fan0: fan@0 { - compatible = "pmbus-fan"; reg = <0>; - tach-pulses = <2>; }; fan1: fan@1 { - compatible = "pmbus-fan"; reg = <1>; - tach-pulses = <2>; }; }; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-everest.dts index 9f144f527f03b..5a0975d52492c 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-everest.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-everest.dts @@ -2066,27 +2066,19 @@ reg = <0x52>; fan@0 { - compatible = "pmbus-fan"; reg = <0>; - tach-pulses = <2>; }; fan@1 { - compatible = "pmbus-fan"; reg = <1>; - tach-pulses = <2>; }; fan@2 { - compatible = "pmbus-fan"; reg = <2>; - tach-pulses = <2>; }; fan@3 { - compatible = "pmbus-fan"; reg = <3>; - tach-pulses = <2>; }; }; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dts index c5fb5d410001b..e90421bf7e3af 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dts @@ -1080,39 +1080,27 @@ #size-cells = <0>; fan0: fan@0 { - compatible = "pmbus-fan"; reg = <0>; - tach-pulses = <2>; }; fan1: fan@1 { - compatible = "pmbus-fan"; reg = <1>; - tach-pulses = <2>; }; fan2: fan@2 { - compatible = "pmbus-fan"; reg = <2>; - tach-pulses = <2>; }; fan3: fan@3 { - compatible = "pmbus-fan"; reg = <3>; - tach-pulses = <2>; }; fan4: fan@4 { - compatible = "pmbus-fan"; reg = <4>; - tach-pulses = <2>; }; fan5: fan@5 { - compatible = "pmbus-fan"; reg = <5>; - tach-pulses = <2>; }; }; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts index b31eb8e58c6b4..6fe7023599e88 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts @@ -481,55 +481,19 @@ #size-cells = <0>; fan@0 { - compatible = "pmbus-fan"; reg = <0>; - tach-pulses = <2>; - maxim,fan-rotor-input = "tach"; - maxim,fan-pwm-freq = <25000>; - maxim,fan-dual-tach; - maxim,fan-no-watchdog; - maxim,fan-no-fault-ramp; - maxim,fan-ramp = <2>; - maxim,fan-fault-pin-mon; }; fan@1 { - compatible = "pmbus-fan"; reg = <1>; - tach-pulses = <2>; - maxim,fan-rotor-input = "tach"; - maxim,fan-pwm-freq = <25000>; - maxim,fan-dual-tach; - maxim,fan-no-watchdog; - maxim,fan-no-fault-ramp; - maxim,fan-ramp = <2>; - maxim,fan-fault-pin-mon; }; fan@2 { - compatible = "pmbus-fan"; reg = <2>; - tach-pulses = <2>; - maxim,fan-rotor-input = "tach"; - maxim,fan-pwm-freq = <25000>; - maxim,fan-dual-tach; - maxim,fan-no-watchdog; - maxim,fan-no-fault-ramp; - maxim,fan-ramp = <2>; - maxim,fan-fault-pin-mon; }; fan@3 { - compatible = "pmbus-fan"; reg = <3>; - tach-pulses = <2>; - maxim,fan-rotor-input = "tach"; - maxim,fan-pwm-freq = <25000>; - maxim,fan-dual-tach; - maxim,fan-no-watchdog; - maxim,fan-no-fault-ramp; - maxim,fan-ramp = <2>; - maxim,fan-fault-pin-mon; }; }; diff --git a/arch/arm/boot/dts/aspeed/ibm-power11-dual.dtsi b/arch/arm/boot/dts/aspeed/ibm-power11-dual.dtsi new file mode 100644 index 0000000000000..6db02d4753800 --- /dev/null +++ b/arch/arm/boot/dts/aspeed/ibm-power11-dual.dtsi @@ -0,0 +1,779 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright 2025 IBM Corp. + +/ { + aliases { + i2c100 = &cfam0_i2c0; + i2c101 = &cfam0_i2c1; + i2c110 = &cfam0_i2c10; + i2c111 = &cfam0_i2c11; + i2c112 = &cfam0_i2c12; + i2c113 = &cfam0_i2c13; + i2c114 = &cfam0_i2c14; + i2c115 = &cfam0_i2c15; + i2c202 = &cfam1_i2c2; + i2c203 = &cfam1_i2c3; + i2c210 = &cfam1_i2c10; + i2c211 = &cfam1_i2c11; + i2c214 = &cfam1_i2c14; + i2c215 = &cfam1_i2c15; + i2c216 = &cfam1_i2c16; + i2c217 = &cfam1_i2c17; + + sbefifo100 = &sbefifo100; + sbefifo101 = &sbefifo101; + sbefifo110 = &sbefifo110; + sbefifo111 = &sbefifo111; + sbefifo112 = &sbefifo112; + sbefifo113 = &sbefifo113; + sbefifo114 = &sbefifo114; + sbefifo115 = &sbefifo115; + sbefifo202 = &sbefifo202; + sbefifo203 = &sbefifo203; + sbefifo210 = &sbefifo210; + sbefifo211 = &sbefifo211; + sbefifo214 = &sbefifo214; + sbefifo215 = &sbefifo215; + sbefifo216 = &sbefifo216; + sbefifo217 = &sbefifo217; + + scom100 = &scom100; + scom101 = &scom101; + scom110 = &scom110; + scom111 = &scom111; + scom112 = &scom112; + scom113 = &scom113; + scom114 = &scom114; + scom115 = &scom115; + scom202 = &scom202; + scom203 = &scom203; + scom210 = &scom210; + scom211 = &scom211; + scom214 = &scom214; + scom215 = &scom215; + scom216 = &scom216; + scom217 = &scom217; + + spi10 = &cfam0_spi0; + spi11 = &cfam0_spi1; + spi12 = &cfam0_spi2; + spi13 = &cfam0_spi3; + spi20 = &cfam1_spi0; + spi21 = &cfam1_spi1; + spi22 = &cfam1_spi2; + spi23 = &cfam1_spi3; + }; +}; + +&fsim0 { + bus-frequency = <100000000>; + #address-cells = <2>; + #size-cells = <0>; + cfam-reset-gpios = <&gpio0 ASPEED_GPIO(Q, 0) GPIO_ACTIVE_HIGH>; + status = "okay"; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom@1000 { + compatible = "ibm,p9-scom"; + reg = <0x1000 0x400>; + }; + + i2c@1800 { + compatible = "ibm,i2c-fsi"; + reg = <0x1800 0x400>; + #address-cells = <1>; + #size-cells = <0>; + + cfam0_i2c0: i2c-bus@0 { + reg = <0>; /* OMI01 */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom100: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo100: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam0_i2c1: i2c-bus@1 { + reg = <1>; /* OMI23 */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom101: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo101: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam0_i2c10: i2c-bus@a { + reg = <10>; /* OP3A */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom110: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo110: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam0_i2c11: i2c-bus@b { + reg = <11>; /* OP3B */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom111: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo111: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam0_i2c12: i2c-bus@c { + reg = <12>; /* OP4A */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom112: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo112: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam0_i2c13: i2c-bus@d { + reg = <13>; /* OP4B */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom113: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo113: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam0_i2c14: i2c-bus@e { + reg = <14>; /* OP5A */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom114: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo114: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam0_i2c15: i2c-bus@f { + reg = <15>; /* OP5B */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom115: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo115: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + }; + + fsi2spi@1c00 { + compatible = "ibm,fsi2spi"; + reg = <0x1c00 0x400>; + #address-cells = <1>; + #size-cells = <0>; + + cfam0_spi0: spi@0 { + compatible = "ibm,spi-fsi"; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom@0 { + compatible = "atmel,at25"; + reg = <0>; + address-width = <24>; + pagesize = <256>; + size = <0x80000>; + spi-max-frequency = <10000000>; + }; + }; + + cfam0_spi1: spi@20 { + compatible = "ibm,spi-fsi"; + reg = <0x20>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom@0 { + compatible = "atmel,at25"; + reg = <0>; + address-width = <24>; + pagesize = <256>; + size = <0x80000>; + spi-max-frequency = <10000000>; + }; + }; + + cfam0_spi2: spi@40 { + compatible = "ibm,spi-fsi"; + reg = <0x40>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom@0 { + compatible = "atmel,at25"; + reg = <0>; + address-width = <24>; + pagesize = <256>; + size = <0x80000>; + spi-max-frequency = <10000000>; + }; + }; + + cfam0_spi3: spi@60 { + compatible = "ibm,spi-fsi"; + reg = <0x60>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom@0 { + compatible = "atmel,at25"; + reg = <0>; + address-width = <24>; + pagesize = <256>; + size = <0x80000>; + spi-max-frequency = <10000000>; + }; + }; + }; + + sbefifo@2400 { + compatible = "ibm,p9-sbefifo"; + reg = <0x2400 0x400>; + + occ { + compatible = "ibm,p10-occ"; + + hwmon { + compatible = "ibm,p10-occ-hwmon"; + ibm,no-poll-on-init; + }; + }; + }; + + fsi_hub0: fsi@3400 { + compatible = "ibm,p9-fsi-controller"; + reg = <0x3400 0x400>; + #address-cells = <2>; + #size-cells = <0>; + }; + }; +}; + +&fsi_hub0 { + cfam@1,0 { + reg = <1 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <1>; + + scom@1000 { + compatible = "ibm,p9-scom"; + reg = <0x1000 0x400>; + }; + + i2c@1800 { + compatible = "ibm,i2c-fsi"; + reg = <0x1800 0x400>; + #address-cells = <1>; + #size-cells = <0>; + + cfam1_i2c2: i2c-bus@2 { + reg = <2>; /* OMI45 */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom202: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo202: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam1_i2c3: i2c-bus@3 { + reg = <3>; /* OMI67 */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom203: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo203: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam1_i2c10: i2c-bus@a { + reg = <10>; /* OP3A */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom210: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo210: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam1_i2c11: i2c-bus@b { + reg = <11>; /* OP3B */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom211: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo211: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam1_i2c14: i2c-bus@e { + reg = <14>; /* OP5A */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom214: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo214: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam1_i2c15: i2c-bus@f { + reg = <15>; /* OP5B */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom215: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo215: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam1_i2c16: i2c-bus@10 { + reg = <16>; /* OP6A */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom216: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo216: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + + cfam1_i2c17: i2c-bus@11 { + reg = <17>; /* OP6B */ + #address-cells = <1>; + #size-cells = <0>; + + fsi@20 { + compatible = "ibm,i2cr-fsi-master"; + reg = <0x20>; + #address-cells = <2>; + #size-cells = <0>; + + cfam@0,0 { + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + chip-id = <0>; + + scom217: scom@1000 { + compatible = "ibm,i2cr-scom"; + reg = <0x1000 0x400>; + }; + + sbefifo217: sbefifo@2400 { + compatible = "ibm,odyssey-sbefifo"; + reg = <0x2400 0x400>; + }; + }; + }; + }; + }; + + fsi2spi@1c00 { + compatible = "ibm,fsi2spi"; + reg = <0x1c00 0x400>; + #address-cells = <1>; + #size-cells = <0>; + + cfam1_spi0: spi@0 { + compatible = "ibm,spi-fsi"; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom@0 { + compatible = "atmel,at25"; + reg = <0>; + address-width = <24>; + pagesize = <256>; + size = <0x80000>; + spi-max-frequency = <10000000>; + }; + }; + + cfam1_spi1: spi@20 { + compatible = "ibm,spi-fsi"; + reg = <0x20>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom@0 { + compatible = "atmel,at25"; + reg = <0>; + address-width = <24>; + pagesize = <256>; + size = <0x80000>; + spi-max-frequency = <10000000>; + }; + }; + + cfam1_spi2: spi@40 { + compatible = "ibm,spi-fsi"; + reg = <0x40>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom@0 { + compatible = "atmel,at25"; + reg = <0>; + address-width = <24>; + pagesize = <256>; + size = <0x80000>; + spi-max-frequency = <10000000>; + }; + }; + + cfam1_spi3: spi@60 { + compatible = "ibm,spi-fsi"; + reg = <0x60>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom@0 { + compatible = "atmel,at25"; + reg = <0>; + address-width = <24>; + pagesize = <256>; + size = <0x80000>; + spi-max-frequency = <10000000>; + }; + }; + }; + + sbefifo@2400 { + compatible = "ibm,p9-sbefifo"; + reg = <0x2400 0x400>; + + occ { + compatible = "ibm,p10-occ"; + + hwmon { + compatible = "ibm,p10-occ-hwmon"; + ibm,no-poll-on-init; + }; + }; + }; + + fsi@3400 { + compatible = "ibm,p9-fsi-controller"; + reg = <0x3400 0x400>; + #address-cells = <2>; + #size-cells = <0>; + no-scan-on-init; + }; + }; +}; diff --git a/arch/arm/boot/dts/aspeed/ibm-power11-quad.dtsi b/arch/arm/boot/dts/aspeed/ibm-power11-quad.dtsi index 68c941a194b64..7aa4113d30263 100644 --- a/arch/arm/boot/dts/aspeed/ibm-power11-quad.dtsi +++ b/arch/arm/boot/dts/aspeed/ibm-power11-quad.dtsi @@ -1,24 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright 2024 IBM Corp. +#include "ibm-power11-dual.dtsi" + / { aliases { - i2c100 = &cfam0_i2c0; - i2c101 = &cfam0_i2c1; - i2c110 = &cfam0_i2c10; - i2c111 = &cfam0_i2c11; - i2c112 = &cfam0_i2c12; - i2c113 = &cfam0_i2c13; - i2c114 = &cfam0_i2c14; - i2c115 = &cfam0_i2c15; - i2c202 = &cfam1_i2c2; - i2c203 = &cfam1_i2c3; - i2c210 = &cfam1_i2c10; - i2c211 = &cfam1_i2c11; - i2c214 = &cfam1_i2c14; - i2c215 = &cfam1_i2c15; - i2c216 = &cfam1_i2c16; - i2c217 = &cfam1_i2c17; i2c300 = &cfam2_i2c0; i2c301 = &cfam2_i2c1; i2c310 = &cfam2_i2c10; @@ -36,22 +22,6 @@ i2c416 = &cfam3_i2c16; i2c417 = &cfam3_i2c17; - sbefifo100 = &sbefifo100; - sbefifo101 = &sbefifo101; - sbefifo110 = &sbefifo110; - sbefifo111 = &sbefifo111; - sbefifo112 = &sbefifo112; - sbefifo113 = &sbefifo113; - sbefifo114 = &sbefifo114; - sbefifo115 = &sbefifo115; - sbefifo202 = &sbefifo202; - sbefifo203 = &sbefifo203; - sbefifo210 = &sbefifo210; - sbefifo211 = &sbefifo211; - sbefifo214 = &sbefifo214; - sbefifo215 = &sbefifo215; - sbefifo216 = &sbefifo216; - sbefifo217 = &sbefifo217; sbefifo300 = &sbefifo300; sbefifo301 = &sbefifo301; sbefifo310 = &sbefifo310; @@ -69,22 +39,6 @@ sbefifo416 = &sbefifo416; sbefifo417 = &sbefifo417; - scom100 = &scom100; - scom101 = &scom101; - scom110 = &scom110; - scom111 = &scom111; - scom112 = &scom112; - scom113 = &scom113; - scom114 = &scom114; - scom115 = &scom115; - scom202 = &scom202; - scom203 = &scom203; - scom210 = &scom210; - scom211 = &scom211; - scom214 = &scom214; - scom215 = &scom215; - scom216 = &scom216; - scom217 = &scom217; scom300 = &scom300; scom301 = &scom301; scom310 = &scom310; @@ -102,14 +56,6 @@ scom416 = &scom416; scom417 = &scom417; - spi10 = &cfam0_spi0; - spi11 = &cfam0_spi1; - spi12 = &cfam0_spi2; - spi13 = &cfam0_spi3; - spi20 = &cfam1_spi0; - spi21 = &cfam1_spi1; - spi22 = &cfam1_spi2; - spi23 = &cfam1_spi3; spi30 = &cfam2_spi0; spi31 = &cfam2_spi1; spi32 = &cfam2_spi2; @@ -121,718 +67,7 @@ }; }; -&fsim0 { - #address-cells = <2>; - #size-cells = <0>; - status = "okay"; - bus-frequency = <100000000>; - cfam-reset-gpios = <&gpio0 ASPEED_GPIO(Q, 0) GPIO_ACTIVE_HIGH>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom@1000 { - compatible = "ibm,p9-scom"; - reg = <0x1000 0x400>; - }; - - i2c@1800 { - compatible = "ibm,i2c-fsi"; - reg = <0x1800 0x400>; - #address-cells = <1>; - #size-cells = <0>; - - cfam0_i2c0: i2c-bus@0 { - reg = <0>; /* OMI01 */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom100: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo100: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam0_i2c1: i2c-bus@1 { - reg = <1>; /* OMI23 */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom101: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo101: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam0_i2c10: i2c-bus@a { - reg = <10>; /* OP3A */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom110: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo110: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam0_i2c11: i2c-bus@b { - reg = <11>; /* OP3B */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom111: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo111: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam0_i2c12: i2c-bus@c { - reg = <12>; /* OP4A */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom112: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo112: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam0_i2c13: i2c-bus@d { - reg = <13>; /* OP4B */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom113: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo113: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam0_i2c14: i2c-bus@e { - reg = <14>; /* OP5A */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom114: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo114: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam0_i2c15: i2c-bus@f { - reg = <15>; /* OP5B */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom115: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo115: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - }; - - fsi2spi@1c00 { - compatible = "ibm,fsi2spi"; - reg = <0x1c00 0x400>; - #address-cells = <1>; - #size-cells = <0>; - - cfam0_spi0: spi@0 { - compatible = "ibm,spi-fsi"; - reg = <0x0>; - #address-cells = <1>; - #size-cells = <0>; - - eeprom@0 { - compatible = "atmel,at25"; - reg = <0>; - address-width = <24>; - pagesize = <256>; - size = <0x80000>; - spi-max-frequency = <10000000>; - }; - }; - - cfam0_spi1: spi@20 { - compatible = "ibm,spi-fsi"; - reg = <0x20>; - #address-cells = <1>; - #size-cells = <0>; - - eeprom@0 { - compatible = "atmel,at25"; - reg = <0>; - address-width = <24>; - pagesize = <256>; - size = <0x80000>; - spi-max-frequency = <10000000>; - }; - }; - - cfam0_spi2: spi@40 { - compatible = "ibm,spi-fsi"; - reg = <0x40>; - #address-cells = <1>; - #size-cells = <0>; - - eeprom@0 { - compatible = "atmel,at25"; - reg = <0>; - address-width = <24>; - pagesize = <256>; - size = <0x80000>; - spi-max-frequency = <10000000>; - }; - }; - - cfam0_spi3: spi@60 { - compatible = "ibm,spi-fsi"; - reg = <0x60>; - #address-cells = <1>; - #size-cells = <0>; - - eeprom@0 { - compatible = "atmel,at25"; - reg = <0>; - address-width = <24>; - pagesize = <256>; - size = <0x80000>; - spi-max-frequency = <10000000>; - }; - }; - }; - - sbefifo@2400 { - compatible = "ibm,p9-sbefifo"; - reg = <0x2400 0x400>; - - occ { - compatible = "ibm,p10-occ"; - - hwmon { - compatible = "ibm,p10-occ-hwmon"; - ibm,no-poll-on-init; - }; - }; - }; - - fsi_hub0: fsi@3400 { - compatible = "ibm,p9-fsi-controller"; - reg = <0x3400 0x400>; - #address-cells = <2>; - #size-cells = <0>; - }; - }; -}; - &fsi_hub0 { - cfam@1,0 { - reg = <1 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <1>; - - scom@1000 { - compatible = "ibm,p9-scom"; - reg = <0x1000 0x400>; - }; - - i2c@1800 { - compatible = "ibm,i2c-fsi"; - reg = <0x1800 0x400>; - #address-cells = <1>; - #size-cells = <0>; - - cfam1_i2c2: i2c-bus@2 { - reg = <2>; /* OMI45 */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom202: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo202: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam1_i2c3: i2c-bus@3 { - reg = <3>; /* OMI67 */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom203: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo203: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam1_i2c10: i2c-bus@a { - reg = <10>; /* OP3A */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom210: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo210: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam1_i2c11: i2c-bus@b { - reg = <11>; /* OP3B */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom211: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo211: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam1_i2c14: i2c-bus@e { - reg = <14>; /* OP5A */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom214: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo214: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam1_i2c15: i2c-bus@f { - reg = <15>; /* OP5B */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom215: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo215: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam1_i2c16: i2c-bus@10 { - reg = <16>; /* OP6A */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom216: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo216: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - - cfam1_i2c17: i2c-bus@11 { - reg = <17>; /* OP6B */ - #address-cells = <1>; - #size-cells = <0>; - - fsi@20 { - compatible = "ibm,i2cr-fsi-master"; - reg = <0x20>; - #address-cells = <2>; - #size-cells = <0>; - - cfam@0,0 { - reg = <0 0>; - #address-cells = <1>; - #size-cells = <1>; - chip-id = <0>; - - scom217: scom@1000 { - compatible = "ibm,i2cr-scom"; - reg = <0x1000 0x400>; - }; - - sbefifo217: sbefifo@2400 { - compatible = "ibm,odyssey-sbefifo"; - reg = <0x2400 0x400>; - }; - }; - }; - }; - }; - - fsi2spi@1c00 { - compatible = "ibm,fsi2spi"; - reg = <0x1c00 0x400>; - #address-cells = <1>; - #size-cells = <0>; - - cfam1_spi0: spi@0 { - compatible = "ibm,spi-fsi"; - reg = <0x0>; - #address-cells = <1>; - #size-cells = <0>; - - eeprom@0 { - compatible = "atmel,at25"; - reg = <0>; - address-width = <24>; - pagesize = <256>; - size = <0x80000>; - spi-max-frequency = <10000000>; - }; - }; - - cfam1_spi1: spi@20 { - compatible = "ibm,spi-fsi"; - reg = <0x20>; - #address-cells = <1>; - #size-cells = <0>; - - eeprom@0 { - compatible = "atmel,at25"; - reg = <0>; - address-width = <24>; - pagesize = <256>; - size = <0x80000>; - spi-max-frequency = <10000000>; - }; - }; - - cfam1_spi2: spi@40 { - compatible = "ibm,spi-fsi"; - reg = <0x40>; - #address-cells = <1>; - #size-cells = <0>; - - eeprom@0 { - compatible = "atmel,at25"; - reg = <0>; - address-width = <24>; - pagesize = <256>; - size = <0x80000>; - spi-max-frequency = <10000000>; - }; - }; - - cfam1_spi3: spi@60 { - compatible = "ibm,spi-fsi"; - reg = <0x60>; - #address-cells = <1>; - #size-cells = <0>; - - eeprom@0 { - compatible = "atmel,at25"; - reg = <0>; - address-width = <24>; - pagesize = <256>; - size = <0x80000>; - spi-max-frequency = <10000000>; - }; - }; - }; - - sbefifo@2400 { - compatible = "ibm,p9-sbefifo"; - reg = <0x2400 0x400>; - - occ { - compatible = "ibm,p10-occ"; - - hwmon { - compatible = "ibm,p10-occ-hwmon"; - ibm,no-poll-on-init; - }; - }; - }; - - fsi@3400 { - compatible = "ibm,p9-fsi-controller"; - reg = <0x3400 0x400>; - #address-cells = <2>; - #size-cells = <0>; - no-scan-on-init; - }; - }; - cfam@2,0 { reg = <2 0>; #address-cells = <1>; diff --git a/arch/arm/boot/dts/intel/socfpga/Makefile b/arch/arm/boot/dts/intel/socfpga/Makefile index 7f69a0355ea50..8df0976da01ce 100644 --- a/arch/arm/boot/dts/intel/socfpga/Makefile +++ b/arch/arm/boot/dts/intel/socfpga/Makefile @@ -2,7 +2,30 @@ dtb-$(CONFIG_ARCH_INTEL_SOCFPGA) += \ socfpga_arria5_socdk.dtb \ socfpga_arria10_chameleonv3.dtb \ - socfpga_arria10_mercury_pe1.dtb \ + socfpga_arria10_mercury_aa1_pe1_emmc.dtb \ + socfpga_arria10_mercury_aa1_pe1_qspi.dtb \ + socfpga_arria10_mercury_aa1_pe1_sdmmc.dtb \ + socfpga_arria10_mercury_aa1_pe3_emmc.dtb \ + socfpga_arria10_mercury_aa1_pe3_qspi.dtb \ + socfpga_arria10_mercury_aa1_pe3_sdmmc.dtb \ + socfpga_arria10_mercury_aa1_st1_emmc.dtb \ + socfpga_arria10_mercury_aa1_st1_qspi.dtb \ + socfpga_arria10_mercury_aa1_st1_sdmmc.dtb \ + socfpga_cyclone5_mercury_sa1_pe1_emmc.dtb \ + socfpga_cyclone5_mercury_sa1_pe1_qspi.dtb \ + socfpga_cyclone5_mercury_sa1_pe1_sdmmc.dtb \ + socfpga_cyclone5_mercury_sa1_pe3_emmc.dtb \ + socfpga_cyclone5_mercury_sa1_pe3_qspi.dtb \ + socfpga_cyclone5_mercury_sa1_pe3_sdmmc.dtb \ + socfpga_cyclone5_mercury_sa1_st1_emmc.dtb \ + socfpga_cyclone5_mercury_sa1_st1_qspi.dtb \ + socfpga_cyclone5_mercury_sa1_st1_sdmmc.dtb \ + socfpga_cyclone5_mercury_sa2_pe1_qspi.dtb \ + socfpga_cyclone5_mercury_sa2_pe1_sdmmc.dtb \ + socfpga_cyclone5_mercury_sa2_pe3_qspi.dtb \ + socfpga_cyclone5_mercury_sa2_pe3_sdmmc.dtb \ + socfpga_cyclone5_mercury_sa2_st1_qspi.dtb \ + socfpga_cyclone5_mercury_sa2_st1_sdmmc.dtb \ socfpga_arria10_socdk_nand.dtb \ socfpga_arria10_socdk_qspi.dtb \ socfpga_arria10_socdk_sdmmc.dtb \ diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1.dtsi b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1.dtsi index 41f865c8c0985..c80201bce793a 100644 --- a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1.dtsi +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1.dtsi @@ -7,12 +7,14 @@ / { - model = "Enclustra Mercury AA1"; - compatible = "enclustra,mercury-aa1", "altr,socfpga-arria10", "altr,socfpga"; + model = "Enclustra Mercury+ AA1"; + compatible = "enclustra,mercury-aa1", + "altr,socfpga-arria10", "altr,socfpga"; aliases { ethernet0 = &gmac0; serial1 = &uart1; + spi0 = &qspi; }; memory@0 { @@ -24,52 +26,102 @@ chosen { stdout-path = "serial1:115200n8"; }; + + /* Adjusted the i2c labels to use generic base-board dtsi files for + * Enclustra Arria10 and Cyclone5 SoMs. + * + * The set of i2c0 and i2c1 labels defined in socfpga_cyclone5.dtsi and in + * socfpga_arria10.dtsi do not allow for using the same base-board .dtsi + * fragments. Thus define generic labels here to match the correct i2c + * bus in a generic base-board .dtsi file. + */ + soc { + i2c_encl: i2c@ffc02300 { + }; + i2c_encl_fpga: i2c@ffc02200 { + }; + }; +}; + +&i2c_encl { + status = "okay"; + i2c-sda-hold-time-ns = <300>; + clock-frequency = <100000>; + + atsha204a: crypto@64 { + compatible = "atmel,atsha204a"; + reg = <0x64>; + }; + + isl12022: rtc@6f { + compatible = "isil,isl12022"; + reg = <0x6f>; + }; +}; + +&i2c_encl_fpga { + i2c-sda-hold-time-ns = <300>; + status = "disabled"; }; &gmac0 { - phy-mode = "rgmii"; + status = "okay"; + phy-mode = "rgmii-id"; phy-addr = <0xffffffff>; /* probe for phy addr */ - max-frame-size = <3800>; - phy-handle = <&phy3>; + /delete-property/ mac-address; + mdio { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy3: ethernet-phy@3 { - txd0-skew-ps = <0>; /* -420ps */ - txd1-skew-ps = <0>; /* -420ps */ - txd2-skew-ps = <0>; /* -420ps */ - txd3-skew-ps = <0>; /* -420ps */ + reg = <3>; + + /* Add 2ns RX clock delay (1.2ns + 0.78ns)*/ + rxc-skew-ps = <1680>; /* 780ps */ rxd0-skew-ps = <420>; /* 0ps */ rxd1-skew-ps = <420>; /* 0ps */ rxd2-skew-ps = <420>; /* 0ps */ rxd3-skew-ps = <420>; /* 0ps */ - txen-skew-ps = <0>; /* -420ps */ - txc-skew-ps = <1860>; /* 960ps */ rxdv-skew-ps = <420>; /* 0ps */ - rxc-skew-ps = <1680>; /* 780ps */ - reg = <3>; + + /* Add 1.38ns TX clock delay (0.96ns + 0.42ns)*/ + txc-skew-ps = <1860>; /* 960ps */ + txd0-skew-ps = <0>; /* -420ps */ + txd1-skew-ps = <0>; /* -420ps */ + txd2-skew-ps = <0>; /* -420ps */ + txd3-skew-ps = <0>; /* -420ps */ + txen-skew-ps = <0>; /* -420ps */ }; }; }; -&i2c1 { - atsha204a: crypto@64 { - compatible = "atmel,atsha204a"; - reg = <0x64>; - }; +&gpio0 { + status = "okay"; +}; - isl12022: isl12022@6f { - compatible = "isil,isl12022"; - reg = <0x6f>; - }; +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&uart0 { + status = "disabled"; +}; + +&uart1 { + status = "okay"; }; /* Following mappings are taken from arria10 socdk dts */ &mmc { + status = "okay"; cap-sd-highspeed; broken-cd; bus-width = <4>; @@ -79,3 +131,50 @@ &osc1 { clock-frequency = <33330000>; }; + +&eccmgr { + sdmmca-ecc@ff8c2c00 { + compatible = "altr,socfpga-sdmmc-ecc"; + reg = <0xff8c2c00 0x400>; + altr,ecc-parent = <&mmc>; + interrupts = <15 IRQ_TYPE_LEVEL_HIGH>, + <47 IRQ_TYPE_LEVEL_HIGH>, + <16 IRQ_TYPE_LEVEL_HIGH>, + <48 IRQ_TYPE_LEVEL_HIGH>; + }; +}; + +&qspi { + status = "okay"; + flash0: flash@0 { + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + spi-max-frequency = <10000000>; + + cdns,read-delay = <4>; + cdns,tshsl-ns = <50>; + cdns,tsd2d-ns = <50>; + cdns,tchsh-ns = <4>; + cdns,tslch-ns = <4>; + + partition@raw { + label = "Flash Raw"; + reg = <0x0 0x4000000>; + }; + }; +}; + +&watchdog1 { + status = "disabled"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe1_emmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe1_emmc.dts new file mode 100644 index 0000000000000..b6cca0b5fd099 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe1_emmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_arria10_mercury_aa1.dtsi" +#include "socfpga_enclustra_mercury_pe1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_emmc.dtsi" + +/ { + model = "Enclustra Mercury SA1 on Mercury+ PE1 Base Board"; + compatible = "enclustra,mercury-sa1-pe1", "enclustra,mercury-sa1", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe1_qspi.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe1_qspi.dts new file mode 100644 index 0000000000000..6ad023477cd2c --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe1_qspi.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_arria10_mercury_aa1.dtsi" +#include "socfpga_enclustra_mercury_pe1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_qspi.dtsi" + +/ { + model = "Enclustra Mercury+ AA1 on Mercury+ PE1 Base Board"; + compatible = "enclustra,mercury-aa1-pe1", "enclustra,mercury-aa1", + "altr,socfpga-arria10", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe1_sdmmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe1_sdmmc.dts new file mode 100644 index 0000000000000..653c9a86516ba --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe1_sdmmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_arria10_mercury_aa1.dtsi" +#include "socfpga_enclustra_mercury_pe1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_sdmmc.dtsi" + +/ { + model = "Enclustra Mercury+ AA1 on Mercury+ PE1 Base Board"; + compatible = "enclustra,mercury-aa1-pe1", "enclustra,mercury-aa1", + "altr,socfpga-arria10", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe3_emmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe3_emmc.dts new file mode 100644 index 0000000000000..ae9c7c6a23706 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe3_emmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_arria10_mercury_aa1.dtsi" +#include "socfpga_enclustra_mercury_pe3.dtsi" +#include "socfpga_enclustra_mercury_bootmode_emmc.dtsi" + +/ { + model = "Enclustra Mercury+ AA1 on Mercury+ PE3 Base Board"; + compatible = "enclustra,mercury-aa1-pe3", "enclustra,mercury-aa1", + "altr,socfpga-arria10", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe3_qspi.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe3_qspi.dts new file mode 100644 index 0000000000000..c3a0c30a07a51 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe3_qspi.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_arria10_mercury_aa1.dtsi" +#include "socfpga_enclustra_mercury_pe3.dtsi" +#include "socfpga_enclustra_mercury_bootmode_qspi.dtsi" + +/ { + model = "Enclustra Mercury+ AA1 on Mercury+ PE3 Base Board"; + compatible = "enclustra,mercury-aa1-pe3", "enclustra,mercury-aa1", + "altr,socfpga-arria10", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe3_sdmmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe3_sdmmc.dts new file mode 100644 index 0000000000000..dc1e1ad20381f --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_pe3_sdmmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_arria10_mercury_aa1.dtsi" +#include "socfpga_enclustra_mercury_pe3.dtsi" +#include "socfpga_enclustra_mercury_bootmode_sdmmc.dtsi" + +/ { + model = "Enclustra Mercury+ AA1 on Mercury+ PE3 Base Board"; + compatible = "enclustra,mercury-aa1-pe3", "enclustra,mercury-aa1", + "altr,socfpga-arria10", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_st1_emmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_st1_emmc.dts new file mode 100644 index 0000000000000..61d5e4c85d9b9 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_st1_emmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_arria10_mercury_aa1.dtsi" +#include "socfpga_enclustra_mercury_st1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_emmc.dtsi" + +/ { + model = "Enclustra Mercury+ AA1 on Mercury+ ST1 Base Board"; + compatible = "enclustra,mercury-aa1-st1", "enclustra,mercury-aa1", + "altr,socfpga-arria10", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_st1_qspi.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_st1_qspi.dts new file mode 100644 index 0000000000000..a3b99c9b16fd4 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_st1_qspi.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_arria10_mercury_aa1.dtsi" +#include "socfpga_enclustra_mercury_st1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_qspi.dtsi" + +/ { + model = "Enclustra Mercury+ AA1 on Mercury+ ST1 Base Board"; + compatible = "enclustra,mercury-aa1-st1", "enclustra,mercury-aa1", + "altr,socfpga-arria10", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_st1_sdmmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_st1_sdmmc.dts new file mode 100644 index 0000000000000..5deb289e2b55c --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_aa1_st1_sdmmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_arria10_mercury_aa1.dtsi" +#include "socfpga_enclustra_mercury_st1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_sdmmc.dtsi" + +/ { + model = "Enclustra Mercury+ AA1 on Mercury+ ST1 Base Board"; + compatible = "enclustra,mercury-aa1-st1", "enclustra,mercury-aa1", + "altr,socfpga-arria10", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_pe1.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_pe1.dts deleted file mode 100644 index cf533f76a9fd3..0000000000000 --- a/arch/arm/boot/dts/intel/socfpga/socfpga_arria10_mercury_pe1.dts +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright 2023 Steffen Trumtrar - */ -/dts-v1/; -#include "socfpga_arria10_mercury_aa1.dtsi" - -/ { - model = "Enclustra Mercury+ PE1"; - compatible = "enclustra,mercury-pe1", "enclustra,mercury-aa1", - "altr,socfpga-arria10", "altr,socfpga"; - - aliases { - ethernet0 = &gmac0; - serial0 = &uart0; - serial1 = &uart1; - }; -}; - -&gmac0 { - status = "okay"; -}; - -&gpio0 { - status = "okay"; -}; - -&gpio1 { - status = "okay"; -}; - -&gpio2 { - status = "okay"; -}; - -&i2c1 { - status = "okay"; -}; - -&mmc { - status = "okay"; -}; - -&uart0 { - status = "okay"; -}; - -&uart1 { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1.dtsi b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1.dtsi new file mode 100644 index 0000000000000..49944f9632f97 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1.dtsi @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +#include "socfpga_cyclone5.dtsi" + +/ { + model = "Enclustra Mercury SA1"; + compatible = "altr,socfpga-cyclone5", "altr,socfpga"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + ethernet0 = &gmac1; + }; + + /* Adjusted the i2c labels to use generic base-board dtsi files for + * Enclustra Arria10 and Cyclone5 SoMs. + * + * The set of i2c0 and i2c1 labels defined in socfpga_cyclone5.dtsi and in + * socfpga_arria10.dtsi do not allow for using the same base-board .dtsi + * fragments. Thus define generic labels here to match the correct i2c + * bus in a generic base-board .dtsi file. + */ + soc { + i2c_encl: i2c@ffc04000 { + }; + i2c_encl_fpga: i2c@ffc05000 { + }; + }; + + memory { + name = "memory"; + device_type = "memory"; + reg = <0x0 0x40000000>; /* 1GB */ + }; +}; + +&osc1 { + clock-frequency = <50000000>; +}; + +&i2c_encl { + i2c-sda-hold-time-ns = <300>; + clock-frequency = <100000>; + status = "okay"; + + isl12020: rtc@6f { + compatible = "isil,isl12022"; + reg = <0x6f>; + }; +}; + +&i2c_encl_fpga { + i2c-sda-hold-time-ns = <300>; + status = "disabled"; +}; + +&uart0 { + clock-frequency = <100000000>; +}; + +&mmc0 { + status = "okay"; + /delete-property/ cap-mmc-highspeed; + /delete-property/ cap-sd-highspeed; +}; + +&qspi { + status = "okay"; + + flash0: flash@0 { + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + spi-max-frequency = <10000000>; + + cdns,read-delay = <4>; + cdns,tshsl-ns = <50>; + cdns,tsd2d-ns = <50>; + cdns,tchsh-ns = <4>; + cdns,tslch-ns = <4>; + + partition@raw { + label = "Flash Raw"; + reg = <0x0 0x4000000>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gmac1 { + status = "okay"; + /delete-property/ mac-address; + phy-mode = "rgmii-id"; + phy-handle = <&phy3>; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + + phy3: ethernet-phy@3 { + reg = <3>; + + /* Add 2ns RX clock delay (1.2ns + 0.78ns)*/ + rxc-skew-ps = <1680>; + rxd0-skew-ps = <420>; + rxd1-skew-ps = <420>; + rxd2-skew-ps = <420>; + rxd3-skew-ps = <420>; + rxdv-skew-ps = <420>; + + /* Add 1.38ns TX clock delay (0.96ns + 0.42ns)*/ + txc-skew-ps = <1860>; + txd0-skew-ps = <0>; + txd1-skew-ps = <0>; + txd2-skew-ps = <0>; + txd3-skew-ps = <0>; + txen-skew-ps = <0>; + }; + }; +}; + +&usb1 { + status = "okay"; + dr_mode = "host"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe1_emmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe1_emmc.dts new file mode 100644 index 0000000000000..85d6146da0da3 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe1_emmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa1.dtsi" +#include "socfpga_enclustra_mercury_pe1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_emmc.dtsi" + +/ { + model = "Enclustra Mercury SA1 on Mercury+ PE1 Base Board"; + compatible = "enclustra,mercury-sa1-pe1", "enclustra,mercury-aa1", + "altr,socfpga-arria10", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe1_qspi.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe1_qspi.dts new file mode 100644 index 0000000000000..770ab680a18cc --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe1_qspi.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa1.dtsi" +#include "socfpga_enclustra_mercury_pe1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_qspi.dtsi" + +/ { + model = "Enclustra Mercury SA1 on Mercury+ PE1 Base Board"; + compatible = "enclustra,mercury-sa1-pe1", "enclustra,mercury-sa1", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe1_sdmmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe1_sdmmc.dts new file mode 100644 index 0000000000000..990ca0fec61ea --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe1_sdmmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa1.dtsi" +#include "socfpga_enclustra_mercury_pe1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_sdmmc.dtsi" + +/ { + model = "Enclustra Mercury SA1 on Mercury+ PE1 Base Board"; + compatible = "enclustra,mercury-sa1-pe1", "enclustra,mercury-sa1", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe3_emmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe3_emmc.dts new file mode 100644 index 0000000000000..6c8fd5b0d6ebc --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe3_emmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa1.dtsi" +#include "socfpga_enclustra_mercury_pe3.dtsi" +#include "socfpga_enclustra_mercury_bootmode_emmc.dtsi" + +/ { + model = "Enclustra Mercury SA1 on Mercury+ PE3 Base Board"; + compatible = "enclustra,mercury-sa1-pe3", "enclustra,mercury-sa1", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe3_qspi.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe3_qspi.dts new file mode 100644 index 0000000000000..3292426078a18 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe3_qspi.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa1.dtsi" +#include "socfpga_enclustra_mercury_pe3.dtsi" +#include "socfpga_enclustra_mercury_bootmode_qspi.dtsi" + +/ { + model = "Enclustra Mercury SA1 on Mercury+ PE3 Base Board"; + compatible = "enclustra,mercury-sa1-pe3", "enclustra,mercury-sa1", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe3_sdmmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe3_sdmmc.dts new file mode 100644 index 0000000000000..1eb10b5244ddc --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_pe3_sdmmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa1.dtsi" +#include "socfpga_enclustra_mercury_pe3.dtsi" +#include "socfpga_enclustra_mercury_bootmode_sdmmc.dtsi" + +/ { + model = "Enclustra Mercury SA1 on Mercury+ PE3 Base Board"; + compatible = "enclustra,mercury-sa1-pe3", "enclustra,mercury-sa1", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_st1_emmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_st1_emmc.dts new file mode 100644 index 0000000000000..8c97b5b3adeaf --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_st1_emmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa1.dtsi" +#include "socfpga_enclustra_mercury_st1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_emmc.dtsi" + +/ { + model = "Enclustra Mercury SA1 on Mercury+ ST1 Base Board"; + compatible = "enclustra,mercury-sa1-st1", "enclustra,mercury-sa1", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_st1_qspi.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_st1_qspi.dts new file mode 100644 index 0000000000000..e6d14b22e41d4 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_st1_qspi.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa1.dtsi" +#include "socfpga_enclustra_mercury_st1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_qspi.dtsi" + +/ { + model = "Enclustra Mercury SA1 on Mercury+ ST1 Base Board"; + compatible = "enclustra,mercury-sa1-st1", "enclustra,mercury-sa1", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_st1_sdmmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_st1_sdmmc.dts new file mode 100644 index 0000000000000..beaeca94d4df0 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa1_st1_sdmmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa1.dtsi" +#include "socfpga_enclustra_mercury_st1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_sdmmc.dtsi" + +/ { + model = "Enclustra Mercury SA1 on Mercury+ ST1 Base Board"; + compatible = "enclustra,mercury-sa1-st1", "enclustra,mercury-sa1", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2.dtsi b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2.dtsi new file mode 100644 index 0000000000000..0b28964e03781 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2.dtsi @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +#include "socfpga_cyclone5.dtsi" + +/ { + model = "Enclustra Mercury+ SA2"; + compatible = "altr,socfpga-cyclone5", "altr,socfpga"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + ethernet0 = &gmac1; + }; + + /* Adjusted the i2c labels to use generic base-board dtsi files for + * Enclustra Arria10 and Cyclone5 SoMs. + * + * The set of i2c0 and i2c1 labels defined in socfpga_cyclone5.dtsi and in + * socfpga_arria10.dtsi do not allow for using the same base-board .dtsi + * fragments. Thus define generic labels here to match the correct i2c + * bus in a generic base-board .dtsi file. + */ + soc { + i2c_encl: i2c@ffc04000 { + }; + i2c_encl_fpga: i2c@ffc05000 { + }; + }; + + memory { + name = "memory"; + device_type = "memory"; + reg = <0x0 0x80000000>; /* 2GB */ + }; +}; + +&osc1 { + clock-frequency = <50000000>; +}; + +&i2c_encl { + i2c-sda-hold-time-ns = <300>; + clock-frequency = <100000>; + status = "okay"; + + isl12020: rtc@6f { + compatible = "isil,isl12022"; + reg = <0x6f>; + }; + + atsha204a: crypto@64 { + compatible = "atmel,atsha204a"; + reg = <0x64>; + }; +}; + +&i2c_encl_fpga { + i2c-sda-hold-time-ns = <300>; + status = "disabled"; +}; + +&uart0 { + clock-frequency = <100000000>; +}; + +&mmc0 { + status = "okay"; +}; + +&qspi { + status = "okay"; + + flash0: flash@0 { + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + spi-max-frequency = <10000000>; + + cdns,read-delay = <4>; + cdns,tshsl-ns = <50>; + cdns,tsd2d-ns = <50>; + cdns,tchsh-ns = <4>; + cdns,tslch-ns = <4>; + + partition@raw { + label = "Flash Raw"; + reg = <0x0 0x4000000>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gmac1 { + status = "okay"; + /delete-property/ mac-address; + phy-mode = "rgmii-id"; + phy-handle = <&phy3>; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + + phy3: ethernet-phy@3 { + reg = <3>; + + /* Add 2ns RX clock delay (1.2ns + 0.78ns)*/ + rxc-skew-ps = <1680>; + rxd0-skew-ps = <420>; + rxd1-skew-ps = <420>; + rxd2-skew-ps = <420>; + rxd3-skew-ps = <420>; + rxdv-skew-ps = <420>; + + /* Add 1.38ns TX clock delay (0.96ns + 0.42ns)*/ + txc-skew-ps = <1860>; + txd0-skew-ps = <0>; + txd1-skew-ps = <0>; + txd2-skew-ps = <0>; + txd3-skew-ps = <0>; + txen-skew-ps = <0>; + }; + }; +}; + +&usb1 { + status = "okay"; + dr_mode = "host"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe1_qspi.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe1_qspi.dts new file mode 100644 index 0000000000000..6f79d9ed1d366 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe1_qspi.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa2.dtsi" +#include "socfpga_enclustra_mercury_pe1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_qspi.dtsi" + +/ { + model = "Enclustra Mercury+ SA2 on Mercury+ PE1 Base Board"; + compatible = "enclustra,mercury-sa2-pe1", "enclustra,mercury-sa2", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe1_sdmmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe1_sdmmc.dts new file mode 100644 index 0000000000000..b94bd8bafc26f --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe1_sdmmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa2.dtsi" +#include "socfpga_enclustra_mercury_pe1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_sdmmc.dtsi" + +/ { + model = "Enclustra Mercury+ SA2 on Mercury+ PE1 Base Board"; + compatible = "enclustra,mercury-sa2-pe1", "enclustra,mercury-sa2", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe3_qspi.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe3_qspi.dts new file mode 100644 index 0000000000000..51fc4a22937a5 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe3_qspi.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa2.dtsi" +#include "socfpga_enclustra_mercury_pe3.dtsi" +#include "socfpga_enclustra_mercury_bootmode_qspi.dtsi" + +/ { + model = "Enclustra Mercury+ SA2 on Mercury+ PE3 Base Board"; + compatible = "enclustra,mercury-sa2-pe3", "enclustra,mercury-sa2", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe3_sdmmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe3_sdmmc.dts new file mode 100644 index 0000000000000..e4209209f4fad --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_pe3_sdmmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa2.dtsi" +#include "socfpga_enclustra_mercury_pe3.dtsi" +#include "socfpga_enclustra_mercury_bootmode_sdmmc.dtsi" + +/ { + model = "Enclustra Mercury+ SA2 on Mercury+ PE3 Base Board"; + compatible = "enclustra,mercury-sa2-pe3", "enclustra,mercury-sa2", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_st1_qspi.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_st1_qspi.dts new file mode 100644 index 0000000000000..ab4549a0d4554 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_st1_qspi.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa2.dtsi" +#include "socfpga_enclustra_mercury_st1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_qspi.dtsi" + +/ { + model = "Enclustra Mercury+ SA2 on Mercury+ ST1 Base Board"; + compatible = "enclustra,mercury-sa2-st1", "enclustra,mercury-sa2", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_st1_sdmmc.dts b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_st1_sdmmc.dts new file mode 100644 index 0000000000000..ebe62879c3fbe --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_cyclone5_mercury_sa2_st1_sdmmc.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +/dts-v1/; + +#include "socfpga_cyclone5_mercury_sa2.dtsi" +#include "socfpga_enclustra_mercury_st1.dtsi" +#include "socfpga_enclustra_mercury_bootmode_sdmmc.dtsi" + +/ { + model = "Enclustra Mercury+ SA2 on Mercury+ ST1 Base Board"; + compatible = "enclustra,mercury-sa2-st1", "enclustra,mercury-sa2", + "altr,socfpga-cyclone5", "altr,socfpga"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_bootmode_emmc.dtsi b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_bootmode_emmc.dtsi new file mode 100644 index 0000000000000..d79cb64da0de7 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_bootmode_emmc.dtsi @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +&qspi { + status = "disabled"; +}; + +&mmc { + bus-width = <8>; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_bootmode_qspi.dtsi b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_bootmode_qspi.dtsi new file mode 100644 index 0000000000000..5ba21dd8f5ba1 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_bootmode_qspi.dtsi @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +&mmc { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_bootmode_sdmmc.dtsi b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_bootmode_sdmmc.dtsi new file mode 100644 index 0000000000000..2b102e0b6217a --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_bootmode_sdmmc.dtsi @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +&qspi { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_pe1.dtsi b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_pe1.dtsi new file mode 100644 index 0000000000000..abc4bfb7fccf0 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_pe1.dtsi @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +&i2c_encl { + status = "okay"; + + eeprom@57 { + status = "okay"; + compatible = "microchip,24c128"; + reg = <0x57>; + pagesize = <64>; + label = "user eeprom"; + address-width = <16>; + }; + + lm96080: temperature-sensor@2f { + status = "okay"; + compatible = "national,lm80"; + reg = <0x2f>; + }; + + si5338: clock-controller@70 { + compatible = "silabs,si5338"; + reg = <0x70>; + }; + +}; + +&i2c_encl_fpga { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_pe3.dtsi b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_pe3.dtsi new file mode 100644 index 0000000000000..bc57b0680878e --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_pe3.dtsi @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +&i2c_encl { + i2c-mux@74 { + status = "okay"; + compatible = "nxp,pca9547"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + eeprom@56 { + status = "okay"; + compatible = "microchip,24c128"; + reg = <0x56>; + pagesize = <64>; + label = "user eeprom"; + address-width = <16>; + }; + + lm96080: temperature-sensor@2f { + status = "okay"; + compatible = "national,lm80"; + reg = <0x2f>; + }; + + pcal6416: gpio@20 { + status = "okay"; + compatible = "nxp,pcal6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + }; + }; + }; +}; + +&i2c_encl_fpga { + status = "okay"; + + i2c-mux@75 { + status = "okay"; + compatible = "nxp,pca9547"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + }; +}; diff --git a/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_st1.dtsi b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_st1.dtsi new file mode 100644 index 0000000000000..4c00475f43030 --- /dev/null +++ b/arch/arm/boot/dts/intel/socfpga/socfpga_enclustra_mercury_st1.dtsi @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com + */ + +&i2c_encl { + si5338: clock-controller@70 { + compatible = "silabs,si5338"; + reg = <0x70>; + }; +}; + +&i2c_encl_fpga { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/marvell/armada-38x.dtsi b/arch/arm/boot/dts/marvell/armada-38x.dtsi index 1181b13deabc6..1d616edda322d 100644 --- a/arch/arm/boot/dts/marvell/armada-38x.dtsi +++ b/arch/arm/boot/dts/marvell/armada-38x.dtsi @@ -247,7 +247,7 @@ marvell,function = "dev"; }; - nand_rb: nand-rb { + nand_rb: nand-rb-pins { marvell,pins = "mpp41"; marvell,function = "nand"; }; diff --git a/arch/arm/boot/dts/marvell/armada-xp-98dx3236.dtsi b/arch/arm/boot/dts/marvell/armada-xp-98dx3236.dtsi index 7a7e2066c498a..a9a71326aafcb 100644 --- a/arch/arm/boot/dts/marvell/armada-xp-98dx3236.dtsi +++ b/arch/arm/boot/dts/marvell/armada-xp-98dx3236.dtsi @@ -322,7 +322,7 @@ marvell,function = "dev"; }; - nand_rb: nand-rb { + nand_rb: nand-rb-pins { marvell,pins = "mpp19"; marvell,function = "nand"; }; diff --git a/arch/arm/boot/dts/mediatek/Makefile b/arch/arm/boot/dts/mediatek/Makefile index e48de3efeb3b9..37c4cded0eae8 100644 --- a/arch/arm/boot/dts/mediatek/Makefile +++ b/arch/arm/boot/dts/mediatek/Makefile @@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt6572-jty-d101.dtb \ mt6572-lenovo-a369i.dtb \ mt6580-evbp1.dtb \ + mt6582-alcatel-yarisxl.dtb \ mt6582-prestigio-pmt5008-3g.dtb \ mt6589-aquaris5.dtb \ mt6589-fairphone-fp1.dtb \ diff --git a/arch/arm/boot/dts/mediatek/mt2701.dtsi b/arch/arm/boot/dts/mediatek/mt2701.dtsi index ce6a4015fed5a..128b87229f3d5 100644 --- a/arch/arm/boot/dts/mediatek/mt2701.dtsi +++ b/arch/arm/boot/dts/mediatek/mt2701.dtsi @@ -597,7 +597,7 @@ }; hifsys: syscon@1a000000 { - compatible = "mediatek,mt2701-hifsys", "syscon"; + compatible = "mediatek,mt2701-hifsys"; reg = <0 0x1a000000 0 0x1000>; #clock-cells = <1>; #reset-cells = <1>; diff --git a/arch/arm/boot/dts/mediatek/mt6582-alcatel-yarisxl.dts b/arch/arm/boot/dts/mediatek/mt6582-alcatel-yarisxl.dts new file mode 100644 index 0000000000000..f55d8edad1acf --- /dev/null +++ b/arch/arm/boot/dts/mediatek/mt6582-alcatel-yarisxl.dts @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Cristian Cozzolino + */ + +/dts-v1/; +#include "mt6582.dtsi" + +/ { + model = "Alcatel One Touch Pop C7 (OT-7041D)"; + compatible = "alcatel,yarisxl", "mediatek,mt6582"; + + aliases { + serial0 = &uart0; + }; + + chosen { + #address-cells = <1>; + #size-cells = <1>; + stdout-path = "serial0:921600n8"; + + framebuffer: framebuffer@9fa00000 { + compatible = "simple-framebuffer"; + memory-region = <&framebuffer_reserved>; + width = <480>; + height = <854>; + stride = <(480 * 4)>; + format = "r5g6b5"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x20000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + connsys@9f900000 { + reg = <0x9f900000 0x100000>; + no-map; + }; + + modem@9e000000 { + reg = <0x9e000000 0x1800000>; + no-map; + }; + + framebuffer_reserved: framebuffer@9fa00000 { + reg = <0x9fa00000 0x600000>; + no-map; + }; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/mediatek/mt6582.dtsi b/arch/arm/boot/dts/mediatek/mt6582.dtsi index 4263371784cd1..f941ea44898a9 100644 --- a/arch/arm/boot/dts/mediatek/mt6582.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6582.dtsi @@ -9,12 +9,12 @@ / { #address-cells = <1>; #size-cells = <1>; - compatible = "mediatek,mt6582"; interrupt-parent = <&sysirq>; cpus { - #address-cells = <1>; #size-cells = <0>; + #address-cells = <1>; + enable-method = "mediatek,mt6589-smp"; cpu@0 { device_type = "cpu"; @@ -38,91 +38,95 @@ }; }; - system_clk: dummy13m { + uart_clk: dummy26m { compatible = "fixed-clock"; - clock-frequency = <13000000>; #clock-cells = <0>; + clock-frequency = <26000000>; }; - rtc_clk: dummy32k { + system_clk: dummy13m { compatible = "fixed-clock"; - clock-frequency = <32000>; #clock-cells = <0>; + clock-frequency = <13000000>; }; - uart_clk: dummy26m { + rtc_clk: dummy32k { compatible = "fixed-clock"; - clock-frequency = <26000000>; #clock-cells = <0>; + clock-frequency = <32000>; }; - timer: timer@11008000 { - compatible = "mediatek,mt6577-timer"; - reg = <0x10008000 0x80>; - interrupts = ; - clocks = <&system_clk>, <&rtc_clk>; - clock-names = "system-clk", "rtc-clk"; - }; + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; - sysirq: interrupt-controller@10200100 { - compatible = "mediatek,mt6582-sysirq", - "mediatek,mt6577-sysirq"; - interrupt-controller; - #interrupt-cells = <3>; - interrupt-parent = <&gic>; - reg = <0x10200100 0x1c>; - }; + watchdog: watchdog@10007000 { + compatible = "mediatek,mt6582-wdt", "mediatek,mt6589-wdt"; + reg = <0x10007000 0x100>; + }; - gic: interrupt-controller@10211000 { - compatible = "arm,cortex-a7-gic"; - interrupt-controller; - #interrupt-cells = <3>; - interrupt-parent = <&gic>; - reg = <0x10211000 0x1000>, - <0x10212000 0x2000>, - <0x10214000 0x2000>, - <0x10216000 0x2000>; - }; + timer: timer@10008000 { + compatible = "mediatek,mt6582-timer", "mediatek,mt6577-timer"; + reg = <0x10008000 0x80>; + interrupts = ; + clocks = <&system_clk>, <&rtc_clk>; + }; - uart0: serial@11002000 { - compatible = "mediatek,mt6582-uart", - "mediatek,mt6577-uart"; - reg = <0x11002000 0x400>; - interrupts = ; - clocks = <&uart_clk>; - status = "disabled"; - }; + sysirq: interrupt-controller@10200100 { + compatible = "mediatek,mt6582-sysirq", "mediatek,mt6577-sysirq"; + reg = <0x10200100 0x1c>; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <3>; + }; - uart1: serial@11003000 { - compatible = "mediatek,mt6582-uart", - "mediatek,mt6577-uart"; - reg = <0x11003000 0x400>; - interrupts = ; - clocks = <&uart_clk>; - status = "disabled"; - }; + gic: interrupt-controller@10211000 { + compatible = "arm,cortex-a7-gic"; + #interrupt-cells = <3>; + interrupt-controller; + interrupt-parent = <&gic>; + reg = <0x10211000 0x1000>, + <0x10212000 0x2000>, + <0x10214000 0x2000>, + <0x10216000 0x2000>; + }; - uart2: serial@11004000 { - compatible = "mediatek,mt6582-uart", - "mediatek,mt6577-uart"; - reg = <0x11004000 0x400>; - interrupts = ; - clocks = <&uart_clk>; - status = "disabled"; - }; + uart0: serial@11002000 { + compatible = "mediatek,mt6582-uart", "mediatek,mt6577-uart"; + reg = <0x11002000 0x400>; + interrupts = ; + clocks = <&uart_clk>; + clock-names = "baud"; + status = "disabled"; + }; - uart3: serial@11005000 { - compatible = "mediatek,mt6582-uart", - "mediatek,mt6577-uart"; - reg = <0x11005000 0x400>; - interrupts = ; - clocks = <&uart_clk>; - status = "disabled"; - }; + uart1: serial@11003000 { + compatible = "mediatek,mt6582-uart", "mediatek,mt6577-uart"; + reg = <0x11003000 0x400>; + interrupts = ; + clocks = <&uart_clk>; + clock-names = "baud"; + status = "disabled"; + }; - watchdog: watchdog@10007000 { - compatible = "mediatek,mt6582-wdt", - "mediatek,mt6589-wdt"; - reg = <0x10007000 0x100>; + uart2: serial@11004000 { + compatible = "mediatek,mt6582-uart", "mediatek,mt6577-uart"; + reg = <0x11004000 0x400>; + interrupts = ; + clocks = <&uart_clk>; + clock-names = "baud"; + status = "disabled"; + }; + + uart3: serial@11005000 { + compatible = "mediatek,mt6582-uart", "mediatek,mt6577-uart"; + reg = <0x11005000 0x400>; + interrupts = ; + clocks = <&uart_clk>; + clock-names = "baud"; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/mediatek/mt7623.dtsi b/arch/arm/boot/dts/mediatek/mt7623.dtsi index fd7a89cc337d6..4b1685b939891 100644 --- a/arch/arm/boot/dts/mediatek/mt7623.dtsi +++ b/arch/arm/boot/dts/mediatek/mt7623.dtsi @@ -744,8 +744,7 @@ hifsys: syscon@1a000000 { compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", - "syscon"; + "mediatek,mt2701-hifsys"; reg = <0 0x1a000000 0 0x1000>; #clock-cells = <1>; #reset-cells = <1>; diff --git a/arch/arm/boot/dts/microchip/sama5d2.dtsi b/arch/arm/boot/dts/microchip/sama5d2.dtsi index 17430d7f20555..fde890f18d201 100644 --- a/arch/arm/boot/dts/microchip/sama5d2.dtsi +++ b/arch/arm/boot/dts/microchip/sama5d2.dtsi @@ -571,7 +571,7 @@ AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(12))>; dma-names = "tx", "rx"; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; @@ -642,7 +642,7 @@ AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(14))>; dma-names = "tx", "rx"; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; @@ -854,7 +854,7 @@ AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(16))>; dma-names = "tx", "rx"; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; @@ -925,7 +925,7 @@ AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(18))>; dma-names = "tx", "rx"; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; @@ -997,7 +997,7 @@ AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(20))>; dma-names = "tx", "rx"; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/microchip/sama7d65.dtsi b/arch/arm/boot/dts/microchip/sama7d65.dtsi index e53e2dd6d530c..cd2cf9a6f40b8 100644 --- a/arch/arm/boot/dts/microchip/sama7d65.dtsi +++ b/arch/arm/boot/dts/microchip/sama7d65.dtsi @@ -557,7 +557,7 @@ dma-names = "tx", "rx"; atmel,use-dma-rx; atmel,use-dma-tx; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; atmel,usart-mode = ; status = "disabled"; }; @@ -618,7 +618,7 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 40>; clock-names = "usart"; atmel,usart-mode = ; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; }; @@ -643,7 +643,7 @@ dma-names = "tx", "rx"; atmel,use-dma-rx; atmel,use-dma-tx; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; atmel,usart-mode = ; status = "disabled"; }; diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi index 381cbcfcb34a1..03ef3d9aaeec6 100644 --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi @@ -824,7 +824,7 @@ dma-names = "tx", "rx"; atmel,use-dma-rx; atmel,use-dma-tx; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; }; @@ -850,7 +850,7 @@ dma-names = "tx", "rx"; atmel,use-dma-rx; atmel,use-dma-tx; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/nvidia/Makefile b/arch/arm/boot/dts/nvidia/Makefile index 2ed2d923c8f92..faf591485ada7 100644 --- a/arch/arm/boot/dts/nvidia/Makefile +++ b/arch/arm/boot/dts/nvidia/Makefile @@ -11,7 +11,8 @@ dtb-$(CONFIG_ARCH_TEGRA_124_SOC) += \ tegra124-nyan-big.dtb \ tegra124-nyan-big-fhd.dtb \ tegra124-nyan-blaze.dtb \ - tegra124-venice2.dtb + tegra124-venice2.dtb \ + tegra124-xiaomi-mocha.dtb dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \ tegra20-acer-a500-picasso.dtb \ tegra20-asus-sl101.dtb \ diff --git a/arch/arm/boot/dts/nvidia/tegra114.dtsi b/arch/arm/boot/dts/nvidia/tegra114.dtsi index a2a50f959927d..a98667641be20 100644 --- a/arch/arm/boot/dts/nvidia/tegra114.dtsi +++ b/arch/arm/boot/dts/nvidia/tegra114.dtsi @@ -48,6 +48,45 @@ ranges = <0x54000000 0x54000000 0x01000000>; + vi@54080000 { + compatible = "nvidia,tegra114-vi"; + reg = <0x54080000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA114_CLK_VI>; + resets = <&tegra_car 20>; + reset-names = "vi"; + + iommus = <&mc TEGRA_SWGROUP_VI>; + + status = "disabled"; + }; + + epp@540c0000 { + compatible = "nvidia,tegra114-epp"; + reg = <0x540c0000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA114_CLK_EPP>; + resets = <&tegra_car TEGRA114_CLK_EPP>; + reset-names = "epp"; + + iommus = <&mc TEGRA_SWGROUP_EPP>; + + status = "disabled"; + }; + + isp@54100000 { + compatible = "nvidia,tegra114-isp"; + reg = <0x54100000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA114_CLK_ISP>; + resets = <&tegra_car TEGRA114_CLK_ISP>; + reset-names = "isp"; + + iommus = <&mc TEGRA_SWGROUP_ISP>; + + status = "disabled"; + }; + gr2d@54140000 { compatible = "nvidia,tegra114-gr2d"; reg = <0x54140000 0x00040000>; @@ -150,6 +189,31 @@ #address-cells = <1>; #size-cells = <0>; }; + + msenc@544c0000 { + compatible = "nvidia,tegra114-msenc"; + reg = <0x544c0000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA114_CLK_MSENC>; + resets = <&tegra_car TEGRA114_CLK_MSENC>; + reset-names = "mpe"; + + iommus = <&mc TEGRA_SWGROUP_MSENC>; + + status = "disabled"; + }; + + tsec@54500000 { + compatible = "nvidia,tegra114-tsec"; + reg = <0x54500000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA114_CLK_TSEC>; + resets = <&tegra_car TEGRA114_CLK_TSEC>; + + iommus = <&mc TEGRA_SWGROUP_TSEC>; + + status = "disabled"; + }; }; gic: interrupt-controller@50041000 { diff --git a/arch/arm/boot/dts/nvidia/tegra124-xiaomi-mocha.dts b/arch/arm/boot/dts/nvidia/tegra124-xiaomi-mocha.dts new file mode 100644 index 0000000000000..18c9cdf45eca8 --- /dev/null +++ b/arch/arm/boot/dts/nvidia/tegra124-xiaomi-mocha.dts @@ -0,0 +1,2790 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include +#include +#include +#include +#include + +#include "tegra124.dtsi" + +/ { + model = "Xiaomi Mi Pad A0101"; + compatible = "xiaomi,mocha", "nvidia,tegra124"; + chassis-type = "tablet"; + + aliases { + mmc0 = &sdmmc4; /* eMMC */ + mmc1 = &sdmmc3; /* uSD slot */ + mmc2 = &sdmmc1; /* WiFi */ + + rtc0 = &palmas; + rtc1 = "/rtc@7000e000"; + + serial0 = &uartd; /* Console */ + serial1 = &uartc; /* Bluetooth */ + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@80000000 { + reg = <0 0x80000000 0 0x80000000>; + }; + + host1x@50000000 { + dsia: dsi@54300000 { + status = "okay"; + + avdd-dsi-csi-supply = <&avdd_dsi_csi>; + nvidia,ganged-mode = <&dsib>; + + panel@0 { + compatible = "sharp,lq079l1sx01"; + reg = <0>; + + reset-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_LOW>; + + avdd-supply = <&avdd_lcd>; + vddio-supply = <&vdd_lcd_io>; + + vsp-supply = <&vsp_5v5_lcd>; + vsn-supply = <&vsn_5v5_lcd>; + + backlight = <&lp8556>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + panel_link0: endpoint { + remote-endpoint = <&dsia_out>; + }; + }; + + port@1 { + reg = <1>; + + panel_link1: endpoint { + remote-endpoint = <&dsib_out>; + }; + }; + }; + }; + + port { + dsia_out: endpoint { + remote-endpoint = <&panel_link0>; + }; + }; + }; + + dsib: dsi@54400000 { + status = "okay"; + + avdd-dsi-csi-supply = <&avdd_dsi_csi>; + + port { + dsib_out: endpoint { + remote-endpoint = <&panel_link1>; + }; + }; + }; + }; + + gpu@57000000 { + vdd-supply = <&vdd_gpu>; + }; + + clock@60006000 { + emc-timings-0 { + nvidia,ram-code = <0>; + + timing-12750000 { + clock-frequency = <12750000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-20400000 { + clock-frequency = <20400000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-40800000 { + clock-frequency = <40800000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-68000000 { + clock-frequency = <68000000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-102000000 { + clock-frequency = <102000000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-204000000 { + clock-frequency = <204000000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-300000000 { + clock-frequency = <300000000>; + nvidia,parent-clock-frequency = <600000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_C>; + clock-names = "emc-parent"; + }; + + timing-396000000 { + clock-frequency = <396000000>; + nvidia,parent-clock-frequency = <792000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_M>; + clock-names = "emc-parent"; + }; + + timing-528000000 { + clock-frequency = <528000000>; + nvidia,parent-clock-frequency = <528000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>; + clock-names = "emc-parent"; + }; + + timing-600000000 { + clock-frequency = <600000000>; + nvidia,parent-clock-frequency = <600000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_C_UD>; + clock-names = "emc-parent"; + }; + + timing-792000000 { + clock-frequency = <792000000>; + nvidia,parent-clock-frequency = <792000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>; + clock-names = "emc-parent"; + }; + + timing-924000000 { + clock-frequency = <924000000>; + nvidia,parent-clock-frequency = <924000000>; + clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>; + clock-names = "emc-parent"; + }; + }; + }; + + pinmux@70000868 { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + /* Keys pinmux */ + keys { + nvidia,pins = "kb_col0_pq0", + "kb_col6_pq6", + "kb_col7_pq7"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + hall-front { + nvidia,pins = "pi5"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + hall-back { + nvidia,pins = "gpio_w3_aud_pw3"; + nvidia,function = "spi1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Leds pinmux */ + bl-en { + nvidia,pins = "pbb4"; + nvidia,function = "vgp4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + keys-led { + nvidia,pins = "ph1"; + nvidia,function = "pwm1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + rgb-led-en { + nvidia,pins = "pg7"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* Panel pinmux */ + lcd-rst { + nvidia,pins = "ph3"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + lcd-vsp-en { + nvidia,pins = "pi4"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + lcd-vsn-en { + nvidia,pins = "kb_row10_ps2"; + nvidia,function = "kbc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + lcd-id { + nvidia,pins = "kb_row6_pr6"; + nvidia,function = "displaya_alt"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + lcd-pwm { + nvidia,pins = "ph2"; + nvidia,function = "pwm2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* SDMMC1 pinmux */ + sdmmc1-clk { + nvidia,pins = "sdmmc1_clk_pz0"; + nvidia,function = "sdmmc1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + sdmmc1-cmd { + nvidia,pins = "sdmmc1_cmd_pz1", + "sdmmc1_dat0_py7", + "sdmmc1_dat1_py6", + "sdmmc1_dat2_py5", + "sdmmc1_dat3_py4"; + nvidia,function = "sdmmc1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* SDMMC3 pinmux */ + sdmmc3-clk { + nvidia,pins = "sdmmc3_clk_pa6"; + nvidia,function = "sdmmc3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + sdmmc3-cmd { + nvidia,pins = "sdmmc3_cmd_pa7", + "sdmmc3_dat0_pb7", + "sdmmc3_dat1_pb6", + "sdmmc3_dat2_pb5", + "sdmmc3_dat3_pb4", + "sdmmc3_clk_lb_out_pee4", + "sdmmc3_clk_lb_in_pee5"; + nvidia,function = "sdmmc3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + sdmmc3-cd { + nvidia,pins = "sdmmc3_cd_n_pv2"; + nvidia,function = "sdmmc3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + usd-pwr { + nvidia,pins = "kb_row0_pr0"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* SDMMC4 pinmux */ + sdmmc4-clk { + nvidia,pins = "sdmmc4_clk_pcc4"; + nvidia,function = "sdmmc4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + sdmmc4-cmd { + nvidia,pins = "sdmmc4_cmd_pt7", + "sdmmc4_dat0_paa0", + "sdmmc4_dat1_paa1", + "sdmmc4_dat2_paa2", + "sdmmc4_dat3_paa3", + "sdmmc4_dat4_paa4", + "sdmmc4_dat5_paa5", + "sdmmc4_dat6_paa6", + "sdmmc4_dat7_paa7"; + nvidia,function = "sdmmc4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* UART-B pinmux */ + uartb-cts { + nvidia,pins = "uart2_cts_n_pj5"; + nvidia,function = "uartb"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + uartb-rts { + nvidia,pins = "uart2_rts_n_pj6"; + nvidia,function = "uartb"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + uartb-rxd { + nvidia,pins = "uart2_rxd_pc3"; + nvidia,function = "irda"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + uartb-txd { + nvidia,pins = "uart2_txd_pc2"; + nvidia,function = "irda"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* UART-C pinmux */ + uartc-cts-rxd { + nvidia,pins = "uart3_cts_n_pa1", + "uart3_rxd_pw7"; + nvidia,function = "uartc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + uartc-rts-txd { + nvidia,pins = "uart3_rts_n_pc0", + "uart3_txd_pw6"; + nvidia,function = "uartc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* UART-D pinmux */ + uartd-txd { + nvidia,pins = "pj7"; + nvidia,function = "uartd"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + uartd-rxd { + nvidia,pins = "pb0"; + nvidia,function = "uartd"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + /* I2C pinmux */ + gen1-i2c { + nvidia,pins = "gen1_i2c_sda_pc5", + "gen1_i2c_scl_pc4"; + nvidia,function = "i2c1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; + nvidia,open-drain = ; + }; + + gen2-i2c { + nvidia,pins = "gen2_i2c_scl_pt5", + "gen2_i2c_sda_pt6"; + nvidia,function = "i2c2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; + nvidia,open-drain = ; + }; + + cam-i2c { + nvidia,pins = "cam_i2c_scl_pbb1", + "cam_i2c_sda_pbb2"; + nvidia,function = "i2c3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; + nvidia,open-drain = ; + }; + + ddc-i2c { + nvidia,pins = "ddc_scl_pv4", + "ddc_sda_pv5"; + nvidia,function = "i2c4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + pwr-i2c { + nvidia,pins = "pwr_i2c_scl_pz6", + "pwr_i2c_sda_pz7"; + nvidia,function = "i2cpwr"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + }; + + ts-irq { + nvidia,pins = "kb_row7_pr7"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + ts-rst { + nvidia,pins = "pk4"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + ts-en { + nvidia,pins = "pk1"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + hapt-en { + nvidia,pins = "pg6"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + charger-irq { + nvidia,pins = "pj0"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + bat-irq { + nvidia,pins = "kb_col5_pq5"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + compass-rst { + nvidia,pins = "kb_col4_pq4"; + nvidia,function = "kbc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + als-irq { + nvidia,pins = "gpio_x3_aud_px3"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + therm-irq { + nvidia,pins = "pi6"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + wlan-reg-on { + nvidia,pins = "gpio_x7_aud_px7"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + wlan-host-wake { + nvidia,pins = "pu5"; + nvidia,function = "pwm2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + bt-reg-on { + nvidia,pins = "kb_row1_pr1"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + bt-host-wake { + nvidia,pins = "pu6"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + bt-dev-wake { + nvidia,pins = "clk3_req_pee1"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + imu-irq { + nvidia,pins = "kb_row3_pr3"; + nvidia,function = "kbc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + imu-sync { + nvidia,pins = "kb_row8_ps0"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cdc-mclk1 { + nvidia,pins = "dap_mclk1_pw4"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cdc-din { + nvidia,pins = "dap1_din_pn1", + "dap1_fs_pn0", + "dap1_sclk_pn3"; + nvidia,function = "i2s0"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cdc-dout { + nvidia,pins = "dap1_dout_pn2"; + nvidia,function = "i2s0"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + spkr-rl-rst { + nvidia,pins = "dap2_din_pa4"; + nvidia,function = "i2s1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + spkr-rl-irq { + nvidia,pins = "dap2_fs_pa2", + "dap2_sclk_pa3"; + nvidia,function = "i2s1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + dvfs-pwm { + nvidia,pins = "dvfs_pwm_px0"; + nvidia,function = "cldvfs"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + dvfs-clk { + nvidia,pins = "dvfs_clk_px2"; + nvidia,function = "cldvfs"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cam-mclk { + nvidia,pins = "cam_mclk_pcc0"; + nvidia,function = "vi_alt3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cam-mclk2 { + nvidia,pins = "pbb0"; + nvidia,function = "vimclk2_alt"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + vbrtr-pwm { + nvidia,pins = "ph0"; + nvidia,function = "pwm0"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + soc-pins { + nvidia,pins = "pj2", "kb_row15_ps7", + "clk_32k_out_pa0"; + nvidia,function = "soc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + clk-32k-in { + nvidia,pins = "clk_32k_in"; + nvidia,function = "clk"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + core-pwr-req { + nvidia,pins = "core_pwr_req"; + nvidia,function = "pwron"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cpu-pwr-req { + nvidia,pins = "cpu_pwr_req"; + nvidia,function = "cpu"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + pwr-int-n { + nvidia,pins = "pwr_int_n"; + nvidia,function = "pmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + reset-out-n { + nvidia,pins = "reset_out_n"; + nvidia,function = "reset_out_n"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + lcd-id-det0 { + nvidia,pins = "pi7"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cdc-rst { + nvidia,pins = "gpio_x5_aud_px5"; + nvidia,function = "spi1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cdc-det-irq { + nvidia,pins = "gpio_w2_aud_pw2"; + nvidia,function = "rsvd2"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + hph-pa-sd { + nvidia,pins = "gpio_x1_aud_px1"; + nvidia,function = "spi6"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + hph-en { + nvidia,pins = "kb_row2_pr2"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cam-rear-rst-n { + nvidia,pins = "pbb3"; + nvidia,function = "vgp3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cam-af-pwdn { + nvidia,pins = "pbb7"; + nvidia,function = "i2s4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cam-front-pwdn { + nvidia,pins = "pbb6"; + nvidia,function = "i2s4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + cam-front-rst-n { + nvidia,pins = "pcc1"; + nvidia,function = "i2s4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + gps-en { + nvidia,pins = "ph5"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + boot-select { + nvidia,pins = "pg0", "pg1", "pg2", "pg3"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + ram-select { + nvidia,pins = "pg4", "pg5"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + line-in-det { + nvidia,pins = "pk2"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + gpadc-sync { + nvidia,pins = "pi0"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + gpu-pwr-req { + nvidia,pins = "kb_row5_pr5"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + ear-uart-sw { + nvidia,pins = "pu4"; + nvidia,function = "pwm1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + + dsi-b { + nvidia,pins = "mipi_pad_ctrl_dsi_b"; + nvidia,function = "dsi_b"; + }; + + /* GPIO power/drive control */ + drive-sdio1 { + nvidia,pins = "drive_sdio1"; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,pull-down-strength = <32>; + nvidia,pull-up-strength = <42>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; + }; + + drive-sdio3 { + nvidia,pins = "drive_sdio3"; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,pull-down-strength = <20>; + nvidia,pull-up-strength = <36>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; + }; + + drive-gma { + nvidia,pins = "drive_gma"; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; + nvidia,pull-down-strength = <1>; + nvidia,pull-up-strength = <2>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; + }; + }; + }; + + uartc: serial@70006200 { + compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; + reset-names = "serial"; + /delete-property/ reg-shift; + status = "okay"; + + nvidia,adjust-baud-rates = <0 9600 100>, + <9600 115200 200>, + <1000000 4000000 136>; + + bluetooth { + compatible = "brcm,bcm43540-bt"; + max-speed = <4000000>; + + clocks = <&clk32k_pmic>; + clock-names = "lpo"; + + interrupt-parent = <&gpio>; + interrupts = ; + interrupt-names = "host-wakeup"; + + device-wakeup-gpios = <&gpio TEGRA_GPIO(EE, 1) GPIO_ACTIVE_HIGH>; + shutdown-gpios = <&gpio TEGRA_GPIO(R, 1) GPIO_ACTIVE_HIGH>; + + vbat-supply = <&vdd_3v3_sys>; + vddio-supply = <&vdd_1v8_vio>; + }; + }; + + uartd: serial@70006300 { + /delete-property/ dmas; + /delete-property/ dma-names; + status = "okay"; + + /* Console */ + }; + + pwm@7000a000 { + status = "okay"; + }; + + gen1_i2c: i2c@7000c000 { + status = "okay"; + clock-frequency = <400000>; + + lp8556: backlight@2c { + compatible = "ti,lp8556"; + reg = <0x2c>; + + dev-ctrl = /bits/ 8 <0x83>; + init-brt = /bits/ 8 <0x1f>; + + power-supply = <&vdd_3v3_sys>; + enable-supply = <&vddio_1v8_bl>; + + rom-98h { + rom-addr = /bits/ 8 <0x98>; + rom-val = /bits/ 8 <0x80>; + }; + + rom-9eh { + rom-addr = /bits/ 8 <0x9e>; + rom-val = /bits/ 8 <0x21>; + }; + + rom-a0h { + rom-addr = /bits/ 8 <0xa0>; + rom-val = /bits/ 8 <0xff>; + }; + + rom-a1h { + rom-addr = /bits/ 8 <0xa1>; + rom-val = /bits/ 8 <0x3f>; + }; + + rom-a2h { + rom-addr = /bits/ 8 <0xa2>; + rom-val = /bits/ 8 <0x20>; + }; + + rom-a3h { + rom-addr = /bits/ 8 <0xa3>; + rom-val = /bits/ 8 <0x00>; + }; + + rom-a4h { + rom-addr = /bits/ 8 <0xa4>; + rom-val = /bits/ 8 <0x72>; + }; + + rom-a5h { + rom-addr = /bits/ 8 <0xa5>; + rom-val = /bits/ 8 <0x24>; + }; + + rom-a6h { + rom-addr = /bits/ 8 <0xa6>; + rom-val = /bits/ 8 <0x80>; + }; + + rom-a7h { + rom-addr = /bits/ 8 <0xa7>; + rom-val = /bits/ 8 <0xf5>; + }; + + rom-a8h { + rom-addr = /bits/ 8 <0xa8>; + rom-val = /bits/ 8 <0x24>; + }; + + rom-a9h { + rom-addr = /bits/ 8 <0xa9>; + rom-val = /bits/ 8 <0xb2>; + }; + + rom-aah { + rom-addr = /bits/ 8 <0xaa>; + rom-val = /bits/ 8 <0x8f>; + }; + + rom-aeh { + rom-addr = /bits/ 8 <0xae>; + rom-val = /bits/ 8 <0x0f>; + }; + }; + + led-controller@32 { + compatible = "national,lp5521"; + reg = <0x32>; + + enable-gpios = <&gpio TEGRA_GPIO(G, 7) GPIO_ACTIVE_HIGH>; + clock-mode = /bits/ 8 <2>; + + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + + led-cur = /bits/ 8 <0x14>; + max-cur = /bits/ 8 <0xff>; + + color = ; + function = LED_FUNCTION_STATUS; + }; + + led@1 { + reg = <1>; + + led-cur = /bits/ 8 <0x14>; + max-cur = /bits/ 8 <0xff>; + + color = ; + function = LED_FUNCTION_STATUS; + }; + + led@2 { + reg = <2>; + + led-cur = /bits/ 8 <0x14>; + max-cur = /bits/ 8 <0xff>; + + color = ; + function = LED_FUNCTION_STATUS; + }; + }; + + audio-codec@34 { + compatible = "nxp,tfa9890"; + reg = <0x34>; + + sound-name-prefix = "Speaker Right"; + vddd-supply = <&vdd_1v8_vio>; + + #sound-dai-cells = <0>; + }; + + audio-codec@37 { + compatible = "nxp,tfa9890"; + reg = <0x37>; + + sound-name-prefix = "Speaker Left"; + vddd-supply = <&vdd_1v8_vio>; + + #sound-dai-cells = <0>; + }; + + light-sensor@44 { + compatible = "isil,isl29035"; + reg = <0x44>; + + interrupt-parent = <&gpio>; + interrupts = ; + + vcc-supply = <&vdd_3v3_sys>; + }; + + temp_sensor: temperature-sensor@4c { + compatible = "ti,tmp451"; + reg = <0x4c>; + + interrupt-parent = <&gpio>; + interrupts = ; + + vcc-supply = <&vdd_1v8_vio>; + #thermal-sensor-cells = <1>; + }; + + haptic-engine@5a { + compatible = "ti,drv2604"; + reg = <0x5a>; + + enable-gpios = <&gpio TEGRA_GPIO(G, 6) GPIO_ACTIVE_HIGH>; + + mode = ; + library-sel = ; + + vib-rated-mv = <3200>; + vib-overdrive-mv = <3400>; + + vbat-supply = <&vdd_3v3_sys>; + }; + }; + + gen2_i2c: i2c@7000c400 { + status = "okay"; + clock-frequency = <400000>; + + power-sensor@40 { + compatible = "ti,ina230"; + reg = <0x40>; + + vs-supply = <&vdd_hv_sdmmc>; + #io-channel-cells = <1>; + }; + + fuel-gauge@55 { + compatible = "ti,bq27520g4"; + reg = <0x55>; + + interrupt-parent = <&gpio>; + interrupts = ; + + monitored-battery = <&battery>; + power-supplies = <&bq24192>; + }; + + bq24192: charger@6b { + compatible = "ti,bq24192"; + reg = <0x6b>; + + interrupt-parent = <&gpio>; + interrupts = ; + + ce-gpios = <&palmas_gpio 7 GPIO_ACTIVE_LOW>; + + monitored-battery = <&battery>; + + omit-battery-class; + ti,system-minimum-microvolt = <3500000>; + + usb_otg_vbus: usb-otg-vbus { + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + }; + }; + + i2c@7000c700 { + status = "okay"; + clock-frequency = <400000>; + + /* Atmel mxT1664T/mxT1066T touchscreen */ + touchscreen@4a { + compatible = "atmel,maxtouch"; + reg = <0x4a>; + + interrupt-parent = <&gpio>; + interrupts = ; + + reset-gpios = <&gpio TEGRA_GPIO(K, 4) GPIO_ACTIVE_LOW>; + + linux,keycodes = ; + + vdda-supply = <&avdd_3v3_ts>; + vdd-supply = <&vdd_2v8_tp>; + }; + }; + + i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + /* Texas Instruments TPS65913 PMIC */ + palmas: pmic@58 { + compatible = "ti,tps65913", "ti,palmas"; + reg = <0x58>; + interrupts = ; + + #interrupt-cells = <2>; + interrupt-controller; + + ti,system-power-controller; + + adc { + compatible = "ti,palmas-gpadc"; + interrupts = <18 IRQ_TYPE_NONE>, + <16 IRQ_TYPE_NONE>, + <17 IRQ_TYPE_NONE>; + + ti,channel0-current-microamp = <20>; + #io-channel-cells = <1>; + }; + + palmas_extcon: extcon { + compatible = "ti,palmas-usb-vid"; + + ti,enable-vbus-detection; + ti,enable-id-detection; + + ti,wakeup; + }; + + palmas_gpio: gpio { + compatible = "ti,palmas-gpio"; + gpio-controller; + #gpio-cells = <2>; + }; + + clk32k_pmic: palmas-clk32k@0 { + compatible = "ti,palmas-clk32kg"; + #clock-cells = <0>; + }; + + pinmux { + compatible = "ti,tps65913-pinctrl"; + + pinctrl-names = "default"; + pinctrl-0 = <&palmas_default>; + + palmas_default: pinmux { + pin_gpio0 { + pins = "gpio0"; + function = "id"; + bias-pull-up; + }; + + pin_gpio1 { + pins = "gpio1"; + function = "gpio"; + }; + + pin_gpio2 { + pins = "gpio2"; + function = "gpio"; + }; + + /* GPIO3 is not used */ + + pin_gpio4 { + pins = "gpio4"; + function = "gpio"; + }; + + pin_gpio5 { + pins = "gpio5"; + function = "clk32kgaudio"; + }; + + /* GPIO6 is not used */ + + pin_gpio7 { + pins = "gpio7"; + function = "gpio"; + }; + + pin_powergood { + pins = "powergood"; + function = "powergood"; + }; + + pin_vac { + pins = "vac"; + function = "vac"; + }; + }; + }; + + pmic { + compatible = "ti,tps65913-pmic", "ti,palmas-pmic"; + + ldo1-in-supply = <&vdd_1v8_vio>; + ldo2-in-supply = <&vdd_3v3_sys>; + ldo3-in-supply = <&vdd_smps10_out2>; + ldo4-in-supply = <&vdd_3v3_sys>; + ldo5-in-supply = <&vdd_1v8_vio>; + ldo6-in-supply = <&vdd_3v3_sys>; + ldo7-in-supply = <&vdd_3v3_sys>; + ldo8-in-supply = <&vdd_3v3_sys>; + ldo9-in-supply = <&vdd_hv_sdmmc>; + ldousb-in-supply = <&vdd_smps10_out2>; + ldoln-in-supply = <&vdd_smps10_out2>; + + regulators { + vdd_cpu: smps123 { + regulator-name = "vdd_cpu"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + regulator-boot-on; + ti,roof-floor = <1>; + ti,mode-sleep = <3>; + }; + + vdd_gpu: smps45 { + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1400000>; + }; + + vddio_ddr: smps6 { + regulator-name = "vddio_ddr"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_core: smps7 { + regulator-name = "vdd_core"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + regulator-boot-on; + ti,roof-floor = <3>; + }; + + vdd_1v8_vio: smps8 { + regulator-name = "vdd_1v8_gen"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_hv_sdmmc: smps9 { + regulator-name = "vdd_hv_sdmmc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + smps10_out1 { + regulator-name = "vd_smps10_out1"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_smps10_out2: smps10_out2 { + regulator-name = "vd_smps10_out2"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; + + avdd_pll: ldo1 { + regulator-name = "avdd_pll"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-always-on; + regulator-boot-on; + ti,roof-floor = <3>; + }; + + avdd_lcd: ldo2 { + regulator-name = "avdd_lcd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + }; + + avdd_3v3_ts: ldo3 { + regulator-name = "avdd_3v3_ts"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + avdd_2v7_cam: ldo4 { + regulator-name = "avdd_2v7_cam"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + }; + + avdd_dsi_csi: ldo5 { + regulator-name = "avdd_dsi_csi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-boot-on; + }; + + ldo6 { + regulator-name = "vdd_1v8_fuse"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + avdd_2v7_vcm: ldo7 { + regulator-name = "avdd_2v7_vcm"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + }; + + ldo8 { + regulator-name = "vdd_rtc"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + regulator-always-on; + regulator-boot-on; + ti,enable-ldo8-tracking; + }; + + vddio_usd: ldo9 { + regulator-name = "vddio_sdmmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; + + avdd_usb: ldousb { + regulator-name = "vdd_usb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + ldoln { + regulator-name = "vddio_hv"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + }; + }; + + rtc { + compatible = "ti,palmas-rtc"; + interrupt-parent = <&palmas>; + interrupts = <8 IRQ_TYPE_NONE>; + }; + }; + }; + + pmc@7000e400 { + nvidia,suspend-mode = <1>; + nvidia,cpu-pwr-good-time = <500>; + nvidia,cpu-pwr-off-time = <300>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <2000>; + nvidia,core-power-req-active-high; + nvidia,sys-clock-req-active-high; + core-supply = <&vdd_core>; + + /* Clear DEV_ON bit in DEV_CTRL register of TPS65913 PMIC */ + i2c-thermtrip { + nvidia,i2c-controller-id = <4>; + nvidia,bus-addr = <0x58>; + nvidia,reg-addr = <0xa0>; + nvidia,reg-data = <0x00>; + }; + }; + + memory-controller@70019000 { + emc-timings-0 { + /* Hynix H9CKNNNBKTMTDR DDR3 924MHz */ + nvidia,ram-code = <0>; + + timing-12750000 { + clock-frequency = <12750000>; + + nvidia,emem-configuration = < 0x40040001 0x8000000a + 0x00000001 0x00000002 0x00000004 0x00000000 + 0x00000003 0x00000001 0x00000002 0x00000007 + 0x00000002 0x00000001 0x00000004 0x00000005 + 0x05040102 0x000b0604 0x77230305 0x70000f03 + 0x001f0000 >; + }; + + timing-20400000 { + clock-frequency = <20400000>; + + nvidia,emem-configuration = < 0x40020001 0x80000012 + 0x00000001 0x00000002 0x00000004 0x00000000 + 0x00000003 0x00000001 0x00000002 0x00000007 + 0x00000002 0x00000001 0x00000004 0x00000005 + 0x05040102 0x000b0604 0x75a30305 0x70000f03 + 0x001f0000 >; + }; + + timing-40800000 { + clock-frequency = <40800000>; + + nvidia,emem-configuration = < 0xa0000001 0x80000017 + 0x00000001 0x00000002 0x00000004 0x00000000 + 0x00000003 0x00000001 0x00000002 0x00000007 + 0x00000002 0x00000001 0x00000004 0x00000005 + 0x05040102 0x000b0604 0x74030305 0x70000f03 + 0x001f0000 >; + }; + + timing-68000000 { + clock-frequency = <68000000>; + + nvidia,emem-configuration = < 0x00000001 0x8000001e + 0x00000001 0x00000002 0x00000003 0x00000000 + 0x00000003 0x00000001 0x00000002 0x00000007 + 0x00000002 0x00000001 0x00000004 0x00000005 + 0x05040102 0x000a0503 0x73830404 0x70000f03 + 0x001f0000 >; + }; + + timing-102000000 { + clock-frequency = <102000000>; + + nvidia,emem-configuration = < 0x08000001 0x80000026 + 0x00000001 0x00000002 0x00000004 0x00000001 + 0x00000003 0x00000001 0x00000002 0x00000007 + 0x00000002 0x00000001 0x00000004 0x00000005 + 0x05040102 0x000a0504 0x73430505 0x70000f03 + 0x001f0000 >; + }; + + timing-204000000 { + clock-frequency = <204000000>; + + nvidia,emem-configuration = < 0x01000003 0x80000040 + 0x00000001 0x00000002 0x00000007 0x00000003 + 0x00000005 0x00000001 0x00000002 0x00000007 + 0x00000003 0x00000001 0x00000005 0x00000005 + 0x05050103 0x000b0607 0x72e40a08 0x70000f03 + 0x001f0000 >; + }; + + timing-300000000 { + clock-frequency = <300000000>; + + nvidia,emem-configuration = < 0x08000004 0x80000040 + 0x00000001 0x00000002 0x00000009 0x00000005 + 0x00000007 0x00000001 0x00000002 0x00000007 + 0x00000003 0x00000001 0x00000005 0x00000005 + 0x05050103 0x000c0709 0x72c50e0a 0x70000f03 + 0x001f0000 >; + }; + + timing-396000000 { + clock-frequency = <396000000>; + + nvidia,emem-configuration = < 0x0f000005 0x80000040 + 0x00000002 0x00000003 0x0000000c 0x00000007 + 0x00000009 0x00000001 0x00000002 0x00000007 + 0x00000003 0x00000001 0x00000005 0x00000005 + 0x05050103 0x000e090c 0x72c6120d 0x70000f03 + 0x001f0000 >; + }; + + timing-528000000 { + clock-frequency = <528000000>; + + nvidia,emem-configuration = < 0x0f000007 0x80000040 + 0x00000003 0x00000004 0x00000010 0x0000000a + 0x0000000d 0x00000002 0x00000002 0x00000009 + 0x00000003 0x00000001 0x00000006 0x00000006 + 0x06060103 0x00120b10 0x72c81811 0x70000f03 + 0x001f0000 >; + }; + + timing-600000000 { + clock-frequency = <600000000>; + + nvidia,emem-configuration = < 0x00000009 0x80000040 + 0x00000004 0x00000005 0x00000012 0x0000000b + 0x0000000e 0x00000002 0x00000003 0x0000000a + 0x00000003 0x00000001 0x00000006 0x00000007 + 0x07060103 0x00140d12 0x72c91b13 0x70000f03 + 0x001f0000 >; + }; + + timing-792000000 { + clock-frequency = <792000000>; + + nvidia,emem-configuration = < 0x0e00000b 0x80000040 + 0x00000006 0x00000007 0x00000018 0x0000000f + 0x00000013 0x00000003 0x00000003 0x0000000c + 0x00000003 0x00000001 0x00000008 0x00000008 + 0x08080103 0x001a1118 0x72ac2419 0x70000f02 + 0x001f0000 >; + }; + + timing-924000000 { + clock-frequency = <924000000>; + + nvidia,emem-configuration = < 0x0e00000d 0x80000040 + 0x00000007 0x00000008 0x0000001b 0x00000012 + 0x00000017 0x00000004 0x00000004 0x0000000e + 0x00000004 0x00000001 0x00000009 0x00000009 + 0x09090104 0x001e141b 0x72ae2a1c 0x70000f02 + 0x001f0000 >; + }; + }; + }; + + external-memory-controller@7001b000 { + emc-timings-0 { + /* Hynix H9CKNNNBKTMTDR DDR3 924MHz */ + nvidia,ram-code = <0>; + + timing-12750000 { + clock-frequency = <12750000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000008>; + nvidia,emc-cfg = <0xd3200000>; + nvidia,emc-cfg-2 = <0x000008c7>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x80010083>; + nvidia,emc-mode-2 = <0x80020004>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x000d0011>; + nvidia,emc-sel-dpd-ctrl = <0x0004013c>; + nvidia,emc-xm2dqspadctrl2 = <0x0130b018>; + nvidia,emc-zcal-cnt-long = <0x00000015>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x00000000 0x00000002 0x00000000 0x00000002 + 0x00000005 0x00000006 0x00000008 0x00000003 + 0x0000000a 0x00000002 0x00000002 0x00000001 + 0x00000002 0x00000000 0x00000003 0x00000003 + 0x00000006 0x00000002 0x00000000 0x00000005 + 0x00000005 0x00010000 0x00000003 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000004 + 0x0000000c 0x0000000d 0x0000000f 0x00000030 + 0x00000000 0x0000000c 0x00000002 0x00000002 + 0x00000005 0x00000000 0x00000001 0x0000000c + 0x00000003 0x00000003 0x00000003 0x00000003 + 0x00000003 0x00000006 0x00000006 0x00000003 + 0x00000003 0x00000056 0x00000000 0x00000000 + 0x00000000 0x1363a296 0x005800a0 0x00008000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x000fc000 0x000fc000 0x00000000 0x000fc000 + 0x000fc000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x000fc000 0x000fc000 + 0x000fc000 0x000fc000 0x0000fc00 0x0000fc00 + 0x0000fc00 0x0000fc00 0x00000200 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc000 + 0x00000404 0x81f1f008 0x07070000 0x0000003f + 0x015ddddd 0x51451400 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x00000011 0x000d0011 0x00000000 0x00000003 + 0x0000f3f3 0x80000164 0x0000000a >; + }; + + timing-20400000 { + clock-frequency = <20400000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000008>; + nvidia,emc-cfg = <0xd3200000>; + nvidia,emc-cfg-2 = <0x000008c7>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x80010083>; + nvidia,emc-mode-2 = <0x80020004>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x00150011>; + nvidia,emc-sel-dpd-ctrl = <0x0004013c>; + nvidia,emc-xm2dqspadctrl2 = <0x0130b018>; + nvidia,emc-zcal-cnt-long = <0x00000015>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x00000001 0x00000004 0x00000000 0x00000002 + 0x00000005 0x00000006 0x00000008 0x00000003 + 0x0000000a 0x00000002 0x00000002 0x00000001 + 0x00000002 0x00000000 0x00000003 0x00000003 + 0x00000006 0x00000002 0x00000000 0x00000005 + 0x00000005 0x00010000 0x00000003 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000004 + 0x0000000c 0x0000000d 0x0000000f 0x0000004d + 0x00000000 0x00000013 0x00000002 0x00000002 + 0x00000005 0x00000000 0x00000001 0x0000000c + 0x00000005 0x00000005 0x00000003 0x00000003 + 0x00000003 0x00000006 0x00000006 0x00000003 + 0x00000003 0x0000008a 0x00000000 0x00000000 + 0x00000000 0x1363a296 0x005800a0 0x00008000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x000fc000 0x000fc000 0x00000000 0x000fc000 + 0x000fc000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x000fc000 0x000fc000 + 0x000fc000 0x000fc000 0x0000fc00 0x0000fc00 + 0x0000fc00 0x0000fc00 0x00000200 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc000 + 0x00000404 0x81f1f008 0x07070000 0x0000003f + 0x015ddddd 0x51451400 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x00000011 0x00150011 0x00000000 0x00000003 + 0x0000f3f3 0x8000019f 0x0000000a >; + }; + + timing-40800000 { + clock-frequency = <40800000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000008>; + nvidia,emc-cfg = <0xd3200000>; + nvidia,emc-cfg-2 = <0x000008c7>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x80010083>; + nvidia,emc-mode-2 = <0x80020004>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x00290011>; + nvidia,emc-sel-dpd-ctrl = <0x0004013c>; + nvidia,emc-xm2dqspadctrl2 = <0x0130b018>; + nvidia,emc-zcal-cnt-long = <0x00000015>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x00000002 0x00000008 0x00000000 0x00000002 + 0x00000005 0x00000006 0x00000008 0x00000003 + 0x0000000a 0x00000002 0x00000002 0x00000001 + 0x00000002 0x00000000 0x00000003 0x00000003 + 0x00000006 0x00000002 0x00000000 0x00000005 + 0x00000005 0x00010000 0x00000003 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000004 + 0x0000000c 0x0000000d 0x0000000f 0x0000009a + 0x00000000 0x00000026 0x00000002 0x00000002 + 0x00000005 0x00000000 0x00000001 0x0000000c + 0x00000009 0x00000009 0x00000003 0x00000003 + 0x00000003 0x00000006 0x00000007 0x00000003 + 0x00000003 0x00000113 0x00000000 0x00000000 + 0x00000000 0x1363a296 0x005800a0 0x00008000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x000fc000 0x000fc000 0x00000000 0x000fc000 + 0x000fc000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x000fc000 0x000fc000 + 0x000fc000 0x000fc000 0x0000fc00 0x0000fc00 + 0x0000fc00 0x0000fc00 0x00000200 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc000 + 0x00000404 0x81f1f008 0x07070000 0x0000003f + 0x015ddddd 0x51451400 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x00000011 0x00290011 0x00000000 0x00000003 + 0x0000f3f3 0x8000023a 0x0000000a >; + }; + + timing-68000000 { + clock-frequency = <68000000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000008>; + nvidia,emc-cfg = <0xd3200000>; + nvidia,emc-cfg-2 = <0x000008c7>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x80010083>; + nvidia,emc-mode-2 = <0x80020004>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x00440011>; + nvidia,emc-sel-dpd-ctrl = <0x0004013c>; + nvidia,emc-xm2dqspadctrl2 = <0x0130b018>; + nvidia,emc-zcal-cnt-long = <0x00000015>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x00000004 0x00000010 0x00000000 0x00000002 + 0x00000004 0x00000006 0x00000008 0x00000003 + 0x0000000a 0x00000002 0x00000002 0x00000001 + 0x00000002 0x00000000 0x00000003 0x00000003 + 0x00000006 0x00000002 0x00000000 0x00000005 + 0x00000005 0x00010000 0x00000003 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000004 + 0x0000000c 0x0000000d 0x0000000f 0x00000101 + 0x00000000 0x00000040 0x00000002 0x00000002 + 0x00000004 0x00000000 0x00000001 0x0000000c + 0x0000000f 0x0000000f 0x00000003 0x00000003 + 0x00000003 0x00000006 0x00000005 0x00000003 + 0x00000003 0x000001c9 0x00000000 0x00000000 + 0x00000000 0x1363a296 0x005800a0 0x00008000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x000fc000 0x000fc000 0x00000000 0x000fc000 + 0x000fc000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x000fc000 0x000fc000 + 0x000fc000 0x000fc000 0x0000fc00 0x0000fc00 + 0x0000fc00 0x0000fc00 0x00000200 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc000 + 0x00000404 0x81f1f008 0x07070000 0x0000003f + 0x015ddddd 0x51451400 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x00000019 0x00440011 0x00000000 0x00000003 + 0x0000f3f3 0x80000309 0x0000000a >; + }; + + timing-102000000 { + clock-frequency = <102000000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000008>; + nvidia,emc-cfg = <0xd3200000>; + nvidia,emc-cfg-2 = <0x000008c7>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x80010083>; + nvidia,emc-mode-2 = <0x80020004>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x00660011>; + nvidia,emc-sel-dpd-ctrl = <0x0004013c>; + nvidia,emc-xm2dqspadctrl2 = <0x0130b018>; + nvidia,emc-zcal-cnt-long = <0x00000015>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x00000006 0x00000015 0x00000000 0x00000004 + 0x00000004 0x00000006 0x00000008 0x00000003 + 0x0000000a 0x00000002 0x00000002 0x00000001 + 0x00000002 0x00000000 0x00000003 0x00000003 + 0x00000006 0x00000002 0x00000000 0x00000005 + 0x00000005 0x00010000 0x00000003 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000004 + 0x0000000c 0x0000000d 0x0000000f 0x00000182 + 0x00000000 0x00000060 0x00000002 0x00000002 + 0x00000004 0x00000000 0x00000001 0x0000000c + 0x00000017 0x00000017 0x00000003 0x00000003 + 0x00000003 0x00000006 0x00000005 0x00000003 + 0x00000003 0x000002ae 0x00000000 0x00000000 + 0x00000000 0x1363a296 0x005800a0 0x00008000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00090000 0x00090000 0x00090000 0x00090000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x000fc000 0x000fc000 0x00000000 0x000fc000 + 0x000fc000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x000fc000 0x000fc000 + 0x000fc000 0x000fc000 0x0000fc00 0x0000fc00 + 0x0000fc00 0x0000fc00 0x00000200 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc000 + 0x00000404 0x81f1f008 0x07070000 0x0000003f + 0x015ddddd 0x51451400 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x00000025 0x00660011 0x00000000 0x00000003 + 0x0000f3f3 0x8000040b 0x0000000a >; + }; + + timing-204000000 { + clock-frequency = <204000000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000008>; + nvidia,emc-cfg = <0xd3200000>; + nvidia,emc-cfg-2 = <0x000008cf>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x80010083>; + nvidia,emc-mode-2 = <0x80020004>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x00cc0011>; + nvidia,emc-sel-dpd-ctrl = <0x0004013c>; + nvidia,emc-xm2dqspadctrl2 = <0x0130b018>; + nvidia,emc-zcal-cnt-long = <0x00000017>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x0000000c 0x0000002a 0x00000000 0x00000008 + 0x00000005 0x00000007 0x00000008 0x00000003 + 0x0000000a 0x00000003 0x00000003 0x00000002 + 0x00000003 0x00000000 0x00000002 0x00000002 + 0x00000005 0x00000003 0x00000000 0x00000003 + 0x00000007 0x00010000 0x00000004 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000002 + 0x0000000e 0x0000000f 0x00000011 0x00000304 + 0x00000000 0x000000c1 0x00000002 0x00000002 + 0x00000005 0x00000000 0x00000001 0x0000000c + 0x0000002d 0x0000002d 0x00000003 0x00000004 + 0x00000003 0x00000009 0x00000006 0x00000003 + 0x00000003 0x0000055b 0x00000000 0x00000000 + 0x00000000 0x1363a296 0x005800a0 0x00008000 + 0x00080000 0x00080000 0x00080000 0x00080000 + 0x00080000 0x00080000 0x00080000 0x00080000 + 0x00080000 0x00080000 0x00080000 0x00080000 + 0x00080000 0x00080000 0x00080000 0x00080000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00098000 0x00098000 0x00000000 0x00098000 + 0x00098000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x0008c000 0x00088000 + 0x00088000 0x00088000 0x00008800 0x00008800 + 0x00008800 0x00008800 0x00000200 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc000 + 0x00000404 0x81f1f008 0x07070000 0x0000003f + 0x015ddddd 0x51451400 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x0000004a 0x00cc0011 0x00000000 0x00000004 + 0x0000d3b3 0x80000713 0x0000000a >; + }; + + timing-300000000 { + clock-frequency = <300000000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000000>; + nvidia,emc-cfg = <0xd3300000>; + nvidia,emc-cfg-2 = <0x000008d7>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x80010083>; + nvidia,emc-mode-2 = <0x80020004>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x012c0011>; + nvidia,emc-sel-dpd-ctrl = <0x0004013c>; + nvidia,emc-xm2dqspadctrl2 = <0x01231239>; + nvidia,emc-zcal-cnt-long = <0x0000001f>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x00000011 0x0000003e 0x00000000 0x0000000c + 0x00000005 0x00000007 0x00000008 0x00000003 + 0x0000000a 0x00000005 0x00000005 0x00000002 + 0x00000003 0x00000000 0x00000002 0x00000002 + 0x00000006 0x00000003 0x00000000 0x00000003 + 0x00000008 0x00030000 0x00000004 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000002 + 0x0000000f 0x00000012 0x00000014 0x0000046e + 0x00000000 0x0000011b 0x00000002 0x00000002 + 0x00000005 0x00000000 0x00000001 0x0000000c + 0x00000042 0x00000042 0x00000003 0x00000005 + 0x00000003 0x0000000d 0x00000007 0x00000003 + 0x00000003 0x000007e0 0x00000000 0x00000000 + 0x00000000 0x1363a096 0x005800a0 0x00008000 + 0x00020000 0x00020000 0x00020000 0x00020000 + 0x00020000 0x00020000 0x00020000 0x00020000 + 0x00020000 0x00020000 0x00020000 0x00020000 + 0x00020000 0x00020000 0x00020000 0x00020000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00060000 0x00060000 0x00000000 0x00060000 + 0x00060000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00048000 0x00048000 + 0x00048000 0x00048000 0x00004800 0x00004800 + 0x00004800 0x00004800 0x00000200 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc000 + 0x00000404 0x81f1f008 0x07070000 0x0000003f + 0x015ddddd 0x51451420 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x0000006c 0x012c0011 0x00000000 0x00000004 + 0x000052a3 0x800009ed 0x0000000b >; + }; + + timing-396000000 { + clock-frequency = <396000000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000000>; + nvidia,emc-cfg = <0xd3300000>; + nvidia,emc-cfg-2 = <0x00000897>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x80010083>; + nvidia,emc-mode-2 = <0x80020004>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x018c0011>; + nvidia,emc-sel-dpd-ctrl = <0x0004001c>; + nvidia,emc-xm2dqspadctrl2 = <0x01231239>; + nvidia,emc-zcal-cnt-long = <0x00000028>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x00000017 0x00000053 0x00000000 0x00000010 + 0x00000007 0x00000008 0x00000008 0x00000003 + 0x0000000a 0x00000007 0x00000007 0x00000003 + 0x00000003 0x00000000 0x00000002 0x00000002 + 0x00000006 0x00000003 0x00000000 0x00000002 + 0x00000009 0x00030000 0x00000004 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000001 + 0x00000010 0x00000012 0x00000014 0x000005d9 + 0x00000000 0x00000176 0x00000002 0x00000002 + 0x00000007 0x00000000 0x00000001 0x0000000e + 0x00000058 0x00000058 0x00000003 0x00000006 + 0x00000003 0x00000012 0x00000009 0x00000003 + 0x00000003 0x00000a66 0x00000000 0x00000000 + 0x00000000 0x1363a096 0x005800a0 0x00008000 + 0x00020000 0x00020000 0x00020000 0x00020000 + 0x00020000 0x00020000 0x00020000 0x00020000 + 0x00020000 0x00020000 0x00020000 0x00020000 + 0x00020000 0x00020000 0x00020000 0x00020000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00048000 0x00048000 0x00000000 0x00048000 + 0x00048000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00038000 0x00038000 + 0x00038000 0x00038000 0x00003800 0x00003800 + 0x00003800 0x00003800 0x00000200 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc000 + 0x00000404 0x81f1f008 0x07070000 0x0000003f + 0x015ddddd 0x51451420 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x0000008f 0x018c0011 0x00000000 0x00000004 + 0x000052a3 0x80000cc7 0x0000000b >; + }; + + timing-528000000 { + clock-frequency = <528000000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000000>; + nvidia,emc-cfg = <0xd3300000>; + nvidia,emc-cfg-2 = <0x0000089f>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x800100c3>; + nvidia,emc-mode-2 = <0x80020006>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x02100013>; + nvidia,emc-sel-dpd-ctrl = <0x0004001c>; + nvidia,emc-xm2dqspadctrl2 = <0x0123123d>; + nvidia,emc-zcal-cnt-long = <0x00000034>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x0000001f 0x0000006e 0x00000000 0x00000016 + 0x00000009 0x00000009 0x00000009 0x00000003 + 0x0000000d 0x00000009 0x00000009 0x00000005 + 0x00000004 0x00000000 0x00000002 0x00000002 + 0x00000008 0x00000003 0x00000000 0x00000003 + 0x0000000a 0x00050000 0x00000004 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000002 + 0x00000011 0x00000015 0x00000017 0x000007cd + 0x00000000 0x000001f3 0x00000003 0x00000003 + 0x00000009 0x00000000 0x00000001 0x00000011 + 0x00000075 0x00000075 0x00000004 0x00000008 + 0x00000004 0x00000019 0x0000000c 0x00000003 + 0x00000003 0x00000ddd 0x00000000 0x00000000 + 0x00000000 0x1363a096 0xe01200b9 0x00008000 + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00004010 0x00004010 0x00000000 0x00004010 + 0x00004010 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x0000000c 0x0000000c + 0x0000000c 0x0000000c 0x0000000c 0x0000000c + 0x0000000c 0x0000000c 0x00000220 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc004 + 0x00000404 0x81f1f008 0x07070000 0x0000003f + 0x015ddddd 0x51451420 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x000000bf 0x02100013 0x00000000 0x00000004 + 0x000042a0 0x800010b3 0x0000000d >; + }; + + timing-600000000 { + clock-frequency = <600000000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000000>; + nvidia,emc-cfg = <0xd3300000>; + nvidia,emc-cfg-2 = <0x0000089f>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x800100e3>; + nvidia,emc-mode-2 = <0x80020007>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x02580014>; + nvidia,emc-sel-dpd-ctrl = <0x0004001c>; + nvidia,emc-xm2dqspadctrl2 = <0x0121103d>; + nvidia,emc-zcal-cnt-long = <0x0000003a>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x00000023 0x0000007d 0x00000000 0x00000019 + 0x0000000a 0x0000000a 0x0000000b 0x00000004 + 0x0000000f 0x0000000a 0x0000000a 0x00000005 + 0x00000004 0x00000000 0x00000004 0x00000004 + 0x0000000a 0x00000004 0x00000000 0x00000003 + 0x0000000d 0x00070000 0x00000005 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000002 + 0x00000014 0x00000018 0x0000001a 0x000008e4 + 0x00000000 0x00000239 0x00000004 0x00000004 + 0x0000000a 0x00000000 0x00000001 0x00000013 + 0x00000084 0x00000084 0x00000005 0x00000009 + 0x00000005 0x0000001c 0x0000000d 0x00000003 + 0x00000003 0x00000fc0 0x00000000 0x00000000 + 0x00000000 0x1363a096 0xe00e00b9 0x00008000 + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000010 0x00000010 0x00000000 0x00000010 + 0x00000010 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000001 + 0x00000000 0x00000001 0x00000001 0x00000000 + 0x00000001 0x00000000 0x00000000 0x00000001 + 0x00000000 0x00000001 0x00000001 0x00000000 + 0x00000001 0x00000000 0x0000000c 0x0000000b + 0x0000000b 0x0000000b 0x0000000b 0x0000000b + 0x0000000b 0x0000000b 0x00000220 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc004 + 0x00000404 0x81f1f008 0x07070000 0x0000003f + 0x015ddddd 0x51451420 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x000000d8 0x02580014 0x00000000 0x00000005 + 0x000040a0 0x800012d6 0x00000010 >; + }; + + timing-792000000 { + clock-frequency = <792000000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000000>; + nvidia,emc-cfg = <0xd3300000>; + nvidia,emc-cfg-2 = <0x0000089f>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x80010043>; + nvidia,emc-mode-2 = <0x8002001a>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x03180017>; + nvidia,emc-sel-dpd-ctrl = <0x0004001c>; + nvidia,emc-xm2dqspadctrl2 = <0x0120103d>; + nvidia,emc-zcal-cnt-long = <0x0000004c>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x0000002f 0x000000a6 0x00000000 0x00000021 + 0x0000000e 0x0000000d 0x0000000d 0x00000005 + 0x00000013 0x0000000e 0x0000000e 0x00000007 + 0x00000004 0x00000000 0x00000005 0x00000005 + 0x0000000e 0x00000004 0x00000000 0x00000005 + 0x0000000f 0x000b0000 0x00000006 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000004 + 0x00000016 0x0000001d 0x0000001f 0x00000bd1 + 0x00000000 0x000002f4 0x00000005 0x00000005 + 0x0000000e 0x00000000 0x00000001 0x00000017 + 0x000000af 0x000000af 0x00000006 0x0000000c + 0x00000006 0x00000026 0x00000011 0x00000003 + 0x00000003 0x000014cb 0x00000000 0x00000000 + 0x00000000 0x1363a096 0xe00700b9 0x00008000 + 0x00000006 0x00000006 0x00000006 0x00000006 + 0x00000006 0x00000006 0x00000006 0x00000006 + 0x00000006 0x00000006 0x00000006 0x00000006 + 0x00000006 0x00000006 0x00000006 0x00000006 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00008012 0x00008012 0x00000000 0x00008012 + 0x00008012 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000002 0x00000005 + 0x00000002 0x00000004 0x00000005 0x00000004 + 0x00000004 0x00000003 0x00000002 0x00000005 + 0x00000002 0x00000004 0x00000005 0x00000004 + 0x00000004 0x00000003 0x0000000b 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x0000000a 0x0000000a 0x00000220 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc004 + 0x00000808 0x81f1f008 0x07070000 0x00000000 + 0x015ddddd 0x61861820 0x00514514 0x00514514 + 0x61861800 0x0000003f 0x00000000 0x00000000 + 0x0000011e 0x03180017 0x00000000 0x00000006 + 0x00004080 0x8000188b 0x00000014 >; + }; + + timing-924000000 { + clock-frequency = <924000000>; + + nvidia,emc-auto-cal-config = <0xa1430000>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-bgbias-ctl0 = <0x00000000>; + nvidia,emc-cfg = <0xd3300000>; + nvidia,emc-cfg-2 = <0x0000089f>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mode-1 = <0x80010083>; + nvidia,emc-mode-2 = <0x8002001c>; + nvidia,emc-mode-4 = <0x800b0000>; + nvidia,emc-mode-reset = <0x00000000>; + nvidia,emc-mrs-wait-cnt = <0x039c0019>; + nvidia,emc-sel-dpd-ctrl = <0x0004001c>; + nvidia,emc-xm2dqspadctrl2 = <0x0120103d>; + nvidia,emc-zcal-cnt-long = <0x00000058>; + nvidia,emc-zcal-interval = <0x00064000>; + + nvidia,emc-configuration = < + 0x00000037 0x000000c2 0x00000000 0x00000026 + 0x00000010 0x0000000f 0x00000010 0x00000006 + 0x00000017 0x00000010 0x00000010 0x00000009 + 0x00000005 0x00000000 0x00000007 0x00000007 + 0x00000010 0x00000005 0x00000000 0x00000005 + 0x00000012 0x000d0000 0x00000007 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000004 + 0x00000019 0x00000020 0x00000022 0x00000dd4 + 0x00000000 0x00000375 0x00000006 0x00000006 + 0x00000010 0x00000000 0x00000001 0x0000001b + 0x000000cc 0x000000cc 0x00000007 0x0000000e + 0x00000007 0x0000002d 0x00000014 0x00000003 + 0x00000003 0x00001842 0x00000000 0x00000000 + 0x00000000 0x1363a896 0xe00400b9 0x00008000 + 0x00000004 0x00000004 0x00000004 0x00000004 + 0x00000004 0x00000004 0x00000004 0x00000004 + 0x00000004 0x00000004 0x00000004 0x00000004 + 0x00000004 0x00000004 0x00000004 0x00000004 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x0000000f 0x0000000f 0x00000000 0x00000011 + 0x00000012 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000004 0x00000006 + 0x00000004 0x00000006 0x00000006 0x00000006 + 0x00000006 0x00000005 0x00000004 0x00000006 + 0x00000004 0x00000006 0x00000006 0x00000006 + 0x00000006 0x00000005 0x0000000a 0x00000009 + 0x00000009 0x0000000a 0x00000009 0x00000009 + 0x00000009 0x00000009 0x00000220 0x00000000 + 0x00100100 0x00000000 0x00000000 0x77ffc004 + 0x00000404 0x81f1f008 0x07070000 0x00000000 + 0x015ddddd 0x51451420 0x00514514 0x00514514 + 0x51451400 0x0000003f 0x00000000 0x00000000 + 0x0000014d 0x039c0019 0x00000000 0x00000007 + 0x00004080 0x80001c77 0x00000017 >; + }; + }; + }; + + padctl@7009f000 { + status = "disabled"; + }; + + /* WiFi */ + sdmmc1: mmc@700b0000 { + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + assigned-clocks = <&tegra_car TEGRA124_CLK_SDMMC1>; + assigned-clock-parents = <&tegra_car TEGRA124_CLK_PLL_P>; + assigned-clock-rates = <204000000>; + + max-frequency = <82000000>; + keep-power-in-suspend; + bus-width = <4>; + non-removable; + + sd-uhs-sdr104; + mmc-ddr-1_8v; + + mmc-pwrseq = <&brcm_wifi_pwrseq>; + vmmc-supply = <&vdd_3v3_sys>; + vqmmc-supply = <&vdd_1v8_vio>; + + /* BCM4354XKUBG */ + wifi@1 { + compatible = "brcm,bcm4354-fmac", "brcm,bcm4329-fmac"; + reg = <1>; + + clocks = <&clk32k_pmic>; + clock-names = "lpo"; + + interrupt-parent = <&gpio>; + interrupts = ; + interrupt-names = "host-wake"; + }; + }; + + /* MicroSD */ + sdmmc3: mmc@700b0400 { + status = "okay"; + bus-width = <4>; + + sd-uhs-sdr104; + mmc-ddr-1_8v; + + cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>; + + vmmc-supply = <&vdd_hv_sdmmc>; + vqmmc-supply = <&vddio_usd>; + }; + + /* eMMC */ + sdmmc4: mmc@700b0600 { + status = "okay"; + bus-width = <8>; + + mmc-hs200-1_8v; + non-removable; + + vmmc-supply = <&vdd_hv_sdmmc>; + vqmmc-supply = <&vdd_1v8_vio>; + }; + + /* CPU DFLL clock */ + clock@70110000 { + status = "okay"; + vdd-cpu-supply = <&vdd_cpu>; + nvidia,i2c-fs-rate = <400000>; + }; + + ahub@70300000 { + /* HIFI CODEC */ + i2s@70301000 { /* i2s0 */ + status = "okay"; + }; + + /* LEFT SPK */ + i2s@70301100 { /* i2s1 */ + status = "okay"; + }; + + /* RIGHT SPK */ + i2s@70301200 { /* i2s2 */ + status = "okay"; + }; + + /* BT SCO */ + i2s@70301300 { /* i2s3 */ + status = "okay"; + }; + }; + + usb1: usb@7d000000 { + compatible = "nvidia,tegra124-udc"; + status = "okay"; + dr_mode = "otg"; + + hnp-disable; + srp-disable; + adp-disable; + + usb-role-switch; + extcon = <&bq24192>, <&palmas_extcon>; /* vbus, id */ + vbus-supply = <&usb_otg_vbus>; + + port { + usb_in: endpoint { + remote-endpoint = <&connector_out>; + }; + }; + }; + + usb-phy@7d000000 { + status = "okay"; + dr_mode = "otg"; + nvidia,xcvr-lsfslew = <2>; + nvidia,xcvr-lsrslew = <2>; + vbus-supply = <&avdd_usb>; + }; + + battery: battery-cell { + compatible = "simple-battery"; + device-chemistry = "lithium-ion-polymer"; + + charge-full-design-microamp-hours = <6520000>; + energy-full-design-microwatt-hours = <2478000>; + + voltage-min-design-microvolt = <4300000>; + voltage-max-design-microvolt = <4350000>; + + precharge-current-microamp = <256000>; + charge-term-current-microamp = <400000>; + + operating-range-celsius = <0 45>; + }; + + clk32k_in: clock-32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "ref-oscillator"; + }; + + connector { + compatible = "usb-b-connector"; + type = "micro"; + + port { + connector_out: endpoint { + remote-endpoint = <&usb_in>; + }; + }; + }; + + cpus { + cpu0: cpu@0 { + vdd-cpu-supply = <&vdd_cpu>; + #cooling-cells = <2>; + }; + + cpu1: cpu@1 { + #cooling-cells = <2>; + }; + + cpu2: cpu@2 { + #cooling-cells = <2>; + }; + + cpu3: cpu@3 { + #cooling-cells = <2>; + }; + }; + + extcon-keys { + compatible = "gpio-keys"; + + switch-back-hall-sensor { + label = "Hall sensor (back)"; + gpios = <&gpio TEGRA_GPIO(W, 3) GPIO_ACTIVE_LOW>; + linux,code = ; + linux,can-disable; + wakeup-source; + }; + + switch-front-hall-sensor { + label = "Hall sensor (front)"; + gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + linux,code = ; + linux,can-disable; + wakeup-source; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + key-power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <10>; + wakeup-source; + }; + + key-volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(Q, 7) GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <10>; + }; + + key-volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(Q, 6) GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <10>; + }; + }; + + led-controller { + compatible = "pwm-leds"; + + led-button { + color = ; + function = LED_FUNCTION_BACKLIGHT; + + pwms = <&pwm 1 10000>; + max-brightness = <100>; + }; + }; + + brcm_wifi_pwrseq: pwrseq-wifi { + compatible = "mmc-pwrseq-simple"; + + reset-gpios = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_LOW>; + + post-power-on-delay-ms = <300>; + power-off-delay-us = <300>; + }; + + vdd_3v3_sys: regulator-3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vdd_3v3_sys"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + vddio_1v8_bl: regulator-bl-io { + compatible = "regulator-fixed"; + regulator-name = "vddio_1v8_bl"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(BB, 4) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_1v8_vio>; + }; + + vdd_lcd_io: regulator-lcd-vio { + compatible = "regulator-fixed"; + regulator-name = "dvdd_lcd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + gpio = <&palmas_gpio 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_1v8_vio>; + }; + + vsp_5v5_lcd: regulator-vsp { + compatible = "regulator-fixed"; + regulator-name = "avdd_lcd_vsp"; + regulator-min-microvolt = <5500000>; + regulator-max-microvolt = <5500000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(I, 4) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_3v3_sys>; + }; + + vsn_5v5_lcd: regulator-vsn { + compatible = "regulator-fixed"; + regulator-name = "avdd_lcd_vsn"; + regulator-min-microvolt = <5500000>; + regulator-max-microvolt = <5500000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(S, 2) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_3v3_sys>; + }; + + vdd_2v8_tp: regulator-vtp { + compatible = "regulator-fixed"; + regulator-name = "vdd_2v8_tp"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_smps10_out2>; + }; + + iovdd_1v8_cam: regulator-iovdd-cam { + compatible = "regulator-fixed"; + regulator-name = "iovdd_1v8_cam"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&palmas_gpio 1 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_1v8_vio>; + }; + + dvdd_1v2_cam: regulator-dvdd-cam { + compatible = "regulator-fixed"; + regulator-name = "dvdd_1v2_cam"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + gpio = <&palmas_gpio 2 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_1v8_vio>; + }; + + vdd_3v3_hph: regulator-hph { + compatible = "regulator-fixed"; + regulator-name = "vdd_3v3_hph"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_3v3_sys>; + }; + + thermal-zones { + /* + * TMP451 has two sensors: + * + * 0: internal that monitors ambient/skin temperature + * 1: external that is connected to the CPU's diode + * + * Ideally we should use userspace thermal governor, + * but it's a much more complex solution. The "skin" + * zone exists as a simpler solution which prevents + * tablet from getting too hot from a user's tactile + * perspective. The CPU zone is intended to protect + * silicon from damage. + */ + + tmp451-skin-thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <10000>; /* milliseconds */ + + thermal-sensors = <&temp_sensor 0>; + + trips { + skip_alert_trip: skin-alert { + /* throttle at 50C until temperature drops to 49.5C */ + temperature = <50000>; + hysteresis = <500>; + type = "passive"; + }; + + skin-crit { + /* shut down at 85C */ + temperature = <85000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map-skip { + trip = <&skip_alert_trip>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + tmp451-cpu-thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <10000>; /* milliseconds */ + + thermal-sensors = <&temp_sensor 1>; + + trips { + cpu_alert_trip: cpu-alert { + /* throttle at 85C until temperature drops to 84.5C */ + temperature = <85000>; + hysteresis = <500>; + type = "passive"; + }; + + cpu-crit { + /* shut down at 95C */ + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map-cpu { + trip = <&cpu_alert_trip>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/nvidia/tegra124.dtsi b/arch/arm/boot/dts/nvidia/tegra124.dtsi index ec4f0e346b2bf..ce4efa1de509b 100644 --- a/arch/arm/boot/dts/nvidia/tegra124.dtsi +++ b/arch/arm/boot/dts/nvidia/tegra124.dtsi @@ -103,6 +103,45 @@ ranges = <0 0x54000000 0 0x54000000 0 0x01000000>; + vi@54080000 { + compatible = "nvidia,tegra124-vi"; + reg = <0x0 0x54080000 0x0 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_VI>; + resets = <&tegra_car 20>; + reset-names = "vi"; + + iommus = <&mc TEGRA_SWGROUP_VI>; + + status = "disabled"; + }; + + isp@54600000 { + compatible = "nvidia,tegra124-isp"; + reg = <0x0 0x54600000 0x0 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_ISP>; + resets = <&tegra_car TEGRA124_CLK_ISP>; + reset-names = "isp"; + + iommus = <&mc TEGRA_SWGROUP_ISP2>; + + status = "disabled"; + }; + + isp@54680000 { + compatible = "nvidia,tegra124-isp"; + reg = <0x0 0x54680000 0x0 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_ISPB>; + resets = <&tegra_car TEGRA124_CLK_ISPB>; + reset-names = "isp"; + + iommus = <&mc TEGRA_SWGROUP_ISP2B>; + + status = "disabled"; + }; + dc@54200000 { compatible = "nvidia,tegra124-dc"; reg = <0x0 0x54200000 0x0 0x00040000>; @@ -209,6 +248,31 @@ #size-cells = <0>; }; + msenc@544c0000 { + compatible = "nvidia,tegra124-msenc"; + reg = <0x0 0x544c0000 0x0 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_MSENC>; + resets = <&tegra_car TEGRA124_CLK_MSENC>; + reset-names = "mpe"; + + iommus = <&mc TEGRA_SWGROUP_MSENC>; + + status = "disabled"; + }; + + tsec@54500000 { + compatible = "nvidia,tegra124-tsec"; + reg = <0x0 0x54500000 0x0 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_TSEC>; + resets = <&tegra_car TEGRA124_CLK_TSEC>; + + iommus = <&mc TEGRA_SWGROUP_TSEC>; + + status = "disabled"; + }; + sor@54540000 { compatible = "nvidia,tegra124-sor"; reg = <0x0 0x54540000 0x0 0x00040000>; diff --git a/arch/arm/boot/dts/nvidia/tegra20.dtsi b/arch/arm/boot/dts/nvidia/tegra20.dtsi index 882adb7f2f263..c60fc1971188c 100644 --- a/arch/arm/boot/dts/nvidia/tegra20.dtsi +++ b/arch/arm/boot/dts/nvidia/tegra20.dtsi @@ -64,7 +64,7 @@ vi@54080000 { compatible = "nvidia,tegra20-vi"; - reg = <0x54080000 0x00040000>; + reg = <0x54080000 0x00000800>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_VI>; resets = <&tegra_car 20>; @@ -72,6 +72,23 @@ power-domains = <&pd_venc>; operating-points-v2 = <&vi_dvfs_opp_table>; status = "disabled"; + + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0x0 0x54080000 0x4000>; + + csi: csi@800 { + compatible = "nvidia,tegra20-csi"; + reg = <0x800 0x200>; + clocks = <&tegra_car TEGRA20_CLK_CSI>; + power-domains = <&pd_venc>; + #nvidia,mipi-calibrate-cells = <1>; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + }; }; epp@540c0000 { diff --git a/arch/arm/boot/dts/nvidia/tegra30.dtsi b/arch/arm/boot/dts/nvidia/tegra30.dtsi index 2a4d93db81347..4c4e6097c9163 100644 --- a/arch/arm/boot/dts/nvidia/tegra30.dtsi +++ b/arch/arm/boot/dts/nvidia/tegra30.dtsi @@ -150,8 +150,8 @@ }; vi@54080000 { - compatible = "nvidia,tegra30-vi"; - reg = <0x54080000 0x00040000>; + compatible = "nvidia,tegra30-vi", "nvidia,tegra20-vi"; + reg = <0x54080000 0x00000800>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_VI>; resets = <&tegra_car 20>; @@ -162,6 +162,26 @@ iommus = <&mc TEGRA_SWGROUP_VI>; status = "disabled"; + + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0x0 0x54080000 0x4000>; + + csi: csi@800 { + compatible = "nvidia,tegra30-csi"; + reg = <0x800 0x200>; + clocks = <&tegra_car TEGRA30_CLK_CSI>, + <&tegra_car TEGRA30_CLK_CSIA_PAD>, + <&tegra_car TEGRA30_CLK_CSIB_PAD>; + clock-names = "csi", "csia-pad", "csib-pad"; + power-domains = <&pd_venc>; + #nvidia,mipi-calibrate-cells = <1>; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + }; }; epp@540c0000 { diff --git a/arch/arm/boot/dts/nxp/imx/e70k02.dtsi b/arch/arm/boot/dts/nxp/imx/e70k02.dtsi index dcc3c9d488a88..3bb11c5a63536 100644 --- a/arch/arm/boot/dts/nxp/imx/e70k02.dtsi +++ b/arch/arm/boot/dts/nxp/imx/e70k02.dtsi @@ -69,6 +69,14 @@ reg = <0x80000000 0x20000000>; }; + epd_pmic_supply: regulator-epd-pmic-in { + compatible = "regulator-fixed"; + regulator-name = "epd_pmic_supply"; + gpio = <&gpio2 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + startup-delay-us = <20000>; + }; + reg_wifi: regulator-wifi { compatible = "regulator-fixed"; regulator-name = "SD3_SPWR"; @@ -133,7 +141,22 @@ vdd-supply = <&ldo5_reg>; }; - /* TODO: SY7636 PMIC for E Ink at 0x62 */ + sy7636: pmic@62 { + compatible = "silergy,sy7636a"; + reg = <0x62>; + enable-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; + vcom-en-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>; + epd-pwr-good-gpios = <&gpio2 13 GPIO_ACTIVE_HIGH>; + vin-supply = <&epd_pmic_supply>; + + #thermal-sensor-cells = <0>; + + regulators { + reg_epdpmic: vcom { + regulator-name = "vcom"; + }; + }; + }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx53-ppd.dts b/arch/arm/boot/dts/nxp/imx/imx53-ppd.dts index 2892e457fea7e..e45a97d3f449d 100644 --- a/arch/arm/boot/dts/nxp/imx/imx53-ppd.dts +++ b/arch/arm/boot/dts/nxp/imx/imx53-ppd.dts @@ -537,6 +537,8 @@ mpl3115: pressure-sensor@60 { compatible = "fsl,mpl3115"; reg = <0x60>; + vdd-supply = <®_3v3>; + vddio-supply = <®_3v3>; }; eeprom: eeprom@50 { diff --git a/arch/arm/boot/dts/nxp/imx/imx53-qsrb.dts b/arch/arm/boot/dts/nxp/imx/imx53-qsrb.dts index 2f06ad61a7665..6938ad6dbc2ce 100644 --- a/arch/arm/boot/dts/nxp/imx/imx53-qsrb.dts +++ b/arch/arm/boot/dts/nxp/imx/imx53-qsrb.dts @@ -28,6 +28,7 @@ reg = <0x08>; interrupt-parent = <&gpio5>; interrupts = <23 IRQ_TYPE_LEVEL_HIGH>; + fsl,mc13xxx-uses-rtc; regulators { sw1_reg: sw1a { regulator-name = "SW1"; diff --git a/arch/arm/boot/dts/nxp/imx/imx53-usbarmory.dts b/arch/arm/boot/dts/nxp/imx/imx53-usbarmory.dts index acc44010d5106..3ad9db4b14425 100644 --- a/arch/arm/boot/dts/nxp/imx/imx53-usbarmory.dts +++ b/arch/arm/boot/dts/nxp/imx/imx53-usbarmory.dts @@ -1,47 +1,10 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) /* * USB armory MkI device tree file * https://inversepath.com/usbarmory * * Copyright (C) 2015, Inverse Path * Andrej Rosano - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file 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. - * - * This file 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. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ /dts-v1/; diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos2_7.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos2_7.dts index a7400d42475b4..bf8e07f971435 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos2_7.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos2_7.dts @@ -20,6 +20,7 @@ panel: panel { compatible = "lg,lb070wv8"; backlight = <&backlight>; + power-supply = <®_3p3v>; enable-gpios = <&gpio6 15 GPIO_ACTIVE_HIGH>; port { diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-b1x5v2.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-b1x5v2.dtsi index 590dcc0953cc7..5dc7f1f9ca178 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-b1x5v2.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-b1x5v2.dtsi @@ -47,7 +47,8 @@ mpl3115a2: pressure-sensor@60 { compatible = "fsl,mpl3115"; reg = <0x60>; - + vdd-supply = <®_3v3>; + vddio-supply = <®_3v3>; /* * The MPL3115 interrupts are connected to pin 22 and 23 * of &tca6424a, but the binding does not yet support diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-lanmcu.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-lanmcu.dts index 7c62db91173b7..47a6d63c8e04c 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-lanmcu.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-lanmcu.dts @@ -72,6 +72,7 @@ panel { compatible = "edt,etm0700g0bdh6"; backlight = <&backlight>; + power-supply = <®_panel>; port { panel_in: endpoint { @@ -89,6 +90,13 @@ enable-active-high; }; + reg_panel: regulator-panel { + compatible = "regulator-fixed"; + regulator-name = "panel"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + usdhc2_wifi_pwrseq: usdhc2-wifi-pwrseq { compatible = "mmc-pwrseq-simple"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-plym2m.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-plym2m.dts index dfa8110b1d97b..0ef24a07dedf9 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-plym2m.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-plym2m.dts @@ -123,7 +123,7 @@ }; }; - touch-thermal0 { + touch-0-thermal { polling-delay = <20000>; polling-delay-passive = <0>; thermal-sensors = <&touch_temp0>; @@ -137,7 +137,7 @@ }; }; - touch-thermal1 { + touch-1-thermal { polling-delay = <20000>; polling-delay-passive = <0>; thermal-sensors = <&touch_temp1>; diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-prtvt7.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-prtvt7.dts index 29dc6875ab668..353f7097cb7e0 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-prtvt7.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-prtvt7.dts @@ -55,7 +55,7 @@ iio-hwmon { compatible = "iio-hwmon"; - io-channels = <&vdiv_vaccu>; + io-channels = <&vdiv_vaccu 0>; }; keys { @@ -256,7 +256,7 @@ }; }; - touch-thermal0 { + touch-0-thermal { polling-delay = <20000>; polling-delay-passive = <0>; thermal-sensors = <&touch_temp0>; @@ -270,7 +270,7 @@ }; }; - touch-thermal1 { + touch-1-thermal { polling-delay = <20000>; polling-delay-passive = <0>; thermal-sensors = <&touch_temp1>; @@ -318,7 +318,7 @@ io-channels = <&adc_ts 2>; output-ohms = <2500>; full-ohms = <64000>; - #io-channel-cells = <0>; + #io-channel-cells = <1>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-qmx6.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-qmx6.dtsi index 7a3b96315eaf5..d5baec5e7a782 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-qmx6.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-qmx6.dtsi @@ -14,6 +14,7 @@ / { memory@10000000 { reg = <0x10000000 0x40000000>; + device_type = "memory"; }; reg_3p3v: 3p3v { diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-victgo.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-victgo.dts index 4875afadb6300..76b0007d20ad2 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-victgo.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-victgo.dts @@ -35,7 +35,7 @@ iio-hwmon { compatible = "iio-hwmon"; - io-channels = <&vdiv_vaccu>, <&vdiv_hitch_pos>; + io-channels = <&vdiv_vaccu 0>, <&vdiv_hitch_pos 0>; }; panel { @@ -84,7 +84,7 @@ }; }; - touch-thermal0 { + touch-0-thermal { polling-delay = <20000>; polling-delay-passive = <0>; thermal-sensors = <&touch_temp0>; @@ -98,7 +98,7 @@ }; }; - touch-thermal1 { + touch-1-thermal { polling-delay = <20000>; polling-delay-passive = <0>; thermal-sensors = <&touch_temp1>; @@ -147,7 +147,7 @@ io-channels = <&adc_ts 2>; output-ohms = <2500>; full-ohms = <64000>; - #io-channel-cells = <0>; + #io-channel-cells = <1>; }; vdiv_hitch_pos: voltage-divider-hitch-pos { @@ -155,7 +155,7 @@ io-channels = <&adc_ts 6>; output-ohms = <3300>; full-ohms = <13300>; - #io-channel-cells = <0>; + #io-channel-cells = <1>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi index 8bc6376d0dc10..4a5736526927c 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi @@ -279,28 +279,32 @@ #size-cells = <0>; status = "disabled"; - led@0 { - chan-name = "R"; - led-cur = /bits/ 8 <0x20>; - max-cur = /bits/ 8 <0x60>; - reg = <0>; - color = ; - }; + multi-led@0 { + #address-cells = <1>; + #size-cells = <0>; + color = ; + function = LED_FUNCTION_INDICATOR; + + led@0 { + led-cur = /bits/ 8 <0x20>; + max-cur = /bits/ 8 <0x60>; + reg = <0>; + color = ; + }; - led@1 { - chan-name = "G"; - led-cur = /bits/ 8 <0x20>; - max-cur = /bits/ 8 <0x60>; - reg = <1>; - color = ; - }; + led@1 { + led-cur = /bits/ 8 <0x20>; + max-cur = /bits/ 8 <0x60>; + reg = <1>; + color = ; + }; - led@2 { - chan-name = "B"; - led-cur = /bits/ 8 <0x20>; - max-cur = /bits/ 8 <0x60>; - reg = <2>; - color = ; + led@2 { + led-cur = /bits/ 8 <0x20>; + max-cur = /bits/ 8 <0x60>; + reg = <2>; + color = ; + }; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-lynx.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-lynx.dts index 5c2cd517589bf..0a6b668428a34 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-lynx.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-lynx.dts @@ -21,6 +21,10 @@ status = "okay"; }; +&beeper { + status = "okay"; +}; + &lcd_display { status = "okay"; }; @@ -37,6 +41,10 @@ status = "okay"; }; +&pwm3 { + status = "okay"; +}; + ®_usb_h1_vbus { status = "okay"; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp43-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp43-common.dtsi index 2f42c56c21f63..6e49e1ccf6fc3 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp43-common.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp43-common.dtsi @@ -26,6 +26,12 @@ status = "disabled"; }; + beeper: beeper { + compatible = "pwm-beeper"; + pwms = <&pwm3 0 500000 0>; + status = "disabled"; + }; + gpio_keys: gpio-keys { compatible = "gpio-keys"; pinctrl-names = "default"; @@ -272,28 +278,32 @@ #size-cells = <0>; status = "disabled"; - led@0 { - chan-name = "R"; - led-cur = /bits/ 8 <0x6e>; - max-cur = /bits/ 8 <0xc8>; - reg = <0>; - color = ; - }; + multi-led@0 { + #address-cells = <1>; + #size-cells = <0>; + color = ; + function = LED_FUNCTION_INDICATOR; + + led@0 { + led-cur = /bits/ 8 <0x6e>; + max-cur = /bits/ 8 <0xc8>; + reg = <0>; + color = ; + }; - led@1 { - chan-name = "G"; - led-cur = /bits/ 8 <0xbe>; - max-cur = /bits/ 8 <0xc8>; - reg = <1>; - color = ; - }; + led@1 { + led-cur = /bits/ 8 <0xbe>; + max-cur = /bits/ 8 <0xc8>; + reg = <1>; + color = ; + }; - led@2 { - chan-name = "B"; - led-cur = /bits/ 8 <0xbe>; - max-cur = /bits/ 8 <0xc8>; - reg = <2>; - color = ; + led@2 { + led-cur = /bits/ 8 <0xbe>; + max-cur = /bits/ 8 <0xc8>; + reg = <2>; + color = ; + }; }; }; @@ -466,6 +476,13 @@ >; }; + pinctrl_sound: soundgrp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x1b0b0 + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x8 + >; + }; + pinctrl_touch: touchgrp { fsl,pins = < MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b098 @@ -551,6 +568,12 @@ status = "disabled"; }; +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sound>; + status = "disabled"; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts b/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts index d3f14b4d3b51e..929def2bb35eb 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts @@ -46,6 +46,7 @@ panel { compatible = "dataimage,fg1001l0dsswmg01"; backlight = <&backlight_lvds>; + power-supply = <®_lcd>; port { panel_in: endpoint { diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi index e1d0c6e123fd7..1e2266a2368be 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi @@ -195,6 +195,8 @@ mma8453: mma8453@1c { compatible = "fsl,mma8453"; reg = <0x1c>; + vdd-supply = <®_3p3v>; + vddio-supply = <®_3p3v>; }; }; @@ -211,6 +213,8 @@ mpl3115: mpl3115@60 { compatible = "fsl,mpl3115"; reg = <0x60>; + vdd-supply = <®_3p3v>; + vddio-supply = <®_3p3v>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-cm-fx6.dts b/arch/arm/boot/dts/nxp/imx/imx6q-cm-fx6.dts index 299106fbe51c4..13245af8f74d4 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-cm-fx6.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-cm-fx6.dts @@ -73,7 +73,7 @@ reset-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>; }; - reg_pcie_power_on_gpio: regulator-pcie-power-on-gpio { + reg_pcie_power_on_gpio: regulator-pcie-power-on { compatible = "regulator-fixed"; regulator-name = "regulator-pcie-power-on-gpio"; regulator-min-microvolt = <3300000>; @@ -99,6 +99,34 @@ enable-active-high; }; + avdd_reg: regulator-avdd { + compatible = "regulator-fixed"; + regulator-name = "avdd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + hpvdd_reg: regulator-hpvdd { + compatible = "regulator-fixed"; + regulator-name = "hpvdd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + dcvdd_reg: regulator-dcvdd { + compatible = "regulator-fixed"; + regulator-name = "dcvdd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + dbvdd_reg: regulator-dbvdd { + compatible = "regulator-fixed"; + regulator-name = "dbvdd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + sound-analog { compatible = "simple-audio-card"; simple-audio-card,name = "On-board analog audio"; @@ -307,6 +335,10 @@ #sound-dai-cells = <0>; compatible = "wlf,wm8731"; reg = <0x1a>; + AVDD-supply = <&avdd_reg>; + HPVDD-supply = <&hpvdd_reg>; + DCVDD-supply = <&dcvdd_reg>; + DBVDD-supply = <&dbvdd_reg>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/nxp/imx/imx6q-dmo-edmqmx6.dts index 17fabff80e903..cbe580dec182e 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-dmo-edmqmx6.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-dmo-edmqmx6.dts @@ -236,9 +236,12 @@ vcc-supply = <&sw2_reg>; vio-supply = <&sw2_reg>; - stmpe_gpio1: stmpe_gpio { + stmpe_gpio1: gpio { #gpio-cells = <2>; compatible = "st,stmpe-gpio"; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; }; }; @@ -250,9 +253,12 @@ vcc-supply = <&sw2_reg>; vio-supply = <&sw2_reg>; - stmpe_gpio2: stmpe_gpio { + stmpe_gpio2: gpio { #gpio-cells = <2>; compatible = "st,stmpe-gpio"; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-evi.dts b/arch/arm/boot/dts/nxp/imx/imx6q-evi.dts index 78d941fef5dfb..c936180ed32a8 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-evi.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-evi.dts @@ -55,6 +55,13 @@ reg = <0x10000000 0x40000000>; }; + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + reg_usbh1_vbus: regulator-usbhubreset { compatible = "regulator-fixed"; regulator-name = "usbh1_vbus"; @@ -81,6 +88,7 @@ panel { compatible = "sharp,lq101k1ly04"; + power-supply = <®_3v3>; port { panel_in: endpoint { @@ -124,7 +132,7 @@ pinctrl-0 = <&pinctrl_ecspi5 &pinctrl_ecspi5cs>; status = "okay"; - eeprom: m95m02@1 { + eeprom: eeprom@1 { compatible = "st,m95m02", "atmel,at25"; size = <262144>; pagesize = <256>; @@ -134,7 +142,7 @@ }; pb_rtc: rtc@3 { - compatible = "nxp,rtc-pcf2123"; + compatible = "nxp,pcf2123"; spi-max-frequency = <2450000>; spi-cs-high; reg = <3>; diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-icore-ofcap10.dts b/arch/arm/boot/dts/nxp/imx/imx6q-icore-ofcap10.dts index 02aca1e28ce3f..1ad3bdcea4a34 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-icore-ofcap10.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-icore-ofcap10.dts @@ -16,6 +16,7 @@ panel { compatible = "ampire,am-1280800n3tzqw-t00h"; backlight = <&backlight_lvds>; + power-supply = <®_3p3v>; port { panel_in: endpoint { diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-icore-ofcap12.dts b/arch/arm/boot/dts/nxp/imx/imx6q-icore-ofcap12.dts index 241811c52b624..9e1c64da0b30a 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-icore-ofcap12.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-icore-ofcap12.dts @@ -16,6 +16,7 @@ panel { compatible = "koe,tx31d200vm0baa"; backlight = <&backlight_lvds>; + power-supply = <®_3p3v>; port { panel_in: endpoint { diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts b/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts index 56b77cc0af2be..b8567167779cb 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts @@ -145,6 +145,7 @@ panel { compatible = "hannstar,hsd100pxn1"; backlight = <&backlight_lvds>; + power-supply = <®_3p3v>; port { panel_in: endpoint { @@ -324,8 +325,6 @@ }; &iomuxc { - pinctrl-names = "default"; - pinctrl_hog: hoggrp { fsl,pins = < MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /*pcie power*/ diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts b/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts index fb81bd8ba0351..73ed40ae5a7bc 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts @@ -57,6 +57,7 @@ panel { compatible = "kyo,tcg121xglp"; backlight = <&backlight_lcd>; + power-supply = <®_3v3>; port { panel_in: endpoint { @@ -72,6 +73,13 @@ regulator-max-microvolt = <1800000>; }; + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + reg_wifi: regulator-wifi { compatible = "regulator-fixed"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts b/arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts index 5353a0c244205..3bd0e2c9e57ac 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts @@ -37,7 +37,7 @@ 3000 1>; }; - ir_recv { + ir-receiver { compatible = "gpio-ir-receiver"; gpios = <&gpio3 18 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-utilite-pro.dts b/arch/arm/boot/dts/nxp/imx/imx6q-utilite-pro.dts index aae81feee00db..c78f101c3cc12 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-utilite-pro.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-utilite-pro.dts @@ -326,11 +326,14 @@ &pcie { pcie@0,0 { reg = <0x000000 0 0 0 0>; + device_type = "pci"; #address-cells = <3>; #size-cells = <2>; + bus-range = <0x00 0xff>; + ranges; /* non-removable i211 ethernet card */ - eth1: intel,i211@pcie0,0 { + eth1: ethernet@0,0 { reg = <0x010000 0 0 0 0>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-var-mx6customboard.dts b/arch/arm/boot/dts/nxp/imx/imx6q-var-mx6customboard.dts index 18a620832a2ad..a55644529c67f 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-var-mx6customboard.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-var-mx6customboard.dts @@ -8,6 +8,7 @@ /dts-v1/; +#include "imx6q.dtsi" #include "imx6qdl-var-som.dtsi" #include diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-yapp4-pegasus.dts b/arch/arm/boot/dts/nxp/imx/imx6q-yapp4-pegasus.dts index ec6651ba4ba2e..7332f27189826 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-yapp4-pegasus.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-yapp4-pegasus.dts @@ -17,6 +17,10 @@ }; }; +&beeper { + status = "okay"; +}; + &gpio_oled { status = "okay"; }; @@ -37,6 +41,10 @@ status = "okay"; }; +&pwm3 { + status = "okay"; +}; + ®_pu { regulator-always-on; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi index 419d85b5a6606..8a0ce250e5760 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi @@ -589,7 +589,7 @@ st,touch-det-delay = <5>; }; - stmpe_adc: stmpe_adc { + stmpe_adc: adc { compatible = "st,stmpe-adc"; /* forbid to use ADC channels 3-0 (touch) */ st,norequest-mask = <0x0F>; diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi index ea92b2b5c50d9..e9d5bbb43145f 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi @@ -462,7 +462,6 @@ regulator-ramp-delay = <7000>; regulator-boot-on; regulator-always-on; - linux,phandle = <®_vdd_arm>; }; /* VDD_1P8 (1+R1/R2 = 2.505): GPS/VideoIn/ENET-PHY */ diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5903.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5903.dtsi index b518bcb6b7a99..01f77142e153b 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5903.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw5903.dtsi @@ -360,7 +360,6 @@ regulator-ramp-delay = <7000>; regulator-boot-on; regulator-always-on; - linux,phandle = <®_vdd_arm>; }; /* VDD_SOC (1+R1/R2 = 1.635) */ @@ -372,7 +371,6 @@ regulator-ramp-delay = <7000>; regulator-boot-on; regulator-always-on; - linux,phandle = <®_vdd_soc>; }; /* VDD_1P0 (1+R1/R2 = 1.38): */ diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-nit6xlite.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-nit6xlite.dtsi index 8d471450d5c5c..610b2a72fe825 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-nit6xlite.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-nit6xlite.dtsi @@ -127,6 +127,7 @@ panel-lvds0 { compatible = "hannstar,hsd100pxn1"; backlight = <&backlight_lvds0>; + power-supply = <®_3p3v>; port { panel_in_lvds0: endpoint { diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi index c727aac257f9c..ef0c26688446e 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi @@ -135,13 +135,13 @@ i2c-parent = <&i2c2>; idle-state = <0>; - i2c2mux@1 { + i2c@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; }; - i2c2mux@2 { + i2c@2 { reg = <2>; #address-cells = <1>; #size-cells = <0>; @@ -158,7 +158,7 @@ i2c-parent = <&i2c3>; idle-state = <0>; - i2c3mux@1 { + i2c@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; @@ -237,6 +237,7 @@ panel-lcd { compatible = "okaya,rs800480t-7x0gp"; backlight = <&backlight_lcd>; + power-supply = <®_3p3v>; port { lcd_panel_in: endpoint { @@ -248,6 +249,7 @@ panel-lvds0 { compatible = "hannstar,hsd100pxn1"; backlight = <&backlight_lvds0>; + power-supply = <®_3p3v>; port { panel_in_lvds0: endpoint { @@ -259,6 +261,7 @@ panel-lvds1 { compatible = "hannstar,hsd100pxn1"; backlight = <&backlight_lvds1>; + power-supply = <®_3p3v>; port { panel_in_lvds1: endpoint { diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_som2.dtsi index 806af7f60419e..03fe053880ca6 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_som2.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_som2.dtsi @@ -114,6 +114,7 @@ panel-lcd { compatible = "okaya,rs800480t-7x0gp"; backlight = <&backlight_lcd>; + power-supply = <®_3p3v>; port { lcd_panel_in: endpoint { @@ -125,6 +126,7 @@ panel-lvds0 { compatible = "hannstar,hsd100pxn1"; backlight = <&backlight_lvds0>; + power-supply = <®_3p3v>; port { panel_in_lvds0: endpoint { @@ -136,6 +138,7 @@ panel-lvds1 { compatible = "hannstar,hsd100pxn1"; backlight = <&backlight_lvds1>; + power-supply = <®_3p3v>; port { panel_in_lvds1: endpoint { diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6x.dtsi index c71aa7498acf4..6a353a99e13da 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6x.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6x.dtsi @@ -179,6 +179,7 @@ panel-lcd { compatible = "okaya,rs800480t-7x0gp"; backlight = <&backlight_lcd>; + power-supply = <®_3p3v>; port { lcd_panel_in: endpoint { @@ -190,6 +191,7 @@ panel-lvds0 { compatible = "hannstar,hsd100pxn1"; backlight = <&backlight_lvds>; + power-supply = <®_3p3v>; port { panel_in: endpoint { diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabrelite.dtsi index f7abc17c7c93a..3b7d01065e87b 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabrelite.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabrelite.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include / { chosen { @@ -207,6 +208,7 @@ panel-lcd { compatible = "okaya,rs800480t-7x0gp"; backlight = <&backlight_lcd>; + power-supply = <®_3p3v>; port { lcd_panel_in: endpoint { @@ -218,6 +220,7 @@ panel-lvds0 { compatible = "hannstar,hsd100pxn1"; backlight = <&backlight_lvds>; + power-supply = <®_3p3v>; port { panel_in: endpoint { @@ -360,7 +363,6 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ov5642>; clocks = <&clks IMX6QDL_CLK_CKO2>; - clock-names = "xclk"; reg = <0x42>; reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; powerdown-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; @@ -370,6 +372,7 @@ port { ov5642_to_ipu1_csi0_mux: endpoint { remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; + bus-type = ; bus-width = <8>; hsync-active = <1>; vsync-active = <1>; diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi index e8368c6b27ef3..ba29720e3f720 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include / { chosen { @@ -17,6 +18,13 @@ reg = <0x10000000 0x40000000>; }; + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "reg-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + reg_usb_otg_vbus: regulator-usb-otg-vbus { compatible = "regulator-fixed"; regulator-name = "usb_otg_vbus"; @@ -139,6 +147,7 @@ panel { compatible = "hannstar,hsd100pxn1"; backlight = <&backlight_lvds>; + power-supply = <®_3v3>; port { panel_in: endpoint { @@ -278,7 +287,6 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ov5642>; clocks = <&clks IMX6QDL_CLK_CKO>; - clock-names = "xclk"; reg = <0x3c>; DOVDD-supply = <&vgen4_reg>; /* 1.8v */ AVDD-supply = <&vgen3_reg>; /* 2.8v, rev C board is VGEN3 @@ -291,6 +299,7 @@ port { ov5642_to_ipu1_csi0_mux: endpoint { remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; + bus-type = ; bus-width = <8>; hsync-active = <1>; vsync-active = <1>; diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi index 6ab71a729fd85..c93dbc595ef6e 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi @@ -69,7 +69,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_switch>; interrupt-parent = <&gpio3>; - interrupt = <30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <30 IRQ_TYPE_LEVEL_HIGH>; reset-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; reg = <0>; diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-ts4900.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-ts4900.dtsi index f88da757edda5..948b612496a5b 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-ts4900.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-ts4900.dtsi @@ -140,7 +140,7 @@ reg = <0x28>; #gpio-cells = <2>; gpio-controller; - ngpio = <32>; + ngpios = <32>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-mb7.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-mb7.dtsi index dd4e5bce4a55d..8232f4ea27526 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-mb7.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-tx6-mb7.dtsi @@ -16,16 +16,19 @@ lcd-panel { compatible = "edt,et057090dhu"; + power-supply = <®_lcd1_pwr>; pixelclk-active = <0>; }; lvds0-panel { compatible = "edt,etml1010g0dka"; + power-supply = <®_lcd1_pwr>; pixelclk-active = <0>; }; lvds1-panel { compatible = "edt,etml1010g0dka"; + power-supply = <®_lcd1_pwr>; pixelclk-active = <0>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi index 2bff5f92242ac..fef34ce961d5f 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-var-som.dtsi @@ -9,9 +9,6 @@ * Copyright 2022 Bootlin */ -/dts-v1/; - -#include "imx6q.dtsi" #include #include #include diff --git a/arch/arm/boot/dts/nxp/imx/imx6qp-yapp4-pegasus-plus.dts b/arch/arm/boot/dts/nxp/imx/imx6qp-yapp4-pegasus-plus.dts index 4a961a33bf2d0..770a85e0561cf 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qp-yapp4-pegasus-plus.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6qp-yapp4-pegasus-plus.dts @@ -17,6 +17,10 @@ }; }; +&beeper { + status = "okay"; +}; + &gpio_oled { status = "okay"; }; @@ -37,6 +41,10 @@ status = "okay"; }; +&pwm3 { + status = "okay"; +}; + ®_pu { regulator-always-on; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-vision.dts b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-vision.dts index 2694fe18a91b1..7cda1f21e4182 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-vision.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-vision.dts @@ -227,7 +227,6 @@ }; &usbotg1 { - pinctrl-names = "default"; disable-over-current; srp-disable; hnp-disable; diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-vision5.dts b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-vision5.dts index a2534c422a522..f8709a9524093 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-vision5.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-vision5.dts @@ -26,6 +26,11 @@ compatible = "kobo,tolino-vision5", "fsl,imx6sl"; }; +&epd_pmic_supply { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_epd_pmic_supply>; +}; + &gpio_keys { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio_keys>; @@ -59,6 +64,12 @@ >; }; + pinctrl_epd_pmic_supply: epd-pmic-supplygrp { + fsl,pins = < + MX6SL_PAD_EPDC_PWRWAKEUP__GPIO2_IO14 0x40010059 + >; + }; + pinctrl_gpio_keys: gpio-keysgrp { fsl,pins = < MX6SL_PAD_FEC_CRS_DV__GPIO4_IO25 0x17059 /* PWR_SW */ @@ -159,6 +170,14 @@ >; }; + pinctrl_sy7636_gpio: sy7636-gpiogrp { + fsl,pins = < + MX6SL_PAD_EPDC_VCOM0__GPIO2_IO03 0x40010059 /* VCOM_CTRL */ + MX6SL_PAD_EPDC_PWRCTRL1__GPIO2_IO08 0x40010059 /* EN */ + MX6SL_PAD_EPDC_PWRSTAT__GPIO2_IO13 0x17059 /* PWR_GOOD */ + >; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1 @@ -329,6 +348,11 @@ pinctrl-0 = <&pinctrl_ricoh_gpio>; }; +&sy7636 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sy7636_gpio>; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; diff --git a/arch/arm/boot/dts/nxp/imx/imx6sll-kobo-librah2o.dts b/arch/arm/boot/dts/nxp/imx/imx6sll-kobo-librah2o.dts index 660620d226f71..19bbe60331b36 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6sll-kobo-librah2o.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6sll-kobo-librah2o.dts @@ -36,6 +36,11 @@ soc-supply = <&dcdc1_reg>; }; +&epd_pmic_supply { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_epd_pmic_supply>; +}; + &gpio_keys { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio_keys>; @@ -69,6 +74,12 @@ >; }; + pinctrl_epd_pmic_supply: epd-pmic-supplygrp { + fsl,pins = < + MX6SLL_PAD_EPDC_PWR_WAKE__GPIO2_IO14 0x40010059 + >; + }; + pinctrl_gpio_keys: gpio-keysgrp { fsl,pins = < MX6SLL_PAD_GPIO4_IO25__GPIO4_IO25 0x17059 /* PWR_SW */ @@ -169,6 +180,14 @@ >; }; + pinctrl_sy7636_gpio: sy7636-gpiogrp { + fsl,pins = < + MX6SLL_PAD_EPDC_VCOM0__GPIO2_IO03 0x40010059 /* VCOM_CTRL */ + MX6SLL_PAD_EPDC_PWR_CTRL1__GPIO2_IO08 0x40010059 /* EN */ + MX6SLL_PAD_EPDC_PWR_STAT__GPIO2_IO13 0x17059 /* PWR_GOOD */ + >; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX6SLL_PAD_UART1_TXD__UART1_DCE_TX 0x1b0b1 @@ -319,6 +338,11 @@ pinctrl-0 = <&pinctrl_ricoh_gpio>; }; +&sy7636 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sy7636_gpio>; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi index c7aeb99d8f002..3e238d8118fae 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi @@ -119,7 +119,7 @@ regulator-always-on; }; - reg_pcie_gpio: regulator-pcie-gpio { + reg_pcie_gpio: regulator-pcie { compatible = "regulator-fixed"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie_reg>; diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi index 73c9cfbdba621..3d147b160ecf1 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi @@ -43,6 +43,13 @@ regulator-max-microvolt = <2800000>; }; + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + reg_sd1_vmmc: regulator-sd1-vmmc { compatible = "regulator-fixed"; regulator-name = "VSD_3V3"; @@ -157,6 +164,7 @@ panel { compatible = "innolux,at043tn24"; backlight = <&backlight_display>; + power-supply = <®_3v3>; port { panel_in: endpoint { diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-isiot.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-isiot.dtsi index 4c09bb3126966..e34c8cbe36aec 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ul-isiot.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6ul-isiot.dtsi @@ -122,15 +122,21 @@ VDDD-supply = <®_1p8v>; }; - stmpe811: gpio-expander@44 { + gpio-expander@44 { compatible = "st,stmpe811"; reg = <0x44>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_stmpe>; interrupt-parent = <&gpio1>; interrupts = <18 IRQ_TYPE_EDGE_FALLING>; - interrupt-controller; - #interrupt-cells = <2>; + + gpio { + compatible = "st,stmpe-gpio"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; stmpe: touchscreen { compatible = "st,stmpe-ts"; diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-pico-dwarf.dts b/arch/arm/boot/dts/nxp/imx/imx6ul-pico-dwarf.dts index fb206c1d8aca1..fbab126f95b95 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ul-pico-dwarf.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6ul-pico-dwarf.dts @@ -49,5 +49,7 @@ pressure-sensor@60 { compatible = "fsl,mpl3115"; reg = <0x60>; + vdd-supply = <®_3p3v>; + vddio-supply = <®_3p3v>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-pdk2.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-pdk2.dts index b29713831a744..04e570d76e42c 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-pdk2.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-pdk2.dts @@ -199,7 +199,7 @@ reg = <0x38>; interrupt-parent = <&gpio5>; interrupts = <4 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */ - power-supply = <®_panel_3v3>; + vcc-supply = <®_panel_3v3>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi index 7ee25b1416276..6fd68970c0b45 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi @@ -126,7 +126,7 @@ s25fl064: flash@2 { #address-cells = <1>; #size-cells = <1>; - compatible = " jedec,spi-nor"; + compatible = "jedec,spi-nor"; reg = <2>; spi-max-frequency = <40000000>; m25p,fast-read; diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-nitrogen7.dts b/arch/arm/boot/dts/nxp/imx/imx7d-nitrogen7.dts index 7acd28658e6ff..2192f105ec81c 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7d-nitrogen7.dts +++ b/arch/arm/boot/dts/nxp/imx/imx7d-nitrogen7.dts @@ -35,6 +35,7 @@ panel-lcd { compatible = "okaya,rs800480t-7x0gp"; backlight = <&backlight_lcd>; + power-supply = <®_3v3>; port { panel_in: endpoint { @@ -61,6 +62,13 @@ enable-active-high; }; + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "reg-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + reg_can2_3v3: regulator-can2-3v3 { compatible = "regulator-fixed"; regulator-name = "can2-3v3"; diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-pico-dwarf.dts b/arch/arm/boot/dts/nxp/imx/imx7d-pico-dwarf.dts index 1b965652291bf..347dd0fe4f82e 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7d-pico-dwarf.dts +++ b/arch/arm/boot/dts/nxp/imx/imx7d-pico-dwarf.dts @@ -49,6 +49,8 @@ pressure-sensor@60 { compatible = "fsl,mpl3115"; reg = <0x60>; + vdd-supply = <®_3p3v>; + vddio-supply = <®_3p3v>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts b/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts index 17236f90ab335..a370e868cafec 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts +++ b/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts @@ -406,6 +406,8 @@ mpl3115@60 { compatible = "fsl,mpl3115"; reg = <0x60>; + vdd-supply = <®_audio_3v3>; + vddio-supply = <®_audio_3v3>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts b/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts index 56dedd4fb8f08..92b6258059ee0 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts +++ b/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts @@ -31,6 +31,13 @@ }; }; + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + reg_peri_3p15v: regulator-peri-3p15v { compatible = "regulator-fixed"; regulator-name = "peri_3p15v_reg"; @@ -228,6 +235,8 @@ mpl3115@60 { compatible = "fsl,mpl3115"; reg = <0x60>; + vdd-supply = <®_3v3>; + vddio-supply = <®_3v3>; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx7ulp-evk.dts b/arch/arm/boot/dts/nxp/imx/imx7ulp-evk.dts index eff51e113db4f..88d7dc005fa0e 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7ulp-evk.dts +++ b/arch/arm/boot/dts/nxp/imx/imx7ulp-evk.dts @@ -92,7 +92,6 @@ IMX7ULP_PAD_PTC3__LPUART4_RX 0x3 IMX7ULP_PAD_PTC2__LPUART4_TX 0x3 >; - bias-pull-up; }; pinctrl_pwm0: pwm0grp { diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-amarula-rmm.dts b/arch/arm/boot/dts/nxp/mxs/imx28-amarula-rmm.dts index af59211842fb2..ddb64f3d0471a 100644 --- a/arch/arm/boot/dts/nxp/mxs/imx28-amarula-rmm.dts +++ b/arch/arm/boot/dts/nxp/mxs/imx28-amarula-rmm.dts @@ -112,6 +112,29 @@ enable-active-high; regulator-always-on; }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx28-mrmmi-tlv320aic3x-audio"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&cpu_dai>; + simple-audio-card,frame-master = <&cpu_dai>; + simple-audio-card,widgets = + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Headphone Jack", "HPROUT", + "Headphone Jack", "HPRCOM"; + simple-audio-card,mclk-fs = <512>; + + cpu_dai: simple-audio-card,cpu { + sound-dai = <&saif0>; + clocks = <&saif0>; + }; + + codec_dai: simple-audio-card,codec { + sound-dai = <&tlv320aic3x>; + }; + }; }; &auart0 { @@ -154,6 +177,19 @@ pinctrl-0 = <&i2c0_pins_a>; status = "okay"; + tlv320aic3x: audio-codec@18 { + compatible = "ti,tlv320aic3x"; + pinctrl-names = "default"; + pinctrl-0 = <&tlv320aic3x_pins>; + reg = <0x18>; + reset-gpios = <&gpio2 4 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + DVDD-supply = <®_1v8>; + IOVDD-supply = <®_3v3>; + AVDD-supply = <®_3v3>; + DRVDD-supply = <®_3v3>; + }; + touchscreen: touchscreen@38 { compatible = "edt,edt-ft5306"; reg = <0x38>; @@ -246,6 +282,14 @@ fsl,voltage = ; }; + tlv320aic3x_pins: tlv320aic3x-pins@0 { + reg = <0>; + fsl,pinmux-ids = ; + fsl,drive-strength = ; + fsl,pull-up = ; + fsl,voltage = ; + }; + usb0_vbus_enable_pin: usb0-vbus-enable@0 { reg = <0>; fsl,pinmux-ids = ; @@ -269,6 +313,12 @@ status = "okay"; }; +&saif0 { + pinctrl-names = "default"; + pinctrl-0 = <&saif0_pins_a>; + status = "okay"; +}; + /* microSD */ &ssp0 { compatible = "fsl,imx28-mmc"; diff --git a/arch/arm/boot/dts/qcom/qcom-msm8226-samsung-ms013g.dts b/arch/arm/boot/dts/qcom/qcom-msm8226-samsung-ms013g.dts index 08b50dc63923c..80fe2916501a8 100644 --- a/arch/arm/boot/dts/qcom/qcom-msm8226-samsung-ms013g.dts +++ b/arch/arm/boot/dts/qcom/qcom-msm8226-samsung-ms013g.dts @@ -13,13 +13,37 @@ chassis-type = "handset"; aliases { + display0 = &framebuffer0; mmc0 = &sdhc_1; /* SDC1 eMMC slot */ mmc1 = &sdhc_2; /* SDC2 SD card slot */ serial0 = &blsp1_uart3; }; chosen { - stdout-path = "serial0:115200n8"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + stdout-path = "display0"; + + framebuffer0: framebuffer@3200000 { + compatible = "simple-framebuffer"; + reg = <0x03200000 0x800000>; + memory-region = <&cont_splash_region>; + + width = <720>; + height = <1280>; + stride = <(720 * 3)>; + format = "r8g8b8"; + + clocks = <&mmcc MDSS_AHB_CLK>, + <&mmcc MDSS_AXI_CLK>, + <&mmcc MDSS_BYTE0_CLK>, + <&mmcc MDSS_MDP_CLK>, + <&mmcc MDSS_PCLK0_CLK>, + <&mmcc MDSS_VSYNC_CLK>; + power-domains = <&mmcc MDSS_GDSC>; + }; }; gpio-hall-sensor { @@ -93,6 +117,11 @@ }; reserved-memory { + cont_splash_region: cont-splash@3200000 { + reg = <0x03200000 0x800000>; + no-map; + }; + smem_region: smem@fa00000 { reg = <0x0fa00000 0x100000>; no-map; diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960-cdp.dts b/arch/arm/boot/dts/qcom/qcom-msm8960-cdp.dts index 36f4c997b0b3a..1df078d7d89b8 100644 --- a/arch/arm/boot/dts/qcom/qcom-msm8960-cdp.dts +++ b/arch/arm/boot/dts/qcom/qcom-msm8960-cdp.dts @@ -19,7 +19,7 @@ ext_l2: gpio-regulator { compatible = "regulator-fixed"; regulator-name = "ext_l2"; - gpio = <&msmgpio 91 0>; + gpio = <&tlmm 91 0>; startup-delay-us = <10000>; enable-active-high; }; @@ -38,12 +38,12 @@ ethernet@0 { compatible = "micrel,ks8851"; reg = <0>; - interrupt-parent = <&msmgpio>; + interrupt-parent = <&tlmm>; interrupts = <90 IRQ_TYPE_LEVEL_LOW>; spi-max-frequency = <5400000>; vdd-supply = <&ext_l2>; vdd-io-supply = <&pm8921_lvs6>; - reset-gpios = <&msmgpio 89 0>; + reset-gpios = <&tlmm 89 0>; }; }; @@ -56,7 +56,7 @@ status = "okay"; }; -&msmgpio { +&tlmm { spi1_default: spi1-default-state { mosi-pins { pins = "gpio6"; @@ -90,7 +90,7 @@ }; &pm8921 { - interrupts-extended = <&msmgpio 104 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&tlmm 104 IRQ_TYPE_LEVEL_LOW>; }; &pm8921_keypad { diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960-pins.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8960-pins.dtsi deleted file mode 100644 index f18753e9f5ef3..0000000000000 --- a/arch/arm/boot/dts/qcom/qcom-msm8960-pins.dtsi +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -&msmgpio { - i2c3_default_state: i2c3-default-state { - i2c3-pins { - pins = "gpio16", "gpio17"; - function = "gsbi3"; - drive-strength = <8>; - bias-disable; - }; - }; - - i2c3_sleep_state: i2c3-sleep-state { - i2c3-pins { - pins = "gpio16", "gpio17"; - function = "gpio"; - drive-strength = <2>; - bias-bus-hold; - }; - }; - - sdcc3_default_state: sdcc3-default-state { - clk-pins { - pins = "sdc3_clk"; - drive-strength = <8>; - bias-disable; - }; - - cmd-pins { - pins = "sdc3_cmd"; - drive-strength = <8>; - bias-pull-up; - }; - - data-pins { - pins = "sdc3_data"; - drive-strength = <8>; - bias-pull-up; - }; - }; - - sdcc3_sleep_state: sdcc3-sleep-state { - clk-pins { - pins = "sdc3_clk"; - drive-strength = <2>; - bias-disable; - }; - - cmd-pins { - pins = "sdc3_cmd"; - drive-strength = <2>; - bias-pull-up; - }; - - data-pins { - pins = "sdc3_data"; - drive-strength = <2>; - bias-pull-up; - }; - }; -}; diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960-samsung-expressatt.dts b/arch/arm/boot/dts/qcom/qcom-msm8960-samsung-expressatt.dts index 49d117ea033a0..5ee919dce75b3 100644 --- a/arch/arm/boot/dts/qcom/qcom-msm8960-samsung-expressatt.dts +++ b/arch/arm/boot/dts/qcom/qcom-msm8960-samsung-expressatt.dts @@ -31,7 +31,7 @@ key-home { label = "Home"; - gpios = <&msmgpio 40 GPIO_ACTIVE_LOW>; + gpios = <&tlmm 40 GPIO_ACTIVE_LOW>; debounce-interval = <5>; linux,code = ; wakeup-event-action = ; @@ -40,14 +40,14 @@ key-volume-up { label = "Volume Up"; - gpios = <&msmgpio 50 GPIO_ACTIVE_LOW>; + gpios = <&tlmm 50 GPIO_ACTIVE_LOW>; debounce-interval = <5>; linux,code = ; }; key-volume-down { label = "Volume Down"; - gpios = <&msmgpio 81 GPIO_ACTIVE_LOW>; + gpios = <&tlmm 81 GPIO_ACTIVE_LOW>; debounce-interval = <5>; linux,code = ; }; @@ -102,7 +102,7 @@ touchscreen@4a { compatible = "atmel,maxtouch"; reg = <0x4a>; - interrupt-parent = <&msmgpio>; + interrupt-parent = <&tlmm>; interrupts = <11 IRQ_TYPE_EDGE_FALLING>; vdda-supply = <&pm8921_lvs6>; vdd-supply = <&pm8921_l17>; @@ -111,7 +111,7 @@ }; }; -&msmgpio { +&tlmm { spi1_default: spi1-default-state { mosi-pins { pins = "gpio6"; @@ -160,7 +160,7 @@ }; &pm8921 { - interrupts-extended = <&msmgpio 104 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&tlmm 104 IRQ_TYPE_LEVEL_LOW>; }; &rpm { diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts b/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts index f2f59fc8b9b61..591dc837e6003 100644 --- a/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts +++ b/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts @@ -54,7 +54,7 @@ }; &pm8921 { - interrupts-extended = <&msmgpio 104 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&tlmm 104 IRQ_TYPE_LEVEL_LOW>; }; &pm8921_gpio { diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi index 6e272d5345a85..38bd4fd8dda5c 100644 --- a/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi +++ b/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi @@ -15,6 +15,35 @@ compatible = "qcom,msm8960"; interrupt-parent = <&intc>; + clocks { + cxo_board: cxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + clock-output-names = "cxo_board"; + }; + + pxo_board: pxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + clock-output-names = "pxo_board"; + }; + + sleep_clk: sleep_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "sleep_clk"; + }; + }; + + cpu-pmu { + compatible = "qcom,krait-pmu"; + interrupts = ; + qcom,no-pc-write; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -22,9 +51,9 @@ cpu@0 { compatible = "qcom,krait"; + reg = <0>; enable-method = "qcom,kpss-acc-v1"; device_type = "cpu"; - reg = <0>; next-level-cache = <&l2>; qcom,acc = <&acc0>; qcom,saw = <&saw0>; @@ -32,9 +61,9 @@ cpu@1 { compatible = "qcom,krait"; + reg = <1>; enable-method = "qcom,kpss-acc-v1"; device_type = "cpu"; - reg = <1>; next-level-cache = <&l2>; qcom,acc = <&acc1>; qcom,saw = <&saw1>; @@ -52,111 +81,29 @@ reg = <0x80000000 0>; }; - thermal-zones { - cpu0-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsens 0>; - - trips { - cpu_alert0: trip0 { - temperature = <60000>; - hysteresis = <10000>; - type = "passive"; - }; - - cpu_crit0: trip1 { - temperature = <95000>; - hysteresis = <10000>; - type = "critical"; - }; - }; - }; - - cpu1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsens 1>; - - trips { - cpu_alert1: trip0 { - temperature = <60000>; - hysteresis = <10000>; - type = "passive"; - }; - - cpu_crit1: trip1 { - temperature = <95000>; - hysteresis = <10000>; - type = "critical"; - }; - }; - }; - }; - - cpu-pmu { - compatible = "qcom,krait-pmu"; - interrupts = ; - qcom,no-pc-write; - }; - - clocks { - cxo_board: cxo_board { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <19200000>; - clock-output-names = "cxo_board"; - }; - - pxo_board: pxo_board { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <27000000>; - clock-output-names = "pxo_board"; - }; - - sleep_clk: sleep_clk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32768>; - clock-output-names = "sleep_clk"; - }; - }; - - /* Temporary fixed regulator */ - vsdcc_fixed: vsdcc-regulator { - compatible = "regulator-fixed"; - regulator-name = "SDCC Power"; - regulator-min-microvolt = <2700000>; - regulator-max-microvolt = <2700000>; - regulator-always-on; - }; - soc: soc { + compatible = "simple-bus"; + ranges; #address-cells = <1>; #size-cells = <1>; - ranges; - compatible = "simple-bus"; - intc: interrupt-controller@2000000 { - compatible = "qcom,msm-qgic2"; - interrupt-controller; - #interrupt-cells = <3>; - reg = <0x02000000 0x1000>, - <0x02002000 0x1000>; + rpm: rpm@108000 { + compatible = "qcom,rpm-msm8960"; + reg = <0x108000 0x1000>; + qcom,ipc = <&l2cc 0x8 2>; + + interrupts = , + , + ; + interrupt-names = "ack", + "err", + "wakeup"; }; - timer@200a000 { - compatible = "qcom,kpss-wdt-msm8960", "qcom,kpss-timer", - "qcom,msm-timer"; - interrupts = , - , - ; - reg = <0x0200a000 0x100>; - clock-frequency = <27000000>; - clocks = <&sleep_clk>; - clock-names = "sleep"; - cpu-offset = <0x80000>; + ssbi: ssbi@500000 { + compatible = "qcom,ssbi"; + reg = <0x500000 0x1000>; + qcom,controller-type = "pmic-arbiter"; }; qfprom: efuse@700000 { @@ -174,26 +121,158 @@ }; }; - msmgpio: pinctrl@800000 { + tlmm: pinctrl@800000 { compatible = "qcom,msm8960-pinctrl"; + reg = <0x800000 0x4000>; gpio-controller; - gpio-ranges = <&msmgpio 0 0 152>; + gpio-ranges = <&tlmm 0 0 152>; #gpio-cells = <2>; interrupts = ; interrupt-controller; #interrupt-cells = <2>; - reg = <0x800000 0x4000>; + + i2c1_default_state: i2c1-default-state { + i2c1-pins { + pins = "gpio8", "gpio9"; + function = "gsbi1"; + drive-strength = <8>; + bias-disable; + }; + }; + + i2c1_sleep_state: i2c1-sleep-state { + i2c1-pins { + pins = "gpio8", "gpio9"; + function = "gpio"; + drive-strength = <2>; + bias-bus-hold; + }; + }; + + i2c3_default_state: i2c3-default-state { + i2c3-pins { + pins = "gpio16", "gpio17"; + function = "gsbi3"; + drive-strength = <8>; + bias-disable; + }; + }; + + i2c3_sleep_state: i2c3-sleep-state { + i2c3-pins { + pins = "gpio16", "gpio17"; + function = "gpio"; + drive-strength = <2>; + bias-bus-hold; + }; + }; + + i2c8_default_state: i2c8-default-state { + i2c8-pins { + pins = "gpio36", "gpio37"; + function = "gsbi8"; + drive-strength = <8>; + bias-disable; + }; + }; + + i2c8_sleep_state: i2c8-sleep-state { + i2c8-pins { + pins = "gpio36", "gpio37"; + function = "gpio"; + drive-strength = <2>; + bias-bus-hold; + }; + }; + + i2c10_default_state: i2c10-default-state { + i2c10-pins { + pins = "gpio73", "gpio74"; + function = "gsbi10"; + drive-strength = <8>; + bias-disable; + }; + }; + + i2c10_sleep_state: i2c10-sleep-state { + i2c10-pins { + pins = "gpio73", "gpio74"; + function = "gpio"; + drive-strength = <2>; + bias-bus-hold; + }; + }; + + i2c12_default_state: i2c12-default-state { + i2c12-pins { + pins = "gpio44", "gpio45"; + function = "gsbi12"; + drive-strength = <8>; + bias-disable; + }; + }; + + i2c12_sleep_state: i2c12-sleep-state { + i2c12-pins { + pins = "gpio44", "gpio45"; + function = "gpio"; + drive-strength = <2>; + bias-bus-hold; + }; + }; + + sdcc3_default_state: sdcc3-default-state { + clk-pins { + pins = "sdc3_clk"; + drive-strength = <8>; + bias-disable; + }; + + cmd-pins { + pins = "sdc3_cmd"; + drive-strength = <8>; + bias-pull-up; + }; + + data-pins { + pins = "sdc3_data"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + sdcc3_sleep_state: sdcc3-sleep-state { + clk-pins { + pins = "sdc3_clk"; + drive-strength = <2>; + bias-disable; + }; + + cmd-pins { + pins = "sdc3_cmd"; + drive-strength = <2>; + bias-pull-up; + }; + + data-pins { + pins = "sdc3_data"; + drive-strength = <2>; + bias-pull-up; + }; + }; }; gcc: clock-controller@900000 { compatible = "qcom,gcc-msm8960", "syscon"; + reg = <0x900000 0x4000>; #clock-cells = <1>; #reset-cells = <1>; - reg = <0x900000 0x4000>; clocks = <&cxo_board>, <&pxo_board>, <&lcc PLL4>; - clock-names = "cxo", "pxo", "pll4"; + clock-names = "cxo", + "pxo", + "pll4"; tsens: thermal-sensor { compatible = "qcom,msm8960-tsens"; @@ -208,49 +287,25 @@ }; }; - lcc: clock-controller@28000000 { - compatible = "qcom,lcc-msm8960"; - reg = <0x28000000 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - clocks = <&pxo_board>, - <&gcc PLL4_VOTE>, - <0>, - <0>, <0>, - <0>, <0>, - <0>; - clock-names = "pxo", - "pll4_vote", - "mi2s_codec_clk", - "codec_i2s_mic_codec_clk", - "spare_i2s_mic_codec_clk", - "codec_i2s_spkr_codec_clk", - "spare_i2s_spkr_codec_clk", - "pcm_codec_clk"; + intc: interrupt-controller@2000000 { + compatible = "qcom,msm-qgic2"; + reg = <0x02000000 0x1000>, + <0x02002000 0x1000>; + interrupt-controller; + #interrupt-cells = <3>; }; - clock-controller@4000000 { - compatible = "qcom,mmcc-msm8960"; - reg = <0x4000000 0x1000>; - #clock-cells = <1>; - #power-domain-cells = <1>; - #reset-cells = <1>; - clocks = <&pxo_board>, - <&gcc PLL3>, - <&gcc PLL8_VOTE>, - <0>, - <0>, - <0>, - <0>, - <0>; - clock-names = "pxo", - "pll3", - "pll8_vote", - "dsi1pll", - "dsi1pllbyte", - "dsi2pll", - "dsi2pllbyte", - "hdmipll"; + timer@200a000 { + compatible = "qcom,kpss-wdt-msm8960", "qcom,kpss-timer", + "qcom,msm-timer"; + reg = <0x0200a000 0x100>; + interrupts = , + , + ; + clock-frequency = <27000000>; + clocks = <&sleep_clk>; + clock-names = "sleep"; + cpu-offset = <0x80000>; }; l2cc: clock-controller@2011000 { @@ -261,17 +316,6 @@ #clock-cells = <0>; }; - rpm: rpm@108000 { - compatible = "qcom,rpm-msm8960"; - reg = <0x108000 0x1000>; - qcom,ipc = <&l2cc 0x8 2>; - - interrupts = , - , - ; - interrupt-names = "ack", "err", "wakeup"; - }; - acc0: clock-controller@2088000 { compatible = "qcom,kpss-acc-v1"; reg = <0x02088000 0x1000>, <0x02008000 0x1000>; @@ -281,15 +325,6 @@ #clock-cells = <0>; }; - acc1: clock-controller@2098000 { - compatible = "qcom,kpss-acc-v1"; - reg = <0x02098000 0x1000>, <0x02008000 0x1000>; - clocks = <&gcc PLL8_VOTE>, <&pxo_board>; - clock-names = "pll8_vote", "pxo"; - clock-output-names = "acpu1_aux"; - #clock-cells = <0>; - }; - saw0: power-manager@2089000 { compatible = "qcom,msm8960-saw2-cpu", "qcom,saw2"; reg = <0x02089000 0x1000>, <0x02009000 0x1000>; @@ -300,6 +335,15 @@ }; }; + acc1: clock-controller@2098000 { + compatible = "qcom,kpss-acc-v1"; + reg = <0x02098000 0x1000>, <0x02008000 0x1000>; + clocks = <&gcc PLL8_VOTE>, <&pxo_board>; + clock-names = "pll8_vote", "pxo"; + clock-output-names = "acpu1_aux"; + #clock-cells = <0>; + }; + saw1: power-manager@2099000 { compatible = "qcom,msm8960-saw2-cpu", "qcom,saw2"; reg = <0x02099000 0x1000>, <0x02009000 0x1000>; @@ -310,77 +354,34 @@ }; }; - gsbi5: gsbi@16400000 { - compatible = "qcom,gsbi-v1.0.0"; - cell-index = <5>; - reg = <0x16400000 0x100>; - clocks = <&gcc GSBI5_H_CLK>; - clock-names = "iface"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - syscon-tcsr = <&tcsr>; - - status = "disabled"; - - gsbi5_serial: serial@16440000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x16440000 0x1000>, - <0x16400000 0x1000>; - interrupts = ; - clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>; - clock-names = "core", "iface"; - status = "disabled"; - }; - }; - - gsbi8: gsbi@1a000000 { - compatible = "qcom,gsbi-v1.0.0"; - cell-index = <8>; - reg = <0x1a000000 0x100>; - clocks = <&gcc GSBI8_H_CLK>; - clock-names = "iface"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - syscon-tcsr = <&tcsr>; - - status = "disabled"; - - gsbi8_serial: serial@1a040000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x1a040000 0x1000>, - <0x1a000000 0x1000>; - interrupts = ; - clocks = <&gcc GSBI8_UART_CLK>, - <&gcc GSBI8_H_CLK>; - clock-names = "core", - "iface"; - - status = "disabled"; - }; - }; - - ssbi: ssbi@500000 { - compatible = "qcom,ssbi"; - reg = <0x500000 0x1000>; - qcom,controller-type = "pmic-arbiter"; - }; - - rng@1a500000 { - compatible = "qcom,prng"; - reg = <0x1a500000 0x200>; - clocks = <&gcc PRNG_CLK>; - clock-names = "core"; + clock-controller@4000000 { + compatible = "qcom,mmcc-msm8960"; + reg = <0x4000000 0x1000>; + #clock-cells = <1>; + #power-domain-cells = <1>; + #reset-cells = <1>; + clocks = <&pxo_board>, + <&gcc PLL3>, + <&gcc PLL8_VOTE>, + <0>, + <0>, + <0>, + <0>, + <0>; + clock-names = "pxo", + "pll3", + "pll8_vote", + "dsi1pll", + "dsi1pllbyte", + "dsi2pll", + "dsi2pllbyte", + "hdmipll"; }; sdcc3: mmc@12180000 { compatible = "arm,pl18x", "arm,primecell"; - arm,primecell-periphid = <0x00051180>; - status = "disabled"; reg = <0x12180000 0x2000>; + arm,primecell-periphid = <0x00051180>; interrupts = ; clocks = <&gcc SDC3_CLK>, <&gcc SDC3_H_CLK>; clock-names = "mclk", "apb_pclk"; @@ -392,6 +393,8 @@ vmmc-supply = <&vsdcc_fixed>; dmas = <&sdcc3bam 2>, <&sdcc3bam 1>; dma-names = "tx", "rx"; + + status = "disabled"; }; sdcc3bam: dma-controller@12182000 { @@ -405,10 +408,9 @@ }; sdcc1: mmc@12400000 { - status = "disabled"; compatible = "arm,pl18x", "arm,primecell"; - arm,primecell-periphid = <0x00051180>; reg = <0x12400000 0x2000>; + arm,primecell-periphid = <0x00051180>; interrupts = ; clocks = <&gcc SDC1_CLK>, <&gcc SDC1_H_CLK>; clock-names = "mclk", "apb_pclk"; @@ -420,6 +422,8 @@ vmmc-supply = <&vsdcc_fixed>; dmas = <&sdcc1bam 2>, <&sdcc1bam 1>; dma-names = "tx", "rx"; + + status = "disabled"; }; sdcc1bam: dma-controller@12402000 { @@ -432,33 +436,32 @@ qcom,ee = <0>; }; - tcsr: syscon@1a400000 { - compatible = "qcom,tcsr-msm8960", "syscon"; - reg = <0x1a400000 0x100>; - }; - - gsbi1: gsbi@16000000 { + gsbi12: gsbi@12480000 { compatible = "qcom,gsbi-v1.0.0"; - cell-index = <1>; - reg = <0x16000000 0x100>; - clocks = <&gcc GSBI1_H_CLK>; + reg = <0x12480000 0x100>; + ranges; + cell-index = <12>; + clocks = <&gcc GSBI12_H_CLK>; clock-names = "iface"; #address-cells = <1>; #size-cells = <1>; - ranges; status = "disabled"; - gsbi1_spi: spi@16080000 { - compatible = "qcom,spi-qup-v1.1.1"; + gsbi12_i2c: i2c@124a0000 { + compatible = "qcom,i2c-qup-v1.1.1"; + reg = <0x124a0000 0x1000>; + pinctrl-0 = <&i2c12_default_state>; + pinctrl-1 = <&i2c12_sleep_state>; + pinctrl-names = "default", "sleep"; + interrupts = ; + clocks = <&gcc GSBI12_QUP_CLK>, + <&gcc GSBI12_H_CLK>; + clock-names = "core", + "iface"; #address-cells = <1>; #size-cells = <0>; - reg = <0x16080000 0x1000>; - interrupts = ; - cs-gpios = <&msmgpio 8 0>; - clocks = <&gcc GSBI1_QUP_CLK>, <&gcc GSBI1_H_CLK>; - clock-names = "core", "iface"; status = "disabled"; }; }; @@ -479,6 +482,7 @@ phys = <&usb_hs1_phy>; phy-names = "usb-phy"; #reset-cells = <1>; + status = "disabled"; ulpi { @@ -494,6 +498,51 @@ }; }; + gsbi1: gsbi@16000000 { + compatible = "qcom,gsbi-v1.0.0"; + reg = <0x16000000 0x100>; + ranges; + cell-index = <1>; + clocks = <&gcc GSBI1_H_CLK>; + clock-names = "iface"; + #address-cells = <1>; + #size-cells = <1>; + + status = "disabled"; + + gsbi1_i2c: i2c@16080000 { + compatible = "qcom,i2c-qup-v1.1.1"; + reg = <0x16080000 0x1000>; + pinctrl-0 = <&i2c1_default_state>; + pinctrl-1 = <&i2c1_sleep_state>; + pinctrl-names = "default", "sleep"; + interrupts = ; + clocks = <&gcc GSBI1_QUP_CLK>, + <&gcc GSBI1_H_CLK>; + clock-names = "core", + "iface"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + gsbi1_spi: spi@16080000 { + compatible = "qcom,spi-qup-v1.1.1"; + reg = <0x16080000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + cs-gpios = <&tlmm 8 0>; + clocks = <&gcc GSBI1_QUP_CLK>, + <&gcc GSBI1_H_CLK>; + clock-names = "core", + "iface"; + + status = "disabled"; + }; + }; + gsbi3: gsbi@16200000 { compatible = "qcom,gsbi-v1.0.0"; reg = <0x16200000 0x100>; @@ -503,6 +552,7 @@ clock-names = "iface"; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; gsbi3_i2c: i2c@16280000 { @@ -514,12 +564,200 @@ interrupts = ; clocks = <&gcc GSBI3_QUP_CLK>, <&gcc GSBI3_H_CLK>; - clock-names = "core", "iface"; + clock-names = "core", + "iface"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + }; + + gsbi5: gsbi@16400000 { + compatible = "qcom,gsbi-v1.0.0"; + reg = <0x16400000 0x100>; + ranges; + cell-index = <5>; + clocks = <&gcc GSBI5_H_CLK>; + clock-names = "iface"; + #address-cells = <1>; + #size-cells = <1>; + syscon-tcsr = <&tcsr>; + + status = "disabled"; + + gsbi5_serial: serial@16440000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x16440000 0x1000>, + <0x16400000 0x1000>; + interrupts = ; + clocks = <&gcc GSBI5_UART_CLK>, + <&gcc GSBI5_H_CLK>; + clock-names = "core", + "iface"; + + status = "disabled"; + }; + }; + + gsbi8: gsbi@1a000000 { + compatible = "qcom,gsbi-v1.0.0"; + reg = <0x1a000000 0x100>; + ranges; + cell-index = <8>; + clocks = <&gcc GSBI8_H_CLK>; + clock-names = "iface"; + #address-cells = <1>; + #size-cells = <1>; + syscon-tcsr = <&tcsr>; + + status = "disabled"; + + gsbi8_serial: serial@1a040000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x1a040000 0x1000>, + <0x1a000000 0x1000>; + interrupts = ; + clocks = <&gcc GSBI8_UART_CLK>, + <&gcc GSBI8_H_CLK>; + clock-names = "core", + "iface"; + + status = "disabled"; + }; + + gsbi8_i2c: i2c@1a080000 { + compatible = "qcom,i2c-qup-v1.1.1"; + reg = <0x1a080000 0x1000>; + pinctrl-0 = <&i2c8_default_state>; + pinctrl-1 = <&i2c8_sleep_state>; + pinctrl-names = "default", "sleep"; + interrupts = ; + clocks = <&gcc GSBI8_QUP_CLK>, + <&gcc GSBI8_H_CLK>; + clock-names = "core", + "iface"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + }; + + gsbi10: gsbi@1a200000 { + compatible = "qcom,gsbi-v1.0.0"; + reg = <0x1a200000 0x100>; + ranges; + cell-index = <10>; + clocks = <&gcc GSBI10_H_CLK>; + clock-names = "iface"; + #address-cells = <1>; + #size-cells = <1>; + + status = "disabled"; + + gsbi10_i2c: i2c@1a280000 { + compatible = "qcom,i2c-qup-v1.1.1"; + reg = <0x1a280000 0x1000>; + pinctrl-0 = <&i2c10_default_state>; + pinctrl-1 = <&i2c10_sleep_state>; + pinctrl-names = "default", "sleep"; + interrupts = ; + clocks = <&gcc GSBI10_QUP_CLK>, + <&gcc GSBI10_H_CLK>; + clock-names = "core", + "iface"; #address-cells = <1>; #size-cells = <0>; + status = "disabled"; }; }; + + tcsr: syscon@1a400000 { + compatible = "qcom,tcsr-msm8960", "syscon"; + reg = <0x1a400000 0x100>; + }; + + rng@1a500000 { + compatible = "qcom,prng"; + reg = <0x1a500000 0x200>; + clocks = <&gcc PRNG_CLK>; + clock-names = "core"; + }; + + lcc: clock-controller@28000000 { + compatible = "qcom,lcc-msm8960"; + reg = <0x28000000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + clocks = <&pxo_board>, + <&gcc PLL4_VOTE>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>; + clock-names = "pxo", + "pll4_vote", + "mi2s_codec_clk", + "codec_i2s_mic_codec_clk", + "spare_i2s_mic_codec_clk", + "codec_i2s_spkr_codec_clk", + "spare_i2s_spkr_codec_clk", + "pcm_codec_clk"; + }; + }; + + thermal-zones { + cpu0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&tsens 0>; + + trips { + cpu_alert0: trip0 { + temperature = <60000>; + hysteresis = <10000>; + type = "passive"; + }; + + cpu_crit0: trip1 { + temperature = <95000>; + hysteresis = <10000>; + type = "critical"; + }; + }; + }; + + cpu1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&tsens 1>; + + trips { + cpu_alert1: trip0 { + temperature = <60000>; + hysteresis = <10000>; + type = "passive"; + }; + + cpu_crit1: trip1 { + temperature = <95000>; + hysteresis = <10000>; + type = "critical"; + }; + }; + }; + }; + + /* Temporary fixed regulator */ + vsdcc_fixed: vsdcc-regulator { + compatible = "regulator-fixed"; + regulator-name = "SDCC Power"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + regulator-always-on; }; }; -#include "qcom-msm8960-pins.dtsi" diff --git a/arch/arm/boot/dts/renesas/r7s72100.dtsi b/arch/arm/boot/dts/renesas/r7s72100.dtsi index a1e4e9ac8f621..245c26bb8e037 100644 --- a/arch/arm/boot/dts/renesas/r7s72100.dtsi +++ b/arch/arm/boot/dts/renesas/r7s72100.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r7s72100"; #address-cells = <1>; #size-cells = <1>; + interrupt-parent = <&gic>; aliases { i2c0 = &i2c0; @@ -84,7 +85,7 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts-extended = <&gic GIC_PPI 0 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; rtc_x1_clk: rtc_x1 { @@ -103,7 +104,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/renesas/r7s9210.dtsi b/arch/arm/boot/dts/renesas/r7s9210.dtsi index fdeb0bc12cb79..2b349b51003b5 100644 --- a/arch/arm/boot/dts/renesas/r7s9210.dtsi +++ b/arch/arm/boot/dts/renesas/r7s9210.dtsi @@ -52,7 +52,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/renesas/r8a7742.dtsi b/arch/arm/boot/dts/renesas/r8a7742.dtsi index 9083d288cc339..4220b2349b409 100644 --- a/arch/arm/boot/dts/renesas/r8a7742.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7742.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r8a7742"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -208,19 +209,19 @@ pmu-0 { compatible = "arm,cortex-a15-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; }; pmu-1 { compatible = "arm,cortex-a7-pmu"; - interrupts-extended = <&gic GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>; }; @@ -234,7 +235,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; @@ -1932,10 +1932,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm/boot/dts/renesas/r8a7743.dtsi b/arch/arm/boot/dts/renesas/r8a7743.dtsi index 58a06cf37784c..c697942387e1d 100644 --- a/arch/arm/boot/dts/renesas/r8a7743.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7743.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r8a7743"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -115,8 +116,8 @@ pmu { compatible = "arm,cortex-a15-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&cpu0>, <&cpu1>; }; @@ -130,7 +131,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; @@ -1841,10 +1841,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm/boot/dts/renesas/r8a7744.dtsi b/arch/arm/boot/dts/renesas/r8a7744.dtsi index 034244648d18c..fed46345807cb 100644 --- a/arch/arm/boot/dts/renesas/r8a7744.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7744.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r8a7744"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -115,8 +116,8 @@ pmu { compatible = "arm,cortex-a15-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&cpu0>, <&cpu1>; }; @@ -130,7 +131,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; @@ -1827,10 +1827,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm/boot/dts/renesas/r8a7745.dtsi b/arch/arm/boot/dts/renesas/r8a7745.dtsi index 704fa6f3cbd08..5424a73562ddb 100644 --- a/arch/arm/boot/dts/renesas/r8a7745.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7745.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r8a7745"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; aliases { i2c0 = &i2c0; @@ -105,8 +106,8 @@ pmu { compatible = "arm,cortex-a7-pmu"; - interrupts-extended = <&gic GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&cpu0>, <&cpu1>; }; @@ -120,7 +121,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; @@ -1631,10 +1631,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm/boot/dts/renesas/r8a77470.dtsi b/arch/arm/boot/dts/renesas/r8a77470.dtsi index a8a12275c98a6..c61790e7667f5 100644 --- a/arch/arm/boot/dts/renesas/r8a77470.dtsi +++ b/arch/arm/boot/dts/renesas/r8a77470.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r8a77470"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; aliases { i2c0 = &i2c0; @@ -66,8 +67,8 @@ pmu { compatible = "arm,cortex-a7-pmu"; - interrupts-extended = <&gic GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&cpu0>, <&cpu1>; }; @@ -81,7 +82,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; @@ -1057,10 +1057,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm/boot/dts/renesas/r8a7790.dtsi b/arch/arm/boot/dts/renesas/r8a7790.dtsi index 4f97c09dbc9fe..12cce9bdc4499 100644 --- a/arch/arm/boot/dts/renesas/r8a7790.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7790.dtsi @@ -16,6 +16,7 @@ compatible = "renesas,r8a7790"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; aliases { i2c0 = &i2c0; @@ -239,19 +240,19 @@ pmu-0 { compatible = "arm,cortex-a15-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; }; pmu-1 { compatible = "arm,cortex-a7-pmu"; - interrupts-extended = <&gic GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>; }; @@ -265,7 +266,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -2012,10 +2012,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts b/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts index e9f90fa44d551..61ea438eb6af1 100644 --- a/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts @@ -301,6 +301,16 @@ clock-frequency = <12000000>; }; + composite-in { + compatible = "composite-video-connector"; + + port { + composite_con_in: endpoint { + remote-endpoint = <&adv7180_in>; + }; + }; + }; + hdmi-out { compatible = "hdmi-connector"; type = "a"; @@ -383,13 +393,25 @@ }; composite-in@20 { - compatible = "adi,adv7180"; + compatible = "adi,adv7180cp"; reg = <0x20>; - port { - adv7180: endpoint { - bus-width = <8>; - remote-endpoint = <&vin1ep>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7180_in: endpoint { + remote-endpoint = <&composite_con_in>; + }; + }; + + port@3 { + reg = <3>; + adv7180_out: endpoint { + remote-endpoint = <&vin1ep>; + }; }; }; }; @@ -900,7 +922,7 @@ port { vin1ep: endpoint { - remote-endpoint = <&adv7180>; + remote-endpoint = <&adv7180_out>; bus-width = <8>; }; }; diff --git a/arch/arm/boot/dts/renesas/r8a7791.dtsi b/arch/arm/boot/dts/renesas/r8a7791.dtsi index 5023b41c28b36..35313e8da4265 100644 --- a/arch/arm/boot/dts/renesas/r8a7791.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7791.dtsi @@ -16,6 +16,7 @@ compatible = "renesas,r8a7791"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; aliases { i2c0 = &i2c0; @@ -137,8 +138,8 @@ pmu { compatible = "arm,cortex-a15-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&cpu0>, <&cpu1>; }; @@ -152,7 +153,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -1939,10 +1939,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm/boot/dts/renesas/r8a7792.dtsi b/arch/arm/boot/dts/renesas/r8a7792.dtsi index 7513afc1c9585..9e0de69ac3a3a 100644 --- a/arch/arm/boot/dts/renesas/r8a7792.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7792.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r8a7792"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; aliases { i2c0 = &i2c0; @@ -94,8 +95,8 @@ pmu { compatible = "arm,cortex-a15-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&cpu0>, <&cpu1>; }; @@ -109,7 +110,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -992,10 +992,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; }; diff --git a/arch/arm/boot/dts/renesas/r8a7793-gose.dts b/arch/arm/boot/dts/renesas/r8a7793-gose.dts index 45b267ec26794..5c6928c941aca 100644 --- a/arch/arm/boot/dts/renesas/r8a7793-gose.dts +++ b/arch/arm/boot/dts/renesas/r8a7793-gose.dts @@ -373,7 +373,6 @@ port@3 { reg = <3>; adv7180_out: endpoint { - bus-width = <8>; remote-endpoint = <&vin1ep>; }; }; diff --git a/arch/arm/boot/dts/renesas/r8a7793.dtsi b/arch/arm/boot/dts/renesas/r8a7793.dtsi index fc6d3bcca2961..1ad50070a1a73 100644 --- a/arch/arm/boot/dts/renesas/r8a7793.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7793.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r8a7793"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; aliases { i2c0 = &i2c0; @@ -122,8 +123,8 @@ pmu { compatible = "arm,cortex-a15-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&cpu0>, <&cpu1>; }; @@ -137,7 +138,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -1518,10 +1518,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm/boot/dts/renesas/r8a7794.dtsi b/arch/arm/boot/dts/renesas/r8a7794.dtsi index 92010d09f6c40..7669a67377c98 100644 --- a/arch/arm/boot/dts/renesas/r8a7794.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7794.dtsi @@ -15,6 +15,7 @@ compatible = "renesas,r8a7794"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; aliases { i2c0 = &i2c0; @@ -104,8 +105,8 @@ pmu { compatible = "arm,cortex-a7-pmu"; - interrupts-extended = <&gic GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&cpu0>, <&cpu1>; }; @@ -119,7 +120,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -1485,10 +1485,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts index 3258b2e274346..4a72aa7663f25 100644 --- a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +++ b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts @@ -308,8 +308,6 @@ &switch { status = "okay"; - #address-cells = <1>; - #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&pins_eth3>, <&pins_eth4>, <&pins_mdio1>; diff --git a/arch/arm/boot/dts/renesas/r9a06g032.dtsi b/arch/arm/boot/dts/renesas/r9a06g032.dtsi index 13a60656b0447..8debb77803bb9 100644 --- a/arch/arm/boot/dts/renesas/r9a06g032.dtsi +++ b/arch/arm/boot/dts/renesas/r9a06g032.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r9a06g032"; #address-cells = <1>; #size-cells = <1>; + interrupt-parent = <&gic>; cpus { #address-cells = <1>; @@ -63,7 +64,6 @@ compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; - interrupt-parent = <&gic>; ranges; rtc0: rtc@40006000 { @@ -290,6 +290,16 @@ status = "disabled"; }; + adc: adc@40065000 { + compatible = "renesas,r9a06g032-adc", "renesas,rzn1-adc"; + reg = <0x40065000 0x200>; + clocks = <&sysctrl R9A06G032_HCLK_ADC>, <&sysctrl R9A06G032_CLK_ADC>; + clock-names = "pclk", "adc"; + power-domains = <&sysctrl>; + #io-channel-cells = <1>; + status = "disabled"; + }; + pinctrl: pinctrl@40067000 { compatible = "renesas,r9a06g032-pinctrl", "renesas,rzn1-pinctrl"; reg = <0x40067000 0x1000>, <0x51000000 0x480>; @@ -522,7 +532,6 @@ timer { compatible = "arm,armv7-timer"; - interrupt-parent = <&gic>; arm,cpu-registers-not-fw-configured; always-on; interrupts = diff --git a/arch/arm/boot/dts/renesas/sh73a0-kzm9g.dts b/arch/arm/boot/dts/renesas/sh73a0-kzm9g.dts index 1ce07d0878dc6..0a9cd61bcb5f9 100644 --- a/arch/arm/boot/dts/renesas/sh73a0-kzm9g.dts +++ b/arch/arm/boot/dts/renesas/sh73a0-kzm9g.dts @@ -209,6 +209,7 @@ reg = <0x1d>; interrupts-extended = <&irqpin3 2 IRQ_TYPE_LEVEL_HIGH>, <&irqpin3 3 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "INT1", "INT2"; }; rtc@32 { diff --git a/arch/arm/boot/dts/rockchip/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rockchip/rk3066a-bqcurie2.dts index c227691013eaf..65f8bc804d212 100644 --- a/arch/arm/boot/dts/rockchip/rk3066a-bqcurie2.dts +++ b/arch/arm/boot/dts/rockchip/rk3066a-bqcurie2.dts @@ -80,26 +80,33 @@ clock-frequency = <400000>; tps: tps@2d { + compatible = "ti,tps65910"; reg = <0x2d>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio6>; interrupts = ; + interrupt-controller; + #interrupt-cells = <2>; + vcc5-supply = <&vcc_io>; vcc6-supply = <&vcc_io>; regulators { - vcc_rtc: regulator@0 { + vcc_rtc: vrtc { regulator-name = "vcc_rtc"; regulator-always-on; }; - vcc_io: regulator@1 { + vcc_io: vio { regulator-name = "vcc_io"; regulator-always-on; }; - vdd_arm: regulator@2 { + vdd_arm: vdd1 { regulator-name = "vdd_arm"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <1500000>; @@ -107,7 +114,7 @@ regulator-always-on; }; - vcc_ddr: regulator@3 { + vcc_ddr: vdd2 { regulator-name = "vcc_ddr"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <1500000>; @@ -115,42 +122,42 @@ regulator-always-on; }; - vcc18_cif: regulator@5 { + vcc18_cif: vdig1 { regulator-name = "vcc18_cif"; regulator-always-on; }; - vdd_11: regulator@6 { + vdd_11: vdig2 { regulator-name = "vdd_11"; regulator-always-on; }; - vcc_25: regulator@7 { + vcc_25: vpll { regulator-name = "vcc_25"; regulator-always-on; }; - vcc_18: regulator@8 { + vcc_18: vdac { regulator-name = "vcc_18"; regulator-always-on; }; - vcc25_hdmi: regulator@9 { + vcc25_hdmi: vaux1 { regulator-name = "vcc25_hdmi"; regulator-always-on; }; - vcca_33: regulator@10 { + vcca_33: vaux2 { regulator-name = "vcca_33"; regulator-always-on; }; - vcc_tp: regulator@11 { + vcc_tp: vaux33 { regulator-name = "vcc_tp"; regulator-always-on; }; - vcc28_cif: regulator@12 { + vcc28_cif: vmmc { regulator-name = "vcc28_cif"; regulator-always-on; }; @@ -158,9 +165,6 @@ }; }; -/* must be included after &tps gets defined */ -#include "../tps65910.dtsi" - &mmc0 { /* sdmmc */ status = "okay"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/rockchip/rk3066a-marsboard.dts b/arch/arm/boot/dts/rockchip/rk3066a-marsboard.dts index de42d1855121c..15dbe1677e309 100644 --- a/arch/arm/boot/dts/rockchip/rk3066a-marsboard.dts +++ b/arch/arm/boot/dts/rockchip/rk3066a-marsboard.dts @@ -96,11 +96,18 @@ clock-frequency = <400000>; tps: tps@2d { + compatible = "ti,tps65910"; reg = <0x2d>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio6>; interrupts = ; + interrupt-controller; + #interrupt-cells = <2>; + vcc1-supply = <&vsys>; vcc2-supply = <&vsys>; vcc3-supply = <&vsys>; @@ -111,17 +118,17 @@ vccio-supply = <&vsys>; regulators { - vcc_rtc: regulator@0 { + vcc_rtc: vrtc { regulator-name = "vcc_rtc"; regulator-always-on; }; - vcc_io: regulator@1 { + vcc_io: vio { regulator-name = "vcc_io"; regulator-always-on; }; - vdd_arm: regulator@2 { + vdd_arm: vdd1 { regulator-name = "vdd_arm"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <1500000>; @@ -129,7 +136,7 @@ regulator-always-on; }; - vcc_ddr: regulator@3 { + vcc_ddr: vdd2 { regulator-name = "vcc_ddr"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <1500000>; @@ -137,41 +144,41 @@ regulator-always-on; }; - vcc18_cif: regulator@5 { + vcc18_cif: vdig1 { regulator-name = "vcc18_cif"; regulator-always-on; }; - vdd_11: regulator@6 { + vdd_11: vdig2 { regulator-name = "vdd_11"; regulator-always-on; }; - vcc_25: regulator@7 { + vcc_25: vpll { regulator-name = "vcc_25"; regulator-always-on; }; - vcc_18: regulator@8 { + vcc_18: vdac { regulator-name = "vcc_18"; regulator-always-on; }; - vcc25_hdmi: regulator@9 { + vcc25_hdmi: vaux1 { regulator-name = "vcc25_hdmi"; regulator-always-on; }; - vcca_33: regulator@10 { + vcca_33: vaux2 { regulator-name = "vcca_33"; regulator-always-on; }; - vcc_rmii: regulator@11 { + vcc_rmii: vaux33 { regulator-name = "vcc_rmii"; }; - vcc28_cif: regulator@12 { + vcc28_cif: vmmc { regulator-name = "vcc28_cif"; regulator-always-on; }; @@ -179,9 +186,6 @@ }; }; -/* must be included after &tps gets defined */ -#include "../tps65910.dtsi" - &emac { phy = <&phy0>; phy-supply = <&vcc_rmii>; diff --git a/arch/arm/boot/dts/rockchip/rk3066a-rayeager.dts b/arch/arm/boot/dts/rockchip/rk3066a-rayeager.dts index b0b029f146436..07c03ed6fac68 100644 --- a/arch/arm/boot/dts/rockchip/rk3066a-rayeager.dts +++ b/arch/arm/boot/dts/rockchip/rk3066a-rayeager.dts @@ -198,9 +198,18 @@ status = "okay"; tps: tps@2d { + compatible = "ti,tps65910"; reg = <0x2d>; + + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio6>; interrupts = ; + + interrupt-controller; + #interrupt-cells = <2>; + pinctrl-names = "default"; pinctrl-0 = <&pmic_int>, <&pwr_hold>; @@ -214,19 +223,19 @@ vccio-supply = <&vsys>; regulators { - vcc_rtc: regulator@0 { + vcc_rtc: vrtc { regulator-name = "vcc_rtc"; regulator-always-on; }; - vcc_io: regulator@1 { + vcc_io: vio { regulator-name = "vcc_io"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-always-on; }; - vdd_arm: regulator@2 { + vdd_arm: vdd1 { regulator-name = "vdd_arm"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <1500000>; @@ -234,7 +243,7 @@ regulator-boot-on; }; - vcc_ddr: regulator@3 { + vcc_ddr: vdd2 { regulator-name = "vcc_ddr"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <1500000>; @@ -242,52 +251,52 @@ regulator-boot-on; }; - vcc18: regulator@5 { + vcc18: vdig1 { regulator-name = "vcc18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-always-on; }; - vdd_11: regulator@6 { + vdd_11: vdig2 { regulator-name = "vdd_11"; regulator-min-microvolt = <1100000>; regulator-max-microvolt = <1100000>; regulator-always-on; }; - vcc_25: regulator@7 { + vcc_25: vpll { regulator-name = "vcc_25"; regulator-min-microvolt = <2500000>; regulator-max-microvolt = <2500000>; regulator-always-on; }; - vccio_wl: regulator@8 { + vccio_wl: vdac { regulator-name = "vccio_wl"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; - vcc25_hdmi: regulator@9 { + vcc25_hdmi: vaux1 { regulator-name = "vcc25_hdmi"; regulator-min-microvolt = <2500000>; regulator-max-microvolt = <2500000>; }; - vcca_33: regulator@10 { + vcca_33: vaux2 { regulator-name = "vcca_33"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; - vcc_rmii: regulator@11 { + vcc_rmii: vaux33 { regulator-name = "vcc_rmii"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; - vcc28_cif: regulator@12 { + vcc28_cif: vmmc { regulator-name = "vcc28_cif"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -296,8 +305,6 @@ }; }; -#include "../tps65910.dtsi" - &i2c2 { status = "okay"; }; diff --git a/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi b/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi index 260d6c92cfd11..2d6cf08d00f90 100644 --- a/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi @@ -388,7 +388,7 @@ rx-sample-delay-ns = <12>; - flash@0 { + spi_flash: flash@0 { compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi index 42d705b544ecb..7477fc5da3ec9 100644 --- a/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi @@ -34,10 +34,6 @@ i2c3 = &i2c3; i2c4 = &i2c4; i2c5 = &i2c5; - mshc0 = &emmc; - mshc1 = &sdmmc; - mshc2 = &sdio0; - mshc3 = &sdio1; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -745,9 +741,6 @@ #address-cells = <1>; #size-cells = <0>; - assigned-clocks = <&cru SCLK_EDP_24M>; - assigned-clock-parents = <&xin24m>; - /* * Note: Although SCLK_* are the working clocks * of device without including on the NOC, needed for @@ -1197,6 +1190,8 @@ compatible = "rockchip,rk3288-dp"; reg = <0x0 0xff970000 0x0 0x4000>; interrupts = ; + assigned-clocks = <&cru SCLK_EDP_24M>; + assigned-clock-parents = <&xin24m>; clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>; clock-names = "dp", "pclk"; phys = <&edp_phy>; diff --git a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts index df229fb8a16be..8a635bee59fa9 100644 --- a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +++ b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts @@ -853,6 +853,7 @@ #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; vmmc-supply = <&vtf_reg>; diff --git a/arch/arm/boot/dts/samsung/exynos4210-trats.dts b/arch/arm/boot/dts/samsung/exynos4210-trats.dts index 95e0e01b6ff6b..6bd902cb8f4ad 100644 --- a/arch/arm/boot/dts/samsung/exynos4210-trats.dts +++ b/arch/arm/boot/dts/samsung/exynos4210-trats.dts @@ -518,6 +518,7 @@ #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; vmmc-supply = <&tflash_reg>; diff --git a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts index bdc30f8cf748f..91490693432b6 100644 --- a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts @@ -610,6 +610,7 @@ #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; vmmc-supply = <&ldo5_reg>; diff --git a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi index 05ddddb565ee3..48245b1665a69 100644 --- a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +++ b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi @@ -1440,6 +1440,7 @@ #address-cells = <1>; #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; diff --git a/arch/arm/boot/dts/st/stih410.dtsi b/arch/arm/boot/dts/st/stih410.dtsi index d56343f44fda4..07da9b48ccac1 100644 --- a/arch/arm/boot/dts/st/stih410.dtsi +++ b/arch/arm/boot/dts/st/stih410.dtsi @@ -34,6 +34,41 @@ status = "disabled"; }; + display-subsystem { + compatible = "st,sti-display-subsystem"; + ports = <&compositor>, <&hqvdp>, <&tvout>, <&sti_hdmi>; + + assigned-clocks = <&clk_s_d2_quadfs 0>, + <&clk_s_d2_quadfs 1>, + <&clk_s_c0_pll1 0>, + <&clk_s_c0_flexgen CLK_COMPO_DVP>, + <&clk_s_c0_flexgen CLK_MAIN_DISP>, + <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>, + <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>, + <&clk_s_d2_flexgen CLK_PIX_GDP1>, + <&clk_s_d2_flexgen CLK_PIX_GDP2>, + <&clk_s_d2_flexgen CLK_PIX_GDP3>, + <&clk_s_d2_flexgen CLK_PIX_GDP4>; + + assigned-clock-parents = <0>, + <0>, + <0>, + <&clk_s_c0_pll1 0>, + <&clk_s_c0_pll1 0>, + <&clk_s_d2_quadfs 0>, + <&clk_s_d2_quadfs 1>, + <&clk_s_d2_quadfs 0>, + <&clk_s_d2_quadfs 0>, + <&clk_s_d2_quadfs 0>, + <&clk_s_d2_quadfs 0>; + + assigned-clock-rates = <297000000>, + <297000000>, + <0>, + <400000000>, + <400000000>; + }; + soc { ohci0: usb@9a03c00 { compatible = "st,st-ohci-300x"; @@ -99,151 +134,174 @@ status = "disabled"; }; - sti-display-subsystem@0 { - compatible = "st,sti-display-subsystem"; - #address-cells = <1>; - #size-cells = <1>; - - reg = <0 0>; - assigned-clocks = <&clk_s_d2_quadfs 0>, - <&clk_s_d2_quadfs 1>, - <&clk_s_c0_pll1 0>, - <&clk_s_c0_flexgen CLK_COMPO_DVP>, - <&clk_s_c0_flexgen CLK_MAIN_DISP>, - <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>, - <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>, - <&clk_s_d2_flexgen CLK_PIX_GDP1>, - <&clk_s_d2_flexgen CLK_PIX_GDP2>, - <&clk_s_d2_flexgen CLK_PIX_GDP3>, - <&clk_s_d2_flexgen CLK_PIX_GDP4>; - - assigned-clock-parents = <0>, - <0>, - <0>, - <&clk_s_c0_pll1 0>, - <&clk_s_c0_pll1 0>, - <&clk_s_d2_quadfs 0>, - <&clk_s_d2_quadfs 1>, - <&clk_s_d2_quadfs 0>, + compositor: display-controller@9d11000 { + compatible = "st,stih407-compositor"; + reg = <0x9d11000 0x1000>; + + clock-names = "compo_main", + "compo_aux", + "pix_main", + "pix_aux", + "pix_gdp1", + "pix_gdp2", + "pix_gdp3", + "pix_gdp4", + "main_parent", + "aux_parent"; + + clocks = <&clk_s_c0_flexgen CLK_COMPO_DVP>, + <&clk_s_c0_flexgen CLK_COMPO_DVP>, + <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>, + <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>, + <&clk_s_d2_flexgen CLK_PIX_GDP1>, + <&clk_s_d2_flexgen CLK_PIX_GDP2>, + <&clk_s_d2_flexgen CLK_PIX_GDP3>, + <&clk_s_d2_flexgen CLK_PIX_GDP4>, + <&clk_s_d2_quadfs 0>, + <&clk_s_d2_quadfs 1>; + + reset-names = "compo-main", "compo-aux"; + resets = <&softreset STIH407_COMPO_SOFTRESET>, + <&softreset STIH407_COMPO_SOFTRESET>; + st,vtg = <&vtg_main>, <&vtg_aux>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + compo_main_out: endpoint { + remote-endpoint = <&tvout_in0>; + }; + }; + + port@1 { + reg = <1>; + compo_aux_out: endpoint { + remote-endpoint = <&tvout_in1>; + }; + }; + }; + }; + + tvout: encoder@8d08000 { + compatible = "st,stih407-tvout"; + reg = <0x8d08000 0x1000>; + reg-names = "tvout-reg"; + reset-names = "tvout"; + resets = <&softreset STIH407_HDTVOUT_SOFTRESET>; + assigned-clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>, + <&clk_s_d2_flexgen CLK_TMDS_HDMI>, + <&clk_s_d2_flexgen CLK_REF_HDMIPHY>, + <&clk_s_d0_flexgen CLK_PCM_0>, + <&clk_s_d2_flexgen CLK_PIX_HDDAC>, + <&clk_s_d2_flexgen CLK_HDDAC>; + + assigned-clock-parents = <&clk_s_d2_quadfs 0>, + <&clk_tmdsout_hdmi>, <&clk_s_d2_quadfs 0>, + <&clk_s_d0_quadfs 0>, <&clk_s_d2_quadfs 0>, <&clk_s_d2_quadfs 0>; - assigned-clock-rates = <297000000>, - <297000000>, - <0>, - <400000000>, - <400000000>; - - ranges; - - sti-compositor@9d11000 { - compatible = "st,stih407-compositor"; - reg = <0x9d11000 0x1000>; - - clock-names = "compo_main", - "compo_aux", - "pix_main", - "pix_aux", - "pix_gdp1", - "pix_gdp2", - "pix_gdp3", - "pix_gdp4", - "main_parent", - "aux_parent"; - - clocks = <&clk_s_c0_flexgen CLK_COMPO_DVP>, - <&clk_s_c0_flexgen CLK_COMPO_DVP>, - <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>, - <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>, - <&clk_s_d2_flexgen CLK_PIX_GDP1>, - <&clk_s_d2_flexgen CLK_PIX_GDP2>, - <&clk_s_d2_flexgen CLK_PIX_GDP3>, - <&clk_s_d2_flexgen CLK_PIX_GDP4>, - <&clk_s_d2_quadfs 0>, - <&clk_s_d2_quadfs 1>; - - reset-names = "compo-main", "compo-aux"; - resets = <&softreset STIH407_COMPO_SOFTRESET>, - <&softreset STIH407_COMPO_SOFTRESET>; - st,vtg = <&vtg_main>, <&vtg_aux>; - }; - - sti-tvout@8d08000 { - compatible = "st,stih407-tvout"; - reg = <0x8d08000 0x1000>; - reg-names = "tvout-reg"; - reset-names = "tvout"; - resets = <&softreset STIH407_HDTVOUT_SOFTRESET>; + ports { #address-cells = <1>; - #size-cells = <1>; - assigned-clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>, - <&clk_s_d2_flexgen CLK_TMDS_HDMI>, - <&clk_s_d2_flexgen CLK_REF_HDMIPHY>, - <&clk_s_d0_flexgen CLK_PCM_0>, - <&clk_s_d2_flexgen CLK_PIX_HDDAC>, - <&clk_s_d2_flexgen CLK_HDDAC>; - - assigned-clock-parents = <&clk_s_d2_quadfs 0>, - <&clk_tmdsout_hdmi>, - <&clk_s_d2_quadfs 0>, - <&clk_s_d0_quadfs 0>, - <&clk_s_d2_quadfs 0>, - <&clk_s_d2_quadfs 0>; + #size-cells = <0>; + + port@0 { + reg = <0>; + tvout_in0: endpoint { + remote-endpoint = <&compo_main_out>; + }; + }; + + port@1 { + reg = <1>; + tvout_in1: endpoint { + remote-endpoint = <&compo_aux_out>; + }; + }; + + port@2 { + reg = <2>; + tvout_out0: endpoint { + remote-endpoint = <&hdmi_in>; + }; + }; + + port@3 { + reg = <3>; + tvout_out1: endpoint { + remote-endpoint = <&hda_in>; + }; + }; }; + }; - sti_hdmi: sti-hdmi@8d04000 { - compatible = "st,stih407-hdmi"; - reg = <0x8d04000 0x1000>; - reg-names = "hdmi-reg"; - #sound-dai-cells = <0>; - interrupts = ; - interrupt-names = "irq"; - clock-names = "pix", - "tmds", - "phy", - "audio", - "main_parent", - "aux_parent"; - - clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>, - <&clk_s_d2_flexgen CLK_TMDS_HDMI>, - <&clk_s_d2_flexgen CLK_REF_HDMIPHY>, - <&clk_s_d0_flexgen CLK_PCM_0>, - <&clk_s_d2_quadfs 0>, - <&clk_s_d2_quadfs 1>; - - hdmi,hpd-gpio = <&pio5 3 GPIO_ACTIVE_LOW>; - reset-names = "hdmi"; - resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>; - ddc = <&hdmiddc>; + sti_hdmi: hdmi@8d04000 { + compatible = "st,stih407-hdmi"; + reg = <0x8d04000 0x1000>; + reg-names = "hdmi-reg"; + #sound-dai-cells = <0>; + interrupts = ; + interrupt-names = "irq"; + clock-names = "pix", + "tmds", + "phy", + "audio", + "main_parent", + "aux_parent"; + + clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>, + <&clk_s_d2_flexgen CLK_TMDS_HDMI>, + <&clk_s_d2_flexgen CLK_REF_HDMIPHY>, + <&clk_s_d0_flexgen CLK_PCM_0>, + <&clk_s_d2_quadfs 0>, + <&clk_s_d2_quadfs 1>; + + hdmi,hpd-gpio = <&pio5 3 GPIO_ACTIVE_LOW>; + reset-names = "hdmi"; + resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>; + ddc = <&hdmiddc>; + + port { + hdmi_in: endpoint { + remote-endpoint = <&tvout_out0>; + }; }; + }; - sti-hda@8d02000 { - compatible = "st,stih407-hda"; - status = "disabled"; - reg = <0x8d02000 0x400>, <0x92b0120 0x4>; - reg-names = "hda-reg", "video-dacs-ctrl"; - clock-names = "pix", - "hddac", - "main_parent", - "aux_parent"; - clocks = <&clk_s_d2_flexgen CLK_PIX_HDDAC>, - <&clk_s_d2_flexgen CLK_HDDAC>, - <&clk_s_d2_quadfs 0>, - <&clk_s_d2_quadfs 1>; + analog@8d02000 { + compatible = "st,stih407-hda"; + status = "disabled"; + reg = <0x8d02000 0x400>, <0x92b0120 0x4>; + reg-names = "hda-reg", "video-dacs-ctrl"; + clock-names = "pix", + "hddac", + "main_parent", + "aux_parent"; + clocks = <&clk_s_d2_flexgen CLK_PIX_HDDAC>, + <&clk_s_d2_flexgen CLK_HDDAC>, + <&clk_s_d2_quadfs 0>, + <&clk_s_d2_quadfs 1>; + + port { + hda_in: endpoint { + remote-endpoint = <&tvout_out1>; + }; }; + }; - sti-hqvdp@9c00000 { - compatible = "st,stih407-hqvdp"; - reg = <0x9C00000 0x100000>; - clock-names = "hqvdp", "pix_main"; - clocks = <&clk_s_c0_flexgen CLK_MAIN_DISP>, - <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>; - reset-names = "hqvdp"; - resets = <&softreset STIH407_HDQVDP_SOFTRESET>; - st,vtg = <&vtg_main>; - }; + hqvdp: plane@9c00000 { + compatible = "st,stih407-hqvdp"; + reg = <0x9C00000 0x100000>; + clock-names = "hqvdp", "pix_main"; + clocks = <&clk_s_c0_flexgen CLK_MAIN_DISP>, + <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>; + reset-names = "hqvdp"; + resets = <&softreset STIH407_HDQVDP_SOFTRESET>; + st,vtg = <&vtg_main>; }; bdisp0:bdisp@9f10000 { diff --git a/arch/arm/boot/dts/st/stm32mp131.dtsi b/arch/arm/boot/dts/st/stm32mp131.dtsi index fd730aa37c22e..b9657ff91c234 100644 --- a/arch/arm/boot/dts/st/stm32mp131.dtsi +++ b/arch/arm/boot/dts/st/stm32mp131.dtsi @@ -29,6 +29,12 @@ interrupt-parent = <&intc>; }; + arm_wdt: watchdog { + compatible = "arm,smc-wdt"; + arm,smc-id = <0xbc000000>; + status = "disabled"; + }; + firmware { optee { method = "smc"; @@ -1000,6 +1006,7 @@ iwdg2: watchdog@5a002000 { compatible = "st,stm32mp1-iwdg"; reg = <0x5a002000 0x400>; + interrupts = ; clocks = <&rcc IWDG2>, <&scmi_clk CK_SCMI_LSI>; clock-names = "pclk", "lsi"; status = "disabled"; @@ -1657,6 +1664,16 @@ reg = <1>; }; }; + + iwdg1: watchdog@5c003000 { + compatible = "st,stm32mp1-iwdg"; + reg = <0x5c003000 0x400>; + interrupts = ; + clocks = <&rcc IWDG1>, <&scmi_clk CK_SCMI_LSI>; + clock-names = "pclk", "lsi"; + access-controllers = <&etzpc 12>; + status = "disabled"; + }; }; /* diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts index 9764a6bfa5b42..f894ee35b3db2 100644 --- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts +++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts @@ -161,6 +161,11 @@ }; }; +&arm_wdt { + timeout-sec = <32>; + status = "okay"; +}; + &crc1 { status = "okay"; }; diff --git a/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi index 9eeb9d6b5eb0e..7d3a6a3b5d09e 100644 --- a/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi +++ b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi @@ -374,9 +374,6 @@ baseboard_eeprom: &sip_eeprom { phys = <&usbphyc_port1 0>; phy-names = "usb2-phy"; - vusb_d-supply = <&vdd_usb>; - vusb_a-supply = <®18>; - status = "okay"; }; diff --git a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi index bf0c32027baf7..370b2afbf15bf 100644 --- a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi +++ b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi @@ -185,13 +185,13 @@ interrupt-parent = <&gpioi>; vio-supply = <&v3v3>; vcc-supply = <&v3v3>; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <1>; touchscreen { compatible = "st,stmpe-ts"; - st,sample-time = <4>; - st,mod-12b = <1>; - st,ref-sel = <0>; - st,adc-freq = <1>; st,ave-ctrl = <1>; st,touch-det-delay = <2>; st,settling = <2>; diff --git a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi index 154698f87b0e5..ab13f0c39892f 100644 --- a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi +++ b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi @@ -493,9 +493,6 @@ baseboard_eeprom: &sip_eeprom { phys = <&usbphyc_port1 0>; phy-names = "usb2-phy"; - vusb_d-supply = <&vdd_usb>; - vusb_a-supply = <®18>; - g-rx-fifo-size = <512>; g-np-tx-fifo-size = <32>; g-tx-fifo-size = <128 128 64 16 16 16 16 16>; diff --git a/arch/arm/boot/dts/ti/omap/Makefile b/arch/arm/boot/dts/ti/omap/Makefile index 1aef60eef6718..14e500846875e 100644 --- a/arch/arm/boot/dts/ti/omap/Makefile +++ b/arch/arm/boot/dts/ti/omap/Makefile @@ -101,6 +101,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \ am335x-guardian.dtb \ am335x-icev2.dtb \ am335x-lxm.dtb \ + am335x-mba335x.dtb \ am335x-moxa-uc-2101.dtb \ am335x-moxa-uc-8100-me-t.dtb \ am335x-myirtech-myd.dtb \ diff --git a/arch/arm/boot/dts/ti/omap/am335x-baltos-leds.dtsi b/arch/arm/boot/dts/ti/omap/am335x-baltos-leds.dtsi index 049fd8e1b40f5..ed194469973e0 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-baltos-leds.dtsi +++ b/arch/arm/boot/dts/ti/omap/am335x-baltos-leds.dtsi @@ -17,18 +17,18 @@ compatible = "gpio-leds"; - led-power { + led_power: led-power { label = "onrisc:red:power"; linux,default-trigger = "default-on"; gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; default-state = "on"; }; - led-wlan { + led_wlan: led-wlan { label = "onrisc:blue:wlan"; gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; default-state = "off"; }; - led-app { + led_app: led-app { label = "onrisc:green:app"; gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; default-state = "off"; diff --git a/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi b/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi index ea47f9960c356..afb38f023b837 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi +++ b/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi @@ -45,6 +45,23 @@ startup-delay-us = <70000>; enable-active-high; }; + + mpcie_regulator: mpcie-regulator { + compatible = "regulator-fixed"; + regulator-name = "mpcie-regulator"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio3 4 0>; + enable-active-high; + regulator-boot-on; + }; + + mpcie_power_switch: mpcie-power-switch { + compatible = "regulator-output"; + regulator-name = "mpcie-power-switch"; + regulator-supplies = "vcc"; + vout-supply = <&mpcie_regulator>; + }; }; &am33xx_pinmux { diff --git a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi index ad1e60a9b6fde..1d83fc116b662 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi @@ -16,7 +16,7 @@ }; chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; leds { @@ -217,7 +217,7 @@ }; baseboard_eeprom: eeprom@50 { - compatible = "atmel,24c256"; + compatible = "atmel,24c32"; reg = <0x50>; vcc-supply = <&ldo4_reg>; diff --git a/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts b/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts index f579df4c2c540..d430f0bef1653 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts @@ -13,7 +13,7 @@ compatible = "ti,am335x-bone-blue", "ti,am33xx"; chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; leds { diff --git a/arch/arm/boot/dts/ti/omap/am335x-chiliboard.dts b/arch/arm/boot/dts/ti/omap/am335x-chiliboard.dts index 648e97fe1dfd5..ae5bc58984972 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-chiliboard.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-chiliboard.dts @@ -12,7 +12,7 @@ "ti,am33xx"; chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; leds { diff --git a/arch/arm/boot/dts/ti/omap/am335x-evm.dts b/arch/arm/boot/dts/ti/omap/am335x-evm.dts index 20222f82f21bf..856fa1191ed24 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-evm.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-evm.dts @@ -23,7 +23,7 @@ }; chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; vbat: fixedregulator0 { diff --git a/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts b/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts index eba888dcd60e7..d8baccdf8bc46 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts @@ -30,7 +30,7 @@ }; chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; vbat: fixedregulator0 { diff --git a/arch/arm/boot/dts/ti/omap/am335x-guardian.dts b/arch/arm/boot/dts/ti/omap/am335x-guardian.dts index 4b070e634b281..6ce3a2d029eed 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-guardian.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-guardian.dts @@ -14,7 +14,7 @@ compatible = "bosch,am335x-guardian", "ti,am33xx"; chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; tick-timer = &timer2; }; diff --git a/arch/arm/boot/dts/ti/omap/am335x-icev2.dts b/arch/arm/boot/dts/ti/omap/am335x-icev2.dts index 6f0f4fba043b9..ba488bba6925d 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-icev2.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-icev2.dts @@ -22,7 +22,7 @@ }; chosen { - stdout-path = &uart3; + stdout-path = "serial3:115200n8"; }; vbat: fixedregulator0 { diff --git a/arch/arm/boot/dts/ti/omap/am335x-mba335x.dts b/arch/arm/boot/dts/ti/omap/am335x-mba335x.dts new file mode 100644 index 0000000000000..8c0b2a1c99b12 --- /dev/null +++ b/arch/arm/boot/dts/ti/omap/am335x-mba335x.dts @@ -0,0 +1,633 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021-2025 TQ-Systems GmbH , D-82229 Seefeld, Germany. + * Authors: Gregor Herburger, Matthias Schiffer + * + * Based on: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + */ +/dts-v1/; + +#include +#include +#include "am335x-tqma335x.dtsi" + +/ { + model = "TQ-Systems TQMa335x[L] SoM on MBa335x carrier board"; + compatible = "tq,tqma3359-mba335x", "tq,tqma3359", "ti,am33xx"; + chassis-type = "embedded"; + + chosen { + stdout-path = &uart4; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = <0 58 61 66 75 90 125 170 255>; + default-brightness-level = <7>; + enable-gpios = <&expander1 4 GPIO_ACTIVE_HIGH>; + power-supply = <®_mba335x_12v>; + status = "disabled"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + button-s5 { + label = "S5"; + linux,code = ; + gpios = <&expander2 0 GPIO_ACTIVE_LOW>; + }; + + button-s6 { + label = "S6"; + linux,code = ; + gpios = <&expander2 1 GPIO_ACTIVE_LOW>; + }; + + button-s7 { + label = "S7"; + linux,code = ; + gpios = <&expander2 2 GPIO_ACTIVE_LOW>; + }; + }; + + reg_mba335x_12v: regulator-12v { + compatible = "regulator-fixed"; + regulator-name = "MBa335x-V12"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + + vcc3v3: regulator-vcc3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "tqm-tlv320aic32"; + simple-audio-card,widgets = + "Headphone", "Headphone Jack", + "Line", "Line In", + "Line", "Line Out", + "Microphone", "Mic Jack"; + simple-audio-card,routing = + "Headphone Jack", "HPL", + "Headphone Jack", "HPR", + "Line Out", "LOL", + "Line Out", "LOR", + "IN3_L", "Mic Jack", + "Mic Jack", "Mic Bias", + "Line In", "IN1_L", + "Line In", "IN1_R"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&sound_master>; + simple-audio-card,frame-master = <&sound_master>; + + simple-audio-card,cpu { + sound-dai = <&mcasp0>; + #sound-dai-cells = <0>; + system-clock-direction-out; + }; + + sound_master: simple-audio-card,codec { + sound-dai = <&tlv320aic32x4>; + system-clock-frequency = <24000000>; + system-clock-direction-out; + }; + }; +}; + +&am33xx_pinmux { + codec_pins: codec-pins { + pinctrl-single,pins = < + /* xdma_event_intr0.clkout1 */ + AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR0, PIN_OUTPUT, MUX_MODE3) + >; + }; + + cpsw_default_pins: cpsw-default-pins { + pinctrl-single,pins = < + /* Port 1 */ + /* mii1_tx_en.rgmii1_tctl */ + AM33XX_PADCONF(AM335X_PIN_MII1_TX_EN, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* mii1_rx_dv.rgmii1_rctl */ + AM33XX_PADCONF(AM335X_PIN_MII1_RX_DV, PIN_INPUT_PULLDOWN, MUX_MODE2) + /* mii1_txd3.rgmii1_td3 */ + AM33XX_PADCONF(AM335X_PIN_MII1_TXD3, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* mii1_txd2.rgmii1_td2 */ + AM33XX_PADCONF(AM335X_PIN_MII1_TXD2, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* mii1_txd1.rgmii1_td1 */ + AM33XX_PADCONF(AM335X_PIN_MII1_TXD1, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* mii1_txd0.rgmii1_td0 */ + AM33XX_PADCONF(AM335X_PIN_MII1_TXD0, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* mii1_tx_clk.rgmii1_tclk */ + AM33XX_PADCONF(AM335X_PIN_MII1_TX_CLK, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* mii1_rx_clk.rgmii1_rclk */ + AM33XX_PADCONF(AM335X_PIN_MII1_RX_CLK, PIN_INPUT_PULLDOWN, MUX_MODE2) + /* mii1_rxd3.rgmii1_rd3 */ + AM33XX_PADCONF(AM335X_PIN_MII1_RXD3, PIN_INPUT_PULLDOWN, MUX_MODE2) + /* mii1_rxd2.rgmii1_rd2 */ + AM33XX_PADCONF(AM335X_PIN_MII1_RXD2, PIN_INPUT_PULLDOWN, MUX_MODE2) + /* mii1_rxd1.rgmii1_rd1 */ + AM33XX_PADCONF(AM335X_PIN_MII1_RXD1, PIN_INPUT_PULLDOWN, MUX_MODE2) + /* mii1_rxd0.rgmii1_rd0 */ + AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_INPUT_PULLDOWN, MUX_MODE2) + + /* Port 2 */ + /* gpmc_a0.rgmii2_tctl */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A0, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a1.rgmii2_rctl */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A1, PIN_INPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a2.rgmii2_td3 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A2, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a3.rgmii2_td2 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A3, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a4.rgmii2_td1 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A4, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a5.rgmii2_td0 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A5, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a6.rgmii2_tclk */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A6, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a7.rgmii2_rclk */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A7, PIN_INPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a8.rgmii2_rd3 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A8, PIN_INPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a9.rgmii2_rd2 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A9, PIN_INPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a10.rgmii2_rd1 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A10, PIN_INPUT_PULLDOWN, MUX_MODE2) + /* gpmc_a11.rgmii2_rd0 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A11, PIN_INPUT_PULLDOWN, MUX_MODE2) + >; + }; + + cpsw_sleep_pins: cpsw-sleep-pins { + pinctrl-single,pins = < + /* Port 1 */ + AM33XX_PADCONF(AM335X_PIN_MII1_TX_EN, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_RX_DV, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_TXD3, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_TXD2, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_TXD1, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_TXD0, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_TX_CLK, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_RX_CLK, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_RXD3, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_RXD2, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_RXD1, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_INPUT_PULLDOWN, MUX_MODE7) + + /* Port 2 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A0, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A1, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A2, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A3, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A4, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A5, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A6, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A7, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A8, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A9, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A10, PIN_INPUT_PULLDOWN, MUX_MODE7) + AM33XX_PADCONF(AM335X_PIN_GPMC_A11, PIN_INPUT_PULLDOWN, MUX_MODE7) + >; + }; + + davinci_mdio_default_pins: davinci_mdio-default-pins { + pinctrl-single,pins = < + /* mdio.mdio_data */ + AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT_PULLUP | SLEWCTRL_FAST, MUX_MODE0) + /* mdc.mdio_clk */ + AM33XX_PADCONF(AM335X_PIN_MDC, PIN_OUTPUT_PULLUP, MUX_MODE0) + >; + }; + + davinci_mdio_sleep_pins: davinci_mdio-sleep-pins { + pinctrl-single,pins = < + /* mdio.mdio_data */ + AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT_PULLUP, MUX_MODE7) + /* mdc.mdio_clk */ + AM33XX_PADCONF(AM335X_PIN_MDC, PIN_INPUT_PULLUP, MUX_MODE7) + >; + }; + + davinci_mdio_phy0_pins: davinci_mdio-phy0-pins { + pinctrl-single,pins = < + /* usb0_drvvbus.gpio0_18 - PHY interrupt */ + AM33XX_PADCONF(AM335X_PIN_USB0_DRVVBUS, PIN_INPUT, MUX_MODE7) + >; + }; + + davinci_mdio_phy1_pins: davinci_mdio-phy1-pins { + pinctrl-single,pins = < + /* gpmc_csn0.gpio1_29 - PHY interrupt */ + AM33XX_PADCONF(AM335X_PIN_GPMC_CSN0, PIN_INPUT, MUX_MODE7) + >; + }; + + dcan0_pins: dcan0-pins { + pinctrl-single,pins = < + /* uart1_ctsn.d_can0_tx */ + AM33XX_PADCONF(AM335X_PIN_UART1_CTSN, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* uart1_rtsn.d_can0_rx */ + AM33XX_PADCONF(AM335X_PIN_UART1_RTSN, PIN_INPUT_PULLUP, MUX_MODE2) + >; + }; + + dcan1_pins: dcan1-pins { + pinctrl-single,pins = < + /* uart0_ctsn.d_can1_tx */ + AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_OUTPUT_PULLDOWN, MUX_MODE2) + /* uart0_rtsn.d_can1_rx */ + AM33XX_PADCONF(AM335X_PIN_UART0_RTSN, PIN_INPUT_PULLUP, MUX_MODE2) + >; + }; + + ecap2_pins: ecap2-pins { + pinctrl-single,pins = < + /* mcasp0_ahclkr.ecap2_in_pwm2_out */ + AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKR, PIN_OUTPUT, MUX_MODE4) + >; + }; + + expander1_pins: expander1-pins { + pinctrl-single,pins = < + /* gpmc_csn3.gpio2_0 - interrupt */ + AM33XX_PADCONF(AM335X_PIN_GPMC_CSN3, PIN_INPUT_PULLUP, MUX_MODE7 ) + >; + }; + + expander2_pins: expander2-pins { + pinctrl-single,pins = < + /* gpmc_ben1.gpio1_28 - interrupt */ + AM33XX_PADCONF(AM335X_PIN_GPMC_BEN1, PIN_INPUT_PULLUP, MUX_MODE7) + >; + }; + + i2c1_pins: i2c1-pins { + pinctrl-single,pins = < + /* uart1_rxd.i2c1_sda */ + AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_INPUT_PULLUP, MUX_MODE3) + /* uart1_txd.i2c1_scl */ + AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_INPUT_PULLUP, MUX_MODE3) + >; + }; + + lcd_pins: lcd-pins { + pinctrl-single,pins = < + /* gpmc_ad8.lcd_data23 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD8, PIN_OUTPUT, MUX_MODE1) + /* gpmc_ad9.lcd_data22 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD9, PIN_OUTPUT, MUX_MODE1) + /* gpmc_ad10.lcd_data21 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD10, PIN_OUTPUT, MUX_MODE1) + /* gpmc_ad11.lcd_data20 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD11, PIN_OUTPUT, MUX_MODE1) + /* gpmc_ad12.lcd_data19 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_OUTPUT, MUX_MODE1) + /* gpmc_ad13.lcd_data18 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_OUTPUT, MUX_MODE1) + /* gpmc_ad14.lcd_data17 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD14, PIN_OUTPUT, MUX_MODE1) + /* gpmc_ad15.lcd_data16 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_OUTPUT, MUX_MODE1) + /* lcd_data0.lcd_data0 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA0, PIN_OUTPUT, MUX_MODE0) + /* lcd_data1.lcd_data1 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA1, PIN_OUTPUT, MUX_MODE0) + /* lcd_data2.lcd_data2 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA2, PIN_OUTPUT, MUX_MODE0) + /* lcd_data3.lcd_data3 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA3, PIN_OUTPUT, MUX_MODE0) + /* lcd_data4.lcd_data4 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA4, PIN_OUTPUT, MUX_MODE0) + /* lcd_data5.lcd_data5 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA5, PIN_OUTPUT, MUX_MODE0) + /* lcd_data6.lcd_data6 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA6, PIN_OUTPUT, MUX_MODE0) + /* lcd_data7.lcd_data7 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA7, PIN_OUTPUT, MUX_MODE0) + /* lcd_data8.lcd_data8 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE0) + /* lcd_data9.lcd_data9 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT, MUX_MODE0) + /* lcd_data10.lcd_data10 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA10, PIN_OUTPUT, MUX_MODE0) + /* lcd_data11.lcd_data11 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA11, PIN_OUTPUT, MUX_MODE0) + /* lcd_data12.lcd_data12 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_OUTPUT, MUX_MODE0) + /* lcd_data13.lcd_data13 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_OUTPUT, MUX_MODE0) + /* lcd_data14.lcd_data14 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_OUTPUT, MUX_MODE0) + /* lcd_data15.lcd_data15 */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT, MUX_MODE0) + /* lcd_vsync.lcd_vsync */ + AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT, MUX_MODE0) + /* lcd_hsync.lcd_hsync */ + AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_OUTPUT, MUX_MODE0) + /* lcd_pclk.lcd_pclk */ + AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT, MUX_MODE0) + /* lcd_ac_bias_en.lcd_ac_bias_en */ + AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT, MUX_MODE0) + >; + }; + + mcasp0_pins: mcasp0-pins { + pinctrl-single,pins = < + /* mcasp0_fsx.mcasp0_fsx */ + AM33XX_PADCONF(AM335X_PIN_MCASP0_FSX, PIN_INPUT_PULLDOWN, MUX_MODE0) + /* mcasp0_aclkx.mcasp0_aclkx*/ + AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_INPUT_PULLDOWN, MUX_MODE0) + /* mcasp0_axr0.mcasp0_axr0 */ + AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR0, PIN_INPUT_PULLDOWN, MUX_MODE0) + /* mcasp0_axr1.mcasp0_axr1 */ + AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR1, PIN_INPUT_PULLDOWN, MUX_MODE0) + /* mcasp0_aclkr.mcasp0_aclkr */ + AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKR, PIN_INPUT_PULLDOWN, MUX_MODE0) + /* mcasp0_fsr.mcasp0_fsr */ + AM33XX_PADCONF(AM335X_PIN_MCASP0_FSR, PIN_INPUT_PULLDOWN, MUX_MODE0) + >; + }; + + mmc1_pins: mmc1-pins { + pinctrl-single,pins = < + /* mmc0_dat3.mmc0_dat3 */ + AM33XX_PADCONF(AM335X_PIN_MMC0_DAT3, PIN_INPUT_PULLUP, MUX_MODE0) + /* mmc0_dat2.mmc0_dat2 */ + AM33XX_PADCONF(AM335X_PIN_MMC0_DAT2, PIN_INPUT_PULLUP, MUX_MODE0) + /* mmc0_dat1.mmc0_dat1 */ + AM33XX_PADCONF(AM335X_PIN_MMC0_DAT1, PIN_INPUT_PULLUP, MUX_MODE0) + /* mmc0_dat0.mmc0_dat0 */ + AM33XX_PADCONF(AM335X_PIN_MMC0_DAT0, PIN_INPUT_PULLUP, MUX_MODE0) + /* mmc0_clk.mmc0_clk */ + AM33XX_PADCONF(AM335X_PIN_MMC0_CLK, PIN_INPUT_PULLUP, MUX_MODE0) + /* mmc0_cmd.mmc0_cmd */ + AM33XX_PADCONF(AM335X_PIN_MMC0_CMD, PIN_INPUT_PULLUP, MUX_MODE0) + >; + }; + + polytouch_pins: polytouch-pins { + pinctrl-single,pins = < + /* gpmc_clk.gpio2_1 - touch interrupt */ + AM33XX_PADCONF(AM335X_PIN_GPMC_CLK, PIN_INPUT_PULLUP, MUX_MODE7) + >; + }; + + uart0_pins: uart0-pins { + pinctrl-single,pins = < + /* uart0_rxd.uart0_rxd */ + AM33XX_PADCONF(AM335X_PIN_UART0_RXD, PIN_INPUT_PULLUP, MUX_MODE0) + /* uart0_txd.uart0_txd */ + AM33XX_PADCONF(AM335X_PIN_UART0_TXD, PIN_OUTPUT_PULLDOWN, MUX_MODE0) + >; + }; + + uart3_pins: uart3-pins { + pinctrl-single,pins = < + /* spi0_cs1.uart3_rxd */ + AM33XX_PADCONF(AM335X_PIN_SPI0_CS1, PIN_INPUT_PULLUP, MUX_MODE1) + /* ecap0_in_pwm0_out.uart3_txd */ + AM33XX_PADCONF(AM335X_PIN_ECAP0_IN_PWM0_OUT, PIN_OUTPUT_PULLDOWN, MUX_MODE1) + >; + }; + + uart4_pins: uart4-pins { + pinctrl-single,pins = < + /* gpmc_wait0.uart4_rxd */ + AM33XX_PADCONF(AM335X_PIN_GPMC_WAIT0, PIN_INPUT_PULLUP, MUX_MODE6) + /* gpmc_wpn.uart4_txd */ + AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_OUTPUT_PULLDOWN, MUX_MODE6) + >; + }; +}; + +&cpsw_port1 { + phy-handle = <ðphy0>; + phy-mode = "rgmii-id"; + ti,dual-emac-pvid = <1>; +}; + +&cpsw_port2 { + phy-handle = <ðphy1>; + phy-mode = "rgmii-id"; + ti,dual-emac-pvid = <2>; +}; + +&davinci_mdio_sw { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&davinci_mdio_default_pins>; + pinctrl-1 = <&davinci_mdio_sleep_pins>; + status = "okay"; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&davinci_mdio_phy0_pins>; + interrupt-parent = <&gpio0>; + interrupts = <18 IRQ_TYPE_LEVEL_LOW>; + rxc-skew-ps = <1860>; + rxd0-skew-ps = <0>; + rxd1-skew-ps = <0>; + rxd2-skew-ps = <0>; + rxd3-skew-ps = <0>; + rxdv-skew-ps = <0>; + txc-skew-ps = <1860>; + txd0-skew-ps = <0>; + txd1-skew-ps = <0>; + txd2-skew-ps = <0>; + txd3-skew-ps = <0>; + txen-skew-ps = <0>; + }; + + ethphy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&davinci_mdio_phy1_pins>; + interrupt-parent = <&gpio1>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + rxc-skew-ps = <1860>; + rxd0-skew-ps = <0>; + rxd1-skew-ps = <0>; + rxd2-skew-ps = <0>; + rxd3-skew-ps = <0>; + rxdv-skew-ps = <0>; + txc-skew-ps = <1860>; + txd0-skew-ps = <0>; + txd1-skew-ps = <0>; + txd2-skew-ps = <0>; + txd3-skew-ps = <0>; + txen-skew-ps = <0>; + }; +}; + +&dcan0 { + pinctrl-names = "default"; + pinctrl-0 = <&dcan0_pins>; + status = "okay"; +}; + +&dcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&dcan1_pins>; + status = "okay"; +}; + +&ds1339 { + interrupt-parent = <&expander2>; + interrupts = <3 IRQ_TYPE_EDGE_RISING>; +}; + +&ecap2 { + pinctrl-names = "default"; + pinctrl-0 = <&ecap2_pins>; +}; + +&i2c0 { + tlv320aic32x4: audio-codec@18 { + compatible = "ti,tlv320aic32x4"; + reg = <0x18>; + pinctrl-names = "default"; + pinctrl-0 = <&codec_pins>; + clocks = <&clk_24mhz>; + clock-names = "mclk"; + iov-supply = <&vcc3v3>; + ldoin-supply = <&vcc3v3>; + #sound-dai-cells = <0>; + }; + + jc42_2: temperature-sensor@19 { + compatible = "nxp,se97b", "jedec,jc-42.4-temp"; + reg = <0x19>; + }; + + expander1: gpio@20 { + compatible = "nxp,pca9554"; + reg = <0x20>; + pinctrl-names = "default"; + pinctrl-0 = <&expander1_pins>; + vcc-supply = <&vcc3v3>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&gpio2>; + interrupts = <0 IRQ_TYPE_EDGE_FALLING>; + }; + + expander2: gpio@21 { + compatible = "nxp,pca9554"; + reg = <0x21>; + pinctrl-names = "default"; + pinctrl-0 = <&expander2_pins>; + vcc-supply = <&vcc3v3>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&gpio1>; + interrupts = <28 IRQ_TYPE_EDGE_FALLING>; + }; + + eeprom3: eeprom@51 { + compatible = "nxp,se97b", "atmel,24c02"; + reg = <0x51>; + pagesize = <16>; + vcc-supply = <&vcc3v3>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; + status = "okay"; +}; + +&lcdc { + pinctrl-names = "default"; + pinctrl-0 = <&lcd_pins>; + blue-and-red-wiring = "crossed"; +}; + +&mac_sw { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&cpsw_default_pins>; + pinctrl-1 = <&cpsw_sleep_pins>; + status = "okay"; +}; + +&mcasp0 { + pinctrl-names = "default"; + pinctrl-0 = <&mcasp0_pins>; + #sound-dai-cells = <0>; + op-mode = <0>; + tdm-slots = <2>; + /* 16 serializer */ + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 2 1 0 0 + 0 0 0 0 + 0 0 0 0 + 0 0 0 0 + >; + tx-num-evt = <32>; + rx-num-evt = <32>; + status = "okay"; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + vmmc-supply = <&vcc3v3>; + bus-width = <4>; + no-1-8-v; + no-mmc; + no-sdio; + status = "okay"; +}; + +&tps { + interrupt-parent = <&expander2>; + interrupts = <4 IRQ_TYPE_EDGE_RISING>; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins>; + status = "okay"; +}; + +&usb0 { + dr_mode = "host"; +}; + +&usb1 { + /* Should be "otg", but role switching currently doesn't work */ + dr_mode = "peripheral"; +}; + +/* SOM supply */ +&vcc3v3in { + vin-supply = <&vcc3v3>; +}; diff --git a/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts b/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts index 06a352f98b220..476a6bdaf43f3 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts @@ -15,7 +15,7 @@ compatible = "myir,myd-am335x", "myir,myc-am335x", "ti,am33xx"; chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; clk12m: clk12m { diff --git a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts index f66d57bb685ee..f0519ab301416 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts @@ -222,10 +222,10 @@ "ModeA1", "ModeA2", "ModeA3", - "NC", - "NC", - "NC", - "NC", + "ModeB0", + "ModeB1", + "ModeB2", + "ModeB3", "NC", "NC", "NC", diff --git a/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts b/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts index d28d397288476..23caaaabf3513 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts @@ -147,7 +147,7 @@ }; chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; leds { diff --git a/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts b/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts index c9ccb9de21ad7..9f611debc2090 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts @@ -21,7 +21,7 @@ compatible = "ti,am33xx"; chosen { - stdout-path = &uart3; + stdout-path = "serial3:115200n8"; }; cpus { diff --git a/arch/arm/boot/dts/ti/omap/am335x-pepper.dts b/arch/arm/boot/dts/ti/omap/am335x-pepper.dts index e7d561a527fdd..10d54e0ad15a7 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-pepper.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-pepper.dts @@ -347,7 +347,7 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&wireless_pins>; - vmmmc-supply = <&v3v3c_reg>; + vmmc-supply = <&v3v3c_reg>; bus-width = <4>; non-removable; dmas = <&edma_xbar 12 0 1 diff --git a/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts b/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts index 78ce860e59b3d..24d9f90fad01f 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts @@ -15,7 +15,7 @@ compatible = "ti,am335x-pocketbeagle", "ti,am335x-bone", "ti,am33xx"; chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; leds { diff --git a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts index 7c9f65126c636..8b47f45a9959c 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts @@ -87,7 +87,6 @@ bus-width = <4>; non-removable; cap-power-off-card; - ti,needs-special-hs-handling; keep-power-in-suspend; pinctrl-names = "default"; pinctrl-0 = <&mmc3_pins>; diff --git a/arch/arm/boot/dts/ti/omap/am335x-sl50.dts b/arch/arm/boot/dts/ti/omap/am335x-sl50.dts index f3524e5ee43e2..1dc4e344efd63 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-sl50.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-sl50.dts @@ -25,7 +25,7 @@ }; chosen { - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; leds { diff --git a/arch/arm/boot/dts/ti/omap/am335x-tqma335x.dtsi b/arch/arm/boot/dts/ti/omap/am335x-tqma335x.dtsi new file mode 100644 index 0000000000000..b75949f0f023a --- /dev/null +++ b/arch/arm/boot/dts/ti/omap/am335x-tqma335x.dtsi @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2014-2025 TQ-Systems GmbH , D-82229 Seefeld, Germany. + * Authors: Gregor Herburger, Matthias Schiffer + * + * Based on: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + */ + +#include +#include "am33xx.dtsi" + +/ { + compatible = "tq,tqma3359", "ti,am33xx"; + + aliases { + mmc0 = &mmc2; + mmc1 = &mmc1; + /delete-property/ mmc2; + rtc0 = &tps; + rtc1 = &ds1339; + rtc2 = &rtc; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; + + /* SOM input voltage */ + vcc3v3in: regulator-vcc3v3in { + compatible = "regulator-fixed"; + regulator-name = "VCC3V3IN"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + /* + * Regulator is enabled by PMIC power sequence. The supplied voltage + * rail is also usable on baseboard. + */ + vddshv: regulator-vddshv { + compatible = "regulator-fixed"; + regulator-name = "VDDSHV"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + vin-supply = <&vcc3v3in>; + }; +}; + +&am33xx_pinmux { + i2c0_pins: i2c0-pins { + pinctrl-single,pins = < + /* i2c0_sda.i2c0_sda */ + AM33XX_PADCONF(AM335X_PIN_I2C0_SDA, PIN_INPUT_PULLUP, MUX_MODE0) + /* i2c0_scl.i2c0_scl */ + AM33XX_PADCONF(AM335X_PIN_I2C0_SCL, PIN_INPUT_PULLUP, MUX_MODE0) + >; + }; + + mmc2_pins: mmc2-pins { + pinctrl-single,pins = < + /* gpmc_ad0.mmc1_dat0 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD0, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE1) + /* gpmc_ad1.mmc1_dat1 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD1, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE1) + /* gpmc_ad2.mmc1_dat2 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD2, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE1) + /* gpmc_ad3.mmc1_dat3 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD3, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE1) + /* gpmc_ad4.mmc1_dat4 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD4, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE1) + /* gpmc_ad5.mmc1_dat5 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD5, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE1) + /* gpmc_ad6.mmc1_dat6 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD6, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE1) + /* gpmc_ad7.mmc1_dat7 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD7, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE1) + /* gpmc_csn1.mmc1_clk */ + AM33XX_PADCONF(AM335X_PIN_GPMC_CSN1, PIN_INPUT_PULLUP, MUX_MODE2) + /* gpmc_csn2.mmc1_cmd */ + AM33XX_PADCONF(AM335X_PIN_GPMC_CSN2, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE2) + >; + }; + + spi0_pins: spi0-pins { + pinctrl-single,pins = < + /* spi0_sclk.spi0_sclk */ + AM33XX_PADCONF(AM335X_PIN_SPI0_SCLK, PIN_INPUT, MUX_MODE0) + /* spi0_d0.spi0_d0 */ + AM33XX_PADCONF(AM335X_PIN_SPI0_D0, PIN_INPUT_PULLDOWN, MUX_MODE0) + /* spi0_d1.spi0_d1 */ + AM33XX_PADCONF(AM335X_PIN_SPI0_D1, PIN_OUTPUT, MUX_MODE0) + /* spi0_cs0.spi0_cs0 */ + AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, PIN_OUTPUT, MUX_MODE0) + >; + }; +}; + +&cpu { + cpu0-supply = <&vdd1_reg>; +}; + +&elm { + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; + status = "okay"; + + /* optional, not on TQMa335xL */ + jc42_1: temperature-sensor@1f { + compatible = "nxp,se97b", "jedec,jc-42.4-temp"; + reg = <0x1f>; + }; + + tps: pmic@2d { + reg = <0x2d>; + ti,en-ck32k-xtal; + /* Filled in by tps65910.dtsi */ + }; + + /* optional, not on TQMa335xL */ + eeprom: eeprom@50 { + compatible = "st,24c64", "atmel,24c64"; + reg = <0x50>; + pagesize = <32>; + vcc-supply = <&vddshv>; + }; + + /* optional, not on TQMa335xL */ + se97btp: eeprom@57 { + compatible = "nxp,se97b", "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + vcc-supply = <&vddshv>; + }; + + /* optional, not on TQMa335xL */ + ds1339: rtc@68 { + compatible = "dallas,ds1339"; + reg = <0x68>; + }; +}; + +#include "../../tps65910.dtsi" + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; + bus-width = <8>; + no-1-8-v; + no-sd; + no-sdio; + vmmc-supply = <&vddshv>; + non-removable; + status = "okay"; +}; + +&rtc { + status = "disabled"; +}; + +&tps { + vcc1-supply = <&vcc3v3in>; + vcc2-supply = <&vcc3v3in>; + vcc3-supply = <&vcc3v3in>; + vcc4-supply = <&vcc3v3in>; + vcc5-supply = <&vcc3v3in>; + vcc6-supply = <&vcc3v3in>; + vcc7-supply = <&vcc3v3in>; + vccio-supply = <&vcc3v3in>; +}; + +/* TPS outputs */ +&vrtc_reg { + regulator-always-on; +}; + +&vio_reg { + regulator-always-on; +}; + +&vdd1_reg { + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; +}; + +&vdd2_reg { + regulator-name = "vdd_core"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; +}; + +&vdd3_reg { + regulator-always-on; +}; + +&vdig1_reg { + regulator-always-on; +}; + +&vdig2_reg { + regulator-always-on; +}; + +&vpll_reg { + regulator-always-on; +}; + +&vdac_reg { + regulator-always-on; +}; + +&vaux1_reg { + regulator-always-on; +}; + +&vaux2_reg { + regulator-always-on; +}; + +&vaux33_reg { + regulator-always-on; +}; + +&vmmc_reg { + regulator-always-on; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <24000000>; + vcc-supply = <&vddshv>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + }; + }; +}; + +&usb0_phy { + vcc-supply = <&vaux1_reg>; +}; + +&usb1_phy { + vcc-supply = <&vaux1_reg>; +}; + +&wkup_m3_ipc { + firmware-name = "am335x-evm-scale-data.bin"; +}; diff --git a/arch/arm/boot/dts/ti/omap/am33xx-l4.dtsi b/arch/arm/boot/dts/ti/omap/am33xx-l4.dtsi index 18ad52e939551..89d16fcc773e0 100644 --- a/arch/arm/boot/dts/ti/omap/am33xx-l4.dtsi +++ b/arch/arm/boot/dts/ti/omap/am33xx-l4.dtsi @@ -1501,7 +1501,6 @@ mmc1: mmc@0 { compatible = "ti,am335-sdhci"; - ti,needs-special-reset; dmas = <&edma 24 0>, <&edma 25 0>; dma-names = "tx", "rx"; interrupts = <64>; @@ -1987,7 +1986,6 @@ mmc2: mmc@0 { compatible = "ti,am335-sdhci"; - ti,needs-special-reset; dmas = <&edma 2 0 &edma 3 0>; dma-names = "tx", "rx"; diff --git a/arch/arm/boot/dts/ti/omap/am33xx.dtsi b/arch/arm/boot/dts/ti/omap/am33xx.dtsi index 43ec2a95f4bb7..ca3e7f5d7d0dc 100644 --- a/arch/arm/boot/dts/ti/omap/am33xx.dtsi +++ b/arch/arm/boot/dts/ti/omap/am33xx.dtsi @@ -45,7 +45,7 @@ cpus { #address-cells = <1>; #size-cells = <0>; - cpu@0 { + cpu: cpu@0 { compatible = "arm,cortex-a8"; enable-method = "ti,am3352"; device_type = "cpu"; @@ -338,7 +338,6 @@ mmc3: mmc@0 { compatible = "ti,am335-sdhci"; - ti,needs-special-reset; interrupts = <29>; reg = <0x0 0x1000>; status = "disabled"; diff --git a/arch/arm/boot/dts/ti/omap/am4372.dtsi b/arch/arm/boot/dts/ti/omap/am4372.dtsi index 0a1df30f2818b..504fa6b57d39b 100644 --- a/arch/arm/boot/dts/ti/omap/am4372.dtsi +++ b/arch/arm/boot/dts/ti/omap/am4372.dtsi @@ -321,7 +321,6 @@ mmc3: mmc@0 { compatible = "ti,am437-sdhci"; - ti,needs-special-reset; interrupts = ; reg = <0x0 0x1000>; status = "disabled"; diff --git a/arch/arm/boot/dts/ti/omap/am437x-l4.dtsi b/arch/arm/boot/dts/ti/omap/am437x-l4.dtsi index fd4634f8c6293..e08f356e71cb0 100644 --- a/arch/arm/boot/dts/ti/omap/am437x-l4.dtsi +++ b/arch/arm/boot/dts/ti/omap/am437x-l4.dtsi @@ -1103,7 +1103,6 @@ mmc1: mmc@0 { compatible = "ti,am437-sdhci"; reg = <0x0 0x1000>; - ti,needs-special-reset; dmas = <&edma 24 0>, <&edma 25 0>; dma-names = "tx", "rx"; @@ -1620,7 +1619,6 @@ mmc2: mmc@0 { compatible = "ti,am437-sdhci"; reg = <0x0 0x1000>; - ti,needs-special-reset; dmas = <&edma 2 0>, <&edma 3 0>; dma-names = "tx", "rx"; diff --git a/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts b/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts index e6a18954e449e..43cf4ade950b6 100644 --- a/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts +++ b/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts @@ -545,7 +545,6 @@ non-removable; mmc-pwrseq = <&emmc_pwrseq>; - ti,needs-special-reset; dmas = <&sdma_xbar 47>, <&sdma_xbar 48>; dma-names = "tx", "rx"; @@ -561,7 +560,6 @@ /* DDR50: DDR up to 50 MHz (1.8 V signaling). */ status = "okay"; - ti,needs-special-reset; vmmc-supply = <&vdd_3v3>; cap-power-off-card; keep-power-in-suspend; diff --git a/arch/arm/boot/dts/ti/omap/am57xx-cl-som-am57x.dts b/arch/arm/boot/dts/ti/omap/am57xx-cl-som-am57x.dts index 3dd898955e767..77c9fbb3bfbd8 100644 --- a/arch/arm/boot/dts/ti/omap/am57xx-cl-som-am57x.dts +++ b/arch/arm/boot/dts/ti/omap/am57xx-cl-som-am57x.dts @@ -481,7 +481,6 @@ vmmc-supply = <&vdd_3v3>; bus-width = <8>; ti,non-removable; - cap-mmc-dual-data-rate; }; &qspi { diff --git a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts index 08ee0f8ea68fd..71b39a923d37c 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts @@ -291,7 +291,7 @@ }; twl_power: power { - compatible = "ti,twl4030-power-beagleboard-xm", "ti,twl4030-power-idle-osc-off"; + compatible = "ti,twl4030-power-idle-osc-off"; ti,use_poweroff; }; }; diff --git a/arch/arm/boot/dts/ti/omap/omap3-n900.dts b/arch/arm/boot/dts/ti/omap/omap3-n900.dts index c50ca572d1b9b..7db73d9bed9e4 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-n900.dts +++ b/arch/arm/boot/dts/ti/omap/omap3-n900.dts @@ -508,7 +508,7 @@ }; twl_power: power { - compatible = "ti,twl4030-power-n900", "ti,twl4030-power-idle-osc-off"; + compatible = "ti,twl4030-power-idle-osc-off"; ti,use_poweroff; }; }; diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 3389a70e4d497..04ff75dcc20e7 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -1371,7 +1371,7 @@ static void sa1111_bus_remove(struct device *dev) drv->remove(sadev); } -struct bus_type sa1111_bus_type = { +const struct bus_type sa1111_bus_type = { .name = "sa1111-rab", .match = sa1111_match, .probe = sa1111_bus_probe, diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig index 134a559aba3dd..2367b1685c1cf 100644 --- a/arch/arm/configs/am200epdkit_defconfig +++ b/arch/arm/configs/am200epdkit_defconfig @@ -68,7 +68,6 @@ CONFIG_SOUND=m CONFIG_SND=m CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_VERBOSE_PROCFS is not set CONFIG_SND_PXA2XX_AC97=m CONFIG_USB_GADGET=y diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig index 28b724d59e7e2..45d8738abb750 100644 --- a/arch/arm/configs/aspeed_g4_defconfig +++ b/arch/arm/configs/aspeed_g4_defconfig @@ -117,7 +117,6 @@ CONFIG_KEYBOARD_GPIO_POLLED=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_RUNTIME_UARTS=6 diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig index 61cee1e7ebea6..2e6ea13c1e9be 100644 --- a/arch/arm/configs/aspeed_g5_defconfig +++ b/arch/arm/configs/aspeed_g5_defconfig @@ -138,7 +138,6 @@ CONFIG_SERIO_RAW=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_RUNTIME_UARTS=6 @@ -308,7 +307,7 @@ CONFIG_PANIC_ON_OOPS=y CONFIG_PANIC_TIMEOUT=-1 CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y -CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=1 CONFIG_WQ_WATCHDOG=y # CONFIG_SCHED_DEBUG is not set CONFIG_FUNCTION_TRACER=y diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig index ff13e1ecf4bb9..4f1153098b16f 100644 --- a/arch/arm/configs/at91_dt_defconfig +++ b/arch/arm/configs/at91_dt_defconfig @@ -181,7 +181,7 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_OF_AT91=y CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_SPI=y +CONFIG_MMC_SPI=m CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y diff --git a/arch/arm/configs/hisi_defconfig b/arch/arm/configs/hisi_defconfig index e19c1039fb938..384aade1a48bb 100644 --- a/arch/arm/configs/hisi_defconfig +++ b/arch/arm/configs/hisi_defconfig @@ -35,7 +35,6 @@ CONFIG_NETDEVICES=y CONFIG_HIX5HD2_GMAC=y CONFIG_HIP04_ETH=y CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=2 diff --git a/arch/arm/configs/lpc18xx_defconfig b/arch/arm/configs/lpc18xx_defconfig index 2d489186e945f..f142a6637edee 100644 --- a/arch/arm/configs/lpc18xx_defconfig +++ b/arch/arm/configs/lpc18xx_defconfig @@ -90,7 +90,6 @@ CONFIG_KEYBOARD_GPIO_POLLED=y # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_NONSTANDARD=y diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig index 2bddb0924a8c0..b9e2e603cd95e 100644 --- a/arch/arm/configs/lpc32xx_defconfig +++ b/arch/arm/configs/lpc32xx_defconfig @@ -113,7 +113,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_SOUND=y CONFIG_SND=y -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_VERBOSE_PROCFS is not set CONFIG_SND_DEBUG=y CONFIG_SND_DEBUG_VERBOSE=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 12f706e2ded54..7f1fa9dd88c92 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -281,6 +281,8 @@ CONFIG_TI_CPSW_SWITCHDEV=y CONFIG_TI_CPTS=y CONFIG_TI_KEYSTONE_NETCP=y CONFIG_TI_KEYSTONE_NETCP_ETHSS=y +CONFIG_TI_PRUSS=m +CONFIG_TI_PRUETH=m CONFIG_XILINX_EMACLITE=y CONFIG_SFP=m CONFIG_BROADCOM_PHY=y diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 3b08c63b6de4f..603fb003b2236 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -100,6 +100,8 @@ CONFIG_SND=y CONFIG_SND_SOC=y CONFIG_SND_MXS_SOC=y CONFIG_SND_SOC_MXS_SGTL5000=y +CONFIG_SND_SOC_TLV320AIC3X_I2C=y +CONFIG_SND_SIMPLE_CARD=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index dee820474f444..df88763fc7c3d 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig @@ -148,7 +148,6 @@ CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_VERBOSE_PROCFS is not set CONFIG_SND_DUMMY=y CONFIG_SND_USB_AUDIO=y diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index e4cb33b2bcee2..0085921833c3e 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -10,7 +10,6 @@ CONFIG_KEXEC=y CONFIG_ARCH_RENESAS=y CONFIG_PL310_ERRATA_588369=y CONFIG_SMP=y -CONFIG_SCHED_MC=y CONFIG_NR_CPUS=8 CONFIG_HIGHMEM=y CONFIG_ARM_APPENDED_DTB=y @@ -24,6 +23,7 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_CPUFREQ_DT=y CONFIG_VFP=y CONFIG_NEON=y +# CONFIG_SCHED_SMT is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_SLAB_FREELIST_HARDENED=y CONFIG_CMA=y @@ -75,7 +75,6 @@ CONFIG_INPUT_DA9063_ONKEY=y CONFIG_INPUT_ADXL34X=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set # CONFIG_SERIAL_8250_16550A_VARIANTS is not set CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_PCI is not set @@ -200,6 +199,7 @@ CONFIG_RZN1_DMAMUX=y CONFIG_RCAR_DMAC=y CONFIG_RENESAS_USB_DMAC=y CONFIG_RZ_DMAC=y +CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=1 # CONFIG_IOMMU_SUPPORT is not set CONFIG_IIO=y CONFIG_AK8975=y @@ -218,6 +218,7 @@ CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y CONFIG_ROOT_NFS=y +# CONFIG_RPCSEC_GSS_KRB5 is not set CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_DMA_CMA=y diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index ab477ca13f899..68aedaf92667a 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -219,7 +219,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y CONFIG_SOUND=y CONFIG_SND=y -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_DRIVERS is not set CONFIG_SND_HDA_TEGRA=y CONFIG_SND_HDA_INPUT_BEEP=y @@ -315,10 +314,6 @@ CONFIG_AK8975=y CONFIG_PWM=y CONFIG_PWM_TEGRA=y CONFIG_PHY_TEGRA_XUSB=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index a815f39b42439..90b6a832108dd 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -368,7 +368,7 @@ -extern struct bus_type sa1111_bus_type; +extern const struct bus_type sa1111_bus_type; #define SA1111_DEVID_SBI (1 << 0) #define SA1111_DEVID_SK (1 << 1) diff --git a/arch/arm/include/asm/word-at-a-time.h b/arch/arm/include/asm/word-at-a-time.h index f9a3897b06e7f..5023f98d8293d 100644 --- a/arch/arm/include/asm/word-at-a-time.h +++ b/arch/arm/include/asm/word-at-a-time.h @@ -67,7 +67,7 @@ static inline unsigned long find_zero(unsigned long mask) */ static inline unsigned long load_unaligned_zeropad(const void *addr) { - unsigned long ret, offset; + unsigned long ret, tmp; /* Load word from unaligned pointer addr */ asm( @@ -75,9 +75,9 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) "2:\n" " .pushsection .text.fixup,\"ax\"\n" " .align 2\n" - "3: and %1, %2, #0x3\n" - " bic %2, %2, #0x3\n" - " ldr %0, [%2]\n" + "3: bic %1, %2, #0x3\n" + " ldr %0, [%1]\n" + " and %1, %2, #0x3\n" " lsl %1, %1, #0x3\n" #ifndef __ARMEB__ " lsr %0, %0, %1\n" @@ -90,7 +90,7 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) " .align 3\n" " .long 1b, 3b\n" " .popsection" - : "=&r" (ret), "=&r" (offset) + : "=&r" (ret), "=&r" (tmp) : "r" (addr), "Qo" (*(unsigned long *)addr)); return ret; diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c index fd0dbeb93357d..cb7d8a7b14e0d 100644 --- a/arch/arm/mach-exynos/mcpm-exynos.c +++ b/arch/arm/mach-exynos/mcpm-exynos.c @@ -215,7 +215,7 @@ static const struct of_device_id exynos_dt_mcpm_match[] = { {}, }; -static void exynos_mcpm_setup_entry_point(void) +static void exynos_mcpm_setup_entry_point(void *data) { /* * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr @@ -228,10 +228,14 @@ static void exynos_mcpm_setup_entry_point(void) __raw_writel(__pa_symbol(mcpm_entry_point), ns_sram_base_addr + 8); } -static struct syscore_ops exynos_mcpm_syscore_ops = { +static const struct syscore_ops exynos_mcpm_syscore_ops = { .resume = exynos_mcpm_setup_entry_point, }; +static struct syscore exynos_mcpm_syscore = { + .ops = &exynos_mcpm_syscore_ops, +}; + static int __init exynos_mcpm_init(void) { struct device_node *node; @@ -300,9 +304,9 @@ static int __init exynos_mcpm_init(void) pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i)); } - exynos_mcpm_setup_entry_point(); + exynos_mcpm_setup_entry_point(NULL); - register_syscore_ops(&exynos_mcpm_syscore_ops); + register_syscore(&exynos_mcpm_syscore); return ret; } diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 150a1e56dcae9..22d723553f627 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -53,9 +53,9 @@ struct exynos_pm_data { void (*pm_prepare)(void); void (*pm_resume_prepare)(void); - void (*pm_resume)(void); - int (*pm_suspend)(void); int (*cpu_suspend)(unsigned long); + + const struct syscore_ops *syscore_ops; }; /* Used only on Exynos542x/5800 */ @@ -376,7 +376,7 @@ static void exynos5420_pm_prepare(void) } -static int exynos_pm_suspend(void) +static int exynos_pm_suspend(void *data) { exynos_pm_central_suspend(); @@ -390,7 +390,7 @@ static int exynos_pm_suspend(void) return 0; } -static int exynos5420_pm_suspend(void) +static int exynos5420_pm_suspend(void *data) { u32 this_cluster; @@ -408,7 +408,7 @@ static int exynos5420_pm_suspend(void) return 0; } -static void exynos_pm_resume(void) +static void exynos_pm_resume(void *data) { u32 cpuid = read_cpuid_part(); @@ -429,7 +429,7 @@ static void exynos_pm_resume(void) exynos_set_delayed_reset_assertion(true); } -static void exynos3250_pm_resume(void) +static void exynos3250_pm_resume(void *data) { u32 cpuid = read_cpuid_part(); @@ -473,7 +473,7 @@ static void exynos5420_prepare_pm_resume(void) } } -static void exynos5420_pm_resume(void) +static void exynos5420_pm_resume(void *data) { unsigned long tmp; @@ -596,41 +596,52 @@ static const struct platform_suspend_ops exynos_suspend_ops = { .valid = suspend_valid_only_mem, }; +static const struct syscore_ops exynos3250_syscore_ops = { + .suspend = exynos_pm_suspend, + .resume = exynos3250_pm_resume, +}; + static const struct exynos_pm_data exynos3250_pm_data = { .wkup_irq = exynos3250_wkup_irq, .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), - .pm_suspend = exynos_pm_suspend, - .pm_resume = exynos3250_pm_resume, .pm_prepare = exynos3250_pm_prepare, .cpu_suspend = exynos3250_cpu_suspend, + .syscore_ops = &exynos3250_syscore_ops, +}; + +static const struct syscore_ops exynos_syscore_ops = { + .suspend = exynos_pm_suspend, + .resume = exynos_pm_resume, }; static const struct exynos_pm_data exynos4_pm_data = { .wkup_irq = exynos4_wkup_irq, .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), - .pm_suspend = exynos_pm_suspend, - .pm_resume = exynos_pm_resume, .pm_prepare = exynos_pm_prepare, .cpu_suspend = exynos_cpu_suspend, + .syscore_ops = &exynos_syscore_ops, }; static const struct exynos_pm_data exynos5250_pm_data = { .wkup_irq = exynos5250_wkup_irq, .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), - .pm_suspend = exynos_pm_suspend, - .pm_resume = exynos_pm_resume, .pm_prepare = exynos_pm_prepare, .cpu_suspend = exynos_cpu_suspend, + .syscore_ops = &exynos_syscore_ops, +}; + +static const struct syscore_ops exynos5420_syscore_ops = { + .resume = exynos5420_pm_resume, + .suspend = exynos5420_pm_suspend, }; static const struct exynos_pm_data exynos5420_pm_data = { .wkup_irq = exynos5250_wkup_irq, .wake_disable_mask = (0x7F << 7) | (0x1F << 1), .pm_resume_prepare = exynos5420_prepare_pm_resume, - .pm_resume = exynos5420_pm_resume, - .pm_suspend = exynos5420_pm_suspend, .pm_prepare = exynos5420_pm_prepare, .cpu_suspend = exynos5420_cpu_suspend, + .syscore_ops = &exynos5420_syscore_ops, }; static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = { @@ -656,7 +667,7 @@ static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = { { /*sentinel*/ }, }; -static struct syscore_ops exynos_pm_syscore_ops; +static struct syscore exynos_pm_syscore; void __init exynos_pm_init(void) { @@ -684,10 +695,9 @@ void __init exynos_pm_init(void) tmp |= pm_data->wake_disable_mask; pmu_raw_writel(tmp, S5P_WAKEUP_MASK); - exynos_pm_syscore_ops.suspend = pm_data->pm_suspend; - exynos_pm_syscore_ops.resume = pm_data->pm_resume; + exynos_pm_syscore.ops = pm_data->syscore_ops; - register_syscore_ops(&exynos_pm_syscore_ops); + register_syscore(&exynos_pm_syscore); suspend_set_ops(&exynos_suspend_ops); /* diff --git a/arch/arm/mach-gemini/board-dt.c b/arch/arm/mach-gemini/board-dt.c index fbafe7475c028..2bba617e4d54a 100644 --- a/arch/arm/mach-gemini/board-dt.c +++ b/arch/arm/mach-gemini/board-dt.c @@ -34,7 +34,7 @@ static void gemini_idle(void) { /* * Because of broken hardware we have to enable interrupts or the CPU - * will never wakeup... Acctualy it is not very good to enable + * will never wakeup... Actually it is not very good to enable * interrupts first since scheduler can miss a tick, but there is * no other way around this. Platforms that needs it for power saving * should enable it in init code, since by default it is diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig index 638eabad2dd37..64ec487c13abd 100644 --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig @@ -19,6 +19,10 @@ config MACH_MT6572 bool "MediaTek MT6572 SoCs support" default ARCH_MEDIATEK +config MACH_MT6582 + bool "MediaTek MT6582 SoCs support" + default ARCH_MEDIATEK + config MACH_MT6589 bool "MediaTek MT6589 SoCs support" default ARCH_MEDIATEK diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c index 5c28124bd0078..fd3a8834fc4fd 100644 --- a/arch/arm/mach-mediatek/mediatek.c +++ b/arch/arm/mach-mediatek/mediatek.c @@ -39,6 +39,7 @@ static void __init mediatek_timer_init(void) static const char * const mediatek_board_dt_compat[] = { "mediatek,mt2701", "mediatek,mt6572", + "mediatek,mt6582", "mediatek,mt6589", "mediatek,mt6592", "mediatek,mt7623", diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c index bbd26d423bdef..6b0943d95555a 100644 --- a/arch/arm/mach-mediatek/platsmp.c +++ b/arch/arm/mach-mediatek/platsmp.c @@ -56,6 +56,7 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { static const struct of_device_id mtk_smp_boot_infos[] __initconst = { { .compatible = "mediatek,mt6572", .data = &mtk_mt6572_boot }, + { .compatible = "mediatek,mt6582", .data = &mtk_mt7623_boot }, { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot }, { .compatible = "mediatek,mt7623", .data = &mtk_mt7623_boot }, { .compatible = "mediatek,mt7629", .data = &mtk_mt7623_boot }, diff --git a/arch/arm/mach-omap1/ams-delta-fiq-handler.S b/arch/arm/mach-omap1/ams-delta-fiq-handler.S index 35c2f9574dbd5..5cf6fcca602ce 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq-handler.S +++ b/arch/arm/mach-omap1/ams-delta-fiq-handler.S @@ -97,7 +97,7 @@ ENTRY(qwerty_fiqin_start) ldr r13, [r12, #IRQ_ITR_REG_OFFSET] @ fetch interrupts status bics r13, r13, r11 @ clear masked - any left? - beq exit @ none - spurious FIQ? exit + beq .Lexit @ none - spurious FIQ? exit ldr r10, [r12, #IRQ_SIR_FIQ_REG_OFFSET] @ get requested interrupt number @@ -105,25 +105,25 @@ ENTRY(qwerty_fiqin_start) str r8, [r12, #IRQ_CONTROL_REG_OFFSET] cmp r10, #(INT_GPIO_BANK1 - NR_IRQS_LEGACY) @ is it GPIO interrupt? - beq gpio @ yes - process it + beq .Lgpio @ yes - process it mov r8, #1 orr r8, r11, r8, lsl r10 @ mask spurious interrupt str r8, [r12, #IRQ_MIR_REG_OFFSET] -exit: +.Lexit: subs pc, lr, #4 @ return from FIQ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@ -gpio: @ GPIO bank interrupt handler +.Lgpio: @ GPIO bank interrupt handler ldr r12, omap1510_gpio_base @ set base pointer to GPIO bank ldr r11, [r12, #OMAP1510_GPIO_INT_MASK] @ fetch GPIO interrupts mask -restart: +.Lrestart: ldr r13, [r12, #OMAP1510_GPIO_INT_STATUS] @ fetch status bits bics r13, r13, r11 @ clear masked - any left? - beq exit @ no - spurious interrupt? exit + beq .Lexit @ no - spurious interrupt? exit orr r11, r11, r13 @ mask all requested interrupts str r11, [r12, #OMAP1510_GPIO_INT_MASK] @@ -131,7 +131,7 @@ restart: str r13, [r12, #OMAP1510_GPIO_INT_STATUS] @ ack all requested interrupts ands r10, r13, #KEYBRD_CLK_MASK @ extract keyboard status - set? - beq hksw @ no - try next source + beq .Lhksw @ no - try next source @@@@@@@@@@@@@@@@@@@@@@ @@ -145,10 +145,10 @@ restart: ldr r10, [r9, #BUF_STATE] @ fetch kbd interface state cmp r10, #0 @ are we expecting start bit? - bne data @ no - go to data processing + bne .Ldata @ no - go to data processing ands r8, r8, #KEYBRD_DATA_MASK @ check start bit - detected? - beq hksw @ no - try next source + beq .Lhksw @ no - try next source @ r8 contains KEYBRD_DATA_MASK, use it str r8, [r9, #BUF_STATE] @ enter data processing state @@ -162,9 +162,9 @@ restart: mvn r11, #KEYBRD_CLK_MASK @ prepare all except kbd mask str r11, [r12, #OMAP1510_GPIO_INT_MASK] @ store into the mask register - b restart @ restart + b .Lrestart @ restart -data: ldr r10, [r9, #BUF_MASK] @ fetch current input bit mask +.Ldata: ldr r10, [r9, #BUF_MASK] @ fetch current input bit mask @ r8 still contains GPIO input bits ands r8, r8, #KEYBRD_DATA_MASK @ is keyboard data line low? @@ -175,7 +175,7 @@ data: ldr r10, [r9, #BUF_MASK] @ fetch current input bit mask mov r10, r10, lsl #1 @ shift mask left bics r10, r10, #0x800 @ have we got all the bits? strne r10, [r9, #BUF_MASK] @ not yet - store the mask - bne restart @ and restart + bne .Lrestart @ and restart @ r10 already contains 0, reuse it str r10, [r9, #BUF_STATE] @ reset state to start @@ -189,7 +189,7 @@ data: ldr r10, [r9, #BUF_MASK] @ fetch current input bit mask ldr r10, [r9, #BUF_KEYS_CNT] @ get saved keystrokes count ldr r8, [r9, #BUF_BUF_LEN] @ get buffer size cmp r10, r8 @ is buffer full? - beq hksw @ yes - key lost, next source + beq .Lhksw @ yes - key lost, next source add r10, r10, #1 @ incremet keystrokes counter str r10, [r9, #BUF_KEYS_CNT] @@ -213,9 +213,9 @@ data: ldr r10, [r9, #BUF_MASK] @ fetch current input bit mask @@@@@@@@@@@@@@@@@@@@@@@@ -hksw: @Is hook switch interrupt requested? +.Lhksw: @Is hook switch interrupt requested? tst r13, #HOOK_SWITCH_MASK @ is hook switch status bit set? - beq mdm @ no - try next source + beq .Lmdm @ no - try next source @@@@@@@@@@@@@@@@@@@@@@@@ @@ -230,9 +230,9 @@ hksw: @Is hook switch interrupt requested? @@@@@@@@@@@@@@@@@@@@@@@@ -mdm: @Is it a modem interrupt? +.Lmdm: @Is it a modem interrupt? tst r13, #MODEM_IRQ_MASK @ is modem status bit set? - beq irq @ no - check for next interrupt + beq .Lirq @ no - check for next interrupt @@@@@@@@@@@@@@@@@@@@@@@@ @@ -245,13 +245,13 @@ mdm: @Is it a modem interrupt? @@@@@@@@@@@@@@@@@@@@@@@@ -irq: @ Place deferred_fiq interrupt request +.Lirq: @ Place deferred_fiq interrupt request ldr r12, deferred_fiq_ih_base @ set pointer to IRQ handler mov r10, #DEFERRED_FIQ_MASK @ set deferred_fiq bit str r10, [r12, #IRQ_ISR_REG_OFFSET] @ place it in the ISR register ldr r12, omap1510_gpio_base @ set pointer back to GPIO bank - b restart @ check for next GPIO interrupt + b .Lrestart @ check for next GPIO interrupt @@@@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h index 2517c4a5a0e20..04b4ba0f59ab8 100644 --- a/arch/arm/mach-omap2/omap-secure.h +++ b/arch/arm/mach-omap2/omap-secure.h @@ -68,7 +68,7 @@ extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2, u32 arg3, u32 arg4); extern void omap_smccc_smc(u32 fn, u32 arg); extern void omap_smc1(u32 fn, u32 arg); -extern u32 omap_smc2(u32 id, u32 falg, u32 pargs); +extern u32 omap_smc2(u32 id, u32 flag, u32 pargs); extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs); extern int omap_secure_ram_reserve_memblock(void); extern u32 save_secure_ram_context(u32 args_pa); diff --git a/arch/arm/mach-omap2/omap-smc.S b/arch/arm/mach-omap2/omap-smc.S index 7376f528034db..fe3b5478200a4 100644 --- a/arch/arm/mach-omap2/omap-smc.S +++ b/arch/arm/mach-omap2/omap-smc.S @@ -32,7 +32,7 @@ ENTRY(_omap_smc1) ENDPROC(_omap_smc1) /** - * u32 omap_smc2(u32 id, u32 falg, u32 pargs) + * u32 omap_smc2(u32 id, u32 flag, u32 pargs) * Low level common routine for secure HAL and PPA APIs. * @id: Application ID of HAL APIs * @flag: Flag to indicate the criticality of operation diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index c9c2c46ecead0..caad4fca8de3e 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h @@ -34,9 +34,9 @@ extern void __init pxa27x_map_io(void); extern void __init pxa3xx_init_irq(void); extern void __init pxa3xx_map_io(void); -extern struct syscore_ops pxa_irq_syscore_ops; -extern struct syscore_ops pxa2xx_mfp_syscore_ops; -extern struct syscore_ops pxa3xx_mfp_syscore_ops; +extern struct syscore pxa_irq_syscore; +extern struct syscore pxa2xx_mfp_syscore; +extern struct syscore pxa3xx_mfp_syscore; void __init pxa_set_ffuart_info(void *info); void __init pxa_set_btuart_info(void *info); diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 5bfce8aa4102d..99acebbbf0653 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -178,7 +178,7 @@ void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int)) static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32]; static unsigned long saved_ipr[MAX_INTERNAL_IRQS]; -static int pxa_irq_suspend(void) +static int pxa_irq_suspend(void *data) { int i; @@ -197,7 +197,7 @@ static int pxa_irq_suspend(void) return 0; } -static void pxa_irq_resume(void) +static void pxa_irq_resume(void *data) { int i; @@ -219,11 +219,15 @@ static void pxa_irq_resume(void) #define pxa_irq_resume NULL #endif -struct syscore_ops pxa_irq_syscore_ops = { +static const struct syscore_ops pxa_irq_syscore_ops = { .suspend = pxa_irq_suspend, .resume = pxa_irq_resume, }; +struct syscore pxa_irq_syscore = { + .ops = &pxa_irq_syscore_ops, +}; + #ifdef CONFIG_OF static const struct of_device_id intc_ids[] __initconst = { { .compatible = "marvell,pxa-intc", }, diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index f5a3d890f682e..d1347055fbe4f 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -346,7 +346,7 @@ static unsigned long saved_gpdr[4]; static unsigned long saved_gplr[4]; static unsigned long saved_pgsr[4]; -static int pxa2xx_mfp_suspend(void) +static int pxa2xx_mfp_suspend(void *data) { int i; @@ -385,7 +385,7 @@ static int pxa2xx_mfp_suspend(void) return 0; } -static void pxa2xx_mfp_resume(void) +static void pxa2xx_mfp_resume(void *data) { int i; @@ -404,11 +404,15 @@ static void pxa2xx_mfp_resume(void) #define pxa2xx_mfp_resume NULL #endif -struct syscore_ops pxa2xx_mfp_syscore_ops = { +static const struct syscore_ops pxa2xx_mfp_syscore_ops = { .suspend = pxa2xx_mfp_suspend, .resume = pxa2xx_mfp_resume, }; +struct syscore pxa2xx_mfp_syscore = { + .ops = &pxa2xx_mfp_syscore_ops, +}; + static int __init pxa2xx_mfp_init(void) { int i; diff --git a/arch/arm/mach-pxa/mfp-pxa3xx.c b/arch/arm/mach-pxa/mfp-pxa3xx.c index d16ab7451efef..fe7498fbb62b3 100644 --- a/arch/arm/mach-pxa/mfp-pxa3xx.c +++ b/arch/arm/mach-pxa/mfp-pxa3xx.c @@ -27,13 +27,13 @@ * a pull-down mode if they're an active low chip select, and we're * just entering standby. */ -static int pxa3xx_mfp_suspend(void) +static int pxa3xx_mfp_suspend(void *data) { mfp_config_lpm(); return 0; } -static void pxa3xx_mfp_resume(void) +static void pxa3xx_mfp_resume(void *data) { mfp_config_run(); @@ -49,7 +49,11 @@ static void pxa3xx_mfp_resume(void) #define pxa3xx_mfp_resume NULL #endif -struct syscore_ops pxa3xx_mfp_syscore_ops = { +static const struct syscore_ops pxa3xx_mfp_syscore_ops = { .suspend = pxa3xx_mfp_suspend, .resume = pxa3xx_mfp_resume, }; + +struct syscore pxa3xx_mfp_syscore = { + .ops = &pxa3xx_mfp_syscore_ops, +}; diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 03e34841fc004..70509a5998142 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -235,8 +235,8 @@ static int __init pxa25x_init(void) pxa25x_init_pm(); - register_syscore_ops(&pxa_irq_syscore_ops); - register_syscore_ops(&pxa2xx_mfp_syscore_ops); + register_syscore(&pxa_irq_syscore); + register_syscore(&pxa2xx_mfp_syscore); if (!of_have_populated_dt()) { software_node_register(&pxa2xx_gpiochip_node); diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index f8382477d629e..ff63619790383 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -337,8 +337,8 @@ static int __init pxa27x_init(void) pxa27x_init_pm(); - register_syscore_ops(&pxa_irq_syscore_ops); - register_syscore_ops(&pxa2xx_mfp_syscore_ops); + register_syscore(&pxa_irq_syscore); + register_syscore(&pxa2xx_mfp_syscore); if (!of_have_populated_dt()) { software_node_register(&pxa2xx_gpiochip_node); diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 1d1e5713464dc..06c578ea658e3 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -424,8 +424,8 @@ static int __init pxa3xx_init(void) if (cpu_is_pxa320()) enable_irq_wake(IRQ_WAKEUP1); - register_syscore_ops(&pxa_irq_syscore_ops); - register_syscore_ops(&pxa3xx_mfp_syscore_ops); + register_syscore(&pxa_irq_syscore); + register_syscore(&pxa3xx_mfp_syscore); } return ret; diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c index 2d2a321d82f81..fb93a8f28356e 100644 --- a/arch/arm/mach-pxa/smemc.c +++ b/arch/arm/mach-pxa/smemc.c @@ -18,7 +18,7 @@ static unsigned long msc[2]; static unsigned long sxcnfg, memclkcfg; static unsigned long csadrcfg[4]; -static int pxa3xx_smemc_suspend(void) +static int pxa3xx_smemc_suspend(void *data) { msc[0] = __raw_readl(MSC0); msc[1] = __raw_readl(MSC1); @@ -32,7 +32,7 @@ static int pxa3xx_smemc_suspend(void) return 0; } -static void pxa3xx_smemc_resume(void) +static void pxa3xx_smemc_resume(void *data) { __raw_writel(msc[0], MSC0); __raw_writel(msc[1], MSC1); @@ -46,11 +46,15 @@ static void pxa3xx_smemc_resume(void) __raw_writel(0x2, CSMSADRCFG); } -static struct syscore_ops smemc_syscore_ops = { +static const struct syscore_ops smemc_syscore_ops = { .suspend = pxa3xx_smemc_suspend, .resume = pxa3xx_smemc_resume, }; +static struct syscore smemc_syscore = { + .ops = &smemc_syscore_ops, +}; + static int __init smemc_init(void) { if (cpu_is_pxa3xx()) { @@ -64,7 +68,7 @@ static int __init smemc_init(void) */ __raw_writel(0x2, CSMSADRCFG); - register_syscore_ops(&smemc_syscore_ops); + register_syscore(&smemc_syscore); } return 0; diff --git a/arch/arm/mach-s3c/irq-pm-s3c64xx.c b/arch/arm/mach-s3c/irq-pm-s3c64xx.c index 4a1e935bada19..ab726c595001d 100644 --- a/arch/arm/mach-s3c/irq-pm-s3c64xx.c +++ b/arch/arm/mach-s3c/irq-pm-s3c64xx.c @@ -58,7 +58,7 @@ static struct irq_grp_save { static u32 irq_uart_mask[SERIAL_SAMSUNG_UARTS]; -static int s3c64xx_irq_pm_suspend(void) +static int s3c64xx_irq_pm_suspend(void *data) { struct irq_grp_save *grp = eint_grp_save; int i; @@ -79,7 +79,7 @@ static int s3c64xx_irq_pm_suspend(void) return 0; } -static void s3c64xx_irq_pm_resume(void) +static void s3c64xx_irq_pm_resume(void *data) { struct irq_grp_save *grp = eint_grp_save; int i; @@ -100,18 +100,22 @@ static void s3c64xx_irq_pm_resume(void) S3C_PMDBG("%s: IRQ configuration restored\n", __func__); } -static struct syscore_ops s3c64xx_irq_syscore_ops = { +static const struct syscore_ops s3c64xx_irq_syscore_ops = { .suspend = s3c64xx_irq_pm_suspend, .resume = s3c64xx_irq_pm_resume, }; +static struct syscore s3c64xx_irq_syscore = { + .ops = &s3c64xx_irq_syscore_ops, +}; + static __init int s3c64xx_syscore_init(void) { /* Appropriate drivers (pinctrl, uart) handle this when using DT. */ if (of_have_populated_dt() || !soc_is_s3c64xx()) return 0; - register_syscore_ops(&s3c64xx_irq_syscore_ops); + register_syscore(&s3c64xx_irq_syscore); return 0; } diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c index 6fa70f787df4e..fa270750364cf 100644 --- a/arch/arm/mach-s5pv210/pm.c +++ b/arch/arm/mach-s5pv210/pm.c @@ -195,20 +195,24 @@ static const struct platform_suspend_ops s5pv210_suspend_ops = { /* * Syscore operations used to delay restore of certain registers. */ -static void s5pv210_pm_resume(void) +static void s5pv210_pm_resume(void *data) { s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save)); } -static struct syscore_ops s5pv210_pm_syscore_ops = { +static const struct syscore_ops s5pv210_pm_syscore_ops = { .resume = s5pv210_pm_resume, }; +static struct syscore s5pv210_pm_syscore = { + .ops = &s5pv210_pm_syscore_ops, +}; + /* * Initialization entry point. */ void __init s5pv210_pm_init(void) { - register_syscore_ops(&s5pv210_pm_syscore_ops); + register_syscore(&s5pv210_pm_syscore); suspend_set_ops(&s5pv210_suspend_ops); } diff --git a/arch/arm/mach-versatile/integrator_ap.c b/arch/arm/mach-versatile/integrator_ap.c index 4bd6712e9f525..ee90d6619d0db 100644 --- a/arch/arm/mach-versatile/integrator_ap.c +++ b/arch/arm/mach-versatile/integrator_ap.c @@ -63,13 +63,13 @@ static void __init ap_map_io(void) #ifdef CONFIG_PM static unsigned long ic_irq_enable; -static int irq_suspend(void) +static int irq_suspend(void *data) { ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE); return 0; } -static void irq_resume(void) +static void irq_resume(void *data) { /* disable all irq sources */ cm_clear_irqs(); @@ -83,14 +83,18 @@ static void irq_resume(void) #define irq_resume NULL #endif -static struct syscore_ops irq_syscore_ops = { +static const struct syscore_ops irq_syscore_ops = { .suspend = irq_suspend, .resume = irq_resume, }; +static struct syscore irq_syscore = { + .ops = &irq_syscore_ops, +}; + static int __init irq_syscore_init(void) { - register_syscore_ops(&irq_syscore_ops); + register_syscore(&irq_syscore); return 0; } diff --git a/arch/arm/mach-versatile/versatile.c b/arch/arm/mach-versatile/versatile.c index 7ef03d0c224d5..f0c80d4663ca5 100644 --- a/arch/arm/mach-versatile/versatile.c +++ b/arch/arm/mach-versatile/versatile.c @@ -134,7 +134,7 @@ static void __init versatile_dt_pci_init(void) val = readl(versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET); if (val & 1) { /* - * Enable PCI accesses. Note that the documentaton is + * Enable PCI accesses. Note that the documentation is * inconsistent whether or not this is needed, but the old * driver had it so we will keep it. */ diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 3c6ddb1afdc46..812380f30ae36 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -19,10 +19,11 @@ #include #include #include +#include #include #include -#include +#include #include #include "fault.h" @@ -809,6 +810,9 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) int thumb2_32b = 0; int fault; + if (addr >= TASK_SIZE && user_mode(regs)) + harden_branch_predictor(); + if (interrupts_enabled(regs)) local_irq_enable(); diff --git a/arch/arm/mm/cache-b15-rac.c b/arch/arm/mm/cache-b15-rac.c index 6f63b90f9e1ac..e7807356dfab0 100644 --- a/arch/arm/mm/cache-b15-rac.c +++ b/arch/arm/mm/cache-b15-rac.c @@ -256,7 +256,7 @@ static int b15_rac_dead_cpu(unsigned int cpu) return 0; } -static int b15_rac_suspend(void) +static int b15_rac_suspend(void *data) { /* Suspend the read-ahead cache oeprations, forcing our cache * implementation to fallback to the regular ARMv7 calls. @@ -271,7 +271,7 @@ static int b15_rac_suspend(void) return 0; } -static void b15_rac_resume(void) +static void b15_rac_resume(void *data) { /* Coming out of a S3 suspend/resume cycle, the read-ahead cache * register RAC_CONFIG0_REG will be restored to its default value, make @@ -282,11 +282,15 @@ static void b15_rac_resume(void) clear_bit(RAC_SUSPENDED, &b15_rac_flags); } -static struct syscore_ops b15_rac_syscore_ops = { +static const struct syscore_ops b15_rac_syscore_ops = { .suspend = b15_rac_suspend, .resume = b15_rac_resume, }; +static struct syscore b15_rac_syscore = { + .ops = &b15_rac_syscore_ops, +}; + static int __init b15_rac_init(void) { struct device_node *dn, *cpu_dn; @@ -347,7 +351,7 @@ static int __init b15_rac_init(void) } if (IS_ENABLED(CONFIG_PM_SLEEP)) - register_syscore_ops(&b15_rac_syscore_ops); + register_syscore(&b15_rac_syscore); spin_lock(&rac_lock); reg = __raw_readl(b15_rac_base + RAC_CONFIG0_REG); diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 08641a936394c..a4c765d24692a 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -624,16 +624,14 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr, kfree(buf); } -static void dma_cache_maint_page(struct page *page, unsigned long offset, - size_t size, enum dma_data_direction dir, +static void dma_cache_maint_page(phys_addr_t phys, size_t size, + enum dma_data_direction dir, void (*op)(const void *, size_t, int)) { - unsigned long pfn; + unsigned long offset = offset_in_page(phys); + unsigned long pfn = __phys_to_pfn(phys); size_t left = size; - pfn = page_to_pfn(page) + offset / PAGE_SIZE; - offset %= PAGE_SIZE; - /* * A single sg entry may refer to multiple physically contiguous * pages. But we still need to process highmem pages individually. @@ -644,17 +642,18 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, size_t len = left; void *vaddr; - page = pfn_to_page(pfn); - - if (PageHighMem(page)) { + phys = __pfn_to_phys(pfn); + if (PhysHighMem(phys)) { if (len + offset > PAGE_SIZE) len = PAGE_SIZE - offset; if (cache_is_vipt_nonaliasing()) { - vaddr = kmap_atomic(page); + vaddr = kmap_atomic_pfn(pfn); op(vaddr + offset, len, dir); kunmap_atomic(vaddr); } else { + struct page *page = phys_to_page(phys); + vaddr = kmap_high_get(page); if (vaddr) { op(vaddr + offset, len, dir); @@ -662,7 +661,8 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, } } } else { - vaddr = page_address(page) + offset; + phys += offset; + vaddr = phys_to_virt(phys); op(vaddr, len, dir); } offset = 0; @@ -676,14 +676,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, * Note: Drivers should NOT use this function directly. * Use the driver DMA support - see dma-mapping.h (dma_sync_*) */ -static void __dma_page_cpu_to_dev(struct page *page, unsigned long off, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { - phys_addr_t paddr; + dma_cache_maint_page(paddr, size, dir, dmac_map_area); - dma_cache_maint_page(page, off, size, dir, dmac_map_area); - - paddr = page_to_phys(page) + off; if (dir == DMA_FROM_DEVICE) { outer_inv_range(paddr, paddr + size); } else { @@ -692,17 +689,15 @@ static void __dma_page_cpu_to_dev(struct page *page, unsigned long off, /* FIXME: non-speculating: flush on bidirectional mappings? */ } -static void __dma_page_dev_to_cpu(struct page *page, unsigned long off, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { - phys_addr_t paddr = page_to_phys(page) + off; - /* FIXME: non-speculating: not required */ /* in any case, don't bother invalidating if DMA to device */ if (dir != DMA_TO_DEVICE) { outer_inv_range(paddr, paddr + size); - dma_cache_maint_page(page, off, size, dir, dmac_unmap_area); + dma_cache_maint_page(paddr, size, dir, dmac_unmap_area); } /* @@ -737,6 +732,9 @@ static int __dma_info_to_prot(enum dma_data_direction dir, unsigned long attrs) if (attrs & DMA_ATTR_PRIVILEGED) prot |= IOMMU_PRIV; + if (attrs & DMA_ATTR_MMIO) + prot |= IOMMU_MMIO; + switch (dir) { case DMA_BIDIRECTIONAL: return prot | IOMMU_READ | IOMMU_WRITE; @@ -1205,7 +1203,7 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg, unsigned int len = PAGE_ALIGN(s->offset + s->length); if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir); + arch_sync_dma_for_device(sg_phys(s), s->length, dir); prot = __dma_info_to_prot(dir, attrs); @@ -1307,8 +1305,7 @@ static void arm_iommu_unmap_sg(struct device *dev, __iommu_remove_mapping(dev, sg_dma_address(s), sg_dma_len(s)); if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - __dma_page_dev_to_cpu(sg_page(s), s->offset, - s->length, dir); + arch_sync_dma_for_cpu(sg_phys(s), s->length, dir); } } @@ -1330,7 +1327,7 @@ static void arm_iommu_sync_sg_for_cpu(struct device *dev, return; for_each_sg(sg, s, nents, i) - __dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir); + arch_sync_dma_for_cpu(sg_phys(s), s->length, dir); } @@ -1352,29 +1349,31 @@ static void arm_iommu_sync_sg_for_device(struct device *dev, return; for_each_sg(sg, s, nents, i) - __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir); + arch_sync_dma_for_device(sg_phys(s), s->length, dir); } /** - * arm_iommu_map_page + * arm_iommu_map_phys * @dev: valid struct device pointer - * @page: page that buffer resides in - * @offset: offset into page for start of buffer + * @phys: physical address that buffer resides in * @size: size of buffer to map * @dir: DMA transfer direction + * @attrs: DMA mapping attributes * * IOMMU aware version of arm_dma_map_page() */ -static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, enum dma_data_direction dir, - unsigned long attrs) +static dma_addr_t arm_iommu_map_phys(struct device *dev, phys_addr_t phys, + size_t size, enum dma_data_direction dir, unsigned long attrs) { struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); + int len = PAGE_ALIGN(size + offset_in_page(phys)); + phys_addr_t addr = phys & PAGE_MASK; dma_addr_t dma_addr; - int ret, prot, len = PAGE_ALIGN(size + offset); + int ret, prot; - if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - __dma_page_cpu_to_dev(page, offset, size, dir); + if (!dev->dma_coherent && + !(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO))) + arch_sync_dma_for_device(phys, size, dir); dma_addr = __alloc_iova(mapping, len); if (dma_addr == DMA_MAPPING_ERROR) @@ -1382,12 +1381,11 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page, prot = __dma_info_to_prot(dir, attrs); - ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, - prot, GFP_KERNEL); + ret = iommu_map(mapping->domain, dma_addr, addr, len, prot, GFP_KERNEL); if (ret < 0) goto fail; - return dma_addr + offset; + return dma_addr + offset_in_page(phys); fail: __free_iova(mapping, dma_addr, len); return DMA_MAPPING_ERROR; @@ -1399,82 +1397,27 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page, * @handle: DMA address of buffer * @size: size of buffer (same as passed to dma_map_page) * @dir: DMA transfer direction (same as passed to dma_map_page) + * @attrs: DMA mapping attributes * - * IOMMU aware version of arm_dma_unmap_page() + * IOMMU aware version of arm_dma_unmap_phys() */ -static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle, +static void arm_iommu_unmap_phys(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir, unsigned long attrs) { struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); dma_addr_t iova = handle & PAGE_MASK; - struct page *page; int offset = handle & ~PAGE_MASK; int len = PAGE_ALIGN(size + offset); if (!iova) return; - if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) { - page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova)); - __dma_page_dev_to_cpu(page, offset, size, dir); - } - - iommu_unmap(mapping->domain, iova, len); - __free_iova(mapping, iova, len); -} - -/** - * arm_iommu_map_resource - map a device resource for DMA - * @dev: valid struct device pointer - * @phys_addr: physical address of resource - * @size: size of resource to map - * @dir: DMA transfer direction - */ -static dma_addr_t arm_iommu_map_resource(struct device *dev, - phys_addr_t phys_addr, size_t size, - enum dma_data_direction dir, unsigned long attrs) -{ - struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); - dma_addr_t dma_addr; - int ret, prot; - phys_addr_t addr = phys_addr & PAGE_MASK; - unsigned int offset = phys_addr & ~PAGE_MASK; - size_t len = PAGE_ALIGN(size + offset); - - dma_addr = __alloc_iova(mapping, len); - if (dma_addr == DMA_MAPPING_ERROR) - return dma_addr; - - prot = __dma_info_to_prot(dir, attrs) | IOMMU_MMIO; - - ret = iommu_map(mapping->domain, dma_addr, addr, len, prot, GFP_KERNEL); - if (ret < 0) - goto fail; - - return dma_addr + offset; -fail: - __free_iova(mapping, dma_addr, len); - return DMA_MAPPING_ERROR; -} + if (!dev->dma_coherent && + !(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO))) { + phys_addr_t phys = iommu_iova_to_phys(mapping->domain, iova); -/** - * arm_iommu_unmap_resource - unmap a device DMA resource - * @dev: valid struct device pointer - * @dma_handle: DMA address to resource - * @size: size of resource to map - * @dir: DMA transfer direction - */ -static void arm_iommu_unmap_resource(struct device *dev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction dir, - unsigned long attrs) -{ - struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); - dma_addr_t iova = dma_handle & PAGE_MASK; - unsigned int offset = dma_handle & ~PAGE_MASK; - size_t len = PAGE_ALIGN(size + offset); - - if (!iova) - return; + arch_sync_dma_for_cpu(phys + offset, size, dir); + } iommu_unmap(mapping->domain, iova, len); __free_iova(mapping, iova, len); @@ -1485,14 +1428,14 @@ static void arm_iommu_sync_single_for_cpu(struct device *dev, { struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); dma_addr_t iova = handle & PAGE_MASK; - struct page *page; unsigned int offset = handle & ~PAGE_MASK; + phys_addr_t phys; if (dev->dma_coherent || !iova) return; - page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova)); - __dma_page_dev_to_cpu(page, offset, size, dir); + phys = iommu_iova_to_phys(mapping->domain, iova); + arch_sync_dma_for_cpu(phys + offset, size, dir); } static void arm_iommu_sync_single_for_device(struct device *dev, @@ -1500,14 +1443,14 @@ static void arm_iommu_sync_single_for_device(struct device *dev, { struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); dma_addr_t iova = handle & PAGE_MASK; - struct page *page; unsigned int offset = handle & ~PAGE_MASK; + phys_addr_t phys; if (dev->dma_coherent || !iova) return; - page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova)); - __dma_page_cpu_to_dev(page, offset, size, dir); + phys = iommu_iova_to_phys(mapping->domain, iova); + arch_sync_dma_for_device(phys + offset, size, dir); } static const struct dma_map_ops iommu_ops = { @@ -1516,8 +1459,8 @@ static const struct dma_map_ops iommu_ops = { .mmap = arm_iommu_mmap_attrs, .get_sgtable = arm_iommu_get_sgtable, - .map_page = arm_iommu_map_page, - .unmap_page = arm_iommu_unmap_page, + .map_phys = arm_iommu_map_phys, + .unmap_phys = arm_iommu_unmap_phys, .sync_single_for_cpu = arm_iommu_sync_single_for_cpu, .sync_single_for_device = arm_iommu_sync_single_for_device, @@ -1525,9 +1468,6 @@ static const struct dma_map_ops iommu_ops = { .unmap_sg = arm_iommu_unmap_sg, .sync_sg_for_cpu = arm_iommu_sync_sg_for_cpu, .sync_sg_for_device = arm_iommu_sync_sg_for_device, - - .map_resource = arm_iommu_map_resource, - .unmap_resource = arm_iommu_unmap_resource, }; /** @@ -1794,20 +1734,6 @@ void arch_teardown_dma_ops(struct device *dev) set_dma_ops(dev, NULL); } -void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, - enum dma_data_direction dir) -{ - __dma_page_cpu_to_dev(phys_to_page(paddr), paddr & (PAGE_SIZE - 1), - size, dir); -} - -void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, - enum dma_data_direction dir) -{ - __dma_page_dev_to_cpu(phys_to_page(paddr), paddr & (PAGE_SIZE - 1), - size, dir); -} - void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 2bc828a1940c0..ed4330cc3f4e6 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -128,6 +128,19 @@ static inline bool is_translation_fault(unsigned int fsr) return false; } +static inline bool is_permission_fault(unsigned int fsr) +{ + int fs = fsr_fs(fsr); +#ifdef CONFIG_ARM_LPAE + if ((fs & FS_MMU_NOLL_MASK) == FS_PERM_NOLL) + return true; +#else + if (fs == FS_L1_PERM || fs == FS_L2_PERM) + return true; +#endif + return false; +} + static void die_kernel_fault(const char *msg, struct mm_struct *mm, unsigned long addr, unsigned int fsr, struct pt_regs *regs) @@ -162,6 +175,8 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, */ if (addr < PAGE_SIZE) { msg = "NULL pointer dereference"; + } else if (is_permission_fault(fsr) && fsr & FSR_LNX_PF) { + msg = "execution of memory"; } else { if (is_translation_fault(fsr) && kfence_handle_page_fault(addr, is_write_fault(fsr), regs)) @@ -183,9 +198,6 @@ __do_user_fault(unsigned long addr, unsigned int fsr, unsigned int sig, { struct task_struct *tsk = current; - if (addr > TASK_SIZE) - harden_branch_predictor(); - #ifdef CONFIG_DEBUG_USER if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) || ((user_debug & UDBG_BUS) && (sig == SIGBUS))) { @@ -225,19 +237,6 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) } #ifdef CONFIG_MMU -static inline bool is_permission_fault(unsigned int fsr) -{ - int fs = fsr_fs(fsr); -#ifdef CONFIG_ARM_LPAE - if ((fs & FS_MMU_NOLL_MASK) == FS_PERM_NOLL) - return true; -#else - if (fs == FS_L1_PERM || fs == FS_L2_PERM) - return true; -#endif - return false; -} - #ifdef CONFIG_CPU_TTBR0_PAN static inline bool ttbr0_usermode_access_allowed(struct pt_regs *regs) { @@ -259,6 +258,37 @@ static inline bool ttbr0_usermode_access_allowed(struct pt_regs *regs) } #endif +static int __kprobes +do_kernel_address_page_fault(struct mm_struct *mm, unsigned long addr, + unsigned int fsr, struct pt_regs *regs) +{ + if (user_mode(regs)) { + /* + * Fault from user mode for a kernel space address. User mode + * should not be faulting in kernel space, which includes the + * vector/khelper page. Handle the branch predictor hardening + * while interrupts are still disabled, then send a SIGSEGV. + */ + harden_branch_predictor(); + __do_user_fault(addr, fsr, SIGSEGV, SEGV_MAPERR, regs); + } else { + /* + * Fault from kernel mode. Enable interrupts if they were + * enabled in the parent context. Section (upper page table) + * translation faults are handled via do_translation_fault(), + * so we will only get here for a non-present kernel space + * PTE or PTE permission fault. This may happen in exceptional + * circumstances and need the fixup tables to be walked. + */ + if (interrupts_enabled(regs)) + local_irq_enable(); + + __do_kernel_fault(mm, addr, fsr, regs); + } + + return 0; +} + static int __kprobes do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { @@ -272,6 +302,12 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (kprobe_page_fault(regs, fsr)) return 0; + /* + * Handle kernel addresses faults separately, which avoids touching + * the mmap lock from contexts that are not able to sleep. + */ + if (addr >= TASK_SIZE) + return do_kernel_address_page_fault(mm, addr, fsr, regs); /* Enable interrupts if they were enabled in the parent context. */ if (interrupts_enabled(regs)) @@ -448,16 +484,20 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) * We enter here because the first level page table doesn't contain * a valid entry for the address. * - * If the address is in kernel space (>= TASK_SIZE), then we are - * probably faulting in the vmalloc() area. + * If this is a user address (addr < TASK_SIZE), we handle this as a + * normal page fault. This leaves the remainder of the function to handle + * kernel address translation faults. + * + * Since user mode is not permitted to access kernel addresses, pass these + * directly to do_kernel_address_page_fault() to handle. * - * If the init_task's first level page tables contains the relevant - * entry, we copy the it to this task. If not, we send the process - * a signal, fixup the exception, or oops the kernel. + * Otherwise, we're probably faulting in the vmalloc() area, so try to fix + * that up. Note that we must not take any locks or enable interrupts in + * this case. * - * NOTE! We MUST NOT take any locks for this case. We may be in an - * interrupt or a critical region, and should only copy the information - * from the master page table, nothing more. + * If vmalloc() fixup fails, that means the non-leaf page tables did not + * contain an entry for this address, so handle this via + * do_kernel_address_page_fault(). */ #ifdef CONFIG_MMU static int __kprobes @@ -523,7 +563,8 @@ do_translation_fault(unsigned long addr, unsigned int fsr, return 0; bad_area: - do_bad_area(addr, fsr, regs); + do_kernel_address_page_fault(current->mm, addr, fsr, regs); + return 0; } #else /* CONFIG_MMU */ @@ -543,7 +584,16 @@ do_translation_fault(unsigned long addr, unsigned int fsr, static int do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { + /* + * If this is a kernel address, but from user mode, then userspace + * is trying bad stuff. Invoke the branch predictor handling. + * Interrupts are disabled here. + */ + if (addr >= TASK_SIZE && user_mode(regs)) + harden_branch_predictor(); + do_bad_area(addr, fsr, regs); + return 0; } #endif /* CONFIG_ARM_LPAE */ diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 65db12f66b8f7..93173f0a09c7d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -21,6 +21,7 @@ config ARM64 select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE select ARCH_HAS_CACHE_LINE_SIZE select ARCH_HAS_CC_PLATFORM + select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION select ARCH_HAS_CURRENT_STACK_POINTER select ARCH_HAS_DEBUG_VIRTUAL select ARCH_HAS_DEBUG_VM_PGTABLE @@ -148,6 +149,7 @@ config ARM64 select GENERIC_ARCH_TOPOLOGY select GENERIC_CLOCKEVENTS_BROADCAST select GENERIC_CPU_AUTOPROBE + select GENERIC_CPU_CACHE_MAINTENANCE select GENERIC_CPU_DEVICES select GENERIC_CPU_VULNERABILITIES select GENERIC_EARLY_IOREMAP diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 13173795c43d4..fff14807c965a 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -119,6 +119,14 @@ config ARCH_BLAIZE help This enables support for the Blaize SoC family +config ARCH_BST + bool "Black Sesame Technologies SoC Family" + help + This enables support for Black Sesame Technologies (BST) SoC family. + BST produces automotive-grade system-on-chips for intelligent driving, + focusing on computer vision and AI capabilities. The BST C1200 family + includes SoCs for ADAS and autonomous driving applications. + config ARCH_CIX bool "Cixtech SoC family" help @@ -316,6 +324,7 @@ config ARCH_QCOM select GPIOLIB select PINCTRL select HAVE_PWRCTRL if PCI + select HAVE_SHARED_GPIOS help This enables support for the ARMv8 based Qualcomm chipsets. diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index b0844404eda18..98ec8f1b76e47 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -13,6 +13,7 @@ subdir-y += axiado subdir-y += bitmain subdir-y += blaize subdir-y += broadcom +subdir-y += bst subdir-y += cavium subdir-y += cix subdir-y += exynos diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi index ceedae9e399b6..8d1110c14bad2 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi @@ -304,6 +304,42 @@ bias-pull-up; }; + /omit-if-no-ref/ + nand_pins: nand-pins { + pins = "PC0", "PC1", "PC2", "PC5", "PC8", "PC9", + "PC10", "PC11", "PC12", "PC13", "PC14", + "PC15", "PC16"; + function = "nand0"; + }; + + /omit-if-no-ref/ + nand_cs0_pin: nand-cs0-pin { + pins = "PC4"; + function = "nand0"; + bias-pull-up; + }; + + /omit-if-no-ref/ + nand_cs1_pin: nand-cs1-pin { + pins = "PC3"; + function = "nand0"; + bias-pull-up; + }; + + /omit-if-no-ref/ + nand_rb0_pin: nand-rb0-pin { + pins = "PC6"; + function = "nand0"; + bias-pull-up; + }; + + /omit-if-no-ref/ + nand_rb1_pin: nand-rb1-pin { + pins = "PC7"; + function = "nand0"; + bias-pull-up; + }; + /omit-if-no-ref/ spi0_pins: spi0-pins { pins = "PC0", "PC2", "PC4"; @@ -377,6 +413,22 @@ #iommu-cells = <1>; }; + nfc: nand-controller@4011000 { + compatible = "allwinner,sun50i-h616-nand-controller"; + reg = <0x04011000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_NAND>, <&ccu CLK_NAND0>, + <&ccu CLK_NAND1>, <&ccu CLK_MBUS_NAND>; + clock-names = "ahb", "mod", "ecc", "mbus"; + resets = <&ccu RST_BUS_NAND>; + reset-names = "ahb"; + dmas = <&dma 10>; + dma-names = "rxtx"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + mmc0: mmc@4020000 { compatible = "allwinner,sun50i-h616-mmc", "allwinner,sun50i-a100-mmc"; diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi index 7b36c47a3a139..42dab01e3f56b 100644 --- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi @@ -145,6 +145,14 @@ interrupt-controller; #interrupt-cells = <3>; + /omit-if-no-ref/ + i2s2_pi_pins: i2s2-pi-pins { + pins = "PI2", "PI3", "PI4", "PI5"; + allwinner,pinmux = <5>; + function = "i2s2"; + bias-disable; + }; + mmc0_pins: mmc0-pins { pins = "PF0" ,"PF1", "PF2", "PF3", "PF4", "PF5"; allwinner,pinmux = <2>; @@ -182,6 +190,30 @@ bias-disable; }; + rgmii1_pins: rgmii1-pins { + pins = "PJ0", "PJ1", "PJ2", "PJ3", "PJ4", + "PJ5", "PJ6", "PJ7", "PJ8", "PJ9", + "PJ11", "PJ12", "PJ13", "PJ14", "PJ15"; + allwinner,pinmux = <5>; + function = "gmac1"; + drive-strength = <40>; + bias-disable; + }; + + /omit-if-no-ref/ + spdif_out_pb_pin: spdif-pb-pin { + pins = "PB8"; + function = "spdif"; + allwinner,pinmux = <2>; + }; + + /omit-if-no-ref/ + spdif_out_pi_pin: spdif-pi-pin { + pins = "PI10"; + function = "spdif"; + allwinner,pinmux = <2>; + }; + uart0_pb_pins: uart0-pb-pins { pins = "PB9", "PB10"; allwinner,pinmux = <2>; @@ -231,6 +263,8 @@ reg-io-width = <4>; clocks = <&ccu CLK_BUS_UART0>; resets = <&ccu RST_BUS_UART0>; + dmas = <&dma 14>, <&dma 14>; + dma-names = "tx", "rx"; status = "disabled"; }; @@ -242,6 +276,8 @@ reg-io-width = <4>; clocks = <&ccu CLK_BUS_UART1>; resets = <&ccu RST_BUS_UART1>; + dmas = <&dma 15>, <&dma 15>; + dma-names = "tx", "rx"; status = "disabled"; }; @@ -253,6 +289,8 @@ reg-io-width = <4>; clocks = <&ccu CLK_BUS_UART2>; resets = <&ccu RST_BUS_UART2>; + dmas = <&dma 16>, <&dma 16>; + dma-names = "tx", "rx"; status = "disabled"; }; @@ -264,6 +302,8 @@ reg-io-width = <4>; clocks = <&ccu CLK_BUS_UART3>; resets = <&ccu RST_BUS_UART3>; + dmas = <&dma 17>, <&dma 17>; + dma-names = "tx", "rx"; status = "disabled"; }; @@ -275,6 +315,8 @@ reg-io-width = <4>; clocks = <&ccu CLK_BUS_UART4>; resets = <&ccu RST_BUS_UART4>; + dmas = <&dma 18>, <&dma 18>; + dma-names = "tx", "rx"; status = "disabled"; }; @@ -286,6 +328,8 @@ reg-io-width = <4>; clocks = <&ccu CLK_BUS_UART5>; resets = <&ccu RST_BUS_UART5>; + dmas = <&dma 19>, <&dma 19>; + dma-names = "tx", "rx"; status = "disabled"; }; @@ -297,6 +341,8 @@ reg-io-width = <4>; clocks = <&ccu CLK_BUS_UART6>; resets = <&ccu RST_BUS_UART6>; + dmas = <&dma 20>, <&dma 20>; + dma-names = "tx", "rx"; status = "disabled"; }; @@ -308,6 +354,8 @@ reg-io-width = <4>; clocks = <&ccu CLK_BUS_UART7>; resets = <&ccu RST_BUS_UART7>; + dmas = <&dma 21>, <&dma 21>; + dma-names = "tx", "rx"; status = "disabled"; }; @@ -319,6 +367,8 @@ interrupts = ; clocks = <&ccu CLK_BUS_I2C0>; resets = <&ccu RST_BUS_I2C0>; + dmas = <&dma 43>, <&dma 43>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -332,6 +382,8 @@ interrupts = ; clocks = <&ccu CLK_BUS_I2C1>; resets = <&ccu RST_BUS_I2C1>; + dmas = <&dma 44>, <&dma 44>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -345,6 +397,8 @@ interrupts = ; clocks = <&ccu CLK_BUS_I2C2>; resets = <&ccu RST_BUS_I2C2>; + dmas = <&dma 45>, <&dma 45>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -358,6 +412,8 @@ interrupts = ; clocks = <&ccu CLK_BUS_I2C3>; resets = <&ccu RST_BUS_I2C3>; + dmas = <&dma 46>, <&dma 46>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -371,6 +427,8 @@ interrupts = ; clocks = <&ccu CLK_BUS_I2C4>; resets = <&ccu RST_BUS_I2C4>; + dmas = <&dma 47>, <&dma 47>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -384,6 +442,8 @@ interrupts = ; clocks = <&ccu CLK_BUS_I2C5>; resets = <&ccu RST_BUS_I2C5>; + dmas = <&dma 48>, <&dma 48>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -398,6 +458,19 @@ ranges; }; + dma: dma-controller@3002000 { + compatible = "allwinner,sun55i-a523-dma", + "allwinner,sun50i-a100-dma"; + reg = <0x03002000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>; + clock-names = "bus", "mbus"; + dma-channels = <16>; + dma-requests = <54>; + resets = <&ccu RST_BUS_DMA>; + #dma-cells = <1>; + }; + sid: efuse@3006000 { compatible = "allwinner,sun55i-a523-sid", "allwinner,sun50i-a64-sid"; @@ -603,6 +676,51 @@ }; }; + gmac1: ethernet@4510000 { + compatible = "allwinner,sun55i-a523-gmac200", + "snps,dwmac-4.20a"; + reg = <0x04510000 0x10000>; + clocks = <&ccu CLK_BUS_EMAC1>, <&ccu CLK_MBUS_EMAC1>; + clock-names = "stmmaceth", "mbus"; + resets = <&ccu RST_BUS_EMAC1>; + reset-names = "stmmaceth"; + interrupts = ; + interrupt-names = "macirq"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii1_pins>; + power-domains = <&pck600 PD_VO1>; + syscon = <&syscon>; + snps,fixed-burst; + snps,axi-config = <&gmac1_stmmac_axi_setup>; + snps,mtl-rx-config = <&gmac1_mtl_rx_setup>; + snps,mtl-tx-config = <&gmac1_mtl_tx_setup>; + status = "disabled"; + + mdio1: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + + gmac1_mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <1>; + + queue0 {}; + }; + + gmac1_stmmac_axi_setup: stmmac-axi-config { + snps,wr_osr_lmt = <0xf>; + snps,rd_osr_lmt = <0xf>; + snps,blen = <256 128 64 32 16 8 4>; + }; + + gmac1_mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <1>; + + queue0 {}; + }; + }; + ppu: power-controller@7001400 { compatible = "allwinner,sun55i-a523-ppu"; reg = <0x07001400 0x400>; @@ -674,6 +792,8 @@ reg = <0x07081400 0x400>; interrupts = ; clocks = <&r_ccu CLK_BUS_R_I2C0>; + dmas = <&dma 49>, <&dma 49>; + dma-names = "rx", "tx"; resets = <&r_ccu RST_BUS_R_I2C0>; pinctrl-names = "default"; pinctrl-0 = <&r_i2c_pins>; @@ -720,6 +840,90 @@ #reset-cells = <1>; }; + i2s0: i2s@7112000 { + compatible = "allwinner,sun55i-a523-i2s", + "allwinner,sun50i-r329-i2s"; + reg = <0x07112000 0x1000>; + interrupts = ; + clocks = <&mcu_ccu CLK_BUS_MCU_I2S0>, <&mcu_ccu CLK_MCU_I2S0>; + clock-names = "apb", "mod"; + resets = <&mcu_ccu RST_BUS_MCU_I2S0>; + dmas = <&mcu_dma 3>, <&mcu_dma 3>; + dma-names = "rx", "tx"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s1: i2s@7113000 { + compatible = "allwinner,sun55i-a523-i2s", + "allwinner,sun50i-r329-i2s"; + reg = <0x07113000 0x1000>; + interrupts = ; + clocks = <&mcu_ccu CLK_BUS_MCU_I2S1>, <&mcu_ccu CLK_MCU_I2S1>; + clock-names = "apb", "mod"; + resets = <&mcu_ccu RST_BUS_MCU_I2S1>; + dmas = <&mcu_dma 4>, <&mcu_dma 4>; + dma-names = "rx", "tx"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s2: i2s@7114000 { + compatible = "allwinner,sun55i-a523-i2s", + "allwinner,sun50i-r329-i2s"; + reg = <0x07114000 0x1000>; + interrupts = ; + clocks = <&mcu_ccu CLK_BUS_MCU_I2S2>, <&mcu_ccu CLK_MCU_I2S2>; + clock-names = "apb", "mod"; + resets = <&mcu_ccu RST_BUS_MCU_I2S2>; + dmas = <&mcu_dma 5>, <&mcu_dma 5>; + dma-names = "rx", "tx"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s3: i2s@7115000 { + compatible = "allwinner,sun55i-a523-i2s", + "allwinner,sun50i-r329-i2s"; + reg = <0x07115000 0x1000>; + interrupts = ; + clocks = <&mcu_ccu CLK_BUS_MCU_I2S3>, <&mcu_ccu CLK_MCU_I2S3>; + clock-names = "apb", "mod"; + resets = <&mcu_ccu RST_BUS_MCU_I2S3>; + dmas = <&mcu_dma 6>, <&mcu_dma 6>; + dma-names = "rx", "tx"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + spdif: spdif@7116000 { + compatible = "allwinner,sun55i-a523-spdif"; + reg = <0x07116000 0x400>; + interrupts = ; + clocks = <&mcu_ccu CLK_BUS_MCU_SPDIF>, + <&mcu_ccu CLK_MCU_SPDIF_TX>, + <&mcu_ccu CLK_MCU_SPDIF_RX>; + clock-names = "apb", "tx", "rx"; + resets = <&mcu_ccu RST_BUS_MCU_SPDIF>; + dmas = <&mcu_dma 2>, <&mcu_dma 2>; + dma-names = "rx", "tx"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + mcu_dma: dma-controller@7121000 { + compatible = "allwinner,sun55i-a523-mcu-dma", + "allwinner,sun50i-a100-dma"; + reg = <0x07121000 0x1000>; + interrupts = ; + clocks = <&mcu_ccu CLK_BUS_MCU_DMA>, <&mcu_ccu CLK_MCU_MBUS_DMA>; + clock-names = "bus", "mbus"; + dma-channels = <16>; + dma-requests = <15>; + resets = <&mcu_ccu RST_BUS_MCU_DMA>; + #dma-cells = <1>; + }; + npu: npu@7122000 { compatible = "vivante,gc"; reg = <0x07122000 0x1000>; diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts index f82a8d1216978..bfdf1728cd14b 100644 --- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts +++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts @@ -14,6 +14,7 @@ aliases { ethernet0 = &gmac0; + ethernet1 = &gmac1; serial0 = &uart0; }; @@ -75,7 +76,7 @@ &gmac0 { phy-mode = "rgmii-id"; - phy-handle = <&ext_rgmii_phy>; + phy-handle = <&ext_rgmii0_phy>; phy-supply = <®_cldo3>; allwinner,tx-delay-ps = <300>; @@ -84,13 +85,24 @@ status = "okay"; }; +&gmac1 { + phy-mode = "rgmii-id"; + phy-handle = <&ext_rgmii1_phy>; + phy-supply = <®_cldo4>; + + tx-internal-delay-ps = <300>; + rx-internal-delay-ps = <400>; + + status = "okay"; +}; + &gpu { mali-supply = <®_dcdc2>; status = "okay"; }; &mdio0 { - ext_rgmii_phy: ethernet-phy@1 { + ext_rgmii0_phy: ethernet-phy@1 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <1>; reset-gpios = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH8 */ @@ -99,6 +111,16 @@ }; }; +&mdio1 { + ext_rgmii1_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + reset-gpios = <&pio 9 16 GPIO_ACTIVE_LOW>; /* PJ16 */ + reset-assert-us = <10000>; + reset-deassert-us = <150000>; + }; +}; + &mmc0 { vmmc-supply = <®_cldo3>; cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ @@ -250,6 +272,8 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-name = "vcc-pj-phy"; + /* enough time for the PHY to fully power on */ + regulator-enable-ramp-delay = <150000>; }; reg_cpusldo: cpusldo { diff --git a/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts b/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts index 1b054fa8ef74f..054d0357c139f 100644 --- a/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts +++ b/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts @@ -13,6 +13,7 @@ aliases { ethernet0 = &gmac0; + ethernet1 = &gmac1; serial0 = &uart0; }; @@ -73,7 +74,7 @@ &gmac0 { phy-mode = "rgmii-id"; - phy-handle = <&ext_rgmii_phy>; + phy-handle = <&ext_rgmii0_phy>; phy-supply = <®_dcdc4>; allwinner,tx-delay-ps = <100>; @@ -82,13 +83,24 @@ status = "okay"; }; +&gmac1 { + phy-mode = "rgmii-id"; + phy-handle = <&ext_rgmii1_phy>; + phy-supply = <®_dcdc4>; + + tx-internal-delay-ps = <100>; + rx-internal-delay-ps = <100>; + + status = "okay"; +}; + &gpu { mali-supply = <®_dcdc2>; status = "okay"; }; &mdio0 { - ext_rgmii_phy: ethernet-phy@1 { + ext_rgmii0_phy: ethernet-phy@1 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <1>; reset-gpios = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH8 */ @@ -97,6 +109,16 @@ }; }; +&mdio1 { + ext_rgmii1_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + reset-gpios = <&pio 9 16 GPIO_ACTIVE_LOW>; /* PJ16 */ + reset-assert-us = <10000>; + reset-deassert-us = <150000>; + }; +}; + &mmc0 { vmmc-supply = <®_cldo3>; cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ diff --git a/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts b/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts index 39a4e194712a2..9e6b21cf293ee 100644 --- a/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts +++ b/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts @@ -15,6 +15,7 @@ compatible = "xunlong,orangepi-4a", "allwinner,sun55i-t527"; aliases { + ethernet0 = &gmac1; serial0 = &uart0; }; @@ -102,11 +103,33 @@ status = "okay"; }; +&gmac1 { + phy-mode = "rgmii-id"; + phy-handle = <&ext_rgmii_phy>; + phy-supply = <®_cldo4>; + + tx-internal-delay-ps = <0>; + rx-internal-delay-ps = <300>; + + status = "okay"; +}; + &gpu { mali-supply = <®_dcdc2>; status = "okay"; }; +&mdio1 { + ext_rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + interrupts-extended = <&pio 8 16 IRQ_TYPE_LEVEL_LOW>; /* PI16 */ + reset-gpios = <&pio 8 15 GPIO_ACTIVE_LOW>; /* PI15 */ + reset-assert-us = <10000>; + reset-deassert-us = <150000>; + }; +}; + &mmc0 { vmmc-supply = <®_cldo3>; cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi index effd242f6bf70..657e986e5dba7 100644 --- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi @@ -630,6 +630,15 @@ interrupts = <5 4>; }; + sdmmca-ecc@ff8c8c00 { + compatible = "altr,socfpga-s10-sdmmc-ecc", + "altr,socfpga-sdmmc-ecc"; + reg = <0xff8c8c00 0x100>; + altr,ecc-parent = <&mmc>; + interrupts = <14 4>, + <15 4>; + }; + }; qspi: spi@ff8d2000 { diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts index 4eee777ef1a14..58f776e411fc3 100644 --- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts @@ -50,19 +50,6 @@ regulator-min-microvolt = <330000>; regulator-max-microvolt = <330000>; }; - - soc@0 { - eccmgr { - sdmmca-ecc@ff8c8c00 { - compatible = "altr,socfpga-s10-sdmmc-ecc", - "altr,socfpga-sdmmc-ecc"; - reg = <0xff8c8c00 0x100>; - altr,ecc-parent = <&mmc>; - interrupts = <14 4>, - <15 4>; - }; - }; - }; }; &pinctrl0 { @@ -190,6 +177,8 @@ cdns,tsd2d-ns = <50>; cdns,tchsh-ns = <4>; cdns,tslch-ns = <4>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; partitions { compatible = "fixed-partitions"; diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts index 7c53cb9621e57..92954c5beb543 100644 --- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts @@ -50,19 +50,6 @@ regulator-min-microvolt = <330000>; regulator-max-microvolt = <330000>; }; - - soc@0 { - eccmgr { - sdmmca-ecc@ff8c8c00 { - compatible = "altr,socfpga-s10-sdmmc-ecc", - "altr,socfpga-sdmmc-ecc"; - reg = <0xff8c8c00 0x100>; - altr,ecc-parent = <&mmc>; - interrupts = <14 4>, - <15 4>; - }; - }; - }; }; &gpio1 { diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_swvp.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_swvp.dts index ad52e8a0b9ba4..5ba6ca4ef19a0 100644 --- a/arch/arm64/boot/dts/altera/socfpga_stratix10_swvp.dts +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_swvp.dts @@ -62,7 +62,6 @@ &gmac0 { status = "okay"; phy-mode = "rgmii"; - phy-addr = <0xffffffff>; }; &gmac1 { @@ -73,7 +72,6 @@ &gmac2 { status = "okay"; phy-mode = "rgmii"; - phy-addr = <0xffffffff>; }; &mmc { @@ -104,5 +102,4 @@ &sysmgr { reg = <0xffd12000 0x1000>; - interrupts = <0x0 0x10 0x4>; }; diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile index 619dce79b0204..219fb088c704d 100644 --- a/arch/arm64/boot/dts/amlogic/Makefile +++ b/arch/arm64/boot/dts/amlogic/Makefile @@ -80,6 +80,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q200.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q201.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-libretech-pc.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-gxm-tx9-pro.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-ugoos-am3.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi index b1da8cbaa25a1..2b12d8284594f 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi @@ -5,6 +5,7 @@ #include "amlogic-a4-common.dtsi" #include "amlogic-a5-reset.h" +#include #include / { cpus { @@ -58,6 +59,95 @@ #reset-cells = <1>; }; + periphs_pinctrl: pinctrl@4000 { + compatible = "amlogic,pinctrl-a5", + "amlogic,pinctrl-a4"; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0x4000 0x0 0x300>; + + gpioz: gpio@c0 { + reg = <0x0 0xc0 0x0 0x40>, + <0x0 0x18 0x0 0x8>; + reg-names = "gpio", "mux"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_Z<<8) 16>; + }; + + gpiox: gpio@100 { + reg = <0x0 0x100 0x0 0x40>, + <0x0 0xc 0x0 0xc>; + reg-names = "gpio", "mux"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_X<<8) 20>; + }; + + gpiot: gpio@140 { + reg = <0x0 0x140 0x0 0x40>, + <0x0 0x2c 0x0 0x8>; + reg-names = "gpio", "mux"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_T<<8) 14>; + }; + + gpiod: gpio@180 { + reg = <0x0 0x180 0x0 0x40>, + <0x0 0x40 0x0 0x8>; + reg-names = "gpio", "mux"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_D<<8) 16>; + }; + + gpioe: gpio@1c0 { + reg = <0x0 0x1c0 0x0 0x40>, + <0x0 0x48 0x0 0x4>; + reg-names = "gpio", "mux"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_E<<8) 2>; + }; + + gpioc: gpio@200 { + reg = <0x0 0x200 0x0 0x40>, + <0x0 0x24 0x0 0x8>; + reg-names = "gpio", "mux"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_C<<8) 11>; + }; + + gpiob: gpio@240 { + reg = <0x0 0x240 0x0 0x40>, + <0x0 0x0 0x0 0x8>; + reg-names = "gpio", "mux"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_B<<8) 14>; + }; + + gpioh: gpio@280 { + reg = <0x0 0x280 0x0 0x40>, + <0x0 0x4c 0x0 0x4>; + reg-names = "gpio", "mux"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_H<<8) 5>; + }; + + gpio_test_n: gpio@2c0 { + reg = <0x0 0x2c0 0x0 0x40>, + <0x0 0x3c 0x0 0x4>; + reg-names = "gpio", "mux"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_TEST_N<<8) 1>; + }; + }; + gpio_intc: interrupt-controller@4080 { compatible = "amlogic,a5-gpio-intc", "amlogic,meson-gpio-intc"; diff --git a/arch/arm64/boot/dts/amlogic/amlogic-c3-c308l-aw419.dts b/arch/arm64/boot/dts/amlogic/amlogic-c3-c308l-aw419.dts index 45f8631f9feb6..e026604c55e62 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-c3-c308l-aw419.dts +++ b/arch/arm64/boot/dts/amlogic/amlogic-c3-c308l-aw419.dts @@ -17,6 +17,7 @@ aliases { serial0 = &uart_b; spi0 = &spifc; + i2c2 = &i2c2; }; memory@0 { @@ -146,6 +147,36 @@ regulator-boot-on; regulator-always-on; }; + + camera_vdddo_1v8: regulator-camera-1v8 { + compatible = "regulator-fixed"; + regulator-name = "CAMERA_VDDDO"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + regulator-boot-on; + regulator-always-on; + }; + + camera_vdda_2v9: regulator-camera-2v9 { + compatible = "regulator-fixed"; + regulator-name = "CAMERA_VDDA"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + vin-supply = <&vcc_5v>; + regulator-boot-on; + regulator-always-on; + }; + + camera_vddd_1v2: regulator-camera-1v2 { + compatible = "regulator-fixed"; + regulator-name = "CAMERA_VDDD"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + vin-supply = <&vcc_3v3>; + regulator-boot-on; + regulator-always-on; + }; }; &uart_b { @@ -258,3 +289,56 @@ vmmc-supply = <&sdcard>; vqmmc-supply = <&sdcard>; }; + +&i2c2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins1>; + clock-frequency = <100000>; /* default 100k */ + + imx290: sensor0@1a { + compatible = "sony,imx290"; + reg = <0x1a>; + clocks = <&clkc_pll CLKID_MCLK0>; + clock-names = "xclk"; + clock-frequency = <37125000>; + assigned-clocks = <&clkc_pll CLKID_MCLK_PLL>, + <&clkc_pll CLKID_MCLK0>; + assigned-clock-rates = <74250000>, <37125000>; + + vdddo-supply = <&camera_vdddo_1v8>; + vdda-supply = <&camera_vdda_2v9>; + vddd-supply = <&camera_vddd_1v2>; + + reset-gpios = <&gpio GPIOE_4 GPIO_ACTIVE_LOW>; + + port { + imx290_out: endpoint { + data-lanes = <1 2 3 4>; + link-frequencies = /bits/ 64 <222750000 148500000>; + remote-endpoint = <&c3_mipi_csi_in>; + }; + }; + }; +}; + +&csi2 { + status = "okay"; + + ports { + port@0 { + c3_mipi_csi_in: endpoint { + remote-endpoint = <&imx290_out>; + data-lanes = <1 2 3 4>; + }; + }; + }; +}; + +&adap { + status = "okay"; +}; + +&isp { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi index 07aaaf71ea9ae..13b7ac03f9b20 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi @@ -1031,5 +1031,93 @@ #size-cells = <0>; }; }; + + csi2: csi2@ff018000 { + compatible = "amlogic,c3-mipi-csi2"; + reg = <0x0 0xff018000 0x0 0x100>, + <0x0 0xff019000 0x0 0x300>, + <0x0 0xff01a000 0x0 0x100>; + reg-names = "aphy", "dphy", "host"; + power-domains = <&pwrc PWRC_C3_MIPI_ISP_WRAP_ID>; + clocks = <&clkc_periphs CLKID_VAPB>, + <&clkc_periphs CLKID_CSI_PHY0>; + clock-names = "vapb", "phy0"; + assigned-clocks = <&clkc_periphs CLKID_VAPB>, + <&clkc_periphs CLKID_CSI_PHY0>; + assigned-clock-rates = <0>, <200000000>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + }; + + port@1 { + reg = <1>; + c3_mipi_csi_out: endpoint { + remote-endpoint = <&c3_adap_in>; + }; + }; + }; + }; + + adap: adap@ff010000 { + compatible = "amlogic,c3-mipi-adapter"; + reg = <0x0 0xff010000 0x0 0x100>, + <0x0 0xff01b000 0x0 0x100>, + <0x0 0xff01d000 0x0 0x200>; + reg-names = "top", "fd", "rd"; + power-domains = <&pwrc PWRC_C3_ISP_TOP_ID>; + clocks = <&clkc_periphs CLKID_VAPB>, + <&clkc_periphs CLKID_ISP0>; + clock-names = "vapb", "isp0"; + assigned-clocks = <&clkc_periphs CLKID_VAPB>, + <&clkc_periphs CLKID_ISP0>; + assigned-clock-rates = <0>, <400000000>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + c3_adap_in: endpoint { + remote-endpoint = <&c3_mipi_csi_out>; + }; + }; + + port@1 { + reg = <1>; + c3_adap_out: endpoint { + remote-endpoint = <&c3_isp_in>; + }; + }; + }; + }; + + isp: isp@ff000000 { + compatible = "amlogic,c3-isp"; + reg = <0x0 0xff000000 0x0 0xf000>; + reg-names = "isp"; + power-domains = <&pwrc PWRC_C3_ISP_TOP_ID>; + clocks = <&clkc_periphs CLKID_VAPB>, + <&clkc_periphs CLKID_ISP0>; + clock-names = "vapb", "isp0"; + assigned-clocks = <&clkc_periphs CLKID_VAPB>, + <&clkc_periphs CLKID_ISP0>; + assigned-clock-rates = <0>, <400000000>; + interrupts = ; + status = "disabled"; + + port { + c3_isp_in: endpoint { + remote-endpoint = <&c3_adap_out>; + }; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi index 5f602f1170c00..8ef6319390331 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include / { cpus { #address-cells = <2>; @@ -41,6 +42,15 @@ }; }; + sm: secure-monitor { + compatible = "amlogic,meson-gxbb-sm"; + + pwrc: power-controller { + compatible = "amlogic,s6-pwrc"; + #power-domain-cells = <1>; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts = , @@ -189,6 +199,24 @@ gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_CC<<8) 2>; }; }; + + gpio_intc: interrupt-controller@4080 { + compatible = "amlogic,s6-gpio-intc", + "amlogic,meson-gpio-intc"; + reg = <0x0 0x4080 0x0 0x20>; + interrupt-controller; + #interrupt-cells = <2>; + amlogic,channel-interrupts = + <10 11 12 13 14 15 16 17 18 19 20 21>; + }; + + ao-secure@10220 { + compatible = "amlogic,s6-ao-secure", + "amlogic,meson-gx-ao-secure", + "syscon"; + reg = <0x0 0x10220 0x0 0x140>; + amlogic,has-chip-id; + }; }; }; }; diff --git a/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi index d262c0b66e4b5..a3faf4d188e11 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include / { cpus { @@ -79,6 +80,15 @@ }; }; + sm: secure-monitor { + compatible = "amlogic,meson-gxbb-sm"; + + pwrc: power-controller { + compatible = "amlogic,s7-pwrc"; + #power-domain-cells = <1>; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts = , @@ -211,6 +221,24 @@ gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_CC<<8) 2>; }; }; + + gpio_intc: interrupt-controller@4080 { + compatible = "amlogic,s7-gpio-intc", + "amlogic,meson-gpio-intc"; + reg = <0x0 0x4080 0x0 0x20>; + interrupt-controller; + #interrupt-cells = <2>; + amlogic,channel-interrupts = + <10 11 12 13 14 15 16 17 18 19 20 21>; + }; + + ao-secure@10220 { + compatible = "amlogic,s7-ao-secure", + "amlogic,meson-gx-ao-secure", + "syscon"; + reg = <0x0 0x10220 0x0 0x140>; + amlogic,has-chip-id; + }; }; }; }; diff --git a/arch/arm64/boot/dts/amlogic/amlogic-s7d.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-s7d.dtsi index c4d260d5bb586..0c4417bcd6827 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-s7d.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-s7d.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include / { cpus { @@ -43,6 +44,15 @@ }; + sm: secure-monitor { + compatible = "amlogic,meson-gxbb-sm"; + + pwrc: power-controller { + compatible = "amlogic,s7d-pwrc"; + #power-domain-cells = <1>; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts = , @@ -184,6 +194,24 @@ gpio-ranges = <&periphs_pinctrl 0 (AMLOGIC_GPIO_CC<<8) 2>; }; }; + + gpio_intc: interrupt-controller@4080 { + compatible = "amlogic,s7d-gpio-intc", + "amlogic,meson-gpio-intc"; + reg = <0x0 0x4080 0x0 0x20>; + interrupt-controller; + #interrupt-cells = <2>; + amlogic,channel-interrupts = + <10 11 12 13 14 15 16 17 18 19 20 21>; + }; + + ao-secure@10220 { + compatible = "amlogic,s7d-ao-secure", + "amlogic,meson-gx-ao-secure", + "syscon"; + reg = <0x0 0x10220 0x0 0x140>; + amlogic,has-chip-id; + }; }; }; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi index 04fb130ac7c6a..e95c91894968b 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi @@ -208,7 +208,7 @@ reg = <0x0 0xf9800000 0x0 0x400000>, <0x0 0xff646000 0x0 0x2000>, <0x0 0xf9f00000 0x0 0x100000>; - reg-names = "elbi", "cfg", "config"; + reg-names = "dbi", "cfg", "config"; interrupts = ; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; @@ -234,7 +234,7 @@ reg = <0x0 0xfa000000 0x0 0x400000>, <0x0 0xff648000 0x0 0x2000>, <0x0 0xfa400000 0x0 0x100000>; - reg-names = "elbi", "cfg", "config"; + reg-names = "dbi", "cfg", "config"; interrupts = ; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi index dcc927a9da802..ca455f634834b 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi @@ -138,7 +138,7 @@ reg = <0x0 0xfc000000 0x0 0x400000>, <0x0 0xff648000 0x0 0x2000>, <0x0 0xfc400000 0x0 0x200000>; - reg-names = "elbi", "cfg", "config"; + reg-names = "dbi", "cfg", "config"; interrupts = ; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi index f04efa8282561..23358d94844c9 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi @@ -87,7 +87,7 @@ i-cache-line-size = <32>; i-cache-size = <0x8000>; i-cache-sets = <32>; - next-level-cache = <&l2_cache_l>; + next-level-cache = <&l2_cache_b>; #cooling-cells = <2>; }; @@ -103,7 +103,7 @@ i-cache-line-size = <32>; i-cache-size = <0x8000>; i-cache-sets = <32>; - next-level-cache = <&l2_cache_l>; + next-level-cache = <&l2_cache_b>; #cooling-cells = <2>; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts new file mode 100644 index 0000000000000..9a62176cfe5a1 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2016 Endless Computers, Inc. + * Author: Carlo Caione + */ + +/dts-v1/; + +#include "meson-gxm.dtsi" +#include "meson-gx-p23x-q20x.dtsi" +#include + +/ { + compatible = "oranth,tx9-pro", "amlogic,s912", "amlogic,meson-gxm"; + model = "Tanix TX9 Pro"; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1710000>; + + button-function { + label = "Update"; + linux,code = ; + press-threshold-microvolt = <10000>; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + button { + label = "power"; + linux,code = ; + gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>; + }; + }; +}; + +ðmac { + pinctrl-0 = <ð_pins>; + pinctrl-names = "default"; + phy-handle = <&external_phy>; + amlogic,tx-delay-ns = <2>; + phy-mode = "rgmii"; +}; + +&external_mdio { + external_phy: ethernet-phy@0 { + /* Realtek RTL8211F (0x001cc916) */ + reg = <0>; + max-speed = <1000>; + + reset-assert-us = <10000>; + reset-deassert-us = <80000>; + reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; + + interrupt-parent = <&gpio_intc>; + /* MAC_INTR on GPIOZ_15 */ + interrupts = <25 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&ir { + linux,rc-map-name = "rc-tanix-tx3mini"; +}; + +&sd_emmc_a { + brcmf: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +&uart_A { + status = "okay"; + pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>; + pinctrl-names = "default"; + uart-has-rtscts; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; + max-speed = <2000000>; + clocks = <&wifi32k>; + clock-names = "lpo"; + }; +}; diff --git a/arch/arm64/boot/dts/bst/Makefile b/arch/arm64/boot/dts/bst/Makefile new file mode 100644 index 0000000000000..4c1b8b4cdad89 --- /dev/null +++ b/arch/arm64/boot/dts/bst/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_ARCH_BST) += bstc1200-cdcu1.0-adas_4c2g.dtb diff --git a/arch/arm64/boot/dts/bst/bstc1200-cdcu1.0-adas_4c2g.dts b/arch/arm64/boot/dts/bst/bstc1200-cdcu1.0-adas_4c2g.dts new file mode 100644 index 0000000000000..5eb9ef369d8c9 --- /dev/null +++ b/arch/arm64/boot/dts/bst/bstc1200-cdcu1.0-adas_4c2g.dts @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "bstc1200.dtsi" + +/ { + model = "BST C1200-96 CDCU1.0 4C2G"; + compatible = "bst,c1200-cdcu1.0-adas-4c2g", "bst,c1200"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@810000000 { + device_type = "memory"; + reg = <0x8 0x10000000 0x0 0x30000000>, + <0x8 0xc0000000 0x1 0x0>, + <0xc 0x00000000 0x0 0x40000000>; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/bst/bstc1200.dtsi b/arch/arm64/boot/dts/bst/bstc1200.dtsi new file mode 100644 index 0000000000000..dd13c6bfc3c89 --- /dev/null +++ b/arch/arm64/boot/dts/bst/bstc1200.dtsi @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +/ { + compatible = "bst,c1200"; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a78"; + reg = <0x0>; + enable-method = "psci"; + next-level-cache = <&l2_cache>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a78"; + reg = <0x100>; + enable-method = "psci"; + next-level-cache = <&l2_cache>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a78"; + reg = <0x200>; + enable-method = "psci"; + next-level-cache = <&l2_cache>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a78"; + reg = <0x300>; + enable-method = "psci"; + next-level-cache = <&l2_cache>; + }; + + l2_cache: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + soc { + compatible = "simple-bus"; + ranges; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + uart0: serial@20008000 { + compatible = "snps,dw-apb-uart"; + reg = <0x0 0x20008000 0x0 0x1000>; + clock-frequency = <25000000>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + gic: interrupt-controller@32800000 { + compatible = "arm,gic-v3"; + reg = <0x0 0x32800000 0x0 0x10000>, + <0x0 0x32880000 0x0 0x100000>; + ranges; + #address-cells = <2>; + #size-cells = <2>; + #interrupt-cells = <3>; + interrupt-controller; + interrupts = ; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + always-on; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts index d74964d53c3bc..4dee8cd0b86da 100644 --- a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts +++ b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts @@ -7,6 +7,8 @@ /dts-v1/; #include "sky1.dtsi" +#include "sky1-pinfunc.h" + / { model = "Radxa Orion O6"; compatible = "radxa,orion-o6", "cix,sky1"; @@ -34,6 +36,56 @@ }; +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_hog: hog-cfg { + pins { + pinmux = , + , + , + ; + bias-pull-down; + drive-strength = <8>; + }; + }; +}; + +&iomuxc_s5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog_s5>; + + pinctrl_hog_s5: hog-s5-cfg { + pins { + pinmux = ; + bias-pull-up; + drive-strength = <8>; + + }; + }; +}; + +&pcie_x8_rc { + status = "okay"; +}; + +&pcie_x4_rc { + status = "okay"; +}; + +&pcie_x2_rc { + status = "okay"; +}; + +&pcie_x1_0_rc { + status = "okay"; +}; + +&pcie_x1_1_rc { + status = "okay"; +}; + &uart2 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/cix/sky1-pinfunc.h b/arch/arm64/boot/dts/cix/sky1-pinfunc.h new file mode 100644 index 0000000000000..ebe9f6fef4036 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-pinfunc.h @@ -0,0 +1,401 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright 2024-2025 Cix Technology Group Co., Ltd. + */ + +#ifndef __CIX_SKY1_H +#define __CIX_SKY1_H + +/* s5 pads */ +#define CIX_PAD_GPIO001_FUNC_GPIO001 (0 << 8 | 0x0) +#define CIX_PAD_GPIO002_FUNC_GPIO002 (1 << 8 | 0x0) +#define CIX_PAD_GPIO003_FUNC_GPIO003 (2 << 8 | 0x0) +#define CIX_PAD_GPIO004_FUNC_GPIO004 (3 << 8 | 0x0) +#define CIX_PAD_GPIO005_FUNC_GPIO005 (4 << 8 | 0x0) +#define CIX_PAD_GPIO006_FUNC_GPIO006 (5 << 8 | 0x0) +#define CIX_PAD_GPIO007_FUNC_GPIO007 (6 << 8 | 0x0) +#define CIX_PAD_GPIO008_FUNC_GPIO008 (7 << 8 | 0x0) +#define CIX_PAD_GPIO009_FUNC_GPIO009 (8 << 8 | 0x0) +#define CIX_PAD_GPIO010_FUNC_GPIO010 (9 << 8 | 0x0) +#define CIX_PAD_GPIO011_FUNC_GPIO011 (10 << 8 | 0x0) +#define CIX_PAD_GPIO012_FUNC_GPIO012 (11 << 8 | 0x0) +#define CIX_PAD_GPIO013_FUNC_GPIO013 (12 << 8 | 0x0) +#define CIX_PAD_GPIO014_FUNC_GPIO014 (13 << 8 | 0x0) +#define CIX_PAD_SFI_I2C0_SCL_FUNC_SFI_I2C0_SCL (28 << 8 | 0x0) +#define CIX_PAD_SFI_I2C0_SCL_FUNC_SFI_I3C0_SCL (28 << 8 | 0x1) +#define CIX_PAD_SFI_I2C0_SDA_FUNC_SFI_I2C0_SDA (29 << 8 | 0x0) +#define CIX_PAD_SFI_I2C0_SDA_FUNC_SFI_I3C0_SDA (29 << 8 | 0x1) +#define CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_I2C1_SCL (30 << 8 | 0x0) +#define CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_I3C1_SCL (30 << 8 | 0x1) +#define CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_SPI_CS0 (30 << 8 | 0x2) +#define CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_I2C1_SDA (31 << 8 | 0x0) +#define CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_I3C1_SDA (31 << 8 | 0x1) +#define CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_SPI_CS1 (31 << 8 | 0x2) +#define CIX_PAD_SFI_GPIO0_FUNC_GPIO015 (32 << 8 | 0x0) +#define CIX_PAD_SFI_GPIO0_FUNC_SFI_SPI_SCK (32 << 8 | 0x1) +#define CIX_PAD_SFI_GPIO0_FUNC_SFI_GPIO0 (32 << 8 | 0x2) +#define CIX_PAD_SFI_GPIO1_FUNC_GPIO016 (33 << 8 | 0x0) +#define CIX_PAD_SFI_GPIO1_FUNC_SFI_SPI_MOSI (33 << 8 | 0x1) +#define CIX_PAD_SFI_GPIO1_FUNC_SFI_GPIO1 (33 << 8 | 0x2) +#define CIX_PAD_SFI_GPIO2_FUNC_GPIO017 (34 << 8 | 0x0) +#define CIX_PAD_SFI_GPIO2_FUNC_SFI_SPI_MISO (34 << 8 | 0x1) +#define CIX_PAD_SFI_GPIO2_FUNC_SFI_GPIO2 (34 << 8 | 0x2) +#define CIX_PAD_GPIO018_FUNC_SFI_GPIO3 (35 << 8 | 0x0) +#define CIX_PAD_GPIO018_FUNC_GPIO018 (35 << 8 | 0x1) +#define CIX_PAD_GPIO019_FUNC_SFI_GPIO4 (36 << 8 | 0x0) +#define CIX_PAD_GPIO019_FUNC_GPIO019 (36 << 8 | 0x1) +#define CIX_PAD_GPIO020_FUNC_SFI_GPIO5 (37 << 8 | 0x0) +#define CIX_PAD_GPIO020_FUNC_GPIO020 (37 << 8 | 0x1) +#define CIX_PAD_GPIO021_FUNC_SFI_GPIO6 (38 << 8 | 0x0) +#define CIX_PAD_GPIO021_FUNC_GPIO021 (38 << 8 | 0x1) +#define CIX_PAD_GPIO022_FUNC_SFI_GPIO7 (39 << 8 | 0x0) +#define CIX_PAD_GPIO022_FUNC_GPIO022 (39 << 8 | 0x1) +#define CIX_PAD_GPIO023_FUNC_SFI_GPIO8 (40 << 8 | 0x0) +#define CIX_PAD_GPIO023_FUNC_GPIO023 (40 << 8 | 0x1) +#define CIX_PAD_GPIO023_FUNC_SFI_I3C0_PUR_EN_L (40 << 8 | 0x2) +#define CIX_PAD_GPIO024_FUNC_SFI_GPIO9 (41 << 8 | 0x0) +#define CIX_PAD_GPIO024_FUNC_GPIO024 (41 << 8 | 0x1) +#define CIX_PAD_GPIO024_FUNC_SFI_I3C1_PUR_EN_L (41 << 8 | 0x2) +#define CIX_PAD_SPI1_MISO_FUNC_SPI1_MISO (42 << 8 | 0x0) +#define CIX_PAD_SPI1_MISO_FUNC_GPIO025 (42 << 8 | 0x1) +#define CIX_PAD_SPI1_CS0_FUNC_SPI1_CS0 (43 << 8 | 0x0) +#define CIX_PAD_SPI1_CS0_FUNC_GPIO026 (43 << 8 | 0x1) +#define CIX_PAD_SPI1_CS1_FUNC_SPI1_CS1 (44 << 8 | 0x0) +#define CIX_PAD_SPI1_CS1_FUNC_GPIO027 (44 << 8 | 0x1) +#define CIX_PAD_SPI1_MOSI_FUNC_SPI1_MOSI (45 << 8 | 0x0) +#define CIX_PAD_SPI1_MOSI_FUNC_GPIO028 (45 << 8 | 0x1) +#define CIX_PAD_SPI1_CLK_FUNC_SPI1_CLK (46 << 8 | 0x0) +#define CIX_PAD_SPI1_CLK_FUNC_GPIO029 (46 << 8 | 0x1) +#define CIX_PAD_GPIO030_FUNC_GPIO030 (47 << 8 | 0x0) +#define CIX_PAD_GPIO030_FUNC_USB_OC0_L (47 << 8 | 0x1) +#define CIX_PAD_GPIO031_FUNC_GPIO031 (48 << 8 | 0x0) +#define CIX_PAD_GPIO031_FUNC_USB_OC1_L (48 << 8 | 0x1) +#define CIX_PAD_GPIO032_FUNC_GPIO032 (49 << 8 | 0x0) +#define CIX_PAD_GPIO032_FUNC_USB_OC2_L (49 << 8 | 0x1) +#define CIX_PAD_GPIO033_FUNC_GPIO033 (50 << 8 | 0x0) +#define CIX_PAD_GPIO033_FUNC_USB_OC3_L (50 << 8 | 0x1) +#define CIX_PAD_GPIO034_FUNC_GPIO034 (51 << 8 | 0x0) +#define CIX_PAD_GPIO034_FUNC_USB_OC4_L (51 << 8 | 0x1) +#define CIX_PAD_GPIO035_FUNC_GPIO035 (52 << 8 | 0x0) +#define CIX_PAD_GPIO035_FUNC_USB_OC5_L (52 << 8 | 0x1) +#define CIX_PAD_GPIO036_FUNC_GPIO036 (53 << 8 | 0x0) +#define CIX_PAD_GPIO036_FUNC_USB_OC6_L (53 << 8 | 0x1) +#define CIX_PAD_GPIO037_FUNC_GPIO037 (54 << 8 | 0x0) +#define CIX_PAD_GPIO037_FUNC_USB_OC7_L (54 << 8 | 0x1) +#define CIX_PAD_GPIO038_FUNC_GPIO038 (55 << 8 | 0x0) +#define CIX_PAD_GPIO038_FUNC_USB_OC8_L (55 << 8 | 0x1) +#define CIX_PAD_GPIO039_FUNC_GPIO039 (56 << 8 | 0x0) +#define CIX_PAD_GPIO039_FUNC_USB_OC9_L (56 << 8 | 0x1) +#define CIX_PAD_GPIO040_FUNC_GPIO040 (57 << 8 | 0x0) +#define CIX_PAD_GPIO040_FUNC_USB_DRIVE_VBUS0 (57 << 8 | 0x1) +#define CIX_PAD_GPIO041_FUNC_GPIO041 (58 << 8 | 0x0) +#define CIX_PAD_GPIO041_FUNC_USB_DRIVE_VBUS4 (58 << 8 | 0x1) +#define CIX_PAD_GPIO042_FUNC_GPIO042 (59 << 8 | 0x0) +#define CIX_PAD_GPIO042_FUNC_USB_DRIVE_VBUS5 (59 << 8 | 0x1) +#define CIX_PAD_SE_QSPI_CLK_FUNC_SE_QSPI_CLK (60 << 8 | 0x0) +#define CIX_PAD_SE_QSPI_CLK_FUNC_QSPI_CLK (60 << 8 | 0x1) +#define CIX_PAD_SE_QSPI_CS_L_FUNC_SE_QSPI_CS_L (61 << 8 | 0x0) +#define CIX_PAD_SE_QSPI_CS_L_FUNC_QSPI_CS_L (61 << 8 | 0x1) +#define CIX_PAD_SE_QSPI_DATA0_FUNC_SE_QSPI_DATA0 (62 << 8 | 0x0) +#define CIX_PAD_SE_QSPI_DATA0_FUNC_QSPI_DATA0 (62 << 8 | 0x1) +#define CIX_PAD_SE_QSPI_DATA1_FUNC_SE_QSPI_DATA1 (63 << 8 | 0x0) +#define CIX_PAD_SE_QSPI_DATA1_FUNC_QSPI_DATA1 (63 << 8 | 0x1) +#define CIX_PAD_SE_QSPI_DATA2_FUNC_SE_QSPI_DATA2 (64 << 8 | 0x0) +#define CIX_PAD_SE_QSPI_DATA2_FUNC_QSPI_DATA2 (64 << 8 | 0x1) +#define CIX_PAD_SE_QSPI_DATA3_FUNC_SE_QSPI_DATA3 (65 << 8 | 0x0) +#define CIX_PAD_SE_QSPI_DATA3_FUNC_QSPI_DATA3 (65 << 8 | 0x1) +/* s0 pads */ +#define CIX_PAD_GPIO043_FUNC_GPIO043 (0 << 8 | 0x0) +#define CIX_PAD_GPIO044_FUNC_GPIO044 (1 << 8 | 0x0) +#define CIX_PAD_GPIO045_FUNC_GPIO045 (2 << 8 | 0x0) +#define CIX_PAD_GPIO046_FUNC_GPIO046 (3 << 8 | 0x0) +#define CIX_PAD_DP2_DIGON_FUNC_DP2_DIGON (18 << 8 | 0x0) +#define CIX_PAD_DP2_BLON_FUNC_DP2_BLON (19 << 8 | 0x0) +#define CIX_PAD_DP2_VARY_BL_FUNC_DP2_VARY_BL (20 << 8 | 0x0) +#define CIX_PAD_I2C7_SCL_FUNC_I2C7_SCL (21 << 8 | 0x0) +#define CIX_PAD_I2C7_SDA_FUNC_I2C7_SDA (22 << 8 | 0x0) +#define CIX_PAD_I2C5_SCL_FUNC_I2C5_SCL (26 << 8 | 0x0) +#define CIX_PAD_I2C5_SCL_FUNC_GPIO047 (26 << 8 | 0x1) +#define CIX_PAD_I2C5_SDA_FUNC_I2C5_SDA (27 << 8 | 0x0) +#define CIX_PAD_I2C5_SDA_FUNC_GPIO048 (27 << 8 | 0x1) +#define CIX_PAD_I2C6_SCL_FUNC_I2C6_SCL (28 << 8 | 0x0) +#define CIX_PAD_I2C6_SCL_FUNC_GPIO049 (28 << 8 | 0x1) +#define CIX_PAD_I2C6_SDA_FUNC_I2C6_SDA (29 << 8 | 0x0) +#define CIX_PAD_I2C6_SDA_FUNC_GPIO050 (29 << 8 | 0x1) +#define CIX_PAD_I2C0_CLK_FUNC_I2C0_CLK (30 << 8 | 0x0) +#define CIX_PAD_I2C0_CLK_FUNC_GPIO051 (30 << 8 | 0x1) +#define CIX_PAD_I2C0_SDA_FUNC_I2C0_SDA (31 << 8 | 0x0) +#define CIX_PAD_I2C0_SDA_FUNC_GPIO052 (31 << 8 | 0x1) +#define CIX_PAD_I2C1_CLK_FUNC_I2C1_CLK (32 << 8 | 0x0) +#define CIX_PAD_I2C1_CLK_FUNC_GPIO053 (32 << 8 | 0x1) +#define CIX_PAD_I2C1_SDA_FUNC_I2C1_SDA (33 << 8 | 0x0) +#define CIX_PAD_I2C1_SDA_FUNC_GPIO054 (33 << 8 | 0x1) +#define CIX_PAD_I2C2_SCL_FUNC_I2C2_SCL (34 << 8 | 0x0) +#define CIX_PAD_I2C2_SCL_FUNC_I3C0_SCL (34 << 8 | 0x1) +#define CIX_PAD_I2C2_SCL_FUNC_GPIO055 (34 << 8 | 0x2) +#define CIX_PAD_I2C2_SDA_FUNC_I2C2_SDA (35 << 8 | 0x0) +#define CIX_PAD_I2C2_SDA_FUNC_I3C0_SDA (35 << 8 | 0x1) +#define CIX_PAD_I2C2_SDA_FUNC_GPIO056 (35 << 8 | 0x2) +#define CIX_PAD_GPIO057_FUNC_GPIO057 (36 << 8 | 0x0) +#define CIX_PAD_GPIO057_FUNC_I3C0_PUR_EN_L (36 << 8 | 0x1) +#define CIX_PAD_I2C3_CLK_FUNC_I2C3_CLK (37 << 8 | 0x0) +#define CIX_PAD_I2C3_CLK_FUNC_I3C1_CLK (37 << 8 | 0x1) +#define CIX_PAD_I2C3_CLK_FUNC_GPIO058 (37 << 8 | 0x2) +#define CIX_PAD_I2C3_SDA_FUNC_I2C3_SDA (38 << 8 | 0x0) +#define CIX_PAD_I2C3_SDA_FUNC_I3C1_SDA (38 << 8 | 0x1) +#define CIX_PAD_I2C3_SDA_FUNC_GPIO059 (38 << 8 | 0x2) +#define CIX_PAD_GPIO060_FUNC_GPIO060 (39 << 8 | 0x0) +#define CIX_PAD_GPIO060_FUNC_I3C1_PUR_EN_L (39 << 8 | 0x1) +#define CIX_PAD_I2C4_CLK_FUNC_I2C4_CLK (40 << 8 | 0x0) +#define CIX_PAD_I2C4_CLK_FUNC_GPIO061 (40 << 8 | 0x1) +#define CIX_PAD_I2C4_SDA_FUNC_I2C4_SDA (41 << 8 | 0x0) +#define CIX_PAD_I2C4_SDA_FUNC_GPIO062 (41 << 8 | 0x1) +#define CIX_PAD_HDA_BITCLK_FUNC_HDA_BITCLK (42 << 8 | 0x0) +#define CIX_PAD_HDA_BITCLK_FUNC_I2S0_SCK (42 << 8 | 0x1) +#define CIX_PAD_HDA_BITCLK_FUNC_I2S9_RSCK_DBG (42 << 8 | 0x2) +#define CIX_PAD_HDA_RST_L_FUNC_HDA_RST_L (43 << 8 | 0x0) +#define CIX_PAD_HDA_RST_L_FUNC_I2S0_DATA_IN (43 << 8 | 0x1) +#define CIX_PAD_HDA_RST_L_FUNC_I2S9_DATA_IN0_DBG (43 << 8 | 0x2) +#define CIX_PAD_HDA_SDIN0_FUNC_HDA_SDIN0 (44 << 8 | 0x0) +#define CIX_PAD_HDA_SDIN0_FUNC_I2S0_MCLK (44 << 8 | 0x1) +#define CIX_PAD_HDA_SDIN0_FUNC_I2S9_TSCK_DBG (44 << 8 | 0x2) +#define CIX_PAD_HDA_SDOUT0_FUNC_HDA_SDOUT0 (45 << 8 | 0x0) +#define CIX_PAD_HDA_SDOUT0_FUNC_I2S0_DATA_OUT (45 << 8 | 0x1) +#define CIX_PAD_HDA_SDOUT0_FUNC_I2S9_TWS_DBG (45 << 8 | 0x2) +#define CIX_PAD_HDA_SYNC_FUNC_HDA_SYNC (46 << 8 | 0x0) +#define CIX_PAD_HDA_SYNC_FUNC_I2S0_WS (46 << 8 | 0x1) +#define CIX_PAD_HDA_SYNC_FUNC_I2S9_RWS_DBG (46 << 8 | 0x2) +#define CIX_PAD_HDA_SDIN1_FUNC_HDA_SDIN1 (47 << 8 | 0x0) +#define CIX_PAD_HDA_SDIN1_FUNC_GPIO063 (47 << 8 | 0x1) +#define CIX_PAD_HDA_SDIN1_FUNC_I2S9_DATA_IN1_DBG (47 << 8 | 0x2) +#define CIX_PAD_HDA_SDOUT1_FUNC_HDA_SDOUT1 (48 << 8 | 0x0) +#define CIX_PAD_HDA_SDOUT1_FUNC_GPIO064 (48 << 8 | 0x1) +#define CIX_PAD_HDA_SDOUT1_FUNC_I2S9_DATA_OUT0_DBG (48 << 8 | 0x2) +#define CIX_PAD_I2S1_MCLK_FUNC_I2S1_MCLK (49 << 8 | 0x0) +#define CIX_PAD_I2S1_MCLK_FUNC_GPIO065 (49 << 8 | 0x1) +#define CIX_PAD_I2S1_SCK_FUNC_I2S1_SCK (50 << 8 | 0x0) +#define CIX_PAD_I2S1_SCK_FUNC_GPIO066 (50 << 8 | 0x1) +#define CIX_PAD_I2S1_WS_FUNC_I2S1_WS (51 << 8 | 0x0) +#define CIX_PAD_I2S1_WS_FUNC_GPIO067 (51 << 8 | 0x1) +#define CIX_PAD_I2S1_DATA_IN_FUNC_I2S1_DATA_IN (52 << 8 | 0x0) +#define CIX_PAD_I2S1_DATA_IN_FUNC_GPIO068 (52 << 8 | 0x1) +#define CIX_PAD_I2S1_DATA_OUT_FUNC_I2S1_DATA_OUT (53 << 8 | 0x0) +#define CIX_PAD_I2S1_DATA_OUT_FUNC_GPIO069 (53 << 8 | 0x1) +#define CIX_PAD_I2S2_MCLK_FUNC_I2S2_MCLK (54 << 8 | 0x0) +#define CIX_PAD_I2S2_MCLK_FUNC_GPIO070 (54 << 8 | 0x1) +#define CIX_PAD_I2S2_RSCK_FUNC_I2S2_RSCK (55 << 8 | 0x0) +#define CIX_PAD_I2S2_RSCK_FUNC_GPIO071 (55 << 8 | 0x1) +#define CIX_PAD_I2S2_RSCK_FUNC_I2S5_RSCK_DBG (55 << 8 | 0x2) +#define CIX_PAD_I2S2_RSCK_FUNC_I2S6_RSCK_DBG (55 << 8 | 0x3) +#define CIX_PAD_I2S2_RWS_FUNC_I2S2_RWS (56 << 8 | 0x0) +#define CIX_PAD_I2S2_RWS_FUNC_GPIO072 (56 << 8 | 0x1) +#define CIX_PAD_I2S2_RWS_FUNC_I2S5_RWS_DBG (56 << 8 | 0x2) +#define CIX_PAD_I2S2_RWS_FUNC_I2S6_RWS_DBG (56 << 8 | 0x3) +#define CIX_PAD_I2S2_TSCK_FUNC_I2S2_TSCK (57 << 8 | 0x0) +#define CIX_PAD_I2S2_TSCK_FUNC_GPIO073 (57 << 8 | 0x1) +#define CIX_PAD_I2S2_TSCK_FUNC_I2S5_TSCK_DBG (57 << 8 | 0x2) +#define CIX_PAD_I2S2_TSCK_FUNC_I2S6_TSCK_DBG (57 << 8 | 0x3) +#define CIX_PAD_I2S2_TWS_FUNC_I2S2_TWS (58 << 8 | 0x0) +#define CIX_PAD_I2S2_TWS_FUNC_GPIO074 (58 << 8 | 0x1) +#define CIX_PAD_I2S2_TWS_FUNC_I2S5_TWS_DBG (58 << 8 | 0x2) +#define CIX_PAD_I2S2_TWS_FUNC_I2S6_TWS_DBG (58 << 8 | 0x3) +#define CIX_PAD_I2S2_DATA_IN0_FUNC_I2S2_DATA_IN0 (59 << 8 | 0x0) +#define CIX_PAD_I2S2_DATA_IN0_FUNC_GPIO075 (59 << 8 | 0x1) +#define CIX_PAD_I2S2_DATA_IN0_FUNC_I2S5_DATA_IN0_DBG (59 << 8 | 0x2) +#define CIX_PAD_I2S2_DATA_IN0_FUNC_I2S6_DATA_IN0_DBG (59 << 8 | 0x3) +#define CIX_PAD_I2S2_DATA_IN1_FUNC_I2S2_DATA_IN1 (60 << 8 | 0x0) +#define CIX_PAD_I2S2_DATA_IN1_FUNC_GPIO076 (60 << 8 | 0x1) +#define CIX_PAD_I2S2_DATA_IN1_FUNC_I2S5_DATA_IN1_DBG (60 << 8 | 0x2) +#define CIX_PAD_I2S2_DATA_IN1_FUNC_I2S6_DATA_IN1_DBG (60 << 8 | 0x3) +#define CIX_PAD_I2S2_DATA_OUT0_FUNC_I2S2_DATA_OUT0 (61 << 8 | 0x0) +#define CIX_PAD_I2S2_DATA_OUT0_FUNC_GPIO077 (61 << 8 | 0x1) +#define CIX_PAD_I2S2_DATA_OUT0_FUNC_I2S5_DATA_OUT0_DBG (61 << 8 | 0x2) +#define CIX_PAD_I2S2_DATA_OUT0_FUNC_I2S6_DATA_OUT0_DBG (61 << 8 | 0x3) +#define CIX_PAD_I2S2_DATA_OUT1_FUNC_I2S2_DATA_OUT1 (62 << 8 | 0x0) +#define CIX_PAD_I2S2_DATA_OUT1_FUNC_GPIO078 (62 << 8 | 0x1) +#define CIX_PAD_I2S2_DATA_OUT1_FUNC_I2S5_DATA_OUT1_DBG (62 << 8 | 0x2) +#define CIX_PAD_I2S2_DATA_OUT1_FUNC_I2S6_DATA_OUT1_DBG (62 << 8 | 0x3) +#define CIX_PAD_I2S2_DATA_OUT2_FUNC_I2S2_DATA_OUT2 (63 << 8 | 0x0) +#define CIX_PAD_I2S2_DATA_OUT2_FUNC_GPIO079 (63 << 8 | 0x1) +#define CIX_PAD_I2S2_DATA_OUT3_FUNC_I2S2_DATA_OUT3 (64 << 8 | 0x0) +#define CIX_PAD_I2S2_DATA_OUT3_FUNC_GPIO080 (64 << 8 | 0x1) +#define CIX_PAD_I2S2_DATA_OUT3_FUNC_I2S9_DATA_OUT1_DBG (64 << 8 | 0x2) +#define CIX_PAD_I2S3_MCLK_FUNC_I2S3_MCLK (65 << 8 | 0x0) +#define CIX_PAD_I2S3_MCLK_FUNC_GPIO081 (65 << 8 | 0x1) +#define CIX_PAD_I2S3_RSCK_FUNC_I2S3_RSCK (66 << 8 | 0x0) +#define CIX_PAD_I2S3_RSCK_FUNC_GPIO082 (66 << 8 | 0x1) +#define CIX_PAD_I2S3_RSCK_FUNC_I2S7_RSCK_DBG (66 << 8 | 0x2) +#define CIX_PAD_I2S3_RSCK_FUNC_I2S8_RSCK_DBG (66 << 8 | 0x3) +#define CIX_PAD_I2S3_RWS_FUNC_I2S3_RWS (67 << 8 | 0x0) +#define CIX_PAD_I2S3_RWS_FUNC_GPIO083 (67 << 8 | 0x1) +#define CIX_PAD_I2S3_RWS_FUNC_I2S7_RWS_DBG (67 << 8 | 0x2) +#define CIX_PAD_I2S3_RWS_FUNC_I2S8_RWS_DBG (67 << 8 | 0x3) +#define CIX_PAD_I2S3_TSCK_FUNC_I2S3_TSCK (68 << 8 | 0x0) +#define CIX_PAD_I2S3_TSCK_FUNC_GPIO084 (68 << 8 | 0x1) +#define CIX_PAD_I2S3_TSCK_FUNC_I2S7_TSCK_DBG (68 << 8 | 0x2) +#define CIX_PAD_I2S3_TSCK_FUNC_I2S8_TSCK_DBG (68 << 8 | 0x3) +#define CIX_PAD_I2S3_TWS_FUNC_I2S3_TWS (69 << 8 | 0x0) +#define CIX_PAD_I2S3_TWS_FUNC_GPIO085 (69 << 8 | 0x1) +#define CIX_PAD_I2S3_TWS_FUNC_I2S7_TWS_DBG (69 << 8 | 0x2) +#define CIX_PAD_I2S3_TWS_FUNC_I2S8_TWS_DBG (69 << 8 | 0x3) +#define CIX_PAD_I2S3_DATA_IN0_FUNC_I2S3_DATA_IN0 (70 << 8 | 0x0) +#define CIX_PAD_I2S3_DATA_IN0_FUNC_GPIO086 (70 << 8 | 0x1) +#define CIX_PAD_I2S3_DATA_IN0_FUNC_I2S7_DATA_IN0_DBG (70 << 8 | 0x2) +#define CIX_PAD_I2S3_DATA_IN0_FUNC_I2S8_DATA_IN0_DBG (70 << 8 | 0x3) +#define CIX_PAD_I2S3_DATA_IN1_FUNC_I2S3_DATA_IN1 (71 << 8 | 0x0) +#define CIX_PAD_I2S3_DATA_IN1_FUNC_GPIO087 (71 << 8 | 0x1) +#define CIX_PAD_I2S3_DATA_IN1_FUNC_I2S7_DATA_IN1_DBG (71 << 8 | 0x2) +#define CIX_PAD_I2S3_DATA_IN1_FUNC_I2S8_DATA_IN1_DBG (71 << 8 | 0x3) +#define CIX_PAD_I2S3_DATA_OUT0_FUNC_I2S3_DATA_OUT0 (72 << 8 | 0x0) +#define CIX_PAD_I2S3_DATA_OUT0_FUNC_GPIO088 (72 << 8 | 0x1) +#define CIX_PAD_I2S3_DATA_OUT0_FUNC_I2S7_DATA_OUT0_DBG (72 << 8 | 0x2) +#define CIX_PAD_I2S3_DATA_OUT0_FUNC_I2S8_DATA_OUT0_DBG (72 << 8 | 0x3) +#define CIX_PAD_I2S3_DATA_OUT1_FUNC_I2S3_DATA_OUT1 (73 << 8 | 0x0) +#define CIX_PAD_I2S3_DATA_OUT1_FUNC_GPIO089 (73 << 8 | 0x1) +#define CIX_PAD_I2S3_DATA_OUT1_FUNC_I2S7_DATA_OUT1_DBG (73 << 8 | 0x2) +#define CIX_PAD_I2S3_DATA_OUT1_FUNC_I2S8_DATA_OUT1_DBG (73 << 8 | 0x3) +#define CIX_PAD_GPIO090_FUNC_GPIO090 (74 << 8 | 0x0) +#define CIX_PAD_GPIO090_FUNC_I2S4_MCLK_LB (74 << 8 | 0x1) +#define CIX_PAD_GPIO091_FUNC_GPIO091 (75 << 8 | 0x0) +#define CIX_PAD_GPIO091_FUNC_I2S4_SCK_LB (75 << 8 | 0x1) +#define CIX_PAD_GPIO092_FUNC_GPIO092 (76 << 8 | 0x0) +#define CIX_PAD_GPIO092_FUNC_I2S4_WS_LB (76 << 8 | 0x1) +#define CIX_PAD_GPIO093_FUNC_GPIO093 (77 << 8 | 0x0) +#define CIX_PAD_GPIO093_FUNC_I2S4_DATA_IN_LB (77 << 8 | 0x1) +#define CIX_PAD_GPIO094_FUNC_GPIO094 (78 << 8 | 0x0) +#define CIX_PAD_GPIO094_FUNC_I2S4_DATA_OUT_LB (78 << 8 | 0x1) +#define CIX_PAD_UART0_TXD_FUNC_UART0_TXD (79 << 8 | 0x0) +#define CIX_PAD_UART0_TXD_FUNC_PWM0 (79 << 8 | 0x1) +#define CIX_PAD_UART0_TXD_FUNC_GPIO095 (79 << 8 | 0x2) +#define CIX_PAD_UART0_RXD_FUNC_UART0_RXD (80 << 8 | 0x0) +#define CIX_PAD_UART0_RXD_FUNC_PWM1 (80 << 8 | 0x1) +#define CIX_PAD_UART0_RXD_FUNC_GPIO096 (80 << 8 | 0x2) +#define CIX_PAD_UART0_CTS_FUNC_UART0_CTS (81 << 8 | 0x0) +#define CIX_PAD_UART0_CTS_FUNC_FAN_OUT2 (81 << 8 | 0x1) +#define CIX_PAD_UART0_CTS_FUNC_GPIO097 (81 << 8 | 0x2) +#define CIX_PAD_UART0_RTS_FUNC_UART0_RTS (82 << 8 | 0x0) +#define CIX_PAD_UART0_RTS_FUNC_FAN_TACH2 (82 << 8 | 0x1) +#define CIX_PAD_UART0_RTS_FUNC_GPIO098 (82 << 8 | 0x2) +#define CIX_PAD_UART1_TXD_FUNC_UART1_TXD (83 << 8 | 0x0) +#define CIX_PAD_UART1_TXD_FUNC_FAN_OUT0 (83 << 8 | 0x1) +#define CIX_PAD_UART1_TXD_FUNC_GPIO099 (83 << 8 | 0x2) +#define CIX_PAD_UART1_RXD_FUNC_UART1_RXD (84 << 8 | 0x0) +#define CIX_PAD_UART1_RXD_FUNC_FAN_TACH0 (84 << 8 | 0x1) +#define CIX_PAD_UART1_RXD_FUNC_GPIO100 (84 << 8 | 0x2) +#define CIX_PAD_UART1_CTS_FUNC_UART1_CTS (85 << 8 | 0x0) +#define CIX_PAD_UART1_CTS_FUNC_FAN_OUT1 (85 << 8 | 0x1) +#define CIX_PAD_UART1_CTS_FUNC_GPIO101 (85 << 8 | 0x2) +#define CIX_PAD_UART1_RTS_FUNC_UART1_RTS (86 << 8 | 0x0) +#define CIX_PAD_UART1_RTS_FUNC_FAN_TACH1 (86 << 8 | 0x1) +#define CIX_PAD_UART1_RTS_FUNC_GPIO102 (86 << 8 | 0x2) +#define CIX_PAD_UART2_TXD_FUNC_UART2_TXD (87 << 8 | 0x0) +#define CIX_PAD_UART2_TXD_FUNC_GPIO103 (87 << 8 | 0x1) +#define CIX_PAD_UART2_RXD_FUNC_UART2_RXD (88 << 8 | 0x0) +#define CIX_PAD_UART2_RXD_FUNC_GPIO104 (88 << 8 | 0x1) +#define CIX_PAD_UART3_TXD_FUNC_UART3_TXD (89 << 8 | 0x0) +#define CIX_PAD_UART3_TXD_FUNC_GPIO105 (89 << 8 | 0x1) +#define CIX_PAD_UART3_RXD_FUNC_UART3_RXD (90 << 8 | 0x0) +#define CIX_PAD_UART3_RXD_FUNC_GPIO106 (90 << 8 | 0x1) +#define CIX_PAD_UART3_CTS_FUNC_UART3_CTS (91 << 8 | 0x0) +#define CIX_PAD_UART3_CTS_FUNC_GPIO107 (91 << 8 | 0x1) +#define CIX_PAD_UART3_CTS_FUNC_TRIGIN0 (91 << 8 | 0x2) +#define CIX_PAD_UART3_RTS_FUNC_UART3_RTS (92 << 8 | 0x0) +#define CIX_PAD_UART3_RTS_FUNC_GPIO108 (92 << 8 | 0x1) +#define CIX_PAD_UART3_RTS_FUNC_TRIGIN1 (92 << 8 | 0x2) +#define CIX_PAD_UART4_CSU_PM_TXD_FUNC_UART4_CSU_PM_TXD (93 << 8 | 0x0) +#define CIX_PAD_UART4_CSU_PM_TXD_FUNC_GPIO109 (93 << 8 | 0x1) +#define CIX_PAD_UART4_CSU_PM_RXD_FUNC_UART4_CSU_PM_RXD (94 << 8 | 0x0) +#define CIX_PAD_UART4_CSU_PM_RXD_FUNC_GPIO110 (94 << 8 | 0x1) +#define CIX_PAD_UART5_CSU_SE_TXD_FUNC_UART5_CSU_SE_TXD (95 << 8 | 0x0) +#define CIX_PAD_UART5_CSU_SE_TXD_FUNC_GPIO111 (95 << 8 | 0x1) +#define CIX_PAD_UART5_CSU_SE_RXD_FUNC_UART5_CSU_SE_RXD (96 << 8 | 0x0) +#define CIX_PAD_UART5_CSU_SE_RXD_FUNC_GPIO112 (96 << 8 | 0x1) +#define CIX_PAD_UART6_CSU_SE_RXD_FUNC_UART6_CSU_SE_RXD (97 << 8 | 0x0) +#define CIX_PAD_UART6_CSU_SE_RXD_FUNC_GPIO113 (97 << 8 | 0x1) +#define CIX_PAD_CLK_REQ0_L_FUNC_CLK_REQ0_L (98 << 8 | 0x0) +#define CIX_PAD_CLK_REQ0_L_FUNC_GPIO114 (98 << 8 | 0x1) +#define CIX_PAD_CLK_REQ2_L_FUNC_CLK_REQ2_L (99 << 8 | 0x0) +#define CIX_PAD_CLK_REQ2_L_FUNC_GPIO115 (99 << 8 | 0x1) +#define CIX_PAD_CLK_REQ4_L_FUNC_CLK_REQ4_L (100 << 8 | 0x0) +#define CIX_PAD_CLK_REQ4_L_FUNC_GPIO116 (100 << 8 | 0x1) +#define CIX_PAD_CSI0_MCLK0_FUNC_CSI0_MCLK0 (101 << 8 | 0x0) +#define CIX_PAD_CSI0_MCLK0_FUNC_GPIO117 (101 << 8 | 0x1) +#define CIX_PAD_CSI0_MCLK1_FUNC_CSI0_MCLK1 (102 << 8 | 0x0) +#define CIX_PAD_CSI0_MCLK1_FUNC_GPIO118 (102 << 8 | 0x1) +#define CIX_PAD_CSI1_MCLK0_FUNC_CSI1_MCLK0 (103 << 8 | 0x0) +#define CIX_PAD_CSI1_MCLK0_FUNC_GPIO119 (103 << 8 | 0x1) +#define CIX_PAD_CSI1_MCLK1_FUNC_CSI1_MCLK1 (104 << 8 | 0x0) +#define CIX_PAD_CSI1_MCLK1_FUNC_GPIO120 (104 << 8 | 0x1) +#define CIX_PAD_GPIO121_FUNC_GPIO121 (105 << 8 | 0x0) +#define CIX_PAD_GPIO121_FUNC_GMAC0_REFCLK_25M (105 << 8 | 0x1) +#define CIX_PAD_GPIO122_FUNC_GPIO122 (106 << 8 | 0x0) +#define CIX_PAD_GPIO122_FUNC_GMAC0_TX_CTL (106 << 8 | 0x1) +#define CIX_PAD_GPIO123_FUNC_GPIO123 (107 << 8 | 0x0) +#define CIX_PAD_GPIO123_FUNC_GMAC0_TXD0 (107 << 8 | 0x1) +#define CIX_PAD_GPIO124_FUNC_GPIO124 (108 << 8 | 0x0) +#define CIX_PAD_GPIO124_FUNC_GMAC0_TXD1 (108 << 8 | 0x1) +#define CIX_PAD_GPIO125_FUNC_GPIO125 (109 << 8 | 0x0) +#define CIX_PAD_GPIO125_FUNC_GMAC0_TXD2 (109 << 8 | 0x1) +#define CIX_PAD_GPIO126_FUNC_GPIO126 (110 << 8 | 0x0) +#define CIX_PAD_GPIO126_FUNC_GMAC0_TXD3 (110 << 8 | 0x1) +#define CIX_PAD_GPIO127_FUNC_GPIO127 (111 << 8 | 0x0) +#define CIX_PAD_GPIO127_FUNC_GMAC0_TX_CLK (111 << 8 | 0x1) +#define CIX_PAD_GPIO128_FUNC_GPIO128 (112 << 8 | 0x0) +#define CIX_PAD_GPIO128_FUNC_GMAC0_RX_CTL (112 << 8 | 0x1) +#define CIX_PAD_GPIO129_FUNC_GPIO129 (113 << 8 | 0x0) +#define CIX_PAD_GPIO129_FUNC_GMAC0_RXD0 (113 << 8 | 0x1) +#define CIX_PAD_GPIO130_FUNC_GPIO130 (114 << 8 | 0x0) +#define CIX_PAD_GPIO130_FUNC_GMAC0_RXD1 (114 << 8 | 0x1) +#define CIX_PAD_GPIO131_FUNC_GPIO131 (115 << 8 | 0x0) +#define CIX_PAD_GPIO131_FUNC_GMAC0_RXD2 (115 << 8 | 0x1) +#define CIX_PAD_GPIO132_FUNC_GPIO132 (116 << 8 | 0x0) +#define CIX_PAD_GPIO132_FUNC_GMAC0_RXD3 (116 << 8 | 0x1) +#define CIX_PAD_GPIO133_FUNC_GPIO133 (117 << 8 | 0x0) +#define CIX_PAD_GPIO133_FUNC_GMAC0_RX_CLK (117 << 8 | 0x1) +#define CIX_PAD_GPIO134_FUNC_GPIO134 (118 << 8 | 0x0) +#define CIX_PAD_GPIO134_FUNC_GMAC0_MDC (118 << 8 | 0x1) +#define CIX_PAD_GPIO135_FUNC_GPIO135 (119 << 8 | 0x0) +#define CIX_PAD_GPIO135_FUNC_GMAC0_MDIO (119 << 8 | 0x1) +#define CIX_PAD_GPIO136_FUNC_GPIO136 (120 << 8 | 0x0) +#define CIX_PAD_GPIO136_FUNC_GMAC1_REFCLK_25M (120 << 8 | 0x1) +#define CIX_PAD_GPIO137_FUNC_GPIO137 (121 << 8 | 0x0) +#define CIX_PAD_GPIO137_FUNC_GMAC1_TX_CTL (121 << 8 | 0x1) +#define CIX_PAD_GPIO138_FUNC_GPIO138 (122 << 8 | 0x0) +#define CIX_PAD_GPIO138_FUNC_GMAC1_TXD0 (122 << 8 | 0x1) +#define CIX_PAD_GPIO138_FUNC_SPI2_MISO (122 << 8 | 0x2) +#define CIX_PAD_GPIO139_FUNC_GPIO139 (123 << 8 | 0x0) +#define CIX_PAD_GPIO139_FUNC_GMAC1_TXD1 (123 << 8 | 0x1) +#define CIX_PAD_GPIO139_FUNC_SPI2_CS0 (123 << 8 | 0x2) +#define CIX_PAD_GPIO140_FUNC_GPIO140 (124 << 8 | 0x0) +#define CIX_PAD_GPIO140_FUNC_GMAC1_TXD2 (124 << 8 | 0x1) +#define CIX_PAD_GPIO140_FUNC_SPI2_CS1 (124 << 8 | 0x2) +#define CIX_PAD_GPIO141_FUNC_GPIO141 (125 << 8 | 0x0) +#define CIX_PAD_GPIO141_FUNC_GMAC1_TXD3 (125 << 8 | 0x1) +#define CIX_PAD_GPIO141_FUNC_SPI2_MOSI (125 << 8 | 0x2) +#define CIX_PAD_GPIO142_FUNC_GPIO142 (126 << 8 | 0x0) +#define CIX_PAD_GPIO142_FUNC_GMAC1_TX_CLK (126 << 8 | 0x1) +#define CIX_PAD_GPIO142_FUNC_SPI2_CLK (126 << 8 | 0x2) +#define CIX_PAD_GPIO143_FUNC_GPIO143 (127 << 8 | 0x0) +#define CIX_PAD_GPIO143_FUNC_GMAC1_RX_CTL (127 << 8 | 0x1) +#define CIX_PAD_GPIO144_FUNC_GPIO144 (128 << 8 | 0x0) +#define CIX_PAD_GPIO144_FUNC_GMAC1_RXD0 (128 << 8 | 0x1) +#define CIX_PAD_GPIO145_FUNC_GPIO145 (129 << 8 | 0x0) +#define CIX_PAD_GPIO145_FUNC_GMAC1_RXD1 (129 << 8 | 0x1) +#define CIX_PAD_GPIO146_FUNC_GPIO146 (130 << 8 | 0x0) +#define CIX_PAD_GPIO146_FUNC_GMAC1_RXD2 (130 << 8 | 0x1) +#define CIX_PAD_GPIO147_FUNC_GPIO147 (131 << 8 | 0x0) +#define CIX_PAD_GPIO147_FUNC_GMAC1_RXD3 (131 << 8 | 0x1) +#define CIX_PAD_GPIO148_FUNC_GPIO148 (132 << 8 | 0x0) +#define CIX_PAD_GPIO148_FUNC_GMAC1_RX_CLK (132 << 8 | 0x1) +#define CIX_PAD_GPIO149_FUNC_GPIO149 (133 << 8 | 0x0) +#define CIX_PAD_GPIO149_FUNC_GMAC1_MDC (133 << 8 | 0x1) +#define CIX_PAD_GPIO150_FUNC_GPIO150 (134 << 8 | 0x0) +#define CIX_PAD_GPIO150_FUNC_GMAC1_MDIO (134 << 8 | 0x1) +#define CIX_PAD_GPIO151_FUNC_GPIO151 (135 << 8 | 0x0) +#define CIX_PAD_GPIO151_FUNC_PM_GPIO0 (135 << 8 | 0x1) +#define CIX_PAD_GPIO152_FUNC_GPIO152 (136 << 8 | 0x0) +#define CIX_PAD_GPIO152_FUNC_PM_GPIO1 (136 << 8 | 0x1) +#define CIX_PAD_GPIO153_FUNC_GPIO153 (137 << 8 | 0x0) +#define CIX_PAD_GPIO153_FUNC_PM_GPIO2 (137 << 8 | 0x1) + +#endif diff --git a/arch/arm64/boot/dts/cix/sky1.dtsi b/arch/arm64/boot/dts/cix/sky1.dtsi index 2fb2c99c0796d..64b76905cbff5 100644 --- a/arch/arm64/boot/dts/cix/sky1.dtsi +++ b/arch/arm64/boot/dts/cix/sky1.dtsi @@ -264,6 +264,26 @@ status = "disabled"; }; + spi0: spi@4090000 { + compatible = "cix,sky1-spi-r1p6", "cdns,spi-r1p6"; + reg = <0x0 0x04090000 0x0 0x10000>; + clocks = <&scmi_clk CLK_TREE_FCH_SPI0_APB>, + <&scmi_clk CLK_TREE_FCH_SPI0_APB>; + clock-names = "ref_clk", "pclk"; + interrupts = ; + status = "disabled"; + }; + + spi1: spi@40a0000 { + compatible = "cix,sky1-spi-r1p6", "cdns,spi-r1p6"; + reg = <0x0 0x040a0000 0x0 0x10000>; + clocks = <&scmi_clk CLK_TREE_FCH_SPI1_APB>, + <&scmi_clk CLK_TREE_FCH_SPI1_APB>; + clock-names = "ref_clk", "pclk"; + interrupts = ; + status = "disabled"; + }; + uart0: serial@40b0000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0 0x040b0000 0x0 0x1000>; @@ -328,6 +348,11 @@ status = "disabled"; }; + iomuxc: pinctrl@4170000 { + compatible = "cix,sky1-pinctrl"; + reg = <0x0 0x04170000 0x0 0x1000>; + }; + mbox_ap2se: mailbox@5060000 { compatible = "cix,sky1-mbox"; reg = <0x0 0x05060000 0x0 0x10000>; @@ -388,6 +413,132 @@ cix,mbox-dir = "tx"; }; + pcie_x8_rc: pcie@a010000 { + compatible = "cix,sky1-pcie-host"; + reg = <0x00 0x0a010000 0x00 0x10000>, + <0x00 0x2c000000 0x00 0x4000000>, + <0x00 0x0a000300 0x00 0x100>, + <0x00 0x0a000400 0x00 0x100>, + <0x00 0x60000000 0x00 0x00100000>; + reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg"; + ranges = <0x01000000 0x0 0x60100000 0x0 0x60100000 0x0 0x00100000>, + <0x02000000 0x0 0x60200000 0x0 0x60200000 0x0 0x1fe00000>, + <0x43000000 0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0xc0 0xff>; + device_type = "pci"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &gic 0 0 GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &gic 0 0 GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &gic 0 0 GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH 0>; + msi-map = <0xc000 &gic_its 0xc000 0x4000>; + status = "disabled"; + }; + + pcie_x4_rc: pcie@a070000 { + compatible = "cix,sky1-pcie-host"; + reg = <0x00 0x0a070000 0x00 0x10000>, + <0x00 0x29000000 0x00 0x3000000>, + <0x00 0x0a060300 0x00 0x40>, + <0x00 0x0a060400 0x00 0x40>, + <0x00 0x50000000 0x00 0x00100000>; + reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg"; + ranges = <0x01000000 0x00 0x50100000 0x00 0x50100000 0x00 0x00100000>, + <0x02000000 0x00 0x50200000 0x00 0x50200000 0x00 0x0fe00000>, + <0x43000000 0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x90 0xbf>; + device_type = "pci"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &gic 0 0 GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &gic 0 0 GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &gic 0 0 GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH 0>; + msi-map = <0x9000 &gic_its 0x9000 0x3000>; + status = "disabled"; + }; + + pcie_x2_rc: pcie@a0c0000 { + compatible = "cix,sky1-pcie-host"; + reg = <0x00 0x0a0c0000 0x00 0x10000>, + <0x00 0x26000000 0x00 0x3000000>, + <0x00 0x0a0600340 0x00 0x20>, + <0x00 0x0a0600440 0x00 0x20>, + <0x00 0x40000000 0x00 0x00100000>; + reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg"; + ranges = <0x01000000 0x0 0x40100000 0x0 0x40100000 0x0 0x00100000>, + <0x02000000 0x0 0x40200000 0x0 0x40200000 0x0 0x0fe00000>, + <0x43000000 0x10 0x00000000 0x10 0x00000000 0x04 0x00000000>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x60 0x8f>; + device_type = "pci"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &gic 0 0 GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &gic 0 0 GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &gic 0 0 GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH 0>; + msi-map = <0x6000 &gic_its 0x6000 0x3000>; + status = "disabled"; + }; + + pcie_x1_0_rc: pcie@a0d0000 { + compatible = "cix,sky1-pcie-host"; + reg = <0x00 0x0a0d0000 0x00 0x10000>, + <0x00 0x20000000 0x00 0x3000000>, + <0x00 0x0a060360 0x00 0x20>, + <0x00 0x0a060460 0x00 0x20>, + <0x00 0x30000000 0x00 0x00100000>; + reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg"; + ranges = <0x01000000 0x0 0x30100000 0x0 0x30100000 0x0 0x00100000>, + <0x02000000 0x0 0x30200000 0x0 0x30200000 0x0 0x07e00000>, + <0x43000000 0x08 0x00000000 0x08 0x00000000 0x04 0x00000000>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x00 0x2f>; + device_type = "pci"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &gic 0 0 GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &gic 0 0 GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &gic 0 0 GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH 0>; + msi-map = <0x0000 &gic_its 0x0000 0x3000>; + status = "disabled"; + }; + + pcie_x1_1_rc: pcie@a0e0000 { + compatible = "cix,sky1-pcie-host"; + reg = <0x00 0x0a0e0000 0x00 0x10000>, + <0x00 0x23000000 0x00 0x3000000>, + <0x00 0x0a060380 0x00 0x20>, + <0x00 0x0a060480 0x00 0x20>, + <0x00 0x38000000 0x00 0x00100000>; + reg-names = "reg", "cfg", "rcsu_strap", "rcsu_status", "msg"; + ranges = <0x01000000 0x0 0x38100000 0x0 0x38100000 0x0 0x00100000>, + <0x02000000 0x0 0x38200000 0x0 0x38200000 0x0 0x07e00000>, + <0x43000000 0x0C 0x00000000 0x0C 0x00000000 0x04 0x00000000>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x30 0x5f>; + device_type = "pci"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &gic 0 0 GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &gic 0 0 GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &gic 0 0 GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH 0>; + msi-map = <0x3000 &gic_its 0x3000 0x3000>; + status = "disabled"; + }; + gic: interrupt-controller@e010000 { compatible = "arm,gic-v3"; reg = <0x0 0x0e010000 0 0x10000>, /* GICD */ @@ -416,6 +567,11 @@ }; }; }; + + iomuxc_s5: pinctrl@16007000 { + compatible = "cix,sky1-pinctrl-s5"; + reg = <0x0 0x16007000 0x0 0x1000>; + }; }; timer { diff --git a/arch/arm64/boot/dts/exynos/exynos7870-a2corelte.dts b/arch/arm64/boot/dts/exynos/exynos7870-a2corelte.dts index eb7b485931874..6f40ca4350ed7 100644 --- a/arch/arm64/boot/dts/exynos/exynos7870-a2corelte.dts +++ b/arch/arm64/boot/dts/exynos/exynos7870-a2corelte.dts @@ -27,20 +27,7 @@ }; chosen { - #address-cells = <2>; - #size-cells = <1>; - ranges; - stdout-path = &serial2; - - framebuffer@67000000 { - compatible = "simple-framebuffer"; - reg = <0x0 0x67000000 (540 * 960 * 4)>; - width = <540>; - height = <960>; - stride = <(540 * 4)>; - format = "a8r8g8b8"; - }; }; gpio-keys { @@ -110,8 +97,9 @@ pmsg-size = <0x4000>; }; - framebuffer@67000000 { + cont_splash_mem: framebuffer@67000000 { reg = <0x0 0x67000000 (540 * 960 * 4)>; + iommu-addresses = <&decon 0x67000000 (540 * 960 * 4)>; no-map; }; }; @@ -124,6 +112,47 @@ }; }; +&decon { + memory-region = <&cont_splash_mem>; + + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + + samsung,burst-clock-frequency = <836000000>; + samsung,esc-clock-frequency = <16000000>; + samsung,pll-clock-frequency = <26000000>; + + status = "okay"; + + panel@0 { + compatible = "syna,td4101-panel"; + reg = <0>; + + backlight-gpios = <&gpd3 7 GPIO_ACTIVE_LOW>; + + width-mm = <62>; + height-mm = <110>; + + panel-timing { + clock-frequency = <69336720>; + + hactive = <540>; + hsync-len = <4>; + hfront-porch = <364>; + hback-porch = <40>; + + vactive = <960>; + vsync-len = <2>; + vfront-porch = <244>; + vback-porch = <13>; + }; + }; +}; + &gpu { status = "okay"; }; @@ -447,6 +476,7 @@ vmmc-supply = <&vdd_ldo26>; vqmmc-supply = <&vdd_ldo27>; + bus-width = <8>; fifo-depth = <64>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; diff --git a/arch/arm64/boot/dts/exynos/exynos7870-j6lte.dts b/arch/arm64/boot/dts/exynos/exynos7870-j6lte.dts index b8ce433b93b1b..09f2367cfec93 100644 --- a/arch/arm64/boot/dts/exynos/exynos7870-j6lte.dts +++ b/arch/arm64/boot/dts/exynos/exynos7870-j6lte.dts @@ -27,20 +27,7 @@ }; chosen { - #address-cells = <2>; - #size-cells = <1>; - ranges; - stdout-path = &serial2; - - framebuffer@67000000 { - compatible = "simple-framebuffer"; - reg = <0x0 0x67000000 (720 * 1480 * 4)>; - width = <720>; - height = <1480>; - stride = <(720 * 4)>; - format = "a8r8g8b8"; - }; }; gpio-hall-effect-sensor { @@ -119,8 +106,9 @@ pmsg-size = <0x4000>; }; - framebuffer@67000000 { + cont_splash_mem: framebuffer@67000000 { reg = <0x0 0x67000000 (720 * 1480 * 4)>; + iommu-addresses = <&decon 0x67000000 (720 * 1480 * 4)>; no-map; }; }; @@ -133,6 +121,28 @@ }; }; +&decon { + memory-region = <&cont_splash_mem>; + + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + + samsung,burst-clock-frequency = <500000000>; + samsung,esc-clock-frequency = <16000000>; + samsung,pll-clock-frequency = <26000000>; + + status = "okay"; + + panel@0 { + compatible = "samsung,s6e8aa5x01-ams561ra01"; + reg = <0>; + }; +}; + &gpu { status = "okay"; }; @@ -430,6 +440,7 @@ vmmc-supply = <&vdd_ldo26>; vqmmc-supply = <&vdd_ldo27>; + bus-width = <8>; fifo-depth = <64>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; diff --git a/arch/arm64/boot/dts/exynos/exynos7870-on7xelte.dts b/arch/arm64/boot/dts/exynos/exynos7870-on7xelte.dts index b1d9eff5a8270..29e124c72e9d2 100644 --- a/arch/arm64/boot/dts/exynos/exynos7870-on7xelte.dts +++ b/arch/arm64/boot/dts/exynos/exynos7870-on7xelte.dts @@ -27,20 +27,7 @@ }; chosen { - #address-cells = <2>; - #size-cells = <1>; - ranges; - stdout-path = &serial2; - - framebuffer@67000000 { - compatible = "simple-framebuffer"; - reg = <0x0 0x67000000 (1080 * 1920 * 4)>; - width = <1080>; - height = <1920>; - stride = <(1080 * 4)>; - format = "a8r8g8b8"; - }; }; gpio-keys { @@ -108,8 +95,9 @@ pmsg-size = <0x4000>; }; - framebuffer@67000000 { + cont_splash_mem: framebuffer@67000000 { reg = <0x0 0x67000000 (1080 * 1920 * 4)>; + iommu-addresses = <&decon 0x67000000 (1080 * 1920 * 4)>; no-map; }; }; @@ -122,6 +110,47 @@ }; }; +&decon { + memory-region = <&cont_splash_mem>; + + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + + samsung,burst-clock-frequency = <1001000000>; + samsung,esc-clock-frequency = <16000000>; + samsung,pll-clock-frequency = <26000000>; + + status = "okay"; + + panel@0 { + compatible = "syna,td4300-panel"; + reg = <0>; + + backlight-gpios = <&gpd3 5 GPIO_ACTIVE_LOW>; + + width-mm = <68>; + height-mm = <121>; + + panel-timing { + clock-frequency = <144389520>; + + hactive = <1080>; + hsync-len = <4>; + hfront-porch = <120>; + hback-porch = <32>; + + vactive = <1920>; + vsync-len = <2>; + vfront-porch = <21>; + vback-porch = <4>; + }; + }; +}; + &gpu { status = "okay"; }; @@ -463,6 +492,7 @@ vmmc-supply = <&vdd_ldo26>; vqmmc-supply = <&vdd_ldo27>; + bus-width = <8>; fifo-depth = <64>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; diff --git a/arch/arm64/boot/dts/exynos/exynos7870.dtsi b/arch/arm64/boot/dts/exynos/exynos7870.dtsi index d5d347623b903..2827e10d69625 100644 --- a/arch/arm64/boot/dts/exynos/exynos7870.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos7870.dtsi @@ -178,6 +178,14 @@ "samsung,exynos7-pmu", "syscon"; reg = <0x10480000 0x10000>; + mipi_phy: mipi-phy { + compatible = "samsung,exynos7870-mipi-video-phy"; + #phy-cells = <1>; + + samsung,cam0-sysreg = <&syscon_cam0>; + samsung,disp-sysreg = <&syscon_disp>; + }; + reboot-mode { compatible = "syscon-reboot-mode"; offset = <0x080c>; @@ -675,6 +683,77 @@ <&cmu_mif CLK_GOUT_MIF_CMU_ISP_VRA>; }; + syscon_cam0: system-controller@144f1040 { + compatible = "samsung,exynos7870-cam0-sysreg", "syscon"; + reg = <0x144f1040 0x04>; + }; + + dsi: dsi@14800000 { + compatible = "samsung,exynos7870-mipi-dsi"; + reg = <0x14800000 0x100>; + interrupts = ; + + clocks = <&cmu_dispaud CLK_GOUT_DISPAUD_BUS_DISP>, + <&cmu_dispaud CLK_GOUT_DISPAUD_APB_DISP>, + <&cmu_dispaud CLK_GOUT_DISPAUD_MUX_MIPIPHY_TXBYTECLKHS_USER>, + <&cmu_dispaud CLK_GOUT_DISPAUD_MUX_MIPIPHY_RXCLKESC0_USER>; + clock-names = "bus", "pll", "byte", "esc"; + + phys = <&mipi_phy 1>; + phy-names = "dsim"; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dsi_to_decon: endpoint { + remote-endpoint = <&decon_to_dsi>; + }; + }; + }; + }; + + decon: display-controller@14830000 { + compatible = "samsung,exynos7870-decon"; + reg = <0x14830000 0x8000>; + interrupts = , + , + ; + interrupt-names = "fifo", "vsync", "lcd_sys"; + + clocks = <&cmu_dispaud CLK_GOUT_DISPAUD_MUX_PLL>, + <&cmu_dispaud CLK_GOUT_DISPAUD_MUX_BUS_USER>, + <&cmu_dispaud CLK_GOUT_DISPAUD_MUX_DECON_ECLK>, + <&cmu_dispaud CLK_GOUT_DISPAUD_MUX_DECON_VCLK>; + clock-names = "pclk_decon0", "aclk_decon0", + "decon0_eclk", "decon0_vclk"; + + iommus = <&sysmmu_decon>; + + status = "disabled"; + + port { + decon_to_dsi: endpoint { + remote-endpoint = <&dsi_to_decon>; + }; + }; + }; + + sysmmu_decon: iommu@14860000 { + compatible = "samsung,exynos-sysmmu"; + reg = <0x14860000 0x1000>; + interrupts = ; + #iommu-cells = <0>; + + clocks = <&cmu_dispaud CLK_GOUT_DISPAUD_MUX_BUS_USER>; + clock-names = "sysmmu"; + }; + pinctrl_dispaud: pinctrl@148c0000 { compatible = "samsung,exynos7870-pinctrl"; reg = <0x148c0000 0x1000>; @@ -692,6 +771,11 @@ <&cmu_mif CLK_GOUT_MIF_CMU_DISPAUD_DECON_ECLK>, <&cmu_mif CLK_GOUT_MIF_CMU_DISPAUD_DECON_VCLK>; }; + + syscon_disp: system-controller@148f100c { + compatible = "samsung,exynos7870-disp-sysreg", "syscon"; + reg = <0x148f100c 0x04>; + }; }; timer { diff --git a/arch/arm64/boot/dts/exynos/exynos990.dtsi b/arch/arm64/boot/dts/exynos/exynos990.dtsi index 7179109c49d0b..f8e2a31b4b751 100644 --- a/arch/arm64/boot/dts/exynos/exynos990.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos990.dtsi @@ -260,6 +260,12 @@ clock-names = "oscclk", "bus", "ip"; }; + sysreg_peric0: syscon@10420000 { + compatible = "samsung,exynos990-peric0-sysreg", "syscon"; + reg = <0x10420000 0x10000>; + clocks = <&cmu_peric0 CLK_GOUT_PERIC0_SYSREG_PCLK>; + }; + pinctrl_peric0: pinctrl@10430000 { compatible = "samsung,exynos990-pinctrl"; reg = <0x10430000 0x1000>; @@ -277,6 +283,12 @@ clock-names = "oscclk", "bus", "ip"; }; + sysreg_peric1: syscon@10720000 { + compatible = "samsung,exynos990-peric1-sysreg", "syscon"; + reg = <0x10720000 0x10000>; + clocks = <&cmu_peric1 CLK_GOUT_PERIC1_SYSREG_PCLK>; + }; + pinctrl_peric1: pinctrl@10730000 { compatible = "samsung,exynos990-pinctrl"; reg = <0x10730000 0x1000>; diff --git a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi index 0fdf2062930a9..6ee74d260776f 100644 --- a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi +++ b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi @@ -1449,11 +1449,37 @@ status = "disabled"; }; + cmu_mfc: clock-controller@19c00000 { + compatible = "samsung,exynosautov920-cmu-mfc"; + reg = <0x19c00000 0x8000>; + #clock-cells = <1>; + + clocks = <&xtcxo>, + <&cmu_top DOUT_CLKCMU_MFC_MFC>, + <&cmu_top DOUT_CLKCMU_MFC_WFD>; + clock-names = "oscclk", + "mfc", + "wfd"; + }; + pinctrl_aud: pinctrl@1a460000 { compatible = "samsung,exynosautov920-pinctrl"; reg = <0x1a460000 0x10000>; }; + cmu_m2m: clock-controller@1a800000 { + compatible = "samsung,exynosautov920-cmu-m2m"; + reg = <0x1a800000 0x8000>; + #clock-cells = <1>; + + clocks = <&xtcxo>, + <&cmu_top DOUT_CLKCMU_M2M_NOC>, + <&cmu_top DOUT_CLKCMU_M2M_JPEG>; + clock-names = "oscclk", + "noc", + "jpeg"; + }; + cmu_cpucl0: clock-controller@1ec00000 { compatible = "samsung,exynosautov920-cmu-cpucl0"; reg = <0x1ec00000 0x8000>; diff --git a/arch/arm64/boot/dts/exynos/google/gs101-pixel-common.dtsi b/arch/arm64/boot/dts/exynos/google/gs101-pixel-common.dtsi index 84ff3e047d3b3..93892adaa6794 100644 --- a/arch/arm64/boot/dts/exynos/google/gs101-pixel-common.dtsi +++ b/arch/arm64/boot/dts/exynos/google/gs101-pixel-common.dtsi @@ -109,6 +109,13 @@ system-power-controller; wakeup-source; + clocks { + compatible = "samsung,s2mpg10-clk"; + #clock-cells = <1>; + clock-output-names = "rtc32k_ap", "peri32k1", + "peri32k2"; + }; + regulators { }; }; diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi index 31c99526470d0..d06d1d05f3640 100644 --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -72,80 +73,96 @@ device_type = "cpu"; compatible = "arm,cortex-a55"; reg = <0x0000>; + clocks = <&acpm_ipc GS101_CLK_ACPM_DVFS_CPUCL0>; enable-method = "psci"; cpu-idle-states = <&ananke_cpu_sleep>; capacity-dmips-mhz = <250>; dynamic-power-coefficient = <70>; + operating-points-v2 = <&cpucl0_opp_table>; }; cpu1: cpu@100 { device_type = "cpu"; compatible = "arm,cortex-a55"; reg = <0x0100>; + clocks = <&acpm_ipc GS101_CLK_ACPM_DVFS_CPUCL0>; enable-method = "psci"; cpu-idle-states = <&ananke_cpu_sleep>; capacity-dmips-mhz = <250>; dynamic-power-coefficient = <70>; + operating-points-v2 = <&cpucl0_opp_table>; }; cpu2: cpu@200 { device_type = "cpu"; compatible = "arm,cortex-a55"; reg = <0x0200>; + clocks = <&acpm_ipc GS101_CLK_ACPM_DVFS_CPUCL0>; enable-method = "psci"; cpu-idle-states = <&ananke_cpu_sleep>; capacity-dmips-mhz = <250>; dynamic-power-coefficient = <70>; + operating-points-v2 = <&cpucl0_opp_table>; }; cpu3: cpu@300 { device_type = "cpu"; compatible = "arm,cortex-a55"; reg = <0x0300>; + clocks = <&acpm_ipc GS101_CLK_ACPM_DVFS_CPUCL0>; enable-method = "psci"; cpu-idle-states = <&ananke_cpu_sleep>; capacity-dmips-mhz = <250>; dynamic-power-coefficient = <70>; + operating-points-v2 = <&cpucl0_opp_table>; }; cpu4: cpu@400 { device_type = "cpu"; compatible = "arm,cortex-a76"; reg = <0x0400>; + clocks = <&acpm_ipc GS101_CLK_ACPM_DVFS_CPUCL1>; enable-method = "psci"; cpu-idle-states = <&enyo_cpu_sleep>; capacity-dmips-mhz = <620>; dynamic-power-coefficient = <284>; + operating-points-v2 = <&cpucl1_opp_table>; }; cpu5: cpu@500 { device_type = "cpu"; compatible = "arm,cortex-a76"; reg = <0x0500>; + clocks = <&acpm_ipc GS101_CLK_ACPM_DVFS_CPUCL1>; enable-method = "psci"; cpu-idle-states = <&enyo_cpu_sleep>; capacity-dmips-mhz = <620>; dynamic-power-coefficient = <284>; + operating-points-v2 = <&cpucl1_opp_table>; }; cpu6: cpu@600 { device_type = "cpu"; compatible = "arm,cortex-x1"; reg = <0x0600>; + clocks = <&acpm_ipc GS101_CLK_ACPM_DVFS_CPUCL2>; enable-method = "psci"; cpu-idle-states = <&hera_cpu_sleep>; capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <650>; + operating-points-v2 = <&cpucl2_opp_table>; }; cpu7: cpu@700 { device_type = "cpu"; compatible = "arm,cortex-x1"; reg = <0x0700>; + clocks = <&acpm_ipc GS101_CLK_ACPM_DVFS_CPUCL2>; enable-method = "psci"; cpu-idle-states = <&hera_cpu_sleep>; capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <650>; + operating-points-v2 = <&cpucl2_opp_table>; }; idle-states { @@ -183,6 +200,273 @@ }; }; + cpucl0_opp_table: opp-table-0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <537500>; + clock-latency-ns = <500000>; + }; + + opp-574000000 { + opp-hz = /bits/ 64 <574000000>; + opp-microvolt = <600000>; + clock-latency-ns = <500000>; + }; + + opp-738000000 { + opp-hz = /bits/ 64 <738000000>; + opp-microvolt = <618750>; + clock-latency-ns = <500000>; + }; + + opp-930000000 { + opp-hz = /bits/ 64 <930000000>; + opp-microvolt = <668750>; + clock-latency-ns = <500000>; + }; + + opp-1098000000 { + opp-hz = /bits/ 64 <1098000000>; + opp-microvolt = <712500>; + clock-latency-ns = <500000>; + }; + + opp-1197000000 { + opp-hz = /bits/ 64 <1197000000>; + opp-microvolt = <731250>; + clock-latency-ns = <500000>; + }; + + opp-1328000000 { + opp-hz = /bits/ 64 <1328000000>; + opp-microvolt = <762500>; + clock-latency-ns = <500000>; + }; + + opp-1401000000 { + opp-hz = /bits/ 64 <1401000000>; + opp-microvolt = <781250>; + clock-latency-ns = <500000>; + }; + + opp-1598000000 { + opp-hz = /bits/ 64 <1598000000>; + opp-microvolt = <831250>; + clock-latency-ns = <500000>; + }; + + opp-1704000000 { + opp-hz = /bits/ 64 <1704000000>; + opp-microvolt = <862500>; + clock-latency-ns = <500000>; + }; + + opp-1803000000 { + opp-hz = /bits/ 64 <1803000000>; + opp-microvolt = <906250>; + clock-latency-ns = <500000>; + }; + }; + + cpucl1_opp_table: opp-table-1 { + compatible = "operating-points-v2"; + opp-shared; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <506250>; + clock-latency-ns = <500000>; + }; + + opp-553000000 { + opp-hz = /bits/ 64 <553000000>; + opp-microvolt = <537500>; + clock-latency-ns = <500000>; + }; + + opp-696000000 { + opp-hz = /bits/ 64 <696000000>; + opp-microvolt = <562500>; + clock-latency-ns = <500000>; + }; + + opp-799000000 { + opp-hz = /bits/ 64 <799000000>; + opp-microvolt = <581250>; + clock-latency-ns = <500000>; + }; + + opp-910000000 { + opp-hz = /bits/ 64 <910000000>; + opp-microvolt = <606250>; + clock-latency-ns = <500000>; + }; + + opp-1024000000 { + opp-hz = /bits/ 64 <1024000000>; + opp-microvolt = <625000>; + clock-latency-ns = <500000>; + }; + + opp-1197000000 { + opp-hz = /bits/ 64 <1197000000>; + opp-microvolt = <662500>; + clock-latency-ns = <500000>; + }; + + opp-1328000000 { + opp-hz = /bits/ 64 <1328000000>; + opp-microvolt = <687500>; + clock-latency-ns = <500000>; + }; + + opp-1491000000 { + opp-hz = /bits/ 64 <1491000000>; + opp-microvolt = <731250>; + clock-latency-ns = <500000>; + }; + + opp-1663000000 { + opp-hz = /bits/ 64 <1663000000>; + opp-microvolt = <775000>; + clock-latency-ns = <500000>; + }; + + opp-1836000000 { + opp-hz = /bits/ 64 <1836000000>; + opp-microvolt = <818750>; + clock-latency-ns = <500000>; + }; + + opp-1999000000 { + opp-hz = /bits/ 64 <1999000000>; + opp-microvolt = <868750>; + clock-latency-ns = <500000>; + }; + + opp-2130000000 { + opp-hz = /bits/ 64 <2130000000>; + opp-microvolt = <918750>; + clock-latency-ns = <500000>; + }; + + opp-2253000000 { + opp-hz = /bits/ 64 <2253000000>; + opp-microvolt = <968750>; + clock-latency-ns = <500000>; + }; + }; + + cpucl2_opp_table: opp-table-2 { + compatible = "operating-points-v2"; + opp-shared; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <500000>; + clock-latency-ns = <500000>; + }; + + opp-851000000 { + opp-hz = /bits/ 64 <851000000>; + opp-microvolt = <556250>; + clock-latency-ns = <500000>; + }; + + opp-984000000 { + opp-hz = /bits/ 64 <984000000>; + opp-microvolt = <575000>; + clock-latency-ns = <500000>; + }; + + opp-1106000000 { + opp-hz = /bits/ 64 <1106000000>; + opp-microvolt = <606250>; + clock-latency-ns = <500000>; + }; + + opp-1277000000 { + opp-hz = /bits/ 64 <1277000000>; + opp-microvolt = <631250>; + clock-latency-ns = <500000>; + }; + + opp-1426000000 { + opp-hz = /bits/ 64 <1426000000>; + opp-microvolt = <662500>; + clock-latency-ns = <500000>; + }; + + opp-1582000000 { + opp-hz = /bits/ 64 <1582000000>; + opp-microvolt = <693750>; + clock-latency-ns = <500000>; + }; + + opp-1745000000 { + opp-hz = /bits/ 64 <1745000000>; + opp-microvolt = <731250>; + clock-latency-ns = <500000>; + }; + + opp-1826000000 { + opp-hz = /bits/ 64 <1826000000>; + opp-microvolt = <750000>; + clock-latency-ns = <500000>; + }; + + opp-2048000000 { + opp-hz = /bits/ 64 <2048000000>; + opp-microvolt = <793750>; + clock-latency-ns = <500000>; + }; + + opp-2188000000 { + opp-hz = /bits/ 64 <2188000000>; + opp-microvolt = <831250>; + clock-latency-ns = <500000>; + }; + + opp-2252000000 { + opp-hz = /bits/ 64 <2252000000>; + opp-microvolt = <850000>; + clock-latency-ns = <500000>; + }; + + opp-2401000000 { + opp-hz = /bits/ 64 <2401000000>; + opp-microvolt = <887500>; + clock-latency-ns = <500000>; + }; + + opp-2507000000 { + opp-hz = /bits/ 64 <2507000000>; + opp-microvolt = <925000>; + clock-latency-ns = <500000>; + }; + + opp-2630000000 { + opp-hz = /bits/ 64 <2630000000>; + opp-microvolt = <968750>; + clock-latency-ns = <500000>; + }; + + opp-2704000000 { + opp-hz = /bits/ 64 <2704000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + + opp-2802000000 { + opp-hz = /bits/ 64 <2802000000>; + opp-microvolt = <1056250>; + clock-latency-ns = <500000>; + }; + }; + /* ect node is required to be present by bootloader */ ect { }; @@ -202,6 +486,7 @@ firmware { acpm_ipc: power-management { compatible = "google,gs101-acpm-ipc"; + #clock-cells = <1>; mboxes = <&ap2apm_mailbox>; shmem = <&apm_sram>; }; @@ -288,13 +573,19 @@ cmu_misc: clock-controller@10010000 { compatible = "google,gs101-cmu-misc"; - reg = <0x10010000 0x8000>; + reg = <0x10010000 0x10000>; #clock-cells = <1>; clocks = <&cmu_top CLK_DOUT_CMU_MISC_BUS>, <&cmu_top CLK_DOUT_CMU_MISC_SSS>; clock-names = "bus", "sss"; }; + sysreg_misc: syscon@10030000 { + compatible = "google,gs101-misc-sysreg", "syscon"; + reg = <0x10030000 0x10000>; + clocks = <&cmu_misc CLK_GOUT_MISC_SYSREG_MISC_PCLK>; + }; + timer@10050000 { compatible = "google,gs101-mct", "samsung,exynos4210-mct"; @@ -365,7 +656,7 @@ cmu_peric0: clock-controller@10800000 { compatible = "google,gs101-cmu-peric0"; - reg = <0x10800000 0x4000>; + reg = <0x10800000 0x10000>; #clock-cells = <1>; clocks = <&ext_24_5m>, <&cmu_top CLK_DOUT_CMU_PERIC0_BUS>, @@ -911,7 +1202,7 @@ cmu_peric1: clock-controller@10c00000 { compatible = "google,gs101-cmu-peric1"; - reg = <0x10c00000 0x4000>; + reg = <0x10c00000 0x10000>; #clock-cells = <1>; clocks = <&ext_24_5m>, <&cmu_top CLK_DOUT_CMU_PERIC1_BUS>, @@ -1265,7 +1556,7 @@ cmu_hsi0: clock-controller@11000000 { compatible = "google,gs101-cmu-hsi0"; - reg = <0x11000000 0x4000>; + reg = <0x11000000 0x10000>; #clock-cells = <1>; clocks = <&ext_24_5m>, @@ -1277,6 +1568,12 @@ "usbdpdbg"; }; + sysreg_hsi0: syscon@11020000 { + compatible = "google,gs101-hsi0-sysreg", "syscon"; + reg = <0x11020000 0x10000>; + clocks = <&cmu_hsi0 CLK_GOUT_HSI0_SYSREG_HSI0_PCLK>; + }; + usbdrd31_phy: phy@11100000 { compatible = "google,gs101-usb31drd-phy"; reg = <0x11100000 0x0200>, @@ -1332,7 +1629,7 @@ cmu_hsi2: clock-controller@14400000 { compatible = "google,gs101-cmu-hsi2"; - reg = <0x14400000 0x4000>; + reg = <0x14400000 0x10000>; #clock-cells = <1>; clocks = <&ext_24_5m>, <&cmu_top CLK_DOUT_CMU_HSI2_BUS>, @@ -1395,16 +1692,16 @@ cmu_apm: clock-controller@17400000 { compatible = "google,gs101-cmu-apm"; - reg = <0x17400000 0x8000>; + reg = <0x17400000 0x10000>; #clock-cells = <1>; clocks = <&ext_24_5m>; clock-names = "oscclk"; }; - sysreg_apm: syscon@174204e0 { + sysreg_apm: syscon@17420000 { compatible = "google,gs101-apm-sysreg", "syscon"; - reg = <0x174204e0 0x1000>; + reg = <0x17420000 0x10000>; }; pmu_system_controller: system-controller@17460000 { @@ -1497,7 +1794,7 @@ cmu_top: clock-controller@1e080000 { compatible = "google,gs101-cmu-top"; - reg = <0x1e080000 0x8000>; + reg = <0x1e080000 0x10000>; #clock-cells = <1>; clocks = <&ext_24_5m>; diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile index 525ef180481d3..f30d3fd724d0c 100644 --- a/arch/arm64/boot/dts/freescale/Makefile +++ b/arch/arm64/boot/dts/freescale/Makefile @@ -136,12 +136,18 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-phg.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-av-10-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-av-10.dtbo +imx8mm-phyboard-polis-peb-av-10-etml1010g3dra-dtbs += imx8mm-phyboard-polis-rdk.dtb \ + imx8mm-phyboard-polis-peb-av-10-etml1010g3dra.dtbo +imx8mm-phyboard-polis-peb-av-10-ph128800t006-dtbs += imx8mm-phyboard-polis-rdk.dtb \ + imx8mm-phyboard-polis-peb-av-10-ph128800t006.dtbo imx8mm-phyboard-polis-peb-eval-01-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-eval-01.dtbo imx8mm-phycore-no-eth-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phycore-no-eth.dtbo imx8mm-phycore-no-spiflash-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phycore-no-spiflash.dtbo imx8mm-phycore-rpmsg-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phycore-rpmsg.dtbo dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-av-10.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-av-10-etml1010g3dra.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-av-10-ph128800t006.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-eval-01.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-phycore-no-eth.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-phycore-no-spiflash.dtb @@ -226,14 +232,32 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-navqp.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-nitrogen-enc-carrier-board.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-nitrogen-smarc-universal-board.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk.dtb +imx8mp-phyboard-pollux-etml1010g3dra-dtbs += imx8mp-phyboard-pollux-rdk.dtb \ + imx8mp-phyboard-pollux-etml1010g3dra.dtbo +imx8mp-phyboard-pollux-peb-av-10-dtbs += imx8mp-phyboard-pollux-rdk.dtb \ + imx8mp-phyboard-pollux-peb-av-10.dtbo +imx8mp-phyboard-pollux-peb-av-10-etml1010g3dra-dtbs += imx8mp-phyboard-pollux-rdk.dtb \ + imx8mp-phyboard-pollux-peb-av-10-etml1010g3dra.dtbo +imx8mp-phyboard-pollux-peb-av-10-ph128800t006-dtbs += imx8mp-phyboard-pollux-rdk.dtb \ + imx8mp-phyboard-pollux-peb-av-10-ph128800t006.dtbo +imx8mp-phyboard-pollux-ph128800t006-dtbs += imx8mp-phyboard-pollux-rdk.dtb \ + imx8mp-phyboard-pollux-ph128800t006.dtbo imx8mp-phyboard-pollux-rdk-no-eth-dtbs += imx8mp-phyboard-pollux-rdk.dtb imx8mp-phycore-no-eth.dtbo +dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-etml1010g3dra.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-peb-av-10.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-peb-av-10-etml1010g3dra.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-peb-av-10-ph128800t006.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-ph128800t006.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk-no-eth.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-prt8ml.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-basic.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revb-hdmi.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revb-lt6.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revb-mi1010ait-1cp1.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revc-bd500.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revc-hdmi.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revc-tian-g07017.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revc-jutouch-jt101tm023.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-toradex-smarc-dev.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-tqma8mpql-mba8mpxl.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-tqma8mpql-mba8mp-ras314.dtb @@ -344,6 +368,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-tqma8xqps-mb-smarc-2.dtb dtb-$(CONFIG_ARCH_MXC) += imx8ulp-9x9-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8ulp-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx91-11x11-evk.dtb +dtb-$(CONFIG_ARCH_MXC) += imx91-phyboard-segin.dtb dtb-$(CONFIG_ARCH_MXC) += imx91-tqma9131-mba91xxca.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-9x9-qsb.dtb @@ -356,11 +381,15 @@ dtb-$(CONFIG_ARCH_MXC) += imx93-kontron-bl-osm-s.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-nash.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin.dtb +imx93-phyboard-nash-jtag-dtbs += imx93-phyboard-nash.dtb imx93-phyboard-nash-jtag.dtbo imx93-phyboard-nash-peb-wlbt-07-dtbs += imx93-phyboard-nash.dtb imx93-phyboard-nash-peb-wlbt-07.dtbo +imx93-phyboard-nash-pwm-fan-dtbs += imx93-phyboard-nash.dtb imx93-phyboard-nash-pwm-fan.dtbo imx93-phyboard-segin-peb-eval-01-dtbs += imx93-phyboard-segin.dtb imx93-phyboard-segin-peb-eval-01.dtbo imx93-phyboard-segin-peb-wlbt-05-dtbs += imx93-phyboard-segin.dtb imx93-phyboard-segin-peb-wlbt-05.dtbo imx93-phycore-rpmsg-dtbs += imx93-phyboard-nash.dtb imx93-phyboard-segin.dtb imx93-phycore-rpmsg.dtbo +dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-nash-jtag.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-nash-peb-wlbt-07.dtb +dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-nash-pwm-fan.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin-peb-eval-01.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin-peb-wlbt-05.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-phycore-rpmsg.dtb @@ -373,6 +402,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx943-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-15x15-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk-sof.dtb +dtb-$(CONFIG_ARCH_MXC) += imx95-toradex-smarc-dev.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-tqma9596sa-mb-smarc-2.dtb imx95-15x15-evk-pcie0-ep-dtbs = imx95-15x15-evk.dtb imx-pcie0-ep.dtbo @@ -382,6 +412,8 @@ imx95-19x19-evk-pcie1-ep-dtbs += imx95-19x19-evk.dtb imx-pcie1-ep.dtbo dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk-pcie0-ep.dtb imx95-19x19-evk-pcie1-ep.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-libra-rdk-fpsc.dtb +dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-verdin-evk.dtb + imx8mm-kontron-dl-dtbs := imx8mm-kontron-bl.dtb imx8mm-kontron-dl.dtbo imx8mm-kontron-bl-lte-dtbs := imx8mm-kontron-bl.dtb imx8mm-kontron-bl-lte.dtbo diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi index fc3e138077b86..ef80bf6a604f4 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi @@ -493,10 +493,11 @@ }; usb0: usb@2f00000 { - compatible = "snps,dwc3"; + compatible = "fsl,ls1012a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x2f00000 0x0 0x10000>; interrupts = ; dr_mode = "host"; + dma-coherent; snps,quirk-frame-length-adjustment = <0x20>; snps,dis_rxdet_inp3_quirk; snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi index 7d172d7e5737c..e7f9c9319319a 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi @@ -613,9 +613,11 @@ }; usb0: usb@3100000 { - compatible = "fsl,ls1028a-dwc3", "snps,dwc3"; + compatible = "fsl,ls1028a-dwc3"; reg = <0x0 0x3100000 0x0 0x10000>; interrupts = ; + iommus = <&smmu 1>; + dma-coherent; snps,dis_rxdet_inp3_quirk; snps,quirk-frame-length-adjustment = <0x20>; snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; @@ -623,9 +625,11 @@ }; usb1: usb@3110000 { - compatible = "fsl,ls1028a-dwc3", "snps,dwc3"; + compatible = "fsl,ls1028a-dwc3"; reg = <0x0 0x3110000 0x0 0x10000>; interrupts = ; + iommus = <&smmu 2>; + dma-coherent; snps,dis_rxdet_inp3_quirk; snps,quirk-frame-length-adjustment = <0x20>; snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 73315c5170394..50d9b03a284a2 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -833,10 +833,11 @@ dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>; usb0: usb@2f00000 { - compatible = "snps,dwc3"; + compatible = "fsl,ls1043a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x2f00000 0x0 0x10000>; interrupts = ; dr_mode = "host"; + dma-coherent; snps,quirk-frame-length-adjustment = <0x20>; snps,dis_rxdet_inp3_quirk; usb3-lpm-capable; @@ -845,10 +846,11 @@ }; usb1: usb@3000000 { - compatible = "snps,dwc3"; + compatible = "fsl,ls1043a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x3000000 0x0 0x10000>; interrupts = ; dr_mode = "host"; + dma-coherent; snps,quirk-frame-length-adjustment = <0x20>; snps,dis_rxdet_inp3_quirk; usb3-lpm-capable; @@ -857,10 +859,11 @@ }; usb2: usb@3100000 { - compatible = "snps,dwc3"; + compatible = "fsl,ls1043a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x3100000 0x0 0x10000>; interrupts = ; dr_mode = "host"; + dma-coherent; snps,quirk-frame-length-adjustment = <0x20>; snps,dis_rxdet_inp3_quirk; usb3-lpm-capable; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts index 736722b58e77f..48a6c08fcea82 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts @@ -42,6 +42,21 @@ chosen { stdout-path = "serial0:115200n8"; }; + + sfp1: sfp-1 { + compatible = "sff,sfp"; + i2c-bus = <&sfp1_i2c>; + maximum-power-milliwatt = <2000>; + mod-def0-gpios = <&stat_pres2 6 GPIO_ACTIVE_LOW>; + }; + + sfp2: sfp-2 { + compatible = "sff,sfp"; + i2c-bus = <&sfp2_i2c>; + maximum-power-milliwatt = <2000>; + mod-def0-gpios = <&stat_pres2 7 GPIO_ACTIVE_LOW>; + }; + }; &dspi { @@ -139,6 +154,31 @@ reg = <0x4c>; }; }; + + i2c@7 { + reg = <0x7>; + #address-cells = <1>; + #size-cells = <0>; + + i2c-mux@76 { + compatible = "nxp,pca9547"; + reg = <0x76>; + #address-cells = <1>; + #size-cells = <0>; + + sfp1_i2c: i2c@6 { + reg = <0x6>; + #address-cells = <1>; + #size-cells = <0>; + }; + + sfp2_i2c: i2c@7 { + reg = <0x7>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; }; }; @@ -166,8 +206,20 @@ fpga: board-control@2,0 { compatible = "fsl,ls1046aqds-fpga", "fsl,fpga-qixis", "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; reg = <0x2 0x0 0x0000100>; ranges = <0 2 0 0x100>; + + stat_pres2: gpio@c { + compatible = "fsl,ls1046aqds-fpga-gpio-stat-pres2"; + reg = <0xc 1>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "SLOT1", "SLOT2", "SLOT3", "SLOT4", "SLOT5", "SLOT6", + "SFP1_MOD_DEF", "SFP2_MOD_DEF"; + }; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index 770d91ef0310d..22173d69713d1 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -749,10 +749,11 @@ dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>; usb0: usb@2f00000 { - compatible = "snps,dwc3"; + compatible = "fsl,ls1046a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x2f00000 0x0 0x10000>; interrupts = ; dr_mode = "host"; + dma-coherent; snps,quirk-frame-length-adjustment = <0x20>; snps,dis_rxdet_inp3_quirk; snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; @@ -760,10 +761,11 @@ }; usb1: usb@3000000 { - compatible = "snps,dwc3"; + compatible = "fsl,ls1046a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x3000000 0x0 0x10000>; interrupts = ; dr_mode = "host"; + dma-coherent; snps,quirk-frame-length-adjustment = <0x20>; snps,dis_rxdet_inp3_quirk; snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; @@ -771,10 +773,11 @@ }; usb2: usb@3100000 { - compatible = "snps,dwc3"; + compatible = "fsl,ls1046a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x3100000 0x0 0x10000>; interrupts = ; dr_mode = "host"; + dma-coherent; snps,quirk-frame-length-adjustment = <0x20>; snps,dis_rxdet_inp3_quirk; snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts index 3a11068f2212f..71765ec91745e 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts @@ -253,6 +253,10 @@ reg = <0x2d>; }; + uc: board-controller@7e { + compatible = "traverse,ten64-controller"; + reg = <0x7e>; + }; }; &i2c2 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi index 9d5726378aa01..b2f6cd237be04 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -489,10 +489,12 @@ }; usb0: usb@3100000 { - compatible = "snps,dwc3"; + compatible = "fsl,ls1088a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x3100000 0x0 0x10000>; interrupts = ; dr_mode = "host"; + iommus = <&smmu 1>; + dma-coherent; snps,quirk-frame-length-adjustment = <0x20>; snps,dis_rxdet_inp3_quirk; snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; @@ -500,10 +502,12 @@ }; usb1: usb@3110000 { - compatible = "snps,dwc3"; + compatible = "fsl,ls1088a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x3110000 0x0 0x10000>; interrupts = ; dr_mode = "host"; + iommus = <&smmu 2>; + dma-coherent; snps,quirk-frame-length-adjustment = <0x20>; snps,dis_rxdet_inp3_quirk; snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts index 2d01e20b47e7f..d8ef68ad3bcc7 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include "fsl-lx2160a.dtsi" +#include "fsl-lx2160a-rev2.dtsi" / { model = "NXP Layerscape LX2160AQDS"; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts index 0c44b3cbef773..935f421475acb 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include "fsl-lx2160a.dtsi" +#include "fsl-lx2160a-rev2.dtsi" / { model = "NXP Layerscape LX2160ARDB"; @@ -31,6 +31,28 @@ regulator-boot-on; regulator-always-on; }; + + sfp2: sfp-2 { + compatible = "sff,sfp"; + i2c-bus = <&sfp2_i2c>; + maximum-power-milliwatt = <2000>; + /* Leave commented out if using DPMAC_LINK_TYPE_FIXED mode */ + /* tx-disable-gpios = <&sfp2_csr 0 GPIO_ACTIVE_HIGH>; */ + los-gpios = <&sfp2_csr 4 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&sfp2_csr 5 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&sfp2_csr 7 GPIO_ACTIVE_LOW>; + }; + + sfp3: sfp-3 { + compatible = "sff,sfp"; + i2c-bus = <&sfp3_i2c>; + maximum-power-milliwatt = <2000>; + /* Leave commented out if using DPMAC_LINK_TYPE_FIXED mode */ + /* tx-disable-gpios = <&sfp3_csr 0 GPIO_ACTIVE_HIGH>; */ + los-gpios = <&sfp3_csr 4 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&sfp3_csr 5 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&sfp3_csr 7 GPIO_ACTIVE_LOW>; + }; }; &crypto { @@ -170,6 +192,37 @@ &i2c0 { status = "okay"; + cpld@66 { + compatible = "fsl,lx2160ardb-fpga"; + reg = <0x66>; + #address-cells = <1>; + #size-cells = <0>; + + sfp2_csr: gpio@19 { + compatible = "fsl,lx2160ardb-fpga-gpio-sfp"; + reg = <0x19>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "SFP2_TX_EN", "", + "", "", + "SFP2_RX_LOS", "SFP2_TX_FAULT", + "", "SFP2_MOD_ABS"; + }; + + sfp3_csr: gpio@1a { + compatible = "fsl,lx2160ardb-fpga-gpio-sfp"; + reg = <0x1a>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "SFP3_TX_EN", "", + "", "", + "SFP3_RX_LOS", "SFP3_TX_FAULT", + "", "SFP3_MOD_ABS"; + }; + }; + i2c-mux@77 { compatible = "nxp,pca9547"; reg = <0x77>; @@ -205,6 +258,31 @@ vcc-supply = <&sb_3v3>; }; }; + + i2c@7 { + reg = <0x7>; + #address-cells = <1>; + #size-cells = <0>; + + i2c-mux@75 { + compatible = "nxp,pca9547"; + reg = <0x75>; + #address-cells = <1>; + #size-cells = <0>; + + sfp2_i2c: i2c@4 { + reg = <0x4>; + #address-cells = <1>; + #size-cells = <0>; + }; + + sfp3_i2c: i2c@5 { + reg = <0x5>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi index c9541403bcd82..d899c0355e51d 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi @@ -1094,24 +1094,28 @@ }; usb0: usb@3100000 { - compatible = "snps,dwc3"; + compatible = "fsl,lx2160a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x3100000 0x0 0x10000>; interrupts = ; dr_mode = "host"; snps,quirk-frame-length-adjustment = <0x20>; usb3-lpm-capable; + iommus = <&smmu 1>; + dma-coherent; snps,dis_rxdet_inp3_quirk; snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; status = "disabled"; }; usb1: usb@3110000 { - compatible = "snps,dwc3"; + compatible = "fsl,lx2160a-dwc3", "fsl,ls1028a-dwc3"; reg = <0x0 0x3110000 0x0 0x10000>; interrupts = ; dr_mode = "host"; snps,quirk-frame-length-adjustment = <0x20>; usb3-lpm-capable; + iommus = <&smmu 2>; + dma-coherent; snps,dis_rxdet_inp3_quirk; snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; status = "disabled"; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2162a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-lx2162a-qds.dts index 9f5ff1ffe7d5e..7a595fddc0273 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2162a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-lx2162a-qds.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include "fsl-lx2160a.dtsi" +#include "fsl-lx2160a-rev2.dtsi" / { model = "NXP Layerscape LX2162AQDS"; diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi index 311d4950793cf..06790255a764a 100644 --- a/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi @@ -109,7 +109,10 @@ status = "okay"; }; -/* TODO: Apalis BKL1_PWM */ +/* Apalis BKL1_PWM */ +&pwm_lvds1 { + status = "okay"; +}; /* Apalis DAP1 */ &sai1 { diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi index 3d8731504ce15..7022de46b8bff 100644 --- a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi @@ -196,7 +196,10 @@ status = "okay"; }; -/* TODO: Apalis BKL1_PWM */ +/* Apalis BKL1_PWM */ +&pwm_lvds1 { + status = "okay"; +}; /* Apalis DAP1 */ &sai1 { diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi index 106e802a68ba5..12732ed7f8119 100644 --- a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi @@ -245,7 +245,10 @@ status = "okay"; }; -/* TODO: Apalis BKL1_PWM */ +/* Apalis BKL1_PWM */ +&pwm_lvds1 { + status = "okay"; +}; /* Apalis DAP1 */ &sai1 { diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi index 86d018f470c1a..9153dddfd3b84 100644 --- a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi @@ -18,7 +18,7 @@ brightness-levels = <0 45 63 88 119 158 203 255>; default-brightness-level = <4>; enable-gpios = <&lsio_gpio1 4 GPIO_ACTIVE_HIGH>; /* Apalis BKL1_ON */ - /* TODO: hook-up to Apalis BKL1_PWM */ + pwms = <&pwm_lvds1 0 6666667 PWM_POLARITY_INVERTED>; status = "disabled"; }; @@ -31,12 +31,6 @@ 3000 1>; }; - /* TODO: LVDS Panel */ - - /* TODO: Shared PCIe/SATA Reference Clock */ - - /* TODO: PCIe Wi-Fi Reference Clock */ - /* * Power management bus used to control LDO1OUT of the * second PMIC PF8100. This is used for controlling voltage levels of @@ -83,8 +77,8 @@ gpio = <&lsio_gpio1 28 GPIO_ACTIVE_HIGH>; enable-active-high; regulator-always-on; - regulator-name = "wifi_pwrdn_fake_regulator"; - regulator-settling-time-us = <100>; + regulator-name = "Wi-Fi_POWER_DOWN"; /* Wi-Fi module PDn */ + startup-delay-us = <100>; }; reg_pcie_switch: regulator-pcie-switch { @@ -232,6 +226,34 @@ spdif-out; }; + thermal-zones { + pmic-thermal { + polling-delay-passive = <250>; + polling-delay = <2000>; + thermal-sensors = <&tsens IMX_SC_R_PMIC_0>; + + cooling-maps { + cooling_maps_map0: map0 { + trip = <&pmic_alert0>; + }; + }; + + trips { + pmic_alert0: trip0 { + hysteresis = <2000>; + temperature = <110000>; + type = "passive"; + }; + + pmic_crit0: trip1 { + hysteresis = <2000>; + temperature = <125000>; + type = "critical"; + }; + }; + }; + }; + touchscreen: touchscreen { compatible = "toradex,vf50-touchscreen"; interrupt-parent = <&lsio_gpio3>; @@ -262,15 +284,15 @@ &adc0 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_adc0>; + vref-supply = <®_vref_1v8>; }; &adc1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_adc1>; + vref-supply = <®_vref_1v8>; }; -/* TODO: Asynchronous Sample Rate Converter (ASRC) */ - &cpu_alert0 { temperature = <95000>; }; @@ -799,7 +821,10 @@ <&hsio_refa_clk>, <&hsio_per_clk>; }; -/* TODO: Apalis BKL1_PWM */ +&pwm_lvds1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm_bkl>; +}; /* Apalis DAP1 */ &sai1 { @@ -841,8 +866,6 @@ status = "okay"; }; -/* TODO: Thermal Zones */ - /* TODO: Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */ /* Apalis USBH4 */ diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi index c32a6947ae9c4..5e4233ccfde46 100644 --- a/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi @@ -296,7 +296,8 @@ audio_subsys: bus@59000000 { , /* 20 unused */ , /* 21 */ , /* 22 unused */ - ; /* 23 unused */ + , /* 23 unused */ + ; power-domains = <&pd IMX_SC_R_DMA_0_CH0>, <&pd IMX_SC_R_DMA_0_CH1>, <&pd IMX_SC_R_DMA_0_CH2>, @@ -558,7 +559,8 @@ audio_subsys: bus@59000000 { , /* 7 unused */ , /* sai4 */ , - ; /* sai5 */ + , /* sai5 */ + ; power-domains = <&pd IMX_SC_R_DMA_1_CH0>, <&pd IMX_SC_R_DMA_1_CH1>, <&pd IMX_SC_R_DMA_1_CH2>, diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi index ce6ef160fd550..176e2e332f87c 100644 --- a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi @@ -77,7 +77,11 @@ conn_subsys: bus@5b000000 { <&sdhc0_lpcg IMX_LPCG_CLK_5>, <&sdhc0_lpcg IMX_LPCG_CLK_0>; clock-names = "ipg", "ahb", "per"; + assigned-clocks = <&clk IMX_SC_R_SDHC_0 IMX_SC_PM_CLK_PER>; + assigned-clock-rates = <400000000>; power-domains = <&pd IMX_SC_R_SDHC_0>; + fsl,tuning-start-tap = <20>; + fsl,tuning-step = <2>; status = "disabled"; }; @@ -88,6 +92,8 @@ conn_subsys: bus@5b000000 { <&sdhc1_lpcg IMX_LPCG_CLK_5>, <&sdhc1_lpcg IMX_LPCG_CLK_0>; clock-names = "ipg", "ahb", "per"; + assigned-clocks = <&clk IMX_SC_R_SDHC_1 IMX_SC_PM_CLK_PER>; + assigned-clock-rates = <200000000>; power-domains = <&pd IMX_SC_R_SDHC_1>; fsl,tuning-start-tap = <20>; fsl,tuning-step = <2>; @@ -101,7 +107,11 @@ conn_subsys: bus@5b000000 { <&sdhc2_lpcg IMX_LPCG_CLK_5>, <&sdhc2_lpcg IMX_LPCG_CLK_0>; clock-names = "ipg", "ahb", "per"; + assigned-clocks = <&clk IMX_SC_R_SDHC_2 IMX_SC_PM_CLK_PER>; + assigned-clock-rates = <200000000>; power-domains = <&pd IMX_SC_R_SDHC_2>; + fsl,tuning-start-tap = <20>; + fsl,tuning-step = <2>; status = "disabled"; }; @@ -114,8 +124,9 @@ conn_subsys: bus@5b000000 { clocks = <&enet0_lpcg IMX_LPCG_CLK_4>, <&enet0_lpcg IMX_LPCG_CLK_2>, <&enet0_lpcg IMX_LPCG_CLK_3>, - <&enet0_lpcg IMX_LPCG_CLK_0>; - clock-names = "ipg", "ahb", "enet_clk_ref", "ptp"; + <&enet0_lpcg IMX_LPCG_CLK_0>, + <&enet0_lpcg IMX_LPCG_CLK_1>; + clock-names = "ipg", "ahb", "enet_clk_ref", "ptp", "enet_2x_txclk"; assigned-clocks = <&clk IMX_SC_R_ENET_0 IMX_SC_PM_CLK_PER>, <&clk IMX_SC_R_ENET_0 IMX_SC_C_CLKDIV>; assigned-clock-rates = <250000000>, <125000000>; @@ -134,8 +145,9 @@ conn_subsys: bus@5b000000 { clocks = <&enet1_lpcg IMX_LPCG_CLK_4>, <&enet1_lpcg IMX_LPCG_CLK_2>, <&enet1_lpcg IMX_LPCG_CLK_3>, - <&enet1_lpcg IMX_LPCG_CLK_0>; - clock-names = "ipg", "ahb", "enet_clk_ref", "ptp"; + <&enet1_lpcg IMX_LPCG_CLK_0>, + <&enet0_lpcg IMX_LPCG_CLK_1>; + clock-names = "ipg", "ahb", "enet_clk_ref", "ptp", "enet_2x_txclk"; assigned-clocks = <&clk IMX_SC_R_ENET_1 IMX_SC_PM_CLK_PER>, <&clk IMX_SC_R_ENET_1 IMX_SC_C_CLKDIV>; assigned-clock-rates = <250000000>, <125000000>; diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi index 575be8115e427..4de78f870c05c 100644 --- a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi @@ -182,7 +182,8 @@ dma_subsys: bus@5a000000 { , , , - ; + , + ; power-domains = <&pd IMX_SC_R_DMA_2_CH0>, <&pd IMX_SC_R_DMA_2_CH1>, <&pd IMX_SC_R_DMA_2_CH2>, @@ -466,7 +467,8 @@ dma_subsys: bus@5a000000 { , , , - ; + , + ; power-domains = <&pd IMX_SC_R_DMA_3_CH0>, <&pd IMX_SC_R_DMA_3_CH1>, <&pd IMX_SC_R_DMA_3_CH2>, diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts index 25a77cac6f0b5..5c68d33e19f22 100644 --- a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts @@ -598,6 +598,10 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lpuart1>; status = "okay"; + + bluetooth { + compatible = "nxp,88w8987-bt"; + }; }; &lsio_mu5 { @@ -649,6 +653,7 @@ pinctrl-names = "default"; reset-gpio = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>; vpcie-supply = <®_pcieb>; + vpcie3v3aux-supply = <®_pcieb>; status = "okay"; }; @@ -775,8 +780,10 @@ }; &usdhc1 { - pinctrl-names = "default"; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1>; + pinctrl-2 = <&pinctrl_usdhc1>; bus-width = <8>; no-sd; no-sdio; @@ -785,12 +792,15 @@ }; &usdhc2 { - pinctrl-names = "default"; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; bus-width = <4>; vmmc-supply = <®_usdhc2_vmmc>; cd-gpios = <&lsio_gpio5 1 GPIO_ACTIVE_LOW>; wp-gpios = <&lsio_gpio5 0 GPIO_ACTIVE_HIGH>; + max-frequency = <100000000>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi index 72434529f78e6..7a191195dbd97 100644 --- a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi @@ -101,7 +101,8 @@ , /* gpt0 */ , /* gpt1 */ , /* gpt2 */ - ; /* gpt3 */ + , /* gpt3 */ + ; power-domains = <&pd IMX_SC_R_DMA_0_CH0>, <&pd IMX_SC_R_DMA_0_CH1>, <&pd IMX_SC_R_DMA_0_CH2>, @@ -145,7 +146,8 @@ , , , - ; + , + ; }; &edma3 { @@ -156,7 +158,8 @@ , , , - ; + , + ; }; &flexcan1 { diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi index da33a35c6d466..74f9ce493248e 100644 --- a/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi @@ -7,6 +7,7 @@ /delete-node/ &fec2; /delete-node/ &usbotg3; /delete-node/ &usb3_phy; +/delete-node/ &usb3_lpcg; / { conn_enet0_root_clk: clock-conn-enet0-root { diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi index ff7ca20752309..6eab8a6001dbf 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi @@ -542,6 +542,7 @@ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>, <&clk IMX8MM_SYS_PLL2_250M>; vpcie-supply = <®_pcie0>; + supports-clkreq; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10-etml1010g3dra.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10-etml1010g3dra.dtso new file mode 100644 index 0000000000000..193fa9dc34d4a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10-etml1010g3dra.dtso @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + */ + +/dts-v1/; +/plugin/; + +#include +#include "imx8mm-phyboard-polis-peb-av-10.dtsi" + +&backlight { + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + pwms = <&pwm4 0 50000 0>; + status = "okay"; +}; + +&bridge_out { + ti,lvds-vod-swing-clock-microvolt = <200000 600000>; + ti,lvds-vod-swing-data-microvolt = <200000 600000>; +}; + +&lcdif { + status = "okay"; +}; + +&mipi_dsi { + status = "okay"; +}; + +&panel { + compatible = "edt,etml1010g3dra"; + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +&sn65dsi83 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10-ph128800t006.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10-ph128800t006.dtso new file mode 100644 index 0000000000000..fd819bd563b8f --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10-ph128800t006.dtso @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + */ + +/dts-v1/; +/plugin/; + +#include +#include "imx8mm-phyboard-polis-peb-av-10.dtsi" + +&backlight { + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + pwms = <&pwm4 0 50000 0>; + status = "okay"; +}; + +&bridge_out { + ti,lvds-vod-swing-clock-microvolt = <200000 600000>; + ti,lvds-vod-swing-data-microvolt = <200000 600000>; +}; + +&lcdif { + status = "okay"; +}; + +&mipi_dsi { + status = "okay"; +}; + +&panel { + compatible = "powertip,ph128800t006-zhc01"; + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +&sn65dsi83 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtsi new file mode 100644 index 0000000000000..bd1f255e15ea9 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtsi @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + */ + +#include +#include +#include "imx8mm-pinfunc.h" + +&{/} { + backlight: backlight { + compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd>; + power-supply = <®_vdd_3v3_s>; + status = "disabled"; + }; + + panel: panel { + backlight = <&backlight>; + power-supply = <®_vcc_3v3>; + status = "disabled"; + + port { + panel_in: endpoint { + remote-endpoint = <&bridge_out>; + }; + }; + }; + + reg_sound_1v8: regulator-1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1V8_Audio"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + reg_sound_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3_Analog"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + sound-peb-av-10 { + compatible = "simple-audio-card"; + simple-audio-card,name = "snd-peb-av-10"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,mclk-fs = <32>; + simple-audio-card,widgets = + "Line", "Line In", + "Speaker", "Speaker", + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Speaker", "SPOP", + "Speaker", "SPOM", + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "LINE1L", "Line In", + "LINE1R", "Line In", + "MIC3R", "Microphone Jack", + "Microphone Jack", "Mic Bias"; + + simple-audio-card,cpu { + sound-dai = <&sai5>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&codec>; + clocks = <&clk IMX8MM_CLK_SAI5>; + }; + }; +}; + +&bridge_out { + remote-endpoint = <&panel_in>; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c3>; + pinctrl-1 = <&pinctrl_i2c3_gpio>; + sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + codec: codec@18 { + compatible = "ti,tlv320aic3007"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tlv320>; + #sound-dai-cells = <0>; + reg = <0x18>; + reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>; + ai3x-gpio-func = <0xd 0x0>; + ai3x-micbias-vg = <2>; + AVDD-supply = <®_sound_3v3>; + IOVDD-supply = <®_sound_3v3>; + DRVDD-supply = <®_sound_3v3>; + DVDD-supply = <®_sound_1v8>; + }; + + eeprom@57 { + compatible = "atmel,24c32"; + pagesize = <32>; + reg = <0x57>; + vcc-supply = <®_vdd_3v3_s>; + }; + + eeprom@5f { + compatible = "atmel,24c32"; + pagesize = <32>; + reg = <0x5f>; + size = <32>; + vcc-supply = <®_vdd_3v3_s>; + }; +}; + +&pwm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm4>; +}; + +&sai5 { + assigned-clocks = <&clk IMX8MM_CLK_SAI5>; + assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>; + assigned-clock-rates = <11289600>; + clocks = <&clk IMX8MM_CLK_SAI5_IPG>, <&clk IMX8MM_CLK_DUMMY>, + <&clk IMX8MM_CLK_SAI5_ROOT>, <&clk IMX8MM_CLK_DUMMY>, + <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_AUDIO_PLL1_OUT>, + <&clk IMX8MM_AUDIO_PLL2_OUT>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", + "pll11k"; + fsl,sai-mclk-direction-output; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai5>; + #sound-dai-cells = <0>; + status = "okay"; +}; + +&iomuxc { + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c2 + MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c2 + >; + }; + + pinctrl_i2c3_gpio: i2c3gpiogrp { + fsl,pins = < + MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18 0x1e2 + MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19 0x1e2 + >; + }; + pinctrl_lcd: lcd0grp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1 0x12 + >; + }; + + pinctrl_pwm4: pwm4grp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_MCLK_PWM4_OUT 0x12 + >; + }; + + pinctrl_sai5: sai5grp { + fsl,pins = < + MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK 0xd6 + MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0 0xd6 + MX8MM_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC 0xd6 + MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK 0xd6 + MX8MM_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0 0xd6 + >; + }; + + pinctrl_tlv320: tlv320grp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x116 + MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x16 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso index 79e4c3710ac3f..28e8589f9f951 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso +++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso @@ -1,239 +1,9 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) /* * Copyright (C) 2025 PHYTEC Messtechnik GmbH - * Author: Teresa Remmet */ /dts-v1/; /plugin/; -#include -#include -#include "imx8mm-pinfunc.h" - -&{/} { - backlight: backlight { - compatible = "pwm-backlight"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_lcd>; - default-brightness-level = <6>; - pwms = <&pwm4 0 50000 0>; - power-supply = <®_vdd_3v3_s>; - enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; - brightness-levels = <0 4 8 16 32 64 128 255>; - }; - - panel { - compatible = "edt,etml1010g3dra"; - backlight = <&backlight>; - power-supply = <®_vcc_3v3>; - - port { - panel_in: endpoint { - remote-endpoint = <&bridge_out>; - }; - }; - }; - - reg_sound_1v8: regulator-1v8 { - compatible = "regulator-fixed"; - regulator-name = "VCC_1V8_Audio"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - - reg_sound_3v3: regulator-3v3 { - compatible = "regulator-fixed"; - regulator-name = "VCC_3V3_Analog"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - sound-peb-av-10 { - compatible = "simple-audio-card"; - simple-audio-card,name = "snd-peb-av-10"; - simple-audio-card,format = "i2s"; - simple-audio-card,bitclock-master = <&dailink_master>; - simple-audio-card,frame-master = <&dailink_master>; - simple-audio-card,mclk-fs = <32>; - simple-audio-card,widgets = - "Line", "Line In", - "Speaker", "Speaker", - "Microphone", "Microphone Jack", - "Headphone", "Headphone Jack"; - simple-audio-card,routing = - "Speaker", "SPOP", - "Speaker", "SPOM", - "Headphone Jack", "HPLOUT", - "Headphone Jack", "HPROUT", - "LINE1L", "Line In", - "LINE1R", "Line In", - "MIC3R", "Microphone Jack", - "Microphone Jack", "Mic Bias"; - - simple-audio-card,cpu { - sound-dai = <&sai5>; - }; - - dailink_master: simple-audio-card,codec { - sound-dai = <&codec>; - clocks = <&clk IMX8MM_CLK_SAI5>; - }; - }; -}; - -&i2c3 { - clock-frequency = <400000>; - pinctrl-names = "default", "gpio"; - pinctrl-0 = <&pinctrl_i2c3>; - pinctrl-1 = <&pinctrl_i2c3_gpio>; - sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; - - codec: codec@18 { - compatible = "ti,tlv320aic3007"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_tlv320>; - #sound-dai-cells = <0>; - reg = <0x18>; - reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>; - ai3x-gpio-func = <0xd 0x0>; - ai3x-micbias-vg = <2>; - AVDD-supply = <®_sound_3v3>; - IOVDD-supply = <®_sound_3v3>; - DRVDD-supply = <®_sound_3v3>; - DVDD-supply = <®_sound_1v8>; - }; - - eeprom@57 { - compatible = "atmel,24c32"; - pagesize = <32>; - reg = <0x57>; - vcc-supply = <®_vdd_3v3_s>; - }; - - eeprom@5f { - compatible = "atmel,24c32"; - pagesize = <32>; - reg = <0x5f>; - size = <32>; - vcc-supply = <®_vdd_3v3_s>; - }; -}; - -&lcdif { - status = "okay"; -}; - -&mipi_dsi { - samsung,esc-clock-frequency = <10000000>; - status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - port@1 { - reg = <1>; - dsi_out: endpoint { - remote-endpoint = <&bridge_in>; - }; - }; - }; -}; - -&pwm4 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm4>; - status = "okay"; -}; - -&sai5 { - assigned-clocks = <&clk IMX8MM_CLK_SAI5>; - assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>; - assigned-clock-rates = <11289600>; - clocks = <&clk IMX8MM_CLK_SAI5_IPG>, <&clk IMX8MM_CLK_DUMMY>, - <&clk IMX8MM_CLK_SAI5_ROOT>, <&clk IMX8MM_CLK_DUMMY>, - <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_AUDIO_PLL1_OUT>, - <&clk IMX8MM_AUDIO_PLL2_OUT>; - clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", - "pll11k"; - fsl,sai-mclk-direction-output; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sai5>; - #sound-dai-cells = <0>; - status = "okay"; -}; - -&sn65dsi83 { - status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - bridge_in: endpoint { - remote-endpoint = <&dsi_out>; - data-lanes = <1 2 3 4>; - }; - }; - - port@2 { - reg = <2>; - bridge_out: endpoint { - remote-endpoint = <&panel_in>; - ti,lvds-vod-swing-clock-microvolt = <200000 600000>; - ti,lvds-vod-swing-data-microvolt = <200000 600000>; - }; - }; - }; -}; - -&iomuxc { - - pinctrl_i2c3: i2c3grp { - fsl,pins = < - MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c2 - MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c2 - >; - }; - - pinctrl_i2c3_gpio: i2c3gpiogrp { - fsl,pins = < - MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18 0x1e2 - MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19 0x1e2 - >; - }; - pinctrl_lcd: lcd0grp { - fsl,pins = < - MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1 0x12 - >; - }; - - pinctrl_pwm4: pwm4grp { - fsl,pins = < - MX8MM_IOMUXC_SAI3_MCLK_PWM4_OUT 0x12 - >; - }; - - pinctrl_sai5: sai5grp { - fsl,pins = < - MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK 0xd6 - MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0 0xd6 - MX8MM_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC 0xd6 - MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK 0xd6 - MX8MM_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0 0xd6 - >; - }; - - pinctrl_tlv320: tlv320grp { - fsl,pins = < - MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x16 - MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x16 - >; - }; -}; +#include "imx8mm-phyboard-polis-peb-av-10.dtsi" diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-eval-01.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-eval-01.dtso index a28f51ece93ba..1059c26990fe6 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-eval-01.dtso +++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-eval-01.dtso @@ -1,7 +1,6 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) /* * Copyright (C) 2025 PHYTEC Messtechnik GmbH - * Author: Janine Hagemann */ /dts-v1/; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts index be470cfb03d75..6043e7d163069 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts @@ -1,7 +1,6 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) /* * Copyright (C) 2022 PHYTEC Messtechnik GmbH - * Author: Teresa Remmet */ /dts-v1/; @@ -285,6 +284,8 @@ over-current-active-low; samsung,picophy-pre-emp-curr-control = <3>; samsung,picophy-dc-vol-level-adjust = <7>; + pinctrl-0 = <&pinctrl_usbotg1>; + pinctrl-names = "default"; srp-disable; vbus-supply = <®_usb_otg1_vbus>; status = "okay"; @@ -458,6 +459,12 @@ >; }; + pinctrl_usbotg1: usbotg1grp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x00 + >; + }; + pinctrl_usdhc1: usdhc1grp { fsl,pins = < MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x182 diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi index 921a7f58fd41d..3d66c6701342a 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi @@ -1,7 +1,6 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) /* * Copyright (C) 2022 PHYTEC Messtechnik GmbH - * Author: Teresa Remmet */ #include "imx8mm.dtsi" @@ -288,6 +287,23 @@ reg = <0x2d>; vcc-supply = <®_vdd_1v8>; status = "disabled"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + bridge_in: endpoint { + remote-endpoint = <&mipi_dsi_out>; + data-lanes = <1 2 3 4>; + }; + }; + + port@2 { + reg = <2>; + bridge_out: endpoint {}; + }; + }; }; /* EEPROM */ @@ -305,6 +321,14 @@ }; }; +&mipi_dsi { + samsung,esc-clock-frequency = <10000000>; +}; + +&mipi_dsi_out { + remote-endpoint = <&bridge_in>; +}; + /* eMMC */ &usdhc3 { assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts index 755cf9cacd227..2ecc8b3c67dab 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts @@ -452,7 +452,7 @@ pinctrl_usbotg1: usbotg1grp { fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x80 + MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x00 >; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi index 37db4f0dd5052..dca213c85cc3b 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi @@ -115,6 +115,7 @@ ethphy0: ethernet-phy@0 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; + ti,clk-output-sel = ; ti,rx-internal-delay = ; ti,tx-internal-delay = ; tx-fifo-depth = ; @@ -445,7 +446,7 @@ MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 - MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f + MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x0 MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi index 752caa38eb03b..266038fbbef97 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi @@ -351,17 +351,6 @@ >; }; - pinctrl_usdhc1: usdhc1grp { - fsl,pins = < - MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 - MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 - MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 - MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 - MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 - MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 - >; - }; - pinctrl_usdhc2: usdhc2grp { fsl,pins = < MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts index c09b40fc6decd..468c7e993c52b 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts @@ -253,6 +253,7 @@ ethphy0: ethernet-phy@0 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; + ti,clk-output-sel = ; ti,rx-internal-delay = ; ti,tx-internal-delay = ; tx-fifo-depth = ; diff --git a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts index a5f52f60169e9..5aa0e2cd155ec 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts +++ b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts @@ -248,6 +248,7 @@ ethphy0: ethernet-phy@0 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; + ti,clk-output-sel = ; ti,rx-internal-delay = ; ti,tx-internal-delay = ; tx-fifo-depth = ; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-aipstz.h b/arch/arm64/boot/dts/freescale/imx8mp-aipstz.h new file mode 100644 index 0000000000000..6481c484ca379 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-aipstz.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright 2025 NXP + */ + +#ifndef __IMX8MP_AIPSTZ_H +#define __IMX8MP_AIPSTZ_H + +/* consumer type - master or peripheral */ +#define IMX8MP_AIPSTZ_MASTER 0x0 +#define IMX8MP_AIPSTZ_PERIPH 0x1 + +/* master configuration options */ +#define IMX8MP_AIPSTZ_MPL (1 << 0) +#define IMX8MP_AIPSTZ_MTW (1 << 1) +#define IMX8MP_AIPSTZ_MTR (1 << 2) +#define IMX8MP_AIPSTZ_MBW (1 << 3) + +/* peripheral configuration options */ +#define IMX8MP_AIPSTZ_TP (1 << 0) +#define IMX8MP_AIPSTZ_WP (1 << 1) +#define IMX8MP_AIPSTZ_SP (1 << 2) +#define IMX8MP_AIPSTZ_BW (1 << 3) + +/* master ID definitions */ +#define IMX8MP_AIPSTZ_EDMA 0 /* AUDIOMIX EDMA */ +#define IMX8MP_AIPSTZ_CA53 1 /* Cortex-A53 cluster */ +#define IMX8MP_AIPSTZ_SDMA2 3 /* AUDIOMIX SDMA2 */ +#define IMX8MP_AIPSTZ_SDMA3 3 /* AUDIOMIX SDMA3 */ +#define IMX8MP_AIPSTZ_HIFI4 5 /* HIFI4 DSP */ +#define IMX8MP_AIPSTZ_CM7 6 /* Cortex-M7 */ + +#endif /* __IMX8MP_AIPSTZ_H */ diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts index af02af9e5334d..9422beee30b29 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts @@ -96,9 +96,9 @@ #address-cells = <1>; #size-cells = <0>; - ethphy0: ethernet-phy@0 { /* RTL8211E */ + ethphy0: ethernet-phy@1 { /* RTL8211E */ compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0>; + reg = <1>; reset-gpios = <&gpio4 18 GPIO_ACTIVE_LOW>; reset-assert-us = <20>; reset-deassert-us = <200000>; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts index d241db3743a9c..04619a7229065 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts @@ -22,6 +22,18 @@ stdout-path = &uart2; }; + hdmi-connector { + compatible = "hdmi-connector"; + label = "hdmi"; + type = "a"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_tx_out>; + }; + }; + }; + reg_baseboard_vdd3v3: regulator-baseboard-vdd3v3 { compatible = "regulator-fixed"; regulator-min-microvolt = <3300000>; @@ -222,6 +234,28 @@ }; }; +&hdmi_pvi { + status = "okay"; +}; + +&hdmi_tx { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hdmi>; + status = "okay"; + + ports { + port@1 { + hdmi_tx_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; + }; + }; +}; + +&hdmi_tx_phy { + status = "okay"; +}; + &i2c4 { expander0: gpio@20 { compatible = "nxp,pca9535"; @@ -276,6 +310,10 @@ }; }; +&lcdif3 { + status = "okay"; +}; + &snvs_pwrkey { status = "okay"; }; @@ -430,6 +468,15 @@ >; }; + pinctrl_hdmi: hdmigrp { + fsl,pins = < + MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x1c3 + MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x1c3 + MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x19 + MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x19 + >; + }; + pinctrl_i2c1: i2c1grp { fsl,pins = < MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c2 diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts index ebdf13e97b4e2..3d18c964a22cd 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dts @@ -88,6 +88,7 @@ color = ; default-state = "off"; function = LED_FUNCTION_INDICATOR; + function-enumerator = <0>; gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; /* GPIO E */ pinctrl-0 = <&pinctrl_dhcom_e>; pinctrl-names = "default"; @@ -97,6 +98,7 @@ color = ; default-state = "off"; function = LED_FUNCTION_INDICATOR; + function-enumerator = <1>; gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>; /* GPIO F */ pinctrl-0 = <&pinctrl_dhcom_f>; pinctrl-names = "default"; @@ -106,6 +108,7 @@ color = ; default-state = "off"; function = LED_FUNCTION_INDICATOR; + function-enumerator = <2>; gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; /* GPIO H */ pinctrl-0 = <&pinctrl_dhcom_h>; pinctrl-names = "default"; @@ -115,6 +118,7 @@ color = ; default-state = "off"; function = LED_FUNCTION_INDICATOR; + function-enumerator = <3>; gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; /* GPIO I */ pinctrl-0 = <&pinctrl_dhcom_i>; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts index 3730792daf501..c6facb2ad9aaa 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -442,6 +442,10 @@ status = "disabled";/* can2 pin conflict with pdm */ }; +&hdmi_pai { + status = "okay"; +}; + &hdmi_pvi { status = "okay"; }; @@ -710,6 +714,8 @@ pinctrl-0 = <&pinctrl_pcie0>; reset-gpio = <&gpio2 7 GPIO_ACTIVE_LOW>; vpcie-supply = <®_pcie0>; + vpcie3v3aux-supply = <®_pcie0>; + supports-clkreq; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-etml1010g3dra.dtso b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-etml1010g3dra.dtso new file mode 100644 index 0000000000000..7a7f27d6bb1be --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-etml1010g3dra.dtso @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + */ + +#include +#include + +/dts-v1/; +/plugin/; + +&backlight_lvds1 { + brightness-levels = <0 8 16 32 64 128 255>; + default-brightness-level = <8>; + enable-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>; + num-interpolated-steps = <2>; + pwms = <&pwm3 0 50000 0>; + status = "okay"; +}; + +&lcdif2 { + status = "okay"; +}; + +&lvds_bridge { + assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>, <&clk IMX8MP_VIDEO_PLL1>; + assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>; + /* + * The LVDS panel uses 72.4 MHz pixel clock, set IMX8MP_VIDEO_PLL1 to + * 72.4 * 7 = 506.8 MHz so the LDB serializer and LCDIFv3 scanout + * engine can reach accurate pixel clock of exactly 72.4 MHz. + */ + assigned-clock-rates = <0>, <506800000>; + status = "okay"; +}; + +&panel_lvds1 { + compatible = "edt,etml1010g3dra"; + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10-etml1010g3dra.dtso b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10-etml1010g3dra.dtso new file mode 100644 index 0000000000000..aceb5b6056ef1 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10-etml1010g3dra.dtso @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include "imx8mp-phyboard-pollux-peb-av-10.dtsi" + +&backlight_lvds0 { + brightness-levels = <0 8 16 32 64 128 255>; + default-brightness-level = <8>; + enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + num-interpolated-steps = <2>; + pwms = <&pwm4 0 50000 0>; + status = "okay"; +}; + +&lcdif2 { + status = "okay"; +}; + +&lvds_bridge { + assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>, <&clk IMX8MP_VIDEO_PLL1>; + assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>; + /* + * The LVDS panel uses 72.4 MHz pixel clock, set IMX8MP_VIDEO_PLL1 to + * 72.4 * 7 = 506.8 MHz so the LDB serializer and LCDIFv3 scanout + * engine can reach accurate pixel clock of exactly 72.4 MHz. + */ + assigned-clock-rates = <0>, <506800000>; + status = "okay"; +}; + +&panel_lvds0 { + compatible = "edt,etml1010g3dra"; + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10-ph128800t006.dtso b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10-ph128800t006.dtso new file mode 100644 index 0000000000000..559286f384be4 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10-ph128800t006.dtso @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + */ + +/dts-v1/; +/plugin/; + +#include +#include +#include "imx8mp-phyboard-pollux-peb-av-10.dtsi" + +&backlight_lvds0 { + brightness-levels = <0 8 16 32 64 128 255>; + default-brightness-level = <8>; + enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + num-interpolated-steps = <2>; + pwms = <&pwm4 0 66667 0>; + status = "okay"; +}; + +&lcdif2 { + status = "okay"; +}; + +&lvds_bridge { + assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>, <&clk IMX8MP_VIDEO_PLL1>; + assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>; + /* + * The LVDS panel uses 66.5 MHz pixel clock, set IMX8MP_VIDEO_PLL1 to + * 66.5 * 7 = 465.5 MHz so the LDB serializer and LCDIFv3 scanout + * engine can reach accurate pixel clock of exactly 66.5 MHz. + */ + assigned-clock-rates = <0>, <465500000>; + status = "okay"; +}; + +&panel_lvds0 { + compatible = "powertip,ph128800t006-zhc01"; + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtsi new file mode 100644 index 0000000000000..bb740f845855a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtsi @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + */ + +#include +#include +#include "imx8mp-pinfunc.h" + +&{/} { + backlight_lvds0: backlight0 { + compatible = "pwm-backlight"; + pinctrl-0 = <&pinctrl_lvds0>; + pinctrl-names = "default"; + power-supply = <®_vcc_12v>; + status = "disabled"; + }; + + panel_lvds0: panel-lvds0 { + backlight = <&backlight_lvds0>; + power-supply = <®_vcc_3v3_sw>; + status = "disabled"; + + port { + panel0_in: endpoint { + remote-endpoint = <&ldb_lvds_ch0>; + }; + }; + }; + + reg_vcc_12v: regulator-12v { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <12000000>; + regulator-min-microvolt = <12000000>; + regulator-name = "VCC_12V"; + }; + + reg_vcc_1v8_audio: regulator-1v8 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "VCC_1V8_Audio"; + }; + + reg_vcc_3v3_analog: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "VCC_3V3_Analog"; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "snd-peb-av-10"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,mclk-fs = <32>; + simple-audio-card,widgets = + "Line", "Line In", + "Speaker", "Speaker", + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Speaker", "SPOP", + "Speaker", "SPOM", + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "LINE1L", "Line In", + "LINE1R", "Line In", + "MIC3R", "Microphone Jack", + "Microphone Jack", "Mic Bias"; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&codec>; + clocks = <&clk IMX8MP_CLK_SAI2>; + }; + }; +}; + +&i2c4 { + clock-frequency = <400000>; + pinctrl-0 = <&pinctrl_i2c4>; + pinctrl-1 = <&pinctrl_i2c4_gpio>; + pinctrl-names = "default", "gpio"; + scl-gpios = <&gpio5 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio5 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + codec: codec@18 { + compatible = "ti,tlv320aic3007"; + reg = <0x18>; + pinctrl-0 = <&pinctrl_tlv320>; + pinctrl-names = "default"; + #sound-dai-cells = <0>; + reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>; + ai3x-gpio-func = <0xd 0x0>; + ai3x-micbias-vg = <2>; + AVDD-supply = <®_vcc_3v3_analog>; + DRVDD-supply = <®_vcc_3v3_analog>; + DVDD-supply = <®_vcc_1v8_audio>; + IOVDD-supply = <®_vcc_3v3_sw>; + }; + + eeprom@57 { + compatible = "atmel,24c32"; + reg = <0x57>; + pagesize = <32>; + vcc-supply = <®_vcc_3v3_sw>; + }; +}; + +&ldb_lvds_ch0 { + remote-endpoint = <&panel0_in>; +}; + +&pwm4 { + pinctrl-0 = <&pinctrl_pwm4>; + pinctrl-names = "default"; +}; + +&sai2 { + pinctrl-0 = <&pinctrl_sai2>; + pinctrl-names = "default"; + assigned-clocks = <&clk IMX8MP_CLK_SAI2>; + assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>; + assigned-clock-rates = <12288000>; + clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI2_IPG>, + <&clk IMX8MP_CLK_DUMMY>, + <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1>, + <&clk IMX8MP_CLK_DUMMY>, + <&clk IMX8MP_CLK_DUMMY>, + <&clk IMX8MP_AUDIO_PLL1_OUT>, + <&clk IMX8MP_AUDIO_PLL2_OUT>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", + "pll11k"; + #sound-dai-cells = <0>; + fsl,sai-mclk-direction-output; + fsl,sai-synchronous-rx; + status = "okay"; +}; + +&iomuxc { + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c2 + MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c2 + >; + }; + + pinctrl_i2c4_gpio: i2c4gpiogrp { + fsl,pins = < + MX8MP_IOMUXC_I2C4_SCL__GPIO5_IO20 0x1e2 + MX8MP_IOMUXC_I2C4_SDA__GPIO5_IO21 0x1e2 + >; + }; + + pinctrl_lvds0: lvds0grp { + fsl,pins = < + MX8MP_IOMUXC_SAI3_TXD__GPIO5_IO01 0x12 + >; + }; + + pinctrl_pwm4: pwm4grp { + fsl,pins = < + MX8MP_IOMUXC_SAI3_MCLK__PWM4_OUT 0x12 + >; + }; + + pinctrl_sai2: sai2grp { + fsl,pins = < + MX8MP_IOMUXC_SAI2_MCLK__AUDIOMIX_SAI2_MCLK 0xd6 + MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_SAI2_RX_SYNC 0xd6 + MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI2_TX_BCLK 0xd6 + MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI2_TX_DATA00 0xd6 + MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI2_RX_DATA00 0xd6 + >; + }; + + pinctrl_tlv320: tlv320grp { + fsl,pins = < + MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28 0x16 + MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x16 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtso b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtso new file mode 100644 index 0000000000000..95078618ee095 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtso @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + */ + +/dts-v1/; +/plugin/; + +#include "imx8mp-phyboard-pollux-peb-av-10.dtsi" diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-ph128800t006.dtso b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-ph128800t006.dtso new file mode 100644 index 0000000000000..a39f83bf82049 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-ph128800t006.dtso @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + */ + +#include +#include + +/dts-v1/; +/plugin/; + +&backlight_lvds1 { + brightness-levels = <0 8 16 32 64 128 255>; + default-brightness-level = <8>; + enable-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>; + num-interpolated-steps = <2>; + pwms = <&pwm3 0 66667 0>; + status = "okay"; +}; + +&lcdif2 { + status = "okay"; +}; + +&lvds_bridge { + assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>, <&clk IMX8MP_VIDEO_PLL1>; + assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>; + /* + * The LVDS panel uses 72.4 MHz pixel clock, set IMX8MP_VIDEO_PLL1 to + * 66.5 * 7 = 465.5 MHz so the LDB serializer and LCDIFv3 scanout + * engine can reach accurate pixel clock of exactly 66.5 MHz. + */ + assigned-clock-rates = <0>, <465500000>; + status = "okay"; +}; + + +&panel_lvds1 { + compatible = "powertip,ph128800t006-zhc01"; + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts index 4361523086422..9687b4ded8f4c 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts @@ -1,14 +1,12 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT /* * Copyright (C) 2020 PHYTEC Messtechnik GmbH - * Author: Teresa Remmet */ /dts-v1/; #include #include -#include #include #include "imx8mp-phycore-som.dtsi" @@ -21,16 +19,12 @@ stdout-path = &uart1; }; - backlight_lvds: backlight { + backlight_lvds1: backlight1 { compatible = "pwm-backlight"; - pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lvds1>; - brightness-levels = <0 4 8 16 32 64 128 255>; - default-brightness-level = <11>; - enable-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>; - num-interpolated-steps = <2>; + pinctrl-names = "default"; power-supply = <®_lvds1_reg_en>; - pwms = <&pwm3 0 50000 0>; + status = "disabled"; }; fan0: fan { @@ -43,10 +37,11 @@ #cooling-cells = <2>; }; - panel1_lvds: panel-lvds { - compatible = "edt,etml1010g3dra"; - backlight = <&backlight_lvds>; + panel_lvds1: panel-lvds1 { + /* compatible panel in overlay */ + backlight = <&backlight_lvds1>; power-supply = <®_vcc_3v3_sw>; + status = "disabled"; port { panel1_in: endpoint { @@ -232,32 +227,8 @@ }; }; -&lcdif2 { - status = "okay"; -}; - -&lvds_bridge { - status = "okay"; - - ports { - port@2 { - ldb_lvds_ch1: endpoint { - remote-endpoint = <&panel1_in>; - }; - }; - }; -}; - -&media_blk_ctrl { - /* - * The LVDS panel on this device uses 72.4 MHz pixel clock, - * set IMX8MP_VIDEO_PLL1 to 72.4 * 7 = 506.8 MHz so the LDB - * serializer and LCDIFv3 scanout engine can reach accurate - * pixel clock of exactly 72.4 MHz. - */ - assigned-clock-rates = <500000000>, <200000000>, - <0>, <0>, <500000000>, - <506800000>; +&ldb_lvds_ch1 { + remote-endpoint = <&panel1_in>; }; &snvs_pwrkey { @@ -282,9 +253,8 @@ }; &pwm3 { - status = "okay"; - pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pwm3>; + pinctrl-names = "default"; }; &rv3028 { diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi index 04f724c6ec210..88831c0fbb7be 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi @@ -1,7 +1,6 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT /* * Copyright (C) 2020 PHYTEC Messtechnik GmbH - * Author: Teresa Remmet */ #include diff --git a/arch/arm64/boot/dts/freescale/imx8mp-prt8ml.dts b/arch/arm64/boot/dts/freescale/imx8mp-prt8ml.dts new file mode 100644 index 0000000000000..30616218017b2 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-prt8ml.dts @@ -0,0 +1,504 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2020 Protonic Holland + * Copyright 2019 NXP + */ + +/dts-v1/; + +#include "imx8mp.dtsi" + +/ { + model = "Protonic PRT8ML"; + compatible = "prt,prt8ml", "fsl,imx8mp"; + + chosen { + stdout-path = &uart4; + }; + + pcie_refclk: pcie0-refclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + }; + + pcie_refclk_oe: pcie0-refclk-oe { + compatible = "gpio-gate-clock"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_refclk>; + clocks = <&pcie_refclk>; + #clock-cells = <0>; + enable-gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>; + }; +}; + +&A53_0 { + cpu-supply = <&fan53555>; +}; + +&A53_1 { + cpu-supply = <&fan53555>; +}; + +&A53_2 { + cpu-supply = <&fan53555>; +}; + +&A53_3 { + cpu-supply = <&fan53555>; +}; + +&a53_opp_table { + opp-1200000000 { + opp-microvolt = <900000>; + }; + + opp-1600000000 { + opp-microvolt = <980000>; + }; + + /* Power supply insuffient for 1.8 GHz */ + /delete-node/ opp-1800000000; +}; + +&ecspi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi2>; + cs-gpios = <&gpio5 13 GPIO_ACTIVE_HIGH>; + + /* Disable DMA to meet performance requirements */ + /delete-property/ dmas; + /delete-property/ dma-names; + status = "okay"; + + switch@0 { + compatible = "nxp,sja1105q"; + reg = <0>; + reset-gpios = <&gpio_exp_1 4 GPIO_ACTIVE_LOW>; + spi-cpha; + spi-max-frequency = <4000000>; + spi-rx-delay-us = <1>; + spi-tx-delay-us = <1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@3 { + reg = <3>; + label = "rj45"; + phy-handle = <&rj45_phy>; + phy-mode = "rgmii-id"; + }; + + port@4 { + reg = <4>; + ethernet = <&fec>; + label = "cpu"; + phy-mode = "rgmii-id"; + rx-internal-delay-ps = <2000>; + tx-internal-delay-ps = <2000>; + + /* Unreliable at 1000Mbps, limit RGMII to 100Mbps */ + fixed-link { + full-duplex; + speed = <100>; + }; + }; + }; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec>; + phy-mode = "rgmii"; /* switch inserts delay */ + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; + status = "okay"; + + fixed-link { + full-duplex; + speed = <100>; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + rj45_phy: ethernet-phy@2 { + reg = <2>; + reset-gpios = <&gpio_exp_1 1 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <80000>; + }; + }; +}; + +&flexcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; + status = "okay"; +}; + +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + status = "okay"; +}; + +&i2c1 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + ak5558: codec@10 { + compatible = "asahi-kasei,ak5558"; + reg = <0x10>; + reset-gpios = <&gpio_exp_1 2 GPIO_ACTIVE_LOW>; + }; + + gpio_exp_1: gpio@25 { + compatible = "nxp,pca9571"; + reg = <0x25>; + gpio-controller; + #gpio-cells = <2>; + }; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + tps65987ddh_0: usb-pd@20 { + compatible = "ti,tps6598x"; + reg = <0x20>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tps65987ddh_0>; + interrupts-extended = <&gpio1 12 IRQ_TYPE_LEVEL_LOW>; + }; + + gpio_exp_2: gpio@25 { + compatible = "nxp,pca9571"; + reg = <0x25>; + gpio-controller; + #gpio-cells = <2>; + + c0-hreset-hog { + gpio-hog; + gpios = <7 GPIO_ACTIVE_LOW>; + line-name = "c0-hreset"; + output-low; + }; + + c1-hreset-hog { + gpio-hog; + gpios = <6 GPIO_ACTIVE_LOW>; + line-name = "c1-hreset"; + output-low; + }; + }; + + fan53555: regulator@60 { + compatible = "fcs,fan53555"; + reg = <0x60>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fan53555>; + regulator-name = "fan53555"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <980000>; + regulator-always-on; + regulator-boot-on; + fcs,suspend-voltage-selector = <1>; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + ak4458: codec@11 { + compatible = "asahi-kasei,ak4458"; + reg = <0x11>; + #sound-dai-cells = <0>; + reset-gpios = <&gpio_exp_2 5 GPIO_ACTIVE_LOW>; + }; + + tps65987ddh_1: usb-pd@20 { + compatible = "ti,tps6598x"; + reg = <0x20>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tps65987ddh_1>; + interrupts-extended = <&gpio1 15 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&lcdif1 { + status = "okay"; +}; + +&snvs_pwrkey { + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&usb3_0 { + status = "okay"; +}; + +&usb3_1 { + status = "okay"; +}; + +&usb3_phy0 { + status = "okay"; +}; + +&usb3_phy1 { + status = "okay"; +}; + +&usb_dwc3_0 { + dr_mode = "host"; + status = "okay"; +}; + +&usb_dwc3_1 { + dr_mode = "host"; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + assigned-clocks = <&clk IMX8MP_CLK_USDHC2>; + assigned-clock-rates = <100000000>; + bus-width = <4>; + cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; + no-1-8-v; + sd-uhs-sdr12; + sd-uhs-sdr25; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + assigned-clocks = <&clk IMX8MP_CLK_USDHC3_ROOT>; + assigned-clock-rates = <400000000>; + bus-width = <8>; + non-removable; + no-sdio; + no-sd; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + pinctrl_ecspi2: ecspi2grp { + fsl,pins = < + MX8MP_IOMUXC_ECSPI2_SCLK__ECSPI2_SCLK 0x154 + MX8MP_IOMUXC_ECSPI2_MOSI__ECSPI2_MOSI 0x154 + MX8MP_IOMUXC_ECSPI2_MISO__ECSPI2_MISO 0x154 + MX8MP_IOMUXC_ECSPI2_SS0__GPIO5_IO13 0x154 + >; + }; + + pinctrl_fan53555: fan53555grp { + fsl,pins = < + MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x114 + >; + }; + + pinctrl_fec: fecgrp { + fsl,pins = < + MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3 + MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x3 + MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x91 + MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x91 + MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x91 + MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x91 + MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x91 + MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91 + MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x1f + MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x1f + MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x1f + MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x1f + MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x1f + MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x1f + >; + }; + + pinctrl_flexcan1: flexcan1grp { + fsl,pins = < + MX8MP_IOMUXC_SPDIF_RX__CAN1_RX 0x154 + MX8MP_IOMUXC_SPDIF_TX__CAN1_TX 0x154 + >; + }; + + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX8MP_IOMUXC_UART3_TXD__CAN2_RX 0x154 + MX8MP_IOMUXC_UART3_RXD__CAN2_TX 0x154 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MP_IOMUXC_ECSPI1_SCLK__I2C1_SCL 0x400000c3 + MX8MP_IOMUXC_ECSPI1_MOSI__I2C1_SDA 0x400000c3 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400000c3 + MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400000c3 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400000c3 + MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400000c3 + >; + }; + + pinctrl_pcie_refclk: pcierefclkgrp { + fsl,pins = < + MX8MP_IOMUXC_UART1_TXD__GPIO5_IO23 0xc6 + >; + }; + + pinctrl_tps65987ddh_0: tps65987ddh-0grp { + fsl,pins = < + MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x1d0 + >; + }; + + pinctrl_tps65987ddh_1: tps65987ddh-1grp { + fsl,pins = < + MX8MP_IOMUXC_GPIO1_IO15__GPIO1_IO15 0x1d0 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX8MP_IOMUXC_UART4_RXD__UART4_DCE_RX 0x040 + MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x040 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 + MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d0 + MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d0 + MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0 + MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0 + MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = < + MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194 + MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4 + MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4 + MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4 + MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4 + MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = < + MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x196 + MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d6 + MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d6 + MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6 + MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6 + MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6 + >; + }; + + pinctrl_usdhc2_gpio: usdhc2-gpiogrp { + fsl,pins = < + MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x0d4 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 + MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d0 + MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d0 + MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d0 + MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d0 + MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d0 + MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d0 + MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d0 + MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d0 + MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d0 + MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x190 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { + fsl,pins = < + MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194 + MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4 + MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d4 + MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d4 + MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d4 + MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d4 + MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d4 + MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d4 + MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d4 + MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d4 + MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x194 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { + fsl,pins = < + MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196 + MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6 + MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6 + MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6 + MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6 + MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6 + MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6 + MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6 + MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6 + MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6 + MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x196 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0x166 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revc-hdmi.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revc-hdmi.dts new file mode 100644 index 0000000000000..c263e8fd04846 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revc-hdmi.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +#include "imx8mp-skov-revb-hdmi.dts" + +/ { + model = "SKOV IMX8MP CPU revC - HDMI"; + compatible = "skov,imx8mp-skov-revc-hdmi", "fsl,imx8mp"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revc-jutouch-jt101tm023.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revc-jutouch-jt101tm023.dts new file mode 100644 index 0000000000000..3e320d6dea3a2 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revc-jutouch-jt101tm023.dts @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +/dts-v1/; + +#include "imx8mp-skov-reva.dtsi" + +/ { + model = "SKOV IMX8MP CPU revC - JuTouch JT101TM023"; + compatible = "skov,imx8mp-skov-revc-jutouch-jt101tm023", "fsl,imx8mp"; + + panel { + compatible = "jutouch,jt101tm023"; + backlight = <&backlight>; + power-supply = <®_tft_vcom>; + + port { + in_lvds0: endpoint { + remote-endpoint = <&ldb_lvds_ch0>; + }; + }; + }; +}; + +&backlight { + status = "okay"; +}; + +&i2c2 { + clock-frequency = <100000>; + status = "okay"; + + touchscreen@2a { + compatible = "eeti,exc81w32", "eeti,exc80h84"; + reg = <0x2a>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_touchscreen>; + interrupts-extended = <&gpio4 28 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpio4 29 GPIO_ACTIVE_LOW>; + touchscreen-size-x = <1280>; + touchscreen-size-y = <800>; + vdd-supply = <®_vdd_3v3>; + }; +}; + +&lcdif2 { + status = "okay"; +}; + +&lvds_bridge { + assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>, + <&clk IMX8MP_VIDEO_PLL1>; + assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>; + /* IMX8MP_VIDEO_PLL1 = IMX8MP_CLK_MEDIA_DISP2_PIX * 7 */ + assigned-clock-rates = <0>, <506800000>; + status = "okay"; + + ports { + port@1 { + ldb_lvds_ch0: endpoint { + remote-endpoint = <&in_lvds0>; + }; + }; + }; +}; + +&pwm4 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +®_tft_vcom { + regulator-min-microvolt = <3160000>; + regulator-max-microvolt = <3160000>; + voltage-table = <3160000 73>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts index 4eedd00d83b9f..59642a8a2c445 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts @@ -238,6 +238,13 @@ audio-asrc = <&easrc>; audio-cpu = <&sai3>; audio-codec = <&tlv320aic3x04>; + audio-routing = + "IN3_L", "Mic Jack", + "Mic Jack", "Mic Bias", + "IN1_L", "Line In Jack", + "IN1_R", "Line In Jack", + "Line Out Jack", "LOL", + "Line Out Jack", "LOR"; }; thermal-zones { diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi index cbf0c9a740faa..de852ebff5712 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi @@ -101,6 +101,7 @@ reg = <0x0>; interrupt-parent = <&gpio3>; interrupts = <16 IRQ_TYPE_EDGE_FALLING>; + ti,clk-output-sel = ; ti,rx-internal-delay = ; ti,tx-internal-delay = ; tx-fifo-depth = ; @@ -395,13 +396,6 @@ status = "okay"; }; -/* off-board header */ -&uart1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1>; - status = "okay"; -}; - /* console */ &uart2 { pinctrl-names = "default"; @@ -409,25 +403,6 @@ status = "okay"; }; -/* off-board header */ -&uart3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart3>; - status = "okay"; -}; - -/* off-board */ -&usdhc1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc1>; - bus-width = <4>; - non-removable; - status = "okay"; - bus-width = <4>; - non-removable; - status = "okay"; -}; - /* eMMC */ &usdhc3 { pinctrl-names = "default", "state_100mhz", "state_200mhz"; @@ -464,7 +439,7 @@ MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x16 MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x16 MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x16 - MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x16 + MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x0 >; }; @@ -523,13 +498,6 @@ >; }; - pinctrl_uart1: uart1grp { - fsl,pins = < - MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140 - MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140 - >; - }; - pinctrl_uart2: uart2grp { fsl,pins = < MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 @@ -537,24 +505,6 @@ >; }; - pinctrl_uart3: uart3grp { - fsl,pins = < - MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x140 - MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x140 - >; - }; - - pinctrl_usdhc1: usdhc1grp { - fsl,pins = < - MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 - MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 - MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 - MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 - MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 - MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 - >; - }; - pinctrl_usdhc3: usdhc3grp { fsl,pins = < MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi index cf747ec6fa16e..76020ef89bf3e 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi @@ -365,17 +365,6 @@ >; }; - pinctrl_usdhc1: usdhc1grp { - fsl,pins = < - MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 - MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 - MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 - MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 - MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 - MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 - >; - }; - pinctrl_usdhc2: usdhc2grp { fsl,pins = < MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts index 12de7cf1e8538..7662663ff5dad 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts @@ -228,6 +228,7 @@ ethphy0: ethernet-phy@0 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0x0>; + ti,clk-output-sel = ; ti,rx-internal-delay = ; ti,tx-internal-delay = ; tx-fifo-depth = ; diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index a3de6604e29f2..9b2b3a9bf9e80 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -13,6 +13,7 @@ #include #include +#include "imx8mp-aipstz.h" #include "imx8mp-pinfunc.h" / { @@ -80,6 +81,12 @@ operating-points-v2 = <&a53_opp_table>; #cooling-cells = <2>; cpu-idle-states = <&cpu_pd_wait>; + + cpu0_therm: thermal-idle { + #cooling-cells = <2>; + duration-us = <10000>; + exit-latency-us = <700>; + }; }; A53_1: cpu@1 { @@ -98,6 +105,12 @@ operating-points-v2 = <&a53_opp_table>; #cooling-cells = <2>; cpu-idle-states = <&cpu_pd_wait>; + + cpu1_therm: thermal-idle { + #cooling-cells = <2>; + duration-us = <10000>; + exit-latency-us = <700>; + }; }; A53_2: cpu@2 { @@ -116,6 +129,12 @@ operating-points-v2 = <&a53_opp_table>; #cooling-cells = <2>; cpu-idle-states = <&cpu_pd_wait>; + + cpu2_therm: thermal-idle { + #cooling-cells = <2>; + duration-us = <10000>; + exit-latency-us = <700>; + }; }; A53_3: cpu@3 { @@ -134,6 +153,12 @@ operating-points-v2 = <&a53_opp_table>; #cooling-cells = <2>; cpu-idle-states = <&cpu_pd_wait>; + + cpu3_therm: thermal-idle { + #cooling-cells = <2>; + duration-us = <10000>; + exit-latency-us = <700>; + }; }; A53_L2: l2-cache0 { @@ -323,7 +348,11 @@ <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&gpu3d THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&gpu2d THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&npu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + <&npu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu0_therm 0 50>, + <&cpu1_therm 0 50>, + <&cpu2_therm 0 50>, + <&cpu3_therm 0 50>; }; }; }; @@ -356,7 +385,11 @@ <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&gpu3d THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&gpu2d THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&npu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + <&npu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu0_therm 0 50>, + <&cpu1_therm 0 50>, + <&cpu2_therm 0 50>, + <&cpu3_therm 0 50>; }; }; }; @@ -1396,12 +1429,14 @@ }; }; - aips5: bus@30c00000 { - compatible = "fsl,aips-bus", "simple-bus"; - reg = <0x30c00000 0x400000>; + aips5: bus@30df0000 { + compatible = "fsl,imx8mp-aipstz"; + reg = <0x30df0000 0x10000>; + power-domains = <&pgc_audio>; #address-cells = <1>; #size-cells = <1>; - ranges; + #access-controller-cells = <3>; + ranges = <0x30c00000 0x30c00000 0x400000>; spba-bus@30c00000 { compatible = "fsl,spba-bus", "simple-bus"; @@ -1770,6 +1805,7 @@ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_250M>, <&clk IMX8MP_CLK_24M>; power-domains = <&media_blk_ctrl IMX8MP_MEDIABLK_PD_MIPI_CSI2_1>; + fsl,num-channels = <3>; status = "disabled"; ports { @@ -1805,6 +1841,7 @@ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_250M>, <&clk IMX8MP_CLK_24M>; power-domains = <&media_blk_ctrl IMX8MP_MEDIABLK_PD_MIPI_CSI2_2>; + fsl,num-channels = <3>; status = "disabled"; ports { @@ -2073,7 +2110,7 @@ hdmi_pvi: display-bridge@32fc4000 { compatible = "fsl,imx8mp-hdmi-pvi"; - reg = <0x32fc4000 0x1000>; + reg = <0x32fc4000 0x800>; interrupt-parent = <&irqsteer_hdmi>; interrupts = <12>; power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>; @@ -2099,6 +2136,23 @@ }; }; + hdmi_pai: audio-bridge@32fc4800 { + compatible = "fsl,imx8mp-hdmi-pai"; + reg = <0x32fc4800 0x800>; + interrupt-parent = <&irqsteer_hdmi>; + interrupts = <14>; + clocks = <&clk IMX8MP_CLK_HDMI_APB>; + clock-names = "apb"; + power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PAI>; + status = "disabled"; + + port { + pai_to_hdmi_tx: endpoint { + remote-endpoint = <&hdmi_tx_from_pai>; + }; + }; + }; + lcdif3: display-controller@32fc6000 { compatible = "fsl,imx8mp-lcdif"; reg = <0x32fc6000 0x1000>; @@ -2150,6 +2204,14 @@ reg = <1>; /* Point endpoint to the HDMI connector */ }; + + port@2 { + reg = <2>; + + hdmi_tx_from_pai: endpoint { + remote-endpoint = <&pai_to_hdmi_tx>; + }; + }; }; }; @@ -2445,6 +2507,11 @@ firmware-name = "imx/dsp/hifi4.bin"; resets = <&audio_blk_ctrl IMX8MP_AUDIOMIX_DSP_RUNSTALL>; reset-names = "runstall"; + access-controllers = <&aips5 + IMX8MP_AIPSTZ_HIFI4 + IMX8MP_AIPSTZ_MASTER + (IMX8MP_AIPSTZ_MPL | IMX8MP_AIPSTZ_MTW | IMX8MP_AIPSTZ_MTR) + >; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts index a88bc90346636..d48f901487d49 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts @@ -375,6 +375,7 @@ <&clk IMX8MQ_CLK_PCIE1_PHY>, <&clk IMX8MQ_CLK_PCIE1_AUX>; vph-supply = <&vgen5_reg>; + supports-clkreq; status = "okay"; }; @@ -397,7 +398,9 @@ <&clk IMX8MQ_CLK_PCIE2_PHY>, <&clk IMX8MQ_CLK_PCIE2_AUX>; vpcie-supply = <®_pcie1>; + vpcie3v3aux-supply = <®_pcie1>; vph-supply = <&vgen5_reg>; + supports-clkreq; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1.dtsi index b1c3f331c4ed0..8a37cbe922acc 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1.dtsi @@ -11,4 +11,12 @@ model = "Toradex Apalis iMX8QM V1.1"; }; -/* TODO: Cooling Maps */ +&cooling_maps_map0 { + cooling-device = + <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A72_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A72_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi index f97feee52c818..7594ac61fe561 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis.dtsi @@ -314,8 +314,6 @@ ; }; -/* TODO: On-module Wi-Fi */ - /* Apalis MMC1 */ &usdhc2 { /* diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts index 9c0b6b8d6459d..779d9f78fb819 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts +++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts @@ -249,6 +249,13 @@ regulator-max-microvolt = <2800000>; }; + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + reg_usdhc2_vmmc: usdhc2-vmmc { compatible = "regulator-fixed"; regulator-name = "SD1_SPWR"; @@ -323,6 +330,15 @@ enable-active-high; }; + reg_usb_otg1_vbus: regulator-usbotg1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&lsio_gpio4 3 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + reg_vref_1v8: regulator-adc-vref { compatible = "regulator-fixed"; regulator-name = "vref_1v8"; @@ -566,6 +582,8 @@ pressure-sensor@60 { compatible = "fsl,mpl3115"; reg = <0x60>; + vdd-supply = <®_3v3>; + vddio-supply = <®_3v3>; }; max7322: gpio@68 { @@ -686,6 +704,16 @@ status = "okay"; }; +&lpuart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpuart1>; + status = "okay"; + + bluetooth { + compatible = "nxp,88w8987-bt"; + }; +}; + &lpuart2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lpuart2>; @@ -775,6 +803,8 @@ pinctrl-names = "default"; reset-gpio = <&lsio_gpio4 29 GPIO_ACTIVE_LOW>; vpcie-supply = <®_pciea>; + vpcie3v3aux-supply = <®_pciea>; + supports-clkreq; status = "okay"; }; @@ -800,8 +830,12 @@ }; &usdhc1 { - pinctrl-names = "default"; + assigned-clocks = <&clk IMX_SC_R_SDHC_0 IMX_SC_PM_CLK_PER>; + assigned-clock-rates = <400000000>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1>; + pinctrl-2 = <&pinctrl_usdhc1>; bus-width = <8>; no-sd; no-sdio; @@ -810,8 +844,10 @@ }; &usdhc2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; bus-width = <4>; vmmc-supply = <®_usdhc2_vmmc>; cd-gpios = <&lsio_gpio5 22 GPIO_ACTIVE_LOW>; @@ -819,10 +855,25 @@ status = "okay"; }; +&usbphy1 { + status = "okay"; +}; + &usb3_phy { status = "okay"; }; +&usbotg1 { + vbus-supply = <®_usb_otg1_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg1>; + srp-disable; + hnp-disable; + adp-disable; + disable-over-current; + status = "okay"; +}; + &usbotg3 { status = "okay"; }; @@ -896,6 +947,38 @@ status = "okay"; }; +&thermal_zones { + pmic-thermal { + polling-delay-passive = <250>; + polling-delay = <2000>; + thermal-sensors = <&tsens IMX_SC_R_PMIC_0>; + + trips { + pmic_alert0: trip0 { + temperature = <110000>; + hysteresis = <2000>; + type = "passive"; + }; + + pmic_crit0: trip1 { + temperature = <125000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&pmic_alert0>; + cooling-device = <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; + &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog>; @@ -1011,38 +1094,38 @@ pinctrl_mipi0_lpi2c0: mipi0_lpi2c0grp { fsl,pins = < - IMX8QM_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL 0xc6000020 - IMX8QM_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA 0xc6000020 - IMX8QM_MIPI_DSI0_GPIO0_01_LSIO_GPIO1_IO19 0x00000020 + IMX8QM_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL 0xc6000020 + IMX8QM_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA 0xc6000020 + IMX8QM_MIPI_DSI0_GPIO0_01_LSIO_GPIO1_IO19 0x00000020 >; }; pinctrl_mipi1_lpi2c0: mipi1_lpi2c0grp { fsl,pins = < - IMX8QM_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL 0xc6000020 - IMX8QM_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA 0xc6000020 - IMX8QM_MIPI_DSI1_GPIO0_01_LSIO_GPIO1_IO23 0x00000020 + IMX8QM_MIPI_DSI1_I2C0_SCL_MIPI_DSI1_I2C0_SCL 0xc6000020 + IMX8QM_MIPI_DSI1_I2C0_SDA_MIPI_DSI1_I2C0_SDA 0xc6000020 + IMX8QM_MIPI_DSI1_GPIO0_01_LSIO_GPIO1_IO23 0x00000020 >; }; pinctrl_flexspi0: flexspi0grp { fsl,pins = < - IMX8QM_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x06000021 - IMX8QM_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x06000021 - IMX8QM_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x06000021 - IMX8QM_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x06000021 - IMX8QM_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x06000021 - IMX8QM_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x06000021 - IMX8QM_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B 0x06000021 - IMX8QM_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x06000021 - IMX8QM_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x06000021 - IMX8QM_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x06000021 - IMX8QM_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x06000021 - IMX8QM_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x06000021 - IMX8QM_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x06000021 - IMX8QM_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x06000021 - IMX8QM_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x06000021 - IMX8QM_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x06000021 + IMX8QM_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x06000021 + IMX8QM_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x06000021 + IMX8QM_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x06000021 + IMX8QM_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x06000021 + IMX8QM_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x06000021 + IMX8QM_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x06000021 + IMX8QM_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B 0x06000021 + IMX8QM_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x06000021 + IMX8QM_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x06000021 + IMX8QM_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x06000021 + IMX8QM_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x06000021 + IMX8QM_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x06000021 + IMX8QM_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x06000021 + IMX8QM_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x06000021 + IMX8QM_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x06000021 + IMX8QM_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x06000021 >; }; @@ -1092,6 +1175,15 @@ >; }; + pinctrl_lpuart1: lpuart1grp { + fsl,pins = < + IMX8QM_UART1_RX_DMA_UART1_RX 0x06000020 + IMX8QM_UART1_TX_DMA_UART1_TX 0x06000020 + IMX8QM_UART1_CTS_B_DMA_UART1_CTS_B 0x06000020 + IMX8QM_UART1_RTS_B_DMA_UART1_RTS_B 0x06000020 + >; + }; + pinctrl_lpuart2: lpuart2grp { fsl,pins = < IMX8QM_UART0_RTS_B_DMA_UART2_RX 0x06000020 @@ -1201,6 +1293,12 @@ >; }; + pinctrl_usbotg1: usbotg1grp { + fsl,pins = < + IMX8QM_USB_SS3_TC0_LSIO_GPIO4_IO03 0x06000021 + >; + }; + pinctrl_usdhc1: usdhc1grp { fsl,pins = < IMX8QM_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041 @@ -1228,4 +1326,12 @@ IMX8QM_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021 >; }; + + pinctrl_usdhc2_gpio: usdhc2gpiogrp { + fsl,pins = < + IMX8QM_USDHC1_DATA6_LSIO_GPIO5_IO21 0x00000021 + IMX8QM_USDHC1_DATA7_LSIO_GPIO5_IO22 0x00000021 + IMX8QM_USDHC1_RESET_B_LSIO_GPIO4_IO07 0x00000021 + >; + }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-audio.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-audio.dtsi index c9b55f02497ab..7c5386d4ab2b7 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm-ss-audio.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-audio.dtsi @@ -327,7 +327,8 @@ , /* sai2 */ , /* sai3 */ , /* sai4 */ - ; /* sai5 */ + , /* sai5 */ + ; power-domains = <&pd IMX_SC_R_DMA_2_CH0>, <&pd IMX_SC_R_DMA_2_CH1>, <&pd IMX_SC_R_DMA_2_CH2>, @@ -365,7 +366,8 @@ , /* no used */ , /* sai6 */ , - ; /* sai7 */ + , /* sai7 */ + ; power-domains = <&pd IMX_SC_R_DMA_3_CH0>, <&pd IMX_SC_R_DMA_3_CH1>, <&pd IMX_SC_R_DMA_3_CH2>, diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi index d4856b8590e0c..5f24850bf322a 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi @@ -99,7 +99,8 @@ , , , - ; + , + ; power-domains = <&pd IMX_SC_R_DMA_0_CH0>, <&pd IMX_SC_R_DMA_0_CH1>, <&pd IMX_SC_R_DMA_0_CH2>, diff --git a/arch/arm64/boot/dts/freescale/imx8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm.dtsi index 5206ca82eaf64..cb66853b1cd3f 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qm.dtsi @@ -369,7 +369,7 @@ }; }; - thermal-zones { + thermal_zones: thermal-zones { cpu0-thermal { polling-delay-passive = <250>; polling-delay = <2000>; diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts index 7b03374455410..523f48896b6b8 100644 --- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts +++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts @@ -150,6 +150,13 @@ regulator-max-microvolt = <2800000>; }; + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + reg_pcieb: regulator-pcie { compatible = "regulator-fixed"; regulator-max-microvolt = <3300000>; @@ -212,6 +219,15 @@ vin-supply = <®_can_en>; }; + reg_fec2_supply: regulator-fec2_nvcc { + compatible = "regulator-fixed"; + regulator-name = "fec2_nvcc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&max7322 0 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + reg_usb_otg1_vbus: regulator-usbotg1-vbus { compatible = "regulator-fixed"; regulator-max-microvolt = <5000000>; @@ -397,6 +413,8 @@ pinctrl-0 = <&pinctrl_fec1>; phy-mode = "rgmii-id"; phy-handle = <ðphy0>; + nvmem-cells = <&fec_mac0>; + nvmem-cell-names = "mac-address"; fsl,magic-packet; status = "okay"; @@ -408,9 +426,26 @@ compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; }; + + ethphy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; }; }; +&fec2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec2>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy1>; + phy-supply = <®_fec2_supply>; + fsl,magic-packet; + nvmem-cells = <&fec_mac1>; + nvmem-cell-names = "mac-address"; + status = "disabled"; +}; + &i2c1 { #address-cells = <1>; #size-cells = <0>; @@ -453,6 +488,8 @@ pressure-sensor@60 { compatible = "fsl,mpl3115"; reg = <0x60>; + vdd-supply = <®_3v3>; + vddio-supply = <®_3v3>; }; }; @@ -586,6 +623,20 @@ status = "okay"; }; +&flexspi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexspi0>; + status = "okay"; + + flash0: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <133000000>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + }; +}; + &jpegdec { status = "okay"; }; @@ -600,6 +651,16 @@ status = "okay"; }; +&lpuart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpuart1>; + status = "okay"; + + bluetooth { + compatible = "nxp,88w8987-bt"; + }; +}; + &lpuart2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lpuart2>; @@ -631,6 +692,8 @@ pinctrl-names = "default"; reset-gpios = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>; vpcie-supply = <®_pcieb>; + vpcie3v3aux-supply = <®_pcieb>; + supports-clkreq; status = "okay"; }; @@ -729,9 +792,11 @@ &usdhc1 { assigned-clocks = <&clk IMX_SC_R_SDHC_0 IMX_SC_PM_CLK_PER>; - assigned-clock-rates = <200000000>; - pinctrl-names = "default"; + assigned-clock-rates = <400000000>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1>; + pinctrl-2 = <&pinctrl_usdhc1>; bus-width = <8>; no-sd; no-sdio; @@ -742,8 +807,10 @@ &usdhc2 { assigned-clocks = <&clk IMX_SC_R_SDHC_1 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <200000000>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; bus-width = <4>; vmmc-supply = <®_usdhc2_vmmc>; cd-gpios = <&lsio_gpio4 22 GPIO_ACTIVE_LOW>; @@ -807,8 +874,8 @@ pinctrl_cm40_i2c: cm40i2cgrp { fsl,pins = < - IMX8QXP_ADC_IN1_M40_I2C0_SDA 0x0600004c - IMX8QXP_ADC_IN0_M40_I2C0_SCL 0x0600004c + IMX8QXP_ADC_IN1_M40_I2C0_SDA 0x0600004c + IMX8QXP_ADC_IN0_M40_I2C0_SCL 0x0600004c >; }; @@ -821,16 +888,16 @@ pinctrl_esai0: esai0grp { fsl,pins = < - IMX8QXP_ESAI0_FSR_ADMA_ESAI0_FSR 0xc6000040 - IMX8QXP_ESAI0_FST_ADMA_ESAI0_FST 0xc6000040 - IMX8QXP_ESAI0_SCKR_ADMA_ESAI0_SCKR 0xc6000040 - IMX8QXP_ESAI0_SCKT_ADMA_ESAI0_SCKT 0xc6000040 - IMX8QXP_ESAI0_TX0_ADMA_ESAI0_TX0 0xc6000040 - IMX8QXP_ESAI0_TX1_ADMA_ESAI0_TX1 0xc6000040 - IMX8QXP_ESAI0_TX2_RX3_ADMA_ESAI0_TX2_RX3 0xc6000040 - IMX8QXP_ESAI0_TX3_RX2_ADMA_ESAI0_TX3_RX2 0xc6000040 - IMX8QXP_ESAI0_TX4_RX1_ADMA_ESAI0_TX4_RX1 0xc6000040 - IMX8QXP_ESAI0_TX5_RX0_ADMA_ESAI0_TX5_RX0 0xc6000040 + IMX8QXP_ESAI0_FSR_ADMA_ESAI0_FSR 0xc6000040 + IMX8QXP_ESAI0_FST_ADMA_ESAI0_FST 0xc6000040 + IMX8QXP_ESAI0_SCKR_ADMA_ESAI0_SCKR 0xc6000040 + IMX8QXP_ESAI0_SCKT_ADMA_ESAI0_SCKT 0xc6000040 + IMX8QXP_ESAI0_TX0_ADMA_ESAI0_TX0 0xc6000040 + IMX8QXP_ESAI0_TX1_ADMA_ESAI0_TX1 0xc6000040 + IMX8QXP_ESAI0_TX2_RX3_ADMA_ESAI0_TX2_RX3 0xc6000040 + IMX8QXP_ESAI0_TX3_RX2_ADMA_ESAI0_TX3_RX2 0xc6000040 + IMX8QXP_ESAI0_TX4_RX1_ADMA_ESAI0_TX4_RX1 0xc6000040 + IMX8QXP_ESAI0_TX5_RX0_ADMA_ESAI0_TX5_RX0 0xc6000040 >; }; @@ -853,6 +920,23 @@ >; }; + pinctrl_fec2: fec2grp { + fsl,pins = < + IMX8QXP_ESAI0_SCKR_CONN_ENET1_RGMII_TX_CTL 0x00000060 + IMX8QXP_ESAI0_FSR_CONN_ENET1_RGMII_TXC 0x00000060 + IMX8QXP_ESAI0_TX4_RX1_CONN_ENET1_RGMII_TXD0 0x00000060 + IMX8QXP_ESAI0_TX5_RX0_CONN_ENET1_RGMII_TXD1 0x00000060 + IMX8QXP_ESAI0_FST_CONN_ENET1_RGMII_TXD2 0x00000060 + IMX8QXP_ESAI0_SCKT_CONN_ENET1_RGMII_TXD3 0x00000060 + IMX8QXP_ESAI0_TX0_CONN_ENET1_RGMII_RXC 0x00000060 + IMX8QXP_SPDIF0_TX_CONN_ENET1_RGMII_RX_CTL 0x00000060 + IMX8QXP_SPDIF0_RX_CONN_ENET1_RGMII_RXD0 0x00000060 + IMX8QXP_ESAI0_TX3_RX2_CONN_ENET1_RGMII_RXD1 0x00000060 + IMX8QXP_ESAI0_TX2_RX3_CONN_ENET1_RGMII_RXD2 0x00000060 + IMX8QXP_ESAI0_TX1_CONN_ENET1_RGMII_RXD3 0x00000060 + >; + }; + pinctrl_flexcan1: flexcan0grp { fsl,pins = < IMX8QXP_FLEXCAN0_TX_ADMA_FLEXCAN0_TX 0x21 @@ -874,6 +958,27 @@ >; }; + pinctrl_flexspi0: flexspi0grp { + fsl,pins = < + IMX8QXP_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x06000021 + IMX8QXP_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x06000021 + IMX8QXP_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x06000021 + IMX8QXP_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x06000021 + IMX8QXP_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x06000021 + IMX8QXP_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x06000021 + IMX8QXP_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B 0x06000021 + IMX8QXP_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x06000021 + IMX8QXP_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x06000021 + IMX8QXP_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x06000021 + IMX8QXP_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x06000021 + IMX8QXP_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x06000021 + IMX8QXP_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x06000021 + IMX8QXP_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x06000021 + IMX8QXP_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x06000021 + IMX8QXP_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x06000021 + >; + }; + pinctrl_ioexp_rst: ioexprstgrp { fsl,pins = < IMX8QXP_SPI2_SDO_LSIO_GPIO1_IO01 0x06000021 @@ -900,17 +1005,26 @@ >; }; + pinctrl_lpuart1: lpuart1grp { + fsl,pins = < + IMX8QXP_UART1_TX_ADMA_UART1_TX 0x06000020 + IMX8QXP_UART1_RX_ADMA_UART1_RX 0x06000020 + IMX8QXP_UART1_RTS_B_ADMA_UART1_RTS_B 0x06000020 + IMX8QXP_UART1_CTS_B_ADMA_UART1_CTS_B 0x06000020 + >; + }; + pinctrl_lpuart2: lpuart2grp { fsl,pins = < - IMX8QXP_UART2_TX_ADMA_UART2_TX 0x06000020 - IMX8QXP_UART2_RX_ADMA_UART2_RX 0x06000020 + IMX8QXP_UART2_TX_ADMA_UART2_TX 0x06000020 + IMX8QXP_UART2_RX_ADMA_UART2_RX 0x06000020 >; }; pinctrl_lpuart3: lpuart3grp { fsl,pins = < - IMX8QXP_FLEXCAN2_TX_ADMA_UART3_TX 0x06000020 - IMX8QXP_FLEXCAN2_RX_ADMA_UART3_RX 0x06000020 + IMX8QXP_FLEXCAN2_TX_ADMA_UART3_TX 0x06000020 + IMX8QXP_FLEXCAN2_RX_ADMA_UART3_RX 0x06000020 >; }; @@ -932,13 +1046,13 @@ pinctrl_typec: typecgrp { fsl,pins = < - IMX8QXP_SPI2_SCK_LSIO_GPIO1_IO03 0x06000021 + IMX8QXP_SPI2_SCK_LSIO_GPIO1_IO03 0x06000021 >; }; pinctrl_typec_mux: typecmuxgrp { fsl,pins = < - IMX8QXP_ENET0_REFCLK_125M_25M_LSIO_GPIO5_IO09 0x60 + IMX8QXP_ENET0_REFCLK_125M_25M_LSIO_GPIO5_IO09 0x60 >; }; @@ -953,11 +1067,11 @@ pinctrl_sai1: sai1grp { fsl,pins = < - IMX8QXP_SAI1_RXD_ADMA_SAI1_RXD 0x06000040 - IMX8QXP_SAI1_RXC_ADMA_SAI1_TXC 0x06000040 - IMX8QXP_SAI1_RXFS_ADMA_SAI1_TXFS 0x06000040 - IMX8QXP_SPI0_CS1_ADMA_SAI1_TXD 0x06000060 - IMX8QXP_SPI2_CS0_LSIO_GPIO1_IO00 0x06000040 + IMX8QXP_SAI1_RXD_ADMA_SAI1_RXD 0x06000040 + IMX8QXP_SAI1_RXC_ADMA_SAI1_TXC 0x06000040 + IMX8QXP_SAI1_RXFS_ADMA_SAI1_TXFS 0x06000040 + IMX8QXP_SPI0_CS1_ADMA_SAI1_TXD 0x06000060 + IMX8QXP_SPI2_CS0_LSIO_GPIO1_IO00 0x06000040 >; }; @@ -977,6 +1091,14 @@ >; }; + pinctrl_usdhc2_gpio: usdhc2gpiogrp { + fsl,pins = < + IMX8QXP_USDHC1_RESET_B_LSIO_GPIO4_IO19 0x00000021 + IMX8QXP_USDHC1_WP_LSIO_GPIO4_IO21 0x00000021 + IMX8QXP_USDHC1_CD_B_LSIO_GPIO4_IO22 0x00000021 + >; + }; + pinctrl_usdhc2: usdhc2grp { fsl,pins = < IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041 diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi index 95edab058276b..7c4a50e0ec9e9 100644 --- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi @@ -234,11 +234,20 @@ compatible = "fsl,imx8qxp-scu-ocotp"; #address-cells = <1>; #size-cells = <1>; + + fec_mac0: mac@2c4 { + reg = <0x2c4 6>; + }; + + fec_mac1: mac@2c6 { + reg = <0x2c6 6>; + }; }; scu_key: keys { compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key"; linux,keycodes = ; + wakeup-source; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/freescale/imx91-phyboard-segin.dts b/arch/arm64/boot/dts/freescale/imx91-phyboard-segin.dts new file mode 100644 index 0000000000000..7b18a58024f5c --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx91-phyboard-segin.dts @@ -0,0 +1,345 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + * Author: Christoph Stoidner + * + * Product homepage: + * phyBOARD-Segin carrier board is reused for the i.MX91 design. + * https://www.phytec.eu/en/produkte/single-board-computer/phyboard-segin-imx6ul/ + */ +/dts-v1/; + +#include "imx91-phycore-som.dtsi" + +/{ + model = "PHYTEC phyBOARD-Segin-i.MX91"; + compatible = "phytec,imx91-phyboard-segin", "phytec,imx91-phycore-som", + "fsl,imx91"; + + aliases { + ethernet1 = &eqos; + gpio0 = &gpio1; + gpio1 = &gpio2; + gpio2 = &gpio3; + gpio3 = &gpio4; + i2c0 = &lpi2c1; + i2c1 = &lpi2c2; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + rtc0 = &i2c_rtc; + rtc1 = &bbnsm_rtc; + serial0 = &lpuart1; + }; + + chosen { + stdout-path = &lpuart1; + }; + + flexcan1_tc: can-phy0 { + /* TI SN65HVD234D CAN-CC 1MBit/s */ + compatible = "ti,tcan1043"; + #phy-cells = <0>; + max-bitrate = <1000000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1_tc>; + enable-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>; + }; + + reg_sound_1v8: regulator-sound-1v8 { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "VCC1V8_AUDIO"; + }; + + reg_sound_3v3: regulator-sound-3v3 { + compatible = "regulator-fixed"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "VCC3V3_ANALOG"; + }; + + reg_usb_otg1_vbus: regulator-usb-otg1-vbus { + compatible = "regulator-fixed"; + regulator-name = "USB_OTG1_VBUS"; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usb_otg2_vbus: regulator-usb-otg2-vbus { + compatible = "regulator-fixed"; + regulator-name = "USB_OTG2_VBUS"; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usdhc2_vmmc: regulator-usdhc2 { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "VCC_SD"; + }; + + sound: sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "phyBOARD-Segin-TLV320AIC3007"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,widgets = + "Line", "Line In", + "Line", "Line Out", + "Speaker", "Speaker"; + simple-audio-card,routing = + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "Speaker", "SPOP", + "Speaker", "SPOM", + "LINE1L", "Line In", + "LINE1R", "Line In"; + + simple-audio-card,cpu { + sound-dai = <&sai1>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&audio_codec>; + clocks = <&clk IMX93_CLK_SAI1>; + }; + }; +}; + +/* Ethernet */ +&eqos { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_eqos>; + phy-mode = "rmii"; + phy-handle = <ðphy2>; + assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>, + <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>; + assigned-clock-rates = <100000000>, <50000000>; + status = "okay"; +}; + +&mdio { + ethphy2: ethernet-phy@2 { + compatible = "ethernet-phy-id0022.1561"; + reg = <2>; + clocks = <&clk IMX91_CLK_ENET2_REGULAR>; + clock-names = "rmii-ref"; + micrel,led-mode = <1>; + }; +}; + +/* CAN */ +&flexcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; + phys = <&flexcan1_tc>; + status = "okay"; +}; + +/* I2C2 */ +&lpi2c2 { + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c2>; + pinctrl-1 = <&pinctrl_lpi2c2_gpio>; + scl-gpios = <&gpio1 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "okay"; + + /* Codec */ + audio_codec: audio-codec@18 { + compatible = "ti,tlv320aic3007"; + reg = <0x18>; + #sound-dai-cells = <0>; + AVDD-supply = <®_sound_3v3>; + IOVDD-supply = <®_sound_3v3>; + DRVDD-supply = <®_sound_3v3>; + DVDD-supply = <®_sound_1v8>; + }; + + /* RTC */ + i2c_rtc: rtc@68 { + compatible = "microcrystal,rv4162"; + reg = <0x68>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rtc>; + interrupt-parent = <&gpio4>; + interrupts = <26 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +/* Console */ +&lpuart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +/* Audio */ +&sai1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai1>; + assigned-clocks = <&clk IMX93_CLK_SAI1>; + assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; + assigned-clock-rates = <19200000>; + fsl,sai-mclk-direction-output; + status = "okay"; +}; + +/* USB */ +&usbphynop1 { + vbus-supply = <®_usb_otg1_vbus>; +}; + +&usbphynop2 { + vbus-supply = <®_usb_otg2_vbus>; +}; + +&usbotg1 { + disable-over-current; + dr_mode = "otg"; + status = "okay"; +}; + +&usbotg2 { + disable-over-current; + dr_mode = "host"; + status = "okay"; +}; + +/* SD-Card */ +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2_default>, <&pinctrl_usdhc2_cd>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_cd>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>; + bus-width = <4>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + disable-wp; + no-mmc; + no-sdio; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&iomuxc { + pinctrl_eqos: eqosgrp { + fsl,pins = < + MX91_PAD_ENET1_TD2__ENET_QOS_CLOCK_GENERATE_CLK 0x4000050e + MX91_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x57e + MX91_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x57e + MX91_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x50e + MX91_PAD_ENET1_TD1__ENET1_RGMII_TD1 0x50e + MX91_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x57e + MX91_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x50e + MX91_PAD_ENET1_RXC__ENET_QOS_RX_ER 0x57e + >; + }; + + pinctrl_flexcan1: flexcan1grp { + fsl,pins = < + MX91_PAD_PDM_BIT_STREAM0__CAN1_RX 0x139e + MX91_PAD_PDM_CLK__CAN1_TX 0x139e + >; + }; + + pinctrl_flexcan1_tc: flexcan1tcgrp { + fsl,pins = < + MX91_PAD_ENET2_TD3__GPIO4_IO16 0x31e + >; + }; + + pinctrl_lpi2c2: lpi2c2grp { + fsl,pins = < + MX91_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e + MX91_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e + >; + }; + + pinctrl_lpi2c2_gpio: lpi2c2gpiogrp { + fsl,pins = < + MX91_PAD_I2C2_SCL__GPIO1_IO2 0x31e + MX91_PAD_I2C2_SDA__GPIO1_IO3 0x31e + >; + }; + + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { + fsl,pins = < + MX91_PAD_SD2_RESET_B__GPIO3_IO7 0x31e + >; + }; + + pinctrl_rtc: rtcgrp { + fsl,pins = < + MX91_PAD_ENET2_RD2__GPIO4_IO26 0x31e + >; + }; + + pinctrl_sai1: sai1grp { + fsl,pins = < + MX91_PAD_UART2_RXD__SAI1_MCLK 0x1202 + MX91_PAD_SAI1_TXFS__SAI1_TX_SYNC 0x1202 + MX91_PAD_SAI1_TXC__SAI1_TX_BCLK 0x1202 + MX91_PAD_SAI1_TXD0__SAI1_TX_DATA0 0x1402 + MX91_PAD_SAI1_RXD0__SAI1_RX_DATA0 0x1402 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX91_PAD_UART1_RXD__LPUART1_RX 0x31e + MX91_PAD_UART1_TXD__LPUART1_TX 0x30e + >; + }; + + pinctrl_usdhc2_cd: usdhc2cdgrp { + fsl,pins = < + MX91_PAD_SD2_CD_B__GPIO3_IO0 0x31e + >; + }; + + pinctrl_usdhc2_default: usdhc2grp { + fsl,pins = < + MX91_PAD_SD2_CLK__USDHC2_CLK 0x158e + MX91_PAD_SD2_CMD__USDHC2_CMD 0x1382 + MX91_PAD_SD2_DATA0__USDHC2_DATA0 0x1386 + MX91_PAD_SD2_DATA1__USDHC2_DATA1 0x138e + MX91_PAD_SD2_DATA2__USDHC2_DATA2 0x139e + MX91_PAD_SD2_DATA3__USDHC2_DATA3 0x139e + MX91_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = < + MX91_PAD_SD2_CLK__USDHC2_CLK 0x159e + MX91_PAD_SD2_CMD__USDHC2_CMD 0x139e + MX91_PAD_SD2_DATA0__USDHC2_DATA0 0x138e + MX91_PAD_SD2_DATA1__USDHC2_DATA1 0x138e + MX91_PAD_SD2_DATA2__USDHC2_DATA2 0x139e + MX91_PAD_SD2_DATA3__USDHC2_DATA3 0x139e + MX91_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = < + MX91_PAD_SD2_CLK__USDHC2_CLK 0x158e + MX91_PAD_SD2_CMD__USDHC2_CMD 0x138e + MX91_PAD_SD2_DATA0__USDHC2_DATA0 0x139e + MX91_PAD_SD2_DATA1__USDHC2_DATA1 0x139e + MX91_PAD_SD2_DATA2__USDHC2_DATA2 0x139e + MX91_PAD_SD2_DATA3__USDHC2_DATA3 0x139e + MX91_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx91-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx91-phycore-som.dtsi new file mode 100644 index 0000000000000..29a428a052b07 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx91-phycore-som.dtsi @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + * Author: Christoph Stoidner + * + * Product homepage: + * https://www.phytec.eu/en/produkte/system-on-modules/phycore-imx-91-93/ + */ + +#include + +#include "imx91.dtsi" + +/ { + model = "PHYTEC phyCORE-i.MX91"; + compatible = "phytec,imx91-phycore-som", "fsl,imx91"; + + aliases { + ethernet0 = &fec; + }; + + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + alloc-ranges = <0 0x80000000 0 0x40000000>; + size = <0 0x10000000>; + linux,cma-default; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_leds>; + + led-0 { + color = ; + function = LED_FUNCTION_HEARTBEAT; + gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + reg_vdda_1v8: regulator-vdda-1v8 { + compatible = "regulator-fixed"; + regulator-name = "VDDA_1V8"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + vin-supply = <&buck5>; + }; +}; + +/* ADC */ +&adc1 { + vref-supply = <®_vdda_1v8>; +}; + +/* Ethernet */ +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec>; + phy-mode = "rmii"; + phy-handle = <ðphy1>; + + assigned-clocks = <&clk IMX91_CLK_ENET_TIMER>, + <&clk IMX91_CLK_ENET2_REGULAR>; + assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>, + <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>; + assigned-clock-rates = <100000000>, <50000000>; + status = "okay"; + + mdio: mdio { + clock-frequency = <5000000>; + #address-cells = <1>; + #size-cells = <0>; + + ethphy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + reset-gpios = <&gpio4 23 GPIO_ACTIVE_HIGH>; + reset-assert-us = <30>; + }; + }; +}; + +/* I2C3 */ +&lpi2c3 { + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c3>; + pinctrl-1 = <&pinctrl_lpi2c3_gpio>; + scl-gpios = <&gpio2 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "okay"; + + pmic@25 { + compatible = "nxp,pca9451a"; + reg = <0x25>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio4>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + + regulators { + buck1: BUCK1 { + regulator-name = "VDD_SOC"; + regulator-max-microvolt = <950000>; + regulator-min-microvolt = <610000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <3125>; + }; + + buck2: BUCK2 { + regulator-name = "VDDQ_0V6"; + regulator-max-microvolt = <600000>; + regulator-min-microvolt = <600000>; + regulator-boot-on; + regulator-always-on; + }; + + buck4: BUCK4 { + regulator-name = "VDD_3V3_BUCK"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + buck5: BUCK5 { + regulator-name = "VDD_1V8"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + buck6: BUCK6 { + regulator-name = "VDD_1V1"; + regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1100000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1: LDO1 { + regulator-name = "PMIC_SNVS_1V8"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4: LDO4 { + regulator-name = "VDD_0V8"; + regulator-max-microvolt = <800000>; + regulator-min-microvolt = <800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo5: LDO5 { + regulator-name = "NVCC_SD2"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + /* EEPROM */ + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + vcc-supply = <&buck4>; + }; +}; + +/* eMMC */ +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + bus-width = <8>; + non-removable; + no-1-8-v; + status = "okay"; +}; + +/* Watchdog */ +&wdog3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + pinctrl_fec: fecgrp { + fsl,pins = < + MX91_PAD_ENET2_MDC__ENET2_MDC 0x50e + MX91_PAD_ENET2_MDIO__ENET2_MDIO 0x502 + /* the three pins below are connected to PHYs straps, + * that is what the pull-up/down setting is for. + */ + MX91_PAD_ENET2_RD0__ENET2_RGMII_RD0 0x37e + MX91_PAD_ENET2_RD1__ENET2_RGMII_RD1 0x37e + MX91_PAD_ENET2_RX_CTL__ENET2_RGMII_RX_CTL 0x57e + MX91_PAD_ENET2_TD0__ENET2_RGMII_TD0 0x50e + MX91_PAD_ENET2_TD1__ENET2_RGMII_TD1 0x50e + MX91_PAD_ENET2_TX_CTL__ENET2_RGMII_TX_CTL 0x50e + MX91_PAD_ENET2_TD2__ENET2_TX_CLK2 0x4000050e + MX91_PAD_ENET2_RXC__GPIO4_IO23 0x51e + >; + }; + + pinctrl_leds: ledsgrp { + fsl,pins = < + MX91_PAD_I2C1_SDA__GPIO1_IO1 0x11e + >; + }; + + pinctrl_lpi2c3: lpi2c3grp { + fsl,pins = < + MX91_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e + MX91_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e + >; + }; + + pinctrl_lpi2c3_gpio: lpi2c3gpiogrp { + fsl,pins = < + MX91_PAD_GPIO_IO28__GPIO2_IO28 0x31e + MX91_PAD_GPIO_IO29__GPIO2_IO29 0x31e + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX91_PAD_ENET2_RD3__GPIO4_IO27 0x31e + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX91_PAD_SD1_CLK__USDHC1_CLK 0x179e + MX91_PAD_SD1_CMD__USDHC1_CMD 0x1386 + MX91_PAD_SD1_DATA0__USDHC1_DATA0 0x138e + MX91_PAD_SD1_DATA1__USDHC1_DATA1 0x1386 + MX91_PAD_SD1_DATA2__USDHC1_DATA2 0x138e + MX91_PAD_SD1_DATA3__USDHC1_DATA3 0x1386 + MX91_PAD_SD1_DATA4__USDHC1_DATA4 0x1386 + MX91_PAD_SD1_DATA5__USDHC1_DATA5 0x1386 + MX91_PAD_SD1_DATA6__USDHC1_DATA6 0x1386 + MX91_PAD_SD1_DATA7__USDHC1_DATA7 0x1386 + MX91_PAD_SD1_STROBE__USDHC1_STROBE 0x179e + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { + fsl,pins = < + MX91_PAD_SD1_CLK__USDHC1_CLK 0x17be + MX91_PAD_SD1_CMD__USDHC1_CMD 0x139e + MX91_PAD_SD1_DATA0__USDHC1_DATA0 0x138e + MX91_PAD_SD1_DATA1__USDHC1_DATA1 0x139e + MX91_PAD_SD1_DATA2__USDHC1_DATA2 0x13be + MX91_PAD_SD1_DATA3__USDHC1_DATA3 0x139e + MX91_PAD_SD1_DATA4__USDHC1_DATA4 0x139e + MX91_PAD_SD1_DATA5__USDHC1_DATA5 0x139e + MX91_PAD_SD1_DATA6__USDHC1_DATA6 0x139e + MX91_PAD_SD1_DATA7__USDHC1_DATA7 0x139e + MX91_PAD_SD1_STROBE__USDHC1_STROBE 0x179e + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + fsl,pins = < + MX91_PAD_SD1_CLK__USDHC1_CLK 0x17be + MX91_PAD_SD1_CMD__USDHC1_CMD 0x139e + MX91_PAD_SD1_DATA0__USDHC1_DATA0 0x139e + MX91_PAD_SD1_DATA1__USDHC1_DATA1 0x13be + MX91_PAD_SD1_DATA2__USDHC1_DATA2 0x13be + MX91_PAD_SD1_DATA3__USDHC1_DATA3 0x13be + MX91_PAD_SD1_DATA4__USDHC1_DATA4 0x13be + MX91_PAD_SD1_DATA5__USDHC1_DATA5 0x13be + MX91_PAD_SD1_DATA6__USDHC1_DATA6 0x13be + MX91_PAD_SD1_DATA7__USDHC1_DATA7 0x13be + MX91_PAD_SD1_STROBE__USDHC1_STROBE 0x179e + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX91_PAD_WDOG_ANY__WDOG1_WDOG_ANY 0x31e + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi b/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi index 52da571f26c4e..7958cef353766 100644 --- a/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi +++ b/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi @@ -706,7 +706,7 @@ }; flexspi1: spi@425e0000 { - compatible = "nxp,imx8mm-fspi"; + compatible = "nxp,imx93-fspi", "nxp,imx8mm-fspi"; reg = <0x425e0000 0x10000>, <0x28000000 0x10000000>; reg-names = "fspi_base", "fspi_mmap"; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/imx93-phyboard-nash-jtag.dtso b/arch/arm64/boot/dts/freescale/imx93-phyboard-nash-jtag.dtso new file mode 100644 index 0000000000000..89f93dca3208b --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-phyboard-nash-jtag.dtso @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + * Author: Primoz Fiser + */ + +#include "imx93-pinfunc.h" + +/dts-v1/; +/plugin/; + +/* + * NOTE: Bind pinctrl_jtag to gpio2 so that the pinctrl settings are applied. + * JTAG itself has no dedicated driver, so without attaching it to an active + * device node (like gpio2), the pinmux configuration would not take effect. + */ +&gpio2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_jtag>; +}; + +&iomuxc { + pinctrl_jtag: jtaggrp { + fsl,pins = < + MX93_PAD_GPIO_IO24__JTAG_MUX_TDO 0x31e + MX93_PAD_GPIO_IO25__JTAG_MUX_TCK 0x31e + MX93_PAD_GPIO_IO26__JTAG_MUX_TDI 0x31e + MX93_PAD_GPIO_IO27__JTAG_MUX_TMS 0x31e + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx93-phyboard-nash-pwm-fan.dtso b/arch/arm64/boot/dts/freescale/imx93-phyboard-nash-pwm-fan.dtso new file mode 100644 index 0000000000000..d1adf04d56d9b --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-phyboard-nash-pwm-fan.dtso @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2025 PHYTEC Messtechnik GmbH + * Author: Primoz Fiser + */ + +#include +#include "imx93-pinfunc.h" + +/dts-v1/; +/plugin/; + +&{/} { + fan0: pwm-fan { + compatible = "pwm-fan"; + #cooling-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fan>; + cooling-levels = <1 90 150 200 255>; + pwms = <&tpm6 1 40000 PWM_POLARITY_INVERTED>; + }; + + thermal-zones { + cpu-thermal { + trips { + cpu_low: cpu-low { + hysteresis = <3000>; + temperature = <50000>; + type = "active"; + }; + + cpu_med: cpu-med { + hysteresis = <3000>; + temperature = <58000>; + type = "active"; + }; + + cpu_high: cpu-high { + hysteresis = <3000>; + temperature = <65000>; + type = "active"; + }; + }; + + cooling-maps { + map1 { + cooling-device = <&fan0 1 1>; + trip = <&cpu_low>; + }; + + map2 { + cooling-device = <&fan0 2 2>; + trip = <&cpu_med>; + }; + + map3 { + cooling-device = <&fan0 4 4>; + trip = <&cpu_high>; + }; + }; + }; + }; +}; + +&tpm6 { + status = "okay"; +}; + +&iomuxc { + pinctrl_fan: fangrp { + fsl,pins = < + MX93_PAD_GPIO_IO23__TPM6_CH1 0x31e + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx93-phyboard-nash.dts b/arch/arm64/boot/dts/freescale/imx93-phyboard-nash.dts index 5599e296919f4..9e875e082ee87 100644 --- a/arch/arm64/boot/dts/freescale/imx93-phyboard-nash.dts +++ b/arch/arm64/boot/dts/freescale/imx93-phyboard-nash.dts @@ -71,6 +71,22 @@ io-channels = <&curr_sens 0>; }; + reg_usb1_vbus: regulator-usb1-vbus { + compatible = "regulator-fixed"; + regulator-name = "USB1_VBUS"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usb2_vbus: regulator-usb2-vbus { + compatible = "regulator-fixed"; + regulator-name = "USB2_VBUS"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + reg_usdhc2_vmmc: regulator-usdhc2 { compatible = "regulator-fixed"; gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; @@ -187,6 +203,14 @@ }; /* USB */ +&usbphynop1 { + vbus-supply = <®_usb1_vbus>; +}; + +&usbphynop2 { + vbus-supply = <®_usb2_vbus>; +}; + &usbotg1 { disable-over-current; dr_mode = "otg"; diff --git a/arch/arm64/boot/dts/freescale/imx93-phyboard-segin.dts b/arch/arm64/boot/dts/freescale/imx93-phyboard-segin.dts index 802d96b19e4cc..ac64abacc4a27 100644 --- a/arch/arm64/boot/dts/freescale/imx93-phyboard-segin.dts +++ b/arch/arm64/boot/dts/freescale/imx93-phyboard-segin.dts @@ -59,6 +59,22 @@ regulator-name = "VCC3V3_ANALOG"; }; + reg_usb_otg1_vbus: regulator-usb-otg1-vbus { + compatible = "regulator-fixed"; + regulator-name = "USB_OTG1_VBUS"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usb_otg2_vbus: regulator-usb-otg2-vbus { + compatible = "regulator-fixed"; + regulator-name = "USB_OTG2_VBUS"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + reg_usdhc2_vmmc: regulator-usdhc2 { compatible = "regulator-fixed"; enable-active-high; @@ -177,6 +193,14 @@ }; /* USB */ +&usbphynop1 { + vbus-supply = <®_usb_otg1_vbus>; +}; + +&usbphynop2 { + vbus-supply = <®_usb_otg2_vbus>; +}; + &usbotg1 { disable-over-current; dr_mode = "otg"; diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi index 82914ca148d3a..3a23e2eb9febe 100644 --- a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi +++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi @@ -67,6 +67,7 @@ spi-max-frequency = <62000000>; spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; + vcc-supply = <&buck5>; partitions { compatible = "fixed-partitions"; diff --git a/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi index a5f09487d8036..2dc8b18ae91e5 100644 --- a/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi @@ -12,7 +12,35 @@ model = "Variscite VAR-SOM-MX93 module"; compatible = "variscite,var-som-mx93", "fsl,imx93"; - mmc_pwrseq: mmc-pwrseq { + sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&codec_dai>; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&codec_dai>; + simple-audio-card,name = "wm8904-audio"; + simple-audio-card,routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "IN1L", "Microphone Jack", + "IN1R", "Microphone Jack"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack", + "Line", "Line In Jack"; + simple-audio-card,mclk-fs = <256>; + + codec_dai: simple-audio-card,codec { + sound-dai = <&wm8904>; + }; + + simple-audio-card,cpu { + sound-dai = <&sai1>; + }; + }; + + usdhc3_pwrseq: mmc-pwrseq { compatible = "mmc-pwrseq-simple"; post-power-on-delay-ms = <100>; power-off-delay-us = <10000>; @@ -70,6 +98,175 @@ }; }; +&lpi2c3 { + clock-frequency = <400000>; + pinctrl-names = "default", "sleep", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c3>; + pinctrl-1 = <&pinctrl_lpi2c3_gpio>; + pinctrl-2 = <&pinctrl_lpi2c3_gpio>; + scl-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>; + sda-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>; + status = "okay"; + + pmic@25 { + compatible = "nxp,pca9451a"; + reg = <0x25>; + + regulators { + buck1: BUCK1 { + regulator-name = "BUCK1"; + regulator-min-microvolt = <650000>; + regulator-max-microvolt = <2237500>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <3125>; + }; + + buck2: BUCK2 { + regulator-name = "BUCK2"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <2187500>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <3125>; + }; + + buck4: BUCK4{ + regulator-name = "BUCK4"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-always-on; + }; + + buck5: BUCK5{ + regulator-name = "BUCK5"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-always-on; + }; + + buck6: BUCK6 { + regulator-name = "BUCK6"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1: LDO1 { + regulator-name = "LDO1"; + regulator-min-microvolt = <1600000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4: LDO4 { + regulator-name = "LDO4"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo5: LDO5 { + regulator-name = "LDO5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + wm8904: audio-codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + #sound-dai-cells = <0>; + clocks = <&clk IMX93_CLK_SAI1_GATE>; + clock-names = "mclk"; + AVDD-supply = <&buck5>; + CPVDD-supply = <&buck5>; + DBVDD-supply = <&buck4>; + DCVDD-supply = <&buck5>; + MICVDD-supply = <&buck5>; + wlf,drc-cfg-names = "default", "peaklimiter", "tradition", + "soft", "music"; + /* + * Config registers per name, respectively: + * KNEE_IP = 0, KNEE_OP = 0, HI_COMP = 1, LO_COMP = 1 + * KNEE_IP = -24, KNEE_OP = -6, HI_COMP = 1/4, LO_COMP = 1 + * KNEE_IP = -42, KNEE_OP = -3, HI_COMP = 0, LO_COMP = 1 + * KNEE_IP = -45, KNEE_OP = -9, HI_COMP = 1/8, LO_COMP = 1 + * KNEE_IP = -30, KNEE_OP = -10.5, HI_COMP = 1/4, LO_COMP = 1 + */ + wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>, + /bits/ 16 <0x04af 0x324b 0x0010 0x0408>, + /bits/ 16 <0x04af 0x324b 0x0028 0x0704>, + /bits/ 16 <0x04af 0x324b 0x0018 0x078c>, + /bits/ 16 <0x04af 0x324b 0x0010 0x050e>; + /* GPIO1 = DMIC_CLK, don't touch others */ + wlf,gpio-cfg = <0x0018>, <0xffff>, <0xffff>, <0xffff>; + }; +}; + +&lpspi8 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpspi8>; + cs-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; + status = "okay"; + + /* Resistive touch controller */ + ads7846: touchscreen@0 { + compatible = "ti,ads7846"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_restouch>; + interrupt-parent = <&gpio4>; + interrupts = <29 IRQ_TYPE_EDGE_FALLING>; + spi-max-frequency = <1000000>; + pendown-gpio = <&gpio4 29 0>; + vcc-supply = <&buck5>; + ti,x-min = /bits/ 16 <125>; + ti,x-max = /bits/ 16 <4008>; + ti,y-min = /bits/ 16 <282>; + ti,y-max = /bits/ 16 <3864>; + ti,x-plate-ohms = /bits/ 16 <180>; + ti,pressure-max = /bits/ 16 <255>; + ti,debounce-max = /bits/ 16 <10>; + ti,debounce-tol = /bits/ 16 <3>; + ti,debounce-rep = /bits/ 16 <1>; + ti,settle-delay-usec = /bits/ 16 <150>; + ti,keep-vref-on; + wakeup-source; + }; +}; + +/* BT module */ +&lpuart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpuart5>, <&pinctrl_bluetooth>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "nxp,88w8987-bt"; + }; +}; + +&sai1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_sai1>; + pinctrl-1 = <&pinctrl_sai1_sleep>; + assigned-clocks = <&clk IMX93_CLK_SAI1>; + assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; + assigned-clock-rates = <12288000>; + fsl,sai-mclk-direction-output; + status = "okay"; +}; + /* eMMC */ &usdhc1 { pinctrl-names = "default", "state_100mhz", "state_200mhz"; @@ -81,7 +278,27 @@ status = "okay"; }; +/* WiFi */ +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_usdhc3_wlan>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>, <&pinctrl_usdhc3_wlan>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>, <&pinctrl_usdhc3_wlan>; + pinctrl-3 = <&pinctrl_usdhc3_sleep>, <&pinctrl_usdhc3_wlan>; + bus-width = <4>; + mmc-pwrseq = <&usdhc3_pwrseq>; + non-removable; + wakeup-source; + status = "okay"; +}; + &iomuxc { + pinctrl_bluetooth: bluetoothgrp { + fsl,pins = < + MX93_PAD_ENET2_MDIO__GPIO4_IO15 0x51e + >; + }; + pinctrl_eqos: eqosgrp { fsl,pins = < MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x57e @@ -108,6 +325,68 @@ >; }; + pinctrl_lpi2c3: lpi2c3grp { + fsl,pins = < + MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e + MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e + >; + }; + + pinctrl_lpi2c3_gpio: lpi2c3-gpiogrp { + fsl,pins = < + MX93_PAD_GPIO_IO28__GPIO2_IO28 0x40000b9e + MX93_PAD_GPIO_IO29__GPIO2_IO29 0x40000b9e + >; + }; + + pinctrl_lpspi8: lpspi8grp { + fsl,pins = < + MX93_PAD_GPIO_IO12__GPIO2_IO12 0x31e + MX93_PAD_GPIO_IO13__LPSPI8_SIN 0x31e + MX93_PAD_GPIO_IO14__LPSPI8_SOUT 0x31e + MX93_PAD_GPIO_IO15__LPSPI8_SCK 0x31e + >; + }; + + pinctrl_lpuart5: lpuart5grp { + fsl,pins = < + MX93_PAD_DAP_TDO_TRACESWO__LPUART5_TX 0x31e + MX93_PAD_DAP_TDI__LPUART5_RX 0x31e + MX93_PAD_DAP_TMS_SWDIO__LPUART5_RTS_B 0x31e + MX93_PAD_DAP_TCLK_SWCLK__LPUART5_CTS_B 0x31e + >; + }; + + pinctrl_restouch: restouchgrp { + fsl,pins = < + MX93_PAD_CCM_CLKO4__GPIO4_IO29 0x31e + >; + }; + + pinctrl_sai1: sai1grp { + fsl,pins = < + MX93_PAD_SAI1_TXC__SAI1_TX_BCLK 0x31e + MX93_PAD_SAI1_TXFS__SAI1_TX_SYNC 0x31e + MX93_PAD_SAI1_TXD0__SAI1_TX_DATA00 0x31e + MX93_PAD_SAI1_RXD0__SAI1_RX_DATA00 0x31e + MX93_PAD_I2C2_SDA__SAI1_RX_BCLK 0x31e + MX93_PAD_I2C2_SCL__SAI1_RX_SYNC 0x31e + MX93_PAD_UART2_RXD__SAI1_MCLK 0x31e + >; + }; + + pinctrl_sai1_sleep: sai1-sleepgrp { + fsl,pins = < + MX93_PAD_SAI1_TXC__GPIO1_IO12 0x31e + MX93_PAD_SAI1_TXFS__GPIO1_IO11 0x31e + MX93_PAD_SAI1_TXD0__GPIO1_IO13 0x31e + MX93_PAD_SAI1_RXD0__GPIO1_IO14 0x31e + MX93_PAD_UART2_RXD__GPIO1_IO06 0x31e + MX93_PAD_I2C2_SDA__GPIO1_IO03 0x31e + MX93_PAD_I2C2_SCL__GPIO1_IO02 0x31e + >; + }; + pinctrl_usdhc1: usdhc1grp { fsl,pins = < MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe @@ -123,4 +402,55 @@ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe >; }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX93_PAD_SD3_CLK__USDHC3_CLK 0x1582 /* SDIO_B_CLK */ + MX93_PAD_SD3_CMD__USDHC3_CMD 0x40001382 /* SDIO_B_CMD */ + MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x40001382 /* SDIO_B_D0 */ + MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x40001382 /* SDIO_B_D1 */ + MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x40001382 /* SDIO_B_D2 */ + MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x40001382 /* SDIO_B_D3 */ + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { + fsl,pins = < + MX93_PAD_SD3_CLK__USDHC3_CLK 0x158e /* SDIO_B_CLK */ + MX93_PAD_SD3_CMD__USDHC3_CMD 0x4000138e /* SDIO_B_CMD */ + MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x4000138e /* SDIO_B_D0 */ + MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x4000138e /* SDIO_B_D1 */ + MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x4000138e /* SDIO_B_D2 */ + MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x4000138e /* SDIO_B_D3 */ + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { + fsl,pins = < + MX93_PAD_SD3_CLK__USDHC3_CLK 0x15fe /* SDIO_B_CLK */ + MX93_PAD_SD3_CMD__USDHC3_CMD 0x400013fe /* SDIO_B_CMD */ + MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x400013fe /* SDIO_B_D0 */ + MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x400013fe /* SDIO_B_D1 */ + MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x400013fe /* SDIO_B_D2 */ + MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x400013fe /* SDIO_B_D3 */ + >; + }; + + pinctrl_usdhc3_sleep: usdhc3-sleepgrp { + fsl,pins = < + MX93_PAD_SD3_CLK__GPIO3_IO20 0x400 + MX93_PAD_SD3_CMD__GPIO3_IO21 0x400 + MX93_PAD_SD3_DATA0__GPIO3_IO22 0x400 + MX93_PAD_SD3_DATA1__GPIO3_IO23 0x400 + MX93_PAD_SD3_DATA2__GPIO3_IO24 0x400 + MX93_PAD_SD3_DATA3__GPIO3_IO25 0x400 + >; + }; + + pinctrl_usdhc3_wlan: usdhc3-wlangrp { + fsl,pins = < + MX93_PAD_ENET2_MDC__GPIO4_IO14 0x51e /* WIFI_REG_ON */ + MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x51e /* WIFI_PWR_EN */ + >; + }; }; diff --git a/arch/arm64/boot/dts/freescale/imx94.dtsi b/arch/arm64/boot/dts/freescale/imx94.dtsi index d4a880496b0ee..73184f03f8a3e 100644 --- a/arch/arm64/boot/dts/freescale/imx94.dtsi +++ b/arch/arm64/boot/dts/freescale/imx94.dtsi @@ -1190,5 +1190,11 @@ status = "disabled"; }; }; + + ddr-pmu@4e090dc0 { + compatible = "fsl,imx94-ddr-pmu", "fsl,imx93-ddr-pmu"; + reg = <0x0 0x4e090dc0 0x0 0x200>; + interrupts = ; + }; }; }; diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts index 148243470dd4a..c1e245ecea9c1 100644 --- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts @@ -61,6 +61,7 @@ fan0: pwm-fan { compatible = "pwm-fan"; + fan-supply = <®_vcc_12v>; #cooling-cells = <2>; cooling-levels = <64 128 192 255>; pwms = <&tpm6 0 4000000 PWM_POLARITY_INVERTED>; @@ -556,6 +557,8 @@ pinctrl-names = "default"; reset-gpio = <&gpio5 13 GPIO_ACTIVE_LOW>; vpcie-supply = <®_m2_pwr>; + vpcie3v3aux-supply = <®_m2_pwr>; + supports-clkreq; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts index 9f968feccef67..aaa0da55a22bc 100644 --- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts @@ -542,6 +542,8 @@ pinctrl-names = "default"; reset-gpio = <&i2c7_pcal6524 5 GPIO_ACTIVE_LOW>; vpcie-supply = <®_pcie0>; + vpcie3v3aux-supply = <®_pcie0>; + supports-clkreq; status = "okay"; }; @@ -557,6 +559,7 @@ pinctrl-names = "default"; reset-gpio = <&i2c7_pcal6524 16 GPIO_ACTIVE_LOW>; vpcie-supply = <®_slot_pwr>; + vpcie3v3aux-supply = <®_slot_pwr>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-verdin-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-verdin-evk.dts new file mode 100644 index 0000000000000..2b0ff232f680d --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-verdin-evk.dts @@ -0,0 +1,695 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023 NXP + * Copyright 2025 Marek Vasut + */ + +/dts-v1/; + +#include +#include "imx95.dtsi" + +#define FALLING_EDGE 1 +#define RISING_EDGE 2 + +#define BRD_SM_CTRL_SD3_WAKE 0x8000 /* PCAL6408A-0 */ +#define BRD_SM_CTRL_PCIE1_WAKE 0x8001 /* PCAL6408A-4 */ +#define BRD_SM_CTRL_BT_WAKE 0x8002 /* PCAL6408A-5 */ +#define BRD_SM_CTRL_PCIE2_WAKE 0x8003 /* PCAL6408A-6 */ +#define BRD_SM_CTRL_BUTTON 0x8004 /* PCAL6408A-7 */ + +/ { + model = "i.MX 95 Verdin Evaluation Kit (EVK)"; + compatible = "toradex,verdin-imx95-19x19-evk", "fsl,imx95"; + + aliases { + ethernet0 = &enetc_port0; + ethernet1 = &enetc_port1; + ethernet2 = &enetc_port2; + gpio0 = &gpio1; + gpio1 = &gpio2; + gpio2 = &gpio3; + gpio3 = &gpio4; + gpio4 = &gpio5; + i2c0 = &lpi2c1; + i2c1 = &lpi2c2; + i2c2 = &lpi2c3; + i2c3 = &lpi2c4; + i2c4 = &lpi2c5; + i2c5 = &lpi2c6; + i2c6 = &lpi2c7; + i2c7 = &lpi2c8; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + serial0 = &lpuart1; + }; + + chosen { + stdout-path = &lpuart1; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0 0x80000000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + linux_cma: linux,cma { + compatible = "shared-dma-pool"; + alloc-ranges = <0 0x80000000 0 0x7f000000>; + size = <0 0x3c000000>; + linux,cma-default; + reusable; + }; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V1.8_SW"; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "+V3.3_SW"; + }; + + reg_m2_pwr: regulator-m2-pwr { + compatible = "regulator-fixed"; + regulator-name = "M.2-power"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 4 GPIO_ACTIVE_LOW>; + }; + + reg_pcie0: regulator-pcie { + compatible = "regulator-fixed"; + regulator-name = "PCIE_WLAN_EN"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <®_m2_pwr>; + gpio = <&i2c7_pcal6524 18 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usdhc2_vmmc: regulator-usdhc2 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; + regulator-name = "VDD_SD2_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + off-on-delay-us = <12000>; + }; + + usdhc3_pwrseq: usdhc3-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&i2c7_pcal6524 11 GPIO_ACTIVE_HIGH>; + }; + + sound-wm8904 { + compatible = "fsl,imx-audio-wm8904"; + model = "wm8904-audio"; + audio-cpu = <&sai3>; + audio-codec = <&wm8904>; + audio-routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "AMIC", "MICBIAS", + "IN2L", "AMIC"; + }; +}; + +&enetc_port0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enetc0>; + phy-handle = <ðphy0>; + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&flexspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexspi1>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexspi1_reset>; + reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <200000000>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + }; +}; + +&lpi2c4 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpi2c4>; + status = "okay"; + + wm8904: codec@1a { + #sound-dai-cells = <0>; + compatible = "wlf,wm8904"; + reg = <0x1a>; + clocks = <&scmi_clk IMX95_CLK_SAI3>; + clock-names = "mclk"; + AVDD-supply = <®_1p8v>; + CPVDD-supply = <®_1p8v>; + DBVDD-supply = <®_1p8v>; + DCVDD-supply = <®_1p8v>; + MICVDD-supply = <®_1p8v>; + }; +}; + +&lpi2c5 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpi2c5>; + status = "okay"; +}; + +&lpi2c6 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpi2c6>; + status = "okay"; +}; + +&lpi2c7 { + clock-frequency = <1000000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpi2c7>; + status = "okay"; + + i2c7_pcal6524: i2c7-gpio@23 { + compatible = "nxp,pcal6524"; + reg = <0x23>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c7_pcal6524>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&gpio5>; + interrupts = <16 IRQ_TYPE_LEVEL_LOW>; + }; + + /* Current measurement at SoM 5V power output */ + hwmon@41 { + compatible = "ti,ina219"; + reg = <0x41>; + shunt-resistor = <10000>; + }; + + /* Current measurement at Board power input */ + hwmon@45 { + compatible = "ti,ina219"; + reg = <0x45>; + shunt-resistor = <10000>; + }; + + eeprom@50 { + compatible = "st,24c02"; + reg = <0x50>; + }; + + ptn5110: tcpc@52 { + compatible = "nxp,ptn5110", "tcpci"; + reg = <0x52>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_typec>; + interrupt-parent = <&gpio5>; + interrupts = <14 IRQ_TYPE_LEVEL_LOW>; + + typec_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + power-role = "dual"; + data-role = "dual"; + try-power-role = "sink"; + source-pdos = ; + sink-pdos = ; + op-sink-microwatt = <15000000>; + self-powered; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + typec_con_hs: endpoint { + remote-endpoint = <&usb3_data_hs>; + }; + }; + + port@1 { + reg = <1>; + + typec_con_ss: endpoint { + remote-endpoint = <&usb3_data_ss>; + }; + }; + }; + }; + }; +}; + +&lpuart1 { + /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&mu7 { + status = "okay"; +}; + +&netcmix_blk_ctrl { + status = "okay"; +}; + +&netc_blk_ctrl { + status = "okay"; +}; + +&netc_emdio { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_emdio>; + status = "okay"; + + ethphy0: ethernet-phy@1 { + reg = <1>; + realtek,clkout-disable; + }; +}; + +&pcie0 { + pinctrl-0 = <&pinctrl_pcie0>; + pinctrl-names = "default"; + reset-gpio = <&i2c7_pcal6524 17 GPIO_ACTIVE_LOW>; + vpcie-supply = <®_pcie0>; + status = "okay"; +}; + +&pcie1 { + pinctrl-0 = <&pinctrl_pcie1>; + pinctrl-names = "default"; + reset-gpio = <&i2c7_pcal6524 16 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&sai1 { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai1>; + assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>, + <&scmi_clk IMX95_CLK_AUDIOPLL2>, + <&scmi_clk IMX95_CLK_SAI1>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, + <3612672000>, <393216000>, + <361267200>, <12288000>; + fsl,sai-mclk-direction-output; + status = "okay"; +}; + +&sai3 { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai3>; + assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>, + <&scmi_clk IMX95_CLK_AUDIOPLL2>, + <&scmi_clk IMX95_CLK_SAI3>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, + <3612672000>, <393216000>, + <361267200>, <12288000>; + fsl,sai-mclk-direction-output; + status = "okay"; +}; + +&usb3 { + status = "okay"; +}; + +&usb3_dwc3 { + dr_mode = "otg"; + hnp-disable; + srp-disable; + adp-disable; + usb-role-switch; + role-switch-default-mode = "peripheral"; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + status = "okay"; + + port { + usb3_data_hs: endpoint { + remote-endpoint = <&typec_con_hs>; + }; + }; +}; + +&usb3_phy { + fsl,phy-tx-preemp-amp-tune-microamp = <600>; + orientation-switch; + status = "okay"; + + port { + usb3_data_ss: endpoint { + remote-endpoint = <&typec_con_ss>; + }; + }; +}; + +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + pinctrl-3 = <&pinctrl_usdhc1>; + bus-width = <8>; + non-removable; + no-sdio; + no-sd; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-3 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + vmmc-supply = <®_usdhc2_vmmc>; + bus-width = <4>; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + mmc-pwrseq = <&usdhc3_pwrseq>; + vmmc-supply = <®_pcie0>; + bus-width = <4>; + keep-power-in-suspend; + non-removable; + status = "okay"; +}; + +&scmi_misc { + nxp,ctrl-ids = ; +}; + +&wdog3 { + fsl,ext-reset-output; + status = "okay"; +}; + +&scmi_iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_hog: hoggrp { + fsl,pins = + ; + }; + + pinctrl_emdio: emdiogrp { + fsl,pins = + , + ; + }; + + pinctrl_enetc0: enetc0grp { + fsl,pins = + , + , + , + , + , + , + , + , + , + , + , + ; + }; + + pinctrl_flexspi1: flexspi1grp { + fsl,pins = + , + , + , + , + , + , + , + , + , + , + ; + }; + + pinctrl_flexspi1_reset: flexspi1-reset-grp { + fsl,pins = + ; + }; + + pinctrl_hp: hpgrp { + fsl,pins = + ; + }; + + pinctrl_i2c4_pcal6408: i2c4pcal6498grp { + fsl,pins = + ; + }; + + pinctrl_i2c7_pcal6524: i2c7pcal6524grp { + fsl,pins = + ; + }; + + pinctrl_lpi2c4: lpi2c4grp { + fsl,pins = + , + ; + }; + + pinctrl_lpi2c5: lpi2c5grp { + fsl,pins = + , + ; + }; + + pinctrl_lpi2c6: lpi2c6grp { + fsl,pins = + , + ; + }; + + pinctrl_lpi2c7: lpi2c7grp { + fsl,pins = + , + ; + }; + + pinctrl_pcal6416: pcal6416grp { + fsl,pins = + ; + }; + + pinctrl_pcie0: pcie0grp { + fsl,pins = + ; + }; + + pinctrl_pcie1: pcie1grp { + fsl,pins = + ; + }; + + pinctrl_pdm: pdmgrp { + fsl,pins = + , + ; + }; + + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { + fsl,pins = + ; + }; + + pinctrl_sai1: sai1grp { + fsl,pins = + , + , + , + ; + }; + + pinctrl_sai2: sai2grp { + fsl,pins = + , + , + , + , + , + , + , + , + , + , + ; + }; + + pinctrl_sai3: sai3grp { + fsl,pins = + , + , + , + , + ; + }; + + pinctrl_tpm6: tpm6grp { + fsl,pins = + ; + }; + + pinctrl_typec: typecgrp { + fsl,pins = + ; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = + , + ; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = + , + , + , + , + , + , + , + , + , + , + ; + }; + + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { + fsl,pins = + , + , + , + , + , + , + , + , + , + , + ; + }; + + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + fsl,pins = + , + , + , + , + , + , + , + , + , + , + ; + }; + + pinctrl_usdhc2_gpio: usdhc2gpiogrp { + fsl,pins = + ; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = + , + , + , + , + , + , + ; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = + , + , + , + , + , + , + ; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = + , + , + , + , + , + , + ; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = + , + , + , + , + , + ; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts new file mode 100644 index 0000000000000..5b05f256fd52e --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 Toradex + * + * https://www.toradex.com/computer-on-modules/smarc-arm-family/nxp-imx95 + * https://www.toradex.com/products/carrier-board/smarc-development-board-kit + */ + +/dts-v1/; + +#include +#include "imx95-toradex-smarc.dtsi" + +/ { + model = "Toradex SMARC iMX95 on Toradex SMARC Development Board"; + compatible = "toradex,smarc-imx95-dev", + "toradex,smarc-imx95", + "fsl,imx95"; + + reg_carrier_1p8v: regulator-carrier-1p8v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "On-carrier 1V8"; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&codec_dai>; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&codec_dai>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "tdx-smarc-wm8904"; + simple-audio-card,routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "Microphone Jack", "MICBIAS", + "IN1L", "Microphone Jack"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack", + "Line", "Line In Jack"; + + codec_dai: simple-audio-card,codec { + clocks = <&scmi_clk IMX95_CLK_SAI3>; + sound-dai = <&wm8904_1a>; + }; + + simple-audio-card,cpu { + sound-dai = <&sai3>; + }; + }; +}; + +/* SMARC GBE0 */ +&enetc_port0 { + status = "okay"; +}; + +/* SMARC GBE1 */ +&enetc_port1 { + status = "okay"; +}; + +/* SMARC CAN0 */ +&flexcan1 { + status = "okay"; +}; + +/* SMARC CAN1 */ +&flexcan2 { + status = "okay"; +}; + +&gpio2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio12>, <&pinctrl_gpio13>; +}; + +&gpio4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio10>, <&pinctrl_gpio11>; +}; + +&gpio5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio2>, + <&pinctrl_gpio3>, + <&pinctrl_gpio4>, + <&pinctrl_gpio6>, + <&pinctrl_gpio8>, + <&pinctrl_gpio9>; +}; + +/* SMARC I2C_CAM0 */ +&i2c_cam0 { + status = "okay"; +}; + +/* SMARC I2C_CAM1 */ +&i2c_cam1 { + status = "okay"; +}; + +/* SMARC I2C_GP */ +&lpi2c2 { + status = "okay"; + + wm8904_1a: audio-codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai3>, <&pinctrl_sai3_mclk>; + #sound-dai-cells = <0>; + clocks = <&scmi_clk IMX95_CLK_SAI3>; + clock-names = "mclk"; + AVDD-supply = <®_carrier_1p8v>; + CPVDD-supply = <®_carrier_1p8v>; + DBVDD-supply = <®_carrier_1p8v>; + DCVDD-supply = <®_carrier_1p8v>; + MICVDD-supply = <®_carrier_1p8v>; + }; + + temperature-sensor@4f { + compatible = "ti,tmp1075"; + reg = <0x4f>; + }; + + eeprom@57 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + }; + +}; + +/* SMARC I2C_PM */ +&lpi2c3 { + clock-frequency = <100000>; + status = "okay"; + + fan_controller: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + #pwm-cells = <2>; + + fan { + cooling-levels = <255>; + pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED>; + }; + }; + + /* Current measurement into module VCC */ + hwmon@40 { + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <5000>; + }; +}; + +/* SMARC I2C_LCD */ +&lpi2c5 { + status = "okay"; + + i2c-mux@70 { + compatible = "nxp,pca9543"; + reg = <0x70>; + i2c-mux-idle-disconnect; + #address-cells = <1>; + #size-cells = <0>; + + /* I2C on DSI Connector Pins 4/6 */ + i2c_dsi_0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* I2C on DSI Connector Pins 52/54 */ + i2c_dsi_1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +/* SMARC SPI0 */ +&lpspi6 { + status = "okay"; +}; + +/* SMARC SER1, used as the Linux Console */ +&lpuart1 { + status = "okay"; +}; + +/* SMARC SER0, RS485 */ +&lpuart2 { + linux,rs485-enabled-at-boot-time; + rs485-rts-active-low; + rs485-rx-during-tx; + status = "okay"; +}; + +/* SMARC SER3, RS232 */ +&lpuart3 { + status = "okay"; +}; + +/* SMARC MDIO, shared between all ethernet ports */ +&netc_emdio { + status = "okay"; + + ethphy3: ethernet-phy@4 { + reg = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio7>; + interrupt-parent = <&gpio5>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +/* SMARC PCIE_A / M2 Key B */ +&pcie0 { + status = "okay"; +}; + +/* SMARC PCIE_B / M2 Key E */ +&pcie1 { + status = "okay"; +}; + +/* SMARC I2S0 */ +&sai3 { + status = "okay"; +}; + +/* SMARC LCD0_BKLT_PWM */ +&tpm3 { + status = "okay"; +}; + +/* SMARC LCD1_BKLT_PWM */ +&tpm4 { + status = "okay"; +}; + +/* SMARC GPIO5 as PWM */ +&tpm5 { + status = "okay"; +}; + +/* SMARC USB0 */ +&usb2 { + status = "okay"; +}; + +/* SMARC USB1..4 */ +&usb3 { + status = "okay"; +}; + +&usb3_dwc3 { + status = "okay"; +}; + +&usb3_phy { + status = "okay"; +}; + +/* SMARC SDIO */ +&usdhc2 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi new file mode 100644 index 0000000000000..afbdadcb36863 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi @@ -0,0 +1,1155 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 Toradex + * + * https://www.toradex.com/computer-on-modules/smarc-arm-family/nxp-imx95 + */ + +#include +#include +#include "imx95.dtsi" + +/ { + aliases { + can0 = &flexcan1; + can1 = &flexcan2; + ethernet0 = &enetc_port0; + ethernet1 = &enetc_port1; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + mmc2 = &usdhc3; + rtc0 = &rtc_i2c; + rtc1 = &scmi_bbm; + serial0 = &lpuart2; + serial1 = &lpuart1; + serial3 = &lpuart3; + }; + + chosen { + stdout-path = "serial1:115200n8"; + }; + + clk_dsi2dp_bridge: clock-dsi2dp-bridge { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + + clk_serdes_eth_ref: clock-eth-ref { + compatible = "gpio-gate-clock"; + #clock-cells = <0>; + /* CTRL_ETH_REF_CLK_STBY# */ + enable-gpios = <&som_gpio_expander_1 13 GPIO_ACTIVE_HIGH>; + }; + + connector { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + /* SMARC P64 - USB0_OTG_ID */ + id-gpios = <&som_gpio_expander_0 3 GPIO_ACTIVE_HIGH>; + label = "USB0"; + self-powered; + type = "micro"; + vbus-supply = <®_usb0_vbus>; + + port { + usb_dr_connector: endpoint { + remote-endpoint = <&usb0_otg_id>; + }; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + smarc_key_sleep: key-sleep { + gpios = <&som_ec_gpio_expander 4 GPIO_ACTIVE_LOW>; + label = "SMARC_SLEEP#"; + wakeup-source; + linux,code = ; + }; + + smarc_switch_lid: switch-lid { + gpios = <&som_ec_gpio_expander 2 GPIO_ACTIVE_LOW>; + label = "SMARC_LID#"; + linux,code = ; + linux,input-type = ; + }; + }; + + reg_module_1p8v: regulator-module-1p8v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "On-module +V1.8"; + }; + + /* Non PMIC On-module Supplies */ + reg_module_dp_1p2v: regulator-module-dp-1p2v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1200000>; + regulator-min-microvolt = <1200000>; + regulator-name = "On-module +V1.2_DP"; + vin-supply = <®_module_1p8v>; + }; + + reg_usb0_vbus: regulator-usb0-vbus { + compatible = "regulator-fixed"; + /* SMARC P62 - USB0_EN_OC# */ + gpios = <&som_gpio_expander_0 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-name = "USB0_EN_OC#"; + }; + + reg_usb1_vbus: regulator-usb1-vbus { + compatible = "regulator-fixed"; + /* CTRL_V_BUS_USB_HUB or SMARC P71 - USB2_EN_OC# */ + gpios = <&som_gpio_expander_0 6 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-name = "CTRL_V_BUS_USB_HUB"; + }; + + reg_usdhc2_vmmc: regulator-vmmc-usdhc2 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2_pwr_en>; + gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + off-on-delay-us = <100000>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "SDIO_PWR_EN"; + startup-delay-us = <20000>; + }; + + reg_usdhc2_vqmmc: regulator-usdhc2-vqmmc { + compatible = "regulator-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2_vsel>; + gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + states = <1800000 0x1>, + <3300000 0x0>; + regulator-name = "PMIC_SD2_VSEL"; + }; + + reg_wifi_en: regulator-wifi-en { + compatible = "regulator-fixed"; + /* CTRL_EN_WIFI */ + gpios = <&som_gpio_expander_1 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "CTRL_EN_WIFI"; + startup-delay-us = <2000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + linux_cma: linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0 0x3c000000>; + alloc-ranges = <0 0x80000000 0 0x7F000000>; + linux,cma-default; + }; + }; +}; + +/* SMARC GBE0 */ +&enetc_port0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enetc0>, <&pinctrl_enetc0_1588_tmr>; + phy-handle = <ðphy1>; + phy-mode = "rgmii-id"; +}; + +/* SMARC GBE1 */ +&enetc_port1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enetc1>, <&pinctrl_enetc1_1588_tmr>; + phy-handle = <ðphy2>; + phy-mode = "rgmii-id"; +}; + +/* SMARC CAN0 */ +&flexcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; +}; + +/* SMARC CAN1 */ +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; +}; + +&gpio1 { + gpio-line-names = "", /* 0 */ + "", + "SMARC_I2C_GP_CK", + "SMARC_I2C_GP_DAT", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "", + "", + "CTRL_IO_EXP_INT_B"; + status = "okay"; +}; + +&gpio2 { + gpio-line-names = "SMARC_SPI0_CS0#", /* 0 */ + "", + "", + "", + "", + "", + "SMARC_GPIO5", + "", + "I2C_CAM_DAT", + "I2C_CAM_CK", + "SMARC_GPIO12", /* 10 */ + "SMARC_GPIO13", + "", + "", + "", + "", + "", + "", + "SMARC_SPI1_CS0#", + "", + "", /* 20 */ + "", + "SMARC_I2C_LCD_DAT", + "SMARC_I2C_LCD_CK", + "SMARC_SPI0_CS1#", + "", + "", + "", + "SMARC_I2C_PM_DAT", + "SMARC_I2C_PM_CK", + "I2C_SOM_DAT", /* 30 */ + "I2C_SOM_CK"; + status = "okay"; +}; + +&gpio3 { + gpio-line-names = "SMARC_SDIO_CD#", /* 0 */ + "", + "", + "", + "", + "", + "", + "SMARC_SDIO_PWR_EN", + "", + "", + "", /* 10 */ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "PMIC_SD2_VSEL"; + status = "okay"; +}; + +&gpio4 { + gpio-line-names = "", /* 0 */ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "", + "", + "SMARC_GPIO11", + "SMARC_GPIO10", + "", + "", + "", + "", + "", /* 20 */ + "", + "", + "", + "", + "", + "", + "", + "SMARC_SMB_ALERT#"; + status = "okay"; +}; + +&gpio5 { + gpio-line-names = "SMARC_GPIO2", /* 0 */ + "SMARC_GPIO3", + "SMARC_GPIO4", + "SMARC_GPIO6", + "", + "", + "", + "", + "SMARC_GPIO9", + "SMARC_GPIO7", + "SMARC_GPIO8", /* 10 */ + "SMARC_SPI1_CS1#", + "", + "SPI1_TPM_CS#"; + status = "okay"; +}; + +/* SMARC I2C_GP */ +&lpi2c2 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c2>; + pinctrl-1 = <&pinctrl_lpi2c2_gpio>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + scl-gpios = <&gpio1 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "okay"; + + eeprom@50 { + compatible = "st,24c32", "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + }; +}; + +/* SMARC I2C_PM */ +&lpi2c3 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c3>; + pinctrl-1 = <&pinctrl_lpi2c3_gpio>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + scl-gpios = <&gpio2 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +}; + +/* I2C_SOM */ +&lpi2c4 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c4>, <&pinctrl_ctrl_io_exp_int_b>; + pinctrl-1 = <&pinctrl_lpi2c4_gpio>, <&pinctrl_ctrl_io_exp_int_b>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + scl-gpios = <&gpio2 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "okay"; + + som_gpio_expander_0: gpio@20 { + compatible = "nxp,pcal6408"; + reg = <0x20>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio1>; + interrupts = <14 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "SMARC_PCIE_WAKE#", /* 0 */ + "SMARC_PCIE_B_RST#", + "SMARC_PCIE_A_RST#", + "SMARC_USB0_OTG_ID", + "SMARC_USB0_EN", /* SMARC USB0_EN_OC# - Open Drain Output */ + "SMARC_USB0_OC#", /* SMARC USB0_EN_OC# - Over-Current Sense Input */ + "", + "SMARC_PCIE_C_RST#"; + }; + + som_gpio_expander_1: gpio@21 { + compatible = "nxp,pcal6416"; + reg = <0x21>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio1>; + interrupts = <14 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "SMARC_GPIO0", /* 0 */ + "SMARC_GPIO1", + "SMARC_LCD0_VDD_EN", + "SMARC_LCD0_BKLT_EN", + "SMARC_LCD1_VDD_EN", + "SMARC_LCD1_BKLT_EN", + "", + "", + "", + "", + "", /* 10 */ + "", + "", + "", + "", + "", + "", + "SMARC_SDIO_WP"; + }; + + embedded-controller@28 { + compatible = "toradex,smarc-imx95-ec", "toradex,smarc-ec"; + reg = <0x28>; + }; + + som_ec_gpio_expander: gpio@29 { + compatible = "toradex,ecgpiol16", "nxp,pcal6416"; + reg = <0x29>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ec_int>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio1>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "SMARC_CHARGER_PRSNT#", + "SMARC_CHARGING#", + "SMARC_LID#", + "SMARC_BATLOW#", + "SMARC_SLEEP#"; + }; + + /* SMARC DP0 */ + som_dsi2dp_bridge: bridge@2c { + compatible = "ti,sn65dsi86"; + reg = <0x2c>; + clocks = <&clk_dsi2dp_bridge>; + clock-names = "refclk"; + vcc-supply = <®_module_dp_1p2v>; + vcca-supply = <®_module_dp_1p2v>; + vccio-supply = <®_module_1p8v>; + vpll-supply = <®_module_1p8v>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + sn65dsi86_in: endpoint { + }; + }; + + port@1 { + reg = <1>; + + sn65dsi86_out: endpoint { + data-lanes = <3 2 1 0>; + }; + }; + }; + }; + + rtc_i2c: rtc@32 { + compatible = "epson,rx8130"; + reg = <0x32>; + }; + + temperature-sensor@48 { + compatible = "ti,tmp1075"; + reg = <0x48>; + }; + + eeprom@50 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +/* SMARC I2C_LCD */ +&lpi2c5 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c5>; + pinctrl-1 = <&pinctrl_lpi2c5_gpio>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + scl-gpios = <&gpio2 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 22 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +}; + +/* I2C_CAM */ +&lpi2c7 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c7>; + pinctrl-1 = <&pinctrl_lpi2c7_gpio>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + scl-gpios = <&gpio2 9 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "okay"; + + i2c-mux@70 { + compatible = "nxp,pca9543"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + /* SMARC I2C_CAM0 */ + i2c_cam0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* SMARC I2C_CAM1 */ + i2c_cam1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +/* SMARC SPI1 */ +&lpspi4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpspi4>; + cs-gpios = <&gpio2 18 GPIO_ACTIVE_LOW>, + <&gpio5 11 GPIO_ACTIVE_LOW>, + <&gpio5 13 GPIO_ACTIVE_LOW>; + status = "okay"; + + som_tpm: tpm@2 { + compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; + reg = <0x2>; + spi-max-frequency = <18500000>; + }; +}; + +/* SMARC SPI0 */ +&lpspi6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpspi6>; + cs-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>, + <&gpio2 24 GPIO_ACTIVE_LOW>; +}; + +/* SMARC SER1, used as the Linux Console */ +&lpuart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; +}; + +/* SMARC SER0 */ +&lpuart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + uart-has-rtscts; +}; + +/* SMARC SER3 */ +&lpuart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; +}; + +/* SMARC MDIO, shared between all ethernet ports */ +&netc_emdio { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_emdio>; + + ethphy1: ethernet-phy@1 { + reg = <1>; + interrupt-parent = <&som_gpio_expander_1>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + }; + + ethphy2: ethernet-phy@2 { + reg = <2>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + }; +}; + +&netcmix_blk_ctrl { + status = "okay"; +}; + +&netc_blk_ctrl { + status = "okay"; +}; + +&netc_timer { + status = "okay"; +}; + +/* SMARC PCIE_A */ +&pcie0 { + pinctrl-0 = <&pinctrl_pcie0>; + pinctrl-names = "default"; + reset-gpios = <&som_gpio_expander_0 2 GPIO_ACTIVE_LOW>; +}; + +/* SMARC PCIE_B */ +&pcie1 { + pinctrl-0 = <&pinctrl_pcie1>; + pinctrl-names = "default"; + reset-gpios = <&som_gpio_expander_0 1 GPIO_ACTIVE_LOW>; +}; + +/* SMARC I2S0 */ +&sai3 { + #sound-dai-cells = <0>; + assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>, + <&scmi_clk IMX95_CLK_AUDIOPLL2>, + <&scmi_clk IMX95_CLK_SAI3>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, + <3612672000>, <393216000>, + <361267200>, <12288000>; + fsl,sai-mclk-direction-output; +}; + +&thermal_zones { + /* PF09 Main PMIC */ + pf09-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 2>; + + trips { + trip0 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; + + /* PF53 VDD_ARM PMIC */ + pf53-arm-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 4>; + + trips { + trip0 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; + + /* PF53 VDD_SOC PMIC */ + pf53-soc-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 3>; + + trips { + trip0 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; +}; + +/* SMARC LCD0_BKLT_PWM */ +&tpm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd0_bklt_pwm>; +}; + +/* SMARC LCD1_BKLT_PWM */ +&tpm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd1_bklt_pwm>; +}; + +/* SMARC GPIO5 as PWM */ +&tpm5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio5_pwm>; +}; + +/* SMARC USB0 */ +&usb2 { + adp-disable; + dr_mode = "otg"; + hnp-disable; + srp-disable; + usb-role-switch; + vbus-supply = <®_usb0_vbus>; + + port { + usb0_otg_id: endpoint { + remote-endpoint = <&usb_dr_connector>; + }; + }; +}; + +&usb3 { + fsl,disable-port-power-control; +}; + +/* SMARC USB1..4 */ +&usb3_dwc3 { + dr_mode = "host"; +}; + +&usb3_phy { + vbus-supply = <®_usb1_vbus>; +}; + +/* On-module eMMC */ +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + bus-width = <8>; + non-removable; + no-sdio; + no-sd; + status = "okay"; +}; + +/* SMARC SDIO */ +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_cd>; + pinctrl-1 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_cd>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>,<&pinctrl_usdhc2_cd>; + pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_cd>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + vmmc-supply = <®_usdhc2_vmmc>; + vqmmc-supply = <®_usdhc2_vqmmc>; + wp-gpios = <&som_gpio_expander_1 15 GPIO_ACTIVE_HIGH>; +}; + +/* On-module Wi-Fi */ +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + keep-power-in-suspend; + non-removable; + vmmc-supply = <®_wifi_en>; +}; + +&scmi_bbm { + linux,code = ; +}; + +&wdog3 { + fsl,ext-reset-output; + status = "okay"; +}; + +&scmi_iomuxc { + /* SMARC CAM_MCK */ + pinctrl_cam_mck: cammckgrp { + fsl,pins = ; /* SMARC S6 - CAM_MCK */ + }; + + pinctrl_ec_int: ecintgrp { + fsl,pins = ; /* SAI1_TXFS - EC_MCU_INT# */ + }; + + /* SMARC MDIO, shared between all ethernet ports */ + pinctrl_emdio: emdiogrp { + fsl,pins = , /* SMARC S45 - MDIO_CLK */ + ; /* SMARC S46 - MDIO_DAT */ + }; + + /* SMARC GBE0 */ + pinctrl_enetc0: enetc0grp { + fsl,pins = , /* ENET1_TX_CTL */ + , /* ENET1_TXC */ + , /* ENET1_TDO */ + , /* ENET1_TD1 */ + , /* ENET1_TD2 */ + , /* ENET1_TD3 */ + , /* ENET1_RX_CTL */ + , /* ENET1_RXC */ + , /* ENET1_RD0 */ + , /* ENET1_RD1 */ + , /* ENET1_RD2 */ + ; /* ENET1_RD3 */ + }; + + /* SMARC GBE0_SDP */ + pinctrl_enetc0_1588_tmr: enetc01588tmrgrp { + fsl,pins = ; /* SMARC P6 - GBE0_SDP */ + }; + + /* SMARC GBE1 */ + pinctrl_enetc1: enetc1grp { + fsl,pins = , /* ENET2_TX_CTL */ + , /* ENET2_TXC */ + , /* ENET2_TD0 */ + , /* ENET2_TD1 */ + , /* ENET2_TD2 */ + , /* ENET2_TD3 */ + , /* ENET2_RX_CTL */ + , /* ENET2_RXC */ + , /* ENET2_RD0 */ + , /* ENET2_RD1 */ + , /* ENET2_RD2 */ + ; /* ENET2_RD3 */ + }; + + /* SMARC GBE1_SDP */ + pinctrl_enetc1_1588_tmr: enetc11588tmrgrp { + fsl,pins = ; /* SMARC P5 - GBE1_SDP */ + }; + + /* SMARC CAN0 */ + pinctrl_flexcan1: flexcan1grp { + fsl,pins = , /* SMARC P143 - CAN0_TX */ + ; /* SMARC P144 - CAN0_RX */ + }; + + /* SMARC CAN1 */ + pinctrl_flexcan2: flexcan2grp { + fsl,pins = , /* SMARC P145 - CAN1_TX */ + ; /* SMARC P146 - CAN1_RX */ + }; + + /* SMARC GPIO2 */ + pinctrl_gpio2: gpio2grp { + fsl,pins = ; /* SMARC P110 - GPIO2 */ + }; + + /* SMARC GPIO3 */ + pinctrl_gpio3: gpio3grp { + fsl,pins = ; /* SMARC P111 - GPIO3 */ + }; + + /* SMARC GPIO4 */ + pinctrl_gpio4: gpio4grp { + fsl,pins = ; /* SMARC P112 - GPIO4 */ + }; + + /* SMARC GPIO5 */ + pinctrl_gpio5: gpio5grp { + fsl,pins = ; /* SMARC P113 - GPIO5 */ + }; + + /* SMARC GPIO5 as PWM */ + pinctrl_gpio5_pwm: gpio5pwmgrp { + fsl,pins = ; /* SMARC P113 - PWM_OUT */ + }; + + /* SMARC GPIO6 */ + pinctrl_gpio6: gpio6grp { + fsl,pins = ; /* SMARC P114 - GPIO6 */ + }; + + /* SMARC GPIO7 */ + pinctrl_gpio7: gpio7grp { + fsl,pins = ; /* SMARC P115 - GPIO7 */ + }; + + /* SMARC GPIO8 */ + pinctrl_gpio8: gpio8grp { + fsl,pins = ; /* SMARC P116 - GPIO8 */ + }; + + /* SMARC GPIO9 */ + pinctrl_gpio9: gpio9grp { + fsl,pins = ; /* SMARC P117 - GPIO9 */ + }; + + /* SMARC GPIO10 */ + pinctrl_gpio10: gpio10grp { + fsl,pins = ; /* SMARC P118 - GPIO10 */ + }; + + /* SMARC GPIO11 */ + pinctrl_gpio11: gpio11grp { + fsl,pins = ; /* SMARC P119 - GPIO11 */ + }; + + /* SMARC GPIO12 */ + pinctrl_gpio12: gpio12grp { + fsl,pins = ; /* SMARC S142 - GPIO12 */ + }; + + /* SMARC GPIO13 */ + pinctrl_gpio13: gpio13grp { + fsl,pins = ; /* SMARC S123 - GPIO13 */ + }; + + pinctrl_ctrl_io_exp_int_b: ioexpintgrp { + fsl,pins = ; /* CTRL_IO_EXP_INT_B */ + }; + + /* SMARC LCD0_BKLT_PWM */ + pinctrl_lcd0_bklt_pwm: lcd0bkltpwmgrp { + fsl,pins = ; /* SMARC S141 - LCD0_BKLT_PWM */ + }; + + /* SMARC LCD1_BKLT_PWM */ + pinctrl_lcd1_bklt_pwm: lcd1bkltpwmgrp { + fsl,pins = ; /* SMARC S122 - LCD1_BKLT_PWM */ + }; + + /* SMARC I2C_GP */ + pinctrl_lpi2c2: lpi2c2grp { + fsl,pins = , /* SMARC S48 - I2C_GP_CK */ + ; /* SMARC S49 - I2C_GP_DAT */ + }; + + /* SMARC I2C_GP as GPIOs */ + pinctrl_lpi2c2_gpio: lpi2c2gpiogrp { + fsl,pins = , /* SMARC S48 - I2C_GP_CK */ + ; /* SMARC S49 - I2C_GP_DAT */ + }; + + /* SMARC I2C_PM */ + pinctrl_lpi2c3: lpi2c3grp { + fsl,pins = , /* SMARC P122 - I2C_PM_DAT */ + ; /* SMARC P121 - I2C_PM_CK */ + }; + + /* SMARC I2C_PM as GPIOs */ + pinctrl_lpi2c3_gpio: lpi2c3gpiogrp { + fsl,pins = , /* SMARC P122 - I2C_PM_DAT */ + ; /* SMARC P121 - I2C_PM_CK */ + }; + + /* I2C_SOM */ + pinctrl_lpi2c4: lpi2c4grp { + fsl,pins = , /* I2C_SOM_CK */ + ; /* I2C_SOM_DAT */ + }; + + /* I2C_SOM as GPIOs */ + pinctrl_lpi2c4_gpio: lpi2c4gpiogrp { + fsl,pins = , /* I2C_SOM_CK */ + ; /* I2C_SOM_DAT */ + }; + + /* SMARC I2C_LCD */ + pinctrl_lpi2c5: lpi2c5grp { + fsl,pins = , /* SMARC S140 - I2C_LCD_DAT */ + ; /* SMARC S139 - I2C_LCD_CK */ + }; + + /* SMARC I2C_LCD as GPIOs */ + pinctrl_lpi2c5_gpio: lpi2c5gpiogrp { + fsl,pins = , /* SMARC S140 - I2C_LCD_DAT */ + ; /* SMARC S139 - I2C_LCD_CK */ + }; + + /* I2C_CAM */ + pinctrl_lpi2c7: lpi2c7grp { + fsl,pins = , /* I2C_CAM_DAT */ + ; /* I2C_CAM_CK */ + }; + + /* I2C_CAM as GPIOs */ + pinctrl_lpi2c7_gpio: lpi2c7gpiogrp { + fsl,pins = , /* I2C_CAM_DAT */ + ; /* I2C_CAM_CK */ + }; + + /* SMARC SPI1 */ + pinctrl_lpspi4: lpspi4grp { + fsl,pins = , /* SMARC P56 - SPI1_CK */ + , /* SMARC P58 - SPI1_DO */ + , /* SMARC P57 - SPI1_DIN */ + , /* SPI1_TPM_CS# */ + , /* SMARC P54 - SPI1_CS0# */ + ; /* SMARC P55 - SPI1_CS1# */ + }; + + /* SMARC SPI0 */ + pinctrl_lpspi6: lpspi6grp { + fsl,pins = , /* SMARC P43 - SPI0_CS0# */ + , /* SMARC P31 - SPI0_CS1# */ + , /* SMARC P45 - SPI0_DIN */ + , /* SMARC P46 - SPI0_DO */ + ; /* SMARC P44 - SPI0_CK */ + }; + + /* SMARC PCIE_A */ + pinctrl_pcie0: pcie0grp { + fsl,pins = ; /* SMARC P78 - PCIE_A_CKREQ# */ + }; + + /* SMARC PCIE_B */ + pinctrl_pcie1: pcie1grp { + fsl,pins = ; /* SMARC P77 - PCIE_B_CKREQ# */ + }; + + /* SMARC I2S0 */ + pinctrl_sai3: sai3grp { + fsl,pins = , /* SMARC S38 - I2S0_CK */ + , /* SMARC S41 - I2S0_SDIN */ + , /* SMARC S40 - I2S0_SDOUT */ + ; /* SMARC S39 - I2S0_LRCK */ + }; + + /* SMARC AUDIO_MCK */ + pinctrl_sai3_mclk: sai3mclkgrp { + fsl,pins = ; /* SMARC S42 - AUDIO_MCK */ + }; + + /* SMARC I2S2 */ + pinctrl_sai5: sai5grp { + fsl,pins = , /* SMARC S53 - I2S2_CK */ + , /* SMARC S51 - I2S2_SDOUT */ + , /* SMARC S52 - I2S2_SDIN */ + ; /* SMARC S50 - I2S2_LRCK */ + }; + + /* SMARC SMB_ALERT# */ + pinctrl_smb_alert_gpio: smbalertgrp { + fsl,pins = ; /* SMARC P1 - SMB_ALERT# */ + }; + + /* SMARC SER1, used as the Linux Console */ + pinctrl_uart1: uart1grp { + fsl,pins = , /* SMARC P134 - SER1_TX */ + ; /* SMARC P135 - SER1_RX */ + }; + + /* SMARC SER0 */ + pinctrl_uart2: uart2grp { + fsl,pins = , /* SMARC P132 - SER0_CTS# */ + , /* SMARC P131 - SER0_RTS# */ + , /* SMARC P130 - SER0_RX */ + ; /* SMARC P129 - SER0_TX */ + }; + + /* SMARC SER3 */ + pinctrl_uart3: uart3grp { + fsl,pins = , /* SMARC P140 - SER3_TX */ + ; /* SMARC P141 - SER3_RX */ + }; + + /* On-module eMMC */ + pinctrl_usdhc1: usdhc1grp { + fsl,pins = , /* SD1_CLK */ + , /* SD1_CMD */ + , /* SD1_DATA0 */ + , /* SD1_DATA1 */ + , /* SD1_DATA2 */ + , /* SD1_DATA3 */ + , /* SD1_DATA4 */ + , /* SD1_DATA5 */ + , /* SD1_DATA6 */ + , /* SD1_DATA7 */ + ; /* SD1_STROBE */ + }; + + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + fsl,pins = , /* SD1_CLK */ + , /* SD1_CMD */ + , /* SD1_DATA0 */ + , /* SD1_DATA1 */ + , /* SD1_DATA2 */ + , /* SD1_DATA3 */ + , /* SD1_DATA4 */ + , /* SD1_DATA5 */ + , /* SD1_DATA6 */ + , /* SD1_DATA7 */ + ; /* SD1_STROBE */ + }; + + /* SMARC SDIO */ + pinctrl_usdhc2: usdhc2grp { + fsl,pins = , /* SMARC P36 - SDIO_CK */ + , /* SMARC P34 - SDIO_CMD */ + , /* SMARC P39 - SDIO_D0 */ + , /* SMARC P40 - SDIO_D1 */ + , /* SMARC P41 - SDIO_D2 */ + ; /* SMARC P42 - SDIO_D3 */ + }; + + /* SMARC SDIO */ + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = , /* SMARC P36 - SDIO_CK */ + , /* SMARC P34 - SDIO_CMD */ + , /* SMARC P39 - SDIO_D0 */ + , /* SMARC P40 - SDIO_D1 */ + , /* SMARC P41 - SDIO_D2 */ + ; /* SMARC P42 - SDIO_D3 */ + }; + + /* SMARC SDIO */ + pinctrl_usdhc2_sleep: usdhc2-sleepgrp { + fsl,pins = , /* SMARC P36 - SDIO_CK */ + , /* SMARC P34 - SDIO_CMD */ + , /* SMARC P39 - SDIO_D0 */ + , /* SMARC P40 - SDIO_D1 */ + , /* SMARC P41 - SDIO_D2 */ + ; /* SMARC P42 - SDIO_D3 */ + }; + + /* SMARC SDIO_CD# */ + pinctrl_usdhc2_cd: usdhc2-cdgrp { + fsl,pins = ; /* SMARC P35 - SDIO_CD# */ + }; + + /* SMARC SDIO_PWR_EN */ + pinctrl_usdhc2_pwr_en: usdhc2-pwrengrp { + fsl,pins = ; /* SMARC P37 - SDIO_PWR_EN */ + }; + + pinctrl_usdhc2_vsel: usdhc2-vselgrp { + fsl,pins = ; /* PMIC_SD2_VSEL */ + }; + + /* On-module Wi-Fi */ + pinctrl_usdhc3: usdhc3grp { + fsl,pins = , /* SD3_CLK */ + , /* SD3_CMD */ + , /* SD3_DATA0 */ + , /* SD3_DATA1 */ + , /* SD3_DATA2 */ + ; /* SD3_DATA3 */ + }; + + /* On-module Wi-Fi */ + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { + fsl,pins = , /* SD3_CLK */ + , /* SD3_CMD */ + , /* SD3_DATA1 */ + , /* SD3_DATA2 */ + , /* SD3_DATA3 */ + ; /* SD3_DATA4 */ + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa-mb-smarc-2.dts b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa-mb-smarc-2.dts index 5b6b2bb80b288..97726eded0f86 100644 --- a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa-mb-smarc-2.dts +++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa-mb-smarc-2.dts @@ -39,6 +39,8 @@ serial5 = &lpuart6; serial6 = &lpuart7; serial7 = &lpuart8; + spi0 = &flexspi1; + spi1 = &lpspi3; }; chosen { @@ -144,6 +146,13 @@ model = "tqm-tlv320aic32"; audio-codec = <&tlv320aic3x04>; audio-cpu = <&sai3>; + audio-routing = + "IN3_L", "Mic Jack", + "Mic Jack", "Mic Bias", + "IN1_L", "Line In Jack", + "IN1_R", "Line In Jack", + "Line Out Jack", "LOL", + "Line Out Jack", "LOR"; }; }; @@ -172,15 +181,11 @@ }; &flexcan1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_flexcan1>; xceiver-supply = <®_3v3>; status = "okay"; }; &flexcan3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_flexcan3>; xceiver-supply = <®_3v3>; status = "okay"; }; @@ -204,15 +209,12 @@ }; &lpspi3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_lpspi3>; - cs-gpios = <&gpio2 8 GPIO_ACTIVE_LOW>, <&gpio2 7 GPIO_ACTIVE_LOW>; status = "okay"; }; /* SER0 */ &lpuart1 { - status = "disabled"; + status = "reserved"; }; /* SER3 */ @@ -232,27 +234,11 @@ /* X44 mPCIe */ &pcie0 { - pinctrl-0 = <&pinctrl_pcie0>; - pinctrl-names = "default"; - clocks = <&scmi_clk IMX95_CLK_HSIO>, - <&pcieclk 1>, - <&scmi_clk IMX95_CLK_HSIOPLL_VCO>, - <&scmi_clk IMX95_CLK_HSIOPCIEAUX>; - clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux"; - reset-gpio = <&expander2 9 GPIO_ACTIVE_LOW>; status = "okay"; }; /* X22 PCIe x1 socket */ &pcie1 { - pinctrl-0 = <&pinctrl_pcie1>; - pinctrl-names = "default"; - clocks = <&scmi_clk IMX95_CLK_HSIO>, - <&pcieclk 0>, - <&scmi_clk IMX95_CLK_HSIOPLL_VCO>, - <&scmi_clk IMX95_CLK_HSIOPCIEAUX>; - clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux"; - reset-gpio = <&expander2 10 GPIO_ACTIVE_LOW>; status = "okay"; }; @@ -261,39 +247,9 @@ }; &sai3 { - #sound-dai-cells = <0>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sai3>; - assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, - <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, - <&scmi_clk IMX95_CLK_AUDIOPLL1>, - <&scmi_clk IMX95_CLK_AUDIOPLL2>, - <&scmi_clk IMX95_CLK_SAI3>; - assigned-clock-parents = <0>, <0>, <0>, <0>, - <&scmi_clk IMX95_CLK_AUDIOPLL1>; - assigned-clock-rates = <3932160000>, - <3612672000>, <393216000>, - <361267200>, <12288000>; - fsl,sai-mclk-direction-output; status = "okay"; }; -&sai5 { - #sound-dai-cells = <0>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sai5>; - assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, - <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, - <&scmi_clk IMX95_CLK_AUDIOPLL1>, - <&scmi_clk IMX95_CLK_AUDIOPLL2>, - <&scmi_clk IMX95_CLK_SAI5>; - assigned-clock-parents = <0>, <0>, <0>, <0>, - <&scmi_clk IMX95_CLK_AUDIOPLL1>; - assigned-clock-rates = <3932160000>, - <3612672000>, <393216000>, - <361267200>, <12288000>; -}; - /* X4 */ &usb2 { srp-disable; @@ -305,20 +261,9 @@ status = "okay"; }; - /* X16 */ &usdhc2 { - pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; - pinctrl-0 = <&pinctrl_usdhc2>; - pinctrl-1 = <&pinctrl_usdhc2_100mhz>; - pinctrl-2 = <&pinctrl_usdhc2_200mhz>; - pinctrl-3 = <&pinctrl_usdhc2>; - vmmc-supply = <®_sdvmmc>; - cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; - no-1-8-v; no-mmc; no-sdio; - disable-wp; - bus-width = <4>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi index 180124cc5bce1..43418844701b1 100644 --- a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi +++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi @@ -106,16 +106,25 @@ status = "okay"; }; +&flexcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; +}; + +&flexcan3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan3>; +}; + &flexspi1 { - pinctrl-names = "default", "sleep"; + pinctrl-names = "default"; pinctrl-0 = <&pinctrl_flexspi1>; - pinctrl-1 = <&pinctrl_flexspi1>; status = "okay"; flash0: flash@0 { compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <80000000>; + spi-max-frequency = <66000000>; spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; vcc-supply = <®_1v8>; @@ -156,9 +165,8 @@ &lpi2c1 { clock-frequency = <400000>; - pinctrl-names = "default", "sleep"; + pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lpi2c1>; - pinctrl-1 = <&pinctrl_lpi2c1>; status = "okay"; tmp1075: temperature-sensor@4a { @@ -195,6 +203,7 @@ eeprom@58 { compatible = "atmel,24c64d-wl"; reg = <0x58>; + pagesize = <32>; vcc-supply = <®_1v8>; }; @@ -202,6 +211,7 @@ eeprom@5c { compatible = "atmel,24c64d-wl"; reg = <0x5c>; + pagesize = <32>; vcc-supply = <®_1v8>; }; @@ -255,9 +265,11 @@ /* I2C_CAM0 */ &lpi2c3 { clock-frequency = <400000>; - pinctrl-names = "default", "sleep"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_lpi2c3>; - pinctrl-1 = <&pinctrl_lpi2c3>; + pinctrl-1 = <&pinctrl_lpi2c3_gpio>; + sda-gpios = <&gpio2 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio2 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; dp_bridge: dp-bridge@f { @@ -292,21 +304,31 @@ /* I2C_CAM1 */ &lpi2c4 { clock-frequency = <400000>; - pinctrl-names = "default", "sleep"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_lpi2c4>; - pinctrl-1 = <&pinctrl_lpi2c4>; + pinctrl-1 = <&pinctrl_lpi2c4_gpio>; + sda-gpios = <&gpio2 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio2 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; }; /* I2C_LCD */ &lpi2c6 { clock-frequency = <400000>; - pinctrl-names = "default", "sleep"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_lpi2c6>; - pinctrl-1 = <&pinctrl_lpi2c6>; + pinctrl-1 = <&pinctrl_lpi2c6_gpio>; + sda-gpios = <&gpio2 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio2 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; }; +&lpspi3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpspi3>; + cs-gpios = <&gpio2 8 GPIO_ACTIVE_LOW>, <&gpio2 7 GPIO_ACTIVE_LOW>; +}; + /* SER0 */ &lpuart1 { pinctrl-names = "default"; @@ -375,6 +397,63 @@ }; }; +&pcie0 { + pinctrl-0 = <&pinctrl_pcie0>; + pinctrl-names = "default"; + clocks = <&scmi_clk IMX95_CLK_HSIO>, + <&scmi_clk IMX95_CLK_HSIOPLL>, + <&scmi_clk IMX95_CLK_HSIOPLL_VCO>, + <&scmi_clk IMX95_CLK_HSIOPCIEAUX>, + <&pcieclk 1>; + clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux", "ref"; + reset-gpios = <&expander2 9 GPIO_ACTIVE_LOW>; +}; + +&pcie1 { + pinctrl-0 = <&pinctrl_pcie1>; + pinctrl-names = "default"; + clocks = <&scmi_clk IMX95_CLK_HSIO>, + <&scmi_clk IMX95_CLK_HSIOPLL>, + <&scmi_clk IMX95_CLK_HSIOPLL_VCO>, + <&scmi_clk IMX95_CLK_HSIOPCIEAUX>, + <&pcieclk 0>; + clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux", "ref"; + reset-gpios = <&expander2 10 GPIO_ACTIVE_LOW>; +}; + +&sai3 { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai3>; + assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>, + <&scmi_clk IMX95_CLK_AUDIOPLL2>, + <&scmi_clk IMX95_CLK_SAI3>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, + <3612672000>, <393216000>, + <361267200>, <12288000>; + fsl,sai-mclk-direction-output; +}; + +&sai5 { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai5>; + assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>, + <&scmi_clk IMX95_CLK_AUDIOPLL2>, + <&scmi_clk IMX95_CLK_SAI5>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, + <3612672000>, <393216000>, + <361267200>, <12288000>; +}; + &scmi_bbm { linux,code = ; }; @@ -425,11 +504,10 @@ }; &usdhc1 { - pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc1>; pinctrl-1 = <&pinctrl_usdhc1_100mhz>; pinctrl-2 = <&pinctrl_usdhc1_200mhz>; - pinctrl-3 = <&pinctrl_usdhc1>; bus-width = <8>; non-removable; no-sdio; @@ -437,6 +515,18 @@ status = "okay"; }; +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>; + vmmc-supply = <®_sdvmmc>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + no-1-8-v; + disable-wp; + bus-width = <4>; +}; + &wdog3 { status = "okay"; }; @@ -497,12 +587,12 @@ }; pinctrl_flexspi1: flexspi1grp { - fsl,pins = , - , - , - , - , - ; + fsl,pins = , + , + , + , + , + ; }; pinctrl_gpio1: gpio1grp { @@ -527,14 +617,29 @@ ; }; + pinctrl_lpi2c3_gpio: lpi2c3-gpiogrp { + fsl,pins = , + ; + }; + pinctrl_lpi2c4: lpi2c4grp { - fsl,pins = , - ; + fsl,pins = , + ; + }; + + pinctrl_lpi2c4_gpio: lpi2c4-gpiogrp { + fsl,pins = , + ; }; pinctrl_lpi2c6: lpi2c6grp { - fsl,pins = , - ; + fsl,pins = , + ; + }; + + pinctrl_lpi2c6_gpio: lpi2c6-gpiogrp { + fsl,pins = , + ; }; pinctrl_lpspi3: lpspi3grp { @@ -617,7 +722,7 @@ fsl,pins = ; }; - pinctrl_tpm5: tpm4grp { + pinctrl_tpm5: tpm5grp { fsl,pins = ; }; diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi index 6da961eb3fe5c..e45014d50abef 100644 --- a/arch/arm64/boot/dts/freescale/imx95.dtsi +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi @@ -250,6 +250,28 @@ clock-output-names = "dummy"; }; + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-hz-real = /bits/ 64 <500000000>; + opp-microvolt = <920000>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-hz-real = /bits/ 64 <800000000>; + opp-microvolt = <920000>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-hz-real = /bits/ 64 <1000000000>; + opp-microvolt = <920000>; + }; + }; + clk_ext1: clock-ext1 { compatible = "fixed-clock"; #clock-cells = <0>; @@ -945,7 +967,7 @@ }; flexspi1: spi@425e0000 { - compatible = "nxp,imx8mm-fspi"; + compatible = "nxp,imx95-fspi", "nxp,imx8mm-fspi"; reg = <0x425e0000 0x10000>, <0x28000000 0x8000000>; reg-names = "fspi_base", "fspi_mmap"; #address-cells = <1>; @@ -2139,6 +2161,21 @@ }; }; + gpu: gpu@4d900000 { + compatible = "nxp,imx95-mali", "arm,mali-valhall-csf"; + reg = <0 0x4d900000 0 0x480000>; + clocks = <&scmi_clk IMX95_CLK_GPU>, <&scmi_clk IMX95_CLK_GPUAPB>; + clock-names = "core", "coregroup"; + interrupts = , + , + ; + interrupt-names = "job", "mmu", "gpu"; + operating-points-v2 = <&gpu_opp_table>; + power-domains = <&scmi_devpd IMX95_PD_GPU>; + #cooling-cells = <2>; + dynamic-power-coefficient = <1013>; + }; + ddr-pmu@4e090dc0 { compatible = "fsl,imx95-ddr-pmu", "fsl,imx93-ddr-pmu"; reg = <0x0 0x4e090dc0 0x0 0x200>; diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi index 79daba930ad64..225cd2f1220bf 100644 --- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi +++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi @@ -141,6 +141,13 @@ model = "tqm-tlv320aic32"; ssi-controller = <&sai3>; audio-codec = <&tlv320aic3x04>; + audio-routing = + "IN3_L", "Mic Jack", + "Mic Jack", "Mic Bias", + "IN1_L", "Line In Jack", + "IN1_R", "Line In Jack", + "Line Out Jack", "LOL", + "Line Out Jack", "LOR"; }; }; diff --git a/arch/arm64/boot/dts/freescale/mba8xx.dtsi b/arch/arm64/boot/dts/freescale/mba8xx.dtsi index c4b5663949ade..f534dab44e8ed 100644 --- a/arch/arm64/boot/dts/freescale/mba8xx.dtsi +++ b/arch/arm64/boot/dts/freescale/mba8xx.dtsi @@ -128,6 +128,13 @@ model = "tqm-tlv320aic32"; audio-codec = <&tlv320aic3x04>; ssi-controller = <&sai1>; + audio-routing = + "IN3_L", "Mic Jack", + "Mic Jack", "Mic Bias", + "IN1_L", "Line In Jack", + "IN1_R", "Line In Jack", + "Line Out Jack", "LOL", + "Line Out Jack", "LOR"; }; }; diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi index d167624d1f0cb..51d00dac12deb 100644 --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi @@ -3,7 +3,7 @@ * NXP S32G2 SoC family * * Copyright (c) 2021 SUSE LLC - * Copyright 2017-2021, 2024 NXP + * Copyright 2017-2021, 2024-2025 NXP */ #include @@ -727,6 +727,62 @@ status = "disabled"; }; + gmac0: ethernet@4033c000 { + compatible = "nxp,s32g2-dwmac"; + reg = <0x4033c000 0x2000>, /* gmac IP */ + <0x4007c004 0x4>; /* GMAC_0_CTRL_STS */ + interrupt-parent = <&gic>; + interrupts = ; + interrupt-names = "macirq"; + snps,mtl-rx-config = <&mtl_rx_setup>; + snps,mtl-tx-config = <&mtl_tx_setup>; + status = "disabled"; + + mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <5>; + + queue0 { + }; + + queue1 { + }; + + queue2 { + }; + + queue3 { + }; + + queue4 { + }; + }; + + mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <5>; + + queue0 { + }; + + queue1 { + }; + + queue2 { + }; + + queue3 { + }; + + queue4 { + }; + }; + + gmac0mdio: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + gic: interrupt-controller@50800000 { compatible = "arm,gic-v3"; reg = <0x50800000 0x10000>, diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts index c4a195dd67bf5..aa40a52f8e531 100644 --- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT /* * Copyright (c) 2021 SUSE LLC - * Copyright 2019-2021, 2024 NXP + * Copyright 2019-2021, 2024-2025 NXP */ /dts-v1/; @@ -14,6 +14,7 @@ compatible = "nxp,s32g274a-evb", "nxp,s32g2"; aliases { + ethernet0 = &gmac0; serial0 = &uart0; }; @@ -43,3 +44,18 @@ no-1-8-v; status = "okay"; }; + +&gmac0 { + clocks = <&clks 24>, <&clks 19>, <&clks 18>, <&clks 15>; + clock-names = "stmmaceth", "tx", "rx", "ptp_ref"; + phy-mode = "rgmii-id"; + phy-handle = <&rgmiiaphy4>; + status = "okay"; +}; + +&gmac0mdio { + /* KSZ 9031 on RGMII */ + rgmiiaphy4: ethernet-phy@4 { + reg = <4>; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts index 4f58be68c8182..ee3121b192e53 100644 --- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts @@ -14,6 +14,7 @@ compatible = "nxp,s32g274a-rdb2", "nxp,s32g2"; aliases { + ethernet0 = &gmac0; serial0 = &uart0; serial1 = &uart1; }; @@ -77,3 +78,18 @@ no-1-8-v; status = "okay"; }; + +&gmac0 { + clocks = <&clks 24>, <&clks 19>, <&clks 18>, <&clks 15>; + clock-names = "stmmaceth", "tx", "rx", "ptp_ref"; + phy-mode = "rgmii-id"; + phy-handle = <&rgmiiaphy1>; + status = "okay"; +}; + +&gmac0mdio { + /* KSZ 9031 on RGMII */ + rgmiiaphy1: ethernet-phy@1 { + reg = <1>; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi index be3a582ebc1bf..eff7673e7f341 100644 --- a/arch/arm64/boot/dts/freescale/s32g3.dtsi +++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright 2021-2024 NXP + * Copyright 2021-2025 NXP * * Authors: Ghennadi Procopciuc * Ciprian Costea @@ -804,6 +804,62 @@ status = "disabled"; }; + gmac0: ethernet@4033c000 { + compatible = "nxp,s32g2-dwmac"; + reg = <0x4033c000 0x2000>, /* gmac IP */ + <0x4007c004 0x4>; /* GMAC_0_CTRL_STS */ + interrupt-parent = <&gic>; + interrupts = ; + interrupt-names = "macirq"; + snps,mtl-rx-config = <&mtl_rx_setup>; + snps,mtl-tx-config = <&mtl_tx_setup>; + status = "disabled"; + + mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <5>; + + queue0 { + }; + + queue1 { + }; + + queue2 { + }; + + queue3 { + }; + + queue4 { + }; + }; + + mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <5>; + + queue0 { + }; + + queue1 { + }; + + queue2 { + }; + + queue3 { + }; + + queue4 { + }; + }; + + gmac0mdio: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + swt8: watchdog@40500000 { compatible = "nxp,s32g3-swt", "nxp,s32g2-swt"; reg = <40500000 0x1000>; diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts index e94f70ad82d97..326322b621921 100644 --- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts +++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright 2021-2024 NXP + * Copyright 2021-2025 NXP * * NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3) */ @@ -15,6 +15,7 @@ compatible = "nxp,s32g399a-rdb3", "nxp,s32g3"; aliases { + ethernet0 = &gmac0; mmc0 = &usdhc0; serial0 = &uart0; serial1 = &uart1; @@ -93,3 +94,18 @@ disable-wp; status = "okay"; }; + +&gmac0 { + clocks = <&clks 24>, <&clks 19>, <&clks 18>, <&clks 15>; + clock-names = "stmmaceth", "tx", "rx", "ptp_ref"; + phy-mode = "rgmii-id"; + phy-handle = <&rgmiiaphy1>; + status = "okay"; +}; + +&gmac0mdio { + /* KSZ 9031 on RGMII */ + rgmiiaphy1: ethernet-phy@1 { + reg = <1>; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/tqma8xxs-mb-smarc-2.dtsi b/arch/arm64/boot/dts/freescale/tqma8xxs-mb-smarc-2.dtsi index 478cc8ede05ef..3d20e3bf32ce7 100644 --- a/arch/arm64/boot/dts/freescale/tqma8xxs-mb-smarc-2.dtsi +++ b/arch/arm64/boot/dts/freescale/tqma8xxs-mb-smarc-2.dtsi @@ -98,6 +98,13 @@ model = "tqm-tlv320aic32"; ssi-controller = <&sai1>; audio-codec = <&tlv320aic3x04>; + audio-routing = + "IN3_L", "Mic Jack", + "Mic Jack", "Mic Bias", + "IN1_L", "Line In Jack", + "IN1_R", "Line In Jack", + "Line Out Jack", "LOL", + "Line Out Jack", "LOR"; }; }; diff --git a/arch/arm64/boot/dts/intel/Makefile b/arch/arm64/boot/dts/intel/Makefile index 33f6d01266b1a..a117268267ee0 100644 --- a/arch/arm64/boot/dts/intel/Makefile +++ b/arch/arm64/boot/dts/intel/Makefile @@ -2,7 +2,9 @@ dtb-$(CONFIG_ARCH_INTEL_SOCFPGA) += socfpga_agilex_n6000.dtb \ socfpga_agilex_socdk.dtb \ socfpga_agilex_socdk_nand.dtb \ + socfpga_agilex3_socdk.dtb \ socfpga_agilex5_socdk.dtb \ + socfpga_agilex5_socdk_013b.dtb \ socfpga_agilex5_socdk_nand.dtb \ socfpga_n5x_socdk.dtb dtb-$(CONFIG_ARCH_KEEMBAY) += keembay-evm.dtb diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi index c1e66db0f4c52..0dfbafde88222 100644 --- a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi +++ b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi @@ -167,6 +167,7 @@ compatible = "intel,agilex-clkmgr"; reg = <0xffd10000 0x1000>; #clock-cells = <1>; + clocks = <&osc1>; }; gmac0: ethernet@ff800000 { diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex3_socdk.dts b/arch/arm64/boot/dts/intel/socfpga_agilex3_socdk.dts new file mode 100644 index 0000000000000..14b299f19f3a5 --- /dev/null +++ b/arch/arm64/boot/dts/intel/socfpga_agilex3_socdk.dts @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025, Altera Corporation + */ +#include "socfpga_agilex5.dtsi" + +/ { + model = "SoCFPGA Agilex3 SoCDK"; + compatible = "intel,socfpga-agilex3-socdk", "intel,socfpga-agilex3", + "intel,socfpga-agilex5"; + + aliases { + serial0 = &uart0; + ethernet2 = &gmac2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + cpus { + /delete-node/ cpu@2; + /delete-node/ cpu@3; + }; + + leds { + compatible = "gpio-leds"; + + led0 { + label = "hps_led0"; + gpios = <&porta 1 GPIO_ACTIVE_HIGH>; + }; + + led1 { + label = "hps_led1"; + gpios = <&porta 12 GPIO_ACTIVE_HIGH>; + }; + + }; + + memory@80000000 { + device_type = "memory"; + /* We expect the bootloader to fill in the reg */ + reg = <0x0 0x80000000 0x0 0x0>; + }; +}; + +&gmac2 { + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <&emac2_phy0>; + max-frame-size = <9000>; + + mdio0 { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + emac2_phy0: ethernet-phy@0 { + reg = <0>; + rxc-skew-ps = <0>; + rxdv-skew-ps = <0>; + rxd0-skew-ps = <0>; + rxd1-skew-ps = <0>; + rxd2-skew-ps = <0>; + rxd3-skew-ps = <0>; + txc-skew-ps = <0>; + txen-skew-ps = <60>; + txd0-skew-ps = <60>; + txd1-skew-ps = <60>; + txd2-skew-ps = <60>; + txd3-skew-ps = <60>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&osc1 { + clock-frequency = <25000000>; +}; + +&qspi { + status = "okay"; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <100000000>; + m25p,fast-read; + cdns,read-delay = <2>; + cdns,tshsl-ns = <50>; + cdns,tsd2d-ns = <50>; + cdns,tchsh-ns = <4>; + cdns,tslch-ns = <4>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + qspi_boot: partition@0 { + label = "u-boot"; + reg = <0x0 0x00c00000>; + }; + + root: partition@c00000 { + label = "root"; + reg = <0x00c00000 0x03400000>; + }; + }; + }; +}; + +&smmu { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&watchdog0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi index 04e99cd7e74b6..a5c2025a616e8 100644 --- a/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi +++ b/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi @@ -37,6 +37,7 @@ reg = <0x0>; device_type = "cpu"; enable-method = "psci"; + next-level-cache = <&L2>; }; cpu1: cpu@1 { @@ -44,6 +45,7 @@ reg = <0x100>; device_type = "cpu"; enable-method = "psci"; + next-level-cache = <&L2>; }; cpu2: cpu@2 { @@ -51,6 +53,7 @@ reg = <0x200>; device_type = "cpu"; enable-method = "psci"; + next-level-cache = <&L2>; }; cpu3: cpu@3 { @@ -58,6 +61,30 @@ reg = <0x300>; device_type = "cpu"; enable-method = "psci"; + next-level-cache = <&L2>; + }; + + L2: l2-cache { + compatible = "cache"; + cache-level = <2>; + next-level-cache = <&L3>; + cache-unified; + }; + + L3: l3-cache { + compatible = "cache"; + cache-level = <3>; + cache-unified; + }; + + }; + + firmware { + svc { + compatible = "intel,agilex5-svc"; + method = "smc"; + memory-region = <&service_reserved>; + iommus = <&smmu 10>; }; }; @@ -75,8 +102,11 @@ #address-cells = <2>; #size-cells = <2>; interrupt-controller; + interrupt-parent = <&intc>; #redistributor-regions = <1>; redistributor-stride = <0x0 0x20000>; + /* VGIC maintenance interrupt */ + interrupts = ; its: msi-controller@1d040000 { compatible = "arm,gic-v3-its"; @@ -133,6 +163,12 @@ compatible = "usb-nop-xceiv"; }; + pmu0: pmu { + compatible = "arm,armv8-pmuv3"; + interrupt-parent = <&intc>; + interrupts = ; + }; + soc: soc@0 { compatible = "simple-bus"; ranges = <0 0 0 0xffffffff>; @@ -203,7 +239,8 @@ }; i3c0: i3c@10da0000 { - compatible = "snps,dw-i3c-master-1.00a"; + compatible = "altr,agilex5-dw-i3c-master", + "snps,dw-i3c-master-1.00a"; reg = <0x10da0000 0x1000>; #address-cells = <3>; #size-cells = <0>; @@ -213,7 +250,8 @@ }; i3c1: i3c@10da1000 { - compatible = "snps,dw-i3c-master-1.00a"; + compatible = "altr,agilex5-dw-i3c-master", + "snps,dw-i3c-master-1.00a"; reg = <0x10da1000 0x1000>; #address-cells = <3>; #size-cells = <0>; @@ -271,7 +309,9 @@ #size-cells = <0>; interrupts = ; clocks = <&clkmgr AGILEX5_NAND_NF_CLK>; + clock-names = "nf_clk"; cdns,board-delay-ps = <4830>; + iommus = <&smmu 4>; status = "disabled"; }; @@ -298,6 +338,7 @@ snps,block-size = <32767 32767 32767 32767>; snps,priority = <0 1 2 3>; snps,axi-max-burst-len = <8>; + iommus = <&smmu 8>; }; dmac1: dma-controller@10dc0000 { @@ -315,6 +356,7 @@ snps,block-size = <32767 32767 32767 32767>; snps,priority = <0 1 2 3>; snps,axi-max-burst-len = <8>; + iommus = <&smmu 9>; }; rst: rstmgr@10d11000 { @@ -323,6 +365,18 @@ #reset-cells = <1>; }; + smmu: iommu@16000000 { + compatible = "arm,smmu-v3"; + reg = <0x16000000 0x30000>; + interrupts = , + , + ; + interrupt-names = "eventq", "gerror", "priq"; + dma-coherent; + #iommu-cells = <1>; + status = "disabled"; + }; + spi0: spi@10da4000 { compatible = "snps,dw-apb-ssi"; reg = <0x10da4000 0x1000>; @@ -423,6 +477,7 @@ phy-names = "usb2-phy"; resets = <&rst USB0_RESET>, <&rst USB0_OCP_RESET>; reset-names = "dwc2", "dwc2-ecc"; + iommus = <&smmu 6>; clocks = <&clkmgr AGILEX5_USB2OTG_HCLK>; clock-names = "otg"; status = "disabled"; @@ -822,5 +877,61 @@ }; }; }; + + pmu0_tcu: pmu@16002000 { + compatible = "arm,smmu-v3-pmcg"; + reg = <0x16002000 0x1000>, + <0x16022000 0x1000>; + interrupt-parent = <&intc>; + interrupts = ; + }; + + pmu0_tbu0: pmu@16042000 { + compatible = "arm,smmu-v3-pmcg"; + reg = <0x16042000 0x1000>, + <0x16052000 0x1000>; + interrupt-parent = <&intc>; + interrupts = ; + }; + + pmu0_tbu1: pmu@16062000 { + compatible = "arm,smmu-v3-pmcg"; + reg = <0x16062000 0x1000>, + <0x16072000 0x1000>; + interrupt-parent = <&intc>; + interrupts = ; + }; + + pmu0_tbu2: pmu@16082000 { + compatible = "arm,smmu-v3-pmcg"; + reg = <0x16082000 0x1000>, + <0x16092000 0x1000>; + interrupt-parent = <&intc>; + interrupts = ; + }; + + pmu0_tbu3: pmu@160a2000 { + compatible = "arm,smmu-v3-pmcg"; + reg = <0x160A2000 0x1000>, + <0x160B2000 0x1000>; + interrupt-parent = <&intc>; + interrupts = ; + }; + + pmu0_tbu4: pmu@160c2000 { + compatible = "arm,smmu-v3-pmcg"; + reg = <0x160C2000 0x1000>, + <0x160D2000 0x1000>; + interrupt-parent = <&intc>; + interrupts = ; + }; + + pmu0_tbu5: pmu@160e2000 { + compatible = "arm,smmu-v3-pmcg"; + reg = <0x160E2000 0x1000>, + <0x160F2000 0x1000>; + interrupt-parent = <&intc>; + interrupts = ; + }; }; }; diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk.dts b/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk.dts index e9776e1cdc9a0..262bb3e8e5c72 100644 --- a/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk.dts +++ b/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk.dts @@ -77,6 +77,8 @@ cdns,tsd2d-ns = <50>; cdns,tchsh-ns = <4>; cdns,tslch-ns = <4>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; partitions { compatible = "fixed-partitions"; diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_013b.dts b/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_013b.dts new file mode 100644 index 0000000000000..f71e1280c7788 --- /dev/null +++ b/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_013b.dts @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025, Altera Corporation + */ +#include "socfpga_agilex5.dtsi" + +/ { + model = "SoCFPGA Agilex5 013B SoCDK"; + compatible = "intel,socfpga-agilex5-socdk-013b", "intel,socfpga-agilex5"; + + aliases { + serial0 = &uart0; + ethernet2 = &gmac2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + led0 { + label = "hps_led0"; + gpios = <&porta 1 GPIO_ACTIVE_HIGH>; + }; + + led1 { + label = "hps_led1"; + gpios = <&porta 12 GPIO_ACTIVE_HIGH>; + }; + + }; + + memory@80000000 { + device_type = "memory"; + /* We expect the bootloader to fill in the reg */ + reg = <0x0 0x80000000 0x0 0x0>; + }; +}; + +&gmac2 { + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <&emac2_phy0>; + max-frame-size = <9000>; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + + emac2_phy0: ethernet-phy@0 { + reg = <0>; + rxc-skew-ps = <0>; + rxdv-skew-ps = <0>; + rxd0-skew-ps = <0>; + rxd1-skew-ps = <0>; + rxd2-skew-ps = <0>; + rxd3-skew-ps = <0>; + txc-skew-ps = <0>; + txen-skew-ps = <60>; + txd0-skew-ps = <60>; + txd1-skew-ps = <60>; + txd2-skew-ps = <60>; + txd3-skew-ps = <60>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&osc1 { + clock-frequency = <25000000>; +}; + +&qspi { + status = "okay"; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <100000000>; + m25p,fast-read; + cdns,read-delay = <2>; + cdns,tshsl-ns = <50>; + cdns,tsd2d-ns = <50>; + cdns,tchsh-ns = <4>; + cdns,tslch-ns = <4>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + qspi_boot: partition@0 { + label = "u-boot"; + reg = <0x0 0x00c00000>; + }; + + root: partition@c00000 { + label = "root"; + reg = <0x00c00000 0x03400000>; + }; + }; + }; +}; + +&smmu { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&watchdog0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_nand.dts b/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_nand.dts index 38a582ef86b42..ec4541d44c9bc 100644 --- a/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_nand.dts +++ b/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_nand.dts @@ -10,6 +10,7 @@ aliases { serial0 = &uart0; + ethernet0 = &gmac0; }; chosen { @@ -36,6 +37,23 @@ }; }; +&gmac0 { + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <&emac0_phy0>; + max-frame-size = <9000>; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + + emac0_phy0: ethernet-phy@0 { + reg = <0>; + }; + }; +}; + &gpio0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts index b31cfa6b802d9..9ee312bae8d27 100644 --- a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts +++ b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts @@ -116,6 +116,8 @@ cdns,tsd2d-ns = <50>; cdns,tchsh-ns = <4>; cdns,tslch-ns = <4>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; partitions { compatible = "fixed-partitions"; diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts index 0f9020bd0c52a..98900cb410dc5 100644 --- a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts +++ b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts @@ -81,7 +81,7 @@ &nand { status = "okay"; - flash@0 { + nand@0 { #address-cells = <1>; #size-cells = <1>; reg = <0>; diff --git a/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts b/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts index 7952c7f47cc2f..0034a48972209 100644 --- a/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts +++ b/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts @@ -93,6 +93,8 @@ cdns,tsd2d-ns = <50>; cdns,tchsh-ns = <4>; cdns,tslch-ns = <4>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; partitions { compatible = "fixed-partitions"; diff --git a/arch/arm64/boot/dts/marvell/armada-70x0.dtsi b/arch/arm64/boot/dts/marvell/armada-70x0.dtsi index 293403a1a333c..df939426d2583 100644 --- a/arch/arm64/boot/dts/marvell/armada-70x0.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-70x0.dtsi @@ -56,7 +56,7 @@ marvell,function = "dev"; }; - nand_rb: nand-rb { + nand_rb: nand-rb-pins { marvell,pins = "mpp13"; marvell,function = "nf"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-80x0.dtsi b/arch/arm64/boot/dts/marvell/armada-80x0.dtsi index ee67c70bf02ef..fb361d657a779 100644 --- a/arch/arm64/boot/dts/marvell/armada-80x0.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-80x0.dtsi @@ -89,7 +89,7 @@ marvell,function = "dev"; }; - nand_rb: nand-rb { + nand_rb: nand-rb-pins { marvell,pins = "mpp13", "mpp12"; marvell,function = "nf"; }; diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi index 50e9e07248289..3cc320f569add 100644 --- a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi +++ b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi @@ -379,7 +379,7 @@ "mpp27"; marvell,function = "dev"; }; - nand_rb: nand-rb { + nand_rb: nand-rb-pins { marvell,pins = "mpp13"; marvell,function = "nf"; }; diff --git a/arch/arm64/boot/dts/marvell/cn9132-clearfog.dts b/arch/arm64/boot/dts/marvell/cn9132-clearfog.dts index 5cf83d8ca1f59..2507896d58f9b 100644 --- a/arch/arm64/boot/dts/marvell/cn9132-clearfog.dts +++ b/arch/arm64/boot/dts/marvell/cn9132-clearfog.dts @@ -413,13 +413,7 @@ /* SRDS #0,#1,#2,#3 - PCIe */ &cp0_pcie0 { num-lanes = <4>; - /* - * The mvebu-comphy driver does not currently know how to pass correct - * lane-count to ATF while configuring the serdes lanes. - * Rely on bootloader configuration only. - * - * phys = <&cp0_comphy0 0>, <&cp0_comphy1 0>, <&cp0_comphy2 0>, <&cp0_comphy3 0>; - */ + phys = <&cp0_comphy0 0>, <&cp0_comphy1 0>, <&cp0_comphy2 0>, <&cp0_comphy3 0>; status = "okay"; }; @@ -481,13 +475,7 @@ /* SRDS #0,#1 - PCIe */ &cp1_pcie0 { num-lanes = <2>; - /* - * The mvebu-comphy driver does not currently know how to pass correct - * lane-count to ATF while configuring the serdes lanes. - * Rely on bootloader configuration only. - * - * phys = <&cp1_comphy0 0>, <&cp1_comphy1 0>; - */ + phys = <&cp1_comphy0 0>, <&cp1_comphy1 0>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/marvell/mmp/pxa1908-samsung-coreprimevelte.dts b/arch/arm64/boot/dts/marvell/mmp/pxa1908-samsung-coreprimevelte.dts index 47a4f01a7077b..b2ce5edd9c6ac 100644 --- a/arch/arm64/boot/dts/marvell/mmp/pxa1908-samsung-coreprimevelte.dts +++ b/arch/arm64/boot/dts/marvell/mmp/pxa1908-samsung-coreprimevelte.dts @@ -10,6 +10,7 @@ aliases { mmc0 = &sdh2; /* eMMC */ mmc1 = &sdh0; /* SD card */ + mmc2 = &sdh1; /* SDIO */ serial0 = &uart0; }; @@ -23,6 +24,7 @@ fb0: framebuffer@17177000 { compatible = "simple-framebuffer"; reg = <0 0x17177000 0 (480 * 800 * 4)>; + power-domains = <&apmu PXA1908_POWER_DOMAIN_DSI>; width = <480>; height = <800>; stride = <(480 * 4)>; @@ -30,46 +32,26 @@ }; }; - /* Bootloader fills this in */ memory@0 { device_type = "memory"; - reg = <0 0 0 0>; + reg = <0 0 0 0x40000000>; }; reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; + /* + * Reserved by the vendor bootloader as a "secure region". + * + * TODO: See if the responsible stage of the bootloader can be + * replaced + */ + secure-region@0 { + reg = <0 0 0 0x1000000>; + }; framebuffer@17000000 { reg = <0 0x17000000 0 0x1800000>; no-map; }; - - gpu@9000000 { - reg = <0 0x9000000 0 0x1000000>; - }; - - /* Communications processor, aka modem */ - cp@5000000 { - reg = <0 0x5000000 0 0x3000000>; - }; - - cm3@a000000 { - reg = <0 0xa000000 0 0x80000>; - }; - - seclog@8000000 { - reg = <0 0x8000000 0 0x100000>; - }; - - ramoops@8100000 { - compatible = "ramoops"; - reg = <0 0x8100000 0 0x40000>; - record-size = <0x8000>; - console-size = <0x20000>; - max-reason = <5>; - }; }; i2c-muic { @@ -88,6 +70,12 @@ reg = <0x14>; interrupt-parent = <&gpio>; interrupts = <0 IRQ_TYPE_EDGE_FALLING>; + + usb_con: connector { + compatible = "usb-b-connector"; + label = "micro-USB"; + type = "micro"; + }; }; }; @@ -115,6 +103,21 @@ gpios = <&gpio 17 GPIO_ACTIVE_LOW>; }; }; + + backlight { + compatible = "kinetic,ktd2801"; + ctrl-gpios = <&gpio 97 GPIO_ACTIVE_HIGH>; + max-brightness = <210>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwm-names = "enable"; + pwms = <&pwm3 100000>; + enable-gpios = <&gpio 20 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vibrator_pin>; + }; }; &smmu { @@ -286,6 +289,151 @@ pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; pinctrl-single,low-power-mode = <0x208 0x388>; }; + + sdh1_pins_0: sdh1-pins-0 { + pinctrl-single,pins = < + 0x170 1 + 0x174 1 + 0x178 1 + 0x17c 1 + 0x180 1 + >; + pinctrl-single,drive-strength = <0x1000 0x1800>; + pinctrl-single,bias-pullup = <0 0xc000 0 0xc000>; + pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>; + pinctrl-single,input-schmitt = <0 0x30>; + pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; + pinctrl-single,low-power-mode = <0 0x388>; + }; + + sdh1_pins_1: sdh1-pins-1 { + pinctrl-single,pins = <0x184 1>; + pinctrl-single,drive-strength = <0 0x1800>; + pinctrl-single,bias-pullup = <0 0xc000 0 0xc000>; + pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>; + pinctrl-single,input-schmitt = <0 0x30>; + pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; + pinctrl-single,low-power-mode = <0x208 0x388>; + }; + + sdh1_pins_2: sdh1-pins-2 { + pinctrl-single,pins = <0xec 0>; + pinctrl-single,drive-strength = <0x1000 0x1800>; + pinctrl-single,bias-pullup = <0x8000 0x8000 0 0xc000>; + pinctrl-single,bias-pulldown = <0x8000 0x8000 0 0xa000>; + pinctrl-single,input-schmitt = <0 0x30>; + pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; + pinctrl-single,low-power-mode = <0 0x388>; + }; + + sdh1_fast_pins_0: sdh1-fast-pins-0 { + pinctrl-single,pins = < + 0x170 1 + 0x174 1 + 0x178 1 + 0x17c 1 + 0x180 1 + >; + pinctrl-single,drive-strength = <0x1800 0x1800>; + pinctrl-single,bias-pullup = <0 0xc000 0 0xc000>; + pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>; + pinctrl-single,input-schmitt = <0 0x30>; + pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; + pinctrl-single,low-power-mode = <0 0x388>; + }; + + sdh1_fast_pins_1: sdh1-fast-pins-1 { + pinctrl-single,pins = <0x184 1>; + pinctrl-single,drive-strength = <0x1800 0x1800>; + pinctrl-single,bias-pullup = <0 0xc000 0 0xc000>; + pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>; + pinctrl-single,input-schmitt = <0 0x30>; + pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; + pinctrl-single,low-power-mode = <0x208 0x388>; + }; + + sdh2_pins_0: sdh2-pins-0 { + pinctrl-single,pins = < + 0x24 1 + 0x28 1 + 0x2c 1 + 0x30 1 + 0x34 1 + 0x38 1 + 0x3c 1 + 0x40 1 + >; + pinctrl-single,drive-strength = <0x1000 0x1800>; + pinctrl-single,bias-pullup = <0 0xc000 0 0xc000>; + pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>; + pinctrl-single,input-schmitt = <0 0x30>; + pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; + pinctrl-single,low-power-mode = <0 0x388>; + }; + + sdh2_pins_1: sdh2-pins-1 { + pinctrl-single,pins = <0x64 1>; + pinctrl-single,drive-strength = <0x1000 0x1800>; + pinctrl-single,bias-pullup = <0 0xc000 0 0xc000>; + pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>; + pinctrl-single,input-schmitt = <0 0x30>; + pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; + pinctrl-single,low-power-mode = <0x208 0x388>; + }; + + sdh2_pins_2: sdh2-pins-2 { + pinctrl-single,pins = <0x5c 1>; + pinctrl-single,bias-pullup = <0xc000 0xc000 0 0xc000>; + pinctrl-single,bias-pulldown = <0x8000 0xa000 0x8000 0xa000>; + pinctrl-single,low-power-mode = <0x288 0x388>; + }; + + sdh2_fast_pins_0: sdh2-fast-pins-0 { + pinctrl-single,pins = < + 0x24 1 + 0x28 1 + 0x2c 1 + 0x30 1 + 0x34 1 + 0x38 1 + 0x3c 1 + 0x40 1 + >; + pinctrl-single,drive-strength = <0x1800 0x1800>; + pinctrl-single,bias-pullup = <0 0xc000 0 0xc000>; + pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>; + pinctrl-single,input-schmitt = <0 0x30>; + pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; + pinctrl-single,low-power-mode = <0 0x388>; + }; + + sdh2_fast_pins_1: sdh2-fast-pins-1 { + pinctrl-single,pins = <0x64 1>; + pinctrl-single,drive-strength = <0x1800 0x1800>; + pinctrl-single,bias-pullup = <0 0xc000 0 0xc000>; + pinctrl-single,bias-pulldown = <0 0xa000 0 0xa000>; + pinctrl-single,input-schmitt = <0 0x30>; + pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; + pinctrl-single,low-power-mode = <0x208 0x388>; + }; + + sdh2_fast_pins_2: sdh2-fast-pins-2 { + pinctrl-single,pins = <0x5c 1>; + pinctrl-single,drive-strength = <0x1800 0x1800>; + pinctrl-single,bias-pullup = <0xc000 0xc000 0 0xc000>; + pinctrl-single,bias-pulldown = <0x8000 0xa000 0x8000 0xa000>; + pinctrl-single,low-power-mode = <0x288 0x388>; + }; + + vibrator_pin: vibrator-pin { + pinctrl-single,pins = <0x12c 0>; + pinctrl-single,drive-strength = <0x1000 0x1800>; + pinctrl-single,bias-pullup = <0x8000 0xc000 0x8000 0xc000>; + pinctrl-single,bias-pulldown = <0xa000 0xa000 0 0xa000>; + pinctrl-single,input-schmitt = <0 0x30>; + pinctrl-single,input-schmitt-enable = <0x40 0 0x40 0x40>; + pinctrl-single,low-power-mode = <0 0x388>; + }; }; &uart0 { @@ -303,10 +451,46 @@ &twsi2 { status = "okay"; + + pmic@30 { + compatible = "marvell,88pm886-a1"; + reg = <0x30>; + interrupts = ; + wakeup-source; + + regulators { + ldo2: ldo2 { + regulator-min-microvolt = <1900000>; + regulator-max-microvolt = <3100000>; + }; + + ldo6: ldo6 { + regulator-boot-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + }; + + ldo14: ldo14 { + regulator-boot-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + }; + }; + }; }; &twsi3 { status = "okay"; + + touchscreen@50 { + compatible = "imagis,ist3032c"; + reg = <0x50>; + interrupt-parent = <&gpio>; + interrupts = <72 IRQ_TYPE_EDGE_FALLING>; + vdd-supply = <&ldo2>; + touchscreen-size-x = <480>; + touchscreen-size-y = <800>; + }; }; &usb { @@ -314,18 +498,33 @@ }; &sdh2 { - /* Disabled for now because initialization fails with -ETIMEDOUT. */ - status = "disabled"; + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&sdh2_pins_0 &sdh2_pins_1 &sdh2_pins_2>; + pinctrl-1 = <&sdh2_fast_pins_0 &sdh2_fast_pins_1 &sdh2_fast_pins_2>; bus-width = <8>; non-removable; mmc-ddr-1_8v; + mmc-hs200-1_8v; }; &sdh0 { pinctrl-names = "default"; pinctrl-0 = <&sdh0_pins_0 &sdh0_pins_1 &sdh0_pins_2>; - cd-gpios = <&gpio 11 0>; - cd-inverted; + cd-gpios = <&gpio 11 GPIO_ACTIVE_LOW>; bus-width = <4>; wp-inverted; + vmmc-supply = <&ldo14>; + vqmmc-supply = <&ldo6>; +}; + +&sdh1 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&sdh1_pins_0 &sdh1_pins_1 &sdh1_pins_2>; + pinctrl-1 = <&sdh1_fast_pins_0 &sdh1_fast_pins_1 &sdh1_pins_2>; + bus-width = <4>; + non-removable; +}; + +&pwm3 { + status = "okay"; }; diff --git a/arch/arm64/boot/dts/marvell/mmp/pxa1908.dtsi b/arch/arm64/boot/dts/marvell/mmp/pxa1908.dtsi index cf2b9109688ce..5778bfdb85675 100644 --- a/arch/arm64/boot/dts/marvell/mmp/pxa1908.dtsi +++ b/arch/arm64/boot/dts/marvell/mmp/pxa1908.dtsi @@ -3,6 +3,7 @@ #include #include +#include / { model = "Marvell Armada PXA1908"; @@ -58,6 +59,20 @@ method = "smc"; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + ramoops@8100000 { + compatible = "ramoops"; + reg = <0 0x8100000 0 0x40000>; + record-size = <0x8000>; + console-size = <0x20000>; + max-reason = <5>; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts = , @@ -79,6 +94,7 @@ #iommu-cells = <1>; interrupts = , ; + power-domains = <&apmu PXA1908_POWER_DOMAIN_VPU>; status = "disabled"; }; @@ -195,6 +211,38 @@ }; }; + pwm0: pwm@1a000 { + compatible = "marvell,pxa250-pwm"; + reg = <0x1a000 0x10>; + clocks = <&apbc PXA1908_CLK_PWM0>; + #pwm-cells = <1>; + status = "disabled"; + }; + + pwm1: pwm@1a400 { + compatible = "marvell,pxa250-pwm"; + reg = <0x1a400 0x10>; + clocks = <&apbc PXA1908_CLK_PWM1>; + #pwm-cells = <1>; + status = "disabled"; + }; + + pwm2: pwm@1a800 { + compatible = "marvell,pxa250-pwm"; + reg = <0x1a800 0x10>; + clocks = <&apbc PXA1908_CLK_PWM2>; + #pwm-cells = <1>; + status = "disabled"; + }; + + pwm3: pwm@1ac00 { + compatible = "marvell,pxa250-pwm"; + reg = <0x1ac00 0x10>; + clocks = <&apbc PXA1908_CLK_PWM3>; + #pwm-cells = <1>; + status = "disabled"; + }; + pmx: pinmux@1e000 { compatible = "marvell,pxa1908-padconf", "pinconf-single"; reg = <0x1e000 0x330>; @@ -291,9 +339,10 @@ }; apmu: clock-controller@82800 { - compatible = "marvell,pxa1908-apmu"; + compatible = "marvell,pxa1908-apmu", "syscon"; reg = <0x82800 0x400>; #clock-cells = <1>; + #power-domain-cells = <1>; }; }; }; diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index a4df4c21399ee..3f76d9ce98797 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -19,12 +19,71 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sata.dtbo dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo +mt7986a-bananapi-bpi-r3-emmc-nand-dtbs := \ + mt7986a-bananapi-bpi-r3.dtb \ + mt7986a-bananapi-bpi-r3-emmc.dtbo \ + mt7986a-bananapi-bpi-r3-nand.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc-nand.dtb +mt7986a-bananapi-bpi-r3-emmc-nor-dtbs := \ + mt7986a-bananapi-bpi-r3.dtb \ + mt7986a-bananapi-bpi-r3-emmc.dtbo \ + mt7986a-bananapi-bpi-r3-nor.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc-nor.dtb +mt7986a-bananapi-bpi-r3-sd-nand-dtbs := \ + mt7986a-bananapi-bpi-r3.dtb \ + mt7986a-bananapi-bpi-r3-sd.dtbo \ + mt7986a-bananapi-bpi-r3-nand.dtbo \ + mt7986a-bananapi-bpi-r3-sata.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd-nand.dtb +mt7986a-bananapi-bpi-r3-sd-nor-dtbs := \ + mt7986a-bananapi-bpi-r3.dtb \ + mt7986a-bananapi-bpi-r3-sd.dtbo \ + mt7986a-bananapi-bpi-r3-nor.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd-nor.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-2g5.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-emmc.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-pro-4e.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-pro-8x.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-pro-cn15.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-pro-cn18.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-pro-emmc.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-pro-sd.dtbo dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtbo +mt7988a-bananapi-bpi-r4-emmc-dtbs := \ + mt7988a-bananapi-bpi-r4.dtb \ + mt7988a-bananapi-bpi-r4-emmc.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-emmc.dtb +mt7988a-bananapi-bpi-r4-sd-dtbs := \ + mt7988a-bananapi-bpi-r4.dtb \ + mt7988a-bananapi-bpi-r4-sd.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtb +mt7988a-bananapi-bpi-r4-2g5-emmc-dtbs := \ + mt7988a-bananapi-bpi-r4-2g5.dtb \ + mt7988a-bananapi-bpi-r4-emmc.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-2g5-emmc.dtb +mt7988a-bananapi-bpi-r4-2g5-sd-dtbs := \ + mt7988a-bananapi-bpi-r4-2g5.dtb \ + mt7988a-bananapi-bpi-r4-sd.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-2g5-sd.dtb +mt7988a-bananapi-bpi-r4-pro-8x-emmc-dtbs := \ + mt7988a-bananapi-bpi-r4-pro-8x.dtb \ + mt7988a-bananapi-bpi-r4-pro-emmc.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-pro-8x-emmc.dtb +mt7988a-bananapi-bpi-r4-pro-8x-sd-dtbs := \ + mt7988a-bananapi-bpi-r4-pro-8x.dtb \ + mt7988a-bananapi-bpi-r4-pro-sd.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-pro-8x-sd.dtb +mt7988a-bananapi-bpi-r4-pro-8x-sd-cn15-dtbs := \ + mt7988a-bananapi-bpi-r4-pro-8x-sd.dtb \ + mt7988a-bananapi-bpi-r4-pro-cn15.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-pro-8x-sd-cn15.dtb +mt7988a-bananapi-bpi-r4-pro-8x-sd-cn18-dtbs := \ + mt7988a-bananapi-bpi-r4-pro-8x-sd.dtb \ + mt7988a-bananapi-bpi-r4-pro-cn18.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-pro-8x-sd-cn18.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb @@ -99,11 +158,16 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8370-genio-510-evk.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8370-grinn-genio-510-sbc.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk-ufs.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8390-genio-700-evk.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8390-grinn-genio-700-sbc.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-kontron-3-5-sbc-i1200.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l-8-hd-panel.dtbo +mt8395-radxa-nio-12l-8-hd-panel-dtbs := mt8395-radxa-nio-12l.dtb mt8395-radxa-nio-12l-8-hd-panel.dtbo +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l-8-hd-panel.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb # Device tree overlays support @@ -111,4 +175,6 @@ DTC_FLAGS_mt7986a-bananapi-bpi-r3 := -@ DTC_FLAGS_mt7986a-bananapi-bpi-r3-mini := -@ DTC_FLAGS_mt7988a-bananapi-bpi-r4 := -@ DTC_FLAGS_mt7988a-bananapi-bpi-r4-2g5 := -@ +DTC_FLAGS_mt7988a-bananapi-bpi-r4-pro-4e := -@ +DTC_FLAGS_mt7988a-bananapi-bpi-r4-pro-8x := -@ DTC_FLAGS_mt8395-radxa-nio-12l := -@ diff --git a/arch/arm64/boot/dts/mediatek/mt6878-pinfunc.h b/arch/arm64/boot/dts/mediatek/mt6878-pinfunc.h new file mode 100644 index 0000000000000..4e8e475a74549 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt6878-pinfunc.h @@ -0,0 +1,1201 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023 MediaTek Inc. + * Author: Light Hsieh + * + * Copyright (C) 2025 Igor Belwon + */ + +#ifndef __MT6878_PINFUNC_H +#define __MT6878_PINFUNC_H + +#include "mt65xx.h" + +#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) +#define PINMUX_GPIO0__FUNC_TP_GPIO0_AO (MTK_PIN_NO(0) | 1) +#define PINMUX_GPIO0__FUNC_SRCLKENA1 (MTK_PIN_NO(0) | 2) +#define PINMUX_GPIO0__FUNC_DBG_MON_A3 (MTK_PIN_NO(0) | 7) + +#define PINMUX_GPIO1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) +#define PINMUX_GPIO1__FUNC_TP_GPIO1_AO (MTK_PIN_NO(1) | 1) +#define PINMUX_GPIO1__FUNC_SRCLKENA1 (MTK_PIN_NO(1) | 2) +#define PINMUX_GPIO1__FUNC_SRCLKENA2 (MTK_PIN_NO(1) | 3) +#define PINMUX_GPIO1__FUNC_IDDIG (MTK_PIN_NO(1) | 5) +#define PINMUX_GPIO1__FUNC_DBG_MON_A4 (MTK_PIN_NO(1) | 7) + +#define PINMUX_GPIO2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) +#define PINMUX_GPIO2__FUNC_TP_GPIO2_AO (MTK_PIN_NO(2) | 1) +#define PINMUX_GPIO2__FUNC_SRCLKENAI0 (MTK_PIN_NO(2) | 2) +#define PINMUX_GPIO2__FUNC_SCP_DMIC_CLK (MTK_PIN_NO(2) | 4) +#define PINMUX_GPIO2__FUNC_DMIC_CLK (MTK_PIN_NO(2) | 5) +#define PINMUX_GPIO2__FUNC_DBG_MON_A5 (MTK_PIN_NO(2) | 7) + +#define PINMUX_GPIO3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) +#define PINMUX_GPIO3__FUNC_TP_GPIO3_AO (MTK_PIN_NO(3) | 1) +#define PINMUX_GPIO3__FUNC_SRCLKENAI1 (MTK_PIN_NO(3) | 2) +#define PINMUX_GPIO3__FUNC_SCP_DMIC_DAT (MTK_PIN_NO(3) | 4) +#define PINMUX_GPIO3__FUNC_DMIC_DAT (MTK_PIN_NO(3) | 5) +#define PINMUX_GPIO3__FUNC_DBG_MON_A6 (MTK_PIN_NO(3) | 7) + +#define PINMUX_GPIO4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) +#define PINMUX_GPIO4__FUNC_SPI7_CLK (MTK_PIN_NO(4) | 1) +#define PINMUX_GPIO4__FUNC_TP_GPIO4_AO (MTK_PIN_NO(4) | 2) +#define PINMUX_GPIO4__FUNC_ANT_SEL0 (MTK_PIN_NO(4) | 3) +#define PINMUX_GPIO4__FUNC_DMIC1_CLK (MTK_PIN_NO(4) | 5) +#define PINMUX_GPIO4__FUNC_MD_INT4 (MTK_PIN_NO(4) | 6) +#define PINMUX_GPIO4__FUNC_DBG_MON_A7 (MTK_PIN_NO(4) | 7) + +#define PINMUX_GPIO5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) +#define PINMUX_GPIO5__FUNC_SPI7_CSB (MTK_PIN_NO(5) | 1) +#define PINMUX_GPIO5__FUNC_TP_GPIO5_AO (MTK_PIN_NO(5) | 2) +#define PINMUX_GPIO5__FUNC_ANT_SEL1 (MTK_PIN_NO(5) | 3) +#define PINMUX_GPIO5__FUNC_DMIC1_DAT (MTK_PIN_NO(5) | 5) +#define PINMUX_GPIO5__FUNC_MD_INT0 (MTK_PIN_NO(5) | 6) +#define PINMUX_GPIO5__FUNC_DBG_MON_A8 (MTK_PIN_NO(5) | 7) + +#define PINMUX_GPIO6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) +#define PINMUX_GPIO6__FUNC_SPI7_MO (MTK_PIN_NO(6) | 1) +#define PINMUX_GPIO6__FUNC_TP_GPIO6_AO (MTK_PIN_NO(6) | 2) +#define PINMUX_GPIO6__FUNC_ANT_SEL2 (MTK_PIN_NO(6) | 3) +#define PINMUX_GPIO6__FUNC_MD32_0_GPIO0 (MTK_PIN_NO(6) | 4) +#define PINMUX_GPIO6__FUNC_MD_INT3 (MTK_PIN_NO(6) | 6) +#define PINMUX_GPIO6__FUNC_DBG_MON_B0 (MTK_PIN_NO(6) | 7) + +#define PINMUX_GPIO7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) +#define PINMUX_GPIO7__FUNC_SPI7_MI (MTK_PIN_NO(7) | 1) +#define PINMUX_GPIO7__FUNC_TP_GPIO7_AO (MTK_PIN_NO(7) | 2) +#define PINMUX_GPIO7__FUNC_ANT_SEL3 (MTK_PIN_NO(7) | 3) +#define PINMUX_GPIO7__FUNC_MD32_1_GPIO0 (MTK_PIN_NO(7) | 4) + +#define PINMUX_GPIO8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) +#define PINMUX_GPIO8__FUNC_SCP_JTAG0_TRSTN_VLP (MTK_PIN_NO(8) | 2) +#define PINMUX_GPIO8__FUNC_SPM_JTAG_TRSTN_VLP (MTK_PIN_NO(8) | 3) +#define PINMUX_GPIO8__FUNC_SSPM_JTAG_TRSTN_VLP (MTK_PIN_NO(8) | 4) +#define PINMUX_GPIO8__FUNC_HFRP_JTAG0_TRSTN (MTK_PIN_NO(8) | 5) +#define PINMUX_GPIO8__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(8) | 6) +#define PINMUX_GPIO8__FUNC_CONN_BGF_MCU_TDI (MTK_PIN_NO(8) | 7) + +#define PINMUX_GPIO9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) +#define PINMUX_GPIO9__FUNC_SCP_JTAG0_TCK_VLP (MTK_PIN_NO(9) | 2) +#define PINMUX_GPIO9__FUNC_SPM_JTAG_TCK_VLP (MTK_PIN_NO(9) | 3) +#define PINMUX_GPIO9__FUNC_SSPM_JTAG_TCK_VLP (MTK_PIN_NO(9) | 4) +#define PINMUX_GPIO9__FUNC_HFRP_JTAG0_TCK (MTK_PIN_NO(9) | 5) +#define PINMUX_GPIO9__FUNC_IO_JTAG_TCK (MTK_PIN_NO(9) | 6) +#define PINMUX_GPIO9__FUNC_CONN_BGF_MCU_TRST_B (MTK_PIN_NO(9) | 7) + +#define PINMUX_GPIO10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) +#define PINMUX_GPIO10__FUNC_SCP_JTAG0_TMS_VLP (MTK_PIN_NO(10) | 2) +#define PINMUX_GPIO10__FUNC_SPM_JTAG_TMS_VLP (MTK_PIN_NO(10) | 3) +#define PINMUX_GPIO10__FUNC_SSPM_JTAG_TMS_VLP (MTK_PIN_NO(10) | 4) +#define PINMUX_GPIO10__FUNC_HFRP_JTAG0_TMS (MTK_PIN_NO(10) | 5) +#define PINMUX_GPIO10__FUNC_IO_JTAG_TMS (MTK_PIN_NO(10) | 6) +#define PINMUX_GPIO10__FUNC_CONN_BGF_MCU_TCK (MTK_PIN_NO(10) | 7) + +#define PINMUX_GPIO11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) +#define PINMUX_GPIO11__FUNC_SCP_JTAG0_TDI_VLP (MTK_PIN_NO(11) | 2) +#define PINMUX_GPIO11__FUNC_SPM_JTAG_TDI_VLP (MTK_PIN_NO(11) | 3) +#define PINMUX_GPIO11__FUNC_SSPM_JTAG_TDI_VLP (MTK_PIN_NO(11) | 4) +#define PINMUX_GPIO11__FUNC_HFRP_JTAG0_TDI (MTK_PIN_NO(11) | 5) +#define PINMUX_GPIO11__FUNC_IO_JTAG_TDI (MTK_PIN_NO(11) | 6) +#define PINMUX_GPIO11__FUNC_CONN_BGF_MCU_TDO (MTK_PIN_NO(11) | 7) + +#define PINMUX_GPIO12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) +#define PINMUX_GPIO12__FUNC_SCP_JTAG0_TDO_VLP (MTK_PIN_NO(12) | 2) +#define PINMUX_GPIO12__FUNC_SPM_JTAG_TDO_VLP (MTK_PIN_NO(12) | 3) +#define PINMUX_GPIO12__FUNC_SSPM_JTAG_TDO_VLP (MTK_PIN_NO(12) | 4) +#define PINMUX_GPIO12__FUNC_HFRP_JTAG0_TDO (MTK_PIN_NO(12) | 5) +#define PINMUX_GPIO12__FUNC_IO_JTAG_TDO (MTK_PIN_NO(12) | 6) +#define PINMUX_GPIO12__FUNC_CONN_BGF_MCU_TMS (MTK_PIN_NO(12) | 7) + +#define PINMUX_GPIO13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) +#define PINMUX_GPIO13__FUNC_MFG_EB_JTAG_TDI (MTK_PIN_NO(13) | 1) +#define PINMUX_GPIO13__FUNC_CONN_WF_MCU_TDI (MTK_PIN_NO(13) | 2) +#define PINMUX_GPIO13__FUNC_SCP_JTAG0_TDI_VCORE (MTK_PIN_NO(13) | 3) +#define PINMUX_GPIO13__FUNC_SPM_JTAG_TDI_VCORE (MTK_PIN_NO(13) | 5) +#define PINMUX_GPIO13__FUNC_MCUPM_JTAG_TDI (MTK_PIN_NO(13) | 6) + +#define PINMUX_GPIO14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) +#define PINMUX_GPIO14__FUNC_MFG_EB_JTAG_TRSTN (MTK_PIN_NO(14) | 1) +#define PINMUX_GPIO14__FUNC_CONN_WF_MCU_TRST_B (MTK_PIN_NO(14) | 2) +#define PINMUX_GPIO14__FUNC_SCP_JTAG0_TRSTN_VCORE (MTK_PIN_NO(14) | 3) +#define PINMUX_GPIO14__FUNC_SPM_JTAG_TRSTN_VCORE (MTK_PIN_NO(14) | 5) +#define PINMUX_GPIO14__FUNC_MCUPM_JTAG_TRSTN (MTK_PIN_NO(14) | 6) + +#define PINMUX_GPIO15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) +#define PINMUX_GPIO15__FUNC_MFG_EB_JTAG_TCK (MTK_PIN_NO(15) | 1) +#define PINMUX_GPIO15__FUNC_CONN_WF_MCU_TCK (MTK_PIN_NO(15) | 2) +#define PINMUX_GPIO15__FUNC_SCP_JTAG0_TCK_VCORE (MTK_PIN_NO(15) | 3) +#define PINMUX_GPIO15__FUNC_SPM_JTAG_TCK_VCORE (MTK_PIN_NO(15) | 5) +#define PINMUX_GPIO15__FUNC_MCUPM_JTAG_TCK (MTK_PIN_NO(15) | 6) + +#define PINMUX_GPIO16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) +#define PINMUX_GPIO16__FUNC_MFG_EB_JTAG_TDO (MTK_PIN_NO(16) | 1) +#define PINMUX_GPIO16__FUNC_CONN_WF_MCU_TDO (MTK_PIN_NO(16) | 2) +#define PINMUX_GPIO16__FUNC_SCP_JTAG0_TDO_VCORE (MTK_PIN_NO(16) | 3) +#define PINMUX_GPIO16__FUNC_SPM_JTAG_TDO_VCORE (MTK_PIN_NO(16) | 5) +#define PINMUX_GPIO16__FUNC_MCUPM_JTAG_TDO (MTK_PIN_NO(16) | 6) + +#define PINMUX_GPIO17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) +#define PINMUX_GPIO17__FUNC_MFG_EB_JTAG_TMS (MTK_PIN_NO(17) | 1) +#define PINMUX_GPIO17__FUNC_CONN_WF_MCU_TMS (MTK_PIN_NO(17) | 2) +#define PINMUX_GPIO17__FUNC_SCP_JTAG0_TMS_VCORE (MTK_PIN_NO(17) | 3) +#define PINMUX_GPIO17__FUNC_SPM_JTAG_TMS_VCORE (MTK_PIN_NO(17) | 5) +#define PINMUX_GPIO17__FUNC_MCUPM_JTAG_TMS (MTK_PIN_NO(17) | 6) + +#define PINMUX_GPIO18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) +#define PINMUX_GPIO18__FUNC_CONN_BT_TXD (MTK_PIN_NO(18) | 2) +#define PINMUX_GPIO18__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(18) | 3) +#define PINMUX_GPIO18__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(18) | 6) + +#define PINMUX_GPIO19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) +#define PINMUX_GPIO19__FUNC_PWM_0 (MTK_PIN_NO(19) | 1) +#define PINMUX_GPIO19__FUNC_SDA10 (MTK_PIN_NO(19) | 3) +#define PINMUX_GPIO19__FUNC_MD32_0_GPIO0 (MTK_PIN_NO(19) | 4) +#define PINMUX_GPIO19__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(19) | 5) +#define PINMUX_GPIO19__FUNC_DBG_MON_A9 (MTK_PIN_NO(19) | 7) + +#define PINMUX_GPIO20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) +#define PINMUX_GPIO20__FUNC_PWM_1 (MTK_PIN_NO(20) | 1) +#define PINMUX_GPIO20__FUNC_SPI4_CLK (MTK_PIN_NO(20) | 2) +#define PINMUX_GPIO20__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(20) | 4) +#define PINMUX_GPIO20__FUNC_DAP_SONIC_SWCK (MTK_PIN_NO(20) | 6) +#define PINMUX_GPIO20__FUNC_DBG_MON_A10 (MTK_PIN_NO(20) | 7) + +#define PINMUX_GPIO21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) +#define PINMUX_GPIO21__FUNC_PWM_2 (MTK_PIN_NO(21) | 1) +#define PINMUX_GPIO21__FUNC_SPI4_CSB (MTK_PIN_NO(21) | 2) +#define PINMUX_GPIO21__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(21) | 4) +#define PINMUX_GPIO21__FUNC_IDDIG (MTK_PIN_NO(21) | 5) +#define PINMUX_GPIO21__FUNC_DAP_SONIC_SWD (MTK_PIN_NO(21) | 6) +#define PINMUX_GPIO21__FUNC_DBG_MON_A11 (MTK_PIN_NO(21) | 7) + +#define PINMUX_GPIO22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) +#define PINMUX_GPIO22__FUNC_PWM_3 (MTK_PIN_NO(22) | 1) +#define PINMUX_GPIO22__FUNC_SPI4_MO (MTK_PIN_NO(22) | 2) +#define PINMUX_GPIO22__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(22) | 4) +#define PINMUX_GPIO22__FUNC_VBUSVALID (MTK_PIN_NO(22) | 5) +#define PINMUX_GPIO22__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(22) | 6) +#define PINMUX_GPIO22__FUNC_DBG_MON_A12 (MTK_PIN_NO(22) | 7) + +#define PINMUX_GPIO23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) +#define PINMUX_GPIO23__FUNC_SPI4_MI (MTK_PIN_NO(23) | 2) +#define PINMUX_GPIO23__FUNC_MD32_1_GPIO0 (MTK_PIN_NO(23) | 4) +#define PINMUX_GPIO23__FUNC_USB_DRVVBUS (MTK_PIN_NO(23) | 5) +#define PINMUX_GPIO23__FUNC_DAP_MD32_SWD (MTK_PIN_NO(23) | 6) +#define PINMUX_GPIO23__FUNC_DBG_MON_A13 (MTK_PIN_NO(23) | 7) + +#define PINMUX_GPIO24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) +#define PINMUX_GPIO24__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(24) | 1) +#define PINMUX_GPIO24__FUNC_SCL12 (MTK_PIN_NO(24) | 2) +#define PINMUX_GPIO24__FUNC_SCL10 (MTK_PIN_NO(24) | 3) +#define PINMUX_GPIO24__FUNC_CMVREF0 (MTK_PIN_NO(24) | 4) +#define PINMUX_GPIO24__FUNC_CONN_WIFI_TXD (MTK_PIN_NO(24) | 5) +#define PINMUX_GPIO24__FUNC_CMFLASH0 (MTK_PIN_NO(24) | 6) +#define PINMUX_GPIO24__FUNC_DBG_MON_A14 (MTK_PIN_NO(24) | 7) + +#define PINMUX_GPIO25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) +#define PINMUX_GPIO25__FUNC_SPI6_CLK (MTK_PIN_NO(25) | 1) +#define PINMUX_GPIO25__FUNC_SCL11 (MTK_PIN_NO(25) | 2) +#define PINMUX_GPIO25__FUNC_CMVREF1 (MTK_PIN_NO(25) | 4) +#define PINMUX_GPIO25__FUNC_CMFLASH1 (MTK_PIN_NO(25) | 6) +#define PINMUX_GPIO25__FUNC_DBG_MON_A15 (MTK_PIN_NO(25) | 7) + +#define PINMUX_GPIO26__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) +#define PINMUX_GPIO26__FUNC_SPI6_CSB (MTK_PIN_NO(26) | 1) +#define PINMUX_GPIO26__FUNC_SDA11 (MTK_PIN_NO(26) | 2) +#define PINMUX_GPIO26__FUNC_USB_DRVVBUS (MTK_PIN_NO(26) | 3) +#define PINMUX_GPIO26__FUNC_CMVREF2 (MTK_PIN_NO(26) | 4) +#define PINMUX_GPIO26__FUNC_CMFLASH2 (MTK_PIN_NO(26) | 6) +#define PINMUX_GPIO26__FUNC_DBG_MON_A16 (MTK_PIN_NO(26) | 7) + +#define PINMUX_GPIO27__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) +#define PINMUX_GPIO27__FUNC_SPI6_MO (MTK_PIN_NO(27) | 1) +#define PINMUX_GPIO27__FUNC_VBUSVALID (MTK_PIN_NO(27) | 3) +#define PINMUX_GPIO27__FUNC_CMVREF3 (MTK_PIN_NO(27) | 4) +#define PINMUX_GPIO27__FUNC_DMIC1_CLK (MTK_PIN_NO(27) | 5) +#define PINMUX_GPIO27__FUNC_CMFLASH3 (MTK_PIN_NO(27) | 6) +#define PINMUX_GPIO27__FUNC_DBG_MON_A17 (MTK_PIN_NO(27) | 7) + +#define PINMUX_GPIO28__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) +#define PINMUX_GPIO28__FUNC_SPI6_MI (MTK_PIN_NO(28) | 1) +#define PINMUX_GPIO28__FUNC_IDDIG (MTK_PIN_NO(28) | 3) +#define PINMUX_GPIO28__FUNC_DMIC1_DAT (MTK_PIN_NO(28) | 5) +#define PINMUX_GPIO28__FUNC_CMFLASH0 (MTK_PIN_NO(28) | 6) +#define PINMUX_GPIO28__FUNC_DBG_MON_A18 (MTK_PIN_NO(28) | 7) + +#define PINMUX_GPIO29__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) +#define PINMUX_GPIO29__FUNC_I2SIN2_BCK (MTK_PIN_NO(29) | 1) +#define PINMUX_GPIO29__FUNC_TP_UTXD1_VCORE (MTK_PIN_NO(29) | 2) +#define PINMUX_GPIO29__FUNC_MD_UTXD0 (MTK_PIN_NO(29) | 3) +#define PINMUX_GPIO29__FUNC_SSPM_UTXD_AO_VCORE (MTK_PIN_NO(29) | 4) +#define PINMUX_GPIO29__FUNC_MD32_1_TXD (MTK_PIN_NO(29) | 5) +#define PINMUX_GPIO29__FUNC_CONN_BT_TXD (MTK_PIN_NO(29) | 6) +#define PINMUX_GPIO29__FUNC_PTA_TXD (MTK_PIN_NO(29) | 7) + +#define PINMUX_GPIO30__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) +#define PINMUX_GPIO30__FUNC_I2SIN2_LRCK (MTK_PIN_NO(30) | 1) +#define PINMUX_GPIO30__FUNC_TP_URXD1_VCORE (MTK_PIN_NO(30) | 2) +#define PINMUX_GPIO30__FUNC_MD_URXD0 (MTK_PIN_NO(30) | 3) +#define PINMUX_GPIO30__FUNC_SSPM_URXD_AO_VCORE (MTK_PIN_NO(30) | 4) +#define PINMUX_GPIO30__FUNC_MD32_1_RXD (MTK_PIN_NO(30) | 5) +#define PINMUX_GPIO30__FUNC_PTA_RXD (MTK_PIN_NO(30) | 7) + +#define PINMUX_GPIO31__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) +#define PINMUX_GPIO31__FUNC_I2SOUT2_DO (MTK_PIN_NO(31) | 1) +#define PINMUX_GPIO31__FUNC_TP_UTXD2_VCORE (MTK_PIN_NO(31) | 2) +#define PINMUX_GPIO31__FUNC_MD_UTXD1 (MTK_PIN_NO(31) | 3) +#define PINMUX_GPIO31__FUNC_HFRP_UTXD1 (MTK_PIN_NO(31) | 4) +#define PINMUX_GPIO31__FUNC_MD32_0_TXD (MTK_PIN_NO(31) | 5) +#define PINMUX_GPIO31__FUNC_CONN_WIFI_TXD (MTK_PIN_NO(31) | 6) +#define PINMUX_GPIO31__FUNC_CONN_BGF_UART0_TXD (MTK_PIN_NO(31) | 7) + +#define PINMUX_GPIO32__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) +#define PINMUX_GPIO32__FUNC_I2SIN2_DI (MTK_PIN_NO(32) | 1) +#define PINMUX_GPIO32__FUNC_TP_URXD2_VCORE (MTK_PIN_NO(32) | 2) +#define PINMUX_GPIO32__FUNC_MD_URXD1 (MTK_PIN_NO(32) | 3) +#define PINMUX_GPIO32__FUNC_HFRP_URXD1 (MTK_PIN_NO(32) | 4) +#define PINMUX_GPIO32__FUNC_MD32_0_RXD (MTK_PIN_NO(32) | 5) +#define PINMUX_GPIO32__FUNC_CONN_BGF_UART0_RXD (MTK_PIN_NO(32) | 7) + +#define PINMUX_GPIO33__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) +#define PINMUX_GPIO33__FUNC_ANT_SEL0 (MTK_PIN_NO(33) | 1) +#define PINMUX_GPIO33__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(33) | 3) +#define PINMUX_GPIO33__FUNC_SCL1 (MTK_PIN_NO(33) | 4) +#define PINMUX_GPIO33__FUNC_CONN_BPI_BUS18_ANT1 (MTK_PIN_NO(33) | 5) +#define PINMUX_GPIO33__FUNC_MD_UCTS0 (MTK_PIN_NO(33) | 6) + +#define PINMUX_GPIO34__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) +#define PINMUX_GPIO34__FUNC_ANT_SEL1 (MTK_PIN_NO(34) | 1) +#define PINMUX_GPIO34__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(34) | 3) +#define PINMUX_GPIO34__FUNC_SDA1 (MTK_PIN_NO(34) | 4) +#define PINMUX_GPIO34__FUNC_CONN_BPI_BUS19_ANT2 (MTK_PIN_NO(34) | 5) +#define PINMUX_GPIO34__FUNC_MD_URTS0 (MTK_PIN_NO(34) | 6) + +#define PINMUX_GPIO35__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) +#define PINMUX_GPIO35__FUNC_ANT_SEL2 (MTK_PIN_NO(35) | 1) +#define PINMUX_GPIO35__FUNC_SSPM_JTAG_TCK_VCORE (MTK_PIN_NO(35) | 2) +#define PINMUX_GPIO35__FUNC_UDI_TCK (MTK_PIN_NO(35) | 3) +#define PINMUX_GPIO35__FUNC_CONN_BPI_BUS20_ANT3 (MTK_PIN_NO(35) | 5) +#define PINMUX_GPIO35__FUNC_MD_UCTS1 (MTK_PIN_NO(35) | 6) + +#define PINMUX_GPIO36__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) +#define PINMUX_GPIO36__FUNC_ANT_SEL3 (MTK_PIN_NO(36) | 1) +#define PINMUX_GPIO36__FUNC_SSPM_JTAG_TRSTN_VCORE (MTK_PIN_NO(36) | 2) +#define PINMUX_GPIO36__FUNC_UDI_NTRST (MTK_PIN_NO(36) | 3) +#define PINMUX_GPIO36__FUNC_CONN_BPI_BUS21_ANT4 (MTK_PIN_NO(36) | 5) +#define PINMUX_GPIO36__FUNC_MD_URTS1 (MTK_PIN_NO(36) | 6) + +#define PINMUX_GPIO37__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) +#define PINMUX_GPIO37__FUNC_ANT_SEL4 (MTK_PIN_NO(37) | 1) +#define PINMUX_GPIO37__FUNC_SSPM_JTAG_TDI_VCORE (MTK_PIN_NO(37) | 2) +#define PINMUX_GPIO37__FUNC_UDI_TDI (MTK_PIN_NO(37) | 3) +#define PINMUX_GPIO37__FUNC_TP_UCTS1_VCORE (MTK_PIN_NO(37) | 6) + +#define PINMUX_GPIO38__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) +#define PINMUX_GPIO38__FUNC_ANT_SEL5 (MTK_PIN_NO(38) | 1) +#define PINMUX_GPIO38__FUNC_SSPM_JTAG_TMS_VCORE (MTK_PIN_NO(38) | 2) +#define PINMUX_GPIO38__FUNC_UDI_TMS (MTK_PIN_NO(38) | 3) +#define PINMUX_GPIO38__FUNC_TP_URTS1_VCORE (MTK_PIN_NO(38) | 6) + +#define PINMUX_GPIO39__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) +#define PINMUX_GPIO39__FUNC_ANT_SEL6 (MTK_PIN_NO(39) | 1) +#define PINMUX_GPIO39__FUNC_SSPM_JTAG_TDO_VCORE (MTK_PIN_NO(39) | 2) +#define PINMUX_GPIO39__FUNC_UDI_TDO (MTK_PIN_NO(39) | 3) +#define PINMUX_GPIO39__FUNC_CLKM3 (MTK_PIN_NO(39) | 5) + +#define PINMUX_GPIO40__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) +#define PINMUX_GPIO40__FUNC_ANT_SEL7 (MTK_PIN_NO(40) | 1) +#define PINMUX_GPIO40__FUNC_PMSR_SMAP (MTK_PIN_NO(40) | 2) +#define PINMUX_GPIO40__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(40) | 3) +#define PINMUX_GPIO40__FUNC_CONN_WIFI_TXD (MTK_PIN_NO(40) | 4) +#define PINMUX_GPIO40__FUNC_GPS_PPS (MTK_PIN_NO(40) | 5) + +#define PINMUX_GPIO41__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) +#define PINMUX_GPIO41__FUNC_I2SIN1_MCK (MTK_PIN_NO(41) | 1) +#define PINMUX_GPIO41__FUNC_IDDIG (MTK_PIN_NO(41) | 2) +#define PINMUX_GPIO41__FUNC_GPS_PPS (MTK_PIN_NO(41) | 3) +#define PINMUX_GPIO41__FUNC_HFRP_UCTS1 (MTK_PIN_NO(41) | 4) +#define PINMUX_GPIO41__FUNC_TP_UCTS2_VCORE (MTK_PIN_NO(41) | 5) +#define PINMUX_GPIO41__FUNC_ANT_SEL8 (MTK_PIN_NO(41) | 6) +#define PINMUX_GPIO41__FUNC_DBG_MON_B1 (MTK_PIN_NO(41) | 7) + +#define PINMUX_GPIO42__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) +#define PINMUX_GPIO42__FUNC_I2SIN1_BCK (MTK_PIN_NO(42) | 1) +#define PINMUX_GPIO42__FUNC_I2SIN4_BCK (MTK_PIN_NO(42) | 2) +#define PINMUX_GPIO42__FUNC_HFRP_URTS1 (MTK_PIN_NO(42) | 4) +#define PINMUX_GPIO42__FUNC_TP_URTS2_VCORE (MTK_PIN_NO(42) | 5) +#define PINMUX_GPIO42__FUNC_ANT_SEL9 (MTK_PIN_NO(42) | 6) +#define PINMUX_GPIO42__FUNC_DBG_MON_B2 (MTK_PIN_NO(42) | 7) + +#define PINMUX_GPIO43__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) +#define PINMUX_GPIO43__FUNC_I2SIN1_LRCK (MTK_PIN_NO(43) | 1) +#define PINMUX_GPIO43__FUNC_I2SIN4_LRCK (MTK_PIN_NO(43) | 2) +#define PINMUX_GPIO43__FUNC_ANT_SEL10 (MTK_PIN_NO(43) | 6) +#define PINMUX_GPIO43__FUNC_DBG_MON_B3 (MTK_PIN_NO(43) | 7) + +#define PINMUX_GPIO44__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) +#define PINMUX_GPIO44__FUNC_I2SOUT1_DO (MTK_PIN_NO(44) | 1) +#define PINMUX_GPIO44__FUNC_I2SOUT4_DATA0 (MTK_PIN_NO(44) | 2) +#define PINMUX_GPIO44__FUNC_ANT_SEL11 (MTK_PIN_NO(44) | 6) +#define PINMUX_GPIO44__FUNC_DBG_MON_B4 (MTK_PIN_NO(44) | 7) + +#define PINMUX_GPIO45__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) +#define PINMUX_GPIO45__FUNC_I2SIN1_DI (MTK_PIN_NO(45) | 1) +#define PINMUX_GPIO45__FUNC_I2SIN4_DATA0 (MTK_PIN_NO(45) | 2) +#define PINMUX_GPIO45__FUNC_AGPS_SYNC (MTK_PIN_NO(45) | 5) +#define PINMUX_GPIO45__FUNC_ANT_SEL12 (MTK_PIN_NO(45) | 6) +#define PINMUX_GPIO45__FUNC_DBG_MON_B5 (MTK_PIN_NO(45) | 7) + +#define PINMUX_GPIO46__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) +#define PINMUX_GPIO46__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(46) | 1) +#define PINMUX_GPIO46__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(46) | 2) +#define PINMUX_GPIO46__FUNC_SRCLKENAI0 (MTK_PIN_NO(46) | 3) +#define PINMUX_GPIO46__FUNC_SSPM_UTXD_AO_VLP (MTK_PIN_NO(46) | 5) +#define PINMUX_GPIO46__FUNC_MD_MCIF_UTXD0 (MTK_PIN_NO(46) | 6) +#define PINMUX_GPIO46__FUNC_DBG_MON_B6 (MTK_PIN_NO(46) | 7) + +#define PINMUX_GPIO47__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) +#define PINMUX_GPIO47__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(47) | 1) +#define PINMUX_GPIO47__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(47) | 2) +#define PINMUX_GPIO47__FUNC_SRCLKENAI1 (MTK_PIN_NO(47) | 3) +#define PINMUX_GPIO47__FUNC_SRCLKENA1 (MTK_PIN_NO(47) | 4) +#define PINMUX_GPIO47__FUNC_SSPM_URXD_AO_VLP (MTK_PIN_NO(47) | 5) +#define PINMUX_GPIO47__FUNC_MD_MCIF_URXD0 (MTK_PIN_NO(47) | 6) +#define PINMUX_GPIO47__FUNC_DBG_MON_B7 (MTK_PIN_NO(47) | 7) + +#define PINMUX_GPIO48__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) +#define PINMUX_GPIO48__FUNC_UTXD0 (MTK_PIN_NO(48) | 1) +#define PINMUX_GPIO48__FUNC_MD_UTXD1 (MTK_PIN_NO(48) | 3) +#define PINMUX_GPIO48__FUNC_HFRP_UTXD1 (MTK_PIN_NO(48) | 4) +#define PINMUX_GPIO48__FUNC_MD32_0_TXD (MTK_PIN_NO(48) | 5) + +#define PINMUX_GPIO49__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) +#define PINMUX_GPIO49__FUNC_URXD0 (MTK_PIN_NO(49) | 1) +#define PINMUX_GPIO49__FUNC_MD_URXD1 (MTK_PIN_NO(49) | 3) +#define PINMUX_GPIO49__FUNC_HFRP_URXD1 (MTK_PIN_NO(49) | 4) +#define PINMUX_GPIO49__FUNC_MD32_0_RXD (MTK_PIN_NO(49) | 5) + +#define PINMUX_GPIO50__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) +#define PINMUX_GPIO50__FUNC_MD_UTXD0 (MTK_PIN_NO(50) | 1) +#define PINMUX_GPIO50__FUNC_TP_UTXD1_VLP (MTK_PIN_NO(50) | 2) +#define PINMUX_GPIO50__FUNC_CONN_BGF_UART0_TXD (MTK_PIN_NO(50) | 3) +#define PINMUX_GPIO50__FUNC_SSPM_UTXD_AO_VLP (MTK_PIN_NO(50) | 4) +#define PINMUX_GPIO50__FUNC_MD_MCIF_UTXD0 (MTK_PIN_NO(50) | 5) +#define PINMUX_GPIO50__FUNC_TP_UTXD2_VLP (MTK_PIN_NO(50) | 6) +#define PINMUX_GPIO50__FUNC_UTXD1 (MTK_PIN_NO(50) | 7) + +#define PINMUX_GPIO51__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) +#define PINMUX_GPIO51__FUNC_MD_URXD0 (MTK_PIN_NO(51) | 1) +#define PINMUX_GPIO51__FUNC_TP_URXD1_VLP (MTK_PIN_NO(51) | 2) +#define PINMUX_GPIO51__FUNC_CONN_BGF_UART0_RXD (MTK_PIN_NO(51) | 3) +#define PINMUX_GPIO51__FUNC_SSPM_URXD_AO_VLP (MTK_PIN_NO(51) | 4) +#define PINMUX_GPIO51__FUNC_MD_MCIF_URXD0 (MTK_PIN_NO(51) | 5) +#define PINMUX_GPIO51__FUNC_TP_URXD2_VLP (MTK_PIN_NO(51) | 6) +#define PINMUX_GPIO51__FUNC_URXD1 (MTK_PIN_NO(51) | 7) + +#define PINMUX_GPIO52__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) +#define PINMUX_GPIO52__FUNC_KPROW0 (MTK_PIN_NO(52) | 1) +#define PINMUX_GPIO52__FUNC_CMFLASH0 (MTK_PIN_NO(52) | 2) +#define PINMUX_GPIO52__FUNC_SDA12 (MTK_PIN_NO(52) | 3) +#define PINMUX_GPIO52__FUNC_DSI_TE1 (MTK_PIN_NO(52) | 4) + +#define PINMUX_GPIO53__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) +#define PINMUX_GPIO53__FUNC_KPROW1 (MTK_PIN_NO(53) | 1) +#define PINMUX_GPIO53__FUNC_CMFLASH1 (MTK_PIN_NO(53) | 2) +#define PINMUX_GPIO53__FUNC_SCL12 (MTK_PIN_NO(53) | 3) +#define PINMUX_GPIO53__FUNC_LCM_RST1 (MTK_PIN_NO(53) | 4) +#define PINMUX_GPIO53__FUNC_EXTIF0_ACT (MTK_PIN_NO(53) | 6) + +#define PINMUX_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) +#define PINMUX_GPIO54__FUNC_KPCOL0_VLP (MTK_PIN_NO(54) | 1) +#define PINMUX_GPIO54__FUNC_KPCOL0_VLP_A (MTK_PIN_NO(54) | 7) + +#define PINMUX_GPIO55__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) +#define PINMUX_GPIO55__FUNC_KPCOL1 (MTK_PIN_NO(55) | 1) +#define PINMUX_GPIO55__FUNC_SDA12 (MTK_PIN_NO(55) | 3) +#define PINMUX_GPIO55__FUNC_DISP_PWM1 (MTK_PIN_NO(55) | 4) +#define PINMUX_GPIO55__FUNC_JTRSTN_SEL1_VCORE (MTK_PIN_NO(55) | 7) + +#define PINMUX_GPIO56__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) +#define PINMUX_GPIO56__FUNC_SPI0_CLK (MTK_PIN_NO(56) | 1) +#define PINMUX_GPIO56__FUNC_JTCK_SEL1_VCORE (MTK_PIN_NO(56) | 7) + +#define PINMUX_GPIO57__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define PINMUX_GPIO57__FUNC_SPI0_CSB (MTK_PIN_NO(57) | 1) +#define PINMUX_GPIO57__FUNC_JTMS_SEL1_VCORE (MTK_PIN_NO(57) | 7) + +#define PINMUX_GPIO58__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define PINMUX_GPIO58__FUNC_SPI0_MO (MTK_PIN_NO(58) | 1) +#define PINMUX_GPIO58__FUNC_JTDO_SEL1_VCORE (MTK_PIN_NO(58) | 7) + +#define PINMUX_GPIO59__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) +#define PINMUX_GPIO59__FUNC_SPI0_MI (MTK_PIN_NO(59) | 1) +#define PINMUX_GPIO59__FUNC_JTDI_SEL1_VCORE (MTK_PIN_NO(59) | 7) + +#define PINMUX_GPIO60__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) +#define PINMUX_GPIO60__FUNC_SCP_SPI1_CK (MTK_PIN_NO(60) | 1) +#define PINMUX_GPIO60__FUNC_SPI1_CLK (MTK_PIN_NO(60) | 2) +#define PINMUX_GPIO60__FUNC_SCP_SCL3 (MTK_PIN_NO(60) | 4) +#define PINMUX_GPIO60__FUNC_TP_GPIO0_AO (MTK_PIN_NO(60) | 5) +#define PINMUX_GPIO60__FUNC_UTXD0 (MTK_PIN_NO(60) | 6) +#define PINMUX_GPIO60__FUNC_TP_UTXD2_VLP (MTK_PIN_NO(60) | 7) + +#define PINMUX_GPIO61__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) +#define PINMUX_GPIO61__FUNC_SCP_SPI1_CS (MTK_PIN_NO(61) | 1) +#define PINMUX_GPIO61__FUNC_SPI1_CSB (MTK_PIN_NO(61) | 2) +#define PINMUX_GPIO61__FUNC_TP_GPIO1_AO (MTK_PIN_NO(61) | 5) +#define PINMUX_GPIO61__FUNC_URXD0 (MTK_PIN_NO(61) | 6) +#define PINMUX_GPIO61__FUNC_TP_URXD2_VLP (MTK_PIN_NO(61) | 7) + +#define PINMUX_GPIO62__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) +#define PINMUX_GPIO62__FUNC_SCP_SPI1_MO (MTK_PIN_NO(62) | 1) +#define PINMUX_GPIO62__FUNC_SPI1_MO (MTK_PIN_NO(62) | 2) +#define PINMUX_GPIO62__FUNC_SCP_SCL3 (MTK_PIN_NO(62) | 3) +#define PINMUX_GPIO62__FUNC_SCP_SDA3 (MTK_PIN_NO(62) | 4) +#define PINMUX_GPIO62__FUNC_TP_GPIO2_AO (MTK_PIN_NO(62) | 5) +#define PINMUX_GPIO62__FUNC_DBG_MON_B29 (MTK_PIN_NO(62) | 7) + +#define PINMUX_GPIO63__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) +#define PINMUX_GPIO63__FUNC_SCP_SPI1_MI (MTK_PIN_NO(63) | 1) +#define PINMUX_GPIO63__FUNC_SPI1_MI (MTK_PIN_NO(63) | 2) +#define PINMUX_GPIO63__FUNC_SCP_SDA3 (MTK_PIN_NO(63) | 3) +#define PINMUX_GPIO63__FUNC_TP_GPIO3_AO (MTK_PIN_NO(63) | 5) +#define PINMUX_GPIO63__FUNC_DBG_MON_B30 (MTK_PIN_NO(63) | 7) + +#define PINMUX_GPIO64__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) +#define PINMUX_GPIO64__FUNC_SCP_SPI2_CK (MTK_PIN_NO(64) | 1) +#define PINMUX_GPIO64__FUNC_SPI2_CLK (MTK_PIN_NO(64) | 2) +#define PINMUX_GPIO64__FUNC_SCP_SCL2 (MTK_PIN_NO(64) | 4) +#define PINMUX_GPIO64__FUNC_TP_GPIO4_AO (MTK_PIN_NO(64) | 5) + +#define PINMUX_GPIO65__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) +#define PINMUX_GPIO65__FUNC_SCP_SPI2_CS (MTK_PIN_NO(65) | 1) +#define PINMUX_GPIO65__FUNC_SPI2_CSB (MTK_PIN_NO(65) | 2) +#define PINMUX_GPIO65__FUNC_TP_GPIO5_AO (MTK_PIN_NO(65) | 5) +#define PINMUX_GPIO65__FUNC_DBG_MON_B31 (MTK_PIN_NO(65) | 7) + +#define PINMUX_GPIO66__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) +#define PINMUX_GPIO66__FUNC_SCP_SPI2_MO (MTK_PIN_NO(66) | 1) +#define PINMUX_GPIO66__FUNC_SPI2_MO (MTK_PIN_NO(66) | 2) +#define PINMUX_GPIO66__FUNC_SCP_SCL2 (MTK_PIN_NO(66) | 3) +#define PINMUX_GPIO66__FUNC_SCP_SDA2 (MTK_PIN_NO(66) | 4) +#define PINMUX_GPIO66__FUNC_TP_GPIO6_AO (MTK_PIN_NO(66) | 5) + +#define PINMUX_GPIO67__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) +#define PINMUX_GPIO67__FUNC_SCP_SPI2_MI (MTK_PIN_NO(67) | 1) +#define PINMUX_GPIO67__FUNC_SPI2_MI (MTK_PIN_NO(67) | 2) +#define PINMUX_GPIO67__FUNC_SCP_SDA2 (MTK_PIN_NO(67) | 3) +#define PINMUX_GPIO67__FUNC_TP_GPIO7_AO (MTK_PIN_NO(67) | 5) + +#define PINMUX_GPIO68__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) +#define PINMUX_GPIO68__FUNC_SCP_SPI3_CK (MTK_PIN_NO(68) | 1) +#define PINMUX_GPIO68__FUNC_SPI3_CLK (MTK_PIN_NO(68) | 2) +#define PINMUX_GPIO68__FUNC_MD_INT4 (MTK_PIN_NO(68) | 3) +#define PINMUX_GPIO68__FUNC_SCP_SCL4 (MTK_PIN_NO(68) | 4) +#define PINMUX_GPIO68__FUNC_TP_GPIO8_AO (MTK_PIN_NO(68) | 5) +#define PINMUX_GPIO68__FUNC_DBG_MON_A19 (MTK_PIN_NO(68) | 7) + +#define PINMUX_GPIO69__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) +#define PINMUX_GPIO69__FUNC_SCP_SPI3_CS (MTK_PIN_NO(69) | 1) +#define PINMUX_GPIO69__FUNC_SPI3_CSB (MTK_PIN_NO(69) | 2) +#define PINMUX_GPIO69__FUNC_MD_INT3 (MTK_PIN_NO(69) | 3) +#define PINMUX_GPIO69__FUNC_TP_GPIO9_AO (MTK_PIN_NO(69) | 5) +#define PINMUX_GPIO69__FUNC_DBG_MON_A20 (MTK_PIN_NO(69) | 7) + +#define PINMUX_GPIO70__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) +#define PINMUX_GPIO70__FUNC_SCP_SPI3_MO (MTK_PIN_NO(70) | 1) +#define PINMUX_GPIO70__FUNC_SPI3_MO (MTK_PIN_NO(70) | 2) +#define PINMUX_GPIO70__FUNC_SCP_SCL4 (MTK_PIN_NO(70) | 3) +#define PINMUX_GPIO70__FUNC_SCP_SDA4 (MTK_PIN_NO(70) | 4) +#define PINMUX_GPIO70__FUNC_TP_GPIO10_AO (MTK_PIN_NO(70) | 5) +#define PINMUX_GPIO70__FUNC_DBG_MON_A21 (MTK_PIN_NO(70) | 7) + +#define PINMUX_GPIO71__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) +#define PINMUX_GPIO71__FUNC_SCP_SPI3_MI (MTK_PIN_NO(71) | 1) +#define PINMUX_GPIO71__FUNC_SPI3_MI (MTK_PIN_NO(71) | 2) +#define PINMUX_GPIO71__FUNC_SCP_SDA4 (MTK_PIN_NO(71) | 3) +#define PINMUX_GPIO71__FUNC_MD_INT0 (MTK_PIN_NO(71) | 4) +#define PINMUX_GPIO71__FUNC_TP_GPIO11_AO (MTK_PIN_NO(71) | 5) +#define PINMUX_GPIO71__FUNC_DBG_MON_A22 (MTK_PIN_NO(71) | 7) + +#define PINMUX_GPIO72__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) +#define PINMUX_GPIO72__FUNC_SPI5_CLK (MTK_PIN_NO(72) | 1) +#define PINMUX_GPIO72__FUNC_SCP_SPI0_CK (MTK_PIN_NO(72) | 2) +#define PINMUX_GPIO72__FUNC_UCTS2 (MTK_PIN_NO(72) | 3) +#define PINMUX_GPIO72__FUNC_MBISTREADEN_TRIGGER (MTK_PIN_NO(72) | 4) +#define PINMUX_GPIO72__FUNC_TP_GPIO12_AO (MTK_PIN_NO(72) | 5) +#define PINMUX_GPIO72__FUNC_EXTIF0_ACT (MTK_PIN_NO(72) | 6) +#define PINMUX_GPIO72__FUNC_DAP_SONIC_SWCK (MTK_PIN_NO(72) | 7) + +#define PINMUX_GPIO73__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) +#define PINMUX_GPIO73__FUNC_SPI5_CSB (MTK_PIN_NO(73) | 1) +#define PINMUX_GPIO73__FUNC_SCP_SPI0_CS (MTK_PIN_NO(73) | 2) +#define PINMUX_GPIO73__FUNC_URTS2 (MTK_PIN_NO(73) | 3) +#define PINMUX_GPIO73__FUNC_MBISTWRITEEN_TRIGGER (MTK_PIN_NO(73) | 4) +#define PINMUX_GPIO73__FUNC_TP_GPIO13_AO (MTK_PIN_NO(73) | 5) +#define PINMUX_GPIO73__FUNC_EXTIF0_PRI (MTK_PIN_NO(73) | 6) +#define PINMUX_GPIO73__FUNC_DAP_SONIC_SWD (MTK_PIN_NO(73) | 7) + +#define PINMUX_GPIO74__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) +#define PINMUX_GPIO74__FUNC_SPI5_MO (MTK_PIN_NO(74) | 1) +#define PINMUX_GPIO74__FUNC_SCP_SPI0_MO (MTK_PIN_NO(74) | 2) +#define PINMUX_GPIO74__FUNC_UTXD2 (MTK_PIN_NO(74) | 3) +#define PINMUX_GPIO74__FUNC_TP_UTXD2_VCORE (MTK_PIN_NO(74) | 4) +#define PINMUX_GPIO74__FUNC_TP_GPIO14_AO (MTK_PIN_NO(74) | 5) +#define PINMUX_GPIO74__FUNC_EXTIF0_GNT_B (MTK_PIN_NO(74) | 6) +#define PINMUX_GPIO74__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(74) | 7) + +#define PINMUX_GPIO75__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) +#define PINMUX_GPIO75__FUNC_SPI5_MI (MTK_PIN_NO(75) | 1) +#define PINMUX_GPIO75__FUNC_SCP_SPI0_MI (MTK_PIN_NO(75) | 2) +#define PINMUX_GPIO75__FUNC_URXD2 (MTK_PIN_NO(75) | 3) +#define PINMUX_GPIO75__FUNC_TP_URXD2_VCORE (MTK_PIN_NO(75) | 4) +#define PINMUX_GPIO75__FUNC_TP_GPIO15_AO (MTK_PIN_NO(75) | 5) +#define PINMUX_GPIO75__FUNC_DAP_MD32_SWD (MTK_PIN_NO(75) | 7) + +#define PINMUX_GPIO76__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) +#define PINMUX_GPIO76__FUNC_AP_GOOD (MTK_PIN_NO(76) | 1) +#define PINMUX_GPIO76__FUNC_CONN_WIFI_TXD (MTK_PIN_NO(76) | 3) +#define PINMUX_GPIO76__FUNC_GPS_PPS (MTK_PIN_NO(76) | 4) +#define PINMUX_GPIO76__FUNC_PMSR_SMAP (MTK_PIN_NO(76) | 5) +#define PINMUX_GPIO76__FUNC_AGPS_SYNC (MTK_PIN_NO(76) | 6) + +#define PINMUX_GPIO77__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) +#define PINMUX_GPIO77__FUNC_MSDC1_CLK (MTK_PIN_NO(77) | 1) +#define PINMUX_GPIO77__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(77) | 2) +#define PINMUX_GPIO77__FUNC_UDI_TCK (MTK_PIN_NO(77) | 3) +#define PINMUX_GPIO77__FUNC_CONN_DSP_JCK (MTK_PIN_NO(77) | 4) +#define PINMUX_GPIO77__FUNC_TSFDC_EN (MTK_PIN_NO(77) | 6) +#define PINMUX_GPIO77__FUNC_SSPM_JTAG_TCK_VCORE (MTK_PIN_NO(77) | 7) + +#define PINMUX_GPIO78__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) +#define PINMUX_GPIO78__FUNC_MSDC1_CMD (MTK_PIN_NO(78) | 1) +#define PINMUX_GPIO78__FUNC_CONN_WF_MCU_AICE_TMSC (MTK_PIN_NO(78) | 2) +#define PINMUX_GPIO78__FUNC_UDI_TMS (MTK_PIN_NO(78) | 3) +#define PINMUX_GPIO78__FUNC_CONN_DSP_JMS (MTK_PIN_NO(78) | 4) +#define PINMUX_GPIO78__FUNC_TSFDC_VCO_RST (MTK_PIN_NO(78) | 6) +#define PINMUX_GPIO78__FUNC_SSPM_JTAG_TMS_VCORE (MTK_PIN_NO(78) | 7) + +#define PINMUX_GPIO79__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) +#define PINMUX_GPIO79__FUNC_MSDC1_DAT0 (MTK_PIN_NO(79) | 1) +#define PINMUX_GPIO79__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(79) | 2) +#define PINMUX_GPIO79__FUNC_UDI_TDI (MTK_PIN_NO(79) | 3) +#define PINMUX_GPIO79__FUNC_CONN_DSP_JDI (MTK_PIN_NO(79) | 4) +#define PINMUX_GPIO79__FUNC_TSFDC_TSSEL2 (MTK_PIN_NO(79) | 6) +#define PINMUX_GPIO79__FUNC_SSPM_JTAG_TDI_VCORE (MTK_PIN_NO(79) | 7) + +#define PINMUX_GPIO80__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) +#define PINMUX_GPIO80__FUNC_MSDC1_DAT1 (MTK_PIN_NO(80) | 1) +#define PINMUX_GPIO80__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(80) | 2) +#define PINMUX_GPIO80__FUNC_UDI_TDO (MTK_PIN_NO(80) | 3) +#define PINMUX_GPIO80__FUNC_CONN_DSP_JDO (MTK_PIN_NO(80) | 4) +#define PINMUX_GPIO80__FUNC_TSFDC_TSSEL1 (MTK_PIN_NO(80) | 6) +#define PINMUX_GPIO80__FUNC_SSPM_JTAG_TDO_VCORE (MTK_PIN_NO(80) | 7) + +#define PINMUX_GPIO81__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) +#define PINMUX_GPIO81__FUNC_MSDC1_DAT2 (MTK_PIN_NO(81) | 1) +#define PINMUX_GPIO81__FUNC_CONN_WF_MCU_AICE_TCKC (MTK_PIN_NO(81) | 2) +#define PINMUX_GPIO81__FUNC_UDI_NTRST (MTK_PIN_NO(81) | 3) +#define PINMUX_GPIO81__FUNC_CONN_BGF_MCU_AICE_TCKC (MTK_PIN_NO(81) | 4) +#define PINMUX_GPIO81__FUNC_MIPI3_D_SDATA (MTK_PIN_NO(81) | 5) +#define PINMUX_GPIO81__FUNC_TSFDC_TSSEL0 (MTK_PIN_NO(81) | 6) +#define PINMUX_GPIO81__FUNC_SSPM_JTAG_TRSTN_VCORE (MTK_PIN_NO(81) | 7) + +#define PINMUX_GPIO82__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) +#define PINMUX_GPIO82__FUNC_MSDC1_DAT3 (MTK_PIN_NO(82) | 1) +#define PINMUX_GPIO82__FUNC_CONN_BGF_MCU_AICE_TMSC (MTK_PIN_NO(82) | 3) +#define PINMUX_GPIO82__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(82) | 4) +#define PINMUX_GPIO82__FUNC_MIPI3_D_SCLK (MTK_PIN_NO(82) | 5) +#define PINMUX_GPIO82__FUNC_TSFDC_RCK_SELB (MTK_PIN_NO(82) | 6) + +#define PINMUX_GPIO83__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) +#define PINMUX_GPIO83__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(83) | 1) +#define PINMUX_GPIO83__FUNC_TSFDC_26M (MTK_PIN_NO(83) | 6) + +#define PINMUX_GPIO84__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) +#define PINMUX_GPIO84__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(84) | 1) +#define PINMUX_GPIO84__FUNC_SPM_JTAG_TCK_VCORE (MTK_PIN_NO(84) | 3) +#define PINMUX_GPIO84__FUNC_APU_JTAG_TCK (MTK_PIN_NO(84) | 4) +#define PINMUX_GPIO84__FUNC_TSFDC_SDO (MTK_PIN_NO(84) | 6) +#define PINMUX_GPIO84__FUNC_CONN_DSP_L5_JCK (MTK_PIN_NO(84) | 7) + +#define PINMUX_GPIO85__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) +#define PINMUX_GPIO85__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(85) | 1) +#define PINMUX_GPIO85__FUNC_SPM_JTAG_TRSTN_VCORE (MTK_PIN_NO(85) | 3) +#define PINMUX_GPIO85__FUNC_APU_JTAG_TRST (MTK_PIN_NO(85) | 4) +#define PINMUX_GPIO85__FUNC_TSFDC_FOUT (MTK_PIN_NO(85) | 6) +#define PINMUX_GPIO85__FUNC_CONN_DSP_L5_JINTP (MTK_PIN_NO(85) | 7) + +#define PINMUX_GPIO86__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) +#define PINMUX_GPIO86__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(86) | 1) +#define PINMUX_GPIO86__FUNC_SPM_JTAG_TDI_VCORE (MTK_PIN_NO(86) | 3) +#define PINMUX_GPIO86__FUNC_APU_JTAG_TDI (MTK_PIN_NO(86) | 4) +#define PINMUX_GPIO86__FUNC_TSFDC_SCK (MTK_PIN_NO(86) | 6) +#define PINMUX_GPIO86__FUNC_CONN_DSP_L5_JDI (MTK_PIN_NO(86) | 7) + +#define PINMUX_GPIO87__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) +#define PINMUX_GPIO87__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(87) | 1) +#define PINMUX_GPIO87__FUNC_SPM_JTAG_TMS_VCORE (MTK_PIN_NO(87) | 3) +#define PINMUX_GPIO87__FUNC_APU_JTAG_TMS (MTK_PIN_NO(87) | 4) +#define PINMUX_GPIO87__FUNC_TSFDC_SDI (MTK_PIN_NO(87) | 6) +#define PINMUX_GPIO87__FUNC_CONN_DSP_L5_JMS (MTK_PIN_NO(87) | 7) + +#define PINMUX_GPIO88__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) +#define PINMUX_GPIO88__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(88) | 1) +#define PINMUX_GPIO88__FUNC_SPM_JTAG_TDO_VCORE (MTK_PIN_NO(88) | 3) +#define PINMUX_GPIO88__FUNC_APU_JTAG_TDO (MTK_PIN_NO(88) | 4) +#define PINMUX_GPIO88__FUNC_TSFDC_SCF (MTK_PIN_NO(88) | 6) +#define PINMUX_GPIO88__FUNC_CONN_DSP_L5_JDO (MTK_PIN_NO(88) | 7) + +#define PINMUX_GPIO89__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) +#define PINMUX_GPIO89__FUNC_DSI_TE (MTK_PIN_NO(89) | 1) +#define PINMUX_GPIO89__FUNC_DBG_MON_B8 (MTK_PIN_NO(89) | 7) + +#define PINMUX_GPIO90__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) +#define PINMUX_GPIO90__FUNC_LCM_RST (MTK_PIN_NO(90) | 1) +#define PINMUX_GPIO90__FUNC_DBG_MON_B9 (MTK_PIN_NO(90) | 7) + +#define PINMUX_GPIO91__FUNC_GPIO91 (MTK_PIN_NO(91) | 0) +#define PINMUX_GPIO91__FUNC_DISP_PWM (MTK_PIN_NO(91) | 1) +#define PINMUX_GPIO91__FUNC_DBG_MON_B10 (MTK_PIN_NO(91) | 7) + +#define PINMUX_GPIO92__FUNC_GPIO92 (MTK_PIN_NO(92) | 0) +#define PINMUX_GPIO92__FUNC_CMMCLK0 (MTK_PIN_NO(92) | 1) +#define PINMUX_GPIO92__FUNC_DBG_MON_A23 (MTK_PIN_NO(92) | 7) + +#define PINMUX_GPIO93__FUNC_GPIO93 (MTK_PIN_NO(93) | 0) +#define PINMUX_GPIO93__FUNC_CMMCLK1 (MTK_PIN_NO(93) | 1) +#define PINMUX_GPIO93__FUNC_DBG_MON_A24 (MTK_PIN_NO(93) | 7) + +#define PINMUX_GPIO94__FUNC_GPIO94 (MTK_PIN_NO(94) | 0) +#define PINMUX_GPIO94__FUNC_CMMCLK2 (MTK_PIN_NO(94) | 1) +#define PINMUX_GPIO94__FUNC_DBG_MON_A25 (MTK_PIN_NO(94) | 7) + +#define PINMUX_GPIO95__FUNC_GPIO95 (MTK_PIN_NO(95) | 0) +#define PINMUX_GPIO95__FUNC_CMMCLK3 (MTK_PIN_NO(95) | 1) +#define PINMUX_GPIO95__FUNC_MD32_1_TXD (MTK_PIN_NO(95) | 5) +#define PINMUX_GPIO95__FUNC_PTA_TXD (MTK_PIN_NO(95) | 6) +#define PINMUX_GPIO95__FUNC_DBG_MON_A26 (MTK_PIN_NO(95) | 7) + +#define PINMUX_GPIO96__FUNC_GPIO96 (MTK_PIN_NO(96) | 0) +#define PINMUX_GPIO96__FUNC_CMMCLK4 (MTK_PIN_NO(96) | 1) +#define PINMUX_GPIO96__FUNC_MD32_1_RXD (MTK_PIN_NO(96) | 5) +#define PINMUX_GPIO96__FUNC_PTA_RXD (MTK_PIN_NO(96) | 6) +#define PINMUX_GPIO96__FUNC_DBG_MON_A27 (MTK_PIN_NO(96) | 7) + +#define PINMUX_GPIO97__FUNC_GPIO97 (MTK_PIN_NO(97) | 0) +#define PINMUX_GPIO97__FUNC_MD_UCNT_A_TGL (MTK_PIN_NO(97) | 1) + +#define PINMUX_GPIO98__FUNC_GPIO98 (MTK_PIN_NO(98) | 0) +#define PINMUX_GPIO98__FUNC_DIGRF_IRQ (MTK_PIN_NO(98) | 1) + +#define PINMUX_GPIO99__FUNC_GPIO99 (MTK_PIN_NO(99) | 0) +#define PINMUX_GPIO99__FUNC_BPI_BUS0 (MTK_PIN_NO(99) | 1) +#define PINMUX_GPIO99__FUNC_MFG_TSFDC_EN (MTK_PIN_NO(99) | 4) +#define PINMUX_GPIO99__FUNC_ANT_SEL0 (MTK_PIN_NO(99) | 6) +#define PINMUX_GPIO99__FUNC_DBG_MON_B11 (MTK_PIN_NO(99) | 7) + +#define PINMUX_GPIO100__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) +#define PINMUX_GPIO100__FUNC_BPI_BUS1 (MTK_PIN_NO(100) | 1) +#define PINMUX_GPIO100__FUNC_MFG_TSFDC_VCO_RST (MTK_PIN_NO(100) | 4) +#define PINMUX_GPIO100__FUNC_ANT_SEL1 (MTK_PIN_NO(100) | 6) +#define PINMUX_GPIO100__FUNC_DBG_MON_B12 (MTK_PIN_NO(100) | 7) + +#define PINMUX_GPIO101__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) +#define PINMUX_GPIO101__FUNC_BPI_BUS2 (MTK_PIN_NO(101) | 1) +#define PINMUX_GPIO101__FUNC_DMIC1_CLK (MTK_PIN_NO(101) | 3) +#define PINMUX_GPIO101__FUNC_MFG_TSFDC_TSSEL2 (MTK_PIN_NO(101) | 4) +#define PINMUX_GPIO101__FUNC_ANT_SEL2 (MTK_PIN_NO(101) | 6) +#define PINMUX_GPIO101__FUNC_DBG_MON_B13 (MTK_PIN_NO(101) | 7) + +#define PINMUX_GPIO102__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) +#define PINMUX_GPIO102__FUNC_BPI_BUS3 (MTK_PIN_NO(102) | 1) +#define PINMUX_GPIO102__FUNC_DMIC1_DAT (MTK_PIN_NO(102) | 3) +#define PINMUX_GPIO102__FUNC_MFG_TSFDC_TSSEL1 (MTK_PIN_NO(102) | 4) +#define PINMUX_GPIO102__FUNC_ANT_SEL3 (MTK_PIN_NO(102) | 6) +#define PINMUX_GPIO102__FUNC_DBG_MON_B14 (MTK_PIN_NO(102) | 7) + +#define PINMUX_GPIO103__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) +#define PINMUX_GPIO103__FUNC_BPI_BUS4 (MTK_PIN_NO(103) | 1) +#define PINMUX_GPIO103__FUNC_MFG_TSFDC_TSSEL0 (MTK_PIN_NO(103) | 4) +#define PINMUX_GPIO103__FUNC_ANT_SEL4 (MTK_PIN_NO(103) | 6) +#define PINMUX_GPIO103__FUNC_DBG_MON_B15 (MTK_PIN_NO(103) | 7) + +#define PINMUX_GPIO104__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) +#define PINMUX_GPIO104__FUNC_BPI_BUS5 (MTK_PIN_NO(104) | 1) +#define PINMUX_GPIO104__FUNC_MFG_TSFDC_RCK_SELB (MTK_PIN_NO(104) | 4) +#define PINMUX_GPIO104__FUNC_ANT_SEL5 (MTK_PIN_NO(104) | 6) +#define PINMUX_GPIO104__FUNC_DBG_MON_B16 (MTK_PIN_NO(104) | 7) + +#define PINMUX_GPIO105__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) +#define PINMUX_GPIO105__FUNC_BPI_BUS6 (MTK_PIN_NO(105) | 1) +#define PINMUX_GPIO105__FUNC_CONN_BPI_BUS6 (MTK_PIN_NO(105) | 2) +#define PINMUX_GPIO105__FUNC_ANT_SEL6 (MTK_PIN_NO(105) | 6) +#define PINMUX_GPIO105__FUNC_DBG_MON_B17 (MTK_PIN_NO(105) | 7) + +#define PINMUX_GPIO106__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) +#define PINMUX_GPIO106__FUNC_BPI_BUS7 (MTK_PIN_NO(106) | 1) +#define PINMUX_GPIO106__FUNC_CONN_BPI_BUS7 (MTK_PIN_NO(106) | 2) +#define PINMUX_GPIO106__FUNC_MFG_TSFDC_SDO (MTK_PIN_NO(106) | 4) +#define PINMUX_GPIO106__FUNC_AUD_DAC_26M_CLK (MTK_PIN_NO(106) | 5) +#define PINMUX_GPIO106__FUNC_ANT_SEL7 (MTK_PIN_NO(106) | 6) +#define PINMUX_GPIO106__FUNC_DBG_MON_B18 (MTK_PIN_NO(106) | 7) + +#define PINMUX_GPIO107__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) +#define PINMUX_GPIO107__FUNC_BPI_BUS8 (MTK_PIN_NO(107) | 1) +#define PINMUX_GPIO107__FUNC_CONN_BPI_BUS8 (MTK_PIN_NO(107) | 2) +#define PINMUX_GPIO107__FUNC_MFG_TSFDC_FOUT (MTK_PIN_NO(107) | 4) +#define PINMUX_GPIO107__FUNC_I2SOUT4_DATA0 (MTK_PIN_NO(107) | 5) +#define PINMUX_GPIO107__FUNC_ANT_SEL8 (MTK_PIN_NO(107) | 6) +#define PINMUX_GPIO107__FUNC_DBG_MON_B19 (MTK_PIN_NO(107) | 7) + +#define PINMUX_GPIO108__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) +#define PINMUX_GPIO108__FUNC_BPI_BUS9 (MTK_PIN_NO(108) | 1) +#define PINMUX_GPIO108__FUNC_CONN_BPI_BUS9 (MTK_PIN_NO(108) | 2) +#define PINMUX_GPIO108__FUNC_I2SOUT4_DATA1 (MTK_PIN_NO(108) | 5) +#define PINMUX_GPIO108__FUNC_ANT_SEL9 (MTK_PIN_NO(108) | 6) +#define PINMUX_GPIO108__FUNC_DBG_MON_B20 (MTK_PIN_NO(108) | 7) + +#define PINMUX_GPIO109__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) +#define PINMUX_GPIO109__FUNC_BPI_BUS10 (MTK_PIN_NO(109) | 1) +#define PINMUX_GPIO109__FUNC_CONN_BPI_BUS10 (MTK_PIN_NO(109) | 2) +#define PINMUX_GPIO109__FUNC_I2SOUT4_DATA2 (MTK_PIN_NO(109) | 5) +#define PINMUX_GPIO109__FUNC_ANT_SEL10 (MTK_PIN_NO(109) | 6) +#define PINMUX_GPIO109__FUNC_DBG_MON_B21 (MTK_PIN_NO(109) | 7) + +#define PINMUX_GPIO110__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) +#define PINMUX_GPIO110__FUNC_BPI_BUS11 (MTK_PIN_NO(110) | 1) +#define PINMUX_GPIO110__FUNC_CONN_BPI_BUS11_OLAT0 (MTK_PIN_NO(110) | 2) +#define PINMUX_GPIO110__FUNC_I2SOUT4_DATA3 (MTK_PIN_NO(110) | 5) +#define PINMUX_GPIO110__FUNC_ANT_SEL11 (MTK_PIN_NO(110) | 6) +#define PINMUX_GPIO110__FUNC_DBG_MON_B22 (MTK_PIN_NO(110) | 7) + +#define PINMUX_GPIO111__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) +#define PINMUX_GPIO111__FUNC_BPI_BUS12 (MTK_PIN_NO(111) | 1) +#define PINMUX_GPIO111__FUNC_CONN_BPI_BUS12_OLAT1 (MTK_PIN_NO(111) | 2) +#define PINMUX_GPIO111__FUNC_CLKM0 (MTK_PIN_NO(111) | 3) +#define PINMUX_GPIO111__FUNC_I2SIN4_BCK (MTK_PIN_NO(111) | 5) +#define PINMUX_GPIO111__FUNC_ANT_SEL12 (MTK_PIN_NO(111) | 6) +#define PINMUX_GPIO111__FUNC_DBG_MON_B23 (MTK_PIN_NO(111) | 7) + +#define PINMUX_GPIO112__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) +#define PINMUX_GPIO112__FUNC_BPI_BUS13 (MTK_PIN_NO(112) | 1) +#define PINMUX_GPIO112__FUNC_CONN_BPI_BUS13_OLAT2 (MTK_PIN_NO(112) | 2) +#define PINMUX_GPIO112__FUNC_CLKM1 (MTK_PIN_NO(112) | 3) +#define PINMUX_GPIO112__FUNC_I2SIN4_DATA0 (MTK_PIN_NO(112) | 5) +#define PINMUX_GPIO112__FUNC_ANT_SEL13 (MTK_PIN_NO(112) | 6) +#define PINMUX_GPIO112__FUNC_DBG_MON_B24 (MTK_PIN_NO(112) | 7) + +#define PINMUX_GPIO113__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) +#define PINMUX_GPIO113__FUNC_BPI_BUS14 (MTK_PIN_NO(113) | 1) +#define PINMUX_GPIO113__FUNC_CONN_BPI_BUS14_OLAT3 (MTK_PIN_NO(113) | 2) +#define PINMUX_GPIO113__FUNC_CLKM2 (MTK_PIN_NO(113) | 3) +#define PINMUX_GPIO113__FUNC_I2SIN4_DATA1 (MTK_PIN_NO(113) | 5) +#define PINMUX_GPIO113__FUNC_ANT_SEL14 (MTK_PIN_NO(113) | 6) +#define PINMUX_GPIO113__FUNC_DBG_MON_B25 (MTK_PIN_NO(113) | 7) + +#define PINMUX_GPIO114__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) +#define PINMUX_GPIO114__FUNC_BPI_BUS15 (MTK_PIN_NO(114) | 1) +#define PINMUX_GPIO114__FUNC_CONN_BPI_BUS15_OLAT4 (MTK_PIN_NO(114) | 2) +#define PINMUX_GPIO114__FUNC_CLKM3 (MTK_PIN_NO(114) | 3) +#define PINMUX_GPIO114__FUNC_I2SIN4_DATA2 (MTK_PIN_NO(114) | 5) +#define PINMUX_GPIO114__FUNC_ANT_SEL15 (MTK_PIN_NO(114) | 6) +#define PINMUX_GPIO114__FUNC_DBG_MON_B26 (MTK_PIN_NO(114) | 7) + +#define PINMUX_GPIO115__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) +#define PINMUX_GPIO115__FUNC_BPI_BUS16 (MTK_PIN_NO(115) | 1) +#define PINMUX_GPIO115__FUNC_CONN_BPI_BUS16_OLAT5 (MTK_PIN_NO(115) | 2) +#define PINMUX_GPIO115__FUNC_I2SIN4_DATA3 (MTK_PIN_NO(115) | 5) +#define PINMUX_GPIO115__FUNC_ANT_SEL16 (MTK_PIN_NO(115) | 6) +#define PINMUX_GPIO115__FUNC_DBG_MON_B27 (MTK_PIN_NO(115) | 7) + +#define PINMUX_GPIO116__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) +#define PINMUX_GPIO116__FUNC_BPI_BUS17 (MTK_PIN_NO(116) | 1) +#define PINMUX_GPIO116__FUNC_CONN_BPI_BUS17_ANT0 (MTK_PIN_NO(116) | 2) +#define PINMUX_GPIO116__FUNC_I2SIN4_LRCK (MTK_PIN_NO(116) | 5) +#define PINMUX_GPIO116__FUNC_ANT_SEL17 (MTK_PIN_NO(116) | 6) +#define PINMUX_GPIO116__FUNC_DBG_MON_B28 (MTK_PIN_NO(116) | 7) + +#define PINMUX_GPIO117__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) +#define PINMUX_GPIO117__FUNC_MIPI0_D_SCLK (MTK_PIN_NO(117) | 1) +#define PINMUX_GPIO117__FUNC_CONN_MIPI0_SCLK (MTK_PIN_NO(117) | 2) +#define PINMUX_GPIO117__FUNC_BPI_BUS18 (MTK_PIN_NO(117) | 3) +#define PINMUX_GPIO117__FUNC_ANT_SEL18 (MTK_PIN_NO(117) | 6) + +#define PINMUX_GPIO118__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) +#define PINMUX_GPIO118__FUNC_MIPI0_D_SDATA (MTK_PIN_NO(118) | 1) +#define PINMUX_GPIO118__FUNC_CONN_MIPI0_SDATA (MTK_PIN_NO(118) | 2) +#define PINMUX_GPIO118__FUNC_BPI_BUS19 (MTK_PIN_NO(118) | 3) +#define PINMUX_GPIO118__FUNC_ANT_SEL19 (MTK_PIN_NO(118) | 6) + +#define PINMUX_GPIO119__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) +#define PINMUX_GPIO119__FUNC_MIPI1_D_SCLK (MTK_PIN_NO(119) | 1) +#define PINMUX_GPIO119__FUNC_CONN_MIPI1_SCLK (MTK_PIN_NO(119) | 2) +#define PINMUX_GPIO119__FUNC_BPI_BUS20 (MTK_PIN_NO(119) | 3) +#define PINMUX_GPIO119__FUNC_ANT_SEL20 (MTK_PIN_NO(119) | 6) + +#define PINMUX_GPIO120__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) +#define PINMUX_GPIO120__FUNC_MIPI1_D_SDATA (MTK_PIN_NO(120) | 1) +#define PINMUX_GPIO120__FUNC_CONN_MIPI1_SDATA (MTK_PIN_NO(120) | 2) +#define PINMUX_GPIO120__FUNC_BPI_BUS21 (MTK_PIN_NO(120) | 3) +#define PINMUX_GPIO120__FUNC_ANT_SEL21 (MTK_PIN_NO(120) | 6) + +#define PINMUX_GPIO121__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) +#define PINMUX_GPIO121__FUNC_MIPI2_D_SCLK (MTK_PIN_NO(121) | 1) +#define PINMUX_GPIO121__FUNC_MIPI4_D_SCLK (MTK_PIN_NO(121) | 2) +#define PINMUX_GPIO121__FUNC_BPI_BUS22 (MTK_PIN_NO(121) | 3) +#define PINMUX_GPIO121__FUNC_MD_GPS_L1_BLANK (MTK_PIN_NO(121) | 6) + +#define PINMUX_GPIO122__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) +#define PINMUX_GPIO122__FUNC_MIPI2_D_SDATA (MTK_PIN_NO(122) | 1) +#define PINMUX_GPIO122__FUNC_MIPI4_D_SDATA (MTK_PIN_NO(122) | 2) +#define PINMUX_GPIO122__FUNC_BPI_BUS23 (MTK_PIN_NO(122) | 3) +#define PINMUX_GPIO122__FUNC_MD_GPS_L5_BLANK (MTK_PIN_NO(122) | 6) + +#define PINMUX_GPIO123__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) +#define PINMUX_GPIO123__FUNC_MIPI_M_SCLK (MTK_PIN_NO(123) | 1) + +#define PINMUX_GPIO124__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) +#define PINMUX_GPIO124__FUNC_MIPI_M_SDATA (MTK_PIN_NO(124) | 1) + +#define PINMUX_GPIO125__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) +#define PINMUX_GPIO125__FUNC_SCL0 (MTK_PIN_NO(125) | 1) +#define PINMUX_GPIO125__FUNC_SCP_SCL4 (MTK_PIN_NO(125) | 2) +#define PINMUX_GPIO125__FUNC_TP_UTXD2_VLP (MTK_PIN_NO(125) | 3) +#define PINMUX_GPIO125__FUNC_TP_UCTS1_VLP (MTK_PIN_NO(125) | 4) +#define PINMUX_GPIO125__FUNC_TP_GPIO4_AO (MTK_PIN_NO(125) | 5) +#define PINMUX_GPIO125__FUNC_UTXD2 (MTK_PIN_NO(125) | 6) + +#define PINMUX_GPIO126__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) +#define PINMUX_GPIO126__FUNC_SDA0 (MTK_PIN_NO(126) | 1) +#define PINMUX_GPIO126__FUNC_SCP_SDA4 (MTK_PIN_NO(126) | 2) +#define PINMUX_GPIO126__FUNC_TP_URXD2_VLP (MTK_PIN_NO(126) | 3) +#define PINMUX_GPIO126__FUNC_TP_URTS1_VLP (MTK_PIN_NO(126) | 4) +#define PINMUX_GPIO126__FUNC_TP_GPIO5_AO (MTK_PIN_NO(126) | 5) +#define PINMUX_GPIO126__FUNC_URXD2 (MTK_PIN_NO(126) | 6) + +#define PINMUX_GPIO127__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) +#define PINMUX_GPIO127__FUNC_SCL1 (MTK_PIN_NO(127) | 1) +#define PINMUX_GPIO127__FUNC_SCP_SCL5 (MTK_PIN_NO(127) | 2) +#define PINMUX_GPIO127__FUNC_TP_UCTS2_VLP (MTK_PIN_NO(127) | 3) +#define PINMUX_GPIO127__FUNC_TP_UTXD1_VLP (MTK_PIN_NO(127) | 4) +#define PINMUX_GPIO127__FUNC_TP_GPIO6_AO (MTK_PIN_NO(127) | 5) +#define PINMUX_GPIO127__FUNC_MD_MCIF_UTXD0 (MTK_PIN_NO(127) | 6) + +#define PINMUX_GPIO128__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) +#define PINMUX_GPIO128__FUNC_SDA1 (MTK_PIN_NO(128) | 1) +#define PINMUX_GPIO128__FUNC_SCP_SDA5 (MTK_PIN_NO(128) | 2) +#define PINMUX_GPIO128__FUNC_TP_URTS2_VLP (MTK_PIN_NO(128) | 3) +#define PINMUX_GPIO128__FUNC_TP_URXD1_VLP (MTK_PIN_NO(128) | 4) +#define PINMUX_GPIO128__FUNC_TP_GPIO7_AO (MTK_PIN_NO(128) | 5) +#define PINMUX_GPIO128__FUNC_MD_MCIF_URXD0 (MTK_PIN_NO(128) | 6) + +#define PINMUX_GPIO129__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) +#define PINMUX_GPIO129__FUNC_SCL2 (MTK_PIN_NO(129) | 1) + +#define PINMUX_GPIO130__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) +#define PINMUX_GPIO130__FUNC_SDA2 (MTK_PIN_NO(130) | 1) + +#define PINMUX_GPIO131__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) +#define PINMUX_GPIO131__FUNC_SCL3 (MTK_PIN_NO(131) | 1) +#define PINMUX_GPIO131__FUNC_TP_UTXD2_VCORE (MTK_PIN_NO(131) | 3) +#define PINMUX_GPIO131__FUNC_SSPM_UTXD_AO_VCORE (MTK_PIN_NO(131) | 6) + +#define PINMUX_GPIO132__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) +#define PINMUX_GPIO132__FUNC_SDA3 (MTK_PIN_NO(132) | 1) +#define PINMUX_GPIO132__FUNC_TP_URXD2_VCORE (MTK_PIN_NO(132) | 3) +#define PINMUX_GPIO132__FUNC_SSPM_URXD_AO_VCORE (MTK_PIN_NO(132) | 6) + +#define PINMUX_GPIO133__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) +#define PINMUX_GPIO133__FUNC_SCL4 (MTK_PIN_NO(133) | 1) + +#define PINMUX_GPIO134__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) +#define PINMUX_GPIO134__FUNC_SDA4 (MTK_PIN_NO(134) | 1) + +#define PINMUX_GPIO135__FUNC_GPIO135 (MTK_PIN_NO(135) | 0) +#define PINMUX_GPIO135__FUNC_SCL5 (MTK_PIN_NO(135) | 1) + +#define PINMUX_GPIO136__FUNC_GPIO136 (MTK_PIN_NO(136) | 0) +#define PINMUX_GPIO136__FUNC_SDA5 (MTK_PIN_NO(136) | 1) + +#define PINMUX_GPIO137__FUNC_GPIO137 (MTK_PIN_NO(137) | 0) +#define PINMUX_GPIO137__FUNC_SCL6 (MTK_PIN_NO(137) | 1) + +#define PINMUX_GPIO138__FUNC_GPIO138 (MTK_PIN_NO(138) | 0) +#define PINMUX_GPIO138__FUNC_SDA6 (MTK_PIN_NO(138) | 1) + +#define PINMUX_GPIO139__FUNC_GPIO139 (MTK_PIN_NO(139) | 0) +#define PINMUX_GPIO139__FUNC_SCL7 (MTK_PIN_NO(139) | 1) +#define PINMUX_GPIO139__FUNC_TP_UTXD1_VCORE (MTK_PIN_NO(139) | 3) +#define PINMUX_GPIO139__FUNC_MD_UTXD0 (MTK_PIN_NO(139) | 4) +#define PINMUX_GPIO139__FUNC_UTXD1 (MTK_PIN_NO(139) | 6) + +#define PINMUX_GPIO140__FUNC_GPIO140 (MTK_PIN_NO(140) | 0) +#define PINMUX_GPIO140__FUNC_SDA7 (MTK_PIN_NO(140) | 1) +#define PINMUX_GPIO140__FUNC_TP_URXD1_VCORE (MTK_PIN_NO(140) | 3) +#define PINMUX_GPIO140__FUNC_MD_URXD0 (MTK_PIN_NO(140) | 4) +#define PINMUX_GPIO140__FUNC_URXD1 (MTK_PIN_NO(140) | 6) + +#define PINMUX_GPIO141__FUNC_GPIO141 (MTK_PIN_NO(141) | 0) +#define PINMUX_GPIO141__FUNC_SCL8 (MTK_PIN_NO(141) | 1) + +#define PINMUX_GPIO142__FUNC_GPIO142 (MTK_PIN_NO(142) | 0) +#define PINMUX_GPIO142__FUNC_SDA8 (MTK_PIN_NO(142) | 1) + +#define PINMUX_GPIO143__FUNC_GPIO143 (MTK_PIN_NO(143) | 0) +#define PINMUX_GPIO143__FUNC_SCL9 (MTK_PIN_NO(143) | 1) +#define PINMUX_GPIO143__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(143) | 2) +#define PINMUX_GPIO143__FUNC_HFRP_UTXD1 (MTK_PIN_NO(143) | 3) +#define PINMUX_GPIO143__FUNC_CONN_BGF_MCU_AICE_TMSC (MTK_PIN_NO(143) | 4) +#define PINMUX_GPIO143__FUNC_CONN_WF_MCU_AICE_TMSC (MTK_PIN_NO(143) | 5) +#define PINMUX_GPIO143__FUNC_MBISTREADEN_TRIGGER (MTK_PIN_NO(143) | 7) + +#define PINMUX_GPIO144__FUNC_GPIO144 (MTK_PIN_NO(144) | 0) +#define PINMUX_GPIO144__FUNC_SDA9 (MTK_PIN_NO(144) | 1) +#define PINMUX_GPIO144__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(144) | 2) +#define PINMUX_GPIO144__FUNC_HFRP_URXD1 (MTK_PIN_NO(144) | 3) +#define PINMUX_GPIO144__FUNC_CONN_BGF_MCU_AICE_TCKC (MTK_PIN_NO(144) | 4) +#define PINMUX_GPIO144__FUNC_CONN_WF_MCU_AICE_TCKC (MTK_PIN_NO(144) | 5) +#define PINMUX_GPIO144__FUNC_MBISTWRITEEN_TRIGGER (MTK_PIN_NO(144) | 7) + +#define PINMUX_GPIO145__FUNC_GPIO145 (MTK_PIN_NO(145) | 0) +#define PINMUX_GPIO145__FUNC_SCL10 (MTK_PIN_NO(145) | 1) +#define PINMUX_GPIO145__FUNC_SCP_SCL0 (MTK_PIN_NO(145) | 2) +#define PINMUX_GPIO145__FUNC_TP_GPIO8_AO (MTK_PIN_NO(145) | 5) + +#define PINMUX_GPIO146__FUNC_GPIO146 (MTK_PIN_NO(146) | 0) +#define PINMUX_GPIO146__FUNC_SDA10 (MTK_PIN_NO(146) | 1) +#define PINMUX_GPIO146__FUNC_SCP_SDA0 (MTK_PIN_NO(146) | 2) +#define PINMUX_GPIO146__FUNC_TP_GPIO9_AO (MTK_PIN_NO(146) | 5) + +#define PINMUX_GPIO147__FUNC_GPIO147 (MTK_PIN_NO(147) | 0) +#define PINMUX_GPIO147__FUNC_SCL11 (MTK_PIN_NO(147) | 1) +#define PINMUX_GPIO147__FUNC_SCP_SCL1 (MTK_PIN_NO(147) | 2) +#define PINMUX_GPIO147__FUNC_SCP_DMIC_CLK (MTK_PIN_NO(147) | 3) +#define PINMUX_GPIO147__FUNC_DMIC_CLK (MTK_PIN_NO(147) | 4) +#define PINMUX_GPIO147__FUNC_TP_GPIO10_AO (MTK_PIN_NO(147) | 5) +#define PINMUX_GPIO147__FUNC_EXTIF0_PRI (MTK_PIN_NO(147) | 6) + +#define PINMUX_GPIO148__FUNC_GPIO148 (MTK_PIN_NO(148) | 0) +#define PINMUX_GPIO148__FUNC_SDA11 (MTK_PIN_NO(148) | 1) +#define PINMUX_GPIO148__FUNC_SCP_SDA1 (MTK_PIN_NO(148) | 2) +#define PINMUX_GPIO148__FUNC_SCP_DMIC_DAT (MTK_PIN_NO(148) | 3) +#define PINMUX_GPIO148__FUNC_DMIC_DAT (MTK_PIN_NO(148) | 4) +#define PINMUX_GPIO148__FUNC_TP_GPIO11_AO (MTK_PIN_NO(148) | 5) +#define PINMUX_GPIO148__FUNC_EXTIF0_GNT_B (MTK_PIN_NO(148) | 6) + +#define PINMUX_GPIO149__FUNC_GPIO149 (MTK_PIN_NO(149) | 0) +#define PINMUX_GPIO149__FUNC_KPROW2 (MTK_PIN_NO(149) | 1) +#define PINMUX_GPIO149__FUNC_PWM_VLP (MTK_PIN_NO(149) | 2) +#define PINMUX_GPIO149__FUNC_MD_INT0 (MTK_PIN_NO(149) | 4) +#define PINMUX_GPIO149__FUNC_TP_GPIO12_AO (MTK_PIN_NO(149) | 5) +#define PINMUX_GPIO149__FUNC_SCL0 (MTK_PIN_NO(149) | 6) +#define PINMUX_GPIO149__FUNC_DBG_MON_A28 (MTK_PIN_NO(149) | 7) + +#define PINMUX_GPIO150__FUNC_GPIO150 (MTK_PIN_NO(150) | 0) +#define PINMUX_GPIO150__FUNC_KPCOL2 (MTK_PIN_NO(150) | 1) +#define PINMUX_GPIO150__FUNC_PWM_VLP (MTK_PIN_NO(150) | 2) +#define PINMUX_GPIO150__FUNC_CMMCLK5 (MTK_PIN_NO(150) | 3) +#define PINMUX_GPIO150__FUNC_MD_INT3 (MTK_PIN_NO(150) | 4) +#define PINMUX_GPIO150__FUNC_TP_GPIO13_AO (MTK_PIN_NO(150) | 5) +#define PINMUX_GPIO150__FUNC_SDA0 (MTK_PIN_NO(150) | 6) + +#define PINMUX_GPIO151__FUNC_GPIO151 (MTK_PIN_NO(151) | 0) +#define PINMUX_GPIO151__FUNC_SRCLKENAI0 (MTK_PIN_NO(151) | 1) +#define PINMUX_GPIO151__FUNC_MD_INT4 (MTK_PIN_NO(151) | 4) +#define PINMUX_GPIO151__FUNC_TP_GPIO14_AO (MTK_PIN_NO(151) | 5) +#define PINMUX_GPIO151__FUNC_DBG_MON_A29 (MTK_PIN_NO(151) | 7) + +#define PINMUX_GPIO152__FUNC_GPIO152 (MTK_PIN_NO(152) | 0) +#define PINMUX_GPIO152__FUNC_SRCLKENAI1 (MTK_PIN_NO(152) | 1) +#define PINMUX_GPIO152__FUNC_SPMI_M_TRIG_FLAG (MTK_PIN_NO(152) | 4) +#define PINMUX_GPIO152__FUNC_TP_GPIO15_AO (MTK_PIN_NO(152) | 5) +#define PINMUX_GPIO152__FUNC_DBG_MON_A30 (MTK_PIN_NO(152) | 7) + +#define PINMUX_GPIO153__FUNC_GPIO153 (MTK_PIN_NO(153) | 0) +#define PINMUX_GPIO153__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(153) | 1) +#define PINMUX_GPIO153__FUNC_DISP_PWM1 (MTK_PIN_NO(153) | 2) +#define PINMUX_GPIO153__FUNC_SPMI_P_TRIG_FLAG (MTK_PIN_NO(153) | 4) +#define PINMUX_GPIO153__FUNC_DBG_MON_A0 (MTK_PIN_NO(153) | 7) + +#define PINMUX_GPIO154__FUNC_GPIO154 (MTK_PIN_NO(154) | 0) +#define PINMUX_GPIO154__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(154) | 1) +#define PINMUX_GPIO154__FUNC_LCM_RST1 (MTK_PIN_NO(154) | 2) +#define PINMUX_GPIO154__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(154) | 3) +#define PINMUX_GPIO154__FUNC_CMFLASH2 (MTK_PIN_NO(154) | 4) +#define PINMUX_GPIO154__FUNC_MBISTREADEN_TRIGGER (MTK_PIN_NO(154) | 5) +#define PINMUX_GPIO154__FUNC_DBG_MON_A1 (MTK_PIN_NO(154) | 7) + +#define PINMUX_GPIO155__FUNC_GPIO155 (MTK_PIN_NO(155) | 0) +#define PINMUX_GPIO155__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(155) | 1) +#define PINMUX_GPIO155__FUNC_DSI_TE1 (MTK_PIN_NO(155) | 2) +#define PINMUX_GPIO155__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(155) | 3) +#define PINMUX_GPIO155__FUNC_CMFLASH3 (MTK_PIN_NO(155) | 4) +#define PINMUX_GPIO155__FUNC_MBISTWRITEEN_TRIGGER (MTK_PIN_NO(155) | 5) +#define PINMUX_GPIO155__FUNC_DBG_MON_A2 (MTK_PIN_NO(155) | 7) + +#define PINMUX_GPIO156__FUNC_GPIO156 (MTK_PIN_NO(156) | 0) +#define PINMUX_GPIO156__FUNC_SPMI_M_SCL (MTK_PIN_NO(156) | 1) + +#define PINMUX_GPIO157__FUNC_GPIO157 (MTK_PIN_NO(157) | 0) +#define PINMUX_GPIO157__FUNC_SPMI_M_SDA (MTK_PIN_NO(157) | 1) + +#define PINMUX_GPIO158__FUNC_GPIO158 (MTK_PIN_NO(158) | 0) +#define PINMUX_GPIO158__FUNC_SPMI_P_SCL (MTK_PIN_NO(158) | 1) + +#define PINMUX_GPIO159__FUNC_GPIO159 (MTK_PIN_NO(159) | 0) +#define PINMUX_GPIO159__FUNC_SPMI_P_SDA (MTK_PIN_NO(159) | 1) + +#define PINMUX_GPIO160__FUNC_GPIO160 (MTK_PIN_NO(160) | 0) +#define PINMUX_GPIO160__FUNC_SRCLKENA0 (MTK_PIN_NO(160) | 1) + +#define PINMUX_GPIO161__FUNC_GPIO161 (MTK_PIN_NO(161) | 0) +#define PINMUX_GPIO161__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(161) | 1) + +#define PINMUX_GPIO162__FUNC_GPIO162 (MTK_PIN_NO(162) | 0) +#define PINMUX_GPIO162__FUNC_RTC32K_CK (MTK_PIN_NO(162) | 1) + +#define PINMUX_GPIO163__FUNC_GPIO163 (MTK_PIN_NO(163) | 0) +#define PINMUX_GPIO163__FUNC_WATCHDOG (MTK_PIN_NO(163) | 1) + +#define PINMUX_GPIO164__FUNC_GPIO164 (MTK_PIN_NO(164) | 0) +#define PINMUX_GPIO164__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(164) | 1) +#define PINMUX_GPIO164__FUNC_AUD_CLK_MOSI_A (MTK_PIN_NO(164) | 3) + +#define PINMUX_GPIO165__FUNC_GPIO165 (MTK_PIN_NO(165) | 0) +#define PINMUX_GPIO165__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(165) | 1) + +#define PINMUX_GPIO166__FUNC_GPIO166 (MTK_PIN_NO(166) | 0) +#define PINMUX_GPIO166__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(166) | 1) +#define PINMUX_GPIO166__FUNC_AUD_DAT_MOSI0_A (MTK_PIN_NO(166) | 3) + +#define PINMUX_GPIO167__FUNC_GPIO167 (MTK_PIN_NO(167) | 0) +#define PINMUX_GPIO167__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(167) | 1) +#define PINMUX_GPIO167__FUNC_AUD_DAT_MOSI1_A (MTK_PIN_NO(167) | 3) + +#define PINMUX_GPIO168__FUNC_GPIO168 (MTK_PIN_NO(168) | 0) +#define PINMUX_GPIO168__FUNC_AUD_NLE_MOSI0 (MTK_PIN_NO(168) | 1) +#define PINMUX_GPIO168__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(168) | 2) + +#define PINMUX_GPIO169__FUNC_GPIO169 (MTK_PIN_NO(169) | 0) +#define PINMUX_GPIO169__FUNC_AUD_NLE_MOSI1 (MTK_PIN_NO(169) | 1) +#define PINMUX_GPIO169__FUNC_AUD_CLK_MISO (MTK_PIN_NO(169) | 2) +#define PINMUX_GPIO169__FUNC_AUD_CLK_MISO_A (MTK_PIN_NO(169) | 3) + +#define PINMUX_GPIO170__FUNC_GPIO170 (MTK_PIN_NO(170) | 0) +#define PINMUX_GPIO170__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(170) | 1) +#define PINMUX_GPIO170__FUNC_VOW_DAT_MISO (MTK_PIN_NO(170) | 2) +#define PINMUX_GPIO170__FUNC_AUD_DAT_MISO0_A (MTK_PIN_NO(170) | 3) + +#define PINMUX_GPIO171__FUNC_GPIO171 (MTK_PIN_NO(171) | 0) +#define PINMUX_GPIO171__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(171) | 1) +#define PINMUX_GPIO171__FUNC_VOW_CLK_MISO (MTK_PIN_NO(171) | 2) +#define PINMUX_GPIO171__FUNC_AUD_DAT_MISO1_A (MTK_PIN_NO(171) | 3) + +#define PINMUX_GPIO172__FUNC_GPIO172 (MTK_PIN_NO(172) | 0) +#define PINMUX_GPIO172__FUNC_CONN_TOP_CLK (MTK_PIN_NO(172) | 1) +#define PINMUX_GPIO172__FUNC_DBG_MON_A31 (MTK_PIN_NO(172) | 7) + +#define PINMUX_GPIO173__FUNC_GPIO173 (MTK_PIN_NO(173) | 0) +#define PINMUX_GPIO173__FUNC_CONN_TOP_DATA (MTK_PIN_NO(173) | 1) + +#define PINMUX_GPIO174__FUNC_GPIO174 (MTK_PIN_NO(174) | 0) +#define PINMUX_GPIO174__FUNC_CONN_BT_CLK (MTK_PIN_NO(174) | 1) + +#define PINMUX_GPIO175__FUNC_GPIO175 (MTK_PIN_NO(175) | 0) +#define PINMUX_GPIO175__FUNC_CONN_BT_DATA (MTK_PIN_NO(175) | 1) + +#define PINMUX_GPIO176__FUNC_GPIO176 (MTK_PIN_NO(176) | 0) +#define PINMUX_GPIO176__FUNC_CONN_HRST_B (MTK_PIN_NO(176) | 1) + +#define PINMUX_GPIO177__FUNC_GPIO177 (MTK_PIN_NO(177) | 0) +#define PINMUX_GPIO177__FUNC_CONN_WB_PTA (MTK_PIN_NO(177) | 1) + +#define PINMUX_GPIO178__FUNC_GPIO178 (MTK_PIN_NO(178) | 0) +#define PINMUX_GPIO178__FUNC_CONN_WF_CTRL0 (MTK_PIN_NO(178) | 1) + +#define PINMUX_GPIO179__FUNC_GPIO179 (MTK_PIN_NO(179) | 0) +#define PINMUX_GPIO179__FUNC_CONN_WF_CTRL1 (MTK_PIN_NO(179) | 1) + +#define PINMUX_GPIO180__FUNC_GPIO180 (MTK_PIN_NO(180) | 0) +#define PINMUX_GPIO180__FUNC_CONN_WF_CTRL2 (MTK_PIN_NO(180) | 1) + +#define PINMUX_GPIO181__FUNC_GPIO181 (MTK_PIN_NO(181) | 0) +#define PINMUX_GPIO181__FUNC_CONN_WF_CTRL3 (MTK_PIN_NO(181) | 1) +#define PINMUX_GPIO181__FUNC_CONN_TOP_CLK_2 (MTK_PIN_NO(181) | 2) +#define PINMUX_GPIO181__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(181) | 3) + +#define PINMUX_GPIO182__FUNC_GPIO182 (MTK_PIN_NO(182) | 0) +#define PINMUX_GPIO182__FUNC_CONN_WF_CTRL4 (MTK_PIN_NO(182) | 1) +#define PINMUX_GPIO182__FUNC_CONN_TOP_DATA_2 (MTK_PIN_NO(182) | 2) +#define PINMUX_GPIO182__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(182) | 3) + +#define PINMUX_GPIO183__FUNC_GPIO183 (MTK_PIN_NO(183) | 0) +#define PINMUX_GPIO183__FUNC_CONN_HRST_B_2 (MTK_PIN_NO(183) | 1) + +#define PINMUX_GPIO184__FUNC_GPIO184 (MTK_PIN_NO(184) | 0) +#define PINMUX_GPIO184__FUNC_MSDC0_DSL (MTK_PIN_NO(184) | 1) +#define PINMUX_GPIO184__FUNC_ANT_SEL13 (MTK_PIN_NO(184) | 3) + +#define PINMUX_GPIO185__FUNC_GPIO185 (MTK_PIN_NO(185) | 0) +#define PINMUX_GPIO185__FUNC_MSDC0_CLK (MTK_PIN_NO(185) | 1) +#define PINMUX_GPIO185__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(185) | 2) +#define PINMUX_GPIO185__FUNC_ANT_SEL14 (MTK_PIN_NO(185) | 3) + +#define PINMUX_GPIO186__FUNC_GPIO186 (MTK_PIN_NO(186) | 0) +#define PINMUX_GPIO186__FUNC_MSDC0_CMD (MTK_PIN_NO(186) | 1) +#define PINMUX_GPIO186__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(186) | 2) +#define PINMUX_GPIO186__FUNC_ANT_SEL15 (MTK_PIN_NO(186) | 3) +#define PINMUX_GPIO186__FUNC_I2SOUT4_DATA0 (MTK_PIN_NO(186) | 5) + +#define PINMUX_GPIO187__FUNC_GPIO187 (MTK_PIN_NO(187) | 0) +#define PINMUX_GPIO187__FUNC_MSDC0_RSTB (MTK_PIN_NO(187) | 1) +#define PINMUX_GPIO187__FUNC_GPS_L5_ELNA_EN (MTK_PIN_NO(187) | 2) +#define PINMUX_GPIO187__FUNC_ANT_SEL16 (MTK_PIN_NO(187) | 3) +#define PINMUX_GPIO187__FUNC_I2SOUT4_DATA1 (MTK_PIN_NO(187) | 5) + +#define PINMUX_GPIO188__FUNC_GPIO188 (MTK_PIN_NO(188) | 0) +#define PINMUX_GPIO188__FUNC_MSDC0_DAT0 (MTK_PIN_NO(188) | 1) +#define PINMUX_GPIO188__FUNC_ANT_SEL17 (MTK_PIN_NO(188) | 3) +#define PINMUX_GPIO188__FUNC_I2SOUT4_DATA2 (MTK_PIN_NO(188) | 5) + +#define PINMUX_GPIO189__FUNC_GPIO189 (MTK_PIN_NO(189) | 0) +#define PINMUX_GPIO189__FUNC_MSDC0_DAT1 (MTK_PIN_NO(189) | 1) +#define PINMUX_GPIO189__FUNC_ANT_SEL18 (MTK_PIN_NO(189) | 3) +#define PINMUX_GPIO189__FUNC_I2SOUT4_DATA3 (MTK_PIN_NO(189) | 5) + +#define PINMUX_GPIO190__FUNC_GPIO190 (MTK_PIN_NO(190) | 0) +#define PINMUX_GPIO190__FUNC_MSDC0_DAT2 (MTK_PIN_NO(190) | 1) +#define PINMUX_GPIO190__FUNC_DMIC1_CLK (MTK_PIN_NO(190) | 2) +#define PINMUX_GPIO190__FUNC_ANT_SEL19 (MTK_PIN_NO(190) | 3) +#define PINMUX_GPIO190__FUNC_I2SIN4_BCK (MTK_PIN_NO(190) | 5) + +#define PINMUX_GPIO191__FUNC_GPIO191 (MTK_PIN_NO(191) | 0) +#define PINMUX_GPIO191__FUNC_MSDC0_DAT3 (MTK_PIN_NO(191) | 1) +#define PINMUX_GPIO191__FUNC_DMIC1_DAT (MTK_PIN_NO(191) | 2) +#define PINMUX_GPIO191__FUNC_ANT_SEL20 (MTK_PIN_NO(191) | 3) +#define PINMUX_GPIO191__FUNC_I2SIN4_DATA0 (MTK_PIN_NO(191) | 5) + +#define PINMUX_GPIO192__FUNC_GPIO192 (MTK_PIN_NO(192) | 0) +#define PINMUX_GPIO192__FUNC_MSDC0_DAT4 (MTK_PIN_NO(192) | 1) +#define PINMUX_GPIO192__FUNC_IDDIG (MTK_PIN_NO(192) | 2) +#define PINMUX_GPIO192__FUNC_ANT_SEL21 (MTK_PIN_NO(192) | 3) +#define PINMUX_GPIO192__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(192) | 4) +#define PINMUX_GPIO192__FUNC_I2SIN4_DATA1 (MTK_PIN_NO(192) | 5) + +#define PINMUX_GPIO193__FUNC_GPIO193 (MTK_PIN_NO(193) | 0) +#define PINMUX_GPIO193__FUNC_MSDC0_DAT5 (MTK_PIN_NO(193) | 1) +#define PINMUX_GPIO193__FUNC_USB_DRVVBUS (MTK_PIN_NO(193) | 2) +#define PINMUX_GPIO193__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(193) | 4) +#define PINMUX_GPIO193__FUNC_I2SIN4_DATA2 (MTK_PIN_NO(193) | 5) + +#define PINMUX_GPIO194__FUNC_GPIO194 (MTK_PIN_NO(194) | 0) +#define PINMUX_GPIO194__FUNC_MSDC0_DAT6 (MTK_PIN_NO(194) | 1) +#define PINMUX_GPIO194__FUNC_VBUSVALID (MTK_PIN_NO(194) | 2) +#define PINMUX_GPIO194__FUNC_I2SIN4_DATA3 (MTK_PIN_NO(194) | 5) + +#define PINMUX_GPIO195__FUNC_GPIO195 (MTK_PIN_NO(195) | 0) +#define PINMUX_GPIO195__FUNC_MSDC0_DAT7 (MTK_PIN_NO(195) | 1) +#define PINMUX_GPIO195__FUNC_I2SIN4_LRCK (MTK_PIN_NO(195) | 5) + +#endif /* __MT6878_PINFUNC_H */ diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi index 917fa39a74f8d..158bd9a305d70 100644 --- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi @@ -278,6 +278,10 @@ #address-cells = <1>; #size-cells = <1>; + soc-uuid@140 { + reg = <0x140 0x8>; + }; + thermal_calibration: calib@198 { reg = <0x198 0xc>; }; diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts index 4f6cbb4912872..2e39e72877301 100644 --- a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts +++ b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts @@ -3,13 +3,163 @@ /dts-v1/; #include "mt7981b.dtsi" +#include +#include +#include "dt-bindings/pinctrl/mt65xx.h" / { compatible = "openwrt,one", "mediatek,mt7981b"; model = "OpenWrt One"; + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + memory@40000000 { reg = <0 0x40000000 0 0x40000000>; device_type = "memory"; }; + + pwm-leds { + compatible = "pwm-leds"; + + led-0 { + color = ; + default-brightness = <0>; + function = LED_FUNCTION_STATUS; + max-brightness = <255>; + pwms = <&pwm 0 10000>; + }; + + led-1 { + color = ; + default-brightness = <0>; + function = LED_FUNCTION_STATUS; + max-brightness = <255>; + pwms = <&pwm 1 10000>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led-0 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 9 GPIO_ACTIVE_HIGH>; + }; + + led-1 { + color = ; + function = LED_FUNCTION_LAN; + gpios = <&pio 34 GPIO_ACTIVE_LOW>; + linux,default-trigger = "netdev"; + }; + + led-2 { + color = ; + function = LED_FUNCTION_LAN; + gpios = <&pio 35 GPIO_ACTIVE_LOW>; + linux,default-trigger = "netdev"; + }; + }; +}; + +&pio { + pwm_pins: pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_0", "pwm1_1"; + }; + }; + + spi2_flash_pins: spi2-pins { + mux { + function = "spi"; + groups = "spi2"; + }; + + conf-pu { + bias-pull-up = ; + drive-strength = <8>; + pins = "SPI2_CS", "SPI2_WP"; + }; + + conf-pd { + bias-pull-down = ; + drive-strength = <8>; + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&spi2 { + pinctrl-names = "default"; + pinctrl-0 = <&spi2_flash_pins>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + #address-cells = <1>; + #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x00000 0x40000>; + label = "bl2-nor"; + }; + + partition@40000 { + reg = <0x40000 0xc0000>; + label = "factory"; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + wifi_factory_calibration: eeprom@0 { + reg = <0x0 0x1000>; + }; + + wan_factory_mac: macaddr@24 { + reg = <0x24 0x6>; + compatible = "mac-base"; + #nvmem-cell-cells = <1>; + }; + }; + }; + + partition@100000 { + reg = <0x100000 0x80000>; + label = "fip-nor"; + }; + + partition@180000 { + reg = <0x180000 0xc80000>; + label = "recovery"; + }; + }; + }; +}; + +&uart0 { + status = "okay"; }; diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi index 277c11247c132..416096b80770c 100644 --- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi @@ -41,6 +41,18 @@ method = "smc"; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ + secmon_reserved: secmon@43000000 { + reg = <0 0x43000000 0 0x30000>; + no-map; + }; + }; + soc { compatible = "simple-bus"; ranges; @@ -82,7 +94,7 @@ #clock-cells = <1>; }; - pwm@10048000 { + pwm: pwm@10048000 { compatible = "mediatek,mt7981-pwm"; reg = <0 0x10048000 0 0x1000>; clocks = <&infracfg CLK_INFRA_PWM_STA>, @@ -94,7 +106,7 @@ #pwm-cells = <2>; }; - serial@11002000 { + uart0: serial@11002000 { compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart"; reg = <0 0x11002000 0 0x100>; interrupts = ; @@ -102,10 +114,12 @@ clocks = <&infracfg CLK_INFRA_UART0_SEL>, <&infracfg CLK_INFRA_UART0_CK>; clock-names = "baud", "bus"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; status = "disabled"; }; - serial@11003000 { + uart1: serial@11003000 { compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart"; reg = <0 0x11003000 0 0x100>; interrupts = ; @@ -116,7 +130,7 @@ status = "disabled"; }; - serial@11004000 { + uart2: serial@11004000 { compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart"; reg = <0 0x11004000 0 0x100>; interrupts = ; @@ -142,7 +156,7 @@ status = "disabled"; }; - spi@11009000 { + spi2: spi@11009000 { compatible = "mediatek,mt7981-spi-ipm", "mediatek,spi-ipm"; reg = <0 0x11009000 0 0x1000>; interrupts = ; @@ -229,6 +243,13 @@ gpio-controller; #gpio-cells = <2>; #interrupt-cells = <2>; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0"; + }; + }; }; efuse@11f20000 { @@ -237,6 +258,10 @@ #address-cells = <1>; #size-cells = <1>; + soc-uuid@140 { + reg = <0x140 0x10>; + }; + thermal_calibration: thermal-calib@274 { reg = <0x274 0xc>; }; diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts index e7654dc9a1c9b..19f538d160ab5 100644 --- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts +++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts @@ -42,7 +42,7 @@ compatible = "pwm-fan"; #cooling-cells = <2>; /* cooling level (0, 1, 2) - pwm inverted */ - cooling-levels = <255 96 0>; + cooling-levels = <255 40 0>; pwms = <&pwm 0 10000>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi index a8972330a7b89..7790601586ccf 100644 --- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi @@ -450,6 +450,10 @@ #address-cells = <1>; #size-cells = <1>; + soc-uuid@140 { + reg = <0x140 0x8>; + }; + thermal_calibration: calib@274 { reg = <0x274 0xc>; }; diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts index 6f0c81e3fd941..0e41c07d3a5f4 100644 --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts @@ -19,4 +19,5 @@ &int_2p5g_phy { pinctrl-0 = <&i2p5gbe_led0_pins>; pinctrl-names = "i2p5gbe-led"; + status = "okay"; }; diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-4e.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-4e.dts new file mode 100644 index 0000000000000..c7ea6e88c4f48 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-4e.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 MediaTek Inc. + * Author: Frank Wunderlich + */ + +/dts-v1/; + +#include "mt7988a-bananapi-bpi-r4-pro.dtsi" + +/ { + model = "Bananapi BPI-R4"; + compatible = "bananapi,bpi-r4-pro-4e", + "bananapi,bpi-r4-pro", + "mediatek,mt7988a"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-8x.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-8x.dts new file mode 100644 index 0000000000000..c9a0e69e9dd51 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-8x.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 MediaTek Inc. + * Author: Frank Wunderlich + */ + +/dts-v1/; + +#include "mt7988a-bananapi-bpi-r4-pro.dtsi" + +/ { + model = "Bananapi BPI-R4"; + compatible = "bananapi,bpi-r4-pro-8x", + "bananapi,bpi-r4-pro", + "mediatek,mt7988a"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn15.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn15.dtso new file mode 100644 index 0000000000000..9750916042deb --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn15.dtso @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 MediaTek Inc. + * Author: Frank Wunderlich + */ + +/* This enables key-b slot CN15 on pcie2(11280000 1L0) on BPI-R4-Pro */ + +/dts-v1/; +/plugin/; + +#include + +/ { + compatible = "bananapi,bpi-r4-pro", "mediatek,mt7988a"; +}; + +&{/soc/pinctrl@1001f000/pcie-2-hog} { + output-low; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn18.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn18.dtso new file mode 100644 index 0000000000000..9830fb0fd97a2 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn18.dtso @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 MediaTek Inc. + * Author: Frank Wunderlich + */ + +/* This enables key-b slot CN18 on pcie3(11290000 1L1) on BPI-R4-Pro */ + +/dts-v1/; +/plugin/; + +#include + +/ { + compatible = "bananapi,bpi-r4-pro", "mediatek,mt7988a"; +}; + +&{/soc/pinctrl@1001f000/pcie-3-hog} { + output-low; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-emmc.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-emmc.dtso new file mode 100644 index 0000000000000..5ed2f0a6bd662 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-emmc.dtso @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2021 MediaTek Inc. + * Author: Frank Wunderlich + */ + +/dts-v1/; +/plugin/; + +/ { + compatible = "bananapi,bpi-r4-pro", "mediatek,mt7988a"; +}; + +&{/soc/mmc@11230000} { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc0_pins_emmc_51>; + pinctrl-1 = <&mmc0_pins_emmc_51>; + bus-width = <8>; + max-frequency = <200000000>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + hs400-ds-delay = <0x12814>; + vqmmc-supply = <®_1p8v>; + vmmc-supply = <®_3p3v>; + non-removable; + no-sd; + no-sdio; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; +}; + diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-sd.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-sd.dtso new file mode 100644 index 0000000000000..1ec1a9fbd8ba6 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-sd.dtso @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2023 MediaTek Inc. + * Author: Frank Wunderlich + */ + +/dts-v1/; +/plugin/; + +#include + +/ { + compatible = "bananapi,bpi-r4-pro", "mediatek,mt7988a"; +}; + +&{/soc/mmc@11230000} { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc0_pins_sdcard>; + pinctrl-1 = <&mmc0_pins_sdcard>; + cd-gpios = <&pio 12 GPIO_ACTIVE_LOW>; + bus-width = <4>; + max-frequency = <48000000>; + cap-sd-highspeed; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + no-mmc; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; +}; + diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro.dtsi new file mode 100644 index 0000000000000..a48132f094114 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro.dtsi @@ -0,0 +1,534 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 MediaTek Inc. + * Author: Sam.Shih + * Author: Frank Wunderlich + */ + +/dts-v1/; + +#include "mt7988a.dtsi" +#include +#include +#include +#include + +/ { + aliases { + ethernet0 = &gmac0; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + /* PCA9548 (0-0070) provides 4 i2c channels */ + i2c3 = &imux0; + i2c4 = &imux1_sfp1; + i2c5 = &imux2_sfp2; + i2c6 = &imux3_wifi; + }; + + chosen { + stdout-path = &serial0; + }; + + fan: pwm-fan { + compatible = "pwm-fan"; + /* cooling level (0, 1, 2, 3) : (0% duty, 30% duty, 50% duty, 100% duty) */ + cooling-levels = <0 80 128 255>; + pinctrl-0 = <&pwm0_pins>; + pinctrl-names = "default"; + pwms = <&pwm 0 50000>; + #cooling-cells = <2>; + }; + + gpio-keys { + compatible = "gpio-keys"; + + button-reset { + label = "reset"; + gpios = <&pio 13 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + button-wps { + label = "WPS"; + gpios = <&pio 14 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led_red: sys-led-red { + color = ; + gpios = <&pca9555 15 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + led_blue: sys-led-blue { + color = ; + gpios = <&pca9555 14 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; + + reg_1p8v: regulator-dvdd1v8 { + compatible = "regulator-fixed"; + regulator-name = "DVDD1V8_SOC"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator-3v3vd { + compatible = "regulator-fixed"; + regulator-name = "3V3VD"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + /* SFP1 cage (LAN) */ + sfp1: sfp1 { + compatible = "sff,sfp"; + i2c-bus = <&imux1_sfp1>; + los-gpios = <&pio 70 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&pio 69 GPIO_ACTIVE_LOW>; + tx-disable-gpios = <&pio 21 GPIO_ACTIVE_HIGH>; + maximum-power-milliwatt = <3000>; + }; + + /* SFP2 cage (WAN) */ + sfp2: sfp2 { + compatible = "sff,sfp"; + i2c-bus = <&imux2_sfp2>; + los-gpios = <&pio 2 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&pio 1 GPIO_ACTIVE_LOW>; + tx-disable-gpios = <&pio 0 GPIO_ACTIVE_HIGH>; + maximum-power-milliwatt = <3000>; + }; +}; + +&cci { + proc-supply = <&rt5190_buck3>; +}; + +&cpu0 { + proc-supply = <&rt5190_buck3>; +}; + +&cpu1 { + proc-supply = <&rt5190_buck3>; +}; + +&cpu2 { + proc-supply = <&rt5190_buck3>; +}; + +&cpu3 { + proc-supply = <&rt5190_buck3>; +}; + +&cpu_thermal { + trips { + cpu_trip_hot: hot { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu_trip_active_high: active-high { + temperature = <115000>; + hysteresis = <2000>; + type = "active"; + }; + + cpu_trip_active_med: active-med { + temperature = <85000>; + hysteresis = <2000>; + type = "active"; + }; + + cpu_trip_active_low: active-low { + temperature = <40000>; + hysteresis = <2000>; + type = "active"; + }; + }; + + cooling-maps { + map-cpu-active-high { + /* active: set fan to cooling level 2 */ + cooling-device = <&fan 3 3>; + trip = <&cpu_trip_active_high>; + }; + + map-cpu-active-med { + /* active: set fan to cooling level 1 */ + cooling-device = <&fan 2 2>; + trip = <&cpu_trip_active_med>; + }; + + map-cpu-active-low { + /* active: set fan to cooling level 0 */ + cooling-device = <&fan 1 1>; + trip = <&cpu_trip_active_low>; + }; + }; +}; + +ð { + pinctrl-0 = <&mdio0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&fan { + pinctrl-0 = <&pwm0_pins>; + pinctrl-names = "default"; + pwms = <&pwm 0 50000>; + status = "okay"; +}; + +&gmac0 { + status = "okay"; +}; + +&gsw_phy0 { + pinctrl-0 = <&gbe0_led0_pins>; + pinctrl-names = "gbe-led"; +}; + +&gsw_phy0_led0 { + color = ; + status = "okay"; +}; + +&gsw_port0 { + label = "mgmt"; +}; + +/* R4Pro has only port 0 connected, so disable the others */ +&gsw_phy1 { + status = "disabled"; +}; + +&gsw_port1 { + status = "disabled"; +}; + +&gsw_phy2 { + status = "disabled"; +}; + +&gsw_port2 { + status = "disabled"; +}; + +&gsw_phy3 { + status = "disabled"; +}; + +&gsw_port3 { + status = "disabled"; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + status = "okay"; + + rt5190a_64: rt5190a@64 { + compatible = "richtek,rt5190a"; + reg = <0x64>; + vin2-supply = <&rt5190_buck1>; + vin3-supply = <&rt5190_buck1>; + vin4-supply = <&rt5190_buck1>; + + regulators { + rt5190_buck1: buck1 { + regulator-name = "rt5190a-buck1"; + regulator-min-microvolt = <5090000>; + regulator-max-microvolt = <5090000>; + regulator-allowed-modes = + ; + regulator-boot-on; + regulator-always-on; + }; + + buck2 { + regulator-name = "vcore"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + regulator-always-on; + }; + + rt5190_buck3: buck3 { + regulator-name = "vproc"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + regulator-always-on; + }; + + buck4 { + regulator-name = "rt5190a-buck4"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-allowed-modes = + ; + regulator-boot-on; + regulator-always-on; + }; + + ldo { + regulator-name = "rt5190a-ldo"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_1_pins>; + pinctrl-names = "default"; + status = "okay"; + + pca9545: i2c-mux@70 { + compatible = "nxp,pca9545"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + imux0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + pca9555: i2c-gpio-expander@20 { + compatible = "nxp,pca9555"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + }; + + rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; + + eeprom@57 { + compatible = "atmel,24c02"; + reg = <0x57>; + address-width = <8>; + pagesize = <8>; + size = <256>; + }; + }; + + imux1_sfp1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + imux2_sfp2: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + imux3_wifi: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +/* mPCIe SIM2 (11300000) */ +&pcie0 { + status = "okay"; +}; + +/* mPCIe (11310000 near leds) SIM3 */ +&pcie1 { + status = "okay"; +}; + +/* M.2 (11280000) 1L0 key-m SSD1 CN13 / key-b SIM1 CN15 */ +&pcie2 { + status = "okay"; +}; + +/* M.2 (11290000) 1L1 key-m SSD2 CN14 / key-b SIM2 CN18 */ +&pcie3 { + status = "okay"; +}; + +&pio { + gbe0_led0_pins: gbe0-led0-pins { + mux { + function = "led"; + groups = "gbe0_led0"; + }; + }; + + i2c0_pins: i2c0-g0-pins { + mux { + function = "i2c"; + groups = "i2c0_1"; + }; + }; + + i2c1_pins: i2c1-g0-pins { + mux { + function = "i2c"; + groups = "i2c1_0"; + }; + }; + + i2c2_1_pins: i2c2-g1-pins { + mux { + function = "i2c"; + groups = "i2c2_1"; + }; + }; + + mdio0_pins: mdio0-pins { + mux { + function = "eth"; + groups = "mdc_mdio0"; + }; + + conf { + pins = "SMI_0_MDC", "SMI_0_MDIO"; + drive-strength = <8>; + }; + }; + + mmc0_pins_emmc_51: mmc0-emmc-51-pins { + mux { + function = "flash"; + groups = "emmc_51"; + }; + }; + + mmc0_pins_sdcard: mmc0-sdcard-pins { + mux { + function = "flash"; + groups = "sdcard"; + }; + }; + + /* 1L0 0=key-b (CN15), 1=key-m (CN13) */ + pcie-2-hog { + gpio-hog; + gpios = <79 GPIO_ACTIVE_HIGH>; + output-high; + }; + + /* 1L1 0=key-b (CN18), 1=key-m (CN14) */ + pcie-3-hog { + gpio-hog; + gpios = <63 GPIO_ACTIVE_HIGH>; + output-high; + }; + + pwm0_pins: pwm0-pins { + mux { + groups = "pwm0"; + function = "pwm"; + }; + }; + + spi0_flash_pins: spi0-flash-pins { + mux { + function = "spi"; + groups = "spi0", "spi0_wp_hold"; + }; + }; +}; + +&pwm { + status = "okay"; +}; + +&serial0 { + status = "okay"; +}; + +&spi0 { + pinctrl-0 = <&spi0_flash_pins>; + pinctrl-names = "default"; + status = "okay"; + + spi_nand: nand@0 { + compatible = "spi-nand"; + reg = <0>; + spi-max-frequency = <52000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + }; +}; + +&spi_nand { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x0 0x200000>; + label = "bl2"; + }; + + partition@200000 { + compatible = "linux,ubi"; + reg = <0x200000 0xfe00000>; + label = "ubi"; + }; + }; +}; + +/* back USB */ +&ssusb0 { + /* Use U2P only instead of both U3P/U2P due to U3P serdes shared with pcie2 */ + phys = <&xphyu2port0 PHY_TYPE_USB2>; + mediatek,u3p-dis-msk = <1>; + status = "okay"; +}; + +/* front USB */ +&ssusb1 { + status = "okay"; +}; + +&switch { + dsa,member = <1 0>; + status = "okay"; +}; + +&tphy { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&xsphy { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi index 366203a72d6d2..bec590d26659c 100644 --- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi @@ -418,7 +418,7 @@ nvmem-cell-names = "lvts-calib-data-1"; }; - usb@11190000 { + ssusb0: usb@11190000 { compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci"; reg = <0 0x11190000 0 0x2e00>, <0 0x11193e00 0 0x0100>; @@ -714,6 +714,10 @@ #address-cells = <1>; #size-cells = <1>; + soc-uuid@140 { + reg = <0x140 0x10>; + }; + lvts_calibration: calib@918 { reg = <0x918 0x28>; }; @@ -995,6 +999,7 @@ int_2p5g_phy: ethernet-phy@15 { compatible = "ethernet-phy-ieee802.3-c45"; reg = <15>; + status = "disabled"; }; }; }; diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index 960d8955d018c..4e20a8f2eb258 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -1445,11 +1445,11 @@ }; }; - audiosys: audio-controller@11220000 { + audiosys: clock-controller@11220000 { compatible = "mediatek,mt8183-audiosys", "syscon"; reg = <0 0x11220000 0 0x1000>; #clock-cells = <1>; - afe: mt8183-afe-pcm { + afe: audio-controller { compatible = "mediatek,mt8183-audio"; interrupts = ; resets = <&watchdog MT8183_TOPRGU_AUDIO_SW_RST>; diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi index ec452d6570314..c7adafaa83288 100644 --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi @@ -3067,7 +3067,7 @@ jpgdec@0,10000 { compatible = "mediatek,mt8195-jpgdec-hw"; - reg = <0 0 0x10000 0x10000>;/* JPGDEC_C1 */ + reg = <0 0x10000 0 0x10000>;/* JPGDEC_C1 */ iommus = <&iommu_vdo M4U_PORT_L19_JPGDEC_WDMA0>, <&iommu_vdo M4U_PORT_L19_JPGDEC_BSDMA0>, <&iommu_vdo M4U_PORT_L19_JPGDEC_WDMA1>, diff --git a/arch/arm64/boot/dts/mediatek/mt8196-gce.h b/arch/arm64/boot/dts/mediatek/mt8196-gce.h new file mode 100644 index 0000000000000..aa909e4f4964d --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8196-gce.h @@ -0,0 +1,612 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2025 MediaTek Inc. + * + */ + +#ifndef __DTS_GCE_MT8196_H +#define __DTS_GCE_MT8196_H + +/* GCE Thread Priority + * The GCE core has multiple GCE threads, each of which can independently + * execute its own sequence of instructions. + * However, the GCE threads on the same core cannot run in parallel. + * Different GCE threads can determine thread priority based on the scenario, + * thereby serving different user needs. + * + * Low priority thread is executed when no high priority thread is active. + * Same priority thread is scheduled by round robin. + */ +#define CMDQ_THR_PRIO_LOWEST 0 +#define CMDQ_THR_PRIO_1 1 +#define CMDQ_THR_PRIO_2 2 +#define CMDQ_THR_PRIO_3 3 +#define CMDQ_THR_PRIO_4 4 +#define CMDQ_THR_PRIO_5 5 +#define CMDQ_THR_PRIO_6 6 +#define CMDQ_THR_PRIO_HIGHEST 7 + +/* + * GCE0 Hardware Event IDs + * Different SoCs will have varying numbers of hardware event signals, + * which are sent from the corresponding hardware to the GCE. + * Each hardware event signal corresponds to an event ID in the GCE. + * The CMDQ driver can use the following event ID definitions to allow + * the client driver to use wait and clear APIs provided by CMDQ, enabling + * the GCE to execute operations in the instructions for that event ID. + * + * The event IDs of GCE0 are mainly used by display hardware. + */ +/* CMDQ_EVENT_DISP0_STREAM_SOF0 ~ 15: 0 ~ 15 */ +#define CMDQ_EVENT_DISP0_STREAM_SOF(n) (0 + (n)) +/* CMDQ_EVENT_DISP0_FRAME_DONE_SEL0 ~ 15: 16 ~ 31 */ +#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL(n) (16 + (n)) +#define CMDQ_EVENT_DISP0_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT 32 +#define CMDQ_EVENT_DISP0_DISP_WDMA0_SW_RST_DONE_ENG_EVENT 33 +#define CMDQ_EVENT_DISP0_DISP_POSTMASK1_RST_DONE_ENG_EVENT 34 +#define CMDQ_EVENT_DISP0_DISP_POSTMASK0_RST_DONE_ENG_EVENT 35 +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_TIMEOUT_ENG_EVENT 36 +/* CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT0 ~ 15: 37 ~ 52 */ +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT(n) (37 + (n)) +#define CMDQ_EVENT_DISP0_DISP_MUTEX0_GET_RELEASE_ENG_EVENT 53 +#define CMDQ_EVENT_DISP0_DISP_MDP_RDMA0_SW_RST_DONE_ENG_EVENT 54 +/* CMDQ_EVENT_DISP1_STREAM_SOF0 ~ 15: 55 ~ 70 */ +#define CMDQ_EVENT_DISP1_STREAM_SOF(n) (55 + (n)) +/* CMDQ_EVENT_DISP1_FRAME_DONE_SEL0 ~ 15: 71 ~ 86 */ +#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL(n) (71 + (n)) +/* CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT0 ~ 15: 87 ~ 102 */ +#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT(n) (87 + (n)) +/* CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT0 ~ 15: 103 ~ 118 */ +#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT(n) (103 + (n)) +#define CMDQ_EVENT_DISP1_OCIP_SUBSYS_SRAM_ISOINT_ENG_EVENT 119 +#define CMDQ_EVENT_DISP1_DISP_WDMA4_TARGET_LINE_END_ENG_EVENT 120 +#define CMDQ_EVENT_DISP1_DISP_WDMA4_SW_RST_DONE_ENG_EVENT 121 +#define CMDQ_EVENT_DISP1_DISP_WDMA3_TARGET_LINE_END_ENG_EVENT 122 +#define CMDQ_EVENT_DISP1_DISP_WDMA3_SW_RST_DONE_ENG_EVENT 123 +#define CMDQ_EVENT_DISP1_DISP_WDMA2_TARGET_LINE_END_ENG_EVENT 124 +#define CMDQ_EVENT_DISP1_DISP_WDMA2_SW_RST_DONE_ENG_EVENT 125 +#define CMDQ_EVENT_DISP1_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT 126 +#define CMDQ_EVENT_DISP1_DISP_WDMA1_SW_RST_DONE_ENG_EVENT 127 +#define CMDQ_EVENT_DISP1_DISP_MUTEX0_TIMEOUT_ENG_EVENT 128 +#define CMDQ_EVENT_DISP1_DISP_MUTEX0_GET_RLZ_ENG_EVENT 129 +#define CMDQ_EVENT_DISP1_DISP_MDP_RDMA1_SW_RST_DONE_ENG_EVENT 130 +#define CMDQ_EVENT_DISP1_DISP_GDMA0_SW_RST_DONE_ENG_EVENT 131 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VSYNC_START_ENG_EVENT 132 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VSYNC_END_ENG_EVENT 133 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VRR_VFP_LAST_SAFE_BLANK_ENG_EVENT 134 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VFP_START_ENG_EVENT 135 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VFP_LAST_LINE_ENG_EVENT 136 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VDE_END_ENG_EVENT 137 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TRIGGER_LOOP_CLR_ENG_EVENT 138 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TARGET_LINE1_ENG_EVENT 139 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TARGET_LINE0_ENG_EVENT 140 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VSYNC_START_ENG_EVENT 141 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VSYNC_END_ENG_EVENT 142 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VDE_START_ENG_EVENT 143 +#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VDE_END_ENG_EVENT 144 +/* CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT0 ~ 10: 145 ~ 155 */ +#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT(n) (145 + (n)) +/* CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT0 ~ 21: 156 ~ 177 */ +#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT(n) (156 + (n)) +/* CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT0 ~ 10: 178 ~ 188 */ +#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT(n) (178 + (n)) +#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VSYNC_START_ENG_EVENT 189 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VSYNC_END_ENG_EVENT 190 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VDE_START_ENG_EVENT 191 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VDE_END_ENG_EVENT 192 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_TARGET_LINE_ENG_EVENT 193 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VSYNC_START_ENG_EVENT 194 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VSYNC_END_ENG_EVENT 195 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VDE_START_ENG_EVENT 196 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VDE_END_ENG_EVENT 197 +#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_TARGET_LINE_ENG_EVENT 198 +/* CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT0 ~ 10: 199 ~ 209 */ +#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT(n) (199 + (n)) +/* CMDQ_EVENT_MML0_STREAM_SOF0 ~ 15: 210 ~ 225 */ +#define CMDQ_EVENT_MML0_STREAM_SOF(n) (210 + (n)) +/* CMDQ_EVENT_MML0_FRAME_DONE_SEL0 ~ 15: 226 ~ 241 */ +#define CMDQ_EVENT_MML0_FRAME_DONE_SEL(n) (226 + (n)) +/* CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT0 ~ 15: 242 ~ 257 */ +#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT(n) (242 + (n)) +#define CMDQ_EVENT_MML0_MDP_WROT2_SW_RST_DONE_ENG_EVENT 258 +#define CMDQ_EVENT_MML0_MDP_WROT1_SW_RST_DONE_ENG_EVENT 259 +#define CMDQ_EVENT_MML0_MDP_WROT0_SW_RST_DONE_ENG_EVENT 260 +#define CMDQ_EVENT_MML0_MDP_RROT0_SW_RST_DONE_ENG_EVENT 261 +#define CMDQ_EVENT_MML0_MDP_RDMA2_SW_RST_DONE_ENG_EVENT 262 +#define CMDQ_EVENT_MML0_MDP_RDMA1_SW_RST_DONE_ENG_EVENT 263 +#define CMDQ_EVENT_MML0_MDP_RDMA0_SW_RST_DONE_ENG_EVENT 264 +#define CMDQ_EVENT_MML0_MDP_MERGE0_SW_RST_DONE_ENG_EVENT 265 +#define CMDQ_EVENT_MML0_DISP_MUTEX0_TIMEOUT_ENG_EVENT 266 +#define CMDQ_EVENT_MML0_DISP_MUTEX0_GET_RLZ_ENG_EVENT 267 +/* CMDQ_EVENT_MML1_STREAM_SOF0 ~ 15: 268 ~ 283 */ +#define CMDQ_EVENT_MML1_STREAM_SOF(n) (268 + (n)) +/* CMDQ_EVENT_MML1_FRAME_DONE_SEL0 ~ 15: 284 ~ 299 */ +#define CMDQ_EVENT_MML1_FRAME_DONE_SEL(n) (284 + (n)) +/* CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT0 ~ 15: 300 ~ 315 */ +#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT(n) (300 + (n)) +#define CMDQ_EVENT_MML1_MDP_WROT2_SW_RST_DONE_ENG_EVENT 316 +#define CMDQ_EVENT_MML1_MDP_WROT1_SW_RST_DONE_ENG_EVENT 317 +#define CMDQ_EVENT_MML1_MDP_WROT0_SW_RST_DONE_ENG_EVENT 318 +#define CMDQ_EVENT_MML1_MDP_RROT0_SW_RST_DONE_ENG_EVENT 319 +#define CMDQ_EVENT_MML1_MDP_RDMA2_SW_RST_DONE_ENG_EVENT 320 +#define CMDQ_EVENT_MML1_MDP_RDMA1_SW_RST_DONE_ENG_EVENT 321 +#define CMDQ_EVENT_MML1_MDP_RDMA0_SW_RST_DONE_ENG_EVENT 322 +#define CMDQ_EVENT_MML1_MDP_MERGE0_SW_RST_DONE_ENG_EVENT 323 +#define CMDQ_EVENT_MML1_DISP_MUTEX0_TIMEOUT_ENG_EVENT 324 +#define CMDQ_EVENT_MML1_DISP_MUTEX0_GET_RLZ_ENG_EVENT 325 +/* CMDQ_EVENT_OVL0_STREAM_SOF0 ~ 15: 326 ~ 341 */ +#define CMDQ_EVENT_OVL0_STREAM_SOF(n) (326 + (n)) +/* CMDQ_EVENT_OVL0_FRAME_DONE_SEL0 ~ 15: 342 ~ 357 */ +#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL(n) (342 + (n)) +#define CMDQ_EVENT_OVL0_OVL_UFBC_WDMA0_TARGET_LINE_END_ENG_EVENT 358 +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_TIMEOUT_ENG_EVENT 359 +/* CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT0 ~ 15: 360 ~ 375 */ +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT(n) (360 + (n)) +#define CMDQ_EVENT_OVL0_OVL_MUTEX0_GET_RELEASE_ENG_EVENT 376 +#define CMDQ_EVENT_OVL0_OVL_MDP_RDMA1_SW_RST_DONE_ENG_EVENT 377 +#define CMDQ_EVENT_OVL0_OVL_MDP_RDMA0_SW_RST_DONE_ENG_EVENT 378 +#define CMDQ_EVENT_OVL0_OVL_EXDMA9_FRAME_RESET_DONE_ENG_EVENT 379 +#define CMDQ_EVENT_OVL0_OVL_EXDMA8_FRAME_RESET_DONE_ENG_EVENT 380 +#define CMDQ_EVENT_OVL0_OVL_EXDMA7_FRAME_RESET_DONE_ENG_EVENT 381 +#define CMDQ_EVENT_OVL0_OVL_EXDMA6_FRAME_RESET_DONE_ENG_EVENT 382 +#define CMDQ_EVENT_OVL0_OVL_EXDMA5_FRAME_RESET_DONE_ENG_EVENT 383 +#define CMDQ_EVENT_OVL0_OVL_EXDMA4_FRAME_RESET_DONE_ENG_EVENT 384 +#define CMDQ_EVENT_OVL0_OVL_EXDMA3_FRAME_RESET_DONE_ENG_EVENT 385 +#define CMDQ_EVENT_OVL0_OVL_EXDMA2_FRAME_RESET_DONE_ENG_EVENT 386 +#define CMDQ_EVENT_OVL0_OVL_EXDMA1_FRAME_RESET_DONE_ENG_EVENT 387 +#define CMDQ_EVENT_OVL0_OVL_EXDMA0_FRAME_RESET_DONE_ENG_EVENT 388 +#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT 389 +#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA1_SW_RST_DONE_END_ENG_EVENT 390 +#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT 391 +#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA0_SW_RST_DONE_END_ENG_EVENT 392 +#define CMDQ_EVENT_OVL0_OVL_BWM0_FRAME_RESET_DONE_ENG_EVENT 393 +/* CMDQ_EVENT_OVL1_STREAM_SOF0 ~ 15: 394 ~ 409 */ +#define CMDQ_EVENT_OVL1_STREAM_SOF(n) (394 + (n)) +/* CMDQ_EVENT_OVL1_FRAME_DONE_SEL0 ~ 15: 410 ~ 425 */ +#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL(n) (410 + (n)) +#define CMDQ_EVENT_OVL1_OVL_UFBC_WDMA0_TARGET_LINE_END_ENG_EVENT 426 +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_TIMEOUT_ENG_EVENT 427 +/* CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT0 ~ 15: 428 ~ 443 */ +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT(n) (428 + (n)) +#define CMDQ_EVENT_OVL1_OVL_MUTEX0_GET_RELEASE_ENG_EVENT 444 +#define CMDQ_EVENT_OVL1_OVL_MDP_RDMA1_SW_RST_DONE_ENG_EVENT 445 +#define CMDQ_EVENT_OVL1_OVL_MDP_RDMA0_SW_RST_DONE_ENG_EVENT 446 +#define CMDQ_EVENT_OVL1_OVL_EXDMA9_FRAME_RESET_DONE_ENG_EVENT 447 +#define CMDQ_EVENT_OVL1_OVL_EXDMA8_FRAME_RESET_DONE_ENG_EVENT 448 +#define CMDQ_EVENT_OVL1_OVL_EXDMA7_FRAME_RESET_DONE_ENG_EVENT 449 +#define CMDQ_EVENT_OVL1_OVL_EXDMA6_FRAME_RESET_DONE_ENG_EVENT 450 +#define CMDQ_EVENT_OVL1_OVL_EXDMA5_FRAME_RESET_DONE_ENG_EVENT 451 +#define CMDQ_EVENT_OVL1_OVL_EXDMA4_FRAME_RESET_DONE_ENG_EVENT 452 +#define CMDQ_EVENT_OVL1_OVL_EXDMA3_FRAME_RESET_DONE_ENG_EVENT 453 +#define CMDQ_EVENT_OVL1_OVL_EXDMA2_FRAME_RESET_DONE_ENG_EVENT 454 +#define CMDQ_EVENT_OVL1_OVL_EXDMA1_FRAME_RESET_DONE_ENG_EVENT 455 +#define CMDQ_EVENT_OVL1_OVL_EXDMA0_FRAME_RESET_DONE_ENG_EVENT 456 +#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT 457 +#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA1_SW_RST_DONE_END_ENG_EVENT 458 +#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT 459 +#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA0_SW_RST_DONE_END_ENG_EVENT 460 +#define CMDQ_EVENT_OVL1_OVL_BWM0_FRAME_RESET_DONE_ENG_EVENT 461 +#define CMDQ_EVENT_DPC_DT_DONE0 462 +#define CMDQ_EVENT_DPC_DT_DONE1 463 +#define CMDQ_EVENT_DPC_DT_DONE2_0_MERGE 464 +#define CMDQ_EVENT_DPC_DT_DONE2_1_MERGE 465 +#define CMDQ_EVENT_DPC_DT_DONE2_2_MERGE 466 +#define CMDQ_EVENT_DPC_DT_DONE2_3_MERGE 467 +#define CMDQ_EVENT_DPC_DT_DONE3 468 +#define CMDQ_EVENT_DPC_DT_DONE4_MERGE 469 +#define CMDQ_EVENT_DPC_DT_DONE5 470 +#define CMDQ_EVENT_DPC_DT_DONE6_0_MERGE 471 +#define CMDQ_EVENT_DPC_DT_DONE6_1_MERGE 472 +#define CMDQ_EVENT_DPC_DT_DONE6_2_MERGE 473 +#define CMDQ_EVENT_DPC_DT_DONE6_3_MERGE 474 +#define CMDQ_EVENT_DPC_DT_DONE7 475 +#define CMDQ_EVENT_DPC_DT_DONE32_MERGE 476 +#define CMDQ_EVENT_DPC_DT_DONE33 477 +#define CMDQ_EVENT_DPC_DT_DONE34_0 478 +#define CMDQ_EVENT_DPC_DT_DONE35 479 +#define CMDQ_EVENT_DPC_DISP_SSYS_DT_ERR_ON_BEFORE_OFF 480 +#define CMDQ_EVENT_DPC_DISP_SSYS_DT_ERR_PRETE_BEFORE_ON 481 +#define CMDQ_EVENT_DPC_DISP_DVFS_DT_ERR_ON_BEFORE_OFF 482 +#define CMDQ_EVENT_DPC_DISP_DVFS_DT_ERR_PRETE_BEFORE_ON 483 +#define CMDQ_EVENT_DPC_DISP_SB_DT_ERR_ON_BEFORE_OFF 484 +#define CMDQ_EVENT_DPC_DISP_SB_DT_ERR_PRETE_BEFORE_ON 485 +#define CMDQ_EVENT_DPC_DISP_SW_CONFIG_WHEN_MTCMOS_OFF 486 +#define CMDQ_EVENT_DPC_MML_SSYS_DT_ERR_ON_BEFORE_OFF 487 +#define CMDQ_EVENT_DPC_MML_SSYS_DT_ERR_PRETE_BEFORE_ON 488 +#define CMDQ_EVENT_DPC_MML_DVFS_DT_ERR_ON_BEFORE_OFF 489 +#define CMDQ_EVENT_DPC_MML_DVFS_DT_ERR_PRETE_BEFORE_ON 490 +#define CMDQ_EVENT_DPC_MML_SB_DT_ERR_ON_BEFORE_OFF 491 +#define CMDQ_EVENT_DPC_MML_SB_DT_ERR_PRETE_BEFORE_ON 492 +#define CMDQ_EVENT_DPC_MML_SW_CONFIG_WHEN_MTCMOS_OFF 493 +/* CMDQ_EVENT_DPTX_DPTX_EVENT0 ~ 3: 494 ~ 497 */ +#define CMDQ_EVENT_DPTX_DPTX_EVENT(n) (494 + (n)) +/* CMDQ_EVENT_EDPTX_EDPTX_EVENT0 ~ 1: 498 ~ 499 */ +#define CMDQ_EVENT_EDPTX_EDPTX_EVENT(n) (498 + (n)) + +#define CMDQ_EVENT_DSI0_TE_I_DSI0_TE_I 898 +#define CMDQ_EVENT_DSI1_TE_I_DSI1_TE_I 899 +#define CMDQ_EVENT_DSI2_TE_I_DSI2_TE_I 900 +/* CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK0 ~ 23: 901 ~ 924 */ +#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK(n) (901 + (n)) +/* CMDQ_EVENT_GCE_EVENT_DPTX_GCE_EVENT_DPTX0 ~ 1: 925 ~ 926 */ +#define CMDQ_EVENT_GCE_EVENT_DPTX_GCE_EVENT_DPTX(n) (925 + (n)) +/* CMDQ_EVENT_GCE_EVENT_DPTX_P1_GCE_EVENT_DPTX_P10 ~ 1: 927 ~ 928 */ +#define CMDQ_EVENT_GCE_EVENT_DPTX_P1_GCE_EVENT_DPTX_P1(n) (927 + (n)) +/* CMDQ_EVENT_GCE_EVENT_EDPTX_GCE_EVENT_EDPTX0 ~ 1: 929 ~ 930 */ +#define CMDQ_EVENT_GCE_EVENT_EDPTX_GCE_EVENT_EDPTX(n) (929 + (n)) +#define CMDQ_EVENT_DSI3_TE_I_DSI3_TE_I 931 +#define CMDQ_EVENT_SPI0_FINISH_EVENT_DSI4_TE_I 932 +#define CMDQ_EVENT_SPI0_EVENT_EVENT_DSI5_TE_I 933 + +/* + * GCE1 Hardware Event IDs + * Different SoCs will have varying numbers of hardware event signals, + * which are sent from the corresponding hardware to the GCE. + * Each hardware event signal corresponds to an event ID in the GCE. + * The CMDQ driver can use the following event ID definitions to allow + * the client driver to use wait and clear APIs provided by CMDQ, enabling + * the GCE to execute operations in the instructions for that event ID. + * + * The event IDs of GCE1 are mainly used by non-display hardware. + */ +#define CMDQ_EVENT_VENC3_VENC_RESERVED 0 +#define CMDQ_EVENT_VENC3_VENC_FRAME_DONE 1 +#define CMDQ_EVENT_VENC3_VENC_PAUSE_DONE 2 +#define CMDQ_EVENT_VENC3_JPGENC_DONE 3 +#define CMDQ_EVENT_VENC3_VENC_MB_DONE 4 +#define CMDQ_EVENT_VENC3_VENC_128BYTE_DONE 5 +#define CMDQ_EVENT_VENC3_JPGDEC_DONE 6 +#define CMDQ_EVENT_VENC3_JPGDEC_C1_DONE 7 +#define CMDQ_EVENT_VENC3_JPGDEC_INSUFF_DONE 8 +#define CMDQ_EVENT_VENC3_JPGDEC_C1_INSUFF_DONE 9 +#define CMDQ_EVENT_VENC3_WP_2ND_STAGE_DONE 10 +#define CMDQ_EVENT_VENC3_WP_3RD_STAGE_DONE 11 +#define CMDQ_EVENT_VENC3_PPS_HEADER_DONE 12 +#define CMDQ_EVENT_VENC3_SPS_HEADER_DONE 13 +#define CMDQ_EVENT_VENC3_VPS_HEADER_DONE 14 +#define CMDQ_EVENT_VENC3_VENC_SLICE_DONE 15 +#define CMDQ_EVENT_VENC3_VENC_SOC_SLICE_DONE 16 +#define CMDQ_EVENT_VENC3_VENC_SOC_FRAME_DONE 17 + +#define CMDQ_EVENT_VENC2_VENC_FRAME_DONE 33 +#define CMDQ_EVENT_VENC2_VENC_PAUSE_DONE 34 +#define CMDQ_EVENT_VENC2_JPGENC_DONE 35 +#define CMDQ_EVENT_VENC2_VENC_MB_DONE 36 +#define CMDQ_EVENT_VENC2_VENC_128BYTE_DONE 37 +#define CMDQ_EVENT_VENC2_JPGDEC_DONE 38 +#define CMDQ_EVENT_VENC2_JPGDEC_C1_DONE 39 +#define CMDQ_EVENT_VENC2_JPGDEC_INSUFF_DONE 40 +#define CMDQ_EVENT_VENC2_JPGDEC_C1_INSUFF_DONE 41 +#define CMDQ_EVENT_VENC2_WP_2ND_STAGE_DONE 42 +#define CMDQ_EVENT_VENC2_WP_3RD_STAGE_DONE 43 +#define CMDQ_EVENT_VENC2_PPS_HEADER_DONE 44 +#define CMDQ_EVENT_VENC2_SPS_HEADER_DONE 45 +#define CMDQ_EVENT_VENC2_VPS_HEADER_DONE 46 +#define CMDQ_EVENT_VENC2_VENC_SLICE_DONE 47 +#define CMDQ_EVENT_VENC2_VENC_SOC_SLICE_DONE 48 +#define CMDQ_EVENT_VENC2_VENC_SOC_FRAME_DONE 49 + +#define CMDQ_EVENT_VENC1_VENC_FRAME_DONE 65 +#define CMDQ_EVENT_VENC1_VENC_PAUSE_DONE 66 +#define CMDQ_EVENT_VENC1_JPGENC_DONE 67 +#define CMDQ_EVENT_VENC1_VENC_MB_DONE 68 +#define CMDQ_EVENT_VENC1_VENC_128BYTE_DONE 69 +#define CMDQ_EVENT_VENC1_JPGDEC_DONE 70 +#define CMDQ_EVENT_VENC1_JPGDEC_C1_DONE 71 +#define CMDQ_EVENT_VENC1_JPGDEC_INSUFF_DONE 72 +#define CMDQ_EVENT_VENC1_JPGDEC_C1_INSUFF_DONE 73 +#define CMDQ_EVENT_VENC1_WP_2ND_STAGE_DONE 74 +#define CMDQ_EVENT_VENC1_WP_3RD_STAGE_DONE 75 +#define CMDQ_EVENT_VENC1_PPS_HEADER_DONE 76 +#define CMDQ_EVENT_VENC1_SPS_HEADER_DONE 77 +#define CMDQ_EVENT_VENC1_VPS_HEADER_DONE 78 +#define CMDQ_EVENT_VENC1_VENC_SLICE_DONE 79 +#define CMDQ_EVENT_VENC1_VENC_SOC_SLICE_DONE 80 +#define CMDQ_EVENT_VENC1_VENC_SOC_FRAME_DONE 81 + +#define CMDQ_EVENT_VDEC1_VDEC_LINE_CNT_INT 192 +#define CMDQ_EVENT_VDEC1_VDEC_INT 193 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_2 194 +#define CMDQ_EVENT_VDEC1_VDEC_DEC_ERR 195 +#define CMDQ_EVENT_VDEC1_VDEC_BUSY_OVERFLOW 196 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_5 197 +#define CMDQ_EVENT_VDEC1_VDEC_INI_FETCH_RDY 198 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_7 199 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_8 200 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_9 201 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_10 202 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_11 203 + +#define CMDQ_EVENT_VDEC1_VDEC_GCE_CNT_OP_THR 207 + +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_32 224 +#define CMDQ_EVENT_VDEC1_VDEC_LAT_INT 225 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_34 226 +#define CMDQ_EVENT_VDEC1_VDEC_LAT_DEC_ERR 227 +#define CMDQ_EVENT_VDEC1_VDEC_LAT_BUSY_OVERFLOW 228 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_37 229 +#define CMDQ_EVENT_VDEC1_VDEC_LAT_INI_FETCH_RDY 230 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_39 231 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_40 232 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_41 233 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_42 234 +#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_43 235 + +#define CMDQ_EVENT_VDEC1_VDEC_LAT_GCE_CNT_OP_THR 239 + +#define CMDQ_EVENT_IMG_IMG_EVENT_0 256 +/* CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_0 ~ 5: 257 ~ 262 */ +#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0(n) (257 + (n)) +#define CMDQ_EVENT_IMG_TRAW0_DMA_ERR_EVENT 263 +#define CMDQ_EVENT_IMG_TRAW0_DUMMY_0 264 +/* CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_0 ~ 5: 265 ~ 270 */ +#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0(n) (265 + (n)) +#define CMDQ_EVENT_IMG_TRAW1_DMA_ERR_EVENT 271 +#define CMDQ_EVENT_IMG_ADL_TILE_DONE_EVENT 272 +#define CMDQ_EVENT_IMG_ADLWR0_TILE_DONE_EVENT 273 +#define CMDQ_EVENT_IMG_ADLWR1_TILE_DONE_EVENT 274 +#define CMDQ_EVENT_IMG_IMGSYS_IPE_ME_DONE 275 +#define CMDQ_EVENT_IMG_IMGSYS_IPE_MMG_DONE 276 +/* CMDQ_EVENT_IMG_QOF_ACK_EVENT0 ~ 19: 277 ~ 296 */ +#define CMDQ_EVENT_IMG_QOF_ACK_EVENT(n) (277 + (n)) +/* CMDQ_EVENT_IMG_QOF_ON_EVENT0 ~ 4: 297 ~ 301 */ +#define CMDQ_EVENT_IMG_QOF_ON_EVENT(n) (297 + (n)) +/* CMDQ_EVENT_IMG_QOF_OFF_EVENT0 ~ 4: 302 ~ 306 */ +#define CMDQ_EVENT_IMG_QOF_OFF_EVENT(n) (302 + (n)) +/* CMDQ_EVENT_IMG_QOF_SAVE_EVENT0 ~ 4: 307 ~ 311 */ +#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT(n) (307 + (n)) +/* CMDQ_EVENT_IMG_QOF_RESTORE_EVENT0 ~ 4: 312 ~ 316 */ +#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT(n) (312 + (n)) +/* CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P20~5: 317 ~ 322 */ +#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2(n) (317 + (n)) +#define CMDQ_EVENT_IMG_DIP_DMA_ERR_EVENT 323 +#define CMDQ_EVENT_IMG_DIP_NR_DMA_ERR_EVENT 324 +#define CMDQ_EVENT_IMG_DIP_DUMMY_0 325 +#define CMDQ_EVENT_IMG_WPE_EIS_GCE_FRAME_DONE 326 +#define CMDQ_EVENT_IMG_WPE_EIS_DONE_SYNC_OUT 327 +/* CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P20 ~ 5: 328 ~ 333 */ +#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2(n) (328 + (n)) +/* CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P20 ~ 5: 334 ~ 339 */ +#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2(n) (334 + (n)) +#define CMDQ_EVENT_IMG_PQA_DMA_ERR_EVENT 340 +/* CMDQ_EVENT_IMG_WPE0_DUMMY0~2: 341 ~ 343 */ +#define CMDQ_EVENT_IMG_WPE0_DUMMY(n) (341 + (n)) +#define CMDQ_EVENT_IMG_OMC_TNR_GCE_FRAME_DONE 344 +#define CMDQ_EVENT_IMG_OMC_TNR_DONE_SYNC_OUT 345 +/* CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P20 ~ 5: 346 ~ 351 */ +#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2(n) (346 + (n)) +/* CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P20 ~ 5: 352 ~ 357 */ +#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2(n) (352 + (n)) +#define CMDQ_EVENT_IMG_PQB_DMA_ERR_EVENT 358 +/* CMDQ_EVENT_IMG_WPE1_DUMMY0 ~ 2: 359 ~ 361 */ +#define CMDQ_EVENT_IMG_WPE1_DUMMY(n) (359 + (n)) +#define CMDQ_EVENT_IMG_WPE_LITE_GCE_FRAME_DONE 362 +#define CMDQ_EVENT_IMG_WPE_LITE_DONE_SYNC_OUT 363 +/* CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P20 ~ 5: 364 ~ 369 */ +#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2(n) (364 + (n)) +#define CMDQ_EVENT_IMG_OMC_LITE_GCE_FRAME_DONE 370 +#define CMDQ_EVENT_IMG_OMC_LITE_DONE_SYNC_OUT 371 +/* CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P20 ~ 5: 372 ~ 377 */ +#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2(n) (372 + (n)) +/* CMDQ_EVENT_IMG_WPE2_DUMMY0 ~ 2: 378 ~ 380 */ +#define CMDQ_EVENT_IMG_WPE2_DUMMY(n) (378 + (n)) +#define CMDQ_EVENT_IMG_IMGSYS_IPE_FDVT0_DONE 381 +#define CMDQ_EVENT_IMG_IMG_EVENT_126 382 +#define CMDQ_EVENT_IMG_IMG_EVENT_127 383 +#define CMDQ_EVENT_CAM_CAM_EVENT_0 384 +#define CMDQ_EVENT_CAM_CAM_SUBA_SW_PASS1_DONE 385 +#define CMDQ_EVENT_CAM_CAM_SUBB_SW_PASS1_DONE 386 +#define CMDQ_EVENT_CAM_CAM_SUBC_SW_PASS1_DONE 387 +#define CMDQ_EVENT_CAM_CAM_SUBA_TFMR_PASS1_DONE 388 +#define CMDQ_EVENT_CAM_CAM_SUBB_TFMR_PASS1_DONE 389 +#define CMDQ_EVENT_CAM_CAM_SUBC_TFMR_PASS1_DONE 390 +/* CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE0 ~ 3: 391 ~ 394 */ +#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE(n) (391 + (n)) +/* CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE0 ~ 3: 395 ~ 398 */ +#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE(n) (395 + (n)) +/* CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE0 ~ 3: 399 + 402 */ +#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE(n) (399 + (n)) +/* CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE0 ~ 3: 403 ~ 406 */ +#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE(n) (403 + (n)) +/* CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE0 ~ 3: 407 ~ 409 */ +#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE(n) (407 + (n)) +/* CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE0 ~ 3: 411 ~ 413 */ +#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE(n) (411 + (n)) +#define CMDQ_EVENT_CAM_MRAW0_SW_PASS1_DONE 415 +#define CMDQ_EVENT_CAM_MRAW1_SW_PASS1_DONE 416 +#define CMDQ_EVENT_CAM_MRAW2_SW_PASS1_DONE 417 +#define CMDQ_EVENT_CAM_MRAW3_SW_PASS1_DONE 418 +#define CMDQ_EVENT_CAM_UISP_SW_PASS1_DONE 419 +#define CMDQ_EVENT_CAM_TG_MRAW0_OUT_SOF 420 +#define CMDQ_EVENT_CAM_TG_MRAW1_OUT_SOF 421 +#define CMDQ_EVENT_CAM_TG_MRAW2_OUT_SOF 422 +#define CMDQ_EVENT_CAM_TG_MRAW3_OUT_SOF 423 +#define CMDQ_EVENT_CAM_PDA0_IRQO_EVENT_DONE_D1 424 +#define CMDQ_EVENT_CAM_PDA1_IRQO_EVENT_DONE_D1 425 +#define CMDQ_EVENT_CAM_DPE_DVP_CMQ_EVENT 426 +#define CMDQ_EVENT_CAM_DPE_DVS_CMQ_EVENT 427 +#define CMDQ_EVENT_CAM_DPE_DVFG_CMQ_EVENT 428 +#define CMDQ_EVENT_CAM_CAM_EVENT_45 429 +#define CMDQ_EVENT_CAM_CAM_EVENT_46 430 +#define CMDQ_EVENT_CAM_CAM_EVENT_47 431 +#define CMDQ_EVENT_CAM_CAM_EVENT_48 432 +/* CMDQ_EVENT_CAM_CAM_SUBA_TG_INT1 ~ 4: 433 ~ 436 */ +#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT(n) (433 + (n) - 1) +/* CMDQ_EVENT_CAM_CAM_SUBB_TG_INT1 ~ 4: 437 ~ 440 */ +#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT(n) (437 + (n) - 1) +/* CMDQ_EVENT_CAM_CAM_SUBC_TG_INT1 ~ 4: 441 ~ 444 */ +#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT(n) (441 + (n) - 1) +#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBA 445 +#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBB 446 +#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBC 447 +#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBA 448 +#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBB 449 +#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBC 450 +#define CMDQ_EVENT_CAM_RAW_SEL_SOF_UISP 451 +#define CMDQ_EVENT_CAM_CAM_SUBA_RING_BUFFER_OVERFLOW_INT_IN 452 +#define CMDQ_EVENT_CAM_CAM_SUBB_RING_BUFFER_OVERFLOW_INT_IN 453 +#define CMDQ_EVENT_CAM_CAM_SUBC_RING_BUFFER_OVERFLOW_INT_IN 454 +#define CMDQ_EVENT_CAM_CAM_EVENT_71 455 +#define CMDQ_EVENT_CAM_ADL_WR_FRAME_DONE 456 +#define CMDQ_EVENT_CAM_ADL_RD_FRAME_DONE 457 +#define CMDQ_EVENT_CAM_QOF_RAWA_POWER_ON_EVENT 458 +#define CMDQ_EVENT_CAM_QOF_RAWB_POWER_ON_EVENT 459 +#define CMDQ_EVENT_CAM_QOF_RAWC_POWER_ON_EVENT 460 +#define CMDQ_EVENT_CAM_QOF_RAWA_POWER_OFF_EVENT 461 +#define CMDQ_EVENT_CAM_QOF_RAWB_POWER_OFF_EVENT 462 +#define CMDQ_EVENT_CAM_QOF_RAWC_POWER_OFF_EVENT 463 +#define CMDQ_EVENT_CAM_QOF_RAWA_SAVE_EVENT 464 +#define CMDQ_EVENT_CAM_QOF_RAWB_SAVE_EVENT 465 +#define CMDQ_EVENT_CAM_QOF_RAWC_SAVE_EVENT 466 +#define CMDQ_EVENT_CAM_QOF_RAWA_RESTORE_EVENT 467 +#define CMDQ_EVENT_CAM_QOF_RAWB_RESTORE_EVENT 468 +#define CMDQ_EVENT_CAM_QOF_RAWC_RESTORE_EVENT 469 +/* CMDQ_EVENT_CAM_QOF_CAM_EVENT0 ~ 11: 470 ~ 481 */ +#define CMDQ_EVENT_CAM_QOF_CAM_EVENT(n) (470 + (n)) +/* CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT0 ~ 11: 482 ~ 495 */ +#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT(n) (482 + (n)) +#define CMDQ_EVENT_CAM_CCU0_TO_GCE_NON_SEC_IRQ 496 +#define CMDQ_EVENT_CAM_CCU0_TO_GCE_SEC_IRQ 497 +#define CMDQ_EVENT_CAM_CCU0_TO_GCE_VM_IRQ 498 +#define CMDQ_EVENT_CAM_CCU0_TO_GCE_EXCH_VM_IRQ 499 +#define CMDQ_EVENT_CAM_CCU1_TO_GCE_NON_SEC_IRQ 500 +#define CMDQ_EVENT_CAM_CCU1_TO_GCE_SEC_IRQ 501 +#define CMDQ_EVENT_CAM_CCU1_TO_GCE_VM_IRQ 502 +#define CMDQ_EVENT_CAM_CCU1_TO_GCE_EXCH_VM_IRQ 503 +/* CMDQ_EVENT_CAM_I2C_CH2_EVENT0 ~ 4: 504 ~ 509 */ +#define CMDQ_EVENT_CAM_I2C_CH2_EVENT(n) (504 + (n)) +#define CMDQ_EVENT_CAM_CAM_EVENT_125 509 +#define CMDQ_EVENT_CAM_CAM_EVENT_126 510 +#define CMDQ_EVENT_CAM_CAM_EVENT_127 511 + +#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_MMSRAM_COMM_SMIASSER 898 +#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_MDP_COMM_SMIASSER 899 +#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_DISP_COMM_SMIASSER 900 + +/* + * GCE Software Tokens + * Apart from the event IDs that are already bound to hardware event signals, + * the remaining event IDs can be used as software tokens. + * This allows the client driver to name and operate them independently, + * and their usage is the same as that of hardware events. + */ +/* Begin of GCE0 software token */ +/* Config thread notify trigger thread */ +#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY 640 +/* Trigger thread notify config thread */ +#define CMDQ_SYNC_TOKEN_STREAM_EOF 641 +/* Block Trigger thread until the ESD check finishes */ +#define CMDQ_SYNC_TOKEN_ESD_EOF 642 +#define CMDQ_SYNC_TOKEN_STREAM_BLOCK 643 +/* Check CABC setup finish */ +#define CMDQ_SYNC_TOKEN_CABC_EOF 644 +/* VFP period token for Msync */ +#define CMDQ_SYNC_TOKEN_VFP_PERIOD 645 +/* Software sync token for dual display */ +#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY_1 694 +#define CMDQ_SYNC_TOKEN_STREAM_EOF_1 695 +#define CMDQ_SYNC_TOKEN_ESD_EOF_1 696 +#define CMDQ_SYNC_TOKEN_STREAM_BLOCK_1 697 +#define CMDQ_SYNC_TOKEN_CABC_EOF_1 698 + +/* + * GPR access tokens (for HW register backup) + * There are 15 32-bit GPR, form 3 GPR as a set + * (64-bit for address, 32-bit for value) + * + * CMDQ_SYNC_TOKEN_GPR_SET0 ~ 4: 700 ~ 704 + */ +#define CMDQ_SYNC_TOKEN_GPR_SET(n) (700 + (n)) +#define CMDQ_SYNC_TOKEN_TE_0 705 +#define CMDQ_SYNC_TOKEN_PREFETCH_TE_0 706 +#define CMDQ_SYNC_TOKEN_VIDLE_POWER_ON 707 +#define CMDQ_SYNC_TOKEN_CHECK_TRIGGER_MERGE 708 + +/* Resource lock event to control resource in GCE thread */ +#define CMDQ_SYNC_RESOURCE_WROT0 710 +#define CMDQ_SYNC_RESOURCE_WROT1 711 +/* Hardware TRACE software token */ +#define CMDQ_SYNC_TOKEN_HW_TRACE_WAIT 712 +#define CMDQ_SYNC_TOKEN_HW_TRACE_LOCK 713 +/* Software sync token for dual display */ +#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY_3 714 +#define CMDQ_SYNC_TOKEN_STREAM_EOF_3 715 +#define CMDQ_SYNC_TOKEN_ESD_EOF_3 716 +#define CMDQ_SYNC_TOKEN_STREAM_BLOCK_3 717 +#define CMDQ_SYNC_TOKEN_CABC_EOF_3 718 +/* End of GCE0 software token */ + +/* Begin of GCE1 software token */ +/* CMDQ_SYNC_TOKEN_IMGSYS_POOL0 ~ 300: 512 ~ 812 */ +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL(n) (512 + (n)) +/* ISP software token */ +#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_EIS 813 +#define CMDQ_SYNC_TOKEN_IMGSYS_OMC_TNR 814 +#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_LITE 815 +#define CMDQ_SYNC_TOKEN_IMGSYS_TRAW 816 +#define CMDQ_SYNC_TOKEN_IMGSYS_LTRAW 817 +#define CMDQ_SYNC_TOKEN_IMGSYS_XTRAW 818 +#define CMDQ_SYNC_TOKEN_IMGSYS_DIP 819 +#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_A 820 +#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_B 821 +#define CMDQ_SYNC_TOKEN_IPESYS_ME 822 +#define CMDQ_SYNC_TOKEN_APUSYS_APU 823 +#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_TRAW 824 +#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_LTRAW 825 +#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_XTRAW 826 +#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_DIP 827 +#define CMDQ_SYNC_TOKEN_IMGSYS_OMC_LITE 828 +/* IMG software token for QoS */ +#define CMDQ_SYNC_TOKEN_IMGSYS_QOS_LOCK 829 +/* IMG software token for Qof */ +#define CMDQ_SYNC_TOKEN_DIP_POWER_CTRL 830 +#define CMDQ_SYNC_TOKEN_DIP_TRIG_PWR_ON 831 +#define CMDQ_SYNC_TOKEN_DIP_PWR_ON 832 +#define CMDQ_SYNC_TOKEN_DIP_TRIG_PWR_OFF 833 +#define CMDQ_SYNC_TOKEN_DIP_PWR_OFF 834 +#define CMDQ_SYNC_TOKEN_DIP_PWR_HAND_SHAKE 835 +#define CMDQ_SYNC_TOKEN_TRAW_POWER_CTRL 836 +#define CMDQ_SYNC_TOKEN_TRAW_TRIG_PWR_ON 837 +#define CMDQ_SYNC_TOKEN_TRAW_PWR_ON 838 +#define CMDQ_SYNC_TOKEN_TRAW_TRIG_PWR_OFF 839 +#define CMDQ_SYNC_TOKEN_TRAW_PWR_OFF 840 +#define CMDQ_SYNC_TOKEN_TRAW_PWR_HAND_SHAKE 841 +/* End of GCE1 software token */ + +/* Begin of common software token */ +/* + * Notify normal CMDQ there are some secure task done + * MUST NOT CHANGE, this token sync with secure world + */ +#define CMDQ_SYNC_SECURE_THR_EOF 940 +/* CMDQ use software token */ +#define CMDQ_SYNC_TOKEN_USER_0 941 +#define CMDQ_SYNC_TOKEN_USER_1 942 +#define CMDQ_SYNC_TOKEN_POLL_MONITOR 943 +#define CMDQ_SYNC_TOKEN_TPR_LOCK 942 +/* TZMP software token */ +#define CMDQ_SYNC_TOKEN_TZMP_DISP_WAIT 943 +#define CMDQ_SYNC_TOKEN_TZMP_DISP_SET 944 +#define CMDQ_SYNC_TOKEN_TZMP_ISP_WAIT 945 +#define CMDQ_SYNC_TOKEN_TZMP_ISP_SET 946 +#define CMDQ_SYNC_TOKEN_TZMP_AIE_WAIT 947 +#define CMDQ_SYNC_TOKEN_TZMP_AIE_SET 948 +#define CMDQ_SYNC_TOKEN_TZMP_ADL_WAIT 949 +#define CMDQ_SYNC_TOKEN_TZMP_ADL_SET 950 +/* PREBUILT software token */ +#define CMDQ_SYNC_TOKEN_PREBUILT_MDP_LOCK 951 +#define CMDQ_SYNC_TOKEN_PREBUILT_MML_LOCK 952 +#define CMDQ_SYNC_TOKEN_PREBUILT_VFMT_LOCK 953 +#define CMDQ_SYNC_TOKEN_PREBUILT_DISP_LOCK 954 +#define CMDQ_SYNC_TOKEN_DISP_VA_START 955 +#define CMDQ_SYNC_TOKEN_DISP_VA_END 956 + +/* + * Event for GPR timer, used in sleep and poll with timeout + * + * CMDQ_TOKEN_GPR_TIMER_R0~15: 994 ~ 1009 + */ +#define CMDQ_TOKEN_GPR_TIMER_R(n) (994 + (n)) +/* End of common software token */ + +#endif diff --git a/arch/arm64/boot/dts/mediatek/mt8365-evk.dts b/arch/arm64/boot/dts/mediatek/mt8365-evk.dts index c8418888268d9..b5dd5ef9fa11a 100644 --- a/arch/arm64/boot/dts/mediatek/mt8365-evk.dts +++ b/arch/arm64/boot/dts/mediatek/mt8365-evk.dts @@ -284,6 +284,11 @@ }; }; +&gpu { + mali-supply = <&mt6357_vcore_reg>; + status = "okay"; +}; + &i2c0 { clock-frequency = <100000>; pinctrl-0 = <&i2c0_pins>; @@ -353,6 +358,10 @@ }; }; +&mfg { + domain-supply = <&mt6357_vsram_others_reg>; +}; + &mmc0 { assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL>; assigned-clocks = <&topckgen CLK_TOP_MSDC50_0_SEL>; diff --git a/arch/arm64/boot/dts/mediatek/mt8365.dtsi b/arch/arm64/boot/dts/mediatek/mt8365.dtsi index e6d2b3221a3b7..a5ca3cda6ef30 100644 --- a/arch/arm64/boot/dts/mediatek/mt8365.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8365.dtsi @@ -267,6 +267,26 @@ clock-output-names = "clk26m"; }; + gpu_opp_table: opp-table-gpu { + compatible = "operating-points-v2"; + opp-shared; + + opp-450000000 { + opp-hz = /bits/ 64 <450000000>; + opp-microvolt = <650000>; + }; + + opp-560000000 { + opp-hz = /bits/ 64 <560000000>; + opp-microvolt = <700000>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <800000>; + }; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -292,6 +312,27 @@ interrupts = ; }; + mfgcfg: syscon@13000000 { + compatible = "mediatek,mt8365-mfgcfg", "syscon"; + reg = <0 0x13000000 0 0x1000>; + #clock-cells = <1>; + }; + + gpu: gpu@13040000 { + compatible = "mediatek,mt8365-mali", "arm,mali-bifrost"; + reg = <0 0x13040000 0 0x4000>; + + clocks = <&mfgcfg CLK_MFG_BG3D>; + interrupts = , + , + , + ; + interrupt-names = "job", "mmu", "gpu", "event"; + operating-points-v2 = <&gpu_opp_table>; + power-domains = <&spm MT8365_POWER_DOMAIN_MFG>; + status = "disabled"; + }; + topckgen: syscon@10000000 { compatible = "mediatek,mt8365-topckgen", "syscon"; reg = <0 0x10000000 0 0x1000>; @@ -398,7 +439,7 @@ mediatek,infracfg = <&infracfg>; }; - power-domain@MT8365_POWER_DOMAIN_MFG { + mfg: power-domain@MT8365_POWER_DOMAIN_MFG { reg = ; clocks = <&topckgen CLK_TOP_MFG_SEL>; clock-names = "mfg"; diff --git a/arch/arm64/boot/dts/mediatek/mt8370-grinn-genio-510-sbc.dts b/arch/arm64/boot/dts/mediatek/mt8370-grinn-genio-510-sbc.dts new file mode 100644 index 0000000000000..92ff80e60974b --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8370-grinn-genio-510-sbc.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 Grinn sp. z o.o. + * Author: Bartosz Bilas + */ +/dts-v1/; + +#include "mt8370.dtsi" +#include "mt8390-grinn-genio-som.dtsi" +#include "mt8390-grinn-genio-sbc.dtsi" + +/ { + model = "Grinn GenioSBC-510"; + compatible = "grinn,genio-510-sbc", "mediatek,mt8370", "mediatek,mt8188"; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 1 0x00000000>; + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8390-grinn-genio-700-sbc.dts b/arch/arm64/boot/dts/mediatek/mt8390-grinn-genio-700-sbc.dts new file mode 100644 index 0000000000000..4931d761bd1fa --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8390-grinn-genio-700-sbc.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 Grinn sp. z o.o. + * Author: Mateusz Koza + */ +/dts-v1/; + +#include "mt8188.dtsi" +#include "mt8390-grinn-genio-som.dtsi" +#include "mt8390-grinn-genio-sbc.dtsi" + +/ { + model = "Grinn GenioSBC-700"; + compatible = "grinn,genio-700-sbc", "mediatek,mt8390", "mediatek,mt8188"; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 1 0x00000000>; + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8390-grinn-genio-sbc.dtsi b/arch/arm64/boot/dts/mediatek/mt8390-grinn-genio-sbc.dtsi new file mode 100644 index 0000000000000..888248a75e933 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8390-grinn-genio-sbc.dtsi @@ -0,0 +1,538 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 Grinn sp. z o.o. + * Author: Mateusz Koza + */ + +#include + +/ { + chassis-type = "embedded"; + + aliases { + ethernet0 = ð + i2c0 = &i2c0; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c5 = &i2c5; + i2c6 = &i2c6; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:921600n8"; + }; + + firmware { + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* + * 12 MiB reserved for OP-TEE (BL32) + * +-----------------------+ 0x43e0_0000 + * | SHMEM 2MiB | + * +-----------------------+ 0x43c0_0000 + * | | TA_RAM 8MiB | + * + TZDRAM +--------------+ 0x4340_0000 + * | | TEE_RAM 2MiB | + * +-----------------------+ 0x4320_0000 + */ + optee_reserved: optee@43200000 { + no-map; + reg = <0 0x43200000 0 0x00c00000>; + }; + + scp_mem: memory@50000000 { + compatible = "shared-dma-pool"; + reg = <0 0x50000000 0 0x2900000>; + no-map; + }; + + /* 2 MiB reserved for ARM Trusted Firmware (BL31) */ + bl31_secmon_reserved: memory@54600000 { + no-map; + reg = <0 0x54600000 0x0 0x200000>; + }; + + apu_mem: memory@55000000 { + compatible = "shared-dma-pool"; + reg = <0 0x55000000 0 0x1400000>; /* 20 MB */ + }; + + vpu_mem: memory@57000000 { + compatible = "shared-dma-pool"; + reg = <0 0x57000000 0 0x1400000>; /* 20 MB */ + }; + + adsp_mem: memory@60000000 { + compatible = "shared-dma-pool"; + reg = <0 0x60000000 0 0xf00000>; + no-map; + }; + + afe_dma_mem: memory@60f00000 { + compatible = "shared-dma-pool"; + reg = <0 0x60f00000 0 0x100000>; + no-map; + }; + + adsp_dma_mem: memory@61000000 { + compatible = "shared-dma-pool"; + reg = <0 0x61000000 0 0x100000>; + no-map; + }; + }; + + reg_sbc_vsys: regulator-vsys { + compatible = "regulator-fixed"; + regulator-name = "vsys"; + regulator-always-on; + regulator-boot-on; + }; + + reg_fixed_5v: regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "fixed-5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + vin-supply = <®_sbc_vsys>; + }; + + reg_fixed_4v2: regulator-1 { + compatible = "regulator-fixed"; + regulator-name = "fixed-4v2"; + regulator-min-microvolt = <4200000>; + regulator-max-microvolt = <4200000>; + enable-active-high; + regulator-always-on; + vin-supply = <®_sbc_vsys>; + }; + + reg_fixed_3v3: regulator-2 { + compatible = "regulator-fixed"; + regulator-name = "fixed-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + regulator-always-on; + vin-supply = <®_sbc_vsys>; + }; +}; + +&pio { + gpio-line-names = + /* 0 - 4 */ "RPI_GPIO0", "RPI_GPIO1", "", "", "RPI_GPIO4", + /* 5 - 9 */ "", "RPI_GPIO6", "", "", "RPI_GPIO9", + /* 10 - 14 */ "RPI_GPIO10", "RPI_GPIO11", "", "", "", + /* 15 - 19 */ "", "", "", "", "", + /* 20 - 24 */ "", "RPI_GPIO21", "", "RPI_GPIO23", "", + /* 25 - 29 */ "", "", "", "", "", + /* 30 - 34 */ "RPI_GPIO30", "", "", "", "", + /* 35 - 39 */ "RPI_GPIO35", "RPI_GPIO36", "", "", "", + /* 40 - 44 */ "", "", "", "", "", + /* 45 - 49 */ "", "", "", "", "", + /* 50 - 54 */ "", "", "", "", "", + /* 55 - 59 */ "RPI_GPIO55", "RPI_GPIO56", "", "", "RPI_GPIO59", + /* 60 - 64 */ "RPI_GPIO60", "", "", "", "", + /* 65 - 69 */ "", "", "", "", "RPI_GPIO69", + /* 70 - 74 */ "", "", "RPI_GPIO72", "RPI_GPIO73", "RPI_GPIO74", + /* 75 - 79 */ "", "", "", "", "RPI_GPIO79", + /* 80 - 84 */ "RPI_GPIO80", "RPI_GPIO81", "RPI_GPIO82", "", "", + /* 85 - 89 */ "", "", "", "", "", + /* 90 - 94 */ "", "", "", "", "", + /* 95 - 99 */ "", "", "", "", "", + /*100 - 104 */ "", "", "", "", "", + /*105 - 109 */ "", "", "", "", "", + /*110 - 114 */ "", "", "", "", "", + /*115 - 119 */ "", "", "", "", "", + /*120 - 124 */ "", "RPI_GPIO121", "RPI_GPIO122", "RPI_GPIO123", "RPI_GPIO124"; + + i2c0_pins: i2c0-pins { + pins { + pinmux = , + ; + bias-pull-up = ; + drive-strength-microamp = <1000>; + }; + }; + + i2c2_pins: i2c2-pins { + pins { + pinmux = , + ; + bias-pull-up = ; + drive-strength-microamp = <1000>; + }; + }; + + i2c3_pins: i2c3-pins { + pins { + pinmux = , + ; + bias-pull-up = ; + drive-strength-microamp = <1000>; + }; + }; + + i2c5_pins: i2c5-pins { + pins { + pinmux = , + ; + bias-pull-up = ; + drive-strength-microamp = <1000>; + }; + }; + + i2c6_pins: i2c6-pins { + pins { + pinmux = , + ; + bias-pull-up = ; + drive-strength-microamp = <1000>; + }; + }; + + uart0_pins: uart0-pins { + pins { + pinmux = , + ; + bias-pull-up; + }; + }; + + uart1_pins: uart1-pins { + pins { + pinmux = , + ; + bias-pull-up; + }; + }; + + uart2_pins: uart2-pins { + pins { + pinmux = , + ; + bias-pull-up; + }; + }; + + pcie_pins_default: pcie-default { + mux { + pinmux = , + , + ; + bias-pull-up; + }; + }; + + eth_default_pins: eth-default-pins { + pins-cc { + pinmux = , + , + , + ; + drive-strength = <8>; + }; + + pins-mdio { + pinmux = , + ; + drive-strength = <8>; + input-enable; + }; + + pins-power { + pinmux = , + ; + output-high; + }; + + pins-rxd { + pinmux = , + , + , + ; + drive-strength = <8>; + }; + + pins-txd { + pinmux = , + , + , + ; + drive-strength = <8>; + }; + }; + + eth_sleep_pins: eth-sleep-pins { + pins-cc { + pinmux = , + , + , + ; + }; + + pins-mdio { + pinmux = , + ; + input-disable; + bias-disable; + }; + + pins-rxd { + pinmux = , + , + , + ; + }; + + pins-txd { + pinmux = , + , + , + ; + }; + }; + + spi2_pins: spi2-pins { + pins-spi { + pinmux = , + , + , + ; + bias-disable; + }; + }; + + audio_default_pins: audio-default-pins { + pins-cmd-dat { + pinmux = , + , + , + ; + }; + }; + + usb_default_pins: usb-default-pins { + pins-valid { + pinmux = ; + input-enable; + }; + }; +}; + +ð { + phy-mode = "rgmii-id"; + phy-handle = <ðernet_phy0>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <ð_default_pins>; + pinctrl-1 = <ð_sleep_pins>; + mediatek,mac-wol; + mediatek,tx-delay-ps = <30>; + snps,reset-active-low; + snps,reset-delays-us = <0 11000 200000>; + snps,reset-gpio = <&pio 147 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +ð_mdio { + ethernet_phy0: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + interrupts-extended = <&pio 148 IRQ_TYPE_LEVEL_LOW>; + eee-broken-1000t; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <400000>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + clock-frequency = <400000>; + status = "okay"; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins>; + clock-frequency = <400000>; + status = "okay"; +}; + +&i2c5 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_pins>; + clock-frequency = <400000>; + status = "okay"; +}; + +&i2c6 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c6_pins>; + clock-frequency = <400000>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "okay"; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_pins_default>; + status = "okay"; +}; + +&pciephy { + status = "okay"; +}; + +&spi2 { + pinctrl-names = "default"; + pinctrl-0 = <&spi2_pins>; + mediatek,pad-select = <0>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; +}; + +&u3phy0 { + status = "okay"; +}; + +&u3phy1 { + status = "okay"; +}; + +&u3phy2 { + status = "okay"; +}; + +&xhci1 { + #address-cells = <1>; + #size-cells = <0>; + vusb33-supply = <&mt6359_vusb_ldo_reg>; + status = "okay"; + + hub_2_0: hub@1 { + compatible = "usb451,8027"; + reg = <1>; + peer-hub = <&hub_3_0>; + reset-gpios = <&pio 7 GPIO_ACTIVE_HIGH>; + vdd-supply = <®_fixed_3v3>; + }; + + hub_3_0: hub@2 { + compatible = "usb451,8025"; + reg = <2>; + peer-hub = <&hub_2_0>; + reset-gpios = <&pio 7 GPIO_ACTIVE_HIGH>; + vdd-supply = <®_fixed_3v3>; + }; +}; + +&xhci2 { + #address-cells = <1>; + #size-cells = <0>; + vusb33-supply = <&mt6359_vusb_ldo_reg>; + status = "okay"; + + hub@1 { + compatible = "microchip,usb2513bi"; + reg = <1>; + vdd-supply = <®_fixed_3v3>; + }; +}; + +&ssusb0 { + dr_mode = "peripheral"; + pinctrl-names = "default"; + pinctrl-0 = <&usb_default_pins>; + vusb33-supply = <&mt6359_vusb_ldo_reg>; + status = "okay"; +}; + +&ssusb1 { + dr_mode = "host"; + maximum-speed = "super-speed"; + vusb33-supply = <&mt6359_vusb_ldo_reg>; + status = "okay"; +}; + +&ssusb2 { + dr_mode = "host"; + maximum-speed = "high-speed"; + vusb33-supply = <&mt6359_vusb_ldo_reg>; + status = "okay"; +}; + +&scp_cluster { + status = "okay"; +}; + +&scp_c0 { + memory-region = <&scp_mem>; + status = "okay"; +}; + +&gpu { + mali-supply = <&mt6359_vproc2_buck_reg>; + status = "okay"; +}; + +&adsp { + memory-region = <&adsp_dma_mem>, <&adsp_mem>; + status = "okay"; +}; + +&afe { + memory-region = <&afe_dma_mem>; + status = "okay"; +}; + +&sound { + compatible = "mediatek,mt8390-mt6359-evk", "mediatek,mt8188-mt6359-evb"; + model = "mt8390-evk"; + pinctrl-names = "default"; + pinctrl-0 = <&audio_default_pins>; + audio-routing = + "Headphone", "Headphone L", + "Headphone", "Headphone R", + "AP DMIC", "AUDGLB", + "AP DMIC", "MIC_BIAS_0", + "AP DMIC", "MIC_BIAS_2", + "DMIC_INPUT", "AP DMIC"; + + mediatek,adsp = <&adsp>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8390-grinn-genio-som.dtsi b/arch/arm64/boot/dts/mediatek/mt8390-grinn-genio-som.dtsi new file mode 100644 index 0000000000000..8da47c9163138 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8390-grinn-genio-som.dtsi @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 Grinn sp. z o.o. + * Author: Mateusz Koza + */ + +#include "mt6359.dtsi" +#include + +/ { + aliases { + i2c1 = &i2c1; + mmc0 = &mmc0; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <400000>; + status = "okay"; +}; + +&mfg0 { + domain-supply = <&mt6359_vproc2_buck_reg>; +}; + +&mfg1 { + domain-supply = <&mt6359_vsram_others_ldo_reg>; +}; + +&mmc0 { + status = "okay"; + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc0_default_pins>; + pinctrl-1 = <&mmc0_uhs_pins>; + bus-width = <8>; + max-frequency = <200000000>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + supports-cqe; + cap-mmc-hw-reset; + no-sdio; + no-sd; + hs400-ds-delay = <0x1481b>; + vmmc-supply = <&mt6359_vemc_1_ldo_reg>; + vqmmc-supply = <&mt6359_vufs_ldo_reg>; + non-removable; +}; + +&mt6359_vbbck_ldo_reg { + regulator-always-on; +}; + +&mt6359_vcn18_ldo_reg { + regulator-name = "vcn18_pmu"; + regulator-always-on; +}; + +&mt6359_vcn33_2_bt_ldo_reg { + regulator-name = "vcn33_2_pmu"; + regulator-always-on; +}; + +&mt6359_vcore_buck_reg { + regulator-name = "dvdd_proc_l"; + regulator-always-on; +}; + +&mt6359_vgpu11_buck_reg { + regulator-name = "dvdd_core"; + regulator-always-on; +}; + +&mt6359_vpa_buck_reg { + regulator-name = "vpa_pmu"; + regulator-max-microvolt = <3100000>; +}; + +&mt6359_vproc2_buck_reg { + /* The name "vgpu" is required by mtk-regulator-coupler */ + regulator-name = "vgpu"; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <800000>; + regulator-coupled-with = <&mt6359_vsram_others_ldo_reg>; + regulator-coupled-max-spread = <6250>; +}; + +&mt6359_vpu_buck_reg { + regulator-name = "dvdd_adsp"; + regulator-always-on; +}; + +&mt6359_vrf12_ldo_reg { + regulator-name = "va12_abb2_pmu"; + regulator-always-on; +}; + +&mt6359_vsim1_ldo_reg { + regulator-name = "vsim1_pmu"; + regulator-enable-ramp-delay = <480>; +}; + +&mt6359_vsram_others_ldo_reg { + /* The name "vsram_gpu" is required by mtk-regulator-coupler */ + regulator-name = "vsram_gpu"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <800000>; + regulator-coupled-with = <&mt6359_vproc2_buck_reg>; + regulator-coupled-max-spread = <6250>; +}; + +&mt6359_vufs_ldo_reg { + regulator-name = "vufs18_pmu"; + regulator-always-on; +}; + +&pio { + + i2c1_pins: i2c1-pins { + pins { + pinmux = , + ; + bias-pull-up = ; + drive-strength-microamp = <1000>; + }; + }; + + mmc0_default_pins: mmc0-default-pins { + pins-clk { + pinmux = ; + drive-strength = <6>; + bias-pull-down = ; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + drive-strength = <6>; + bias-pull-up = ; + }; + + pins-rst { + pinmux = ; + drive-strength = <6>; + bias-pull-up = ; + }; + }; + + mmc0_uhs_pins: mmc0-uhs-pins { + pins-clk { + pinmux = ; + drive-strength = <8>; + bias-pull-down = ; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + drive-strength = <8>; + bias-pull-up = ; + }; + + pins-ds { + pinmux = ; + drive-strength = <8>; + bias-pull-down = ; + }; + + pins-rst { + pinmux = ; + drive-strength = <8>; + bias-pull-up = ; + }; + }; +}; + +&pmic { + interrupt-parent = <&pio>; + interrupts = <222 IRQ_TYPE_LEVEL_HIGH>; + interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>; + + keys { + compatible = "mediatek,mt6359-keys"; + mediatek,long-press-mode = <1>; + power-off-time-sec = <0>; + + power-key { + linux,keycodes = ; + wakeup-source; + }; + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk-ufs.dts b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk-ufs.dts new file mode 100644 index 0000000000000..e09a3ecd87730 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk-ufs.dts @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 MediaTek Inc. + * Author: Ramax Lo + * Macpaul Lin + */ +/dts-v1/; + +#include "mt8395-genio-common.dtsi" + +/ { + model = "MediaTek Genio 1200 EVK-P1V2-UFS"; + compatible = "mediatek,mt8395-evk-ufs", "mediatek,mt8395", + "mediatek,mt8195"; +}; + +&ufshci { + status = "okay"; + vcc-supply = <&mt6359_vemc_1_ldo_reg>; + vccq2-supply = <&mt6359_vufs_ldo_reg>; +}; + +&ufsphy { + status = "okay"; +}; + +&mmc0 { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts index cf8cd37f57084..68455f28c2467 100644 --- a/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts +++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts @@ -6,1197 +6,10 @@ */ /dts-v1/; -#include "mt8195.dtsi" -#include "mt6359.dtsi" -#include -#include -#include -#include -#include -#include -#include +#include "mt8395-genio-common.dtsi" / { model = "MediaTek Genio 1200 EVK-P1V2-EMMC"; compatible = "mediatek,mt8395-evk", "mediatek,mt8395", "mediatek,mt8195"; - - aliases { - serial0 = &uart0; - ethernet0 = ð - }; - - chosen { - stdout-path = "serial0:921600n8"; - }; - - firmware { - optee { - compatible = "linaro,optee-tz"; - method = "smc"; - }; - }; - - memory@40000000 { - device_type = "memory"; - reg = <0 0x40000000 0x2 0x00000000>; - }; - - reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; - - /* - * 12 MiB reserved for OP-TEE (BL32) - * +-----------------------+ 0x43e0_0000 - * | SHMEM 2MiB | - * +-----------------------+ 0x43c0_0000 - * | | TA_RAM 8MiB | - * + TZDRAM +--------------+ 0x4340_0000 - * | | TEE_RAM 2MiB | - * +-----------------------+ 0x4320_0000 - */ - optee_reserved: optee@43200000 { - no-map; - reg = <0 0x43200000 0 0x00c00000>; - }; - - scp_mem: memory@50000000 { - compatible = "shared-dma-pool"; - reg = <0 0x50000000 0 0x2900000>; - no-map; - }; - - vpu_mem: memory@53000000 { - compatible = "shared-dma-pool"; - reg = <0 0x53000000 0 0x1400000>; /* 20 MB */ - }; - - /* 2 MiB reserved for ARM Trusted Firmware (BL31) */ - bl31_secmon_mem: memory@54600000 { - no-map; - reg = <0 0x54600000 0x0 0x200000>; - }; - - adsp_mem: memory@60000000 { - compatible = "shared-dma-pool"; - reg = <0 0x60000000 0 0xf00000>; - no-map; - }; - - afe_dma_mem: memory@60f00000 { - compatible = "shared-dma-pool"; - reg = <0 0x60f00000 0 0x100000>; - no-map; - }; - - adsp_dma_mem: memory@61000000 { - compatible = "shared-dma-pool"; - reg = <0 0x61000000 0 0x100000>; - no-map; - }; - - apu_mem: memory@62000000 { - compatible = "shared-dma-pool"; - reg = <0 0x62000000 0 0x1400000>; /* 20 MB */ - }; - }; - - backlight_lcm0: backlight-lcm0 { - compatible = "pwm-backlight"; - brightness-levels = <0 1023>; - default-brightness-level = <576>; - num-interpolated-steps = <1023>; - pwms = <&disp_pwm0 0 500000>; - }; - - backlight_lcd1: backlight-lcd1 { - compatible = "pwm-backlight"; - pwms = <&disp_pwm1 0 500000>; - enable-gpios = <&pio 46 GPIO_ACTIVE_HIGH>; - brightness-levels = <0 1023>; - num-interpolated-steps = <1023>; - default-brightness-level = <576>; - status = "disabled"; - }; - - can_clk: can-clk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <20000000>; - clock-output-names = "can-clk"; - }; - - edp_panel_fixed_3v3: regulator-0 { - compatible = "regulator-fixed"; - regulator-name = "edp_panel_3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - enable-active-high; - gpio = <&pio 6 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&edp_panel_3v3_en_pins>; - }; - - edp_panel_fixed_12v: regulator-1 { - compatible = "regulator-fixed"; - regulator-name = "edp_backlight_12v"; - regulator-min-microvolt = <12000000>; - regulator-max-microvolt = <12000000>; - enable-active-high; - gpio = <&pio 96 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&edp_panel_12v_en_pins>; - }; - - keys: gpio-keys { - compatible = "gpio-keys"; - - button-volume-up { - wakeup-source; - debounce-interval = <100>; - gpios = <&pio 106 GPIO_ACTIVE_LOW>; - label = "volume_up"; - linux,code = ; - }; - }; - - lcm0_iovcc: regulator-vio18-lcm0 { - compatible = "regulator-fixed"; - regulator-name = "vio18_lcm0"; - enable-active-high; - gpio = <&pio 47 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&dsi0_vreg_en_pins>; - vin-supply = <&mt6360_ldo2>; - }; - - lcm0_vddp: regulator-vsys-lcm0 { - compatible = "regulator-fixed"; - regulator-name = "vsys_lcm0"; - regulator-always-on; - regulator-boot-on; - vin-supply = <&mt6360_ldo1>; - }; - - wifi_fixed_3v3: regulator-2 { - compatible = "regulator-fixed"; - regulator-name = "wifi_3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&pio 135 GPIO_ACTIVE_HIGH>; - enable-active-high; - regulator-always-on; - }; -}; - -&adsp { - memory-region = <&adsp_dma_mem>, <&adsp_mem>; - status = "okay"; -}; - -&afe { - memory-region = <&afe_dma_mem>; - status = "okay"; -}; - -&disp_pwm0 { - pinctrl-names = "default"; - pinctrl-0 = <&disp_pwm0_pins>; - status = "okay"; -}; - -&dither0_in { - remote-endpoint = <&gamma0_out>; -}; - -&dither0_out { - remote-endpoint = <&dsi0_in>; -}; - -&dmic_codec { - wakeup-delay-ms = <200>; -}; - -&dsi0 { - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; - - panel@0 { - compatible = "startek,kd070fhfid078", "himax,hx8279"; - reg = <0>; - backlight = <&backlight_lcm0>; - enable-gpios = <&pio 48 GPIO_ACTIVE_HIGH>; - reset-gpios = <&pio 108 GPIO_ACTIVE_HIGH>; - iovcc-supply = <&lcm0_iovcc>; - vdd-supply = <&lcm0_vddp>; - pinctrl-names = "default"; - pinctrl-0 = <&panel_default_pins>; - - port { - dsi_panel_in: endpoint { - remote-endpoint = <&dsi0_out>; - }; - }; - }; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - dsi0_in: endpoint { - remote-endpoint = <&dither0_out>; - }; - }; - - port@1 { - reg = <1>; - dsi0_out: endpoint { - remote-endpoint = <&dsi_panel_in>; - }; - }; - }; -}; - -ð { - phy-mode ="rgmii-rxid"; - phy-handle = <ð_phy0>; - snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>; - snps,reset-delays-us = <0 10000 10000>; - mediatek,tx-delay-ps = <2030>; - mediatek,mac-wol; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <ð_default_pins>; - pinctrl-1 = <ð_sleep_pins>; - status = "okay"; - - mdio { - compatible = "snps,dwmac-mdio"; - #address-cells = <1>; - #size-cells = <0>; - eth_phy0: ethernet-phy@1 { - compatible = "ethernet-phy-id001c.c916"; - reg = <0x1>; - }; - }; -}; - -&gamma0_out { - remote-endpoint = <&dither0_in>; -}; - -&gpu { - mali-supply = <&mt6315_7_vbuck1>; - status = "okay"; -}; - -&i2c0 { - clock-frequency = <400000>; - pinctrl-0 = <&i2c0_pins>; - pinctrl-names = "default"; - status = "okay"; -}; - -&i2c1 { - clock-frequency = <400000>; - pinctrl-0 = <&i2c1_pins>; - pinctrl-names = "default"; - status = "okay"; - - touchscreen@5d { - compatible = "goodix,gt9271"; - reg = <0x5d>; - interrupts-extended = <&pio 132 IRQ_TYPE_EDGE_RISING>; - irq-gpios = <&pio 132 GPIO_ACTIVE_HIGH>; - reset-gpios = <&pio 133 GPIO_ACTIVE_HIGH>; - AVDD28-supply = <&mt6360_ldo1>; - pinctrl-names = "default"; - pinctrl-0 = <&touch_pins>; - }; -}; - -&i2c2 { - clock-frequency = <400000>; - pinctrl-0 = <&i2c2_pins>; - pinctrl-names = "default"; - status = "okay"; - - typec-mux@48 { - compatible = "ite,it5205"; - reg = <0x48>; - vcc-supply = <&mt6359_vibr_ldo_reg>; - mode-switch; - orientation-switch; - status = "okay"; - - port { - it5205_sbu_ep: endpoint { - remote-endpoint = <&mt6360_ssusb_sbu_ep>; - }; - }; - }; -}; - -&i2c6 { - clock-frequency = <400000>; - pinctrl-0 = <&i2c6_pins>; - pinctrl-names = "default"; - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; - - mt6360: pmic@34 { - compatible = "mediatek,mt6360"; - reg = <0x34>; - interrupt-parent = <&pio>; - interrupts = <128 IRQ_TYPE_EDGE_FALLING>; - interrupt-names = "IRQB"; - interrupt-controller; - #interrupt-cells = <1>; - pinctrl-0 = <&mt6360_pins>; - - charger { - compatible = "mediatek,mt6360-chg"; - richtek,vinovp-microvolt = <14500000>; - - otg_vbus_regulator: usb-otg-vbus-regulator { - regulator-name = "usb-otg-vbus"; - regulator-min-microvolt = <4425000>; - regulator-max-microvolt = <5825000>; - }; - }; - - regulator { - compatible = "mediatek,mt6360-regulator"; - LDO_VIN3-supply = <&mt6360_buck2>; - - mt6360_buck1: buck1 { - regulator-name = "emi_vdd2"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1300000>; - regulator-allowed-modes = ; - regulator-always-on; - }; - - mt6360_buck2: buck2 { - regulator-name = "emi_vddq"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1300000>; - regulator-allowed-modes = ; - regulator-always-on; - }; - - mt6360_ldo1: ldo1 { - regulator-name = "tp1_p3v0"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-allowed-modes = ; - regulator-always-on; - }; - - mt6360_ldo2: ldo2 { - regulator-name = "panel1_p1v8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-allowed-modes = ; - }; - - mt6360_ldo3: ldo3 { - regulator-name = "vmc_pmu"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3600000>; - regulator-allowed-modes = ; - }; - - mt6360_ldo5: ldo5 { - regulator-name = "vmch_pmu"; - regulator-min-microvolt = <2700000>; - regulator-max-microvolt = <3600000>; - regulator-allowed-modes = ; - }; - - /* This is a measure point, which name is mt6360_ldo1 on schematic */ - mt6360_ldo6: ldo6 { - regulator-name = "mt6360_ldo1"; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <2100000>; - regulator-allowed-modes = ; - }; - - mt6360_ldo7: ldo7 { - regulator-name = "emi_vmddr_en"; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <2100000>; - regulator-allowed-modes = ; - regulator-always-on; - }; - }; - - tcpc { - compatible = "mediatek,mt6360-tcpc"; - interrupts-extended = <&pio 17 IRQ_TYPE_LEVEL_LOW>; - interrupt-names = "PD_IRQB"; - - connector { - compatible = "usb-c-connector"; - label = "USB-C"; - data-role = "dual"; - op-sink-microwatt = <10000000>; - power-role = "dual"; - try-power-role = "sink"; - - source-pdos = ; - sink-pdos = ; - - pd-revision = /bits/ 8 <0x03 0x01 0x01 0x06>; - - altmodes { - displayport { - svid = /bits/ 16 <0xff01>; - vdo = <0x00001c46>; - }; - }; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - typec_con_hs: endpoint { - remote-endpoint = <&mtu3_hs0_role_sw>; - }; - }; - - port@1 { - reg = <1>; - typec_con_ss: endpoint { - remote-endpoint = <&mtu3_ss0_role_sw>; - }; - }; - - port@2 { - reg = <2>; - mt6360_ssusb_sbu_ep: endpoint { - remote-endpoint = <&it5205_sbu_ep>; - }; - }; - }; - }; - }; - }; -}; - -&mfg0 { - domain-supply = <&mt6315_7_vbuck1>; -}; - -&mfg1 { - domain-supply = <&mt6359_vsram_others_ldo_reg>; -}; - -&mipi_tx0 { - status = "okay"; -}; - -&mmc0 { - status = "okay"; - pinctrl-names = "default", "state_uhs"; - pinctrl-0 = <&mmc0_default_pins>; - pinctrl-1 = <&mmc0_uhs_pins>; - bus-width = <8>; - max-frequency = <200000000>; - cap-mmc-highspeed; - mmc-hs200-1_8v; - mmc-hs400-1_8v; - cap-mmc-hw-reset; - no-sdio; - no-sd; - hs400-ds-delay = <0x14c11>; - vmmc-supply = <&mt6359_vemc_1_ldo_reg>; - vqmmc-supply = <&mt6359_vufs_ldo_reg>; - non-removable; -}; - -&mmc1 { - pinctrl-names = "default", "state_uhs"; - pinctrl-0 = <&mmc1_default_pins>; - pinctrl-1 = <&mmc1_uhs_pins>; - bus-width = <4>; - max-frequency = <200000000>; - cap-sd-highspeed; - sd-uhs-sdr50; - sd-uhs-sdr104; - no-mmc; - no-sdio; - vmmc-supply = <&mt6360_ldo5>; - vqmmc-supply = <&mt6360_ldo3>; - status = "okay"; - non-removable; -}; - -&mt6359_vaud18_ldo_reg { - regulator-always-on; -}; - -&mt6359_vbbck_ldo_reg { - regulator-always-on; -}; - -/* For USB Hub */ -&mt6359_vcamio_ldo_reg { - regulator-always-on; -}; - -&mt6359_vcn33_2_bt_ldo_reg { - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -}; - -&mt6359_vcore_buck_reg { - regulator-always-on; -}; - -&mt6359_vgpu11_buck_reg { - regulator-always-on; -}; - -&mt6359_vpu_buck_reg { - regulator-always-on; -}; - -&mt6359_vrf12_ldo_reg { - regulator-always-on; -}; - -/* for GPU SRAM */ -&mt6359_vsram_others_ldo_reg { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <750000>; -}; - -&mt6359codec { - mediatek,mic-type-0 = <1>; /* ACC */ - mediatek,mic-type-1 = <3>; /* DCC */ - mediatek,mic-type-2 = <1>; /* ACC */ -}; - -&ovl0_in { - remote-endpoint = <&vdosys0_ep_main>; -}; - -&pcie0 { - pinctrl-names = "default", "idle"; - pinctrl-0 = <&pcie0_default_pins>; - pinctrl-1 = <&pcie0_idle_pins>; - status = "okay"; -}; - -&pcie1 { - pinctrl-names = "default"; - pinctrl-0 = <&pcie1_default_pins>; - status = "disabled"; -}; - -&pciephy { - status = "okay"; -}; - -&pio { - audio_default_pins: audio-default-pins { - pins-cmd-dat { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - ; - }; - }; - - disp_pwm1_default_pins: disp-pwm1-default-pins { - pins1 { - pinmux = ; - }; - }; - - edp_panel_12v_en_pins: edp-panel-12v-en-pins { - pins1 { - pinmux = ; - output-high; - }; - }; - - edp_panel_3v3_en_pins: edp-panel-3v3-en-pins { - pins1 { - pinmux = ; - output-high; - }; - }; - - eth_default_pins: eth-default-pins { - pins-cc { - pinmux = , - , - , - ; - drive-strength = <8>; - }; - - pins-mdio { - pinmux = , - ; - input-enable; - }; - - pins-power { - pinmux = , - ; - output-high; - }; - - pins-rxd { - pinmux = , - , - , - ; - }; - - pins-txd { - pinmux = , - , - , - ; - drive-strength = <8>; - }; - }; - - eth_sleep_pins: eth-sleep-pins { - pins-cc { - pinmux = , - , - , - ; - }; - - pins-mdio { - pinmux = , - ; - input-disable; - bias-disable; - }; - - pins-rxd { - pinmux = , - , - , - ; - }; - - pins-txd { - pinmux = , - , - , - ; - }; - }; - - gpio_key_pins: gpio-keys-pins { - pins { - pinmux = ; - bias-pull-up; - input-enable; - }; - }; - - i2c0_pins: i2c0-pins { - pins { - pinmux = , - ; - bias-pull-up = ; - drive-strength-microamp = <1000>; - }; - }; - - i2c1_pins: i2c1-pins { - pins { - pinmux = , - ; - bias-pull-up = ; - drive-strength-microamp = <1000>; - }; - }; - - i2c2_pins: i2c2-pins { - pins { - pinmux = , - ; - bias-pull-up = ; - drive-strength = <6>; - }; - }; - - i2c6_pins: i2c6-pins { - pins { - pinmux = , - ; - bias-pull-up; - }; - }; - - mmc0_default_pins: mmc0-default-pins { - pins-clk { - pinmux = ; - drive-strength = <6>; - bias-pull-down = ; - }; - - pins-cmd-dat { - pinmux = , - , - , - , - , - , - , - , - ; - input-enable; - drive-strength = <6>; - bias-pull-up = ; - }; - - pins-rst { - pinmux = ; - drive-strength = <6>; - bias-pull-up = ; - }; - }; - - mmc0_uhs_pins: mmc0-uhs-pins { - pins-clk { - pinmux = ; - drive-strength = <8>; - bias-pull-down = ; - }; - - pins-cmd-dat { - pinmux = , - , - , - , - , - , - , - , - ; - input-enable; - drive-strength = <8>; - bias-pull-up = ; - }; - - pins-ds { - pinmux = ; - drive-strength = <8>; - bias-pull-down = ; - }; - - pins-rst { - pinmux = ; - drive-strength = <8>; - bias-pull-up = ; - }; - }; - - mmc1_default_pins: mmc1-default-pins { - pins-clk { - pinmux = ; - drive-strength = <8>; - bias-pull-down = ; - }; - - pins-cmd-dat { - pinmux = , - , - , - , - ; - input-enable; - drive-strength = <8>; - bias-pull-up = ; - }; - }; - - mmc1_uhs_pins: mmc1-uhs-pins { - pins-clk { - pinmux = ; - drive-strength = <8>; - bias-pull-down = ; - }; - - pins-cmd-dat { - pinmux = , - , - , - , - ; - input-enable; - drive-strength = <8>; - bias-pull-up = ; - }; - }; - - mt6360_pins: mt6360-pins { - pins { - pinmux = , - ; - input-enable; - bias-pull-up; - }; - }; - - dsi0_vreg_en_pins: dsi0-vreg-en-pins { - pins-pwr-en { - pinmux = ; - output-low; - }; - }; - - panel_default_pins: panel-default-pins { - pins-rst { - pinmux = ; - output-high; - }; - - pins-en { - pinmux = ; - output-low; - }; - }; - - pcie0_default_pins: pcie0-default-pins { - pins { - pinmux = , - , - ; - bias-pull-up; - }; - }; - - pcie0_idle_pins: pcie0-idle-pins { - pins { - pinmux = ; - bias-disable; - output-low; - }; - }; - - pcie1_default_pins: pcie1-default-pins { - pins { - pinmux = , - , - ; - bias-pull-up; - }; - }; - - disp_pwm0_pins: disp-pwm0-pins { - pins-disp-pwm { - pinmux = ; - }; - }; - - spi1_pins: spi1-pins { - pins { - pinmux = , - , - , - ; - bias-disable; - }; - }; - - spi2_pins: spi-pins { - pins { - pinmux = , - , - , - ; - bias-disable; - }; - }; - - touch_pins: touch-pins { - pins-irq { - pinmux = ; - input-enable; - bias-disable; - }; - - pins-reset { - pinmux = ; - output-high; - }; - }; - - u3_p0_vbus: u3-p0-vbus-default-pins { - pins-vbus { - pinmux = ; - input-enable; - }; - }; - - uart0_pins: uart0-pins { - pins { - pinmux = , - ; - }; - }; - - uart1_pins: uart1-pins { - pins { - pinmux = , - , - , - ; - }; - }; -}; - -&pmic { - interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>; - - mt6359keys: keys { - compatible = "mediatek,mt6359-keys"; - mediatek,long-press-mode = <1>; - power-off-time-sec = <0>; - - power-key { - linux,keycodes = ; - wakeup-source; - }; - - home { - linux,keycodes = ; - }; - }; -}; - -&scp { - memory-region = <&scp_mem>; - firmware-name = "mediatek/mt8195/scp.img"; - status = "okay"; -}; - -&sound { - compatible = "mediatek,mt8195_mt6359"; - model = "mt8395-evk"; - pinctrl-names = "default"; - pinctrl-0 = <&audio_default_pins>; - audio-routing = - "Headphone", "Headphone L", - "Headphone", "Headphone R"; - mediatek,adsp = <&adsp>; - status = "okay"; - - headphone-dai-link { - link-name = "DL_SRC_BE"; - - codec { - sound-dai = <&pmic 0>; - }; - }; -}; - -&spi1 { - pinctrl-0 = <&spi1_pins>; - pinctrl-names = "default"; - mediatek,pad-select = <0>; - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; - cs-gpios = <&pio 64 GPIO_ACTIVE_LOW>; - - can0: can@0 { - compatible = "microchip,mcp2518fd"; - reg = <0>; - clocks = <&can_clk>; - spi-max-frequency = <20000000>; - interrupts-extended = <&pio 16 IRQ_TYPE_LEVEL_LOW>; - vdd-supply = <&mt6359_vcn33_2_bt_ldo_reg>; - xceiver-supply = <&mt6359_vcn33_2_bt_ldo_reg>; - }; -}; - -&spi2 { - pinctrl-0 = <&spi2_pins>; - pinctrl-names = "default"; - mediatek,pad-select = <0>; - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; -}; - -&spmi { - #address-cells = <2>; - #size-cells = <0>; - - mt6315_6: pmic@6 { - compatible = "mediatek,mt6315-regulator"; - reg = <0x6 SPMI_USID>; - - regulators { - mt6315_6_vbuck1: vbuck1 { - regulator-name = "Vbcpu"; - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1193750>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - regulator-always-on; - }; - }; - }; - - mt6315_7: pmic@7 { - compatible = "mediatek,mt6315-regulator"; - reg = <0x7 SPMI_USID>; - - regulators { - mt6315_7_vbuck1: vbuck1 { - regulator-name = "Vgpu"; - regulator-min-microvolt = <546000>; - regulator-max-microvolt = <787000>; - regulator-enable-ramp-delay = <256>; - regulator-allowed-modes = <0 1 2>; - }; - }; - }; -}; - -&u3phy0 { - status = "okay"; -}; - -&u3phy1 { - status = "okay"; - - u3port1: usb-phy@700 { - mediatek,force-mode; - }; -}; - -&u3phy2 { - status = "okay"; -}; - -&u3phy3 { - status = "okay"; -}; - -&uart0 { - pinctrl-0 = <&uart0_pins>; - pinctrl-names = "default"; - status = "okay"; -}; - -&uart1 { - pinctrl-0 = <&uart1_pins>; - pinctrl-names = "default"; - status = "okay"; -}; - -&ufsphy { - status = "disabled"; -}; - -&ssusb0 { - dr_mode = "otg"; - pinctrl-names = "default"; - pinctrl-0 = <&u3_p0_vbus>; - usb-role-switch; - vusb33-supply = <&mt6359_vusb_ldo_reg>; - status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - mtu3_hs0_role_sw: endpoint { - remote-endpoint = <&typec_con_hs>; - }; - }; - - port@1 { - reg = <1>; - mtu3_ss0_role_sw: endpoint { - remote-endpoint = <&typec_con_ss>; - }; - }; - }; -}; - -&ssusb2 { - vusb33-supply = <&mt6359_vusb_ldo_reg>; - status = "okay"; -}; - -&ssusb3 { - vusb33-supply = <&mt6359_vusb_ldo_reg>; - status = "okay"; -}; - -&vdosys0 { - port { - #address-cells = <1>; - #size-cells = <0>; - - vdosys0_ep_main: endpoint@0 { - reg = <0>; - remote-endpoint = <&ovl0_in>; - }; - }; -}; - -&xhci0 { - status = "okay"; -}; - -&xhci1 { - vusb33-supply = <&mt6359_vusb_ldo_reg>; - status = "okay"; -}; - -&xhci2 { - status = "okay"; -}; - -&xhci3 { - status = "okay"; }; diff --git a/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi b/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi new file mode 100644 index 0000000000000..2b7167804e71d --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi @@ -0,0 +1,1230 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2023 MediaTek Inc. + * Author: Ben Lok + * Macpaul Lin + */ +/dts-v1/; + +#include "mt8195.dtsi" +#include "mt6359.dtsi" +#include +#include +#include +#include +#include +#include +#include + +/ { + aliases { + serial0 = &uart0; + ethernet0 = ð + }; + + chosen { + stdout-path = "serial0:921600n8"; + }; + + firmware { + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0x2 0x00000000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* + * 12 MiB reserved for OP-TEE (BL32) + * +-----------------------+ 0x43e0_0000 + * | SHMEM 2MiB | + * +-----------------------+ 0x43c0_0000 + * | | TA_RAM 8MiB | + * + TZDRAM +--------------+ 0x4340_0000 + * | | TEE_RAM 2MiB | + * +-----------------------+ 0x4320_0000 + */ + optee_reserved: optee@43200000 { + no-map; + reg = <0 0x43200000 0 0x00c00000>; + }; + + scp_mem: memory@50000000 { + compatible = "shared-dma-pool"; + reg = <0 0x50000000 0 0x2900000>; + no-map; + }; + + vpu_mem: memory@53000000 { + compatible = "shared-dma-pool"; + reg = <0 0x53000000 0 0x1400000>; /* 20 MB */ + }; + + /* 2 MiB reserved for ARM Trusted Firmware (BL31) */ + bl31_secmon_mem: memory@54600000 { + no-map; + reg = <0 0x54600000 0x0 0x200000>; + }; + + adsp_mem: memory@60000000 { + compatible = "shared-dma-pool"; + reg = <0 0x60000000 0 0xf00000>; + no-map; + }; + + afe_dma_mem: memory@60f00000 { + compatible = "shared-dma-pool"; + reg = <0 0x60f00000 0 0x100000>; + no-map; + }; + + adsp_dma_mem: memory@61000000 { + compatible = "shared-dma-pool"; + reg = <0 0x61000000 0 0x100000>; + no-map; + }; + + apu_mem: memory@62000000 { + compatible = "shared-dma-pool"; + reg = <0 0x62000000 0 0x1400000>; /* 20 MB */ + }; + }; + + backlight_lcm0: backlight-lcm0 { + compatible = "pwm-backlight"; + brightness-levels = <0 1023>; + default-brightness-level = <576>; + num-interpolated-steps = <1023>; + pwms = <&disp_pwm0 0 500000>; + }; + + backlight_lcd1: backlight-lcd1 { + compatible = "pwm-backlight"; + pwms = <&disp_pwm1 0 500000>; + enable-gpios = <&pio 46 GPIO_ACTIVE_HIGH>; + brightness-levels = <0 1023>; + num-interpolated-steps = <1023>; + default-brightness-level = <576>; + status = "disabled"; + }; + + can_clk: can-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <20000000>; + clock-output-names = "can-clk"; + }; + + edp_panel_fixed_3v3: regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "edp_panel_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&pio 6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&edp_panel_3v3_en_pins>; + }; + + edp_panel_fixed_12v: regulator-1 { + compatible = "regulator-fixed"; + regulator-name = "edp_backlight_12v"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&pio 96 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&edp_panel_12v_en_pins>; + }; + + keys: gpio-keys { + compatible = "gpio-keys"; + + button-volume-up { + wakeup-source; + debounce-interval = <100>; + gpios = <&pio 106 GPIO_ACTIVE_LOW>; + label = "volume_up"; + linux,code = ; + }; + }; + + lcm0_iovcc: regulator-vio18-lcm0 { + compatible = "regulator-fixed"; + regulator-name = "vio18_lcm0"; + enable-active-high; + gpio = <&pio 47 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&dsi0_vreg_en_pins>; + vin-supply = <&mt6360_ldo2>; + }; + + lcm0_vddp: regulator-vsys-lcm0 { + compatible = "regulator-fixed"; + regulator-name = "vsys_lcm0"; + regulator-always-on; + regulator-boot-on; + vin-supply = <&mt6360_ldo1>; + }; + + wifi_fixed_3v3: regulator-2 { + compatible = "regulator-fixed"; + regulator-name = "wifi_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&pio 135 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; +}; + +&adsp { + memory-region = <&adsp_dma_mem>, <&adsp_mem>; + status = "okay"; +}; + +&afe { + memory-region = <&afe_dma_mem>; + 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>; +}; + +&disp_pwm0 { + pinctrl-names = "default"; + pinctrl-0 = <&disp_pwm0_pins>; + status = "okay"; +}; + +&dither0_in { + remote-endpoint = <&gamma0_out>; +}; + +&dither0_out { + remote-endpoint = <&dsi0_in>; +}; + +&dmic_codec { + wakeup-delay-ms = <200>; +}; + +&dsi0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + panel@0 { + compatible = "startek,kd070fhfid078", "himax,hx8279"; + reg = <0>; + backlight = <&backlight_lcm0>; + enable-gpios = <&pio 48 GPIO_ACTIVE_HIGH>; + reset-gpios = <&pio 108 GPIO_ACTIVE_HIGH>; + iovcc-supply = <&lcm0_iovcc>; + vdd-supply = <&lcm0_vddp>; + pinctrl-names = "default"; + pinctrl-0 = <&panel_default_pins>; + + port { + dsi_panel_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsi0_in: endpoint { + remote-endpoint = <&dither0_out>; + }; + }; + + port@1 { + reg = <1>; + dsi0_out: endpoint { + remote-endpoint = <&dsi_panel_in>; + }; + }; + }; +}; + +ð { + phy-mode ="rgmii-rxid"; + phy-handle = <ð_phy0>; + snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>; + snps,reset-delays-us = <0 10000 10000>; + mediatek,tx-delay-ps = <2030>; + mediatek,mac-wol; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <ð_default_pins>; + pinctrl-1 = <ð_sleep_pins>; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + eth_phy0: ethernet-phy@1 { + compatible = "ethernet-phy-id001c.c916"; + reg = <0x1>; + }; + }; +}; + +&gamma0_out { + remote-endpoint = <&dither0_in>; +}; + +&gpu { + mali-supply = <&mt6315_7_vbuck1>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c1 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + status = "okay"; + + touchscreen@5d { + compatible = "goodix,gt9271"; + reg = <0x5d>; + interrupts-extended = <&pio 132 IRQ_TYPE_EDGE_RISING>; + irq-gpios = <&pio 132 GPIO_ACTIVE_HIGH>; + reset-gpios = <&pio 133 GPIO_ACTIVE_HIGH>; + AVDD28-supply = <&mt6360_ldo1>; + pinctrl-names = "default"; + pinctrl-0 = <&touch_pins>; + }; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "default"; + status = "okay"; + + typec-mux@48 { + compatible = "ite,it5205"; + reg = <0x48>; + vcc-supply = <&mt6359_vibr_ldo_reg>; + mode-switch; + orientation-switch; + status = "okay"; + + port { + it5205_sbu_ep: endpoint { + remote-endpoint = <&mt6360_ssusb_sbu_ep>; + }; + }; + }; +}; + +&i2c6 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c6_pins>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + mt6360: pmic@34 { + compatible = "mediatek,mt6360"; + reg = <0x34>; + interrupt-parent = <&pio>; + interrupts = <128 IRQ_TYPE_EDGE_FALLING>; + interrupt-names = "IRQB"; + interrupt-controller; + #interrupt-cells = <1>; + pinctrl-0 = <&mt6360_pins>; + + charger { + compatible = "mediatek,mt6360-chg"; + richtek,vinovp-microvolt = <14500000>; + + otg_vbus_regulator: usb-otg-vbus-regulator { + regulator-name = "usb-otg-vbus"; + regulator-min-microvolt = <4425000>; + regulator-max-microvolt = <5825000>; + }; + }; + + regulator { + compatible = "mediatek,mt6360-regulator"; + LDO_VIN3-supply = <&mt6360_buck2>; + + mt6360_buck1: buck1 { + regulator-name = "emi_vdd2"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1300000>; + regulator-allowed-modes = ; + regulator-always-on; + }; + + mt6360_buck2: buck2 { + regulator-name = "emi_vddq"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1300000>; + regulator-allowed-modes = ; + regulator-always-on; + }; + + mt6360_ldo1: ldo1 { + regulator-name = "tp1_p3v0"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-allowed-modes = ; + regulator-always-on; + }; + + mt6360_ldo2: ldo2 { + regulator-name = "panel1_p1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-allowed-modes = ; + }; + + mt6360_ldo3: ldo3 { + regulator-name = "vmc_pmu"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3600000>; + regulator-allowed-modes = ; + }; + + mt6360_ldo5: ldo5 { + regulator-name = "vmch_pmu"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3600000>; + regulator-allowed-modes = ; + }; + + /* This is a measure point, which name is mt6360_ldo1 on schematic */ + mt6360_ldo6: ldo6 { + regulator-name = "mt6360_ldo1"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <2100000>; + regulator-allowed-modes = ; + }; + + mt6360_ldo7: ldo7 { + regulator-name = "emi_vmddr_en"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <2100000>; + regulator-allowed-modes = ; + regulator-always-on; + }; + }; + + tcpc { + compatible = "mediatek,mt6360-tcpc"; + interrupts-extended = <&pio 17 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "PD_IRQB"; + + connector { + compatible = "usb-c-connector"; + label = "USB-C"; + data-role = "dual"; + op-sink-microwatt = <10000000>; + power-role = "dual"; + try-power-role = "sink"; + + source-pdos = ; + sink-pdos = ; + + pd-revision = /bits/ 8 <0x03 0x01 0x01 0x06>; + + altmodes { + displayport { + svid = /bits/ 16 <0xff01>; + vdo = <0x00001c46>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + typec_con_hs: endpoint { + remote-endpoint = <&mtu3_hs0_role_sw>; + }; + }; + + port@1 { + reg = <1>; + typec_con_ss: endpoint { + remote-endpoint = <&mtu3_ss0_role_sw>; + }; + }; + + port@2 { + reg = <2>; + mt6360_ssusb_sbu_ep: endpoint { + remote-endpoint = <&it5205_sbu_ep>; + }; + }; + }; + }; + }; + }; +}; + +&mfg0 { + domain-supply = <&mt6315_7_vbuck1>; +}; + +&mfg1 { + domain-supply = <&mt6359_vsram_others_ldo_reg>; +}; + +&mipi_tx0 { + status = "okay"; +}; + +&mmc0 { + status = "okay"; + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc0_default_pins>; + pinctrl-1 = <&mmc0_uhs_pins>; + bus-width = <8>; + max-frequency = <200000000>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + cap-mmc-hw-reset; + no-sdio; + no-sd; + hs400-ds-delay = <0x14c11>; + vmmc-supply = <&mt6359_vemc_1_ldo_reg>; + vqmmc-supply = <&mt6359_vufs_ldo_reg>; + non-removable; +}; + +&mmc1 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc1_default_pins>; + pinctrl-1 = <&mmc1_uhs_pins>; + bus-width = <4>; + max-frequency = <200000000>; + cap-sd-highspeed; + sd-uhs-sdr50; + sd-uhs-sdr104; + no-mmc; + no-sdio; + vmmc-supply = <&mt6360_ldo5>; + vqmmc-supply = <&mt6360_ldo3>; + status = "okay"; + non-removable; +}; + +&mt6359_vaud18_ldo_reg { + regulator-always-on; +}; + +&mt6359_vbbck_ldo_reg { + regulator-always-on; +}; + +/* For USB Hub */ +&mt6359_vcamio_ldo_reg { + regulator-always-on; +}; + +&mt6359_vcn33_2_bt_ldo_reg { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +}; + +&mt6359_vcore_buck_reg { + regulator-always-on; +}; + +&mt6359_vgpu11_buck_reg { + regulator-always-on; +}; + +&mt6359_vpu_buck_reg { + regulator-always-on; +}; + +&mt6359_vrf12_ldo_reg { + regulator-always-on; +}; + +/* for GPU SRAM */ +&mt6359_vsram_others_ldo_reg { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; +}; + +&mt6359codec { + mediatek,mic-type-0 = <1>; /* ACC */ + mediatek,mic-type-1 = <3>; /* DCC */ + mediatek,mic-type-2 = <1>; /* ACC */ +}; + +&ovl0_in { + remote-endpoint = <&vdosys0_ep_main>; +}; + +&pcie0 { + pinctrl-names = "default", "idle"; + pinctrl-0 = <&pcie0_default_pins>; + pinctrl-1 = <&pcie0_idle_pins>; + status = "okay"; +}; + +&pcie1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie1_default_pins>; + status = "disabled"; +}; + +&pciephy { + status = "okay"; +}; + +&pio { + audio_default_pins: audio-default-pins { + pins-cmd-dat { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + ; + }; + }; + + disp_pwm1_default_pins: disp-pwm1-default-pins { + pins1 { + pinmux = ; + }; + }; + + edp_panel_12v_en_pins: edp-panel-12v-en-pins { + pins1 { + pinmux = ; + output-high; + }; + }; + + edp_panel_3v3_en_pins: edp-panel-3v3-en-pins { + pins1 { + pinmux = ; + output-high; + }; + }; + + eth_default_pins: eth-default-pins { + pins-cc { + pinmux = , + , + , + ; + drive-strength = <8>; + }; + + pins-mdio { + pinmux = , + ; + input-enable; + }; + + pins-power { + pinmux = , + ; + output-high; + }; + + pins-rxd { + pinmux = , + , + , + ; + }; + + pins-txd { + pinmux = , + , + , + ; + drive-strength = <8>; + }; + }; + + eth_sleep_pins: eth-sleep-pins { + pins-cc { + pinmux = , + , + , + ; + }; + + pins-mdio { + pinmux = , + ; + input-disable; + bias-disable; + }; + + pins-rxd { + pinmux = , + , + , + ; + }; + + pins-txd { + pinmux = , + , + , + ; + }; + }; + + gpio_key_pins: gpio-keys-pins { + pins { + pinmux = ; + bias-pull-up; + input-enable; + }; + }; + + i2c0_pins: i2c0-pins { + pins { + pinmux = , + ; + bias-pull-up = ; + drive-strength-microamp = <1000>; + }; + }; + + i2c1_pins: i2c1-pins { + pins { + pinmux = , + ; + bias-pull-up = ; + drive-strength-microamp = <1000>; + }; + }; + + i2c2_pins: i2c2-pins { + pins { + pinmux = , + ; + bias-pull-up = ; + drive-strength = <6>; + }; + }; + + i2c6_pins: i2c6-pins { + pins { + pinmux = , + ; + bias-pull-up; + }; + }; + + mmc0_default_pins: mmc0-default-pins { + pins-clk { + pinmux = ; + drive-strength = <6>; + bias-pull-down = ; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + drive-strength = <6>; + bias-pull-up = ; + }; + + pins-rst { + pinmux = ; + drive-strength = <6>; + bias-pull-up = ; + }; + }; + + mmc0_uhs_pins: mmc0-uhs-pins { + pins-clk { + pinmux = ; + drive-strength = <8>; + bias-pull-down = ; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + drive-strength = <8>; + bias-pull-up = ; + }; + + pins-ds { + pinmux = ; + drive-strength = <8>; + bias-pull-down = ; + }; + + pins-rst { + pinmux = ; + drive-strength = <8>; + bias-pull-up = ; + }; + }; + + mmc1_default_pins: mmc1-default-pins { + pins-clk { + pinmux = ; + drive-strength = <8>; + bias-pull-down = ; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + ; + input-enable; + drive-strength = <8>; + bias-pull-up = ; + }; + }; + + mmc1_uhs_pins: mmc1-uhs-pins { + pins-clk { + pinmux = ; + drive-strength = <8>; + bias-pull-down = ; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + ; + input-enable; + drive-strength = <8>; + bias-pull-up = ; + }; + }; + + mt6360_pins: mt6360-pins { + pins { + pinmux = , + ; + input-enable; + bias-pull-up; + }; + }; + + dsi0_vreg_en_pins: dsi0-vreg-en-pins { + pins-pwr-en { + pinmux = ; + output-low; + }; + }; + + panel_default_pins: panel-default-pins { + pins-rst { + pinmux = ; + output-high; + }; + + pins-en { + pinmux = ; + output-low; + }; + }; + + pcie0_default_pins: pcie0-default-pins { + pins { + pinmux = , + , + ; + bias-pull-up; + }; + }; + + pcie0_idle_pins: pcie0-idle-pins { + pins { + pinmux = ; + bias-disable; + output-low; + }; + }; + + pcie1_default_pins: pcie1-default-pins { + pins { + pinmux = , + , + ; + bias-pull-up; + }; + }; + + disp_pwm0_pins: disp-pwm0-pins { + pins-disp-pwm { + pinmux = ; + }; + }; + + spi1_pins: spi1-pins { + pins { + pinmux = , + , + , + ; + bias-disable; + }; + }; + + spi2_pins: spi-pins { + pins { + pinmux = , + , + , + ; + bias-disable; + }; + }; + + touch_pins: touch-pins { + pins-irq { + pinmux = ; + input-enable; + bias-disable; + }; + + pins-reset { + pinmux = ; + output-high; + }; + }; + + u3_p0_vbus: u3-p0-vbus-default-pins { + pins-vbus { + pinmux = ; + input-enable; + }; + }; + + uart0_pins: uart0-pins { + pins { + pinmux = , + ; + }; + }; + + uart1_pins: uart1-pins { + pins { + pinmux = , + , + , + ; + }; + }; +}; + +&pmic { + interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>; + + mt6359keys: keys { + compatible = "mediatek,mt6359-keys"; + mediatek,long-press-mode = <1>; + power-off-time-sec = <0>; + + power-key { + linux,keycodes = ; + wakeup-source; + }; + + home { + linux,keycodes = ; + }; + }; +}; + +&scp { + memory-region = <&scp_mem>; + firmware-name = "mediatek/mt8195/scp.img"; + status = "okay"; +}; + +&sound { + compatible = "mediatek,mt8195_mt6359"; + model = "mt8395-evk"; + pinctrl-names = "default"; + pinctrl-0 = <&audio_default_pins>; + audio-routing = + "Headphone", "Headphone L", + "Headphone", "Headphone R"; + mediatek,adsp = <&adsp>; + status = "okay"; + + headphone-dai-link { + link-name = "DL_SRC_BE"; + + codec { + sound-dai = <&pmic 0>; + }; + }; +}; + +&spi1 { + pinctrl-0 = <&spi1_pins>; + pinctrl-names = "default"; + mediatek,pad-select = <0>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + cs-gpios = <&pio 64 GPIO_ACTIVE_LOW>; + + can0: can@0 { + compatible = "microchip,mcp2518fd"; + reg = <0>; + clocks = <&can_clk>; + spi-max-frequency = <20000000>; + interrupts-extended = <&pio 16 IRQ_TYPE_LEVEL_LOW>; + vdd-supply = <&mt6359_vcn33_2_bt_ldo_reg>; + xceiver-supply = <&mt6359_vcn33_2_bt_ldo_reg>; + }; +}; + +&spi2 { + pinctrl-0 = <&spi2_pins>; + pinctrl-names = "default"; + mediatek,pad-select = <0>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; +}; + +&spmi { + #address-cells = <2>; + #size-cells = <0>; + + mt6315_6: pmic@6 { + compatible = "mediatek,mt6315-regulator"; + reg = <0x6 SPMI_USID>; + + regulators { + mt6315_6_vbuck1: vbuck1 { + regulator-name = "Vbcpu"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + regulator-always-on; + }; + }; + }; + + mt6315_7: pmic@7 { + compatible = "mediatek,mt6315-regulator"; + reg = <0x7 SPMI_USID>; + + regulators { + mt6315_7_vbuck1: vbuck1 { + regulator-name = "Vgpu"; + regulator-min-microvolt = <546000>; + regulator-max-microvolt = <787000>; + regulator-enable-ramp-delay = <256>; + regulator-allowed-modes = <0 1 2>; + }; + }; + }; +}; + +&u3phy0 { + status = "okay"; +}; + +&u3phy1 { + status = "okay"; + + u3port1: usb-phy@700 { + mediatek,force-mode; + }; +}; + +&u3phy2 { + status = "okay"; +}; + +&u3phy3 { + status = "okay"; +}; + +&uart0 { + pinctrl-0 = <&uart0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&uart1 { + pinctrl-0 = <&uart1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&ufsphy { + status = "disabled"; +}; + +&ssusb0 { + dr_mode = "otg"; + pinctrl-names = "default"; + pinctrl-0 = <&u3_p0_vbus>; + usb-role-switch; + vusb33-supply = <&mt6359_vusb_ldo_reg>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mtu3_hs0_role_sw: endpoint { + remote-endpoint = <&typec_con_hs>; + }; + }; + + port@1 { + reg = <1>; + mtu3_ss0_role_sw: endpoint { + remote-endpoint = <&typec_con_ss>; + }; + }; + }; +}; + +&ssusb2 { + vusb33-supply = <&mt6359_vusb_ldo_reg>; + status = "okay"; +}; + +&ssusb3 { + vusb33-supply = <&mt6359_vusb_ldo_reg>; + status = "okay"; +}; + +&vdosys0 { + port { + #address-cells = <1>; + #size-cells = <0>; + + vdosys0_ep_main: endpoint@0 { + reg = <0>; + remote-endpoint = <&ovl0_in>; + }; + }; +}; + +&xhci0 { + status = "okay"; +}; + +&xhci1 { + vusb33-supply = <&mt6359_vusb_ldo_reg>; + status = "okay"; +}; + +&xhci2 { + status = "okay"; +}; + +&xhci3 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile index 171e08c94d5a2..b139cbd144422 100644 --- a/arch/arm64/boot/dts/nvidia/Makefile +++ b/arch/arm64/boot/dts/nvidia/Makefile @@ -3,6 +3,7 @@ # Enables support for device-tree overlays DTC_FLAGS_tegra210-p2371-2180 := -@ DTC_FLAGS_tegra210-p3450-0000 := -@ +DTC_FLAGS_tegra210-p3541-0000 := -@ DTC_FLAGS_tegra186-p2771-0000 := -@ DTC_FLAGS_tegra186-p3509-0000+p3636-0001 := -@ DTC_FLAGS_tegra194-p2972-0000 := -@ @@ -19,6 +20,7 @@ dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-0000.dtb dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-2180.dtb dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2571.dtb dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3450-0000.dtb +dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3541-0000.dtb dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-smaug.dtb dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2894-0050-a08.dtb dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p2771-0000.dtb diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi index 5bcccfef3f7f8..26cd11a8a4a12 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -175,6 +175,7 @@ gic: interrupt-controller@50041000 { compatible = "arm,cortex-a15-gic"; + #address-cells = <0>; #interrupt-cells = <3>; interrupt-controller; reg = <0x0 0x50041000 0x0 0x1000>, @@ -271,7 +272,7 @@ interrupt-controller; }; - apbdma: dma@60020000 { + apbdma: dma-controller@60020000 { compatible = "nvidia,tegra124-apbdma", "nvidia,tegra148-apbdma"; reg = <0x0 0x60020000 0x0 0x1400>; interrupts = , diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts b/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts index 5f3f572ecea97..d9aafe0531121 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts +++ b/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts @@ -671,7 +671,6 @@ vbus-gpios = <&gpio TEGRA186_MAIN_GPIO(L, 4) GPIO_ACTIVE_LOW>; - id-gpios = <&pmic 0 GPIO_ACTIVE_HIGH>; }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 5778c93af3e6e..b006304519096 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -36,6 +36,12 @@ interrupt-controller; #gpio-cells = <2>; gpio-controller; + gpio-ranges = <&pinmux 0 0 140>; + }; + + pinmux: pinmux@2430000 { + compatible = "nvidia,tegra186-pinmux"; + reg = <0x0 0x2430000 0x0 0x15000>; }; ethernet@2490000 { @@ -1173,6 +1179,7 @@ gic: interrupt-controller@3881000 { compatible = "arm,gic-400"; + #address-cells = <0>; #interrupt-cells = <3>; interrupt-controller; reg = <0x0 0x03881000 0x0 0x1000>, @@ -1274,10 +1281,16 @@ interrupts = ; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinmux_aon 0 0 47>; interrupt-controller; #interrupt-cells = <2>; }; + pinmux_aon: pinmux@c300000 { + compatible = "nvidia,tegra186-pinmux-aon"; + reg = <0x0 0xc300000 0x0 0x4000>; + }; + pwm4: pwm@c340000 { compatible = "nvidia,tegra186-pwm"; reg = <0x0 0xc340000 0x0 0x10000>; diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index 1399342f23e1c..b782f8db1288a 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -1331,6 +1331,7 @@ gic: interrupt-controller@3881000 { compatible = "arm,gic-400"; + #address-cells = <0>; #interrupt-cells = <3>; interrupt-controller; reg = <0x0 0x03881000 0x0 0x1000>, diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi index e07aeeee35867..9ee7952af7997 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi @@ -18,6 +18,12 @@ stdout-path = "serial0:115200n8"; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + }; + memory@80000000 { device_type = "memory"; reg = <0x0 0x80000000 0x1 0x0>; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi index 584461f3a6196..4a64fe510f035 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi @@ -20,10 +20,10 @@ vi@54080000 { status = "okay"; - avdd-dsi-csi-supply = <&vdd_dsi_csi>; - csi@838 { status = "okay"; + + avdd-dsi-csi-supply = <&vdd_dsi_csi>; }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts index ec0e84cb83ef9..d78b9bd45df6c 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts @@ -22,6 +22,12 @@ stdout-path = "serial0:115200n8"; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + }; + memory@80000000 { device_type = "memory"; reg = <0x0 0x80000000 0x1 0x0>; @@ -64,10 +70,10 @@ vi@54080000 { status = "okay"; - avdd-dsi-csi-supply = <&vdd_sys_1v2>; - csi@838 { status = "okay"; + + avdd-dsi-csi-supply = <&vdd_sys_1v2>; }; }; @@ -520,7 +526,7 @@ ports { usb2-0 { status = "okay"; - mode = "peripheral"; + mode = "otg"; usb-role-switch; vbus-supply = <&vdd_5v0_usb>; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3541-0000.dts b/arch/arm64/boot/dts/nvidia/tegra210-p3541-0000.dts new file mode 100644 index 0000000000000..b86e271dde0be --- /dev/null +++ b/arch/arm64/boot/dts/nvidia/tegra210-p3541-0000.dts @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "tegra210-p3450-0000.dts" + +/ { + model = "NVIDIA Jetson Nano 2GB Developer Kit"; + compatible = "nvidia,p3541-0000", "nvidia,p3450-0000", "nvidia,tegra210"; + + memory@80000000 { + reg = <0x0 0x80000000 0x0 0x80000000>; + }; + + host1x@50000000 { + sor@54540000 { + status = "disabled"; + }; + + dpaux@545c0000 { + status = "disabled"; + }; + }; + + padctl@7009f000 { + ports { + usb2-1 { + vbus-supply = <&vdd_hub_5v0>; + }; + + usb2-2 { + vbus-supply = <&vdd_hub_5v0>; + }; + + usb3-0 { + /delete-property/ vbus-supply; + }; + }; + }; + + regulator-vdd-hdmi-5v0 { + gpio = <&gpio TEGRA_GPIO(A, 6) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + /delete-node/ regulator-vdd-hub-3v3; + + vdd_hub_5v0: regulator-vdd-hub-5v0 { + compatible = "regulator-fixed"; + + regulator-name = "VDD_HUB_5V0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + gpio = <&gpio TEGRA_GPIO(I, 2) GPIO_ACTIVE_HIGH>; + enable-active-high; + + vin-supply = <&vdd_5v0_sys>; + }; +}; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-peripherals-opp.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-peripherals-opp.dtsi new file mode 100644 index 0000000000000..bf2527d737932 --- /dev/null +++ b/arch/arm64/boot/dts/nvidia/tegra210-peripherals-opp.dtsi @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0 + +/ { + /* EMC DVFS OPP table */ + emc_icc_dvfs_opp_table: opp-table-dvfs0 { + compatible = "operating-points-v2"; + + opp-40800000-800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <40800000>; + opp-supported-hw = <0x0003>; + }; + + opp-68000000-800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <68000000>; + opp-supported-hw = <0x0003>; + }; + + opp-102000000-800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x0003>; + }; + + opp-204000000-800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <204000000>; + opp-supported-hw = <0x0007>; + opp-suspend; + }; + + opp-408000000-812 { + opp-microvolt = <812000 812000 1150000>; + opp-hz = /bits/ 64 <408000000>; + opp-supported-hw = <0x0003>; + }; + + opp-665600000-825 { + opp-microvolt = <825000 825000 1150000>; + opp-hz = /bits/ 64 <665600000>; + opp-supported-hw = <0x0003>; + }; + + opp-800000000-825 { + opp-microvolt = <825000 825000 1150000>; + opp-hz = /bits/ 64 <800000000>; + opp-supported-hw = <0x0003>; + }; + + opp-1065600000-837 { + opp-microvolt = <837000 837000 1150000>; + opp-hz = /bits/ 64 <1065600000>; + opp-supported-hw = <0x0003>; + }; + + opp-1331200000-850 { + opp-microvolt = <850000 850000 1150000>; + opp-hz = /bits/ 64 <1331200000>; + opp-supported-hw = <0x0003>; + }; + + opp-1600000000-887 { + opp-microvolt = <887000 887000 1150000>; + opp-hz = /bits/ 64 <1600000000>; + opp-supported-hw = <0x0007>; + }; + }; + + /* EMC bandwidth OPP table */ + emc_bw_dfs_opp_table: opp-table-dvfs1 { + compatible = "operating-points-v2"; + + opp-40800000 { + opp-hz = /bits/ 64 <40800000>; + opp-supported-hw = <0x0003>; + opp-peak-kBps = <652800>; + }; + + opp-68000000 { + opp-hz = /bits/ 64 <68000000>; + opp-supported-hw = <0x0003>; + opp-peak-kBps = <1088000>; + }; + + opp-102000000 { + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x0003>; + opp-peak-kBps = <1632000>; + }; + + opp-204000000 { + opp-hz = /bits/ 64 <204000000>; + opp-supported-hw = <0x0007>; + opp-peak-kBps = <3264000>; + opp-suspend; + }; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-supported-hw = <0x0003>; + opp-peak-kBps = <6528000>; + }; + + opp-665600000 { + opp-hz = /bits/ 64 <665600000>; + opp-supported-hw = <0x0003>; + opp-peak-kBps = <10649600>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <12800000>; + }; + + opp-1065600000 { + opp-hz = /bits/ 64 <1065600000>; + opp-supported-hw = <0x0003>; + opp-peak-kBps = <17049600>; + }; + + opp-1331200000 { + opp-hz = /bits/ 64 <1331200000>; + opp-supported-hw = <0x0003>; + opp-peak-kBps = <21299200>; + }; + + opp-1600000000 { + opp-hz = /bits/ 64 <1600000000>; + opp-supported-hw = <0x0007>; + opp-peak-kBps = <25600000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 402b0ede1472a..709da31d57851 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -9,6 +9,8 @@ #include #include +#include "tegra210-peripherals-opp.dtsi" + / { compatible = "nvidia,tegra210"; interrupt-parent = <&lic>; @@ -183,9 +185,7 @@ reg = <0x0 0x54100000 0x0 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA210_CLK_TSEC>; - clock-names = "tsec"; resets = <&tegra_car 83>; - reset-names = "tsec"; status = "disabled"; }; @@ -202,6 +202,19 @@ nvidia,outputs = <&dsia &dsib &sor0 &sor1>; nvidia,head = <0>; + + interconnects = <&mc TEGRA210_MC_DISPLAY0A &emc>, + <&mc TEGRA210_MC_DISPLAY0B &emc>, + <&mc TEGRA210_MC_DISPLAY0C &emc>, + <&mc TEGRA210_MC_DISPLAYHC &emc>, + <&mc TEGRA210_MC_DISPLAYD &emc>, + <&mc TEGRA210_MC_DISPLAYT &emc>; + interconnect-names = "wina", + "winb", + "winc", + "cursor", + "wind", + "wint"; }; dc@54240000 { @@ -217,6 +230,15 @@ nvidia,outputs = <&dsia &dsib &sor0 &sor1>; nvidia,head = <1>; + + interconnects = <&mc TEGRA210_MC_DISPLAY0AB &emc>, + <&mc TEGRA210_MC_DISPLAY0BB &emc>, + <&mc TEGRA210_MC_DISPLAY0CB &emc>, + <&mc TEGRA210_MC_DISPLAYHCB &emc>; + interconnect-names = "wina", + "winb", + "winc", + "cursor"; }; dsia: dsi@54300000 { @@ -253,7 +275,13 @@ nvjpg@54380000 { compatible = "nvidia,tegra210-nvjpg"; reg = <0x0 0x54380000 0x0 0x00040000>; - status = "disabled"; + clocks = <&tegra_car TEGRA210_CLK_NVJPG>; + clock-names = "nvjpg"; + resets = <&tegra_car 195>; + reset-names = "nvjpg"; + + iommus = <&mc TEGRA_SWGROUP_NVJPG>; + power-domains = <&pd_nvjpg>; }; dsib: dsi@54400000 { @@ -277,13 +305,25 @@ nvdec@54480000 { compatible = "nvidia,tegra210-nvdec"; reg = <0x0 0x54480000 0x0 0x00040000>; - status = "disabled"; + clocks = <&tegra_car TEGRA210_CLK_NVDEC>; + clock-names = "nvdec"; + resets = <&tegra_car 194>; + reset-names = "nvdec"; + + iommus = <&mc TEGRA_SWGROUP_NVDEC>; + power-domains = <&pd_nvdec>; }; nvenc@544c0000 { compatible = "nvidia,tegra210-nvenc"; reg = <0x0 0x544c0000 0x0 0x00040000>; - status = "disabled"; + clocks = <&tegra_car TEGRA210_CLK_NVENC>; + clock-names = "nvenc"; + resets = <&tegra_car 219>; + reset-names = "nvenc"; + + iommus = <&mc TEGRA_SWGROUP_NVENC>; + power-domains = <&pd_nvenc>; }; tsec@54500000 { @@ -409,6 +449,7 @@ gic: interrupt-controller@50041000 { compatible = "arm,gic-400"; + #address-cells = <0>; #interrupt-cells = <3>; interrupt-controller; reg = <0x0 0x50041000 0x0 0x1000>, @@ -485,6 +526,21 @@ reg = <0x0 0x60007000 0x0 0x1000>; }; + actmon@6000c800 { + compatible = "nvidia,tegra210-actmon", "nvidia,tegra124-actmon"; + reg = <0x0 0x6000c800 0x0 0x400>; + interrupts = ; + clocks = <&tegra_car TEGRA210_CLK_ACTMON>, + <&tegra_car TEGRA210_CLK_EMC>; + clock-names = "actmon", "emc"; + resets = <&tegra_car 119>; + reset-names = "actmon"; + operating-points-v2 = <&emc_bw_dfs_opp_table>; + interconnects = <&mc TEGRA210_MC_MPCORER &emc>; + interconnect-names = "cpu-read"; + #cooling-cells = <2>; + }; + gpio: gpio@6000d000 { compatible = "nvidia,tegra210-gpio", "nvidia,tegra30-gpio"; reg = <0x0 0x6000d000 0x0 0x1000>; @@ -502,7 +558,7 @@ interrupt-controller; }; - apbdma: dma@60020000 { + apbdma: dma-controller@60020000 { compatible = "nvidia,tegra210-apbdma", "nvidia,tegra148-apbdma"; reg = <0x0 0x60020000 0x0 0x1400>; interrupts = , @@ -894,6 +950,18 @@ #power-domain-cells = <0>; }; + pd_nvenc: mpe { + clocks = <&tegra_car TEGRA210_CLK_NVENC>; + resets = <&tegra_car 219>; + #power-domain-cells = <0>; + }; + + pd_nvdec: nvdec { + clocks = <&tegra_car TEGRA210_CLK_NVDEC>; + resets = <&tegra_car 194>; + #power-domain-cells = <0>; + }; + pd_sor: sor { clocks = <&tegra_car TEGRA210_CLK_SOR0>, <&tegra_car TEGRA210_CLK_SOR1>, @@ -947,6 +1015,12 @@ resets = <&tegra_car TEGRA210_CLK_XUSB_HOST>; #power-domain-cells = <0>; }; + + pd_nvjpg: nvjpg { + clocks = <&tegra_car TEGRA210_CLK_NVJPG>; + resets = <&tegra_car 195>; + #power-domain-cells = <0>; + }; }; }; @@ -978,6 +1052,7 @@ #iommu-cells = <1>; #reset-cells = <1>; + #interconnect-cells = <1>; }; emc: external-memory-controller@7001b000 { @@ -989,6 +1064,9 @@ clock-names = "emc"; interrupts = ; nvidia,memory-controller = <&mc>; + operating-points-v2 = <&emc_icc_dvfs_opp_table>; + + #interconnect-cells = <0>; #cooling-cells = <2>; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi index 9086a0d010e5c..58bf55c0e414c 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi @@ -8,6 +8,7 @@ aliases { mmc0 = "/bus@0/mmc@3460000"; mmc1 = "/bus@0/mmc@3400000"; + rtc0 = "/bpmp/i2c/pmic@3c"; }; bus@0 { @@ -170,6 +171,16 @@ i2c { status = "okay"; + pmic@3c { + compatible = "nvidia,vrs-10"; + reg = <0x3c>; + interrupt-parent = <&pmc>; + /* VRS Wake ID is 24 */ + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; + }; + thermal-sensor@4c { compatible = "ti,tmp451"; status = "okay"; diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi index 84db7132e8fc8..ab391a71c3d33 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi @@ -7,6 +7,7 @@ aliases { mmc0 = "/bus@0/mmc@3400000"; + rtc0 = "/bpmp/i2c/pmic@3c"; }; bus@0 { @@ -121,6 +122,20 @@ }; }; + bpmp { + i2c { + pmic@3c { + compatible = "nvidia,vrs-10"; + reg = <0x3c>; + interrupt-parent = <&pmc>; + /* VRS Wake ID is 24 */ + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + }; + vdd_5v0_sys: regulator-vdd-5v0-sys { compatible = "regulator-fixed"; regulator-name = "VDD_5V0_SYS"; diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi index df034dbb82853..827dbb4208261 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include / { compatible = "nvidia,tegra234"; @@ -127,6 +128,56 @@ pinmux: pinmux@2430000 { compatible = "nvidia,tegra234-pinmux"; reg = <0x0 0x2430000 0x0 0x19100>; + + pex_rst_c4_in_state: pinmux-pex-rst-c4-in { + pex_rst { + nvidia,pins = "pex_l4_rst_n_pl1"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + }; + + pex_rst_c5_in_state: pinmux-pex-rst-c5-in { + pex_rst { + nvidia,pins = "pex_l5_rst_n_paf1"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + }; + + pex_rst_c6_in_state: pinmux-pex-rst-c6-in { + pex_rst { + nvidia,pins = "pex_l6_rst_n_paf3"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + }; + + pex_rst_c7_in_state: pinmux-pex-rst-c7-in { + pex_rst { + nvidia,pins = "pex_l7_rst_n_pag1"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + }; + + pex_rst_c10_in_state: pinmux-pex-rst-c10-in { + pex_rst { + nvidia,pins = "pex_l10_rst_n_pag7"; + nvidia,function = "rsvd1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + }; }; gpcdma: dma-controller@2600000 { @@ -3276,8 +3327,15 @@ <0x0 0x03650000 0x0 0x10000>; reg-names = "hcd", "fpci", "bar2"; - interrupts = , - ; + interrupts-extended = <&gic GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, + <&gic GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, + <&pmc 76 IRQ_TYPE_LEVEL_HIGH>, + <&pmc 77 IRQ_TYPE_LEVEL_HIGH>, + <&pmc 78 IRQ_TYPE_LEVEL_HIGH>, + <&pmc 79 IRQ_TYPE_LEVEL_HIGH>, + <&pmc 80 IRQ_TYPE_LEVEL_HIGH>, + <&pmc 81 IRQ_TYPE_LEVEL_HIGH>, + <&pmc 82 IRQ_TYPE_LEVEL_HIGH>; clocks = <&bpmp TEGRA234_CLK_XUSB_CORE_HOST>, <&bpmp TEGRA234_CLK_XUSB_FALCON>, @@ -4630,6 +4688,8 @@ <&bpmp TEGRA234_RESET_PEX2_CORE_10>; reset-names = "apb", "core"; + pinctrl-names = "default"; + pinctrl-0 = <&pex_rst_c10_in_state>; interrupts = ; /* controller interrupt */ interrupt-names = "intr"; @@ -4881,6 +4941,8 @@ <&bpmp TEGRA234_RESET_PEX0_CORE_4>; reset-names = "apb", "core"; + pinctrl-names = "default"; + pinctrl-0 = <&pex_rst_c4_in_state>; interrupts = ; /* controller interrupt */ interrupt-names = "intr"; nvidia,bpmp = <&bpmp 4>; @@ -5023,6 +5085,8 @@ <&bpmp TEGRA234_RESET_PEX1_CORE_5>; reset-names = "apb", "core"; + pinctrl-names = "default"; + pinctrl-0 = <&pex_rst_c5_in_state>; interrupts = ; /* controller interrupt */ interrupt-names = "intr"; @@ -5115,6 +5179,8 @@ <&bpmp TEGRA234_RESET_PEX1_CORE_6>; reset-names = "apb", "core"; + pinctrl-names = "default"; + pinctrl-0 = <&pex_rst_c6_in_state>; interrupts = ; /* controller interrupt */ interrupt-names = "intr"; @@ -5207,6 +5273,8 @@ <&bpmp TEGRA234_RESET_PEX2_CORE_7>; reset-names = "apb", "core"; + pinctrl-names = "default"; + pinctrl-0 = <&pex_rst_c7_in_state>; interrupts = ; /* controller interrupt */ interrupt-names = "intr"; diff --git a/arch/arm64/boot/dts/nvidia/tegra264-p3971.dtsi b/arch/arm64/boot/dts/nvidia/tegra264-p3971.dtsi index 6b6259b7310fb..b1bd4ee7aee30 100644 --- a/arch/arm64/boot/dts/nvidia/tegra264-p3971.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra264-p3971.dtsi @@ -1,4 +1,112 @@ // SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause / { + bus@0 { + aconnect@9000000 { + status = "okay"; + + dma-controller@9440000 { + status = "okay"; + }; + + ahub@9630000 { + status = "okay"; + + i2s@9280000 { + status = "okay"; + }; + + i2s@9290000 { + status = "okay"; + }; + + i2s@92b0000 { + status = "okay"; + }; + }; + + interrupt-controller@9960000 { + status = "okay"; + }; + }; + }; + + bus@8800000000 { + hda@90b0000 { + nvidia,model = "NVIDIA Jetson Thor AGX HDA"; + status = "okay"; + }; + }; + + sound { + status = "okay"; + + dais = /* ADMAIF (FE) Ports */ + <&admaif0_port>, <&admaif1_port>, <&admaif2_port>, <&admaif3_port>, + <&admaif4_port>, <&admaif5_port>, <&admaif6_port>, <&admaif7_port>, + <&admaif8_port>, <&admaif9_port>, <&admaif10_port>, <&admaif11_port>, + <&admaif12_port>, <&admaif13_port>, <&admaif14_port>, <&admaif15_port>, + <&admaif16_port>, <&admaif17_port>, <&admaif18_port>, <&admaif19_port>, + <&admaif20_port>, <&admaif21_port>, <&admaif22_port>, <&admaif23_port>, + <&admaif24_port>, <&admaif25_port>, <&admaif26_port>, <&admaif27_port>, + <&admaif28_port>, <&admaif29_port>, <&admaif30_port>, <&admaif31_port>, + /* XBAR Ports */ + <&xbar_i2s1_port>, <&xbar_i2s2_port>, <&xbar_i2s4_port>, + <&xbar_sfc1_in_port>, <&xbar_sfc2_in_port>, + <&xbar_sfc3_in_port>, <&xbar_sfc4_in_port>, + <&xbar_mvc1_in_port>, <&xbar_mvc2_in_port>, + <&xbar_amx1_in1_port>, <&xbar_amx1_in2_port>, + <&xbar_amx1_in3_port>, <&xbar_amx1_in4_port>, + <&xbar_amx2_in1_port>, <&xbar_amx2_in2_port>, + <&xbar_amx2_in3_port>, <&xbar_amx2_in4_port>, + <&xbar_amx3_in1_port>, <&xbar_amx3_in2_port>, + <&xbar_amx3_in3_port>, <&xbar_amx3_in4_port>, + <&xbar_amx4_in1_port>, <&xbar_amx4_in2_port>, + <&xbar_amx4_in3_port>, <&xbar_amx4_in4_port>, + <&xbar_amx5_in1_port>, <&xbar_amx5_in2_port>, + <&xbar_amx5_in3_port>, <&xbar_amx5_in4_port>, + <&xbar_amx6_in1_port>, <&xbar_amx6_in2_port>, + <&xbar_amx6_in3_port>, <&xbar_amx6_in4_port>, + <&xbar_adx1_in_port>, <&xbar_adx2_in_port>, + <&xbar_adx3_in_port>, <&xbar_adx4_in_port>, + <&xbar_adx5_in_port>, <&xbar_adx6_in_port>, + <&xbar_mix_in1_port>, <&xbar_mix_in2_port>, + <&xbar_mix_in3_port>, <&xbar_mix_in4_port>, + <&xbar_mix_in5_port>, <&xbar_mix_in6_port>, + <&xbar_mix_in7_port>, <&xbar_mix_in8_port>, + <&xbar_mix_in9_port>, <&xbar_mix_in10_port>, + <&xbar_asrc_in1_port>, <&xbar_asrc_in2_port>, + <&xbar_asrc_in3_port>, <&xbar_asrc_in4_port>, + <&xbar_asrc_in5_port>, <&xbar_asrc_in6_port>, + <&xbar_asrc_in7_port>, + <&xbar_ope1_in_port>, + /* HW accelerators */ + <&sfc1_out_port>, <&sfc2_out_port>, + <&sfc3_out_port>, <&sfc4_out_port>, + <&mvc1_out_port>, <&mvc2_out_port>, + <&amx1_out_port>, <&amx2_out_port>, + <&amx3_out_port>, <&amx4_out_port>, + <&amx5_out_port>, <&amx6_out_port>, + <&adx1_out1_port>, <&adx1_out2_port>, + <&adx1_out3_port>, <&adx1_out4_port>, + <&adx2_out1_port>, <&adx2_out2_port>, + <&adx2_out3_port>, <&adx2_out4_port>, + <&adx3_out1_port>, <&adx3_out2_port>, + <&adx3_out3_port>, <&adx3_out4_port>, + <&adx4_out1_port>, <&adx4_out2_port>, + <&adx4_out3_port>, <&adx4_out4_port>, + <&adx5_out1_port>, <&adx5_out2_port>, + <&adx5_out3_port>, <&adx5_out4_port>, + <&adx6_out1_port>, <&adx6_out2_port>, + <&adx6_out3_port>, <&adx6_out4_port>, + <&mix_out1_port>, <&mix_out2_port>, <&mix_out3_port>, + <&mix_out4_port>, <&mix_out5_port>, + <&asrc_out1_port>, <&asrc_out2_port>, <&asrc_out3_port>, + <&asrc_out4_port>, <&asrc_out5_port>, <&asrc_out6_port>, + <&ope1_out_port>, + /* BE I/O Ports */ + <&i2s1_port>, <&i2s2_port>, <&i2s4_port>; + + label = "NVIDIA Jetson Thor AGX APE"; + }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra264.dtsi b/arch/arm64/boot/dts/nvidia/tegra264.dtsi index 872a69553e3c8..f137565da8048 100644 --- a/arch/arm64/boot/dts/nvidia/tegra264.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra264.dtsi @@ -4,6 +4,7 @@ #include #include #include +#include #include / { @@ -49,6 +50,3163 @@ status = "disabled"; }; + aconnect@9000000 { + compatible = "nvidia,tegra264-aconnect", + "nvidia,tegra210-aconnect"; + clocks = <&bpmp TEGRA264_CLK_APE>, + <&bpmp TEGRA264_CLK_ADSP>; + clock-names = "ape", "apb2ape"; + power-domains = <&bpmp TEGRA264_POWER_DOMAIN_AUD>; + status = "disabled"; + + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x9000000 0x0 0x9000000 0x0 0x2000000>; + + adma: dma-controller@9440000 { + compatible = "nvidia,tegra264-adma"; + reg = <0x0 0x9440000 0x0 0xb0000>; + interrupt-parent = <&agic_page0>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + #dma-cells = <1>; + clocks = <&bpmp TEGRA264_CLK_AHUB>; + clock-names = "d_audio"; + status = "disabled"; + }; + + tegra_ahub: ahub@9630000 { + compatible = "nvidia,tegra264-ahub"; + reg = <0x0 0x9630000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_AHUB>; + clock-names = "ahub"; + assigned-clocks = <&bpmp TEGRA264_CLK_AHUB>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLAON_APE>; + status = "disabled"; + + #address-cells = <2>; + #size-cells = <2>; + /* ADMA is under AHUB range, its excluded in the defined range */ + ranges = <0x0 0x9280000 0x0 0x9280000 0x0 0x1c0000>, + <0x0 0x9510000 0x0 0x9510000 0x0 0x370000>; + + tegra_i2s1: i2s@9280000 { + compatible = "nvidia,tegra264-i2s"; + reg = <0x0 0x9280000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_I2S1>, + <&bpmp TEGRA264_CLK_I2S1_SCLK_IN>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA264_CLK_I2S1>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S1"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s1_cif: endpoint { + remote-endpoint = <&xbar_i2s1>; + }; + }; + + i2s1_port: port@1 { + reg = <1>; + + i2s1_dap: endpoint { + dai-format = "i2s"; + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_i2s2: i2s@9290000 { + compatible = "nvidia,tegra264-i2s"; + reg = <0x0 0x9290000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_I2S2>, + <&bpmp TEGRA264_CLK_I2S2_SCLK_IN>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA264_CLK_I2S2>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S2"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s2_cif: endpoint { + remote-endpoint = <&xbar_i2s2>; + }; + }; + + i2s2_port: port@1 { + reg = <1>; + + i2s2_dap: endpoint { + dai-format = "i2s"; + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_i2s3: i2s@92a0000 { + compatible = "nvidia,tegra264-i2s"; + reg = <0x0 0x92a0000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_I2S3>, + <&bpmp TEGRA264_CLK_I2S3_SCLK_IN>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA264_CLK_I2S3>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S3"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s3_cif: endpoint { + remote-endpoint = <&xbar_i2s3>; + }; + }; + + i2s3_port: port@1 { + reg = <1>; + + i2s3_dap: endpoint { + dai-format = "i2s"; + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_i2s4: i2s@92b0000 { + compatible = "nvidia,tegra264-i2s"; + reg = <0x0 0x92b0000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_I2S4>, + <&bpmp TEGRA264_CLK_I2S4_SCLK_IN>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA264_CLK_I2S4>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S4"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s4_cif: endpoint { + remote-endpoint = <&xbar_i2s4>; + }; + }; + + i2s4_port: port@1 { + reg = <1>; + + i2s4_dap: endpoint { + dai-format = "i2s"; + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_i2s5: i2s@92c0000 { + compatible = "nvidia,tegra264-i2s"; + reg = <0x0 0x92c0000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_I2S5>, + <&bpmp TEGRA264_CLK_I2S5_SCLK_IN>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA264_CLK_I2S5>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S5"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s5_cif: endpoint { + remote-endpoint = <&xbar_i2s5>; + }; + }; + + i2s5_port: port@1 { + reg = <1>; + + i2s5_dap: endpoint { + dai-format = "i2s"; + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_i2s6: i2s@92d0000 { + compatible = "nvidia,tegra264-i2s"; + reg = <0x0 0x92d0000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_I2S6>, + <&bpmp TEGRA264_CLK_I2S6_SCLK_IN>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA264_CLK_I2S6>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S6"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s6_cif: endpoint { + remote-endpoint = <&xbar_i2s6>; + }; + }; + + i2s6_port: port@1 { + reg = <1>; + + i2s6_dap: endpoint { + dai-format = "i2s"; + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_i2s7: i2s@92e0000 { + compatible = "nvidia,tegra264-i2s"; + reg = <0x0 0x92e0000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_I2S7>, + <&bpmp TEGRA264_CLK_I2S7_SCLK_IN>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA264_CLK_I2S7>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S7"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s7_cif: endpoint { + remote-endpoint = <&xbar_i2s7>; + }; + }; + + i2s7_port: port@1 { + reg = <1>; + + i2s7_dap: endpoint { + dai-format = "i2s"; + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_i2s8: i2s@92f0000 { + compatible = "nvidia,tegra264-i2s"; + reg = <0x0 0x92f0000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_I2S8>, + <&bpmp TEGRA264_CLK_I2S8_SCLK_IN>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA264_CLK_I2S8>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S8"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s8_cif: endpoint { + remote-endpoint = <&xbar_i2s8>; + }; + }; + + i2s8_port: port@1 { + reg = <1>; + + i2s8_dap: endpoint { + dai-format = "i2s"; + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_dmic1: dmic@9300000 { + compatible = "nvidia,tegra264-dmic", + "nvidia,tegra210-dmic"; + reg = <0x0 0x9300000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_DMIC1>; + clock-names = "dmic"; + assigned-clocks = <&bpmp TEGRA264_CLK_DMIC1>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC1"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dmic1_cif: endpoint { + remote-endpoint = <&xbar_dmic1>; + }; + }; + + dmic1_port: port@1 { + reg = <1>; + + dmic1_dap: endpoint { + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_dmic2: dmic@9310000 { + compatible = "nvidia,tegra264-dmic", + "nvidia,tegra210-dmic"; + reg = <0x0 0x9310000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_DMIC1>; + clock-names = "dmic"; + assigned-clocks = <&bpmp TEGRA264_CLK_DMIC1>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC2"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dmic2_cif: endpoint { + remote-endpoint = <&xbar_dmic2>; + }; + }; + + dmic2_port: port@1 { + reg = <1>; + + dmic2_dap: endpoint { + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_dspk1: dspk@9380000 { + compatible = "nvidia,tegra264-dspk", + "nvidia,tegra186-dspk"; + reg = <0x0 0x9380000 0x0 0x10000>; + clocks = <&bpmp TEGRA264_CLK_DSPK1>; + clock-names = "dspk"; + assigned-clocks = <&bpmp TEGRA264_CLK_DSPK1>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + assigned-clock-rates = <12288000>; + sound-name-prefix = "DSPK1"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dspk1_cif: endpoint { + remote-endpoint = <&xbar_dspk1>; + }; + }; + + dspk1_port: port@1 { + reg = <1>; + + dspk1_dap: endpoint { + /* placeholder for external codec */ + }; + }; + }; + }; + + tegra_amx1: amx@9510000 { + compatible = "nvidia,tegra264-amx"; + reg = <0x0 0x9510000 0x0 0x10000>; + sound-name-prefix = "AMX1"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + amx1_in1: endpoint { + remote-endpoint = <&xbar_amx1_in1>; + }; + }; + + port@1 { + reg = <1>; + + amx1_in2: endpoint { + remote-endpoint = <&xbar_amx1_in2>; + }; + }; + + port@2 { + reg = <2>; + + amx1_in3: endpoint { + remote-endpoint = <&xbar_amx1_in3>; + }; + }; + + port@3 { + reg = <3>; + + amx1_in4: endpoint { + remote-endpoint = <&xbar_amx1_in4>; + }; + }; + + amx1_out_port: port@4 { + reg = <4>; + + amx1_out: endpoint { + remote-endpoint = <&xbar_amx1_out>; + }; + }; + }; + }; + + tegra_amx2: amx@9520000 { + compatible = "nvidia,tegra264-amx"; + reg = <0x0 0x9520000 0x0 0x10000>; + sound-name-prefix = "AMX2"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + amx2_in1: endpoint { + remote-endpoint = <&xbar_amx2_in1>; + }; + }; + + port@1 { + reg = <1>; + + amx2_in2: endpoint { + remote-endpoint = <&xbar_amx2_in2>; + }; + }; + + port@2 { + reg = <2>; + + amx2_in3: endpoint { + remote-endpoint = <&xbar_amx2_in3>; + }; + }; + + port@3 { + reg = <3>; + + amx2_in4: endpoint { + remote-endpoint = <&xbar_amx2_in4>; + }; + }; + + amx2_out_port: port@4 { + reg = <4>; + + amx2_out: endpoint { + remote-endpoint = <&xbar_amx2_out>; + }; + }; + }; + }; + + tegra_amx3: amx@9530000 { + compatible = "nvidia,tegra264-amx"; + reg = <0x0 0x9530000 0x0 0x10000>; + sound-name-prefix = "AMX3"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + amx3_in1: endpoint { + remote-endpoint = <&xbar_amx3_in1>; + }; + }; + + port@1 { + reg = <1>; + + amx3_in2: endpoint { + remote-endpoint = <&xbar_amx3_in2>; + }; + }; + + port@2 { + reg = <2>; + + amx3_in3: endpoint { + remote-endpoint = <&xbar_amx3_in3>; + }; + }; + + port@3 { + reg = <3>; + + amx3_in4: endpoint { + remote-endpoint = <&xbar_amx3_in4>; + }; + }; + + amx3_out_port: port@4 { + reg = <4>; + + amx3_out: endpoint { + remote-endpoint = <&xbar_amx3_out>; + }; + }; + }; + }; + + tegra_amx4: amx@9540000 { + compatible = "nvidia,tegra264-amx"; + reg = <0x0 0x9540000 0x0 0x10000>; + sound-name-prefix = "AMX4"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + amx4_in1: endpoint { + remote-endpoint = <&xbar_amx4_in1>; + }; + }; + + port@1 { + reg = <1>; + + amx4_in2: endpoint { + remote-endpoint = <&xbar_amx4_in2>; + }; + }; + + port@2 { + reg = <2>; + + amx4_in3: endpoint { + remote-endpoint = <&xbar_amx4_in3>; + }; + }; + + port@3 { + reg = <3>; + + amx4_in4: endpoint { + remote-endpoint = <&xbar_amx4_in4>; + }; + }; + + amx4_out_port: port@4 { + reg = <4>; + + amx4_out: endpoint { + remote-endpoint = <&xbar_amx4_out>; + }; + }; + }; + }; + + tegra_amx5: amx@9550000 { + compatible = "nvidia,tegra264-amx"; + reg = <0x0 0x9550000 0x0 0x10000>; + sound-name-prefix = "AMX5"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + amx5_in1: endpoint { + remote-endpoint = <&xbar_amx5_in1>; + }; + }; + + port@1 { + reg = <1>; + + amx5_in2: endpoint { + remote-endpoint = <&xbar_amx5_in2>; + }; + }; + + port@2 { + reg = <2>; + + amx5_in3: endpoint { + remote-endpoint = <&xbar_amx5_in3>; + }; + }; + + port@3 { + reg = <3>; + + amx5_in4: endpoint { + remote-endpoint = <&xbar_amx5_in4>; + }; + }; + + amx5_out_port: port@4 { + reg = <4>; + + amx5_out: endpoint { + remote-endpoint = <&xbar_amx5_out>; + }; + }; + }; + }; + + tegra_amx6: amx@9560000 { + compatible = "nvidia,tegra264-amx"; + reg = <0x0 0x9560000 0x0 0x10000>; + sound-name-prefix = "AMX6"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + amx6_in1: endpoint { + remote-endpoint = <&xbar_amx6_in1>; + }; + }; + + port@1 { + reg = <1>; + + amx6_in2: endpoint { + remote-endpoint = <&xbar_amx6_in2>; + }; + }; + + port@2 { + reg = <2>; + + amx6_in3: endpoint { + remote-endpoint = <&xbar_amx6_in3>; + }; + }; + + port@3 { + reg = <3>; + + amx6_in4: endpoint { + remote-endpoint = <&xbar_amx6_in4>; + }; + }; + + amx6_out_port: port@4 { + reg = <4>; + + amx6_out: endpoint { + remote-endpoint = <&xbar_amx6_out>; + }; + }; + }; + }; + + tegra_adx1: adx@9590000 { + compatible = "nvidia,tegra264-adx"; + reg = <0x0 0x9590000 0x0 0x10000>; + sound-name-prefix = "ADX1"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + adx1_in: endpoint { + remote-endpoint = <&xbar_adx1_in>; + }; + }; + + adx1_out1_port: port@1 { + reg = <1>; + + adx1_out1: endpoint { + remote-endpoint = <&xbar_adx1_out1>; + }; + }; + + adx1_out2_port: port@2 { + reg = <2>; + + adx1_out2: endpoint { + remote-endpoint = <&xbar_adx1_out2>; + }; + }; + + adx1_out3_port: port@3 { + reg = <3>; + + adx1_out3: endpoint { + remote-endpoint = <&xbar_adx1_out3>; + }; + }; + + adx1_out4_port: port@4 { + reg = <4>; + + adx1_out4: endpoint { + remote-endpoint = <&xbar_adx1_out4>; + }; + }; + }; + }; + + tegra_adx2: adx@95a0000 { + compatible = "nvidia,tegra264-adx"; + reg = <0x0 0x95a0000 0x0 0x10000>; + sound-name-prefix = "ADX2"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + adx2_in: endpoint { + remote-endpoint = <&xbar_adx2_in>; + }; + }; + + adx2_out1_port: port@1 { + reg = <1>; + + adx2_out1: endpoint { + remote-endpoint = <&xbar_adx2_out1>; + }; + }; + + adx2_out2_port: port@2 { + reg = <2>; + + adx2_out2: endpoint { + remote-endpoint = <&xbar_adx2_out2>; + }; + }; + + adx2_out3_port: port@3 { + reg = <3>; + + adx2_out3: endpoint { + remote-endpoint = <&xbar_adx2_out3>; + }; + }; + + adx2_out4_port: port@4 { + reg = <4>; + + adx2_out4: endpoint { + remote-endpoint = <&xbar_adx2_out4>; + }; + }; + }; + }; + + tegra_adx3: adx@95b0000 { + compatible = "nvidia,tegra264-adx"; + reg = <0x0 0x95b0000 0x0 0x10000>; + sound-name-prefix = "ADX3"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + adx3_in: endpoint { + remote-endpoint = <&xbar_adx3_in>; + }; + }; + + adx3_out1_port: port@1 { + reg = <1>; + + adx3_out1: endpoint { + remote-endpoint = <&xbar_adx3_out1>; + }; + }; + + adx3_out2_port: port@2 { + reg = <2>; + + adx3_out2: endpoint { + remote-endpoint = <&xbar_adx3_out2>; + }; + }; + + adx3_out3_port: port@3 { + reg = <3>; + + adx3_out3: endpoint { + remote-endpoint = <&xbar_adx3_out3>; + }; + }; + + adx3_out4_port: port@4 { + reg = <4>; + + adx3_out4: endpoint { + remote-endpoint = <&xbar_adx3_out4>; + }; + }; + }; + }; + + tegra_adx4: adx@95c0000 { + compatible = "nvidia,tegra264-adx"; + reg = <0x0 0x95c0000 0x0 0x10000>; + sound-name-prefix = "ADX4"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + adx4_in: endpoint { + remote-endpoint = <&xbar_adx4_in>; + }; + }; + + adx4_out1_port: port@1 { + reg = <1>; + + adx4_out1: endpoint { + remote-endpoint = <&xbar_adx4_out1>; + }; + }; + + adx4_out2_port: port@2 { + reg = <2>; + + adx4_out2: endpoint { + remote-endpoint = <&xbar_adx4_out2>; + }; + }; + + adx4_out3_port: port@3 { + reg = <3>; + + adx4_out3: endpoint { + remote-endpoint = <&xbar_adx4_out3>; + }; + }; + + adx4_out4_port: port@4 { + reg = <4>; + + adx4_out4: endpoint { + remote-endpoint = <&xbar_adx4_out4>; + }; + }; + }; + }; + + tegra_adx5: adx@95d0000 { + compatible = "nvidia,tegra264-adx"; + reg = <0x0 0x95d0000 0x0 0x10000>; + sound-name-prefix = "ADX5"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + adx5_in: endpoint { + remote-endpoint = <&xbar_adx5_in>; + }; + }; + + adx5_out1_port: port@1 { + reg = <1>; + + adx5_out1: endpoint { + remote-endpoint = <&xbar_adx5_out1>; + }; + }; + + adx5_out2_port: port@2 { + reg = <2>; + + adx5_out2: endpoint { + remote-endpoint = <&xbar_adx5_out2>; + }; + }; + + adx5_out3_port: port@3 { + reg = <3>; + + adx5_out3: endpoint { + remote-endpoint = <&xbar_adx5_out3>; + }; + }; + + adx5_out4_port: port@4 { + reg = <4>; + + adx5_out4: endpoint { + remote-endpoint = <&xbar_adx5_out4>; + }; + }; + }; + }; + + tegra_adx6: adx@95e0000 { + compatible = "nvidia,tegra264-adx"; + reg = <0x0 0x95e0000 0x0 0x10000>; + sound-name-prefix = "ADX6"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + adx6_in: endpoint { + remote-endpoint = <&xbar_adx6_in>; + }; + }; + + adx6_out1_port: port@1 { + reg = <1>; + + adx6_out1: endpoint { + remote-endpoint = <&xbar_adx6_out1>; + }; + }; + + adx6_out2_port: port@2 { + reg = <2>; + + adx6_out2: endpoint { + remote-endpoint = <&xbar_adx6_out2>; + }; + }; + + adx6_out3_port: port@3 { + reg = <3>; + + adx6_out3: endpoint { + remote-endpoint = <&xbar_adx6_out3>; + }; + }; + + adx6_out4_port: port@4 { + reg = <4>; + + adx6_out4: endpoint { + remote-endpoint = <&xbar_adx6_out4>; + }; + }; + }; + }; + + tegra_admaif: admaif@9610000 { + compatible = "nvidia,tegra264-admaif"; + reg = <0x0 0x9610000 0x0 0x10000>; + dmas = <&adma 1>, <&adma 1>, + <&adma 2>, <&adma 2>, + <&adma 3>, <&adma 3>, + <&adma 4>, <&adma 4>, + <&adma 5>, <&adma 5>, + <&adma 6>, <&adma 6>, + <&adma 7>, <&adma 7>, + <&adma 8>, <&adma 8>, + <&adma 9>, <&adma 9>, + <&adma 10>, <&adma 10>, + <&adma 11>, <&adma 11>, + <&adma 12>, <&adma 12>, + <&adma 13>, <&adma 13>, + <&adma 14>, <&adma 14>, + <&adma 15>, <&adma 15>, + <&adma 16>, <&adma 16>, + <&adma 17>, <&adma 17>, + <&adma 18>, <&adma 18>, + <&adma 19>, <&adma 19>, + <&adma 20>, <&adma 20>, + <&adma 21>, <&adma 21>, + <&adma 22>, <&adma 22>, + <&adma 23>, <&adma 23>, + <&adma 24>, <&adma 24>, + <&adma 25>, <&adma 25>, + <&adma 26>, <&adma 26>, + <&adma 27>, <&adma 27>, + <&adma 28>, <&adma 28>, + <&adma 29>, <&adma 29>, + <&adma 30>, <&adma 30>, + <&adma 31>, <&adma 31>, + <&adma 32>, <&adma 32>; + dma-names = "rx1", "tx1", + "rx2", "tx2", + "rx3", "tx3", + "rx4", "tx4", + "rx5", "tx5", + "rx6", "tx6", + "rx7", "tx7", + "rx8", "tx8", + "rx9", "tx9", + "rx10", "tx10", + "rx11", "tx11", + "rx12", "tx12", + "rx13", "tx13", + "rx14", "tx14", + "rx15", "tx15", + "rx16", "tx16", + "rx17", "tx17", + "rx18", "tx18", + "rx19", "tx19", + "rx20", "tx20", + "rx21", "tx21", + "rx22", "tx22", + "rx23", "tx23", + "rx24", "tx24", + "rx25", "tx25", + "rx26", "tx26", + "rx27", "tx27", + "rx28", "tx28", + "rx29", "tx29", + "rx30", "tx30", + "rx31", "tx31", + "rx32", "tx32"; + + interconnects = + <&mc TEGRA264_MEMORY_CLIENT_APEDMAR &emc>, + <&mc TEGRA264_MEMORY_CLIENT_APEDMAW &emc>; + interconnect-names = "dma-mem", "write"; + + iommus = <&smmu1 TEGRA264_SID_APE>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + admaif0_port: port@0 { + reg = <0x0>; + + admaif0: endpoint { + remote-endpoint = <&xbar_admaif0>; + }; + }; + + admaif1_port: port@1 { + reg = <0x1>; + + admaif1: endpoint { + remote-endpoint = <&xbar_admaif1>; + }; + }; + + admaif2_port: port@2 { + reg = <0x2>; + + admaif2: endpoint { + remote-endpoint = <&xbar_admaif2>; + }; + }; + + admaif3_port: port@3 { + reg = <0x3>; + + admaif3: endpoint { + remote-endpoint = <&xbar_admaif3>; + }; + }; + + admaif4_port: port@4 { + reg = <0x4>; + + admaif4: endpoint { + remote-endpoint = <&xbar_admaif4>; + }; + }; + + admaif5_port: port@5 { + reg = <0x5>; + + admaif5: endpoint { + remote-endpoint = <&xbar_admaif5>; + }; + }; + + admaif6_port: port@6 { + reg = <0x6>; + + admaif6: endpoint { + remote-endpoint = <&xbar_admaif6>; + }; + }; + + admaif7_port: port@7 { + reg = <0x7>; + + admaif7: endpoint { + remote-endpoint = <&xbar_admaif7>; + }; + }; + + admaif8_port: port@8 { + reg = <0x8>; + + admaif8: endpoint { + remote-endpoint = <&xbar_admaif8>; + }; + }; + + admaif9_port: port@9 { + reg = <0x9>; + + admaif9: endpoint { + remote-endpoint = <&xbar_admaif9>; + }; + }; + + admaif10_port: port@a { + reg = <0xa>; + + admaif10: endpoint { + remote-endpoint = <&xbar_admaif10>; + }; + }; + + admaif11_port: port@b { + reg = <0xb>; + + admaif11: endpoint { + remote-endpoint = <&xbar_admaif11>; + }; + }; + + admaif12_port: port@c { + reg = <0xc>; + + admaif12: endpoint { + remote-endpoint = <&xbar_admaif12>; + }; + }; + + admaif13_port: port@d { + reg = <0xd>; + + admaif13: endpoint { + remote-endpoint = <&xbar_admaif13>; + }; + }; + + admaif14_port: port@e { + reg = <0xe>; + + admaif14: endpoint { + remote-endpoint = <&xbar_admaif14>; + }; + }; + + admaif15_port: port@f { + reg = <0xf>; + + admaif15: endpoint { + remote-endpoint = <&xbar_admaif15>; + }; + }; + + admaif16_port: port@10 { + reg = <0x10>; + + admaif16: endpoint { + remote-endpoint = <&xbar_admaif16>; + }; + }; + + admaif17_port: port@11 { + reg = <0x11>; + + admaif17: endpoint { + remote-endpoint = <&xbar_admaif17>; + }; + }; + + admaif18_port: port@12 { + reg = <0x12>; + + admaif18: endpoint { + remote-endpoint = <&xbar_admaif18>; + }; + }; + + admaif19_port: port@13 { + reg = <0x13>; + + admaif19: endpoint { + remote-endpoint = <&xbar_admaif19>; + }; + }; + + admaif20_port: port@14 { + reg = <0x14>; + + admaif20: endpoint { + remote-endpoint = <&xbar_admaif20>; + }; + }; + + admaif21_port: port@15 { + reg = <0x15>; + + admaif21: endpoint { + remote-endpoint = <&xbar_admaif21>; + }; + }; + + admaif22_port: port@16 { + reg = <0x16>; + + admaif22: endpoint { + remote-endpoint = <&xbar_admaif22>; + }; + }; + + admaif23_port: port@17 { + reg = <0x17>; + + admaif23: endpoint { + remote-endpoint = <&xbar_admaif23>; + }; + }; + + admaif24_port: port@18 { + reg = <0x18>; + + admaif24: endpoint { + remote-endpoint = <&xbar_admaif24>; + }; + }; + + admaif25_port: port@19 { + reg = <0x19>; + + admaif25: endpoint { + remote-endpoint = <&xbar_admaif25>; + }; + }; + + admaif26_port: port@1a { + reg = <0x1a>; + + admaif26: endpoint { + remote-endpoint = <&xbar_admaif26>; + }; + }; + + admaif27_port: port@1b { + reg = <0x1b>; + + admaif27: endpoint { + remote-endpoint = <&xbar_admaif27>; + }; + }; + + admaif28_port: port@1c { + reg = <0x1c>; + + admaif28: endpoint { + remote-endpoint = <&xbar_admaif28>; + }; + }; + + admaif29_port: port@1d { + reg = <0x1d>; + + admaif29: endpoint { + remote-endpoint = <&xbar_admaif29>; + }; + }; + + admaif30_port: port@1e { + reg = <0x1e>; + + admaif30: endpoint { + remote-endpoint = <&xbar_admaif30>; + }; + }; + + admaif31_port: port@1f { + reg = <0x1f>; + + admaif31: endpoint { + remote-endpoint = <&xbar_admaif31>; + }; + }; + }; + }; + + tegra_sfc1: sfc@9700000 { + compatible = "nvidia,tegra264-sfc", + "nvidia,tegra210-sfc"; + reg = <0x0 0x9700000 0x0 0x10000>; + sound-name-prefix = "SFC1"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + sfc1_cif_in: endpoint { + remote-endpoint = <&xbar_sfc1_in>; + }; + }; + + sfc1_out_port: port@1 { + reg = <1>; + + sfc1_cif_out: endpoint { + remote-endpoint = <&xbar_sfc1_out>; + }; + }; + }; + }; + + tegra_sfc2: sfc@9710000 { + compatible = "nvidia,tegra264-sfc", + "nvidia,tegra210-sfc"; + reg = <0x0 0x9710000 0x0 0x10000>; + sound-name-prefix = "SFC2"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + sfc2_cif_in: endpoint { + remote-endpoint = <&xbar_sfc2_in>; + }; + }; + + sfc2_out_port: port@1 { + reg = <1>; + + sfc2_cif_out: endpoint { + remote-endpoint = <&xbar_sfc2_out>; + }; + }; + }; + }; + + tegra_sfc3: sfc@9720000 { + compatible = "nvidia,tegra264-sfc", + "nvidia,tegra210-sfc"; + reg = <0x0 0x9720000 0x0 0x10000>; + sound-name-prefix = "SFC3"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + sfc3_cif_in: endpoint { + remote-endpoint = <&xbar_sfc3_in>; + }; + }; + + sfc3_out_port: port@1 { + reg = <1>; + + sfc3_cif_out: endpoint { + remote-endpoint = <&xbar_sfc3_out>; + }; + }; + }; + }; + + tegra_sfc4: sfc@9730000 { + compatible = "nvidia,tegra264-sfc", + "nvidia,tegra210-sfc"; + reg = <0x0 0x9730000 0x0 0x10000>; + sound-name-prefix = "SFC4"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + sfc4_cif_in: endpoint { + remote-endpoint = <&xbar_sfc4_in>; + }; + }; + + sfc4_out_port: port@1 { + reg = <1>; + + sfc4_cif_out: endpoint { + remote-endpoint = <&xbar_sfc4_out>; + }; + }; + }; + }; + + tegra_ope1: processing-engine@9780000 { + compatible = "nvidia,tegra264-ope", + "nvidia,tegra210-ope"; + reg = <0x0 0x9780000 0x0 0x10000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x9780000 0x0 0x9780000 0x0 0x30000>; + sound-name-prefix = "OPE1"; + + equalizer@9790000 { + compatible = "nvidia,tegra264-peq", + "nvidia,tegra210-peq"; + reg = <0x0 0x9790000 0x0 0x10000>; + }; + + dynamic-range-compressor@97a0000 { + compatible = "nvidia,tegra264-mbdrc", + "nvidia,tegra210-mbdrc"; + reg = <0x0 0x97a0000 0x0 0x10000>; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + + ope1_cif_in_ep: endpoint { + remote-endpoint = + <&xbar_ope1_in_ep>; + }; + }; + + ope1_out_port: port@1 { + reg = <0x1>; + + ope1_cif_out_ep: endpoint { + remote-endpoint = + <&xbar_ope1_out_ep>; + }; + }; + }; + }; + + tegra_mvc1: mvc@9800000 { + compatible = "nvidia,tegra264-mvc", + "nvidia,tegra210-mvc"; + reg = <0x0 0x9800000 0x0 0x10000>; + sound-name-prefix = "MVC1"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mvc1_cif_in: endpoint { + remote-endpoint = <&xbar_mvc1_in>; + }; + }; + + mvc1_out_port: port@1 { + reg = <1>; + + mvc1_cif_out: endpoint { + remote-endpoint = <&xbar_mvc1_out>; + }; + }; + }; + }; + + tegra_mvc2: mvc@9810000 { + compatible = "nvidia,tegra264-mvc", + "nvidia,tegra210-mvc"; + reg = <0x0 0x9810000 0x0 0x10000>; + sound-name-prefix = "MVC2"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mvc2_cif_in: endpoint { + remote-endpoint = <&xbar_mvc2_in>; + }; + }; + + mvc2_out_port: port@1 { + reg = <1>; + + mvc2_cif_out: endpoint { + remote-endpoint = <&xbar_mvc2_out>; + }; + }; + }; + }; + + tegra_amixer: amixer@9820000 { + compatible = "nvidia,tegra264-amixer", + "nvidia,tegra210-amixer"; + reg = <0x0 0x9820000 0x0 0x10000>; + sound-name-prefix = "MIXER1"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + + mix_in1: endpoint { + remote-endpoint = <&xbar_mix_in1>; + }; + }; + + port@1 { + reg = <0x1>; + + mix_in2: endpoint { + remote-endpoint = <&xbar_mix_in2>; + }; + }; + + port@2 { + reg = <0x2>; + + mix_in3: endpoint { + remote-endpoint = <&xbar_mix_in3>; + }; + }; + + port@3 { + reg = <0x3>; + + mix_in4: endpoint { + remote-endpoint = <&xbar_mix_in4>; + }; + }; + + port@4 { + reg = <0x4>; + + mix_in5: endpoint { + remote-endpoint = <&xbar_mix_in5>; + }; + }; + + port@5 { + reg = <0x5>; + + mix_in6: endpoint { + remote-endpoint = <&xbar_mix_in6>; + }; + }; + + port@6 { + reg = <0x6>; + + mix_in7: endpoint { + remote-endpoint = <&xbar_mix_in7>; + }; + }; + + port@7 { + reg = <0x7>; + + mix_in8: endpoint { + remote-endpoint = <&xbar_mix_in8>; + }; + }; + + port@8 { + reg = <0x8>; + + mix_in9: endpoint { + remote-endpoint = <&xbar_mix_in9>; + }; + }; + + port@9 { + reg = <0x9>; + + mix_in10: endpoint { + remote-endpoint = <&xbar_mix_in10>; + }; + }; + + mix_out1_port: port@a { + reg = <0xa>; + + mix_out1: endpoint { + remote-endpoint = <&xbar_mix_out1>; + }; + }; + + mix_out2_port: port@b { + reg = <0xb>; + + mix_out2: endpoint { + remote-endpoint = <&xbar_mix_out2>; + }; + }; + + mix_out3_port: port@c { + reg = <0xc>; + + mix_out3: endpoint { + remote-endpoint = <&xbar_mix_out3>; + }; + }; + + mix_out4_port: port@d { + reg = <0xd>; + + mix_out4: endpoint { + remote-endpoint = <&xbar_mix_out4>; + }; + }; + + mix_out5_port: port@e { + reg = <0xe>; + + mix_out5: endpoint { + remote-endpoint = <&xbar_mix_out5>; + }; + }; + }; + }; + + tegra_asrc: asrc@9850000 { + compatible = "nvidia,tegra264-asrc"; + reg = <0x0 0x9850000 0x0 0x10000>; + sound-name-prefix = "ASRC1"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + + asrc_in1_ep: endpoint { + remote-endpoint = + <&xbar_asrc_in1_ep>; + }; + }; + + port@1 { + reg = <0x1>; + + asrc_in2_ep: endpoint { + remote-endpoint = + <&xbar_asrc_in2_ep>; + }; + }; + + port@2 { + reg = <0x2>; + + asrc_in3_ep: endpoint { + remote-endpoint = + <&xbar_asrc_in3_ep>; + }; + }; + + port@3 { + reg = <0x3>; + + asrc_in4_ep: endpoint { + remote-endpoint = + <&xbar_asrc_in4_ep>; + }; + }; + + port@4 { + reg = <0x4>; + + asrc_in5_ep: endpoint { + remote-endpoint = + <&xbar_asrc_in5_ep>; + }; + }; + + port@5 { + reg = <0x5>; + + asrc_in6_ep: endpoint { + remote-endpoint = + <&xbar_asrc_in6_ep>; + }; + }; + + port@6 { + reg = <0x6>; + + asrc_in7_ep: endpoint { + remote-endpoint = + <&xbar_asrc_in7_ep>; + }; + }; + + asrc_out1_port: port@7 { + reg = <0x7>; + + asrc_out1_ep: endpoint { + remote-endpoint = + <&xbar_asrc_out1_ep>; + }; + }; + + asrc_out2_port: port@8 { + reg = <0x8>; + + asrc_out2_ep: endpoint { + remote-endpoint = + <&xbar_asrc_out2_ep>; + }; + }; + + asrc_out3_port: port@9 { + reg = <0x9>; + + asrc_out3_ep: endpoint { + remote-endpoint = + <&xbar_asrc_out3_ep>; + }; + }; + + asrc_out4_port: port@a { + reg = <0xa>; + + asrc_out4_ep: endpoint { + remote-endpoint = + <&xbar_asrc_out4_ep>; + }; + }; + + asrc_out5_port: port@b { + reg = <0xb>; + + asrc_out5_ep: endpoint { + remote-endpoint = + <&xbar_asrc_out5_ep>; + }; + }; + + asrc_out6_port: port@c { + reg = <0xc>; + + asrc_out6_ep: endpoint { + remote-endpoint = + <&xbar_asrc_out6_ep>; + }; + }; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + + xbar_admaif0: endpoint { + remote-endpoint = <&admaif0>; + }; + }; + + port@1 { + reg = <0x1>; + + xbar_admaif1: endpoint { + remote-endpoint = <&admaif1>; + }; + }; + + port@2 { + reg = <0x2>; + + xbar_admaif2: endpoint { + remote-endpoint = <&admaif2>; + }; + }; + + port@3 { + reg = <0x3>; + + xbar_admaif3: endpoint { + remote-endpoint = <&admaif3>; + }; + }; + + port@4 { + reg = <0x4>; + + xbar_admaif4: endpoint { + remote-endpoint = <&admaif4>; + }; + }; + + port@5 { + reg = <0x5>; + + xbar_admaif5: endpoint { + remote-endpoint = <&admaif5>; + }; + }; + + port@6 { + reg = <0x6>; + + xbar_admaif6: endpoint { + remote-endpoint = <&admaif6>; + }; + }; + + port@7 { + reg = <0x7>; + + xbar_admaif7: endpoint { + remote-endpoint = <&admaif7>; + }; + }; + + port@8 { + reg = <0x8>; + + xbar_admaif8: endpoint { + remote-endpoint = <&admaif8>; + }; + }; + + port@9 { + reg = <0x9>; + + xbar_admaif9: endpoint { + remote-endpoint = <&admaif9>; + }; + }; + + port@a { + reg = <0xa>; + + xbar_admaif10: endpoint { + remote-endpoint = <&admaif10>; + }; + }; + + port@b { + reg = <0xb>; + + xbar_admaif11: endpoint { + remote-endpoint = <&admaif11>; + }; + }; + + port@c { + reg = <0xc>; + + xbar_admaif12: endpoint { + remote-endpoint = <&admaif12>; + }; + }; + + port@d { + reg = <0xd>; + + xbar_admaif13: endpoint { + remote-endpoint = <&admaif13>; + }; + }; + + port@e { + reg = <0xe>; + + xbar_admaif14: endpoint { + remote-endpoint = <&admaif14>; + }; + }; + + port@f { + reg = <0xf>; + + xbar_admaif15: endpoint { + remote-endpoint = <&admaif15>; + }; + }; + + port@10 { + reg = <0x10>; + + xbar_admaif16: endpoint { + remote-endpoint = <&admaif16>; + }; + }; + + port@11 { + reg = <0x11>; + + xbar_admaif17: endpoint { + remote-endpoint = <&admaif17>; + }; + }; + + port@12 { + reg = <0x12>; + + xbar_admaif18: endpoint { + remote-endpoint = <&admaif18>; + }; + }; + + port@13 { + reg = <0x13>; + + xbar_admaif19: endpoint { + remote-endpoint = <&admaif19>; + }; + }; + + port@14 { + reg = <0x14>; + + xbar_admaif20: endpoint { + remote-endpoint = <&admaif20>; + }; + }; + + port@15 { + reg = <0x15>; + + xbar_admaif21: endpoint { + remote-endpoint = <&admaif21>; + }; + }; + + port@16 { + reg = <0x16>; + + xbar_admaif22: endpoint { + remote-endpoint = <&admaif22>; + }; + }; + + port@17 { + reg = <0x17>; + + xbar_admaif23: endpoint { + remote-endpoint = <&admaif23>; + }; + }; + + port@18 { + reg = <0x18>; + + xbar_admaif24: endpoint { + remote-endpoint = <&admaif24>; + }; + }; + + port@19 { + reg = <0x19>; + + xbar_admaif25: endpoint { + remote-endpoint = <&admaif25>; + }; + }; + + port@1a { + reg = <0x1a>; + + xbar_admaif26: endpoint { + remote-endpoint = <&admaif26>; + }; + }; + + port@1b { + reg = <0x1b>; + + xbar_admaif27: endpoint { + remote-endpoint = <&admaif27>; + }; + }; + + port@1c { + reg = <0x1c>; + + xbar_admaif28: endpoint { + remote-endpoint = <&admaif28>; + }; + }; + + port@1d { + reg = <0x1d>; + + xbar_admaif29: endpoint { + remote-endpoint = <&admaif29>; + }; + }; + + port@1e { + reg = <0x1e>; + + xbar_admaif30: endpoint { + remote-endpoint = <&admaif30>; + }; + }; + + port@1f { + reg = <0x1f>; + + xbar_admaif31: endpoint { + remote-endpoint = <&admaif31>; + }; + }; + + xbar_i2s1_port: port@20 { + reg = <0x20>; + + xbar_i2s1: endpoint { + remote-endpoint = <&i2s1_cif>; + }; + }; + + xbar_i2s2_port: port@21 { + reg = <0x21>; + + xbar_i2s2: endpoint { + remote-endpoint = <&i2s2_cif>; + }; + }; + + xbar_i2s3_port: port@22 { + reg = <0x22>; + + xbar_i2s3: endpoint { + remote-endpoint = <&i2s3_cif>; + }; + }; + + xbar_i2s4_port: port@23 { + reg = <0x23>; + + xbar_i2s4: endpoint { + remote-endpoint = <&i2s4_cif>; + }; + }; + + xbar_i2s5_port: port@24 { + reg = <0x24>; + + xbar_i2s5: endpoint { + remote-endpoint = <&i2s5_cif>; + }; + }; + + xbar_i2s6_port: port@25 { + reg = <0x25>; + + xbar_i2s6: endpoint { + remote-endpoint = <&i2s6_cif>; + }; + }; + + xbar_i2s7_port: port@26 { + reg = <0x26>; + + xbar_i2s7: endpoint { + remote-endpoint = <&i2s7_cif>; + }; + }; + + xbar_i2s8_port: port@27 { + reg = <0x27>; + + xbar_i2s8: endpoint { + remote-endpoint = <&i2s8_cif>; + }; + }; + + xbar_dmic1_port: port@28 { + reg = <0x28>; + + xbar_dmic1: endpoint { + remote-endpoint = <&dmic1_cif>; + }; + }; + + xbar_dmic2_port: port@29 { + reg = <0x29>; + + xbar_dmic2: endpoint { + remote-endpoint = <&dmic2_cif>; + }; + }; + + xbar_dspk1_port: port@2a { + reg = <0x2a>; + + xbar_dspk1: endpoint { + remote-endpoint = <&dspk1_cif>; + }; + }; + + xbar_sfc1_in_port: port@2b { + reg = <0x2b>; + + xbar_sfc1_in: endpoint { + remote-endpoint = <&sfc1_cif_in>; + }; + }; + + port@2c { + reg = <0x2c>; + + xbar_sfc1_out: endpoint { + remote-endpoint = <&sfc1_cif_out>; + }; + }; + + xbar_sfc2_in_port: port@2d { + reg = <0x2d>; + + xbar_sfc2_in: endpoint { + remote-endpoint = <&sfc2_cif_in>; + }; + }; + + port@2e { + reg = <0x2e>; + + xbar_sfc2_out: endpoint { + remote-endpoint = <&sfc2_cif_out>; + }; + }; + + xbar_sfc3_in_port: port@2f { + reg = <0x2f>; + + xbar_sfc3_in: endpoint { + remote-endpoint = <&sfc3_cif_in>; + }; + }; + + port@30 { + reg = <0x30>; + + xbar_sfc3_out: endpoint { + remote-endpoint = <&sfc3_cif_out>; + }; + }; + + xbar_sfc4_in_port: port@31 { + reg = <0x31>; + + xbar_sfc4_in: endpoint { + remote-endpoint = <&sfc4_cif_in>; + }; + }; + + port@32 { + reg = <0x32>; + + xbar_sfc4_out: endpoint { + remote-endpoint = <&sfc4_cif_out>; + }; + }; + + xbar_mvc1_in_port: port@33 { + reg = <0x33>; + + xbar_mvc1_in: endpoint { + remote-endpoint = <&mvc1_cif_in>; + }; + }; + + port@34 { + reg = <0x34>; + + xbar_mvc1_out: endpoint { + remote-endpoint = <&mvc1_cif_out>; + }; + }; + + xbar_mvc2_in_port: port@35 { + reg = <0x35>; + + xbar_mvc2_in: endpoint { + remote-endpoint = <&mvc2_cif_in>; + }; + }; + + port@36 { + reg = <0x36>; + + xbar_mvc2_out: endpoint { + remote-endpoint = <&mvc2_cif_out>; + }; + }; + + xbar_amx1_in1_port: port@37 { + reg = <0x37>; + + xbar_amx1_in1: endpoint { + remote-endpoint = <&amx1_in1>; + }; + }; + + xbar_amx1_in2_port: port@38 { + reg = <0x38>; + + xbar_amx1_in2: endpoint { + remote-endpoint = <&amx1_in2>; + }; + }; + + xbar_amx1_in3_port: port@39 { + reg = <0x39>; + + xbar_amx1_in3: endpoint { + remote-endpoint = <&amx1_in3>; + }; + }; + + xbar_amx1_in4_port: port@3a { + reg = <0x3a>; + + xbar_amx1_in4: endpoint { + remote-endpoint = <&amx1_in4>; + }; + }; + + port@3b { + reg = <0x3b>; + + xbar_amx1_out: endpoint { + remote-endpoint = <&amx1_out>; + }; + }; + + xbar_amx2_in1_port: port@3c { + reg = <0x3c>; + + xbar_amx2_in1: endpoint { + remote-endpoint = <&amx2_in1>; + }; + }; + + xbar_amx2_in2_port: port@3d { + reg = <0x3d>; + + xbar_amx2_in2: endpoint { + remote-endpoint = <&amx2_in2>; + }; + }; + + xbar_amx2_in3_port: port@3e { + reg = <0x3e>; + + xbar_amx2_in3: endpoint { + remote-endpoint = <&amx2_in3>; + }; + }; + + xbar_amx2_in4_port: port@3f { + reg = <0x3f>; + + xbar_amx2_in4: endpoint { + remote-endpoint = <&amx2_in4>; + }; + }; + + port@40 { + reg = <0x40>; + + xbar_amx2_out: endpoint { + remote-endpoint = <&amx2_out>; + }; + }; + + xbar_amx3_in1_port: port@41 { + reg = <0x41>; + + xbar_amx3_in1: endpoint { + remote-endpoint = <&amx3_in1>; + }; + }; + + xbar_amx3_in2_port: port@42 { + reg = <0x42>; + + xbar_amx3_in2: endpoint { + remote-endpoint = <&amx3_in2>; + }; + }; + + xbar_amx3_in3_port: port@43 { + reg = <0x43>; + + xbar_amx3_in3: endpoint { + remote-endpoint = <&amx3_in3>; + }; + }; + + xbar_amx3_in4_port: port@44 { + reg = <0x44>; + + xbar_amx3_in4: endpoint { + remote-endpoint = <&amx3_in4>; + }; + }; + + port@45 { + reg = <0x45>; + + xbar_amx3_out: endpoint { + remote-endpoint = <&amx3_out>; + }; + }; + + xbar_amx4_in1_port: port@46 { + reg = <0x46>; + + xbar_amx4_in1: endpoint { + remote-endpoint = <&amx4_in1>; + }; + }; + + xbar_amx4_in2_port: port@47 { + reg = <0x47>; + + xbar_amx4_in2: endpoint { + remote-endpoint = <&amx4_in2>; + }; + }; + + xbar_amx4_in3_port: port@48 { + reg = <0x48>; + + xbar_amx4_in3: endpoint { + remote-endpoint = <&amx4_in3>; + }; + }; + + xbar_amx4_in4_port: port@49 { + reg = <0x49>; + + xbar_amx4_in4: endpoint { + remote-endpoint = <&amx4_in4>; + }; + }; + + port@4a { + reg = <0x4a>; + + xbar_amx4_out: endpoint { + remote-endpoint = <&amx4_out>; + }; + }; + + xbar_amx5_in1_port: port@4b { + reg = <0x4b>; + + xbar_amx5_in1: endpoint { + remote-endpoint = <&amx5_in1>; + }; + }; + + xbar_amx5_in2_port: port@4c { + reg = <0x4c>; + + xbar_amx5_in2: endpoint { + remote-endpoint = <&amx5_in2>; + }; + }; + + xbar_amx5_in3_port: port@4d { + reg = <0x4d>; + + xbar_amx5_in3: endpoint { + remote-endpoint = <&amx5_in3>; + }; + }; + + xbar_amx5_in4_port: port@4e { + reg = <0x4e>; + + xbar_amx5_in4: endpoint { + remote-endpoint = <&amx5_in4>; + }; + }; + + port@4f { + reg = <0x4f>; + + xbar_amx5_out: endpoint { + remote-endpoint = <&amx5_out>; + }; + }; + + xbar_amx6_in1_port: port@50 { + reg = <0x50>; + + xbar_amx6_in1: endpoint { + remote-endpoint = <&amx6_in1>; + }; + }; + + xbar_amx6_in2_port: port@51 { + reg = <0x51>; + + xbar_amx6_in2: endpoint { + remote-endpoint = <&amx6_in2>; + }; + }; + + xbar_amx6_in3_port: port@52 { + reg = <0x52>; + + xbar_amx6_in3: endpoint { + remote-endpoint = <&amx6_in3>; + }; + }; + + xbar_amx6_in4_port: port@53 { + reg = <0x53>; + + xbar_amx6_in4: endpoint { + remote-endpoint = <&amx6_in4>; + }; + }; + + port@54 { + reg = <0x54>; + + xbar_amx6_out: endpoint { + remote-endpoint = <&amx6_out>; + }; + }; + + xbar_adx1_in_port: port@55 { + reg = <0x55>; + + xbar_adx1_in: endpoint { + remote-endpoint = <&adx1_in>; + }; + }; + + port@56 { + reg = <0x56>; + + xbar_adx1_out1: endpoint { + remote-endpoint = <&adx1_out1>; + }; + }; + + port@57 { + reg = <0x57>; + + xbar_adx1_out2: endpoint { + remote-endpoint = <&adx1_out2>; + }; + }; + + port@58 { + reg = <0x58>; + + xbar_adx1_out3: endpoint { + remote-endpoint = <&adx1_out3>; + }; + }; + + port@59 { + reg = <0x59>; + + xbar_adx1_out4: endpoint { + remote-endpoint = <&adx1_out4>; + }; + }; + + xbar_adx2_in_port: port@5a { + reg = <0x5a>; + + xbar_adx2_in: endpoint { + remote-endpoint = <&adx2_in>; + }; + }; + + port@5b { + reg = <0x5b>; + + xbar_adx2_out1: endpoint { + remote-endpoint = <&adx2_out1>; + }; + }; + + port@5c { + reg = <0x5c>; + + xbar_adx2_out2: endpoint { + remote-endpoint = <&adx2_out2>; + }; + }; + + port@5d { + reg = <0x5d>; + + xbar_adx2_out3: endpoint { + remote-endpoint = <&adx2_out3>; + }; + }; + + port@5e { + reg = <0x5e>; + + xbar_adx2_out4: endpoint { + remote-endpoint = <&adx2_out4>; + }; + }; + + xbar_adx3_in_port: port@5f { + reg = <0x5f>; + + xbar_adx3_in: endpoint { + remote-endpoint = <&adx3_in>; + }; + }; + + port@60 { + reg = <0x60>; + + xbar_adx3_out1: endpoint { + remote-endpoint = <&adx3_out1>; + }; + }; + + port@61 { + reg = <0x61>; + + xbar_adx3_out2: endpoint { + remote-endpoint = <&adx3_out2>; + }; + }; + + port@62 { + reg = <0x62>; + + xbar_adx3_out3: endpoint { + remote-endpoint = <&adx3_out3>; + }; + }; + + port@63 { + reg = <0x63>; + + xbar_adx3_out4: endpoint { + remote-endpoint = <&adx3_out4>; + }; + }; + + xbar_adx4_in_port: port@64 { + reg = <0x64>; + + xbar_adx4_in: endpoint { + remote-endpoint = <&adx4_in>; + }; + }; + + port@65 { + reg = <0x65>; + + xbar_adx4_out1: endpoint { + remote-endpoint = <&adx4_out1>; + }; + }; + + port@66 { + reg = <0x66>; + + xbar_adx4_out2: endpoint { + remote-endpoint = <&adx4_out2>; + }; + }; + + port@67 { + reg = <0x67>; + + xbar_adx4_out3: endpoint { + remote-endpoint = <&adx4_out3>; + }; + }; + + port@68 { + reg = <0x68>; + + xbar_adx4_out4: endpoint { + remote-endpoint = <&adx4_out4>; + }; + }; + + xbar_adx5_in_port: port@69 { + reg = <0x69>; + + xbar_adx5_in: endpoint { + remote-endpoint = <&adx5_in>; + }; + }; + + port@6a { + reg = <0x6a>; + + xbar_adx5_out1: endpoint { + remote-endpoint = <&adx5_out1>; + }; + }; + + port@6b { + reg = <0x6b>; + + xbar_adx5_out2: endpoint { + remote-endpoint = <&adx5_out2>; + }; + }; + + port@6c { + reg = <0x6c>; + + xbar_adx5_out3: endpoint { + remote-endpoint = <&adx5_out3>; + }; + }; + + port@6d { + reg = <0x6d>; + + xbar_adx5_out4: endpoint { + remote-endpoint = <&adx5_out4>; + }; + }; + + xbar_adx6_in_port: port@6e { + reg = <0x6e>; + + xbar_adx6_in: endpoint { + remote-endpoint = <&adx6_in>; + }; + }; + + port@6f { + reg = <0x6f>; + + xbar_adx6_out1: endpoint { + remote-endpoint = <&adx6_out1>; + }; + }; + + port@70 { + reg = <0x70>; + + xbar_adx6_out2: endpoint { + remote-endpoint = <&adx6_out2>; + }; + }; + + port@71 { + reg = <0x71>; + + xbar_adx6_out3: endpoint { + remote-endpoint = <&adx6_out3>; + }; + }; + + port@72 { + reg = <0x72>; + + xbar_adx6_out4: endpoint { + remote-endpoint = <&adx6_out4>; + }; + }; + + xbar_mix_in1_port: port@73 { + reg = <0x73>; + + xbar_mix_in1: endpoint { + remote-endpoint = <&mix_in1>; + }; + }; + + xbar_mix_in2_port: port@74 { + reg = <0x74>; + + xbar_mix_in2: endpoint { + remote-endpoint = <&mix_in2>; + }; + }; + + xbar_mix_in3_port: port@75 { + reg = <0x75>; + + xbar_mix_in3: endpoint { + remote-endpoint = <&mix_in3>; + }; + }; + + xbar_mix_in4_port: port@76 { + reg = <0x76>; + + xbar_mix_in4: endpoint { + remote-endpoint = <&mix_in4>; + }; + }; + + xbar_mix_in5_port: port@77 { + reg = <0x77>; + + xbar_mix_in5: endpoint { + remote-endpoint = <&mix_in5>; + }; + }; + + xbar_mix_in6_port: port@78 { + reg = <0x78>; + + xbar_mix_in6: endpoint { + remote-endpoint = <&mix_in6>; + }; + }; + + xbar_mix_in7_port: port@79 { + reg = <0x79>; + + xbar_mix_in7: endpoint { + remote-endpoint = <&mix_in7>; + }; + }; + + xbar_mix_in8_port: port@7a { + reg = <0x7a>; + + xbar_mix_in8: endpoint { + remote-endpoint = <&mix_in8>; + }; + }; + + xbar_mix_in9_port: port@7b { + reg = <0x7b>; + + xbar_mix_in9: endpoint { + remote-endpoint = <&mix_in9>; + }; + }; + + xbar_mix_in10_port: port@7c { + reg = <0x7c>; + + xbar_mix_in10: endpoint { + remote-endpoint = <&mix_in10>; + }; + }; + + port@7d { + reg = <0x7d>; + + xbar_mix_out1: endpoint { + remote-endpoint = <&mix_out1>; + }; + }; + + port@7e { + reg = <0x7e>; + + xbar_mix_out2: endpoint { + remote-endpoint = <&mix_out2>; + }; + }; + + port@7f { + reg = <0x7f>; + + xbar_mix_out3: endpoint { + remote-endpoint = <&mix_out3>; + }; + }; + + port@80 { + reg = <0x80>; + + xbar_mix_out4: endpoint { + remote-endpoint = <&mix_out4>; + }; + }; + + port@81 { + reg = <0x81>; + + xbar_mix_out5: endpoint { + remote-endpoint = <&mix_out5>; + }; + }; + + xbar_asrc_in1_port: port@82 { + reg = <0x82>; + + xbar_asrc_in1_ep: endpoint { + remote-endpoint = <&asrc_in1_ep>; + }; + }; + + port@83 { + reg = <0x83>; + + xbar_asrc_out1_ep: endpoint { + remote-endpoint = <&asrc_out1_ep>; + }; + }; + + xbar_asrc_in2_port: port@84 { + reg = <0x84>; + + xbar_asrc_in2_ep: endpoint { + remote-endpoint = <&asrc_in2_ep>; + }; + }; + + port@85 { + reg = <0x85>; + + xbar_asrc_out2_ep: endpoint { + remote-endpoint = <&asrc_out2_ep>; + }; + }; + + xbar_asrc_in3_port: port@86 { + reg = <0x86>; + + xbar_asrc_in3_ep: endpoint { + remote-endpoint = <&asrc_in3_ep>; + }; + }; + + port@87 { + reg = <0x87>; + + xbar_asrc_out3_ep: endpoint { + remote-endpoint = <&asrc_out3_ep>; + }; + }; + + xbar_asrc_in4_port: port@88 { + reg = <0x88>; + + xbar_asrc_in4_ep: endpoint { + remote-endpoint = <&asrc_in4_ep>; + }; + }; + + port@89 { + reg = <0x89>; + + xbar_asrc_out4_ep: endpoint { + remote-endpoint = <&asrc_out4_ep>; + }; + }; + + xbar_asrc_in5_port: port@8a { + reg = <0x8a>; + + xbar_asrc_in5_ep: endpoint { + remote-endpoint = <&asrc_in5_ep>; + }; + }; + + port@8b { + reg = <0x8b>; + + xbar_asrc_out5_ep: endpoint { + remote-endpoint = <&asrc_out5_ep>; + }; + }; + + xbar_asrc_in6_port: port@8c { + reg = <0x8c>; + + xbar_asrc_in6_ep: endpoint { + remote-endpoint = <&asrc_in6_ep>; + }; + }; + + port@8d { + reg = <0x8d>; + + xbar_asrc_out6_ep: endpoint { + remote-endpoint = <&asrc_out6_ep>; + }; + }; + + xbar_asrc_in7_port: port@8e { + reg = <0x8e>; + + xbar_asrc_in7_ep: endpoint { + remote-endpoint = <&asrc_in7_ep>; + }; + }; + + xbar_ope1_in_port: port@8f { + reg = <0x8f>; + + xbar_ope1_in_ep: endpoint { + remote-endpoint = <&ope1_cif_in_ep>; + }; + }; + + port@90 { + reg = <0x90>; + + xbar_ope1_out_ep: endpoint { + remote-endpoint = <&ope1_cif_out_ep>; + }; + }; + }; + }; + + agic_page0: interrupt-controller@9960000 { + compatible = "nvidia,tegra264-agic", + "nvidia,tegra210-agic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x0 0x9961000 0x0 0x1000>, + <0x0 0x9962000 0x0 0x1000>; + interrupts = ; + clocks = <&bpmp TEGRA264_CLK_ADSP>; + clock-names = "clk"; + status = "disabled"; + }; + + agic_page1: interrupt-controller@9970000 { + compatible = "nvidia,tegra264-agic", + "nvidia,tegra210-agic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x0 0x9971000 0x0 0x1000>, + <0x0 0x9972000 0x0 0x1000>; + interrupts = ; + clocks = <&bpmp TEGRA264_CLK_ADSP>; + clock-names = "clk"; + status = "disabled"; + }; + + agic_page2: interrupt-controller@9980000 { + compatible = "nvidia,tegra264-agic", + "nvidia,tegra210-agic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x0 0x9981000 0x0 0x1000>, + <0x0 0x9982000 0x0 0x1000>; + interrupts = ; + clocks = <&bpmp TEGRA264_CLK_ADSP>; + clock-names = "clk"; + status = "disabled"; + }; + + agic_page3: interrupt-controller@9990000 { + compatible = "nvidia,tegra264-agic", + "nvidia,tegra210-agic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x0 0x9991000 0x0 0x1000>, + <0x0 0x9992000 0x0 0x1000>; + interrupts = ; + clocks = <&bpmp TEGRA264_CLK_ADSP>; + clock-names = "clk"; + status = "disabled"; + }; + + agic_page4: interrupt-controller@99a0000 { + compatible = "nvidia,tegra264-agic", + "nvidia,tegra210-agic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x0 0x99a1000 0x0 0x1000>, + <0x0 0x99a2000 0x0 0x1000>; + interrupts = ; + clocks = <&bpmp TEGRA264_CLK_ADSP>; + clock-names = "clk"; + status = "disabled"; + }; + + agic_page5: interrupt-controller@99b0000 { + compatible = "nvidia,tegra264-agic", + "nvidia,tegra210-agic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x0 0x99b1000 0x0 0x1000>, + <0x0 0x99b2000 0x0 0x1000>; + interrupts = ; + clocks = <&bpmp TEGRA264_CLK_ADSP>; + clock-names = "clk"; + status = "disabled"; + }; + }; + gpcdma: dma-controller@8400000 { compatible = "nvidia,tegra264-gpcdma", "nvidia,tegra186-gpcdma"; reg = <0x0 0x08400000 0x0 0x210000>; @@ -542,6 +3700,22 @@ #iommu-cells = <1>; dma-coherent; }; + + hda@90b0000 { + compatible = "nvidia,tegra264-hda"; + reg = <0x0 0x90b0000 0x0 0x10000>; + interrupts = ; + clocks = <&bpmp TEGRA264_CLK_AZA_2XBIT>; + clock-names = "hda"; + resets = <&bpmp TEGRA264_RESET_HDA>, + <&bpmp TEGRA264_RESET_HDACODEC>; + reset-names = "hda", "hda2codec_2x"; + interconnects = <&mc TEGRA264_MEMORY_CLIENT_HDAR &emc>, + <&mc TEGRA264_MEMORY_CLIENT_HDAW &emc>; + interconnect-names = "dma-mem", "write"; + iommus = <&smmu3 TEGRA264_SID_HDA>; + status = "disabled"; + }; }; /* UPHY MMIO */ @@ -625,6 +3799,22 @@ method = "smc"; }; + sound { + compatible = "nvidia,tegra264-audio-graph-card"; + + clocks = <&bpmp TEGRA264_CLK_PLLA1>, + <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + clock-names = "pll_a", "plla_out0"; + assigned-clocks = <&bpmp TEGRA264_CLK_PLLA1>, + <&bpmp TEGRA264_CLK_PLLA1_OUT1>, + <&bpmp TEGRA264_CLK_AUD_MCLK>; + assigned-clock-parents = <0>, + <&bpmp TEGRA264_CLK_PLLA1>, + <&bpmp TEGRA264_CLK_PLLA1_OUT1>; + + status = "disabled"; + }; + timer { compatible = "arm,armv8-timer"; interrupts = , diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 296688f7cb265..6f34d5ed331c4 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -33,8 +33,10 @@ dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp454.dtb dtb-$(CONFIG_ARCH_QCOM) += lemans-evk.dtb lemans-evk-camera-csi1-imx577-dtbs := lemans-evk.dtb lemans-evk-camera-csi1-imx577.dtbo +lemans-evk-camera-dtbs := lemans-evk.dtb lemans-evk-camera.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera-csi1-imx577.dtb +dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera.dtb dtb-$(CONFIG_ARCH_QCOM) += monaco-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8216-samsung-fortuna3g.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-acer-a1-724.dtb @@ -72,6 +74,8 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8916-wingtech-wt88047.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-yiming-uz801v3.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8917-xiaomi-riva.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8929-wingtech-wt82918hd.dtb +dtb-$(CONFIG_ARCH_QCOM) += msm8937-xiaomi-land.dtb +dtb-$(CONFIG_ARCH_QCOM) += msm8939-asus-z00t.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8939-huawei-kiwi.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8939-longcheer-l9100.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8939-samsung-a7.dtb @@ -126,6 +130,7 @@ dtb-$(CONFIG_ARCH_QCOM) += qcm6490-shift-otter.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs615-ride.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs6490-radxa-dragon-q6a.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2.dtb qcs6490-rb3gen2-vision-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-vision-mezzanine.dtbo @@ -258,6 +263,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm845-xiaomi-beryllium-ebbg.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm845-xiaomi-beryllium-tianma.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm845-xiaomi-polaris.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm845-shift-axolotl.dtb +dtb-$(CONFIG_ARCH_QCOM) += sdm850-huawei-matebook-e-2019.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm850-lenovo-yoga-c630.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm850-samsung-w737.dtb dtb-$(CONFIG_ARCH_QCOM) += sdx75-idp.dtb @@ -298,6 +304,10 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8450-qrd.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8450-samsung-r0q.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8450-sony-xperia-nagara-pdx223.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8450-sony-xperia-nagara-pdx224.dtb + +sm8550-hdk-rear-camera-card-dtbs := sm8550-hdk.dtb sm8550-hdk-rear-camera-card.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += sm8550-hdk-rear-camera-card.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8550-hdk.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8550-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8550-qrd.dtb @@ -344,6 +354,8 @@ x1e80100-qcp-el2-dtbs := x1e80100-qcp.dtb x1-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += x1e80100-qcp.dtb x1e80100-qcp-el2.dtb x1p42100-asus-zenbook-a14-el2-dtbs := x1p42100-asus-zenbook-a14.dtb x1-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += x1p42100-asus-zenbook-a14.dtb x1p42100-asus-zenbook-a14-el2.dtb +x1p42100-asus-zenbook-a14-lcd-el2-dtbs := x1p42100-asus-zenbook-a14-lcd.dtb x1-el2.dtbo +dtb-$(CONFIG_ARCH_QCOM) += x1p42100-asus-zenbook-a14-lcd.dtb x1p42100-asus-zenbook-a14-lcd-el2.dtb x1p42100-crd-el2-dtbs := x1p42100-crd.dtb x1-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += x1p42100-crd.dtb x1p42100-crd-el2.dtb x1p42100-hp-omnibook-x14-el2-dtbs := x1p42100-hp-omnibook-x14.dtb x1-el2.dtbo diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/agatti.dtsi similarity index 93% rename from arch/arm64/boot/dts/qcom/qcm2290.dtsi rename to arch/arm64/boot/dts/qcom/agatti.dtsi index 08141b41de246..8bf5c5583fc22 100644 --- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi @@ -17,6 +17,9 @@ #include #include #include +#include +#include +#include / { interrupt-parent = <&intc>; @@ -552,6 +555,13 @@ bias-disable; }; + qup_uart1_default: qup-uart1-default-state { + pins = "gpio4", "gpio5", "gpio69", "gpio70"; + function = "qup1"; + drive-strength = <2>; + bias-disable; + }; + qup_uart3_default: qup-uart3-default-state { pins = "gpio8", "gpio9", "gpio10", "gpio11"; function = "qup3"; @@ -566,6 +576,13 @@ bias-disable; }; + qup_uart5_default: qup-uart5-default-state { + pins = "gpio14", "gpio15", "gpio16", "gpio17"; + function = "qup5"; + drive-strength = <2>; + bias-disable; + }; + cci0_default: cci0-default-state { pins = "gpio22", "gpio23"; function = "cci_i2c"; @@ -671,6 +688,43 @@ }; }; + lpass_tlmm: pinctrl@a7c0000 { + compatible = "qcom,qcm2290-lpass-lpi-pinctrl", + "qcom,sm6115-lpass-lpi-pinctrl"; + reg = <0x0 0x0a7c0000 0x0 0x20000>, + <0x0 0x0a950000 0x0 0x10000>; + + clocks = <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "audio"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&lpass_tlmm 0 0 19>; + + lpi_i2s2_active: lpi-i2s2-active-state { + sck-pins { + pins = "gpio10"; + function = "i2s2_clk"; + bias-disable; + drive-strength = <8>; + }; + + ws-pins { + pins = "gpio11"; + function = "i2s2_ws"; + bias-disable; + drive-strength = <8>; + }; + + data-pins { + pins = "gpio12"; + function = "i2s2_data"; + bias-disable; + drive-strength = <8>; + }; + }; + }; + gcc: clock-controller@1400000 { compatible = "qcom,gcc-qcm2290"; reg = <0x0 0x01400000 0x0 0x1f0000>; @@ -1197,6 +1251,23 @@ status = "disabled"; }; + uart1: serial@4a84000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x04a84000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>; + clock-names = "se"; + pinctrl-0 = <&qup_uart1_default>; + pinctrl-names = "default"; + interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG + &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>, + <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG + &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>; + interconnect-names = "qup-core", + "qup-config"; + status = "disabled"; + }; + i2c2: i2c@4a88000 { compatible = "qcom,geni-i2c"; reg = <0x0 0x04a88000 0x0 0x4000>; @@ -1302,7 +1373,7 @@ interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>, <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG - &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>; + &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; @@ -1418,6 +1489,23 @@ #size-cells = <0>; status = "disabled"; }; + + uart5: serial@4a94000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x04a94000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>; + clock-names = "se"; + pinctrl-0 = <&qup_uart5_default>; + pinctrl-names = "default"; + interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG + &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>, + <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG + &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>; + interconnect-names = "qup-core", + "qup-config"; + status = "disabled"; + }; }; usb: usb@4ef8800 { @@ -1537,7 +1625,7 @@ status = "disabled"; - zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&pil_gpu_mem>; }; @@ -1685,25 +1773,25 @@ }; }; - camss: camss@5c6e000 { + camss: camss@5c11000 { compatible = "qcom,qcm2290-camss"; - reg = <0x0 0x5c6e000 0x0 0x1000>, + reg = <0x0 0x5c11000 0x0 0x1000>, + <0x0 0x5c6e000 0x0 0x1000>, <0x0 0x5c75000 0x0 0x1000>, <0x0 0x5c52000 0x0 0x1000>, <0x0 0x5c53000 0x0 0x1000>, <0x0 0x5c66000 0x0 0x400>, <0x0 0x5c68000 0x0 0x400>, - <0x0 0x5c11000 0x0 0x1000>, <0x0 0x5c6f000 0x0 0x4000>, <0x0 0x5c76000 0x0 0x4000>; - reg-names = "csid0", + reg-names = "top", + "csid0", "csid1", "csiphy0", "csiphy1", "csitpg0", "csitpg1", - "top", "vfe0", "vfe1"; @@ -2077,6 +2165,76 @@ label = "lpass"; qcom,remote-pid = <2>; mboxes = <&apcs_glb 8>; + + apr { + compatible = "qcom,apr-v2"; + qcom,glink-channels = "apr_audio_svc"; + qcom,domain = ; + #address-cells = <1>; + #size-cells = <0>; + + service@3 { + reg = ; + compatible = "qcom,q6core"; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + }; + + q6afe: service@4 { + compatible = "qcom,q6afe"; + reg = ; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + q6afedai: dais { + compatible = "qcom,q6afe-dais"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <1>; + }; + + q6afecc: clock-controller { + compatible = "qcom,q6afe-clocks"; + #clock-cells = <2>; + }; + }; + + q6asm: service@7 { + compatible = "qcom,q6asm"; + reg = ; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + q6asmdai: dais { + compatible = "qcom,q6asm-dais"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <1>; + iommus = <&apps_smmu 0x1c1 0x0>; + + dai@0 { + reg = ; + }; + + dai@1 { + reg = ; + }; + + dai@2 { + reg = ; + }; + }; + }; + + q6adm: service@8 { + compatible = "qcom,q6adm"; + reg = ; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + q6routing: routing { + compatible = "qcom,q6adm-routing"; + #sound-dai-cells = <0>; + }; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts index 5b2e88915c2fd..9fa70ff6887b7 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts @@ -203,6 +203,10 @@ status = "okay"; }; +&gpu_zap_shader { + firmware-name = "qcom/apq8096/a530_zap.mbn"; +}; + &hsusb_phy1 { status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index df8d6e5c1f45e..36dd6599402b4 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -743,20 +743,32 @@ }; &lpass_tlmm { - spkr_01_sd_n_active: spkr-01-sd-n-active-state { + spkr_0_sd_n_active: spkr-0-sd-n-active-state { pins = "gpio12"; function = "gpio"; drive-strength = <16>; bias-disable; - output-low; }; - spkr_23_sd_n_active: spkr-23-sd-n-active-state { + spkr_1_sd_n_active: spkr-1-sd-n-active-state { pins = "gpio13"; function = "gpio"; drive-strength = <16>; bias-disable; - output-low; + }; + + spkr_2_sd_n_active: spkr-2-sd-n-active-state { + pins = "gpio17"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + spkr_3_sd_n_active: spkr-3-sd-n-active-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <16>; + bias-disable; }; }; @@ -908,12 +920,14 @@ &swr0 { status = "okay"; - pinctrl-0 = <&wsa_swr_active>, <&spkr_01_sd_n_active>; + pinctrl-0 = <&wsa_swr_active>; pinctrl-names = "default"; /* WSA8845, Left Woofer */ left_woofer: speaker@0,0 { compatible = "sdw20217020400"; + pinctrl-0 = <&spkr_0_sd_n_active>; + pinctrl-names = "default"; reg = <0 0>; reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; #sound-dai-cells = <0>; @@ -926,8 +940,10 @@ /* WSA8845, Left Tweeter */ left_tweeter: speaker@0,1 { compatible = "sdw20217020400"; + pinctrl-0 = <&spkr_1_sd_n_active>; + pinctrl-names = "default"; reg = <0 1>; - reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; #sound-dai-cells = <0>; sound-name-prefix = "TweeterLeft"; vdd-1p8-supply = <&vreg_l15b_1p8>; @@ -961,14 +977,16 @@ &swr3 { status = "okay"; - pinctrl-0 = <&wsa2_swr_active>, <&spkr_23_sd_n_active>; + pinctrl-0 = <&wsa2_swr_active>; pinctrl-names = "default"; /* WSA8845, Right Woofer */ right_woofer: speaker@0,0 { compatible = "sdw20217020400"; + pinctrl-0 = <&spkr_2_sd_n_active>; + pinctrl-names = "default"; reg = <0 0>; - reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + reset-gpios = <&lpass_tlmm 17 GPIO_ACTIVE_LOW>; #sound-dai-cells = <0>; sound-name-prefix = "WooferRight"; vdd-1p8-supply = <&vreg_l15b_1p8>; @@ -979,8 +997,10 @@ /* WSA8845, Right Tweeter */ right_tweeter: speaker@0,1 { compatible = "sdw20217020400"; + pinctrl-0 = <&spkr_3_sd_n_active>; + pinctrl-names = "default"; reg = <0 1>; - reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + reset-gpios = <&lpass_tlmm 18 GPIO_ACTIVE_LOW>; #sound-dai-cells = <0>; sound-name-prefix = "TweeterRight"; vdd-1p8-supply = <&vreg_l15b_1p8>; diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi b/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi index 1aead50b8920b..4a69852e91760 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi @@ -3,8 +3,8 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "x1e80100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "hamoa.dtsi" +#include "hamoa-pmics.dtsi" #include #include @@ -451,8 +451,7 @@ }; &tlmm { - gpio-reserved-ranges = <34 2>, /* TPM LP & INT */ - <44 4>; /* SPI (TPM) */ + gpio-reserved-ranges = <34 2>; /* TPM LP & INT */ pcie4_default: pcie4-default-state { clkreq-n-pins { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-pmics.dtsi b/arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi similarity index 96% rename from arch/arm64/boot/dts/qcom/x1e80100-pmics.dtsi rename to arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi index 621890ada1536..6a31a0adf8be4 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-pmics.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi @@ -240,6 +240,26 @@ }; }; + pmk8550_sdam_15: nvram@7e00 { + compatible = "qcom,spmi-sdam"; + reg = <0x7e00>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x7e00 0x100>; + + charge_limit_en: charge-limit-en@73 { + reg = <0x73 0x1>; + }; + + charge_limit_end: charge-limit-end@75 { + reg = <0x75 0x1>; + }; + + charge_limit_delta: charge-limit-delta@76 { + reg = <0x76 0x1>; + }; + }; + pmk8550_gpios: gpio@8800 { compatible = "qcom,pmk8550-gpio", "qcom,spmi-gpio"; reg = <0xb800>; diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi similarity index 98% rename from arch/arm64/boot/dts/qcom/x1e80100.dtsi rename to arch/arm64/boot/dts/qcom/hamoa.dtsi index 51576d9c935de..a17900eacb203 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -75,7 +75,6 @@ next-level-cache = <&l2_0>; power-domains = <&cpu_pd0>, <&scmi_dvfs 0>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; l2_0: l2-cache { compatible = "cache"; @@ -92,7 +91,6 @@ next-level-cache = <&l2_0>; power-domains = <&cpu_pd1>, <&scmi_dvfs 0>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; }; cpu2: cpu@200 { @@ -103,7 +101,6 @@ next-level-cache = <&l2_0>; power-domains = <&cpu_pd2>, <&scmi_dvfs 0>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; }; cpu3: cpu@300 { @@ -114,7 +111,6 @@ next-level-cache = <&l2_0>; power-domains = <&cpu_pd3>, <&scmi_dvfs 0>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; }; cpu4: cpu@10000 { @@ -125,7 +121,6 @@ next-level-cache = <&l2_1>; power-domains = <&cpu_pd4>, <&scmi_dvfs 1>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; l2_1: l2-cache { compatible = "cache"; @@ -142,7 +137,6 @@ next-level-cache = <&l2_1>; power-domains = <&cpu_pd5>, <&scmi_dvfs 1>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; }; cpu6: cpu@10200 { @@ -153,7 +147,6 @@ next-level-cache = <&l2_1>; power-domains = <&cpu_pd6>, <&scmi_dvfs 1>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; }; cpu7: cpu@10300 { @@ -164,7 +157,6 @@ next-level-cache = <&l2_1>; power-domains = <&cpu_pd7>, <&scmi_dvfs 1>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; }; cpu8: cpu@20000 { @@ -175,7 +167,6 @@ next-level-cache = <&l2_2>; power-domains = <&cpu_pd8>, <&scmi_dvfs 2>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; l2_2: l2-cache { compatible = "cache"; @@ -192,7 +183,6 @@ next-level-cache = <&l2_2>; power-domains = <&cpu_pd9>, <&scmi_dvfs 2>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; }; cpu10: cpu@20200 { @@ -203,7 +193,6 @@ next-level-cache = <&l2_2>; power-domains = <&cpu_pd10>, <&scmi_dvfs 2>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; }; cpu11: cpu@20300 { @@ -214,7 +203,6 @@ next-level-cache = <&l2_2>; power-domains = <&cpu_pd11>, <&scmi_dvfs 2>; power-domain-names = "psci", "perf"; - cpu-idle-states = <&cluster_c4>; }; cpu-map { @@ -371,61 +359,73 @@ cpu_pd0: power-domain-cpu0 { #power-domain-cells = <0>; power-domains = <&cluster_pd0>; + domain-idle-states = <&cluster_c4>; }; cpu_pd1: power-domain-cpu1 { #power-domain-cells = <0>; power-domains = <&cluster_pd0>; + domain-idle-states = <&cluster_c4>; }; cpu_pd2: power-domain-cpu2 { #power-domain-cells = <0>; power-domains = <&cluster_pd0>; + domain-idle-states = <&cluster_c4>; }; cpu_pd3: power-domain-cpu3 { #power-domain-cells = <0>; power-domains = <&cluster_pd0>; + domain-idle-states = <&cluster_c4>; }; cpu_pd4: power-domain-cpu4 { #power-domain-cells = <0>; power-domains = <&cluster_pd1>; + domain-idle-states = <&cluster_c4>; }; cpu_pd5: power-domain-cpu5 { #power-domain-cells = <0>; power-domains = <&cluster_pd1>; + domain-idle-states = <&cluster_c4>; }; cpu_pd6: power-domain-cpu6 { #power-domain-cells = <0>; power-domains = <&cluster_pd1>; + domain-idle-states = <&cluster_c4>; }; cpu_pd7: power-domain-cpu7 { #power-domain-cells = <0>; power-domains = <&cluster_pd1>; + domain-idle-states = <&cluster_c4>; }; cpu_pd8: power-domain-cpu8 { #power-domain-cells = <0>; power-domains = <&cluster_pd2>; + domain-idle-states = <&cluster_c4>; }; cpu_pd9: power-domain-cpu9 { #power-domain-cells = <0>; power-domains = <&cluster_pd2>; + domain-idle-states = <&cluster_c4>; }; cpu_pd10: power-domain-cpu10 { #power-domain-cells = <0>; power-domains = <&cluster_pd2>; + domain-idle-states = <&cluster_c4>; }; cpu_pd11: power-domain-cpu11 { #power-domain-cells = <0>; power-domains = <&cluster_pd2>; + domain-idle-states = <&cluster_c4>; }; cluster_pd0: power-domain-cpu-cluster0 { @@ -807,7 +807,34 @@ <0>, <&usb_1_ss0_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, <&usb_1_ss1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, - <&usb_1_ss2_qmpphy QMP_USB43DP_USB3_PIPE_CLK>; + <&usb_1_ss2_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>; power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; @@ -3240,74 +3267,132 @@ pcie3_opp_table: opp-table { compatible = "operating-points-v2"; - /* GEN 1 x1 */ - opp-2500000 { + /* 2.5GT/s x1 */ + opp-2500000-1 { opp-hz = /bits/ 64 <2500000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <250000 1>; + opp-level = <1>; }; - /* GEN 1 x2 and GEN 2 x1 */ - opp-5000000 { + /* 2.5 GT/s x2 */ + opp-5000000-1 { opp-hz = /bits/ 64 <5000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <500000 1>; + opp-level = <1>; }; - /* GEN 1 x4 and GEN 2 x2 */ - opp-10000000 { + /* 2.5 GT/s x4 */ + opp-10000000-1 { opp-hz = /bits/ 64 <10000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <1000000 1>; + opp-level = <1>; }; - /* GEN 1 x8 and GEN 2 x4 */ - opp-20000000 { + /* 2.5 GT/s x8 */ + opp-20000000-1 { opp-hz = /bits/ 64 <20000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <2000000 1>; + opp-level = <1>; + }; + + /* 5 GT/s x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; }; - /* GEN 2 x8 */ - opp-40000000 { + /* 5 GT/s x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* 5 GT/s x4 */ + opp-20000000-2 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + opp-level = <2>; + }; + + /* 5 GT/s x8 */ + opp-40000000-2 { opp-hz = /bits/ 64 <40000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <4000000 1>; + opp-level = <2>; }; - /* GEN 3 x1 */ - opp-8000000 { + /* 8 GT/s x1 */ + opp-8000000-3 { opp-hz = /bits/ 64 <8000000>; required-opps = <&rpmhpd_opp_svs>; opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* 8 GT/s x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + /* 8 GT/s x4 */ + opp-32000000-3 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <3>; + }; + + /* 8 GT/s x8 */ + opp-64000000-3 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <7876000 1>; + opp-level = <3>; }; - /* GEN 3 x2 and GEN 4 x1 */ - opp-16000000 { + /* 16 GT/s x1 */ + opp-16000000-4 { opp-hz = /bits/ 64 <16000000>; required-opps = <&rpmhpd_opp_svs>; opp-peak-kBps = <1969000 1>; + opp-level = <4>; }; - /* GEN 3 x4 and GEN 4 x2 */ - opp-32000000 { + /* 16 GT/s x2 */ + opp-32000000-4 { opp-hz = /bits/ 64 <32000000>; required-opps = <&rpmhpd_opp_svs>; opp-peak-kBps = <3938000 1>; + opp-level = <4>; }; - /* GEN 3 x8 and GEN 4 x4 */ - opp-64000000 { + /* 16 GT/s x4 */ + opp-64000000-4 { opp-hz = /bits/ 64 <64000000>; required-opps = <&rpmhpd_opp_svs>; opp-peak-kBps = <7876000 1>; + opp-level = <4>; }; - /* GEN 4 x8 */ - opp-128000000 { + /* 16 GT/s x8 */ + opp-128000000-4 { opp-hz = /bits/ 64 <128000000>; required-opps = <&rpmhpd_opp_svs>; opp-peak-kBps = <15753000 1>; + opp-level = <4>; }; }; @@ -4922,6 +5007,7 @@ interconnect-names = "usb-ddr", "apps-usb"; + qcom,select-utmi-as-pipe-clk; wakeup-source; status = "disabled"; @@ -4939,15 +5025,8 @@ dma-coherent; - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - usb_2_dwc3_hs: endpoint { - }; + port { + usb_2_dwc3_hs: endpoint { }; }; }; @@ -5466,7 +5545,7 @@ compatible = "qcom,x1e80100-dp"; reg = <0 0x0ae90000 0 0x200>, <0 0x0ae90200 0 0x200>, - <0 0x0ae90400 0 0x600>, + <0 0x0ae90400 0 0xc00>, <0 0x0ae91000 0 0x400>, <0 0x0ae91400 0 0x400>; @@ -5554,7 +5633,7 @@ compatible = "qcom,x1e80100-dp"; reg = <0 0x0ae98000 0 0x200>, <0 0x0ae98200 0 0x200>, - <0 0x0ae98400 0 0x600>, + <0 0x0ae98400 0 0xc00>, <0 0x0ae99000 0 0x400>, <0 0x0ae99400 0 0x400>; @@ -5642,7 +5721,7 @@ compatible = "qcom,x1e80100-dp"; reg = <0 0x0ae9a000 0 0x200>, <0 0x0ae9a200 0 0x200>, - <0 0x0ae9a400 0 0x600>, + <0 0x0ae9a400 0 0xc00>, <0 0x0ae9b000 0 0x400>, <0 0x0ae9b400 0 0x400>; @@ -5729,7 +5808,7 @@ compatible = "qcom,x1e80100-dp"; reg = <0 0x0aea0000 0 0x200>, <0 0x0aea0200 0 0x200>, - <0 0x0aea0400 0 0x600>, + <0 0x0aea0400 0 0xc00>, <0 0x0aea1000 0 0x400>, <0 0x0aea1400 0 0x400>; diff --git a/arch/arm64/boot/dts/qcom/ipq5424.dtsi b/arch/arm64/boot/dts/qcom/ipq5424.dtsi index ef2b52f3597d9..eb393f3fd728f 100644 --- a/arch/arm64/boot/dts/qcom/ipq5424.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq5424.dtsi @@ -3,7 +3,7 @@ * IPQ5424 device tree source * * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -13,6 +13,7 @@ #include #include #include +#include / { #address-cells = <2>; @@ -57,6 +58,7 @@ clock-names = "cpu"; operating-points-v2 = <&cpu_opp_table>; interconnects = <&apss_clk MASTER_CPU &apss_clk SLAVE_L3>; + #cooling-cells = <2>; l2_0: l2-cache { compatible = "cache"; @@ -82,6 +84,7 @@ clock-names = "cpu"; operating-points-v2 = <&cpu_opp_table>; interconnects = <&apss_clk MASTER_CPU &apss_clk SLAVE_L3>; + #cooling-cells = <2>; l2_100: l2-cache { compatible = "cache"; @@ -101,6 +104,7 @@ clock-names = "cpu"; operating-points-v2 = <&cpu_opp_table>; interconnects = <&apss_clk MASTER_CPU &apss_clk SLAVE_L3>; + #cooling-cells = <2>; l2_200: l2-cache { compatible = "cache"; @@ -120,6 +124,7 @@ clock-names = "cpu"; operating-points-v2 = <&cpu_opp_table>; interconnects = <&apss_clk MASTER_CPU &apss_clk SLAVE_L3>; + #cooling-cells = <2>; l2_300: l2-cache { compatible = "cache"; @@ -213,7 +218,7 @@ }; tfa@8a832000 { - reg = <0x0 0x8a832000 0x0 0x7d000>; + reg = <0x0 0x8a832000 0x0 0x80000>; no-map; status = "disabled"; }; @@ -815,6 +820,36 @@ #interconnect-cells = <1>; }; + clock-controller@39b00000 { + compatible = "qcom,ipq5424-nsscc"; + reg = <0 0x39b00000 0 0x100000>; + clocks = <&cmn_pll IPQ5424_XO_24MHZ_CLK>, + <&cmn_pll IPQ5424_NSS_300MHZ_CLK>, + <&cmn_pll IPQ5424_PPE_375MHZ_CLK>, + <&gcc GPLL0_OUT_AUX>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <&gcc GCC_NSSCC_CLK>; + clock-names = "xo", + "nss", + "ppe", + "gpll0_out", + "uniphy0_rx", + "uniphy0_tx", + "uniphy1_rx", + "uniphy1_tx", + "uniphy2_rx", + "uniphy2_tx", + "bus"; + #clock-cells = <1>; + #reset-cells = <1>; + #interconnect-cells = <1>; + }; + pcie3: pcie@40000000 { compatible = "qcom,pcie-ipq5424", "qcom,pcie-ipq9574"; reg = <0x0 0x40000000 0x0 0xf1c>, @@ -1235,18 +1270,28 @@ thermal-sensors = <&tsens 14>; trips { - cpu-critical { + cpu0_crit: cpu-critical { temperature = <120000>; hysteresis = <9000>; type = "critical"; }; - cpu-passive { + cpu0_alert: cpu-passive { temperature = <110000>; hysteresis = <9000>; type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&cpu0_alert>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; cpu1-thermal { @@ -1254,18 +1299,28 @@ thermal-sensors = <&tsens 12>; trips { - cpu-critical { + cpu1_crit: cpu-critical { temperature = <120000>; hysteresis = <9000>; type = "critical"; }; - cpu-passive { + cpu1_alert: cpu-passive { temperature = <110000>; hysteresis = <9000>; type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&cpu1_alert>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; cpu2-thermal { @@ -1273,18 +1328,28 @@ thermal-sensors = <&tsens 11>; trips { - cpu-critical { + cpu2_crit: cpu-critical { temperature = <120000>; hysteresis = <9000>; type = "critical"; }; - cpu-passive { + cpu2_alert: cpu-passive { temperature = <110000>; hysteresis = <9000>; type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&cpu2_alert>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; cpu3-thermal { @@ -1292,18 +1357,28 @@ thermal-sensors = <&tsens 13>; trips { - cpu-critical { + cpu3_crit: cpu-critical { temperature = <120000>; hysteresis = <9000>; type = "critical"; }; - cpu-passive { + cpu3_alert: cpu-passive { temperature = <110000>; hysteresis = <9000>; type = "passive"; }; }; + + cooling-maps { + map0 { + trip = <&cpu3_alert>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; wcss-tile2-thermal { diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi similarity index 97% rename from arch/arm64/boot/dts/qcom/sc7280.dtsi rename to arch/arm64/boot/dts/qcom/kodiak.dtsi index 4b04dea57ec8c..c2ccbb67f800c 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -3338,6 +3338,86 @@ }; }; + tpda@6004000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x06004000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1c { + reg = <0x1c>; + + qdss_tpda_in28: endpoint { + remote-endpoint = <&spdm_tpdm_out>; + }; + }; + }; + + out-ports { + port { + qdss_tpda_out: endpoint { + remote-endpoint = <&qdss_dl_funnel_in0>; + }; + }; + }; + }; + + funnel@6005000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x06005000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + qdss_dl_funnel_in0: endpoint { + remote-endpoint = <&qdss_tpda_out>; + }; + }; + }; + + out-ports { + port { + qdss_dl_funnel_out: endpoint { + remote-endpoint = <&funnel0_in6>; + }; + }; + }; + }; + + tpdm@600f000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x0600f000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <32>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + spdm_tpdm_out: endpoint { + remote-endpoint = <&qdss_tpda_in28>; + }; + }; + }; + }; + + cti@6010000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x06010000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + funnel@6041000 { compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; reg = <0 0x06041000 0 0x1000>; @@ -3357,6 +3437,14 @@ #address-cells = <1>; #size-cells = <0>; + port@6 { + reg = <6>; + + funnel0_in6: endpoint { + remote-endpoint = <&qdss_dl_funnel_out>; + }; + }; + port@7 { reg = <7>; funnel0_in7: endpoint { @@ -3471,6 +3559,38 @@ }; }; + cti@6b00000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x06b00000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + + cti@6b01000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x06b01000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + + cti@6b02000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x06b02000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + + cti@6b03000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x06b03000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + funnel@6b04000 { compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; reg = <0 0x06b04000 0 0x1000>; @@ -3490,6 +3610,14 @@ #address-cells = <1>; #size-cells = <0>; + port@6 { + reg = <6>; + + swao_funnel_in6: endpoint { + remote-endpoint = <&aoss_tpda_out>; + }; + }; + port@7 { reg = <7>; swao_funnel_in: endpoint { @@ -3548,6 +3676,170 @@ }; }; + tpda@6b08000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x06b08000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + aoss_tpda_in0: endpoint { + remote-endpoint = <&swao_prio0_tpdm_out>; + }; + }; + + port@1 { + reg = <1>; + + aoss_tpda_in1: endpoint { + remote-endpoint = <&swao_prio1_tpdm_out>; + }; + }; + + port@2 { + reg = <2>; + + aoss_tpda_in2: endpoint { + remote-endpoint = <&swao_prio2_tpdm_out>; + }; + }; + + port@3 { + reg = <3>; + + aoss_tpda_in3: endpoint { + remote-endpoint = <&swao_prio3_tpdm_out>; + }; + }; + + port@4 { + reg = <4>; + + aoss_tpda_in4: endpoint { + remote-endpoint = <&swao_tpdm_out>; + }; + }; + }; + + out-ports { + port { + aoss_tpda_out: endpoint { + remote-endpoint = <&swao_funnel_in6>; + }; + }; + }; + }; + + tpdm@6b09000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x06b09000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + swao_prio0_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in0>; + }; + }; + }; + }; + + tpdm@6b0a000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x06b0a000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + swao_prio1_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in1>; + }; + }; + }; + }; + + tpdm@6b0b000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x06b0b000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + swao_prio2_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in2>; + }; + }; + }; + }; + + tpdm@6b0c000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x06b0c000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; + + out-ports { + port { + swao_prio3_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in3>; + }; + }; + }; + }; + + tpdm@6b0d000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x06b0d000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + swao_tpdm_out: endpoint { + remote-endpoint = <&aoss_tpda_in4>; + }; + }; + }; + }; + + cti@6b11000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x06b11000 0x0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + }; + etm@7040000 { compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0 0x07040000 0 0x1000>; @@ -3885,6 +4177,12 @@ resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; }; + refgen: regulator@88e7000 { + compatible = "qcom,sc7280-refgen-regulator", + "qcom,sm8250-refgen-regulator"; + reg = <0x0 0x088e7000 0x0 0x84>; + }; + usb_1_qmpphy: phy@88e8000 { compatible = "qcom,sc7280-qmp-usb3-dp-phy"; reg = <0 0x088e8000 0 0x3000>; @@ -5074,6 +5372,8 @@ phys = <&mdss_dsi_phy>; + refgen-supply = <&refgen>; + #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/qcom/lemans-evk-camera.dtso b/arch/arm64/boot/dts/qcom/lemans-evk-camera.dtso new file mode 100644 index 0000000000000..4600d5441cce4 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/lemans-evk-camera.dtso @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +/* + * Camera Sensor overlay on top of leman evk core kit. + */ + +/dts-v1/; +/plugin/; + +#include +#include + +&{/} { + vreg_cam1_1p8: vreg_cam1_1p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_cam1_1p8"; + startup-delay-us = <10000>; + enable-active-high; + gpio = <&pmm8654au_0_gpios 8 GPIO_ACTIVE_HIGH>; + }; +}; + +&camcc { + status = "okay"; +}; + +&camss { + vdda-pll-supply = <&vreg_l1c>; + vdda-phy-supply = <&vreg_l4a>; + + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + csiphy1_ep: endpoint { + clock-lanes = <7>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&imx577_ep1>; + }; + }; + }; +}; + +&cci1 { + pinctrl-0 = <&cci1_0_default>; + pinctrl-1 = <&cci1_0_sleep>; + + status = "okay"; +}; + +&cci1_i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + camera@1a { + compatible = "sony,imx577"; + reg = <0x1a>; + + reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&cam1_default>; + pinctrl-names = "default"; + + clocks = <&camcc CAM_CC_MCLK1_CLK>; + assigned-clocks = <&camcc CAM_CC_MCLK1_CLK>; + assigned-clock-rates = <24000000>; + + dovdd-supply = <&vreg_s4a>; + avdd-supply = <&vreg_cam1_1p8>; + + port { + imx577_ep1: endpoint { + clock-lanes = <7>; + link-frequencies = /bits/ 64 <600000000>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&csiphy1_ep>; + }; + }; + }; +}; + +&tlmm { + cam1_default: cam1-default-state { + mclk-pins { + pins = "gpio73"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + rst-pins { + pins = "gpio133"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index c7dc9b8f44578..b40fa203e4a2f 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include #include @@ -501,6 +502,20 @@ }; }; +&i2c19 { + status = "okay"; + + fan_controller: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + #pwm-cells = <2>; + + fan { + pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED>; + }; + }; +}; + &iris { firmware-name = "qcom/vpu/vpu30_p4_s6_16mb.mbn"; @@ -587,15 +602,28 @@ status = "okay"; }; +&pmm8654au_0_pon_resin { + linux,code = ; + status = "okay"; +}; + +&qup_i2c19_default { + drive-strength = <2>; + bias-pull-up; +}; + &qupv3_id_0 { + firmware-name = "qcom/sa8775p/qupv3fw.elf"; status = "okay"; }; &qupv3_id_1 { + firmware-name = "qcom/sa8775p/qupv3fw.elf"; status = "okay"; }; &qupv3_id_2 { + firmware-name = "qcom/sa8775p/qupv3fw.elf"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi b/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi index 1369c3d43f866..341119fc82440 100644 --- a/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi @@ -132,6 +132,15 @@ }; }; + pmm8654au_0_rtc: rtc@6100 { + compatible = "qcom,pmk8350-rtc"; + reg = <0x6100>, + <0x6200>; + reg-names = "rtc", + "alarm"; + interrupts = <0x0 0x62 0x1 IRQ_TYPE_EDGE_RISING>; + }; + pmm8654au_0_gpios: gpio@8800 { compatible = "qcom,pmm8654au-gpio", "qcom,spmi-gpio"; reg = <0x8800>; diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index cf685cb186edc..0b154d57ba24e 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -3901,6 +3901,32 @@ status = "disabled"; }; + usb_1_hsphy: phy@88e6000 { + compatible = "qcom,sa8775p-usb-hs-phy", + "qcom,usb-snps-hs-5nm-phy"; + reg = <0 0x088e6000 0 0x120>; + clocks = <&gcc GCC_USB_CLKREF_EN>; + clock-names = "ref"; + resets = <&gcc GCC_USB2_PHY_SEC_BCR>; + + #phy-cells = <0>; + + status = "disabled"; + }; + + usb_2_hsphy: phy@88e7000 { + compatible = "qcom,sa8775p-usb-hs-phy", + "qcom,usb-snps-hs-5nm-phy"; + reg = <0 0x088e7000 0 0x120>; + clocks = <&gcc GCC_USB_CLKREF_EN>; + clock-names = "ref"; + resets = <&gcc GCC_USB3_PHY_TERT_BCR>; + + #phy-cells = <0>; + + status = "disabled"; + }; + usb_0_qmpphy: phy@88e8000 { compatible = "qcom,sa8775p-qmp-usb3-uni-phy"; reg = <0 0x088e8000 0 0x2000>; @@ -3925,6 +3951,36 @@ status = "disabled"; }; + usb_1_qmpphy: phy@88ea000 { + compatible = "qcom,sa8775p-qmp-usb3-uni-phy"; + reg = <0 0x088ea000 0 0x2000>; + + clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, + <&gcc GCC_USB_CLKREF_EN>, + <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; + clock-names = "aux", "ref", "com_aux", "pipe"; + + resets = <&gcc GCC_USB3_PHY_SEC_BCR>, + <&gcc GCC_USB3PHY_PHY_SEC_BCR>; + reset-names = "phy", "phy_phy"; + + power-domains = <&gcc USB30_SEC_GDSC>; + + #clock-cells = <0>; + clock-output-names = "usb3_sec_phy_pipe_clk_src"; + + #phy-cells = <0>; + + status = "disabled"; + }; + + refgen: regulator@891c000 { + compatible = "qcom,sa8775p-refgen-regulator", + "qcom,sm8250-refgen-regulator"; + reg = <0x0 0x0891c000 0x0 0x84>; + }; + usb_0: usb@a600000 { compatible = "qcom,sa8775p-dwc3", "qcom,snps-dwc3"; reg = <0 0x0a600000 0 0xfc100>; @@ -3973,43 +4029,6 @@ status = "disabled"; }; - usb_1_hsphy: phy@88e6000 { - compatible = "qcom,sa8775p-usb-hs-phy", - "qcom,usb-snps-hs-5nm-phy"; - reg = <0 0x088e6000 0 0x120>; - clocks = <&gcc GCC_USB_CLKREF_EN>; - clock-names = "ref"; - resets = <&gcc GCC_USB2_PHY_SEC_BCR>; - - #phy-cells = <0>; - - status = "disabled"; - }; - - usb_1_qmpphy: phy@88ea000 { - compatible = "qcom,sa8775p-qmp-usb3-uni-phy"; - reg = <0 0x088ea000 0 0x2000>; - - clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, - <&gcc GCC_USB_CLKREF_EN>, - <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>, - <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; - clock-names = "aux", "ref", "com_aux", "pipe"; - - resets = <&gcc GCC_USB3_PHY_SEC_BCR>, - <&gcc GCC_USB3PHY_PHY_SEC_BCR>; - reset-names = "phy", "phy_phy"; - - power-domains = <&gcc USB30_SEC_GDSC>; - - #clock-cells = <0>; - clock-output-names = "usb3_sec_phy_pipe_clk_src"; - - #phy-cells = <0>; - - status = "disabled"; - }; - usb_1: usb@a800000 { compatible = "qcom,sa8775p-dwc3", "qcom,snps-dwc3"; reg = <0 0x0a800000 0 0xfc100>; @@ -4058,19 +4077,6 @@ status = "disabled"; }; - usb_2_hsphy: phy@88e7000 { - compatible = "qcom,sa8775p-usb-hs-phy", - "qcom,usb-snps-hs-5nm-phy"; - reg = <0 0x088e7000 0 0x120>; - clocks = <&gcc GCC_USB_CLKREF_EN>; - clock-names = "ref"; - resets = <&gcc GCC_USB3_PHY_TERT_BCR>; - - #phy-cells = <0>; - - status = "disabled"; - }; - usb_2: usb@a400000 { compatible = "qcom,sa8775p-dwc3", "qcom,snps-dwc3"; reg = <0 0x0a400000 0 0xfc100>; @@ -4106,6 +4112,7 @@ <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB2 0>; interconnect-names = "usb-ddr", "apps-usb"; + qcom,select-utmi-as-pipe-clk; wakeup-source; iommus = <&apps_smmu 0x020 0x0>; @@ -4899,6 +4906,8 @@ operating-points-v2 = <&mdss_dsi_opp_table>; power-domains = <&rpmhpd SA8775P_MMCX>; + refgen-supply = <&refgen>; + #address-cells = <1>; #size-cells = <0>; @@ -4981,6 +4990,8 @@ operating-points-v2 = <&mdss_dsi_opp_table>; power-domains = <&rpmhpd SA8775P_MMCX>; + refgen-supply = <&refgen>; + #address-cells = <1>; #size-cells = <0>; @@ -6812,11 +6823,12 @@ "ptp_ref", "phyaux"; - interconnects = <&aggre1_noc MASTER_EMAC_1 QCOM_ICC_TAG_ALWAYS - &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, - <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS - &config_noc SLAVE_EMAC1_CFG QCOM_ICC_TAG_ALWAYS>; - interconnect-names = "mac-mem", "cpu-mac"; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_EMAC1_CFG QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc MASTER_EMAC_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "cpu-mac", + "mac-mem"; power-domains = <&gcc EMAC1_GDSC>; @@ -6853,11 +6865,12 @@ "ptp_ref", "phyaux"; - interconnects = <&aggre1_noc MASTER_EMAC QCOM_ICC_TAG_ALWAYS - &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, - <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS - &config_noc SLAVE_EMAC_CFG QCOM_ICC_TAG_ALWAYS>; - interconnect-names = "mac-mem", "cpu-mac"; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_EMAC_CFG QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc MASTER_EMAC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "cpu-mac", + "mac-mem"; power-domains = <&gcc EMAC0_GDSC>; diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index e72cf6725a52c..bb35893da73d1 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -9,8 +9,8 @@ #include #include -#include "qcs8300.dtsi" -#include "qcs8300-pmics.dtsi" +#include "monaco.dtsi" +#include "monaco-pmics.dtsi" / { model = "Qualcomm Technologies, Inc. Monaco EVK"; @@ -401,10 +401,12 @@ }; &qupv3_id_0 { + firmware-name = "qcom/qcs8300/qupv3fw.elf"; status = "okay"; }; &qupv3_id_1 { + firmware-name = "qcom/qcs8300/qupv3fw.elf"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/qcs8300-pmics.dtsi b/arch/arm64/boot/dts/qcom/monaco-pmics.dtsi similarity index 98% rename from arch/arm64/boot/dts/qcom/qcs8300-pmics.dtsi rename to arch/arm64/boot/dts/qcom/monaco-pmics.dtsi index a94b0bfa98dc3..e990d7367719b 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-pmics.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco-pmics.dtsi @@ -18,7 +18,6 @@ reg = <0x6100>, <0x6200>; reg-names = "rtc", "alarm"; interrupts = <0x0 0x62 0x1 IRQ_TYPE_EDGE_RISING>; - allow-set-time; }; pmm8620au_0_gpios: gpio@8800 { diff --git a/arch/arm64/boot/dts/qcom/qcs8300.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi similarity index 99% rename from arch/arm64/boot/dts/qcom/qcs8300.dtsi rename to arch/arm64/boot/dts/qcom/monaco.dtsi index 8d78ccac411e4..816fa2af8a9a6 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -20,6 +20,7 @@ #include #include #include +#include / { interrupt-parent = <&intc>; @@ -4294,6 +4295,12 @@ status = "disabled"; }; + refgen: regulator@891c000 { + compatible = "qcom,qcs8300-refgen-regulator", + "qcom,sm8250-refgen-regulator"; + reg = <0x0 0x0891c000 0x0 0x84>; + }; + gpu: gpu@3d00000 { compatible = "qcom,adreno-623.0", "qcom,adreno"; reg = <0x0 0x03d00000 0x0 0x40000>, diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts index 887764dc55b21..93d5ea279cff1 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts @@ -79,6 +79,19 @@ }; }; + reg_ts_vcca: regulator-vcca-ts { + compatible = "regulator-fixed"; + regulator-name = "regulator-vcca-ts"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 78 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&ts_vcca_default>; + pinctrl-names = "default"; + }; + usb_id: usb-id { compatible = "linux,extcon-usb-gpio"; id-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>; @@ -176,6 +189,25 @@ }; }; +&blsp_i2c5 { + status = "okay"; + + touchscreen@48 { + compatible = "himax,hx8527e", "himax,hx852es"; + reg = <0x48>; + + interrupts-extended = <&tlmm 13 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>; + vcca-supply = <®_ts_vcca>; + vccd-supply = <&pm8916_l6>; + + pinctrl-0 = <&ts_int_reset_default>; + pinctrl-names = "default"; + + linux,keycodes = ; + }; +}; + &blsp_uart2 { status = "okay"; pinctrl-0 = <&blsp_uart2_console_default>; @@ -338,6 +370,20 @@ bias-disable; }; + ts_int_reset_default: ts-int-reset-default-state { + pins = "gpio12", "gpio13"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + ts_vcca_default: ts-vcca-default-state { + pins = "gpio78"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + usb_id_default: usb-id-default-state { pins = "gpio110"; function = "gpio"; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi index e7f265e3c2ab8..e33453c3e51e8 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi @@ -5,7 +5,7 @@ /* SM5504 MUIC instead of SM5502 */ /delete-node/ &muic; -/* Touchscreen varies depending on model variant */ +/* IST3038 instead of Zinitix BT541 */ /delete-node/ &touchscreen; &blsp_i2c1 { @@ -24,6 +24,26 @@ }; }; +&blsp_i2c5 { + touchscreen: touchscreen@50 { + compatible = "imagis,ist3038"; + reg = <0x50>; + + interrupts-extended = <&tlmm 13 IRQ_TYPE_EDGE_FALLING>; + + touchscreen-size-x = <480>; + touchscreen-size-y = <800>; + + vdd-supply = <®_vdd_tsp_a>; + vddio-supply = <&pm8916_l6>; + + pinctrl-0 = <&tsp_int_default>; + pinctrl-names = "default"; + + linux,keycodes = ; + }; +}; + /* On rossa backlight is controlled with MIPI DCS commands */ &clk_pwm { status = "disabled"; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts index 3413b0970c4ab..1981bb71f6a92 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts @@ -16,26 +16,6 @@ constant-charge-voltage-max-microvolt = <4400000>; }; -&blsp_i2c5 { - touchscreen@50 { - compatible = "imagis,ist3038"; - reg = <0x50>; - - interrupts-extended = <&tlmm 13 IRQ_TYPE_EDGE_FALLING>; - - touchscreen-size-x = <480>; - touchscreen-size-y = <800>; - - vdd-supply = <®_vdd_tsp_a>; - vddio-supply = <&pm8916_l6>; - - pinctrl-0 = <&tsp_int_default>; - pinctrl-names = "default"; - - linux,keycodes = ; - }; -}; - &mpss_mem { /* Firmware for rossa needs more space */ reg = <0x0 0x86800000 0x0 0x5800000>; diff --git a/arch/arm64/boot/dts/qcom/msm8937-xiaomi-land.dts b/arch/arm64/boot/dts/qcom/msm8937-xiaomi-land.dts new file mode 100644 index 0000000000000..91837ff940f1b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8937-xiaomi-land.dts @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2024, Barnabas Czeman + */ +/dts-v1/; + +#include +#include +#include + +#include "msm8937.dtsi" +#include "pm8937.dtsi" +#include "pmi8950.dtsi" + +/delete-node/ &qseecom_mem; + +/ { + model = "Xiaomi Redmi 3S (land)"; + compatible = "xiaomi,land", "qcom,msm8937"; + chassis-type = "handset"; + + qcom,msm-id = ; + qcom,board-id = <0x1000b 1>, <0x2000b 1>; + + aliases { + mmc0 = &sdhc_1; + mmc1 = &sdhc_2; + }; + + battery: battery { + compatible = "simple-battery"; + + charge-full-design-microamp-hours = <4100000>; + constant-charge-current-max-microamp = <1000000>; + voltage-min-design-microvolt = <3400000>; + voltage-max-design-microvolt = <4400000>; + }; + + chosen { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + stdout-path = "framebuffer0"; + + framebuffer0: framebuffer@8dd01000 { + compatible = "simple-framebuffer"; + reg = <0x0 0x8dd01000 0x0 (720 * 1280 * 3)>; + width = <720>; + height = <1280>; + stride = <(720 * 3)>; + format = "r8g8b8"; + + clocks = <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_AXI_CLK>, + <&gcc GCC_MDSS_VSYNC_CLK>, + <&gcc GCC_MDSS_MDP_CLK>, + <&gcc GCC_MDSS_BYTE0_CLK>, + <&gcc GCC_MDSS_PCLK0_CLK>, + <&gcc GCC_MDSS_ESC0_CLK>; + power-domains = <&gcc MDSS_GDSC>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&gpio_keys_default>; + pinctrl-names = "default"; + + key-volup { + label = "Volume Up"; + linux,code = ; + gpios = <&tlmm 91 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + }; + }; + + irled { + compatible = "gpio-ir-tx"; + gpios = <&tlmm 45 GPIO_ACTIVE_HIGH>; + }; + + reserved-memory { + reserved@84a00000 { + reg = <0x0 0x84a00000 0x0 0x1900000>; + no-map; + }; + + framebuffer: memory@8dd01000 { + reg = <0x0 0x8dd01000 0x0 (720 * 1280 * 3)>; + no-map; + }; + }; + + vph_pwr: vph-pwr-regulator { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&blsp1_i2c2 { + status = "okay"; + + led-controller@45 { + compatible = "awinic,aw2013"; + reg = <0x45>; + #address-cells = <1>; + #size-cells = <0>; + + vcc-supply = <&pm8937_l10>; + vio-supply = <&pm8937_l5>; + + led@0 { + reg = <0>; + function = LED_FUNCTION_STATUS; + led-max-microamp = <5000>; + color = ; + }; + + led@1 { + reg = <1>; + function = LED_FUNCTION_STATUS; + led-max-microamp = <5000>; + color = ; + }; + + led@2 { + reg = <2>; + function = LED_FUNCTION_STATUS; + led-max-microamp = <5000>; + color = ; + }; + }; +}; + +&blsp1_i2c3 { + status = "okay"; + + touchscreen@3e { + compatible = "edt,edt-ft5306"; + reg = <0x3e>; + + interrupts-extended = <&tlmm 65 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&tlmm 64 GPIO_ACTIVE_LOW>; + vcc-supply = <&pm8937_l10>; + iovcc-supply = <&pm8937_l5>; + + pinctrl-0 = <&tsp_int_rst_default>; + pinctrl-names = "default"; + + touchscreen-size-x = <720>; + touchscreen-size-y = <1280>; + }; +}; + +&pm8937_resin { + linux,code = ; + + status = "okay"; +}; + +&pm8937_spmi_regulators { + /* APC */ + pm8937_s5: s5 { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&pmi8950_wled { + qcom,num-strings = <2>; + qcom,external-pfet; + qcom,current-limit-microamp = <20000>; + qcom,ovp-millivolt = <29600>; + + status = "okay"; +}; + +&rpm_requests { + regulators-0 { + compatible = "qcom,rpm-pm8937-regulators"; + + vdd_s1-supply = <&vph_pwr>; + vdd_s2-supply = <&vph_pwr>; + vdd_s3-supply = <&vph_pwr>; + vdd_s4-supply = <&vph_pwr>; + + vdd_l1_l19-supply = <&pm8937_s3>; + vdd_l2_l23-supply = <&pm8937_s3>; + vdd_l3-supply = <&pm8937_s3>; + vdd_l4_l5_l6_l7_l16-supply = <&pm8937_s4>; + vdd_l8_l11_l12_l17_l22-supply = <&vph_pwr>; + vdd_l9_l10_l13_l14_l15_l18-supply = <&vph_pwr>; + + pm8937_s1: s1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1225000>; + }; + + pm8937_s3: s3 { + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + }; + + pm8937_s4: s4 { + regulator-min-microvolt = <2050000>; + regulator-max-microvolt = <2050000>; + }; + + pm8937_l2: l2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + pm8937_l5: l5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8937_l6: l6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8937_l7: l7 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8937_l8: l8 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2900000>; + }; + + pm8937_l9: l9 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + }; + + pm8937_l10: l10 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3000000>; + }; + + pm8937_l11: l11 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + regulator-allow-set-load; + regulator-system-load = <200000>; + }; + + pm8937_l12: l12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; + }; + + pm8937_l13: l13 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3075000>; + }; + + pm8937_l14: l14 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; + + pm8937_l15: l15 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; + + pm8937_l16: l16 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8937_l17: l17 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2900000>; + }; + + pm8937_l19: l19 { + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1350000>; + }; + + pm8937_l22: l22 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + pm8937_l23: l23 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + }; +}; + +&sdc2_cmd_default { + drive-strength = <12>; +}; + +&sdc2_data_default { + drive-strength = <12>; +}; + +&sdhc_1 { + vmmc-supply = <&pm8937_l8>; + vqmmc-supply = <&pm8937_l5>; + + status = "okay"; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 67 GPIO_ACTIVE_LOW>; + vmmc-supply = <&pm8937_l11>; + vqmmc-supply = <&pm8937_l12>; + pinctrl-0 = <&sdc2_default &sdc2_cd_default>; + pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>; + pinctrl-names = "default", "sleep"; + + status = "okay"; +}; + +&sleep_clk { + clock-frequency = <32768>; +}; + +&tlmm { + gpio-reserved-ranges = <0 4>, <20 4>; + + gpio_keys_default: gpio-keys-default-state { + pins = "gpio91"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + sdc2_cd_default: sdc2-cd-default-state { + pins = "gpio67"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + tsp_int_rst_default: tsp-int-rst-default-state { + pins = "gpio64", "gpio65"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; +}; + +&wcnss { + vddpx-supply = <&pm8937_l5>; + + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; + vddxo-supply = <&pm8937_l7>; + vddrfa-supply = <&pm8937_l19>; + vddpa-supply = <&pm8937_l9>; + vdddig-supply = <&pm8937_l5>; +}; + +&wcnss_mem { + status = "okay"; +}; + +&xo_board { + clock-frequency = <19200000>; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8937.dtsi b/arch/arm64/boot/dts/qcom/msm8937.dtsi new file mode 100644 index 0000000000000..b936210809894 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8937.dtsi @@ -0,0 +1,2133 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2023, Dang Huynh + */ + +#include +#include +#include +#include +#include +#include + +/ { + interrupt-parent = <&intc>; + + #address-cells = <2>; + #size-cells = <2>; + + clocks { + xo_board: xo-board { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-a53"; + reg = <0x0>; + device_type = "cpu"; + enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table_c0>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + + l2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-size = <0x80000>; + cache-unified; + }; + }; + + cpu1: cpu@1 { + compatible = "arm,cortex-a53"; + reg = <0x1>; + device_type = "cpu"; + enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table_c0>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu2: cpu@2 { + compatible = "arm,cortex-a53"; + reg = <0x2>; + device_type = "cpu"; + enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table_c0>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu3: cpu@3 { + compatible = "arm,cortex-a53"; + reg = <0x3>; + device_type = "cpu"; + enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table_c0>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu4: cpu@100 { + compatible = "arm,cortex-a53"; + reg = <0x100>; + device_type = "cpu"; + next-level-cache = <&l2_1>; + enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table_c1>; + #cooling-cells = <2>; + + l2_1: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-size = <0x100000>; + cache-unified; + }; + }; + + cpu5: cpu@101 { + compatible = "arm,cortex-a53"; + reg = <0x101>; + device_type = "cpu"; + next-level-cache = <&l2_1>; + enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table_c1>; + #cooling-cells = <2>; + }; + + cpu6: cpu@102 { + compatible = "arm,cortex-a53"; + reg = <0x102>; + device_type = "cpu"; + next-level-cache = <&l2_1>; + enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table_c1>; + #cooling-cells = <2>; + }; + + cpu7: cpu@103 { + compatible = "arm,cortex-a53"; + reg = <0x103>; + device_type = "cpu"; + next-level-cache = <&l2_1>; + enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table_c1>; + #cooling-cells = <2>; + }; + + cpu-map { + /* Little Cores */ + cluster0 { + core0 { + cpu = <&cpu0>; + }; + + core1 { + cpu = <&cpu1>; + }; + + core2 { + cpu = <&cpu2>; + }; + + core3 { + cpu = <&cpu3>; + }; + }; + + /* Big Cores */ + cluster1 { + core0 { + cpu = <&cpu4>; + }; + + core1 { + cpu = <&cpu5>; + }; + + core2 { + cpu = <&cpu6>; + }; + + core3 { + cpu = <&cpu7>; + }; + }; + }; + }; + + firmware { + scm: scm { + compatible = "qcom,scm-msm8937", "qcom,scm"; + clocks = <&gcc GCC_CRYPTO_CLK>, + <&gcc GCC_CRYPTO_AXI_CLK>, + <&gcc GCC_CRYPTO_AHB_CLK>; + clock-names = "core", + "bus", + "iface"; + #reset-cells = <1>; + + qcom,dload-mode = <&tcsr 0x6100>; + }; + }; + + memory@80000000 { + /* We expect the bootloader to fill in the reg */ + reg = <0 0x80000000 0 0>; + device_type = "memory"; + }; + + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + + qseecom_mem: reserved@85b00000 { + reg = <0x0 0x85b00000 0x0 0x800000>; + no-map; + }; + + smem@86300000 { + compatible = "qcom,smem"; + reg = <0x0 0x86300000 0x0 0x100000>; + no-map; + + hwlocks = <&tcsr_mutex 3>; + qcom,rpm-msg-ram = <&rpm_msg_ram>; + }; + + reserved@86400000 { + reg = <0x0 0x86400000 0x0 0x400000>; + no-map; + }; + + rmtfs@92100000 { + compatible = "qcom,rmtfs-mem"; + reg = <0x0 0x92100000 0x0 0x180000>; + no-map; + + qcom,client-id = <1>; + }; + + adsp_mem: adsp { + size = <0x0 0x1100000>; + alignment = <0x0 0x100000>; + alloc-ranges = <0x0 0x86800000 0x0 0x8000000>; + no-map; + status = "disabled"; + }; + + mba_mem: mba { + size = <0x0 0x100000>; + alignment = <0x0 0x100000>; + alloc-ranges = <0x0 0x86800000 0x0 0x8000000>; + no-map; + status = "disabled"; + }; + + wcnss_mem: wcnss { + size = <0x0 0x700000>; + alignment = <0x0 0x100000>; + alloc-ranges = <0x0 0x86800000 0x0 0x8000000>; + no-map; + status = "disabled"; + }; + + venus_mem: venus { + size = <0x0 0x400000>; + alignment = <0x0 0x100000>; + alloc-ranges = <0x0 0x86800000 0x0 0x8000000>; + no-map; + status = "disabled"; + }; + }; + + cpu_opp_table_c0: opp-table-c0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-768000000 { + opp-hz = /bits/ 64 <768000000>; + }; + + opp-902400000 { + opp-hz = /bits/ 64 <902400000>; + }; + + opp-998400000 { + opp-hz = /bits/ 64 <998400000>; + }; + + opp-1094400000 { + opp-hz = /bits/ 64 <1094400000>; + }; + }; + + cpu_opp_table_c1: opp-table-c1 { + compatible = "operating-points-v2"; + opp-shared; + + opp-960000000 { + opp-hz = /bits/ 64 <960000000>; + }; + + opp-1094400000 { + opp-hz = /bits/ 64 <1094400000>; + }; + + opp-1209600000 { + opp-hz = /bits/ 64 <1209600000>; + }; + + opp-1248000000 { + opp-hz = /bits/ 64 <1248000000>; + }; + + opp-1344000000 { + opp-hz = /bits/ 64 <1344000000>; + }; + + opp-1401600000 { + opp-hz = /bits/ 64 <1401600000>; + }; + }; + + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = ; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + rpm: remoteproc { + compatible = "qcom,msm8937-rpm-proc", "qcom,rpm-proc"; + + smd-edge { + interrupts = ; + qcom,ipc = <&apcs1 8 0>; + qcom,smd-edge = <15>; + + rpm_requests: rpm-requests { + compatible = "qcom,rpm-msm8937", "qcom,smd-rpm"; + qcom,smd-channels = "rpm_requests"; + + rpmcc: clock-controller { + compatible = "qcom,rpmcc-msm8937", "qcom,rpmcc"; + #clock-cells = <1>; + clocks = <&xo_board>; + clock-names = "xo"; + }; + + rpmpd: power-controller { + compatible = "qcom,msm8937-rpmpd", "qcom,msm8917-rpmpd"; + #power-domain-cells = <1>; + operating-points-v2 = <&rpmpd_opp_table>; + + rpmpd_opp_table: opp-table { + compatible = "operating-points-v2"; + + rpmpd_opp_ret: opp1 { + opp-level = ; + }; + + rpmpd_opp_ret_plus: opp2 { + opp-level = ; + }; + + rpmpd_opp_min_svs: opp3 { + opp-level = ; + }; + + rpmpd_opp_low_svs: opp4 { + opp-level = ; + }; + + rpmpd_opp_svs: opp5 { + opp-level = ; + }; + + rpmpd_opp_svs_plus: opp6 { + opp-level = ; + }; + + rpmpd_opp_nom: opp7 { + opp-level = ; + }; + + rpmpd_opp_nom_plus: opp8 { + opp-level = ; + }; + + rpmpd_opp_turbo: opp9 { + opp-level = ; + }; + }; + }; + }; + }; + }; + + smp2p-adsp { + compatible = "qcom,smp2p"; + qcom,smem = <443>, <429>; + + interrupts = ; + + mboxes = <&apcs1 10>; + + qcom,local-pid = <0>; + qcom,remote-pid = <2>; + + adsp_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + + #qcom,smem-state-cells = <1>; + }; + + adsp_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smp2p-modem { + compatible = "qcom,smp2p"; + qcom,smem = <435>, <428>; + + interrupts = ; + + mboxes = <&apcs1 14>; + + qcom,local-pid = <0>; + qcom,remote-pid = <1>; + + modem_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + + #qcom,smem-state-cells = <1>; + }; + + modem_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smp2p-wcnss { + compatible = "qcom,smp2p"; + qcom,smem = <451>, <431>; + + interrupts = ; + + mboxes = <&apcs1 18>; + + qcom,local-pid = <0>; + qcom,remote-pid = <4>; + + wcnss_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + + #qcom,smem-state-cells = <1>; + }; + + wcnss_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smsm { + compatible = "qcom,smsm"; + + #address-cells = <1>; + #size-cells = <0>; + + mboxes = <0>, <&apcs1 13>, <0>, <&apcs1 19>; + + apps_smsm: apps@0 { + reg = <0>; + + #qcom,smem-state-cells = <1>; + }; + + hexagon_smsm: hexagon@1 { + reg = <1>; + interrupts = ; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + wcnss_smsm: wcnss@6 { + reg = <6>; + interrupts = ; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + soc: soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xffffffff>; + #address-cells = <1>; + #size-cells = <1>; + + qfprom: qfprom@a4000 { + compatible = "qcom,msm8937-qfprom", "qcom,qfprom"; + reg = <0x000a4000 0x3000>; + #address-cells = <1>; + #size-cells = <1>; + + tsens_base1: base1@1d8 { + reg = <0x1d8 0x1>; + bits = <0 8>; + }; + + tsens_s5_p1: s5-p1@1d9 { + reg = <0x1d9 0x1>; + bits = <0 6>; + }; + + tsens_s5_p2: s5-p2@1d9 { + reg = <0x1d9 0x2>; + bits = <6 6>; + }; + + tsens_s6_p1: s6-p1@1da { + reg = <0x1da 0x2>; + bits = <4 6>; + }; + + tsens_s6_p2: s6-p2@1db { + reg = <0x1db 0x1>; + bits = <2 6>; + }; + + tsens_s7_p1: s7-p1@1dc { + reg = <0x1dc 0x1>; + bits = <0 6>; + }; + + tsens_s7_p2: s7-p2@1dc { + reg = <0x1dc 0x2>; + bits = <6 6>; + }; + + tsens_s8_p1: s8-p1@1dd { + reg = <0x1dd 0x2>; + bits = <4 6>; + }; + + tsens_s8_p2: s8-p2@1de { + reg = <0x1de 0x1>; + bits = <2 6>; + }; + + tsens_base2: base2@1df { + reg = <0x1df 0x1>; + bits = <0 8>; + }; + + tsens_mode: mode@210 { + reg = <0x210 0x1>; + bits = <0 3>; + }; + + tsens_s0_p1: s0-p1@210 { + reg = <0x210 0x2>; + bits = <3 6>; + }; + + tsens_s0_p2: s0-p2@211 { + reg = <0x211 0x1>; + bits = <1 6>; + }; + + tsens_s1_p1: s1-p1@211 { + reg = <0x211 0x2>; + bits = <7 6>; + }; + + tsens_s1_p2: s1-p2@212 { + reg = <0x212 0x2>; + bits = <5 6>; + }; + + tsens_s2_p1: s2-p1@213 { + reg = <0x213 0x2>; + bits = <3 6>; + }; + + tsens_s2_p2: s2-p2@214 { + reg = <0x214 0x1>; + bits = <1 6>; + }; + + tsens_s3_p1: s3-p1@214 { + reg = <0x214 0x2>; + bits = <7 6>; + }; + + tsens_s3_p2: s3-p2@215 { + reg = <0x215 0x2>; + bits = <5 6>; + }; + + tsens_s4_p1: s4-p1@216 { + reg = <0x216 0x2>; + bits = <3 6>; + }; + + tsens_s4_p2: s4-p2@217 { + reg = <0x217 0x1>; + bits = <1 6>; + }; + + tsens_s9_p1: s9-p1@230 { + reg = <0x230 0x1>; + bits = <0 6>; + }; + + tsens_s9_p2: s9-p2@230 { + reg = <0x230 0x2>; + bits = <6 6>; + }; + + tsens_s10_p1: s10-p1@231 { + reg = <0x231 0x2>; + bits = <4 6>; + }; + + tsens_s10_p2: s10-p2@232 { + reg = <0x232 0x1>; + bits = <2 6>; + }; + + gpu_speed_bin: gpu-speed-bin@201b { + reg = <0x201b 0x1>; + bits = <7 1>; + }; + }; + + rpm_msg_ram: sram@60000 { + compatible = "qcom,rpm-msg-ram"; + reg = <0x00060000 0x8000>; + }; + + usb_hs_phy: phy@6c000 { + compatible = "qcom,usb-hs-28nm-femtophy"; + reg = <0x0006c000 0x200>; + #phy-cells = <0>; + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, + <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, + <&gcc GCC_USB2A_PHY_SLEEP_CLK>; + clock-names = "ref", + "ahb", + "sleep"; + resets = <&gcc GCC_QUSB2_PHY_BCR>, + <&gcc GCC_USB2_HS_PHY_ONLY_BCR>; + reset-names = "phy", + "por"; + status = "disabled"; + }; + + rng@e3000 { + compatible = "qcom,prng"; + reg = <0x000e3000 0x1000>; + clocks = <&gcc GCC_PRNG_AHB_CLK>; + clock-names = "core"; + }; + + tsens: thermal-sensor@4a9000 { + compatible = "qcom,msm8937-tsens", "qcom,tsens-v1"; + reg = <0x004a9000 0x1000>, + <0x004a8000 0x1000>; + interrupts = ; + interrupt-names = "uplow"; + nvmem-cells = <&tsens_mode>, + <&tsens_base1>, <&tsens_base2>, + <&tsens_s0_p1>, <&tsens_s0_p2>, + <&tsens_s1_p1>, <&tsens_s1_p2>, + <&tsens_s2_p1>, <&tsens_s2_p2>, + <&tsens_s3_p1>, <&tsens_s3_p2>, + <&tsens_s4_p1>, <&tsens_s4_p2>, + <&tsens_s5_p1>, <&tsens_s5_p2>, + <&tsens_s6_p1>, <&tsens_s6_p2>, + <&tsens_s7_p1>, <&tsens_s7_p2>, + <&tsens_s8_p1>, <&tsens_s8_p2>, + <&tsens_s9_p1>, <&tsens_s9_p2>, + <&tsens_s10_p1>, <&tsens_s10_p2>; + nvmem-cell-names = "mode", + "base1", "base2", + "s0_p1", "s0_p2", + "s1_p1", "s1_p2", + "s2_p1", "s2_p2", + "s3_p1", "s3_p2", + "s4_p1", "s4_p2", + "s5_p1", "s5_p2", + "s6_p1", "s6_p2", + "s7_p1", "s7_p2", + "s8_p1", "s8_p2", + "s9_p1", "s9_p2", + "s10_p1", "s10_p2"; + #qcom,sensors = <11>; + #thermal-sensor-cells = <1>; + }; + + restart@4ab000 { + compatible = "qcom,pshold"; + reg = <0x004ab000 0x4>; + }; + + tlmm: pinctrl@1000000 { + compatible = "qcom,msm8917-pinctrl"; + reg = <0x01000000 0x300000>; + interrupts = ; + gpio-controller; + gpio-ranges = <&tlmm 0 0 134>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + + blsp1_i2c2_default: blsp1-i2c2-default-state { + pins = "gpio6", "gpio7"; + function = "blsp_i2c2"; + drive-strength = <2>; + bias-disable; + }; + + blsp1_i2c2_sleep: blsp1-i2c2-sleep-state { + pins = "gpio6", "gpio7"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + blsp1_i2c3_default: blsp1-i2c3-default-state { + pins = "gpio10", "gpio11"; + function = "blsp_i2c3"; + drive-strength = <2>; + bias-disable; + }; + + blsp1_i2c3_sleep: blsp1-i2c3-sleep-state { + pins = "gpio10", "gpio11"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + blsp1_i2c4_default: blsp1-i2c4-default-state { + pins = "gpio14", "gpio15"; + function = "blsp_i2c4"; + drive-strength = <2>; + bias-disable; + }; + + blsp1_i2c4_sleep: blsp1-i2c4-sleep-state { + pins = "gpio14", "gpio15"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + blsp2_i2c1_default: blsp2-i2c1-default-state { + pins = "gpio18", "gpio19"; + function = "blsp_i2c5"; + drive-strength = <2>; + bias-disable; + }; + + blsp2_i2c1_sleep: blsp2-i2c1-sleep-state { + pins = "gpio18", "gpio19"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + blsp1_spi3_default: blsp1-spi3-default-state { + cs-pins { + pins = "gpio10"; + function = "blsp_spi3"; + drive-strength = <2>; + bias-disable; + }; + + spi-pins { + pins = "gpio8", "gpio9", "gpio11"; + function = "blsp_spi3"; + drive-strength = <12>; + bias-disable; + }; + }; + + blsp1_spi3_sleep: blsp1-spi3-sleep-state { + cs-pins { + pins = "gpio10"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + spi-pins { + pins = "gpio8", "gpio9", "gpio11"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + blsp2_spi2_default: blsp2-spi2-default-state { + cs0-pins { + pins = "gpio47"; + function = "blsp_spi6"; + drive-strength = <16>; + bias-disable; + }; + + cs1-pins { + pins = "gpio22"; + function = "blsp_spi6"; + drive-strength = <16>; + bias-disable; + }; + + spi-pins { + pins = "gpio20", "gpio21", "gpio23"; + function = "blsp_spi6"; + drive-strength = <16>; + bias-disable; + }; + }; + + blsp2_spi2_sleep: blsp2-spi2-sleep-state { + cs0-pins { + pins = "gpio47"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + cs1-pins { + pins = "gpio22"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + spi-pins { + pins = "gpio20", "gpio21", "gpio23"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + blsp1_uart1_default: blsp1-uart1-default-state { + pins = "gpio0", "gpio1", "gpio2", "gpio3"; + function = "blsp_uart1"; + drive-strength = <2>; + bias-disable; + }; + + blsp1_uart1_sleep: blsp1-uart1-sleep-state { + pins = "gpio0", "gpio1", "gpio2", "gpio3"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + blsp1_uart2_default: blsp1-uart2-default-state { + pins = "gpio4", "gpio5"; + function = "blsp_uart2"; + drive-strength = <2>; + bias-disable; + }; + + blsp1_uart2_sleep: blsp1-uart2-sleep-state { + pins = "gpio4", "gpio5"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + sdc1_default: sdc1-default-state { + clk-pins { + pins = "sdc1_clk"; + drive-strength = <16>; + bias-disable; + }; + + cmd-pins { + pins = "sdc1_cmd"; + drive-strength = <10>; + bias-pull-up; + }; + + data-pins { + pins = "sdc1_data"; + drive-strength = <10>; + bias-pull-up; + }; + + rclk-pins { + pins = "sdc1_rclk"; + bias-pull-down; + }; + }; + + sdc1_sleep: sdc1-sleep-state { + clk-pins { + pins = "sdc1_clk"; + drive-strength = <2>; + bias-disable; + }; + + cmd-pins { + pins = "sdc1_cmd"; + drive-strength = <2>; + bias-pull-up; + }; + + data-pins { + pins = "sdc1_data"; + drive-strength = <2>; + bias-pull-up; + }; + + rclk-pins { + pins = "sdc1_rclk"; + bias-pull-down; + }; + }; + + sdc2_default: sdc2-default-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <16>; + bias-disable; + }; + + sdc2_cmd_default: cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <16>; + bias-pull-up; + }; + + sdc2_data_default: data-pins { + pins = "sdc2_data"; + drive-strength = <16>; + bias-pull-up; + }; + }; + + sdc2_sleep: sdc2-sleep-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <2>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <2>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + wcnss_pin_a: wcnss-active-state { + wcss-wlan-pins { + pins = "gpio79", "gpio80"; + function = "wcss_wlan"; + drive-strength = <6>; + bias-pull-up; + + }; + + wcss-wlan0-pins { + pins = "gpio78"; + function = "wcss_wlan0"; + drive-strength = <6>; + bias-pull-up; + + }; + + wcss-wlan1-pins { + pins = "gpio77"; + function = "wcss_wlan1"; + drive-strength = <6>; + bias-pull-up; + + }; + + wcss-wlan2-pins { + pins = "gpio76"; + function = "wcss_wlan2"; + drive-strength = <6>; + bias-pull-up; + + }; + }; + }; + + gcc: clock-controller@1800000 { + compatible = "qcom,gcc-msm8937"; + reg = <0x01800000 0x80000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, + <&sleep_clk>, + <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>, + <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>, + <&mdss_dsi1_phy DSI_PIXEL_PLL_CLK>, + <&mdss_dsi1_phy DSI_BYTE_PLL_CLK>; + clock-names = "xo", + "sleep", + "dsi0pll", + "dsi0pllbyte", + "dsi1pll", + "dsi1pllbyte"; + }; + + tcsr_mutex: hwlock@1905000 { + compatible = "qcom,tcsr-mutex"; + reg = <0x01905000 0x20000>; + #hwlock-cells = <1>; + }; + + tcsr: syscon@1937000 { + compatible = "qcom,tcsr-msm8937", "syscon"; + reg = <0x01937000 0x30000>; + }; + + mdss: display-subsystem@1a00000 { + compatible = "qcom,mdss"; + reg = <0x01a00000 0x1000>, + <0x01ab0000 0x3000>; + reg-names = "mdss_phys", + "vbif_phys"; + ranges; + + power-domains = <&gcc MDSS_GDSC>; + + clocks = <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_AXI_CLK>, + <&gcc GCC_MDSS_VSYNC_CLK>; + clock-names = "iface", + "bus", + "vsync"; + interrupts = ; + + interrupt-controller; + #interrupt-cells = <1>; + + #address-cells = <1>; + #size-cells = <1>; + + status = "disabled"; + + mdp: display-controller@1a01000 { + compatible = "qcom,msm8937-mdp5", "qcom,mdp5"; + reg = <0x01a01000 0x89000>; + reg-names = "mdp_phys"; + + interrupt-parent = <&mdss>; + interrupts = <0>; + + clocks = <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_AXI_CLK>, + <&gcc GCC_MDSS_MDP_CLK>, + <&gcc GCC_MDSS_VSYNC_CLK>; + clock-names = "iface", + "bus", + "core", + "vsync"; + + iommus = <&apps_iommu 0x15>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mdp5_intf1_out: endpoint { + remote-endpoint = <&mdss_dsi0_in>; + }; + }; + + port@1 { + reg = <1>; + mdp5_intf2_out: endpoint { + remote-endpoint = <&mdss_dsi1_in>; + }; + }; + }; + }; + + mdss_dsi0: dsi@1a94000 { + compatible = "qcom,mdss-dsi-ctrl"; + reg = <0x01a94000 0x300>; + reg-names = "dsi_ctrl"; + + interrupt-parent = <&mdss>; + interrupts = <4>; + + assigned-clocks = <&gcc BYTE0_CLK_SRC>, + <&gcc PCLK0_CLK_SRC>; + assigned-clock-parents = <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>, + <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>; + + clocks = <&gcc GCC_MDSS_MDP_CLK>, + <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_AXI_CLK>, + <&gcc GCC_MDSS_BYTE0_CLK>, + <&gcc GCC_MDSS_PCLK0_CLK>, + <&gcc GCC_MDSS_ESC0_CLK>; + clock-names = "mdp_core", + "iface", + "bus", + "byte", + "pixel", + "core"; + phys = <&mdss_dsi0_phy>; + + operating-points-v2 = <&mdss_dsi0_opp_table>; + power-domains = <&rpmpd MSM8937_VDDCX>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mdss_dsi0_in: endpoint { + remote-endpoint = <&mdp5_intf1_out>; + }; + }; + + port@1 { + reg = <1>; + mdss_dsi0_out: endpoint { + }; + }; + }; + + mdss_dsi0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-125000000 { + opp-hz = /bits/ 64 <125000000>; + required-opps = <&rpmpd_opp_svs>; + }; + + opp-187500000 { + opp-hz = /bits/ 64 <187500000>; + required-opps = <&rpmpd_opp_nom>; + }; + }; + }; + + mdss_dsi0_phy: phy@1a94400 { + compatible = "qcom,dsi-phy-28nm-8937"; + reg = <0x01a94a00 0xd4>, + <0x01a94400 0x280>, + <0x01a94b80 0x30>; + reg-names = "dsi_pll", + "dsi_phy", + "dsi_phy_regulator"; + + #clock-cells = <1>; + #phy-cells = <0>; + + clocks = <&gcc GCC_MDSS_AHB_CLK>, + <&rpmcc RPM_SMD_XO_CLK_SRC>; + clock-names = "iface", + "ref"; + + status = "disabled"; + }; + + mdss_dsi1: dsi@1a96000 { + compatible = "qcom,mdss-dsi-ctrl"; + reg = <0x01a96000 0x300>; + reg-names = "dsi_ctrl"; + + interrupt-parent = <&mdss>; + interrupts = <4>; + + assigned-clocks = <&gcc MSM8937_BYTE1_CLK_SRC>, + <&gcc MSM8937_PCLK1_CLK_SRC>; + assigned-clock-parents = <&mdss_dsi1_phy DSI_BYTE_PLL_CLK>, + <&mdss_dsi1_phy DSI_PIXEL_PLL_CLK>; + + clocks = <&gcc GCC_MDSS_MDP_CLK>, + <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_AXI_CLK>, + <&gcc MSM8937_GCC_MDSS_BYTE1_CLK>, + <&gcc MSM8937_GCC_MDSS_PCLK1_CLK>, + <&gcc MSM8937_GCC_MDSS_ESC1_CLK>; + clock-names = "mdp_core", + "iface", + "bus", + "byte", + "pixel", + "core"; + phys = <&mdss_dsi1_phy>; + + operating-points-v2 = <&mdss_dsi1_opp_table>; + power-domains = <&rpmpd MSM8937_VDDCX>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mdss_dsi1_in: endpoint { + remote-endpoint = <&mdp5_intf2_out>; + }; + }; + + port@1 { + reg = <1>; + mdss_dsi1_out: endpoint { + }; + }; + }; + + mdss_dsi1_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-125000000 { + opp-hz = /bits/ 64 <125000000>; + required-opps = <&rpmpd_opp_svs>; + }; + + opp-187500000 { + opp-hz = /bits/ 64 <187500000>; + required-opps = <&rpmpd_opp_nom>; + }; + }; + }; + + mdss_dsi1_phy: phy@1a96a00 { + compatible = "qcom,dsi-phy-28nm-8937"; + reg = <0x01a96a00 0xd4>, + <0x01a96400 0x280>, + <0x01a94b80 0x30>; + reg-names = "dsi_pll", + "dsi_phy", + "dsi_phy_regulator"; + + #clock-cells = <1>; + #phy-cells = <0>; + + clocks = <&gcc GCC_MDSS_AHB_CLK>, + <&rpmcc RPM_SMD_XO_CLK_SRC>; + clock-names = "iface", + "ref"; + + status = "disabled"; + }; + }; + + gpu: gpu@1c00000 { + compatible = "qcom,adreno-505.0", "qcom,adreno"; + reg = <0x01c00000 0x40000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = ; + interrupt-names = "kgsl_3d0_irq"; + #cooling-cells = <2>; + clocks = <&gcc GCC_OXILI_GFX3D_CLK>, + <&gcc GCC_OXILI_AHB_CLK>, + <&gcc GCC_BIMC_GFX_CLK>, + <&gcc GCC_BIMC_GPU_CLK>, + <&gcc MSM8937_GCC_OXILI_TIMER_CLK>, + <&gcc MSM8937_GCC_OXILI_AON_CLK>; + clock-names = "core", + "iface", + "mem_iface", + "alt_mem_iface", + "rbbmtimer", + "alwayson"; + operating-points-v2 = <&gpu_opp_table>; + power-domains = <&gcc OXILI_GX_GDSC>; + + iommus = <&adreno_smmu 0>; + + nvmem-cells = <&gpu_speed_bin>; + nvmem-cell-names = "speed_bin"; + + status = "disabled"; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-19200000 { + opp-hz = /bits/ 64 <19200000>; + opp-supported-hw = <0xff>; + required-opps = <&rpmpd_opp_min_svs>; + }; + + opp-216000000 { + opp-hz = /bits/ 64 <216000000>; + opp-supported-hw = <0xff>; + required-opps = <&rpmpd_opp_svs>; + }; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-supported-hw = <0xff>; + required-opps = <&rpmpd_opp_svs_plus>; + }; + + opp-375000000 { + opp-hz = /bits/ 64 <375000000>; + opp-supported-hw = <0xff>; + required-opps = <&rpmpd_opp_nom>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-supported-hw = <0xff>; + required-opps = <&rpmpd_opp_nom_plus>; + }; + + opp-450000000 { + opp-hz = /bits/ 64 <450000000>; + opp-supported-hw = <0xff>; + required-opps = <&rpmpd_opp_turbo>; + }; + }; + }; + + adreno_smmu: iommu@1c40000 { + compatible = "qcom,msm8996-smmu-v2", + "qcom,adreno-smmu", + "qcom,smmu-v2"; + reg = <0x01c40000 0x10000>; + + #global-interrupts = <1>; + interrupts = , + , + , + , + ; + #iommu-cells = <1>; + + clocks = <&gcc GCC_BIMC_GFX_CLK>, + <&gcc GCC_OXILI_AHB_CLK>; + clock-names = "bus", + "iface"; + + power-domains = <&gcc MSM8937_OXILI_CX_GDSC>; + }; + + apps_iommu: iommu@1e20000 { + compatible = "qcom,msm8937-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x01e20000 0x20000>; + + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_APSS_TCU_CLK>; + clock-names = "iface", + "bus"; + + qcom,iommu-secure-id = <17>; + + #address-cells = <1>; + #iommu-cells = <1>; + #size-cells = <1>; + + /* VFE */ + iommu-ctx@14000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x14000 0x1000>; + interrupts = ; + }; + + /* MDP_0 */ + iommu-ctx@15000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x15000 0x1000>; + interrupts = ; + }; + + /* VENUS_NS */ + iommu-ctx@16000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x16000 0x1000>; + interrupts = ; + }; + }; + + spmi_bus: spmi@200f000 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0x0200f000 0x001000>, + <0x02400000 0x800000>, + <0x02c00000 0x800000>, + <0x03800000 0x200000>, + <0x0200a000 0x002100>; + reg-names = "core", + "chnls", + "obsrvr", + "intr", + "cnfg"; + interrupt-names = "periph_irq"; + interrupts = ; + qcom,ee = <0>; + qcom,channel = <0>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <4>; + }; + + bam_dmux_dma: dma-controller@4044000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0x04044000 0x19000>; + interrupts = ; + #dma-cells = <1>; + qcom,ee = <0>; + + num-channels = <6>; + qcom,num-ees = <1>; + qcom,powered-remotely; + + status = "disabled"; + }; + + sdhc_1: mmc@7824900 { + compatible = "qcom,sdhci-msm-v4"; + reg = <0x07824900 0x500>, + <0x07824000 0x800>; + reg-names = "hc", + "core"; + + interrupts = , + ; + interrupt-names = "hc_irq", + "pwr_irq"; + clocks = <&gcc GCC_SDCC1_AHB_CLK>, + <&gcc GCC_SDCC1_APPS_CLK>, + <&rpmcc RPM_SMD_XO_CLK_SRC>; + clock-names = "iface", + "core", + "xo"; + pinctrl-0 = <&sdc1_default>; + pinctrl-1 = <&sdc1_sleep>; + pinctrl-names = "default", + "sleep"; + power-domains = <&rpmpd MSM8937_VDDCX>; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + mmc-ddr-1_8v; + bus-width = <8>; + non-removable; + status = "disabled"; + }; + + sdhc_2: mmc@7864900 { + compatible = "qcom,sdhci-msm-v4"; + reg = <0x07864900 0x500>, + <0x07864000 0x800>; + reg-names = "hc", + "core"; + + interrupts = , + ; + interrupt-names = "hc_irq", + "pwr_irq"; + clocks = <&gcc GCC_SDCC2_AHB_CLK>, + <&gcc GCC_SDCC2_APPS_CLK>, + <&rpmcc RPM_SMD_XO_CLK_SRC>; + clock-names = "iface", + "core", + "xo"; + pinctrl-0 = <&sdc2_default>; + pinctrl-1 = <&sdc2_sleep>; + pinctrl-names = "default", + "sleep"; + power-domains = <&rpmpd MSM8937_VDDCX>; + bus-width = <4>; + status = "disabled"; + }; + + blsp1_dma: dma-controller@7884000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0x07884000 0x1f000>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "bam_clk"; + qcom,controlled-remotely; + #dma-cells = <1>; + num-channels = <12>; + qcom,num-ees = <4>; + qcom,ee = <0>; + }; + + blsp1_uart2: serial@78b0000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x078b0000 0x200>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", + "iface"; + dmas = <&blsp1_dma 2>, + <&blsp1_dma 3>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&blsp1_uart2_default>; + pinctrl-1 = <&blsp1_uart2_sleep>; + pinctrl-names = "default", + "sleep"; + status = "disabled"; + }; + + blsp1_i2c2: i2c@78b6000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x078b6000 0x600>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp1_dma 6>, + <&blsp1_dma 7>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&blsp1_i2c2_default>; + pinctrl-1 = <&blsp1_i2c2_sleep>; + pinctrl-names = "default", + "sleep"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp1_i2c3: i2c@78b7000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x078b7000 0x600>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", + "iface"; + dmas = <&blsp1_dma 8>, + <&blsp1_dma 9>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&blsp1_i2c3_default>; + pinctrl-1 = <&blsp1_i2c3_sleep>; + pinctrl-names = "default", + "sleep"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp1_spi3: spi@78b7000 { + compatible = "qcom,spi-qup-v2.2.1"; + reg = <0x078b7000 0x600>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_QUP3_SPI_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", + "iface"; + dmas = <&blsp1_dma 8>, + <&blsp1_dma 9>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&blsp1_spi3_default>; + pinctrl-1 = <&blsp1_spi3_sleep>; + pinctrl-names = "default", + "sleep"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp1_i2c4: i2c@78b8000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x078b8000 0x500>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", + "iface"; + dmas = <&blsp1_dma 10>, + <&blsp1_dma 11>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&blsp1_i2c4_default>; + pinctrl-1 = <&blsp1_i2c4_sleep>; + pinctrl-names = "default", + "sleep"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp2_dma: dma-controller@7ac4000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0x07ac4000 0x1d000>; + interrupts = ; + clocks = <&gcc GCC_BLSP2_AHB_CLK>; + clock-names = "bam_clk"; + qcom,controlled-remotely; + #dma-cells = <1>; + num-channels = <10>; + qcom,num-ees = <4>; + qcom,ee = <0>; + }; + + blsp2_i2c1: i2c@7af5000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x07af5000 0x600>; + interrupts = ; + clocks = <&gcc GCC_BLSP2_QUP1_I2C_APPS_CLK>, + <&gcc GCC_BLSP2_AHB_CLK>; + clock-names = "core", + "iface"; + dmas = <&blsp2_dma 4>, + <&blsp2_dma 5>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&blsp2_i2c1_default>; + pinctrl-1 = <&blsp2_i2c1_sleep>; + pinctrl-names = "default", + "sleep"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp2_spi2: spi@7af6000 { + compatible = "qcom,spi-qup-v2.2.1"; + reg = <0x07af6000 0x600>; + interrupts = ; + clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, + <&gcc GCC_BLSP2_AHB_CLK>; + clock-names = "core", + "iface"; + dmas = <&blsp2_dma 6>, + <&blsp2_dma 7>; + dma-names = "tx", + "rx"; + pinctrl-0 = <&blsp2_spi2_default>; + pinctrl-1 = <&blsp2_spi2_sleep>; + pinctrl-names = "default", + "sleep"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + usb: usb@78db000 { + compatible = "qcom,ci-hdrc"; + reg = <0x078db000 0x200>, + <0x078db200 0x200>; + interrupts = , + ; + clocks = <&gcc GCC_USB_HS_AHB_CLK>, + <&gcc GCC_USB_HS_SYSTEM_CLK>; + clock-names = "iface", + "core"; + assigned-clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>; + assigned-clock-rates = <80000000>; + resets = <&gcc GCC_USB_HS_BCR>; + reset-names = "core"; + phy_type = "ulpi"; + dr_mode = "otg"; + hnp-disable; + srp-disable; + adp-disable; + ahb-burst-config = <0>; + phy-names = "usb-phy"; + phys = <&usb_hs_phy>; + status = "disabled"; + #reset-cells = <1>; + }; + + wcnss: remoteproc@a204000 { + compatible = "qcom,pronto-v3-pil", "qcom,pronto"; + reg = <0x0a204000 0x2000>, + <0x0a202000 0x1000>, + <0x0a21b000 0x3000>; + reg-names = "ccu", + "dxe", + "pmu"; + + memory-region = <&wcnss_mem>; + + interrupts-extended = <&intc GIC_SPI 149 IRQ_TYPE_EDGE_RISING>, + <&wcnss_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&wcnss_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&wcnss_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&wcnss_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack"; + + power-domains = <&rpmpd MSM8937_VDDCX>, + <&rpmpd MSM8937_VDDMX>; + power-domain-names = "cx", + "mx"; + + qcom,smem-states = <&wcnss_smp2p_out 0>; + qcom,smem-state-names = "stop"; + + pinctrl-0 = <&wcnss_pin_a>; + pinctrl-names = "default"; + + status = "disabled"; + + wcnss_iris: iris { + clocks = <&rpmcc RPM_SMD_RF_CLK2>; + clock-names = "xo"; + }; + + smd-edge { + interrupts = ; + + mboxes = <&apcs1 17>; + qcom,smd-edge = <6>; + qcom,remote-pid = <4>; + + label = "pronto"; + + wcnss_ctrl: wcnss { + compatible = "qcom,wcnss"; + qcom,smd-channels = "WCNSS_CTRL"; + + qcom,mmio = <&wcnss>; + + wcnss_bt: bluetooth { + compatible = "qcom,wcnss-bt"; + }; + + wcnss_wifi: wifi { + compatible = "qcom,wcnss-wlan"; + + interrupts = , + ; + interrupt-names = "tx", + "rx"; + + qcom,smem-states = <&apps_smsm 10>, <&apps_smsm 9>; + qcom,smem-state-names = "tx-enable", + "tx-rings-empty"; + }; + }; + }; + }; + + intc: interrupt-controller@b000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x0b000000 0x1000>, + <0x0b002000 0x1000>; + }; + + apcs1: mailbox@b011000 { + compatible = "qcom,msm8939-apcs-kpss-global", "syscon"; + reg = <0x0b011000 0x1000>; + #mbox-cells = <1>; + }; + + watchdog@b017000 { + compatible = "qcom,apss-wdt-qcs404", "qcom,kpss-wdt"; + reg = <0x0b017000 0x1000>; + clocks = <&sleep_clk>; + }; + + timer@b120000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0b120000 0x1000>; + ranges; + #address-cells = <1>; + #size-cells = <1>; + + frame@b121000 { + reg = <0x0b121000 0x1000>, + <0x0b122000 0x1000>; + frame-number = <0>; + interrupts = , + ; + }; + + frame@b123000 { + reg = <0x0b123000 0x1000>; + frame-number = <1>; + interrupts = ; + status = "disabled"; + }; + + frame@b124000 { + reg = <0x0b124000 0x1000>; + frame-number = <2>; + interrupts = ; + status = "disabled"; + }; + + frame@b125000 { + reg = <0x0b125000 0x1000>; + frame-number = <3>; + interrupts = ; + status = "disabled"; + }; + + frame@b126000 { + reg = <0x0b126000 0x1000>; + frame-number = <4>; + interrupts = ; + status = "disabled"; + }; + + frame@b127000 { + reg = <0x0b127000 0x1000>; + frame-number = <5>; + interrupts = ; + status = "disabled"; + }; + + frame@b128000 { + reg = <0x0b128000 0x1000>; + frame-number = <6>; + interrupts = ; + status = "disabled"; + }; + }; + }; + + thermal_zones: thermal-zones { + aoss-thermal { + thermal-sensors = <&tsens 0>; + + trips { + aoss_alert0: trip-point0 { + temperature = <85000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + mdm-core-thermal { + thermal-sensors = <&tsens 1>; + + trips { + mdm_core_alert0: trip-point0 { + temperature = <85000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + q6-thermal { + thermal-sensors = <&tsens 2>; + + trips { + q6_alert0: trip-point0 { + temperature = <85000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + camera-thermal { + thermal-sensors = <&tsens 3>; + + trips { + camera_alert0: trip-point0 { + temperature = <85000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpuss1-thermal { + thermal-sensors = <&tsens 4>; + + cooling-maps { + map0 { + trip = <&cpuss1_alert0>; + cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + cpuss1_alert0: trip-point0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpuss1_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpuss1_crit: cpuss1-crit { + temperature = <100000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu4-thermal { + thermal-sensors = <&tsens 5>; + + cooling-maps { + map0 { + trip = <&cpu4_alert1>; + cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + cpu4_alert0: trip-point0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu4_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu4_crit: cpu-crit { + temperature = <100000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu5-thermal { + thermal-sensors = <&tsens 6>; + + cooling-maps { + map0 { + trip = <&cpu5_alert1>; + cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + cpu5_alert0: trip-point0 { + temperature = <75000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu5_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu5_crit: cpu-crit { + temperature = <100000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu6-thermal { + thermal-sensors = <&tsens 7>; + + cooling-maps { + map0 { + trip = <&cpu6_alert1>; + cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + cpu6_alert0: trip-point0 { + temperature = <75000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu6_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu6_crit: cpu-crit { + temperature = <100000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu7-thermal { + thermal-sensors = <&tsens 8>; + + cooling-maps { + map0 { + trip = <&cpu7_alert1>; + cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + cpu7_alert0: trip-point0 { + temperature = <75000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu7_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu7_crit: cpu-crit { + temperature = <100000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpuss0-thermal { + thermal-sensors = <&tsens 9>; + + cooling-maps { + map0 { + trip = <&cpuss0_alert0>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + cpuss0_alert0: trip-point0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpuss0_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpuss0_crit: cpuss0-crit { + temperature = <100000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <250>; + + thermal-sensors = <&tsens 10>; + + cooling-maps { + map0 { + trip = <&gpu_alert>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + gpu_alert: trip-point0 { + temperature = <70000>; + hysteresis = <2000>; + type = "passive"; + }; + + gpu_crit: gpu-crit { + temperature = <90000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; +}; + diff --git a/arch/arm64/boot/dts/qcom/msm8939-asus-z00t.dts b/arch/arm64/boot/dts/qcom/msm8939-asus-z00t.dts new file mode 100644 index 0000000000000..ebb548e62e02b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8939-asus-z00t.dts @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/dts-v1/; + +#include "msm8939-pm8916.dtsi" +#include "msm8916-modem-qdsp6.dtsi" + +#include +#include +#include + +/ { + model = "Asus ZenFone 2 Laser/Selfie (1080p)"; + compatible = "asus,z00t", "qcom,msm8939"; + chassis-type = "handset"; + + aliases { + mmc0 = &sdhc_1; + mmc1 = &sdhc_2; + serial0 = &blsp_uart2; + }; + + chosen { + stdout-path = "serial0"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&gpio_keys_default>; + pinctrl-names = "default"; + + button-volume-up { + label = "Volume Up"; + gpios = <&tlmm 107 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <15>; + }; + + button-volume-down { + label = "Volume Down"; + gpios = <&tlmm 117 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <15>; + }; + }; + + reg_sd_vmmc: regulator-sdcard-vmmc { + compatible = "regulator-fixed"; + regulator-name = "sdcard-vmmc"; + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + + gpio = <&tlmm 87 GPIO_ACTIVE_HIGH>; + enable-active-high; + + startup-delay-us = <200>; + + pinctrl-0 = <&sd_vmmc_en_default>; + pinctrl-names = "default"; + }; + + usb_id: usb-id { + compatible = "linux,extcon-usb-gpio"; + id-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&usb_id_default>; + pinctrl-names = "default"; + }; +}; + +&blsp_i2c2 { + status = "okay"; + + magnetometer@c { + compatible = "asahi-kasei,ak09911"; + reg = <0x0c>; + + vdd-supply = <&pm8916_l8>; + vid-supply = <&pm8916_l6>; + + reset-gpios = <&tlmm 112 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&mag_reset_default>; + pinctrl-names = "default"; + }; + + imu@68 { + compatible = "invensense,mpu6515"; + reg = <0x68>; + + interrupts-extended = <&tlmm 36 IRQ_TYPE_EDGE_RISING>; + + vdd-supply = <&pm8916_l8>; + vddio-supply = <&pm8916_l6>; + + pinctrl-0 = <&imu_default>; + pinctrl-names = "default"; + + mount-matrix = "0", "1", "0", + "-1", "0", "0", + "0", "0", "1"; + }; +}; + +&blsp_i2c5 { + status = "okay"; + + touchscreen@38 { + compatible = "edt,edt-ft5306"; + reg = <0x38>; + + interrupts-extended = <&tlmm 13 IRQ_TYPE_EDGE_FALLING>; + + reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>; + + vcc-supply = <&pm8916_l8>; + iovcc-supply = <&pm8916_l6>; + + touchscreen-size-x = <1080>; + touchscreen-size-y = <1920>; + + pinctrl-0 = <&touchscreen_default>; + pinctrl-names = "default"; + }; +}; + +&blsp_uart2 { + pinctrl-0 = <&blsp_uart2_console_default>; + pinctrl-1 = <&blsp_uart2_console_sleep>; + pinctrl-names = "default", "sleep"; + + status = "okay"; +}; + +&mpss_mem { + reg = <0x0 0x86800000 0x0 0x5500000>; +}; + +&pm8916_codec { + qcom,micbias-lvl = <2800>; + qcom,mbhc-vthreshold-low = <75 150 237 450 500>; + qcom,mbhc-vthreshold-high = <75 150 237 450 500>; + qcom,micbias1-ext-cap; + qcom,hphl-jack-type-normally-open; + + status = "okay"; +}; + +&pm8916_vib { + status = "okay"; +}; + +&sdhc_1 { + status = "okay"; +}; + +&sdhc_2 { + vmmc-supply = <®_sd_vmmc>; + + pinctrl-0 = <&sdc2_default &sdc2_cd_default>; + pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>; + pinctrl-names = "default", "sleep"; + cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; + + status = "okay"; +}; + +&sound { + audio-routing = + "AMIC1", "MIC BIAS External1", + "AMIC2", "MIC BIAS Internal2", + "AMIC3", "MIC BIAS External1"; + + status = "okay"; +}; + +&usb { + extcon = <&usb_id>, <&usb_id>; + + status = "okay"; +}; + +&usb_hs_phy { + extcon = <&usb_id>; +}; + +&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3660b"; +}; + +&wcnss_mem { + status = "okay"; +}; + +&tlmm { + touchscreen_default: touchscreen-default-state { + reset-pins { + pins = "gpio12"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + touch-pins { + pins = "gpio13"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + imu_default: imu-default-state { + pins = "gpio36"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + sdc2_cd_default: sdc2-cd-default-state { + pins = "gpio38"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + sd_vmmc_en_default: sd-vmmc-en-default-state { + pins = "gpio87"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + gpio_keys_default: gpio-keys-default-state { + pins = "gpio107", "gpio117"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + usb_id_default: usb-id-default-state { + pins = "gpio110"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + + mag_reset_default: mag-reset-default-state { + pins = "gpio112"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8996-oneplus3.dts b/arch/arm64/boot/dts/qcom/msm8996-oneplus3.dts index 220eeb31fdc70..0bb9e3d8f7144 100644 --- a/arch/arm64/boot/dts/qcom/msm8996-oneplus3.dts +++ b/arch/arm64/boot/dts/qcom/msm8996-oneplus3.dts @@ -27,10 +27,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/msm8996/oneplus3/a530_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/msm8996/oneplus3/a530_zap.mbn"; }; &mss_pil { diff --git a/arch/arm64/boot/dts/qcom/msm8996-oneplus3t.dts b/arch/arm64/boot/dts/qcom/msm8996-oneplus3t.dts index f772618e80c70..1d7b27c5aff60 100644 --- a/arch/arm64/boot/dts/qcom/msm8996-oneplus3t.dts +++ b/arch/arm64/boot/dts/qcom/msm8996-oneplus3t.dts @@ -28,10 +28,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/msm8996/oneplus3t/a530_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/msm8996/oneplus3t/a530_zap.mbn"; }; &mss_pil { diff --git a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts index bd3f39e1b98fb..3c6a40212a8dc 100644 --- a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts +++ b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts @@ -91,10 +91,8 @@ }; -&gpu { - zap-shader { - firmware-name = "qcom/msm8996/gemini/a530_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/msm8996/gemini/a530_zap.mbn"; }; &mdss_dsi0 { diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index c75b522f6eba6..9d4ce47578fb4 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -1333,7 +1333,7 @@ }; }; - zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&gpu_mem>; }; }; @@ -3496,6 +3496,9 @@ <&gcc GCC_USB20_MASTER_CLK>; assigned-clock-rates = <19200000>, <60000000>; + interconnects = <&pnoc MASTER_USB_HS &bimc SLAVE_EBI_CH0>, + <&bimc MASTER_AMPSS_M0 &pnoc SLAVE_USB_HS>; + interconnect-names = "usb-ddr", "apps-usb"; power-domains = <&gcc USB30_GDSC>; qcom,select-utmi-as-pipe-clk; status = "disabled"; diff --git a/arch/arm64/boot/dts/qcom/msm8996pro-xiaomi-natrium.dts b/arch/arm64/boot/dts/qcom/msm8996pro-xiaomi-natrium.dts index 443599a5a5dd5..f8ab03f106a1b 100644 --- a/arch/arm64/boot/dts/qcom/msm8996pro-xiaomi-natrium.dts +++ b/arch/arm64/boot/dts/qcom/msm8996pro-xiaomi-natrium.dts @@ -39,10 +39,8 @@ }; }; -&gpu { - zap-shader { - firmware-name = "qcom/msm8996/natrium/a530_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/msm8996/natrium/a530_zap.mbn"; }; &mdss_dsi0 { diff --git a/arch/arm64/boot/dts/qcom/msm8996pro-xiaomi-scorpio.dts b/arch/arm64/boot/dts/qcom/msm8996pro-xiaomi-scorpio.dts index 33d84ac541e1c..1cc33c3123a4e 100644 --- a/arch/arm64/boot/dts/qcom/msm8996pro-xiaomi-scorpio.dts +++ b/arch/arm64/boot/dts/qcom/msm8996pro-xiaomi-scorpio.dts @@ -91,10 +91,8 @@ }; }; -&gpu { - zap-shader { - firmware-name = "qcom/msm8996/scorpio/a530_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/msm8996/scorpio/a530_zap.mbn"; }; &mdp_smmu { diff --git a/arch/arm64/boot/dts/qcom/pmi8950.dtsi b/arch/arm64/boot/dts/qcom/pmi8950.dtsi index 3d3b1cd97cc3d..5bd91a5cd1245 100644 --- a/arch/arm64/boot/dts/qcom/pmi8950.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi8950.dtsi @@ -22,19 +22,19 @@ channel@0 { reg = ; - qcom,pre-scaling = <1 4>; + qcom,pre-scaling = <1 20>; label = "usbin"; }; channel@1 { reg = ; - qcom,pre-scaling = <1 4>; + qcom,pre-scaling = <1 20>; label = "dcin"; }; channel@2 { reg = ; - qcom,pre-scaling = <1 1>; + qcom,pre-scaling = <1 3>; label = "vchg_sns"; }; @@ -55,6 +55,14 @@ qcom,pre-scaling = <1 1>; label = "chg_temp"; }; + + channel@e { + reg = ; + }; + + channel@f { + reg = ; + }; }; pmi8950_mpps: mpps@a000 { diff --git a/arch/arm64/boot/dts/qcom/x1p42100.dtsi b/arch/arm64/boot/dts/qcom/purwa.dtsi similarity index 99% rename from arch/arm64/boot/dts/qcom/x1p42100.dtsi rename to arch/arm64/boot/dts/qcom/purwa.dtsi index 10d26958d3c66..2cecd2dd0de8c 100644 --- a/arch/arm64/boot/dts/qcom/x1p42100.dtsi +++ b/arch/arm64/boot/dts/qcom/purwa.dtsi @@ -3,8 +3,8 @@ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. */ -/* X1P42100 is heavily based on X1E80100, with some meaningful differences */ -#include "x1e80100.dtsi" +/* X1P42100 is heavily based on hamoa, with some meaningful differences */ +#include "hamoa.dtsi" /delete-node/ &bwmon_cluster0; /delete-node/ &cluster_pd2; diff --git a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts index 519e458e1a890..455e5c9bb072a 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts @@ -16,7 +16,7 @@ #include #include #include -#include "sc7280.dtsi" +#include "kodiak.dtsi" #include "pm7250b.dtsi" #include "pm7325.dtsi" #include "pm8350c.dtsi" /* PM7350C */ @@ -47,6 +47,8 @@ stride = <(1224 * 4)>; format = "a8r8g8b8"; clocks = <&gcc GCC_DISP_HF_AXI_CLK>; + vci-supply = <&vreg_oled_vci>; + dvdd-supply = <&vreg_oled_dvdd>; }; }; @@ -193,6 +195,19 @@ pinctrl-names = "default"; }; + vreg_vtof_ldo_2p8: regulator-vtof-ldo-2p8 { + compatible = "regulator-fixed"; + regulator-name = "VTOF_LDO_2P8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <233>; + + gpio = <&tlmm 141 GPIO_ACTIVE_HIGH>; + enable-active-high; + + vin-supply = <&vreg_bob>; + }; + reserved-memory { cont_splash_mem: cont-splash@e1000000 { reg = <0x0 0xe1000000 0x0 0x2300000>; @@ -627,6 +642,15 @@ }; &cci0_i2c1 { + camera_imx858_dw9800k: actuator@e { + compatible = "dongwoon,dw9800k"; + reg = <0x0e>; + vdd-supply = <&vreg_afvdd_2p8>; + + dongwoon,sac-mode = <1>; + dongwoon,vcm-prescale = <16>; + }; + /* IMX858 @ 29 */ eeprom@54 { @@ -749,6 +773,8 @@ regulator-name = "vreg_l6p"; regulator-min-microvolt = <1700000>; regulator-max-microvolt = <1904000>; + /* Pull-up for CCI I2C busses */ + regulator-always-on; }; vreg_l7p: ldo7 { @@ -780,7 +806,16 @@ }; }; - /* AW86927FCR haptics @ 5a */ + vibrator@5a { + compatible = "awinic,aw86927"; + reg = <0x5a>; + + interrupts-extended = <&tlmm 101 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&tlmm 100 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&aw86927_int_default>; + pinctrl-names = "default"; + }; }; &i2c2 { @@ -839,6 +874,11 @@ status = "okay"; }; +&lpass_audiocc { + compatible = "qcom,qcm6490-lpassaudiocc"; + /delete-property/ power-domains; +}; + &mdss { status = "okay"; }; @@ -1318,6 +1358,13 @@ bias-disable; output-high; }; + + aw86927_int_default: aw86927-int-default-state { + pins = "gpio101"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; }; &uart5 { diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts index 73fce639370cd..089a027c57d5c 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts @@ -13,7 +13,7 @@ #include #include #include -#include "sc7280.dtsi" +#include "kodiak.dtsi" #include "pm7250b.dtsi" #include "pm7325.dtsi" #include "pm8350c.dtsi" diff --git a/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts b/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts index 251e72f114287..bf18c48520813 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts @@ -11,7 +11,7 @@ #include #include #include -#include "sc7280.dtsi" +#include "kodiak.dtsi" #include "pm8350c.dtsi" #include "pmk8350.dtsi" diff --git a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts index eb8efba1b9dda..797f37596bf19 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts @@ -14,7 +14,7 @@ #include #include #include -#include "sc7280.dtsi" +#include "kodiak.dtsi" #include "pm7250b.dtsi" #include "pm7325.dtsi" #include "pm8350c.dtsi" /* PM7350C */ @@ -118,6 +118,11 @@ no-map; }; + removed_mem: removed@c0000000 { + reg = <0x0 0xc0000000 0x0 0x5100000>; + no-map; + }; + rmtfs_mem: rmtfs@f8500000 { compatible = "qcom,rmtfs-mem"; reg = <0x0 0xf8500000 0x0 0x600000>; @@ -130,8 +135,6 @@ thermal-zones { camera-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; thermal-sensors = <&pmk8350_adc_tm 2>; trips { @@ -144,8 +147,6 @@ }; chg-skin-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; thermal-sensors = <&pm7250b_adc_tm 0>; trips { @@ -158,8 +159,6 @@ }; conn-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; thermal-sensors = <&pm7250b_adc_tm 1>; trips { @@ -172,8 +171,6 @@ }; quiet-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; thermal-sensors = <&pmk8350_adc_tm 1>; trips { @@ -186,8 +183,6 @@ }; rear-cam-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; thermal-sensors = <&pmk8350_adc_tm 4>; trips { @@ -200,8 +195,6 @@ }; sdm-skin-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; thermal-sensors = <&pmk8350_adc_tm 3>; trips { @@ -214,8 +207,6 @@ }; xo-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; thermal-sensors = <&pmk8350_adc_tm 0>; trips { @@ -568,6 +559,11 @@ status = "okay"; }; +&lpass_audiocc { + compatible = "qcom,qcm6490-lpassaudiocc"; + /delete-property/ power-domains; +}; + &pm7250b_adc { channel@4d { reg = ; @@ -614,6 +610,46 @@ }; }; +&pm8350c_flash { + status = "okay"; + + led-0 { + function = LED_FUNCTION_FLASH; + color = ; + led-sources = <1>, <2>; + led-max-microamp = <500000>; + flash-max-microamp = <1500000>; + flash-max-timeout-us = <1280000>; + }; +}; + +&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 = ; + }; + }; +}; + &pmk8350_adc_tm { status = "okay"; @@ -857,7 +893,7 @@ &uart7 { /delete-property/interrupts; interrupts-extended = <&intc GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>, - <&tlmm 31 IRQ_TYPE_EDGE_FALLING>; + <&tlmm 31 IRQ_TYPE_EDGE_FALLING>; pinctrl-1 = <&qup_uart7_sleep_cts>, <&qup_uart7_sleep_rts>, <&qup_uart7_sleep_tx>, <&qup_uart7_sleep_rx>; pinctrl-names = "default", "sleep"; @@ -920,10 +956,6 @@ remote-endpoint = <&pmic_glink_hs_in>; }; -&usb_dp_qmpphy_out { - remote-endpoint = <&pmic_glink_ss_in>; -}; - &usb_1_hsphy { vdda-pll-supply = <&vreg_l10c>; vdda18-supply = <&vreg_l1c>; @@ -950,6 +982,16 @@ status = "okay"; }; +&usb_dp_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +}; + +&venus { + firmware-name = "qcom/qcm6490/SHIFT/otter/venus.mbn"; + + status = "okay"; +}; + &wifi { qcom,calibration-variant = "SHIFTphone_8"; diff --git a/arch/arm64/boot/dts/qcom/qcs615-ride.dts b/arch/arm64/boot/dts/qcom/qcs615-ride.dts index 705ea71b07a10..be67eb173046f 100644 --- a/arch/arm64/boot/dts/qcom/qcs615-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs615-ride.dts @@ -7,10 +7,10 @@ #include #include #include -#include "sm6150.dtsi" +#include "talos.dtsi" #include "pm8150.dtsi" / { - model = "Qualcomm Technologies, Inc. QCS615 Ride"; + model = "Qualcomm Technologies, Inc. QCS615 Ride (IQ-615 Beta EVK)"; compatible = "qcom,qcs615-ride", "qcom,qcs615", "qcom,sm6150"; chassis-type = "embedded"; @@ -39,6 +39,18 @@ }; }; + dp-dsi0-connector { + compatible = "dp-connector"; + label = "DSI0"; + type = "mini"; + + port { + dp_dsi0_connector_in: endpoint { + remote-endpoint = <&dsi2dp_bridge_out>; + }; + }; + }; + vreg_conn_1p8: regulator-conn-1p8 { compatible = "regulator-fixed"; regulator-name = "vreg_conn_1p8"; @@ -65,6 +77,64 @@ regulator-always-on; }; + vreg_12p0: regulator-vreg-12p0 { + compatible = "regulator-fixed"; + regulator-name = "VREG_12P0"; + + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vreg_1p0: regulator-vreg-1p0 { + compatible = "regulator-fixed"; + regulator-name = "VREG_1P0"; + + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + vin-supply = <&vreg_1p8>; + }; + + vreg_1p8: regulator-vreg-1p8 { + compatible = "regulator-fixed"; + regulator-name = "VREG_1P8"; + + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + vin-supply = <&vreg_5p0>; + }; + + vreg_3p0: regulator-vreg-3p0 { + compatible = "regulator-fixed"; + regulator-name = "VREG_3P0"; + + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + vin-supply = <&vreg_12p0>; + }; + + vreg_5p0: regulator-vreg-5p0 { + compatible = "regulator-fixed"; + regulator-name = "VREG_5P0"; + + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + vin-supply = <&vreg_12p0>; + }; + wcn6855-pmu { compatible = "qcom,wcn6855-pmu"; @@ -288,6 +358,86 @@ }; }; +&i2c2 { + clock-frequency = <400000>; + status = "okay"; + + io_expander: pinctrl@3e { + compatible = "semtech,sx1509q"; + reg = <0x3e>; + interrupts-extended = <&tlmm 58 IRQ_TYPE_EDGE_FALLING>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + semtech,probe-reset; + }; + + i2c-mux@77 { + compatible = "nxp,pca9542"; + reg = <0x77>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + bridge@58 { + compatible = "analogix,anx7625"; + reg = <0x58>; + interrupts-extended = <&io_expander 0 IRQ_TYPE_EDGE_FALLING>; + enable-gpios = <&tlmm 4 GPIO_ACTIVE_HIGH>; + reset-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>; + vdd10-supply = <&vreg_1p0>; + vdd18-supply = <&vreg_1p8>; + vdd33-supply = <&vreg_3p0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dsi2dp_bridge_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + + dsi2dp_bridge_out: endpoint { + remote-endpoint = <&dp_dsi0_connector_in>; + }; + }; + }; + }; + }; + }; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dsi0 { + vdda-supply = <&vreg_l11a>; + status = "okay"; +}; + +&mdss_dsi0_out { + remote-endpoint = <&dsi2dp_bridge_in>; + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi0_phy { + vcca-supply = <&vreg_l5a>; + status = "okay"; +}; + &pcie { perst-gpios = <&tlmm 101 GPIO_ACTIVE_LOW>; wake-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>; @@ -398,6 +548,7 @@ pins = "gpio98"; function = "gpio"; bias-pull-down; + drive-strength = <16>; output-low; }; }; diff --git a/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts b/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts new file mode 100644 index 0000000000000..bb5a42b038f19 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts @@ -0,0 +1,1095 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025 Radxa Computer (Shenzhen) Co., Ltd. + */ + +/dts-v1/; + +/* PM7250B is configured to use SID8/9 */ +#define PM7250B_SID 8 +#define PM7250B_SID1 9 + +#include +#include +#include +#include +#include +#include "kodiak.dtsi" +#include "pm7250b.dtsi" +#include "pm7325.dtsi" +#include "pm8350c.dtsi" /* PM7350C */ +#include "pmk8350.dtsi" /* PMK7325 */ +#include "qcs6490-audioreach.dtsi" + +/delete-node/ &adsp_mem; +/delete-node/ &cdsp_mem; +/delete-node/ &ipa_fw_mem; +/delete-node/ &mpss_mem; +/delete-node/ &remoteproc_mpss; +/delete-node/ &remoteproc_wpss; +/delete-node/ &rmtfs_mem; +/delete-node/ &video_mem; +/delete-node/ &wifi; +/delete-node/ &wlan_ce_mem; +/delete-node/ &wlan_fw_mem; +/delete-node/ &wpss_mem; +/delete-node/ &xbl_mem; + +/ { + model = "Radxa Dragon Q6A"; + compatible = "radxa,dragon-q6a", "qcom,qcm6490"; + chassis-type = "embedded"; + + aliases { + mmc0 = &sdhc_1; + mmc1 = &sdhc_2; + serial0 = &uart5; + }; + + wcd938x: audio-codec { + compatible = "qcom,wcd9380-codec"; + + pinctrl-0 = <&wcd_default>; + pinctrl-names = "default"; + + reset-gpios = <&tlmm 83 GPIO_ACTIVE_LOW>; + + vdd-rxtx-supply = <&vreg_l18b_1p8>; + vdd-io-supply = <&vreg_l18b_1p8>; + vdd-buck-supply = <&vreg_l17b_1p8>; + vdd-mic-bias-supply = <&vreg_bob_3p296>; + + qcom,micbias1-microvolt = <1800000>; + qcom,micbias2-microvolt = <1800000>; + qcom,micbias3-microvolt = <1800000>; + qcom,micbias4-microvolt = <1800000>; + qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 500000 500000 500000 500000>; + qcom,mbhc-headset-vthreshold-microvolt = <1700000>; + qcom,mbhc-headphone-vthreshold-microvolt = <50000>; + qcom,rx-device = <&wcd_rx>; + qcom,tx-device = <&wcd_tx>; + + qcom,hphl-jack-type-normally-closed; + + #sound-dai-cells = <1>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + usb2_1_con: connector-0 { + compatible = "usb-a-connector"; + vbus-supply = <&vcc_5v_peri>; + + port { + usb2_1_connector: endpoint { + remote-endpoint = <&usb_hub_2_1>; + }; + }; + }; + + usb2_2_con: connector-1 { + compatible = "usb-a-connector"; + vbus-supply = <&vcc_5v_peri>; + + port { + usb2_2_connector: endpoint { + remote-endpoint = <&usb_hub_2_2>; + }; + }; + }; + + usb2_3_con: connector-2 { + compatible = "usb-a-connector"; + vbus-supply = <&vcc_5v_peri>; + + port { + usb2_3_connector: endpoint { + remote-endpoint = <&usb_hub_2_3>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + pinctrl-0 = <&user_led>; + pinctrl-names = "default"; + + user-led { + color = ; + function = LED_FUNCTION_INDICATOR; + gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "none"; + default-state = "off"; + panic-indicator; + }; + }; + + reserved-memory { + xbl_mem: xbl@80700000 { + reg = <0x0 0x80700000 0x0 0x100000>; + no-map; + }; + + cdsp_secure_heap_mem: cdsp-secure-heap@81800000 { + reg = <0x0 0x81800000 0x0 0x1e00000>; + no-map; + }; + + camera_mem: camera@84300000 { + reg = <0x0 0x84300000 0x0 0x500000>; + no-map; + }; + + adsp_mem: adsp@84800000 { + reg = <0x0 0x84800000 0x0 0x2800000>; + no-map; + }; + + cdsp_mem: cdsp@87000000 { + reg = <0x0 0x87000000 0x0 0x1e00000>; + no-map; + }; + + video_mem: video@88e00000 { + reg = <0x0 0x88e00000 0x0 0x700000>; + no-map; + }; + + cvp_mem: cvp@89500000 { + reg = <0x0 0x89500000 0x0 0x500000>; + no-map; + }; + + gpu_microcode_mem: gpu-microcode@89a00000 { + reg = <0x0 0x89a00000 0x0 0x2000>; + no-map; + }; + + tz_stat_mem: tz-stat@c0000000 { + reg = <0x0 0xc0000000 0x0 0x100000>; + no-map; + }; + + tags_mem: tags@c0100000 { + reg = <0x0 0xc0100000 0x0 0x1200000>; + no-map; + }; + + qtee_mem: qtee@c1300000 { + reg = <0x0 0xc1300000 0x0 0x500000>; + no-map; + }; + + trusted_apps_mem: trusted-apps@c1800000 { + reg = <0x0 0xc1800000 0x0 0x1c00000>; + no-map; + }; + + debug_vm_mem: debug-vm@d0600000 { + reg = <0x0 0xd0600000 0x0 0x100000>; + no-map; + }; + }; + + thermal-zones { + msm-skin-thermal { + polling-delay-passive = <0>; + thermal-sensors = <&pmk8350_adc_tm 2>; + }; + + quiet-thermal { + polling-delay-passive = <0>; + thermal-sensors = <&pmk8350_adc_tm 1>; + }; + + ufs-thermal { + polling-delay-passive = <0>; + thermal-sensors = <&pmk8350_adc_tm 3>; + }; + + xo-thermal { + polling-delay-passive = <0>; + thermal-sensors = <&pmk8350_adc_tm 0>; + }; + }; + + vcc_1v8: regulator-vcc-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_5v_peri>; + + regulator-boot-on; + regulator-always-on; + }; + + vcc_3v3: regulator-vcc-3v3 { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_5v_peri>; + + regulator-boot-on; + regulator-always-on; + }; + + vcc_5v_peri: regulator-vcc-5v-peri { + compatible = "regulator-fixed"; + regulator-name = "vcc_5v_peri"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vph_pwr>; + + regulator-boot-on; + regulator-always-on; + }; + + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + + regulator-boot-on; + regulator-always-on; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pm7325-rpmh-regulators"; + qcom,pmic-id = "b"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; + vdd-s7-supply = <&vph_pwr>; + vdd-s8-supply = <&vph_pwr>; + vdd-l1-l4-l12-l15-supply = <&vreg_s7b_0p536>; + vdd-l2-l7-supply = <&vreg_bob_3p296>; + vdd-l6-l9-l10-supply = <&vreg_s8b_1p2>; + vdd-l11-l17-l18-l19-supply = <&vreg_s1b_1p84>; + + vreg_s1b_1p84: smps1 { + regulator-name = "vreg_s1b_1p84"; + regulator-min-microvolt = <1840000>; + regulator-max-microvolt = <2040000>; + }; + + vreg_s7b_0p536: smps7 { + regulator-name = "vreg_s7b_0p536"; + regulator-min-microvolt = <536000>; + regulator-max-microvolt = <1120000>; + }; + + vreg_s8b_1p2: smps8 { + regulator-name = "vreg_s8b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1496000>; + regulator-initial-mode = ; + }; + + vreg_l1b_0p912: ldo1 { + regulator-name = "vreg_l1b_0p912"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2b_3p072: ldo2 { + regulator-name = "vreg_l2b_3p072"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l6b_1p2: ldo6 { + regulator-name = "vreg_l6b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1256000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l7b_2p96: ldo7 { + regulator-name = "vreg_l7b_2p96"; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l9b_1p2: ldo9 { + regulator-name = "vreg_l9b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l17b_1p8: ldo17 { + regulator-name = "vreg_l17b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1896000>; + regulator-initial-mode = ; + }; + + vreg_l18b_1p8: ldo18 { + regulator-name = "vreg_l18b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + regulator-always-on; + }; + + vreg_l19b_1p8: ldo19 { + regulator-name = "vreg_l19b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-1 { + compatible = "qcom,pm8350c-rpmh-regulators"; + qcom,pmic-id = "c"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; + vdd-s7-supply = <&vph_pwr>; + vdd-s8-supply = <&vph_pwr>; + vdd-s9-supply = <&vph_pwr>; + vdd-s10-supply = <&vph_pwr>; + vdd-l1-l12-supply = <&vreg_s1b_1p84>; + vdd-l6-l9-l11-supply = <&vreg_bob_3p296>; + vdd-l10-supply = <&vreg_s7b_0p536>; + vdd-bob-supply = <&vph_pwr>; + + vreg_l1c_1p8: ldo1 { + regulator-name = "vreg_l1c_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1976000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l6c_2p96: ldo6 { + regulator-name = "vreg_l6c_2p96"; + regulator-min-microvolt = <1650000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l9c_2p96: ldo9 { + regulator-name = "vreg_l9c_2p96"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l10c_0p88: ldo10 { + regulator-name = "vreg_l10c_0p88"; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <1048000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_bob_3p296: bob { + regulator-name = "vreg_bob_3p296"; + regulator-min-microvolt = <3032000>; + regulator-max-microvolt = <3960000>; + }; + }; +}; + +&gcc { + protected-clocks = , + , + , + , + , + , + , + , + , + , + ; +}; + +&gpi_dma0 { + status = "okay"; +}; + +&gpi_dma1 { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/qcs6490/a660_zap.mbn"; +}; + +/* Pin 13, 15 in GPIO header */ +&i2c0 { + qcom,enable-gsi-dma; + status = "okay"; +}; + +/* Pin 27, 28 in GPIO header */ +&i2c2 { + qcom,enable-gsi-dma; + status = "okay"; +}; + +/* Pin 3, 5 in GPIO header */ +&i2c6 { + qcom,enable-gsi-dma; + status = "okay"; +}; + +&i2c10 { + qcom,enable-gsi-dma; + status = "okay"; + + rtc: rtc@68 { + compatible = "st,m41t11"; + reg = <0x68>; + }; +}; + +/* External touchscreen */ +&i2c13 { + qcom,enable-gsi-dma; + status = "okay"; +}; + +&lpass_audiocc { + compatible = "qcom,qcm6490-lpassaudiocc"; + /delete-property/ power-domains; +}; + +&lpass_rx_macro { + status = "okay"; +}; + +&lpass_tx_macro { + status = "okay"; +}; + +&lpass_va_macro { + status = "okay"; +}; + +&pcie0 { + perst-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 89 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&pcie0_clkreq_n>, <&pcie0_reset_n>, <&pcie0_wake_n>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l10c_0p88>; + vdda-pll-supply = <&vreg_l6b_1p2>; + + status = "okay"; +}; + +&pcie1 { + perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 3 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&pcie1_clkreq_n>, <&pcie1_reset_n>, <&pcie1_wake_n>; + pinctrl-names = "default"; + + /* Support for QPS615 PCIe switch */ + iommu-map = <0x0 &apps_smmu 0x1c80 0x1>, + <0x100 &apps_smmu 0x1c81 0x1>, + <0x208 &apps_smmu 0x1c84 0x1>, + <0x210 &apps_smmu 0x1c85 0x1>, + <0x218 &apps_smmu 0x1c86 0x1>, + <0x300 &apps_smmu 0x1c87 0x1>, + <0x400 &apps_smmu 0x1c88 0x1>, + <0x500 &apps_smmu 0x1c89 0x1>, + <0x501 &apps_smmu 0x1c90 0x1>; + + status = "okay"; +}; + +&pcie1_phy { + vdda-phy-supply = <&vreg_l10c_0p88>; + vdda-pll-supply = <&vreg_l6b_1p2>; + + status = "okay"; +}; + +&pm7325_gpios { + pm7325_adc_default: adc-default-state { + pins = "gpio2"; + function = PMIC_GPIO_FUNC_NORMAL; + bias-high-impedance; + }; +}; + +&pm7325_temp_alarm { + io-channels = <&pmk8350_vadc PM7325_ADC7_DIE_TEMP>; + io-channel-names = "thermal"; +}; + +&pmk8350_adc_tm { + status = "okay"; + + xo-therm@0 { + reg = <0>; + io-channels = <&pmk8350_vadc PMK8350_ADC7_AMUX_THM1_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + quiet-therm@1 { + reg = <1>; + io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM1_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + msm-skin-therm@2 { + reg = <2>; + io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM3_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + ufs-therm@3 { + reg = <3>; + io-channels = <&pmk8350_vadc PM7325_ADC7_GPIO1_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; +}; + +&pmk8350_vadc { + pinctrl-0 = <&pm7325_adc_default>; + pinctrl-names = "default"; + + channel@3 { + reg = ; + label = "pmk7325_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + channel@44 { + reg = ; + label = "xo_therm"; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + qcom,ratiometric; + }; + + channel@103 { + reg = ; + label = "pm7325_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + channel@144 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "quiet_therm"; + }; + + channel@146 { + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "msm_skin_therm"; + }; + + channel@14a { + /* According to datasheet, 0x4a = AMUX1_GPIO = GPIO_02 */ + reg = ; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "ufs_therm"; + }; +}; + +&pon_pwrkey { + status = "okay"; +}; + +&qspi { + /* It's not possible to use QSPI with iommu */ + /* due to an error in qcom_smmu_write_s2cr */ + /delete-property/ iommus; + + pinctrl-0 = <&qspi_clk>, <&qspi_cs0>, <&qspi_data0>, + <&qspi_data1>, <&qspi_data23>; + pinctrl-1 = <&qspi_sleep>; + pinctrl-names = "default", "sleep"; + + status = "okay"; + + spi_flash: flash@0 { + compatible = "winbond,w25q256", "jedec,spi-nor"; + reg = <0>; + + spi-max-frequency = <104000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; +}; + +&qupv3_id_0 { + firmware-name = "qcom/qcm6490/qupv3fw.elf"; + status = "okay"; +}; + +&qupv3_id_1 { + firmware-name = "qcom/qcm6490/qupv3fw.elf"; + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/qcs6490/radxa/dragon-q6a/adsp.mbn"; + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/qcs6490/cdsp.mbn"; + status = "okay"; +}; + +&sdhc_1 { + non-removable; + no-sd; + no-sdio; + + vmmc-supply = <&vreg_l7b_2p96>; + vqmmc-supply = <&vreg_l19b_1p8>; + + status = "okay"; +}; + +&sdhc_2 { + pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>, <&sd_cd>; + pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>, <&sd_cd>; + + vmmc-supply = <&vreg_l9c_2p96>; + vqmmc-supply = <&vreg_l6c_2p96>; + + cd-gpios = <&tlmm 91 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&sound { + compatible = "qcom,qcs6490-rb3gen2-sndcard"; + model = "QCS6490-Radxa-Dragon-Q6A"; + + audio-routing = "IN1_HPHL", "HPHL_OUT", + "IN2_HPHR", "HPHR_OUT", + "AMIC2", "MIC BIAS2", + "TX SWR_ADC1", "ADC2_OUTPUT"; + + wcd-playback-dai-link { + link-name = "WCD Playback"; + + codec { + sound-dai = <&wcd938x 0>, <&swr0 0>, <&lpass_rx_macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wcd-capture-dai-link { + link-name = "WCD Capture"; + + codec { + sound-dai = <&wcd938x 1>, <&swr1 0>, <&lpass_tx_macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; +}; + +/* Pin 11, 29, 31, 32 in GPIO header */ +&spi7 { + qcom,enable-gsi-dma; + status = "okay"; +}; + +/* Pin 19, 21, 23, 24, 26 in GPIO header */ +&spi12 { + qcom,enable-gsi-dma; + status = "okay"; +}; + +/* Pin 22, 33, 36, 37 in GPIO header */ +&spi14 { + qcom,enable-gsi-dma; + status = "okay"; +}; + +&swr0 { + status = "okay"; + + wcd_rx: codec@0,4 { + compatible = "sdw20217010d00"; + reg = <0 4>; + qcom,rx-port-mapping = <1 2 3 4 5>; + }; +}; + +&swr1 { + status = "okay"; + + wcd_tx: codec@0,3 { + compatible = "sdw20217010d00"; + reg = <0 3>; + qcom,tx-port-mapping = <1 1 2 3>; + }; +}; + +&tlmm { + gpio-line-names = + /* GPIO_0 ~ GPIO_3 */ + "PIN_13", "PIN_15", "", "", + /* GPIO_4 ~ GPIO_7 */ + "", "", "", "", + /* GPIO_8 ~ GPIO_11 */ + "PIN_27", "PIN_28", "", "", + /* GPIO_12 ~ GPIO_15 */ + "", "", "", "", + /* GPIO_16 ~ GPIO_19 */ + "", "", "", "", + /* GPIO_20 ~ GPIO_23 */ + "", "", "PIN_8", "PIN_10", + /* GPIO_24 ~ GPIO_27 */ + "PIN_3", "PIN_5", "PIN_16", "PIN_27", + /* GPIO_28 ~ GPIO_31 */ + "PIN_31", "PIN_11", "PIN_32", "PIN_29", + /* GPIO_32 ~ GPIO_35 */ + "", "", "", "", + /* GPIO_36 ~ GPIO_39 */ + "", "", "", "", + /* GPIO_40 ~ GPIO_43 */ + "", "", "", "", + /* GPIO_44 ~ GPIO_47 */ + "", "", "", "", + /* GPIO_48 ~ GPIO_51 */ + "PIN_21", "PIN_19", "PIN_23", "PIN_24", + /* GPIO_52 ~ GPIO_55 */ + "", "", "", "PIN_26", + /* GPIO_56 ~ GPIO_59 */ + "PIN_33", "PIN_22", "PIN_37", "PIN_36", + /* GPIO_60 ~ GPIO_63 */ + "", "", "", "", + /* GPIO_64 ~ GPIO_67 */ + "", "", "", "", + /* GPIO_68 ~ GPIO_71 */ + "", "", "", "", + /* GPIO_72 ~ GPIO_75 */ + "", "", "", "", + /* GPIO_76 ~ GPIO_79 */ + "", "", "", "", + /* GPIO_80 ~ GPIO_83 */ + "", "", "", "", + /* GPIO_84 ~ GPIO_87 */ + "", "", "", "", + /* GPIO_88 ~ GPIO_91 */ + "", "", "", "", + /* GPIO_92 ~ GPIO_95 */ + "", "", "", "", + /* GPIO_96 ~ GPIO_99 */ + "PIN_7", "PIN_12", "PIN_38", "PIN_40", + /* GPIO_100 ~ GPIO_103 */ + "PIN_35", "", "", "", + /* GPIO_104 ~ GPIO_107 */ + "", "", "", "", + /* GPIO_108 ~ GPIO_111 */ + "", "", "", "", + /* GPIO_112 ~ GPIO_115 */ + "", "", "", "", + /* GPIO_116 ~ GPIO_119 */ + "", "", "", "", + /* GPIO_120 ~ GPIO_123 */ + "", "", "", "", + /* GPIO_124 ~ GPIO_127 */ + "", "", "", "", + /* GPIO_128 ~ GPIO_131 */ + "", "", "", "", + /* GPIO_132 ~ GPIO_135 */ + "", "", "", "", + /* GPIO_136 ~ GPIO_139 */ + "", "", "", "", + /* GPIO_140 ~ GPIO_143 */ + "", "", "", "", + /* GPIO_144 ~ GPIO_147 */ + "", "", "", "", + /* GPIO_148 ~ GPIO_151 */ + "", "", "", "", + /* GPIO_152 ~ GPIO_155 */ + "", "", "", "", + /* GPIO_156 ~ GPIO_159 */ + "", "", "", "", + /* GPIO_160 ~ GPIO_163 */ + "", "", "", "", + /* GPIO_164 ~ GPIO_167 */ + "", "", "", "", + /* GPIO_168 ~ GPIO_171 */ + "", "", "", "", + /* GPIO_172 ~ GPIO_174 */ + "", "", ""; + + pcie0_reset_n: pcie0-reset-n-state { + pins = "gpio87"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + pcie0_wake_n: pcie0-wake-n-state { + pins = "gpio89"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + pcie1_reset_n: pcie1-reset-n-state { + pins = "gpio2"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + pcie1_wake_n: pcie1-wake-n-state { + pins = "gpio3"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + qspi_sleep: qspi-sleep-state { + pins = "gpio12", "gpio13", "gpio14", "gpio15", "gpio16", "gpio17"; + function = "gpio"; + output-disable; + }; + + sd_cd: sd-cd-state { + pins = "gpio91"; + function = "gpio"; + bias-pull-up; + }; + + user_led: user-led-state { + pins = "gpio42"; + function = "gpio"; + bias-pull-up; + }; + + wcd_default: wcd-reset-n-active-state { + pins = "gpio83"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + output-low; + }; +}; + +&uart5 { + status = "okay"; +}; + +&usb_2 { + dr_mode = "host"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + /* Onboard USB 2.0 hub */ + usb_hub_2_x: hub@1 { + compatible = "usb1a40,0101"; + reg = <1>; + vdd-supply = <&vcc_5v_peri>; + #address-cells = <1>; + #size-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + usb_hub_2_1: endpoint { + remote-endpoint = <&usb2_1_connector>; + }; + }; + + port@2 { + reg = <2>; + + usb_hub_2_2: endpoint { + remote-endpoint = <&usb2_2_connector>; + }; + }; + + port@3 { + reg = <3>; + + usb_hub_2_3: endpoint { + remote-endpoint = <&usb2_3_connector>; + }; + }; + }; + + /* FCU760K Wi-Fi & Bluetooth module */ + wifi@4 { + compatible = "usba69c,8d80"; + reg = <4>; + }; + }; +}; + +&usb_2_hsphy { + vdda-pll-supply = <&vreg_l10c_0p88>; + vdda33-supply = <&vreg_l2b_3p072>; + vdda18-supply = <&vreg_l1c_1p8>; + + status = "okay"; +}; + +&venus { + status = "okay"; +}; + +/* PINCTRL - additions to nodes defined in sc7280.dtsi */ +&pcie0_clkreq_n { + bias-pull-up; + drive-strength = <2>; +}; + +&pcie1_clkreq_n { + bias-pull-up; + drive-strength = <2>; +}; + +&qspi_clk { + bias-disable; + drive-strength = <16>; +}; + +&qspi_cs0 { + bias-disable; + drive-strength = <8>; +}; + +&qspi_data0 { + bias-disable; + drive-strength = <8>; +}; + +&qspi_data1 { + bias-disable; + drive-strength = <8>; +}; + +&qspi_data23 { + bias-disable; + drive-strength = <8>; +}; + +&sdc1_clk { + bias-disable; + drive-strength = <16>; +}; + +&sdc1_cmd { + bias-pull-up; + drive-strength = <10>; +}; + +&sdc1_data { + bias-pull-up; + drive-strength = <10>; +}; + +&sdc1_rclk { + bias-pull-down; +}; + +&sdc2_clk { + bias-disable; + drive-strength = <16>; +}; + +&sdc2_cmd { + bias-pull-up; + drive-strength = <10>; +}; + +&sdc2_data { + bias-pull-up; + drive-strength = <10>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index 18cea88120014..f29a352b0288e 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -14,7 +14,7 @@ #include #include #include -#include "sc7280.dtsi" +#include "kodiak.dtsi" #include "pm7250b.dtsi" #include "pm7325.dtsi" #include "pm8350c.dtsi" @@ -217,6 +217,13 @@ }; }; + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + }; + thermal-zones { sdm-skin-thermal { thermal-sensors = <&pmk8350_adc_tm 3>; @@ -255,13 +262,6 @@ }; }; - vph_pwr: vph-pwr-regulator { - compatible = "regulator-fixed"; - regulator-name = "vph_pwr"; - regulator-min-microvolt = <3700000>; - regulator-max-microvolt = <3700000>; - }; - wcn6750-pmu { compatible = "qcom,wcn6750-pmu"; pinctrl-0 = <&bt_en>; @@ -335,8 +335,6 @@ vdd-s8-supply = <&vph_pwr>; vdd-l1-l4-l12-l15-supply = <&vreg_s7b_0p972>; vdd-l2-l7-supply = <&vreg_bob_3p296>; - vdd-l3-supply = <&vreg_s2b_0p876>; - vdd-l5-supply = <&vreg_s2b_0p876>; vdd-l6-l9-l10-supply = <&vreg_s8b_1p272>; vdd-l8-supply = <&vreg_s7b_0p972>; vdd-l11-l17-l18-l19-supply = <&vreg_s1b_1p872>; @@ -349,12 +347,6 @@ regulator-max-microvolt = <2040000>; }; - vreg_s2b_0p876: smps2 { - regulator-name = "vreg_s2b_0p876"; - regulator-min-microvolt = <570070>; - regulator-max-microvolt = <1050000>; - }; - vreg_s7b_0p972: smps7 { regulator-name = "vreg_s7b_0p972"; regulator-min-microvolt = <535000>; @@ -385,27 +377,13 @@ vreg_l3b_0p504: ldo3 { regulator-name = "vreg_l3b_0p504"; regulator-min-microvolt = <312000>; - regulator-max-microvolt = <910000>; - regulator-initial-mode = ; - }; - - vreg_l4b_0p752: ldo4 { - regulator-name = "vreg_l4b_0p752"; - regulator-min-microvolt = <752000>; - regulator-max-microvolt = <820000>; - regulator-initial-mode = ; - }; - - reg_l5b_0p752: ldo5 { - regulator-name = "reg_l5b_0p752"; - regulator-min-microvolt = <552000>; - regulator-max-microvolt = <832000>; + regulator-max-microvolt = <650000>; regulator-initial-mode = ; }; vreg_l6b_1p2: ldo6 { regulator-name = "vreg_l6b_1p2"; - regulator-min-microvolt = <1140000>; + regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1260000>; regulator-initial-mode = ; }; @@ -436,7 +414,7 @@ vreg_l11b_1p504: ldo11 { regulator-name = "vreg_l11b_1p504"; - regulator-min-microvolt = <1504000>; + regulator-min-microvolt = <1776000>; regulator-max-microvolt = <2000000>; regulator-initial-mode = ; }; @@ -457,7 +435,7 @@ vreg_l14b_1p08: ldo14 { regulator-name = "vreg_l14b_1p08"; - regulator-min-microvolt = <1080000>; + regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1304000>; regulator-initial-mode = ; }; @@ -521,26 +499,8 @@ vreg_s1c_2p19: smps1 { regulator-name = "vreg_s1c_2p19"; - regulator-min-microvolt = <2190000>; - regulator-max-microvolt = <2210000>; - }; - - vreg_s2c_0p752: smps2 { - regulator-name = "vreg_s2c_0p752"; - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <800000>; - }; - - vreg_s5c_0p752: smps5 { - regulator-name = "vreg_s5c_0p752"; - regulator-min-microvolt = <465000>; - regulator-max-microvolt = <1050000>; - }; - - vreg_s7c_0p752: smps7 { - regulator-name = "vreg_s7c_0p752"; - regulator-min-microvolt = <465000>; - regulator-max-microvolt = <800000>; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <2208000>; }; vreg_s9c_1p084: smps9 { @@ -600,7 +560,7 @@ vreg_l8c_1p62: ldo8 { regulator-name = "vreg_l8c_1p62"; - regulator-min-microvolt = <1620000>; + regulator-min-microvolt = <1800000>; regulator-max-microvolt = <2000000>; regulator-initial-mode = ; }; @@ -608,7 +568,7 @@ vreg_l9c_2p96: ldo9 { regulator-name = "vreg_l9c_2p96"; regulator-min-microvolt = <2700000>; - regulator-max-microvolt = <35440000>; + regulator-max-microvolt = <3544000>; regulator-initial-mode = ; }; @@ -628,7 +588,7 @@ vreg_l12c_1p65: ldo12 { regulator-name = "vreg_l12c_1p65"; - regulator-min-microvolt = <1650000>; + regulator-min-microvolt = <1800000>; regulator-max-microvolt = <2000000>; regulator-initial-mode = ; }; @@ -1009,10 +969,12 @@ }; &qupv3_id_0 { + firmware-name = "qcom/qcs6490/qupv3fw.elf"; status = "okay"; }; &qupv3_id_1 { + firmware-name = "qcom/qcs6490/qupv3fw.elf"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index cabb3f508704b..9bcb869dd2706 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -8,8 +8,8 @@ #include #include -#include "qcs8300.dtsi" -#include "qcs8300-pmics.dtsi" +#include "monaco.dtsi" +#include "monaco-pmics.dtsi" / { model = "Qualcomm Technologies, Inc. QCS8300 Ride"; compatible = "qcom,qcs8300-ride", "qcom,qcs8300"; diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts index 67ba508e92ba1..1b9ca957a94b6 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts @@ -7,7 +7,7 @@ #include #include -#include "qcm2290.dtsi" +#include "agatti.dtsi" #include "pm4125.dtsi" / { @@ -188,6 +188,53 @@ regulator-always-on; regulator-boot-on; }; + + sound { + compatible = "qcom,qrb2210-sndcard"; + pinctrl-0 = <&lpi_i2s2_active>; + pinctrl-names = "default"; + model = "Qualcomm-RB1-WSA8815-Speaker-DMIC0"; + + mm1-dai-link { + link-name = "MultiMedia1"; + + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; + }; + }; + + mm2-dai-link { + link-name = "MultiMedia2"; + + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>; + }; + }; + + mm3-dai-link { + link-name = "MultiMedia3"; + + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>; + }; + }; + + hdmi-i2s-dai-link { + link-name = "HDMI/I2S Playback"; + + codec { + sound-dai = <<9611_codec 0>; + }; + + cpu { + sound-dai = <&q6afedai SECONDARY_MI2S_RX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + }; + }; }; &cpu_pd0 { @@ -214,10 +261,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/qcm2290/a702_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/qcm2290/a702_zap.mbn"; }; &i2c2_gpio { @@ -323,6 +370,14 @@ status = "okay"; }; +/* SECONDARY I2S uses 1 I2S SD Line for audio on LT9611UXC HDMI Bridge */ +&q6afedai { + dai@18 { + reg = ; + qcom,sd-lines = <0>; + }; +}; + &qupv3_id_0 { status = "okay"; }; @@ -649,7 +704,7 @@ &uart3 { /delete-property/ interrupts; interrupts-extended = <&intc GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, - <&tlmm 11 IRQ_TYPE_LEVEL_HIGH>; + <&tlmm 11 IRQ_TYPE_EDGE_FALLING>; pinctrl-0 = <&uart3_default>; pinctrl-1 = <&uart3_sleep>; pinctrl-names = "default", "sleep"; diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts index bdf2d66e40c62..0cd36c54632fa 100644 --- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts @@ -245,10 +245,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/qrb4210/a610_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/qrb4210/a610_zap.mbn"; }; &i2c2_gpio { diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts index d99448a0732d9..71b42e76f03d6 100644 --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -594,11 +594,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sm8250/a650_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8250/a650_zap.mbn"; }; /* LS-I2C0 */ diff --git a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts index 64e59299672cb..d28d691624279 100644 --- a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts +++ b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts @@ -149,13 +149,6 @@ enable-active-high; regulator-always-on; }; - - reserved-memory { - gpu_mem: gpu-mem@8bf00000 { - reg = <0 0x8bf00000 0 0x2000>; - no-map; - }; - }; }; &apps_rsc { @@ -345,11 +338,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sa8295p/a690_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sa8295p/a690_zap.mbn"; }; &gpu_smmu { diff --git a/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts b/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts index ad342d8b7508c..1514da6362698 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts @@ -31,7 +31,7 @@ }; reserved-memory { - zap_mem: zap-shader@80840000 { + gpu_mem: zap-shader@80840000 { reg = <0x0 0x80840000 0 0x2000>; no-map; }; @@ -426,11 +426,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&zap_mem>; - firmware-name = "qcom/sc7180/acer/aspire1/qcdxkmsuc7180.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sc7180/acer/aspire1/qcdxkmsuc7180.mbn"; }; &mdss { diff --git a/arch/arm64/boot/dts/qcom/sc7180-el2.dtso b/arch/arm64/boot/dts/qcom/sc7180-el2.dtso index 49a98676ca4db..6e8da59597b65 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-el2.dtso +++ b/arch/arm64/boot/dts/qcom/sc7180-el2.dtso @@ -8,10 +8,8 @@ /plugin/; /* We can't and don't need to use zap shader in EL2 as linux can zap the gpu on it's own. */ -&gpu { - zap-shader { - status = "disabled"; - }; +&gpu_zap_shader { + status = "disabled"; }; /* Venus can be used in EL2 if booted similarly to ChromeOS devices. */ diff --git a/arch/arm64/boot/dts/qcom/sc7180-idp.dts b/arch/arm64/boot/dts/qcom/sc7180-idp.dts index 19cf419cf531f..0bce3eefca2e9 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-idp.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-idp.dts @@ -39,6 +39,7 @@ * */ +/delete-node/ &gpu_zap_shader; /delete-node/ &hyp_mem; /delete-node/ &xbl_mem; /delete-node/ &aop_mem; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi index 74ab321d3333c..b398f69917f0e 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi @@ -41,6 +41,7 @@ * required by the board dts. */ +/delete-node/ &gpu_zap_shader; /delete-node/ &hyp_mem; /delete-node/ &ipa_fw_mem; /delete-node/ &xbl_mem; diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index a0df10a97c7f8..45b9864e3304b 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -1474,6 +1474,12 @@ }; }; + refgen: regulator@ff1000 { + compatible = "qcom,sc7180-refgen-regulator", + "qcom,sdm845-refgen-regulator"; + reg = <0x0 0x00ff1000 0x0 0x60>; + }; + config_noc: interconnect@1500000 { compatible = "qcom,sc7180-config-noc"; reg = <0 0x01500000 0 0x28000>; @@ -2179,6 +2185,10 @@ interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; + gpu_zap_shader: zap-shader { + memory-region = <&gpu_mem>; + }; + gpu_opp_table: opp-table { compatible = "operating-points-v2"; @@ -3332,6 +3342,8 @@ phys = <&mdss_dsi0_phy>; + refgen-supply = <&refgen>; + #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi index ccd39a1baeda5..8cac4ce9c8515 100644 --- a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi @@ -7,7 +7,7 @@ #include #include -#include "sc7280.dtsi" +#include "kodiak.dtsi" #include "pm7325.dtsi" #include "pm8350c.dtsi" #include "pmk8350.dtsi" @@ -573,7 +573,7 @@ }; }; -/* PINCTRL - additions to nodes defined in sc7280.dtsi */ +/* PINCTRL - additions to nodes defined in kodiak.dtsi */ &dp_hot_plug_det { bias-disable; diff --git a/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi b/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi index 7d1d5bbbbbd95..469a5d103e3db 100644 --- a/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi @@ -16,7 +16,7 @@ #include #include -#include "sc7280.dtsi" +#include "kodiak.dtsi" /* PMICs depend on spmi_bus label and so must come after SoC */ #include "pm7325.dtsi" diff --git a/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts b/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts index 08d0784d0cbb8..d86a31ddede29 100644 --- a/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts +++ b/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts @@ -151,11 +151,6 @@ no-map; }; - gpu_mem: gpu-region@98715000 { - reg = <0x0 0x98715000 0x0 0x2000>; - no-map; - }; - cdsp_mem: cdsp-region@98900000 { reg = <0x0 0x98900000 0x0 0x1400000>; no-map; @@ -355,11 +350,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sc8180x/LENOVO/82AK/qcdxkmsuc8180.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sc8180x/LENOVO/82AK/qcdxkmsuc8180.mbn"; }; &i2c1 { diff --git a/arch/arm64/boot/dts/qcom/sc8180x-primus.dts b/arch/arm64/boot/dts/qcom/sc8180x-primus.dts index 93de9fe918ebd..aff398390eba7 100644 --- a/arch/arm64/boot/dts/qcom/sc8180x-primus.dts +++ b/arch/arm64/boot/dts/qcom/sc8180x-primus.dts @@ -14,6 +14,8 @@ #include "sc8180x.dtsi" #include "sc8180x-pmics.dtsi" +/delete-node/ &gpu_mem; + / { model = "Qualcomm SC8180x Primus"; compatible = "qcom,sc8180x-primus", "qcom,sc8180x"; @@ -442,11 +444,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sc8180x/qcdxkmsuc8180.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sc8180x/qcdxkmsuc8180.mbn"; }; &i2c1 { diff --git a/arch/arm64/boot/dts/qcom/sc8180x.dtsi b/arch/arm64/boot/dts/qcom/sc8180x.dtsi index 85c2afcb417de..8319d892c6e49 100644 --- a/arch/arm64/boot/dts/qcom/sc8180x.dtsi +++ b/arch/arm64/boot/dts/qcom/sc8180x.dtsi @@ -646,6 +646,11 @@ no-map; }; + gpu_mem: memory@98715000 { + reg = <0x0 0x98715000 0x0 0x2000>; + no-map; + }; + reserved@9d400000 { reg = <0x0 0x9d400000 0x0 0x1000000>; no-map; @@ -2274,6 +2279,10 @@ status = "disabled"; + gpu_zap_shader: zap-shader { + memory-region = <&gpu_mem>; + }; + gpu_opp_table: opp-table { compatible = "operating-points-v2"; @@ -2530,6 +2539,12 @@ status = "disabled"; }; + refgen: regulator@88e7000 { + compatible = "qcom,sc8180x-refgen-regulator", + "qcom,sdm845-refgen-regulator"; + reg = <0x0 0x088e7000 0x0 0x60>; + }; + usb_prim_qmpphy: phy@88e8000 { compatible = "qcom,sc8180x-qmp-usb3-dp-phy"; reg = <0 0x088e8000 0 0x3000>; @@ -3116,6 +3131,8 @@ phys = <&mdss_dsi0_phy>; phy-names = "dsi"; + refgen-supply = <&refgen>; + status = "disabled"; ports { @@ -3203,6 +3220,8 @@ phys = <&mdss_dsi1_phy>; phy-names = "dsi"; + refgen-supply = <&refgen>; + status = "disabled"; ports { diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts index 490e970c54a24..c53e00cae465a 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts @@ -225,11 +225,6 @@ }; reserved-memory { - gpu_mem: gpu-mem@8bf00000 { - reg = <0 0x8bf00000 0 0x2000>; - no-map; - }; - linux,cma { compatible = "shared-dma-pool"; size = <0x0 0x8000000>; @@ -509,11 +504,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sc8280xp/qcdxkmsuc8280.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sc8280xp/qcdxkmsuc8280.mbn"; }; &mdss0 { diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-el2.dtso b/arch/arm64/boot/dts/qcom/sc8280xp-el2.dtso index 25d1fa4bc2055..cff3735a12dde 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-el2.dtso +++ b/arch/arm64/boot/dts/qcom/sc8280xp-el2.dtso @@ -8,10 +8,8 @@ /plugin/; /* We can't and don't need to use zap shader in EL2 as linux can zap the gpu on it's own. */ -&gpu { - zap-shader { - status = "disabled"; - }; +&gpu_zap_shader { + status = "disabled"; }; /* diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-huawei-gaokun3.dts b/arch/arm64/boot/dts/qcom/sc8280xp-huawei-gaokun3.dts index 0374251d33291..9819454abe131 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-huawei-gaokun3.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-huawei-gaokun3.dts @@ -158,11 +158,6 @@ }; reserved-memory { - gpu_mem: gpu-mem@8bf00000 { - reg = <0 0x8bf00000 0 0x2000>; - no-map; - }; - linux,cma { compatible = "shared-dma-pool"; size = <0x0 0x8000000>; @@ -600,11 +595,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sc8280xp/HUAWEI/gaokun3/qcdxkmsuc8280.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sc8280xp/HUAWEI/gaokun3/qcdxkmsuc8280.mbn"; }; &i2c4 { diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts index 637430719e6d7..d84ca010ab9dc 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts @@ -83,14 +83,11 @@ pinctrl-names = "default"; pinctrl-0 = <&cam_indicator_en>; - led-camera-indicator { - label = "white:camera-indicator"; + privacy_led: privacy-led { function = LED_FUNCTION_INDICATOR; color = ; gpios = <&tlmm 28 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "none"; default-state = "off"; - /* Reuse as a panic indicator until we get a "camera on" trigger */ panic-indicator; }; }; @@ -283,11 +280,6 @@ }; reserved-memory { - gpu_mem: gpu-mem@8bf00000 { - reg = <0 0x8bf00000 0 0x2000>; - no-map; - }; - linux,cma { compatible = "shared-dma-pool"; size = <0x0 0x8000000>; @@ -685,6 +677,9 @@ pinctrl-names = "default"; pinctrl-0 = <&cam_rgb_default>; + leds = <&privacy_led>; + led-names = "privacy"; + clocks = <&camcc CAMCC_MCLK3_CLK>; orientation = <0>; /* Front facing */ @@ -722,11 +717,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sc8280xp/LENOVO/21BX/qcdxkmsuc8280.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sc8280xp/LENOVO/21BX/qcdxkmsuc8280.mbn"; }; &mdss0 { diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-arcata.dts b/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-arcata.dts index aeed3ef152eba..f2b4470d4407f 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-arcata.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-arcata.dts @@ -186,11 +186,6 @@ }; reserved-memory { - gpu_mem: gpu-mem@8bf00000 { - reg = <0 0x8bf00000 0 0x2000>; - no-map; - }; - linux,cma { compatible = "shared-dma-pool"; size = <0x0 0x8000000>; @@ -462,11 +457,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sc8280xp/MICROSOFT/SurfacePro9/qcdxkmsuc8280.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sc8280xp/MICROSOFT/SurfacePro9/qcdxkmsuc8280.mbn"; }; &mdss0 { diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-blackrock.dts b/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-blackrock.dts index a40dccd70dfda..00bbeeef6f14d 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-blackrock.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-blackrock.dts @@ -227,11 +227,6 @@ }; reserved-memory { - gpu_mem: gpu-mem@8bf00000 { - reg = <0 0x8bf00000 0 0x2000>; - no-map; - }; - linux,cma { compatible = "shared-dma-pool"; size = <0x0 0x8000000>; @@ -579,11 +574,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sc8280xp/microsoft/blackrock/qcdxkmsuc8280.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sc8280xp/microsoft/blackrock/qcdxkmsuc8280.mbn"; }; &mdss0 { diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi index 279e5e6beae20..5334adebf2782 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi @@ -691,6 +691,11 @@ no-map; }; + pil_gpu_mem: gpu-mem@8bf00000 { + reg = <0 0x8bf00000 0 0x2000>; + no-map; + }; + pil_adsp_mem: adsp-region@86c00000 { reg = <0 0x86c00000 0 0x2000000>; no-map; @@ -967,8 +972,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 6 QCOM_GPI_SPI>, - <&gpi_dma2 1 6 QCOM_GPI_SPI>; + dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>, + <&gpi_dma2 1 0 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -989,8 +994,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>, - <&gpi_dma2 1 0 QCOM_GPI_I2C>; + dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>, + <&gpi_dma2 1 0 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1011,8 +1016,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>, - <&gpi_dma2 1 0 QCOM_GPI_SPI>; + dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>, + <&gpi_dma2 1 1 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1033,8 +1038,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>, - <&gpi_dma2 1 1 QCOM_GPI_I2C>; + dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>, + <&gpi_dma2 1 1 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1069,8 +1074,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>, - <&gpi_dma2 1 1 QCOM_GPI_SPI>; + dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>, + <&gpi_dma2 1 2 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1091,8 +1096,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>, - <&gpi_dma2 1 2 QCOM_GPI_I2C>; + dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>, + <&gpi_dma2 1 2 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1131,8 +1136,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>, - <&gpi_dma2 1 2 QCOM_GPI_SPI>; + dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>, + <&gpi_dma2 1 3 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1153,8 +1158,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>, - <&gpi_dma2 1 3 QCOM_GPI_I2C>; + dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>, + <&gpi_dma2 1 3 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1175,8 +1180,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>, - <&gpi_dma2 1 3 QCOM_GPI_SPI>; + dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>, + <&gpi_dma2 1 4 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1197,8 +1202,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>, - <&gpi_dma2 1 4 QCOM_GPI_I2C>; + dmas = <&gpi_dma2 0 4 QCOM_GPI_SPI>, + <&gpi_dma2 1 4 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1241,8 +1246,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 4 QCOM_GPI_SPI>, - <&gpi_dma2 1 4 QCOM_GPI_SPI>; + dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>, + <&gpi_dma2 1 5 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1285,8 +1290,8 @@ <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>, - <&gpi_dma2 1 5 QCOM_GPI_SPI>; + dmas = <&gpi_dma2 0 6 QCOM_GPI_SPI>, + <&gpi_dma2 1 6 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1338,7 +1343,7 @@ }; }; - gpi_dma0: dma-controller@900000 { + gpi_dma0: dma-controller@900000 { compatible = "qcom,sc8280xp-gpi-dma", "qcom,sm6350-gpi-dma"; reg = <0 0x00900000 0 0x60000>; @@ -1393,8 +1398,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 7 QCOM_GPI_I2C>, - <&gpi_dma0 1 7 QCOM_GPI_I2C>; + dmas = <&gpi_dma0 0 0 QCOM_GPI_I2C>, + <&gpi_dma0 1 0 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1415,8 +1420,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 0 QCOM_GPI_I2C>, - <&gpi_dma0 1 0 QCOM_GPI_I2C>; + dmas = <&gpi_dma0 0 0 QCOM_GPI_SPI>, + <&gpi_dma0 1 0 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1437,8 +1442,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 0 QCOM_GPI_SPI>, - <&gpi_dma0 1 0 QCOM_GPI_SPI>; + dmas = <&gpi_dma0 0 1 QCOM_GPI_I2C>, + <&gpi_dma0 1 1 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1459,8 +1464,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 1 QCOM_GPI_I2C>, - <&gpi_dma0 1 1 QCOM_GPI_I2C>; + dmas = <&gpi_dma0 0 1 QCOM_GPI_SPI>, + <&gpi_dma0 1 1 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1481,8 +1486,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 1 QCOM_GPI_SPI>, - <&gpi_dma0 1 1 QCOM_GPI_SPI>; + dmas = <&gpi_dma0 0 2 QCOM_GPI_I2C>, + <&gpi_dma0 1 2 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1503,8 +1508,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 2 QCOM_GPI_I2C>, - <&gpi_dma0 1 2 QCOM_GPI_I2C>; + dmas = <&gpi_dma0 0 2 QCOM_GPI_SPI>, + <&gpi_dma0 1 2 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1539,8 +1544,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 2 QCOM_GPI_SPI>, - <&gpi_dma0 1 2 QCOM_GPI_SPI>; + dmas = <&gpi_dma0 0 3 QCOM_GPI_I2C>, + <&gpi_dma0 1 3 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1561,8 +1566,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 3 QCOM_GPI_I2C>, - <&gpi_dma0 1 3 QCOM_GPI_I2C>; + dmas = <&gpi_dma0 0 3 QCOM_GPI_SPI>, + <&gpi_dma0 1 3 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1583,8 +1588,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 3 QCOM_GPI_SPI>, - <&gpi_dma0 1 3 QCOM_GPI_SPI>; + dmas = <&gpi_dma0 0 4 QCOM_GPI_I2C>, + <&gpi_dma0 1 4 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1605,8 +1610,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 4 QCOM_GPI_I2C>, - <&gpi_dma0 1 4 QCOM_GPI_I2C>; + dmas = <&gpi_dma0 0 4 QCOM_GPI_SPI>, + <&gpi_dma0 1 4 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1627,8 +1632,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 4 QCOM_GPI_SPI>, - <&gpi_dma0 1 4 QCOM_GPI_SPI>; + dmas = <&gpi_dma0 0 5 QCOM_GPI_I2C>, + <&gpi_dma0 1 5 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1649,8 +1654,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 5 QCOM_GPI_I2C>, - <&gpi_dma0 1 5 QCOM_GPI_I2C>; + dmas = <&gpi_dma0 0 5 QCOM_GPI_SPI>, + <&gpi_dma0 1 5 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1671,8 +1676,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 5 QCOM_GPI_SPI>, - <&gpi_dma0 1 5 QCOM_GPI_SPI>; + dmas = <&gpi_dma0 0 6 QCOM_GPI_I2C>, + <&gpi_dma0 1 6 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1693,8 +1698,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 6 QCOM_GPI_I2C>, - <&gpi_dma0 1 6 QCOM_GPI_I2C>; + dmas = <&gpi_dma0 0 6 QCOM_GPI_SPI>, + <&gpi_dma0 1 6 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1715,8 +1720,8 @@ <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma0 0 6 QCOM_GPI_SPI>, - <&gpi_dma0 1 6 QCOM_GPI_SPI>; + dmas = <&gpi_dma0 0 7 QCOM_GPI_I2C>, + <&gpi_dma0 1 7 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1800,8 +1805,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 7 QCOM_GPI_I2C>, - <&gpi_dma1 1 7 QCOM_GPI_I2C>; + dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>, + <&gpi_dma1 1 0 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1822,8 +1827,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>, - <&gpi_dma1 1 0 QCOM_GPI_I2C>; + dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>, + <&gpi_dma1 1 0 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1844,8 +1849,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>, - <&gpi_dma1 1 0 QCOM_GPI_SPI>; + dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>, + <&gpi_dma1 1 1 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1866,8 +1871,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>, - <&gpi_dma1 1 1 QCOM_GPI_I2C>; + dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>, + <&gpi_dma1 1 1 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1888,8 +1893,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>, - <&gpi_dma1 1 1 QCOM_GPI_SPI>; + dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>, + <&gpi_dma1 1 2 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1910,8 +1915,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>, - <&gpi_dma1 1 2 QCOM_GPI_I2C>; + dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>, + <&gpi_dma1 1 2 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1932,8 +1937,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>, - <&gpi_dma1 1 2 QCOM_GPI_SPI>; + dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>, + <&gpi_dma1 1 3 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1954,8 +1959,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>, - <&gpi_dma1 1 3 QCOM_GPI_I2C>; + dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>, + <&gpi_dma1 1 3 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -1976,8 +1981,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>, - <&gpi_dma1 1 3 QCOM_GPI_SPI>; + dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>, + <&gpi_dma1 1 4 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -1998,8 +2003,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>, - <&gpi_dma1 1 4 QCOM_GPI_I2C>; + dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>, + <&gpi_dma1 1 4 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -2020,8 +2025,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>, - <&gpi_dma1 1 4 QCOM_GPI_SPI>; + dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>, + <&gpi_dma1 1 5 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -2042,8 +2047,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>, - <&gpi_dma1 1 5 QCOM_GPI_I2C>; + dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>, + <&gpi_dma1 1 5 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -2064,8 +2069,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>, - <&gpi_dma1 1 5 QCOM_GPI_SPI>; + dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>, + <&gpi_dma1 1 6 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -2086,8 +2091,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>, - <&gpi_dma1 1 6 QCOM_GPI_I2C>; + dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>, + <&gpi_dma1 1 6 QCOM_GPI_SPI>; dma-names = "tx", "rx"; @@ -2108,8 +2113,8 @@ <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; - dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>, - <&gpi_dma1 1 6 QCOM_GPI_SPI>; + dmas = <&gpi_dma1 0 7 QCOM_GPI_I2C>, + <&gpi_dma1 1 7 QCOM_GPI_I2C>; dma-names = "tx", "rx"; @@ -3366,6 +3371,10 @@ status = "disabled"; + gpu_zap_shader: zap-shader { + memory-region = <&pil_gpu_mem>; + }; + gpu_opp_table: opp-table { compatible = "operating-points-v2"; @@ -3723,6 +3732,12 @@ status = "disabled"; }; + refgen: regulator@8900000 { + compatible = "qcom,sc8280xp-refgen-regulator", + "qcom,sm8250-refgen-regulator"; + reg = <0x0 0x08900000 0x0 0x96>; + }; + usb_1_hsphy: phy@8902000 { compatible = "qcom,sc8280xp-usb-hs-phy", "qcom,usb-snps-hs-5nm-phy"; diff --git a/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts b/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts index d01422844fbfd..ed55646ca419d 100644 --- a/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts +++ b/arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts @@ -404,11 +404,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sdm670/sargo/a615_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sdm670/sargo/a615_zap.mbn"; }; &i2c9 { diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi index c33f3de779f6e..b8a8dcbdfbe33 100644 --- a/arch/arm64/boot/dts/qcom/sdm670.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi @@ -1124,6 +1124,12 @@ }; }; + refgen: regulator@ff1000 { + compatible = "qcom,sdm670-refgen-regulator", + "qcom,sdm845-refgen-regulator"; + reg = <0x0 0x00ff1000 0x0 0x60>; + }; + mem_noc: interconnect@1380000 { compatible = "qcom,sdm670-mem-noc"; reg = <0 0x01380000 0 0x27200>; @@ -1376,6 +1382,10 @@ status = "disabled"; + gpu_zap_shader: zap-shader { + memory-region = <&gpu_mem>; + }; + gpu_opp_table: opp-table { compatible = "operating-points-v2"; @@ -1926,6 +1936,8 @@ phys = <&mdss_dsi0_phy>; + refgen-supply = <&refgen>; + #address-cells = <1>; #size-cells = <0>; @@ -2000,6 +2012,8 @@ phys = <&mdss_dsi1_phy>; + refgen-supply = <&refgen>; + #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index 8abf3e909502f..ce23f87e0316b 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -455,10 +455,10 @@ &gpu { status = "okay"; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sdm845/a630_zap.mbn"; - }; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sdm845/a630_zap.mbn"; }; &i2c10 { diff --git a/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi index 99dafc6716e76..0ee2f4b99fbdb 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi @@ -99,26 +99,15 @@ no-map; }; - /* rmtfs lower guard */ - memory@f0800000 { - reg = <0 0xf0800000 0 0x1000>; - no-map; - }; - - rmtfs_mem: memory@f0801000 { + rmtfs_mem: rmtfs-region@f0800000 { compatible = "qcom,rmtfs-mem"; - reg = <0 0xf0801000 0 0x200000>; + reg = <0 0xf0800000 0 0x202000>; + qcom,use-guard-pages; no-map; qcom,client-id = <1>; qcom,vmid = ; }; - - /* rmtfs upper guard */ - memory@f0a01000 { - reg = <0 0xf0a01000 0 0x1000>; - no-map; - }; }; gpio-keys { @@ -467,10 +456,6 @@ &gpu { status = "okay"; - - zap-shader { - memory-region = <&gpu_mem>; - }; }; &ipa { diff --git a/arch/arm64/boot/dts/qcom/sdm845-lg-judyln.dts b/arch/arm64/boot/dts/qcom/sdm845-lg-judyln.dts index a12723310c8b6..09bfcef424029 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-lg-judyln.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-lg-judyln.dts @@ -47,10 +47,8 @@ firmware-name = "qcom/sdm845/judyln/cdsp.mbn"; }; -&gpu { - zap-shader { - firmware-name = "qcom/sdm845/judyln/a630_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sdm845/judyln/a630_zap.mbn"; }; &mss_pil { diff --git a/arch/arm64/boot/dts/qcom/sdm845-lg-judyp.dts b/arch/arm64/boot/dts/qcom/sdm845-lg-judyp.dts index d17d4d4d56097..ffe1da2227f00 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-lg-judyp.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-lg-judyp.dts @@ -33,10 +33,8 @@ firmware-name = "qcom/sdm845/judyp/cdsp.mbn"; }; -&gpu { - zap-shader { - firmware-name = "qcom/sdm845/judyp/a630_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sdm845/judyp/a630_zap.mbn"; }; &mss_pil { diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts index 63d2993536ade..091568642faa7 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts @@ -416,11 +416,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sdm845/a630_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sdm845/a630_zap.mbn"; }; &i2c10 { diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi index dcfffb271fcf3..db6dd04c51bb5 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi @@ -75,32 +75,20 @@ }; reserved-memory { - /* - * The rmtfs_mem needs to be guarded due to "XPU limitations" - * it is otherwise possible for an allocation adjacent to the - * rmtfs_mem region to trigger an XPU violation, causing a crash. - */ - rmtfs_lower_guard: rmtfs-lower-guard@f5b00000 { - no-map; - reg = <0 0xf5b00000 0 0x1000>; - }; /* * The rmtfs memory region in downstream is 'dynamically allocated' * but given the same address every time. Hard code it as this address is * where the modem firmware expects it to be. */ - rmtfs_mem: rmtfs-mem@f5b01000 { + rmtfs_mem: rmtfs-region@f5b00000 { compatible = "qcom,rmtfs-mem"; - reg = <0 0xf5b01000 0 0x200000>; + reg = <0 0xf5b00000 0 0x202000>; + qcom,use-guard-pages; no-map; qcom,client-id = <1>; qcom,vmid = ; }; - rmtfs_upper_guard: rmtfs-upper-guard@f5d01000 { - no-map; - reg = <0 0xf5d01000 0 0x1000>; - }; /* * It seems like reserving the old rmtfs_mem region is also needed to prevent @@ -162,6 +150,34 @@ enable-active-high; regulator-boot-on; }; + + panel_vci_3v3: panel-vci-3v3-regulator { + compatible = "regulator-fixed"; + regulator-name = "LCD_VCI_3V"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 26 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-0 = <&panel_vci_default>; + pinctrl-names = "default"; + regulator-boot-on; + }; + + panel_vddi_poc_1p8: panel-vddi-poc-regulator { + compatible = "regulator-fixed"; + regulator-name = "VDDI_POC"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 25 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-0 = <&panel_poc_default>; + pinctrl-names = "default"; + regulator-boot-on; + }; }; &adsp_pas { @@ -351,11 +367,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sdm845/oneplus6/a630_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sdm845/oneplus6/a630_zap.mbn"; }; &i2c10 { @@ -429,11 +444,15 @@ reg = <0>; vddio-supply = <&vreg_l14a_1p88>; + vci-supply = <&panel_vci_3v3>; + poc-supply = <&panel_vddi_poc_1p8>; + te-gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>; reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&panel_reset_pins &panel_te_pin &panel_esd_pin>; + pinctrl-0 = <&panel_default>; + pinctrl-1 = <&panel_sleep>; + pinctrl-names = "default", "sleep"; port { panel_in: endpoint { @@ -803,39 +822,78 @@ bias-disable; }; - tri_state_key_default: tri-state-key-default-state { - pins = "gpio40", "gpio42", "gpio26"; + panel_vci_default: vci-state { + pins = "gpio26"; function = "gpio"; - drive-strength = <2>; + drive-strength = <8>; bias-disable; }; - ts_default_pins: ts-int-state { - pins = "gpio99", "gpio125"; - function = "gpio"; - drive-strength = <16>; - bias-pull-up; - }; - - panel_reset_pins: panel-reset-state { - pins = "gpio6", "gpio25", "gpio26"; + panel_poc_default: poc-state { + pins = "gpio25"; function = "gpio"; drive-strength = <8>; bias-disable; }; - panel_te_pin: panel-te-state { - pins = "gpio10"; - function = "mdp_vsync"; + alert_slider_default: alert-slider-default-state { + pins = "gpio126", "gpio52", "gpio24"; + function = "gpio"; drive-strength = <2>; bias-disable; }; - panel_esd_pin: panel-esd-state { - pins = "gpio30"; + panel_default: panel-default-state { + esd-pins { + pins = "gpio30"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + reset-pins { + pins = "gpio6"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + te-pins { + pins = "gpio10"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-disable; + }; + }; + + panel_sleep: panel-sleep-state { + esd-pins { + pins = "gpio30"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + reset-pins { + pins = "gpio6"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + te-pins { + pins = "gpio10"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-disable; + }; + }; + + ts_default_pins: ts-int-state { + pins = "gpio99", "gpio125"; function = "gpio"; - drive-strength = <2>; - bias-pull-down; + drive-strength = <16>; + bias-pull-up; }; speaker_default: speaker-default-state { diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts b/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts index 7e75decfda052..d6cd873aef0de 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts @@ -32,7 +32,7 @@ &display_panel { status = "okay"; - compatible = "samsung,s6e3fc2x01"; + compatible = "samsung,s6e3fc2x01-ams641rw", "samsung,s6e3fc2x01"; }; &i2c4 { diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts index 75a53f0bbebd0..5d41a92cfebff 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts @@ -158,7 +158,7 @@ }; }; - i2c21 { + i2c-21 { compatible = "i2c-gpio"; sda-gpios = <&tlmm 127 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; scl-gpios = <&tlmm 128 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; @@ -251,11 +251,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sdm845/starqltechn/a630_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sdm845/starqltechn/a630_zap.mbn"; }; &mdss { @@ -599,15 +598,15 @@ &i2c14 { status = "okay"; - pmic@66 { + max77705: pmic@66 { compatible = "maxim,max77705"; reg = <0x66>; + #interrupt-cells = <1>; interrupt-parent = <&pm8998_gpios>; interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; pinctrl-0 = <&pmic_int_default>; pinctrl-names = "default"; - #address-cells = <1>; - #size-cells = <0>; leds { compatible = "maxim,max77705-rgb"; @@ -646,8 +645,8 @@ reg = <0x69>; compatible = "maxim,max77705-charger"; monitored-battery = <&battery>; - interrupt-parent = <&pm8998_gpios>; - interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + interrupt-parent = <&max77705>; + interrupts = <0>; }; fuel-gauge@36 { @@ -655,8 +654,8 @@ compatible = "maxim,max77705-battery"; power-supplies = <&max77705_charger>; maxim,rsns-microohm = <5000>; - interrupt-parent = <&pm8998_gpios>; - interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + interrupt-parent = <&max77705>; + interrupts = <2>; }; }; diff --git a/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts index 89260fce65139..ddc2b3ca3bc57 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts @@ -423,31 +423,29 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sdm845/axolotl/a630_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sdm845/axolotl/a630_zap.mbn"; }; &i2c5 { status = "okay"; touchscreen@38 { - compatible = "focaltech,fts8719"; + compatible = "focaltech,ft5452"; reg = <0x38>; - wakeup-source; - interrupt-parent = <&tlmm>; - interrupts = <125 IRQ_TYPE_EDGE_FALLING>; - vdd-supply = <&vreg_l28a_3p0>; - vcc-i2c-supply = <&vreg_l14a_1p88>; - pinctrl-names = "default", "suspend"; + interrupts-extended = <&tlmm 125 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l28a_3p0>; + iovcc-supply = <&vreg_l14a_1p88>; + pinctrl-0 = <&ts_int_active &ts_reset_active>; pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; + pinctrl-names = "default", "suspend"; - reset-gpio = <&tlmm 99 GPIO_ACTIVE_HIGH>; - irq-gpio = <&tlmm 125 GPIO_TRANSITORY>; touchscreen-size-x = <1080>; touchscreen-size-y = <2160>; }; @@ -479,9 +477,6 @@ vdda-supply = <&vreg_l14a_1p88>; vdd3p3-supply = <&vreg_l28a_3p0>; - #address-cells = <1>; - #size-cells = <0>; - reset-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>; pinctrl-names = "default", "sleep"; diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi index f3f4c0900572a..7dc9349eedfd9 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi @@ -426,11 +426,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sdm845/Sony/tama/a630_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sdm845/Sony/tama/a630_zap.mbn"; }; &i2c5 { diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi index 7480c8d7ac5b7..785006a15e979 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi @@ -246,11 +246,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sdm845/beryllium/a630_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sdm845/beryllium/a630_zap.mbn"; }; &ibb { diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts index 1c50a0563bc47..30e88ff010a39 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts @@ -392,11 +392,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sdm845/polaris/a630_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sdm845/polaris/a630_zap.mbn"; }; &ibb { diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 13c9515260ef1..bf2f9c04adba7 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -2218,6 +2218,11 @@ }; }; + refgen: regulator@ff1000 { + compatible = "qcom,sdm845-refgen-regulator"; + reg = <0x0 0x00ff1000 0x0 0x60>; + }; + llcc: system-cache-controller@1100000 { compatible = "qcom,sdm845-llcc"; reg = <0 0x01100000 0 0x45000>, <0 0x01180000 0 0x50000>, @@ -4750,6 +4755,8 @@ phys = <&mdss_dsi0_phy>; + refgen-supply = <&refgen>; + status = "disabled"; #address-cells = <1>; @@ -4824,6 +4831,8 @@ phys = <&mdss_dsi1_phy>; + refgen-supply = <&refgen>; + status = "disabled"; #address-cells = <1>; @@ -4893,6 +4902,10 @@ status = "disabled"; + gpu_zap_shader: zap-shader { + memory-region = <&gpu_mem>; + }; + gpu_opp_table: opp-table { compatible = "operating-points-v2"; diff --git a/arch/arm64/boot/dts/qcom/sdm850-huawei-matebook-e-2019.dts b/arch/arm64/boot/dts/qcom/sdm850-huawei-matebook-e-2019.dts new file mode 100644 index 0000000000000..0ef9ea38a424a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm850-huawei-matebook-e-2019.dts @@ -0,0 +1,971 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Huawei MateBook E 2019 + * + * Copyright (c) 2025, Jingzhou Zhu + */ + +/dts-v1/; + +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdm850.dtsi" +#include "sdm845-wcd9340.dtsi" +#include "pm8998.dtsi" + +/* + * Update following upstream (sdm845.dtsi) reserved + * memory mappings for firmware loading to succeed + * and enable the IPA device. + */ +/delete-node/ &tz_mem; +/delete-node/ &rmtfs_mem; +/delete-node/ &qseecom_mem; +/delete-node/ &ipa_fw_mem; +/delete-node/ &ipa_gsi_mem; +/delete-node/ &gpu_mem; +/delete-node/ &adsp_mem; +/delete-node/ &wlan_msa_mem; +/delete-node/ &slpi_mem; + +/ { + model = "Huawei MateBook E 2019"; + compatible = "huawei,planck", "qcom,sdm845"; + chassis-type = "convertible"; + + aliases { + serial0 = &uart9; + serial1 = &uart6; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&volume_up_gpio &mode_pin_active>; + pinctrl-names = "default"; + + key-vol-up { + label = "Volume up"; + gpios = <&pm8998_gpios 6 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <15>; + wakeup-source; + }; + + switch-mode { + label = "Tablet mode switch"; + gpios = <&tlmm 79 GPIO_ACTIVE_HIGH>; + linux,input-type = ; + linux,code = ; + wakeup-source; + }; + }; + + leds { + compatible = "gpio-leds"; + + pinctrl-0 = <&cam_indicator_en>; + pinctrl-names = "default"; + + led: led-camera-indicator { + label = "white:camera-indicator"; + function = LED_FUNCTION_INDICATOR; + color = ; + gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "none"; + default-state = "off"; + /* Reuse as a panic indicator until we get a "camera on" trigger */ + panic-indicator; + }; + }; + + sw_edp_1p2: regulator-edp-1p2 { + compatible = "regulator-fixed"; + regulator-name = "sw_edp_1p2"; + + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + + pinctrl-0 = <&sw_edp_1p2_en>; + pinctrl-names = "default"; + + gpio = <&pm8998_gpios 9 GPIO_ACTIVE_HIGH>; + enable-active-high; + + vin-supply = <&vreg_l2a_1p2>; + }; + + vlcm_3v3: regulator-vlcm-3v3 { + compatible = "regulator-fixed"; + regulator-name = "vlcm_3v3"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 88 GPIO_ACTIVE_HIGH>; + enable-active-high; + + vin-supply = <&vph_pwr>; + }; + + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + + regulator-always-on; + }; + + reserved-memory { + cont_splash_mem: framebuffer@80100000 { + reg = <0 0x80100000 0 0xd00000>; + no-map; + }; + + tz_mem: tz@86d00000 { + reg = <0 0x86d00000 0 0x4600000>; + no-map; + }; + + qseecom_mem: qseecom@8b500000 { + reg = <0 0x8b500000 0 0xa00000>; + no-map; + }; + + wlan_msa_mem: wlan-msa@8c400000 { + reg = <0 0x8c400000 0 0x100000>; + no-map; + }; + + adsp_mem: adsp@8c500000 { + reg = <0 0x8c500000 0 0x1a00000>; + no-map; + }; + + ipa_fw_mem: ipa-fw@8df00000 { + reg = <0 0x8df00000 0 0x100000>; + no-map; + }; + + slpi_mem: slpi@96700000 { + reg = <0 0x96700000 0 0x1200000>; + }; + + gpu_mem: gpu@97900000 { + reg = <0 0x97900000 0 0x5000>; + no-map; + }; + + rmtfs_mem: rmtfs@97c00000 { + compatible = "qcom,rmtfs-mem"; + reg = <0 0x97c00000 0 0x200000>; + no-map; + + qcom,client-id = <1>; + qcom,vmid = ; + + }; + }; + + sn65dsi86_refclk: sn65dsi86-refclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + + clock-frequency = <19200000>; + }; +}; + +&adsp_pas { + firmware-name = "qcom/sdm850/HUAWEI/AL09/qcadsp850.mbn"; + + status = "okay"; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pm8998-rpmh-regulators"; + qcom,pmic-id = "a"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; + vdd-s7-supply = <&vph_pwr>; + vdd-s8-supply = <&vph_pwr>; + vdd-s9-supply = <&vph_pwr>; + vdd-s10-supply = <&vph_pwr>; + vdd-s11-supply = <&vph_pwr>; + vdd-s12-supply = <&vph_pwr>; + vdd-s13-supply = <&vph_pwr>; + vdd-l1-l27-supply = <&vreg_s7a_1p025>; + vdd-l2-l8-l17-supply = <&vreg_s3a_1p35>; + vdd-l3-l11-supply = <&vreg_s7a_1p025>; + vdd-l4-l5-supply = <&vreg_s7a_1p025>; + vdd-l6-supply = <&vph_pwr>; + vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p04>; + vdd-l26-supply = <&vreg_s3a_1p35>; + vin-lvs-1-2-supply = <&vreg_s4a_1p8>; + + vreg_s2a_1p125: smps2 { + }; + + vreg_s3a_1p35: smps3 { + regulator-min-microvolt = <1352000>; + regulator-max-microvolt = <1352000>; + regulator-initial-mode = ; + }; + + vreg_s4a_1p8: smps4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_s5a_2p04: smps5 { + regulator-min-microvolt = <2040000>; + regulator-max-microvolt = <2040000>; + regulator-initial-mode = ; + }; + + vreg_s6a_0p8: smps6 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + regulator-initial-mode = ; + }; + + vreg_s7a_1p025: smps7 { + regulator-min-microvolt = <1028000>; + regulator-max-microvolt = <1028000>; + regulator-initial-mode = ; + }; + + vdd_qusb_hs0: + vdda_hp_pcie_core: + vdda_mipi_csi0_0p9: + vdda_mipi_csi1_0p9: + vdda_mipi_csi2_0p9: + vdda_mipi_dsi0_pll: + vdda_mipi_dsi1_pll: + vdda_qlink_lv: + vdda_qlink_lv_ck: + vdda_qrefs_0p875: + vdda_pcie_core: + vdda_pll_cc_ebi01: + vdda_pll_cc_ebi23: + vdda_sp_sensor: + vdda_ufs1_core: + vdda_ufs2_core: + vdda_usb1_ss_core: + vdda_usb2_ss_core: + vreg_l1a_0p875: ldo1 { + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = ; + }; + + vddpx_10: + vreg_l2a_1p2: ldo2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-always-on; + }; + + vreg_l3a_1p0: ldo3 { + }; + + vdd_wcss_cx: + vdd_wcss_mx: + vdda_wcss_pll: + vreg_l5a_0p8: ldo5 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + regulator-initial-mode = ; + }; + + vddpx_13: + vreg_l6a_1p8: ldo6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l7a_1p8: ldo7 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vreg_l8a_1p2: ldo8 { + }; + + vreg_l9a_1p8: ldo9 { + }; + + vreg_l10a_1p8: ldo10 { + }; + + vreg_l11a_1p0: ldo11 { + }; + + vdd_qfprom: + vdd_qfprom_sp: + vdda_apc1_cs_1p8: + vdda_gfx_cs_1p8: + vdda_qrefs_1p8: + vdda_qusb_hs0_1p8: + vddpx_11: + vreg_l12a_1p8: ldo12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + + vddpx_2: + vreg_l13a_2p95: ldo13 { + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = ; + }; + + vreg_l14a_1p88: ldo14 { + regulator-min-microvolt = <1880000>; + regulator-max-microvolt = <1880000>; + regulator-initial-mode = ; + regulator-always-on; + }; + + vreg_l15a_1p8: ldo15 { + }; + + vreg_l16a_2p7: ldo16 { + }; + + vreg_l17a_1p3: ldo17 { + regulator-min-microvolt = <1304000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = ; + }; + + vreg_l18a_2p7: ldo18 { + }; + + vreg_l19a_3p0: ldo19 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = ; + }; + + vreg_l20a_2p95: ldo20 { + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = ; + }; + + vreg_l21a_2p95: ldo21 { + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = ; + }; + + vreg_l22a_2p85: ldo22 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = ; + + regulator-always-on; + }; + + vreg_l23a_3p3: ldo23 { + }; + + vdda_qusb_hs0_3p1: + vreg_l24a_3p075: ldo24 { + /* 3075000 uV causes -ENOTRECOVERABLE error */ + regulator-min-microvolt = <3088000>; + regulator-max-microvolt = <3088000>; + regulator-initial-mode = ; + }; + + vreg_l25a_3p3: ldo25 { + regulator-min-microvolt = <3104000>; + regulator-max-microvolt = <3104000>; + regulator-initial-mode = ; + }; + + vdda_hp_pcie_1p2: + vdda_hv_ebi0: + vdda_hv_ebi1: + vdda_hv_ebi2: + vdda_hv_ebi3: + vdda_mipi_csi_1p25: + vdda_mipi_dsi0_1p2: + vdda_mipi_dsi1_1p2: + vdda_pcie_1p2: + vdda_ufs1_1p2: + vdda_ufs2_1p2: + vdda_usb1_ss_1p2: + vdda_usb2_ss_1p2: + vreg_l26a_1p2: ldo26 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + }; + + vreg_l28a_3p0: ldo28 { + /* 3300000 uV causes -ENOTRECOVERABLE error */ + regulator-min-microvolt = <2856000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + }; + + vreg_lvs1a_1p8: lvs1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + vreg_lvs2a_1p8: lvs2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + }; + + regulators-1 { + compatible = "qcom,pm8005-rpmh-regulators"; + qcom,pmic-id = "c"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + + vreg_s2c_0p752: smps2 { + regulator-min-microvolt = <752000>; + regulator-max-microvolt = <752000>; + }; + }; +}; + +&cci_i2c0 { + /* chipnext,cn3927e vcm@0xc */ + /* samsung,s5k3l6 camera@0x10 */ + /* eeprom@0x50 */ +}; + +&cci_i2c1 { + /* galaxycore,gc5025 camera@0x36 */ + /* eeprom@0x50 */ +}; + +&cdsp_pas { + firmware-name = "qcom/sdm850/HUAWEI/AL09/qccdsp850.mbn"; + + status = "okay"; +}; + +&crypto { + /* FIXME: qce_start triggers an SError */ + status = "disabled"; +}; + +&gcc { + protected-clocks = , + , + , + , + ; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sdm850/HUAWEI/AL09/qcdxkmsuc850.mbn"; +}; + +&i2c5 { + clock-frequency = <400000>; + + status = "okay"; + + touchscreen: hid@5d { + compatible = "hid-over-i2c"; + reg = <0x5d>; + hid-descr-addr = <0x1>; + + interrupts-extended = <&tlmm 125 IRQ_TYPE_LEVEL_LOW>; + + pinctrl-0 = <&i2c5_hid_active>; + pinctrl-names = "default"; + + wakeup-source; + }; +}; + +&i2c7 { + /* ec@0x76 */ +}; + +&i2c10 { + clock-frequency = <400000>; + + status = "okay"; + + sn65dsi86: bridge@2c { + compatible = "ti,sn65dsi86"; + reg = <0x2c>; + + pinctrl-0 = <&sn65dsi86_pin_active>; + pinctrl-names = "default"; + + enable-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; + + vcca-supply = <&sw_edp_1p2>; + vcc-supply = <&sw_edp_1p2>; + vpll-supply = <&vreg_l14a_1p88>; + vccio-supply = <&vreg_l14a_1p88>; + + clocks = <&sn65dsi86_refclk>; + clock-names = "refclk"; + + no-hpd; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + sn65dsi86_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + sn65dsi86_out: endpoint { + remote-endpoint = <&panel_in_edp>; + }; + }; + }; + + aux-bus { + panel: panel { + compatible = "innolux,p120zdg-bf1"; + power-supply = <&vlcm_3v3>; + + port { + panel_in_edp: endpoint { + remote-endpoint = <&sn65dsi86_out>; + }; + }; + }; + }; + }; +}; + +&ipa { + qcom,gsi-loader = "self"; + memory-region = <&ipa_fw_mem>; + firmware-name = "qcom/sdm850/HUAWEI/AL09/ipa_fws.elf"; + + status = "okay"; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dsi0 { + vdda-supply = <&vdda_mipi_dsi0_1p2>; + + status = "okay"; +}; + +&mdss_dsi0_out { + remote-endpoint = <&sn65dsi86_in>; + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi0_phy { + vdds-supply = <&vdda_mipi_dsi0_pll>; + + status = "okay"; +}; + +&mss_pil { + firmware-name = "qcom/sdm850/HUAWEI/AL09/qcdsp1v2850.mbn", + "qcom/sdm850/HUAWEI/AL09/qcdsp2850.mbn"; + + status = "okay"; +}; + +&pm8998_gpios { + sw_edp_1p2_en: sw-edp-1p2-en-state { + pins = "gpio9"; + function = "normal"; + bias-disable; + qcom,drive-strength = ; + }; + + volume_up_gpio: volume-up-gpio-state { + pins = "gpio6"; + function = "normal"; + input-enable; + bias-pull-up; + qcom,drive-strength = ; + }; +}; + +&pm8998_pwrkey { + status = "okay"; +}; + +&pm8998_resin { + linux,code = ; + + status = "okay"; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&q6asmdai { + dai@0 { + reg = ; + }; + + dai@1 { + reg = ; + }; + + dai@2 { + reg = ; + }; +}; + +&sdhc_2 { + pinctrl-0 = <&sdc2_default_state &sdc2_card_det_n>; + pinctrl-names = "default"; + + vmmc-supply = <&vreg_l21a_2p95>; + vqmmc-supply = <&vddpx_2>; + + bus-width = <4>; + cd-gpios = <&tlmm 126 GPIO_ACTIVE_HIGH>; + + status = "okay"; +}; + +&slpi_pas { + firmware-name = "qcom/sdm850/HUAWEI/AL09/qcslpi850.mbn"; + + status = "okay"; +}; + +&sound { + compatible = "lenovo,yoga-c630-sndcard", "qcom,sdm845-sndcard"; + model = "HUAWEI-PAK_AL09-M1040"; + + audio-routing = "RX_BIAS", "MCLK", + "AMIC2", "MIC BIAS2", + "DMIC0", "MCLK", + "DMIC0", "MIC BIAS1", + "DMIC2", "MCLK", + "DMIC2", "MIC BIAS3", + "SpkrLeft IN", "SPK1 OUT", + "SpkrRight IN", "SPK2 OUT"; + + mm1-dai-link { + link-name = "MultiMedia1"; + + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; + }; + }; + + mm2-dai-link { + link-name = "MultiMedia2"; + + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>; + }; + }; + + mm3-dai-link { + link-name = "MultiMedia3"; + + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>; + }; + }; + + slim-dai-link { + link-name = "SLIM Playback"; + + codec { + sound-dai = <&left_spkr>, <&right_spkr>, <&swm 0>, <&wcd9340 AIF1_PB>; + }; + + cpu { + sound-dai = <&q6afedai SLIMBUS_0_RX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + }; + + slimcap-dai-link { + link-name = "SLIM Capture"; + + codec { + sound-dai = <&wcd9340 AIF1_CAP>; + }; + + cpu { + sound-dai = <&q6afedai SLIMBUS_0_TX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + }; + + slim-wcd-dai-link { + link-name = "SLIM WCD Playback"; + + codec { + sound-dai = <&wcd9340 AIF2_PB>; + }; + + cpu { + sound-dai = <&q6afedai SLIMBUS_1_RX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + }; +}; + +&tlmm { + gpio-reserved-ranges = <0 4>, /* Unused */ + <81 4>; /* SPI (fingerprint reader) */ + + cam_indicator_en: cam-indicator-en-state { + pins = "gpio12"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + i2c5_hid_active: i2c5-hid-active-state { + pins = "gpio125"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + mode_pin_active: mode-pin-state { + pins = "gpio79"; + function = "gpio"; + bias-disable; + }; + + sdc2_default_state: sdc2-default-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <16>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <16>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <16>; + bias-pull-up; + }; + }; + + sdc2_card_det_n: sd-card-det-n-state { + pins = "gpio126"; + function = "gpio"; + bias-pull-up; + }; + + sn65dsi86_pin_active: sn65dsi86-enable-state { + pins = "gpio96"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; +}; + +&uart6 { + pinctrl-0 = <&qup_uart6_4pin>; + pinctrl-names = "default"; + + status = "okay"; + + bluetooth { + compatible = "qcom,wcn3990-bt"; + + vddio-supply = <&vreg_s4a_1p8>; + vddxo-supply = <&vreg_l7a_1p8>; + vddrf-supply = <&vreg_l17a_1p3>; + vddch0-supply = <&vreg_l25a_3p3>; + vddch1-supply = <&vreg_l23a_3p3>; + max-speed = <3200000>; + }; +}; + +&uart9 { + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 150 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l20a_2p95>; + vcc-max-microamp = <600000>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vdda_ufs1_core>; + vdda-pll-supply = <&vdda_ufs1_1p2>; + + status = "okay"; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3 { + dr_mode = "host"; +}; + +&usb_1_hsphy { + vdd-supply = <&vdda_usb1_ss_core>; + vdda-pll-supply = <&vdda_qusb_hs0_1p8>; + vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>; + + qcom,imp-res-offset-value = <8>; + qcom,hstx-trim-value = ; + qcom,preemphasis-level = ; + qcom,preemphasis-width = ; + + status = "okay"; +}; + +&usb_1_qmpphy { + vdda-phy-supply = <&vdda_usb1_ss_1p2>; + vdda-pll-supply = <&vdda_usb1_ss_core>; + + status = "okay"; +}; + +&usb_2 { + status = "okay"; +}; + +&usb_2_dwc3 { + dr_mode = "host"; +}; + +&usb_2_hsphy { + vdd-supply = <&vdda_usb2_ss_core>; + vdda-pll-supply = <&vdda_qusb_hs0_1p8>; + vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>; + + qcom,imp-res-offset-value = <8>; + qcom,hstx-trim-value = ; + + status = "okay"; +}; + +&usb_2_qmpphy { + vdda-phy-supply = <&vdda_usb2_ss_1p2>; + vdda-pll-supply = <&vdda_usb2_ss_core>; + + status = "okay"; +}; + +&venus { + firmware-name = "qcom/sdm850/HUAWEI/AL09/qcvss850.mbn"; + + status = "okay"; +}; + +&wcd9340 { + reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; + vdd-rx-supply = <&vreg_s4a_1p8>; + vdd-io-supply = <&vreg_s4a_1p8>; + qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 + 500000 500000 500000 500000>; + qcom,mbhc-headset-vthreshold-microvolt = <1700000>; + qcom,mbhc-headphone-vthreshold-microvolt = <50000>; + qcom,micbias1-microvolt = <1800000>; + qcom,micbias2-microvolt = <2700000>; + qcom,micbias3-microvolt = <1800000>; + + swm: soundwire@c85 { + left_spkr: speaker@0,3 { + compatible = "sdw10217211000"; + reg = <0 3>; + powerdown-gpios = <&wcdgpio 1 GPIO_ACTIVE_LOW>; + #thermal-sensor-cells = <0>; + sound-name-prefix = "SpkrLeft"; + #sound-dai-cells = <0>; + }; + + right_spkr: speaker@0,4 { + compatible = "sdw10217211000"; + reg = <0 4>; + powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_LOW>; + #thermal-sensor-cells = <0>; + sound-name-prefix = "SpkrRight"; + #sound-dai-cells = <0>; + }; + }; +}; + +&wifi { + vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>; + vdd-1.8-xo-supply = <&vreg_l7a_1p8>; + vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; + vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; + vdd-3.3-ch1-supply = <&vreg_l23a_3p3>; + + qcom,snoc-host-cap-8bit-quirk; + qcom,calibration-variant = "Huawei_Planck"; + + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts index 90efbb7e3799b..e41200839dbec 100644 --- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts @@ -356,11 +356,10 @@ }; &gpu { - status = "okay"; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sdm850/LENOVO/81JL/qcdxkmsuc850.mbn"; - }; + status = "okay";}; + +&gpu_zap_shader { + firmware-name = "qcom/sdm850/LENOVO/81JL/qcdxkmsuc850.mbn"; }; &i2c1 { diff --git a/arch/arm64/boot/dts/qcom/sdx75-idp.dts b/arch/arm64/boot/dts/qcom/sdx75-idp.dts index 06cacec3461f1..6696e1aee2436 100644 --- a/arch/arm64/boot/dts/qcom/sdx75-idp.dts +++ b/arch/arm64/boot/dts/qcom/sdx75-idp.dts @@ -337,11 +337,9 @@ }; &usb { - status = "okay"; -}; - -&usb_dwc3 { dr_mode = "peripheral"; + + status = "okay"; }; &usb_hsphy { diff --git a/arch/arm64/boot/dts/qcom/sdx75.dtsi b/arch/arm64/boot/dts/qcom/sdx75.dtsi index 75bfc19f412c8..eff4c9055d663 100644 --- a/arch/arm64/boot/dts/qcom/sdx75.dtsi +++ b/arch/arm64/boot/dts/qcom/sdx75.dtsi @@ -1019,12 +1019,9 @@ }; }; - usb: usb@a6f8800 { - compatible = "qcom,sdx75-dwc3", "qcom,dwc3"; - reg = <0x0 0x0a6f8800 0x0 0x400>; - #address-cells = <2>; - #size-cells = <2>; - ranges; + usb: usb@a600000 { + compatible = "qcom,sdx75-dwc3", "qcom,snps-dwc3"; + reg = <0x0 0x0a600000 0x0 0xfc100>; clocks = <&gcc GCC_USB30_SLV_AHB_CLK>, <&gcc GCC_USB30_MASTER_CLK>, @@ -1041,21 +1038,35 @@ <&gcc GCC_USB30_MASTER_CLK>; assigned-clock-rates = <19200000>, <200000000>; - interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 9 IRQ_TYPE_EDGE_RISING>, <&pdc 10 IRQ_TYPE_EDGE_RISING>, + <&pdc 9 IRQ_TYPE_EDGE_RISING>, <&pdc 17 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "pwr_event", + interrupt-names = "dwc_usb3", + "pwr_event", "hs_phy_irq", - "dm_hs_phy_irq", "dp_hs_phy_irq", + "dm_hs_phy_irq", "ss_phy_irq"; + iommus = <&apps_smmu 0x80 0x0>; + + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + power-domains = <&gcc GCC_USB30_GDSC>; resets = <&gcc GCC_USB30_BCR>; + phys = <&usb_hsphy>, + <&usb_qmpphy>; + phy-names = "usb2-phy", + "usb3-phy"; + interconnects = <&system_noc MASTER_USB3_0 QCOM_ICC_TAG_ALWAYS &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS @@ -1063,38 +1074,25 @@ interconnect-names = "usb-ddr", "apps-usb"; + usb-role-switch; + status = "disabled"; - usb_dwc3: usb@a600000 { - compatible = "snps,dwc3"; - reg = <0x0 0x0a600000 0x0 0xcd00>; - interrupts = ; - iommus = <&apps_smmu 0x80 0x0>; - snps,dis_u2_susphy_quirk; - snps,dis_enblslpm_quirk; - snps,dis-u1-entry-quirk; - snps,dis-u2-entry-quirk; - phys = <&usb_hsphy>, - <&usb_qmpphy>; - phy-names = "usb2-phy", - "usb3-phy"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - usb_1_dwc3_hs: endpoint { - }; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_1_dwc3_hs: endpoint { }; + }; - port@1 { - reg = <1>; + port@1 { + reg = <1>; - usb_1_dwc3_ss: endpoint { - }; + usb_1_dwc3_ss: endpoint { }; }; }; diff --git a/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts b/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts index ad347ccd19755..466ad409e9240 100644 --- a/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts +++ b/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts @@ -121,10 +121,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/sm6115/Fxtec/QX1050/a610_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm6115/Fxtec/QX1050/a610_zap.mbn"; }; &i2c1 { diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi index 91fc36b59abf9..5e2032c26ea38 100644 --- a/arch/arm64/boot/dts/qcom/sm6115.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi @@ -1745,7 +1745,7 @@ status = "disabled"; - zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&pil_gpu_mem>; }; diff --git a/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts b/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts index c17545111f49a..be1f550fd7b50 100644 --- a/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts +++ b/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts @@ -67,10 +67,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/sm6115/LENOVO/J606F/a610_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm6115/LENOVO/J606F/a610_zap.mbn"; }; &mdss { diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi index 8459b27cacc72..f34dc6e278b8c 100644 --- a/arch/arm64/boot/dts/qcom/sm6350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi @@ -1175,18 +1175,47 @@ <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>, <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>, <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; - freq-table-hz = - <50000000 200000000>, - <0 0>, - <0 0>, - <37500000 150000000>, - <75000000 300000000>, - <0 0>, - <0 0>, - <0 0>, - <0 0>; + + operating-points-v2 = <&ufs_opp_table>; + + interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_AMPSS_M0 QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "ufs-ddr", + "cpu-ufs"; status = "disabled"; + + ufs_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-50000000 { + opp-hz = /bits/ 64 <50000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <37500000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <75000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <150000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <300000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; }; ufs_mem_phy: phy@1d87000 { @@ -1768,6 +1797,12 @@ resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; }; + refgen: regulator@88e7000 { + compatible = "qcom,sm6350-refgen-regulator", + "qcom,sm8250-refgen-regulator"; + reg = <0x0 0x088e7000 0x0 0x84>; + }; + usb_1_qmpphy: phy@88e8000 { compatible = "qcom,sm6350-qmp-usb3-dp-phy"; reg = <0x0 0x088e8000 0x0 0x3000>; @@ -2158,6 +2193,8 @@ power-domains = <&dispcc MDSS_GDSC>; iommus = <&apps_smmu 0x800 0x2>; + resets = <&dispcc DISP_CC_MDSS_CORE_BCR>; + #address-cells = <2>; #size-cells = <2>; ranges; @@ -2360,6 +2397,8 @@ phys = <&mdss_dsi0_phy>; phy-names = "dsi"; + refgen-supply = <&refgen>; + #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/qcom/sm6375.dtsi b/arch/arm64/boot/dts/qcom/sm6375.dtsi index 0faa3a40ff824..87d6600ccbd94 100644 --- a/arch/arm64/boot/dts/qcom/sm6375.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6375.dtsi @@ -971,6 +971,12 @@ status = "disabled"; }; + refgen: regulator@162f000 { + compatible = "qcom,sm6375-refgen-regulator", + "qcom,sm8250-refgen-regulator"; + reg = <0x0 0x0162f000 0x0 0x84>; + }; + spmi_bus: spmi@1c40000 { compatible = "qcom,spmi-pmic-arb"; reg = <0 0x01c40000 0 0x1100>, diff --git a/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts b/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts index f16b47b6a74c5..cb59c122f6f6a 100644 --- a/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts +++ b/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts @@ -978,6 +978,11 @@ status = "okay"; }; +&lpass_audiocc { + compatible = "qcom,qcm6490-lpassaudiocc"; + /delete-property/ power-domains; +}; + &mdss { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/sm7325.dtsi b/arch/arm64/boot/dts/qcom/sm7325.dtsi index 85d34b53e5e9d..beb279956df69 100644 --- a/arch/arm64/boot/dts/qcom/sm7325.dtsi +++ b/arch/arm64/boot/dts/qcom/sm7325.dtsi @@ -4,7 +4,7 @@ * Copyright (c) 2024, Danila Tikhonov */ -#include "sc7280.dtsi" +#include "kodiak.dtsi" /* SM7325 uses Kryo 670 */ &cpu0 { compatible = "qcom,kryo670"; }; diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi index acdba79612aa8..e3ec99972a28c 100644 --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -2255,7 +2255,7 @@ status = "disabled"; - zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&gpu_mem>; }; @@ -3469,6 +3469,12 @@ resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; }; + refgen: regulator@88e7000 { + compatible = "qcom,sm8150-refgen-regulator", + "qcom,sdm845-refgen-regulator"; + reg = <0x0 0x088e7000 0x0 0x60>; + }; + usb_1_qmpphy: phy@88e8000 { compatible = "qcom,sm8150-qmp-usb3-dp-phy"; reg = <0 0x088e8000 0 0x3000>; @@ -3992,6 +3998,8 @@ phys = <&mdss_dsi0_phy>; + refgen-supply = <&refgen>; + status = "disabled"; #address-cells = <1>; @@ -4085,6 +4093,8 @@ phys = <&mdss_dsi1_phy>; + refgen-supply = <&refgen>; + status = "disabled"; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts index 7f592bd302486..51779b99176d0 100644 --- a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts @@ -484,11 +484,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sm8250/a650_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8250/a650_zap.mbn"; }; &i2c1 { diff --git a/arch/arm64/boot/dts/qcom/sm8250-samsung-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-samsung-common.dtsi index cf3d917addd82..ef7ea4f72bf99 100644 --- a/arch/arm64/boot/dts/qcom/sm8250-samsung-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250-samsung-common.dtsi @@ -159,7 +159,8 @@ }; &tlmm { - gpio-reserved-ranges = <40 4>; /* I2C (Unused) */ + gpio-reserved-ranges = <20 4>, /* SPI (fingerprint scanner) */ + <40 4>; /* Unused */ }; &usb_1 { diff --git a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi index 465fd6e954a34..c017399297b9d 100644 --- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi @@ -554,11 +554,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sm8250/xiaomi/elish/a650_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8250/xiaomi/elish/a650_zap.mbn"; }; &i2c0 { diff --git a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-pipa.dts b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-pipa.dts index 4ad24974c09f9..078ba13f8762e 100644 --- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-pipa.dts +++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-pipa.dts @@ -424,11 +424,10 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_mem>; - firmware-name = "qcom/sm8250/xiaomi/pipa/a650_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8250/xiaomi/pipa/a650_zap.mbn"; }; &i2c11 { diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index 50dd11432bb2e..c7dffa4400740 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -2944,7 +2944,7 @@ status = "disabled"; - zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&gpu_mem>; }; @@ -3901,6 +3901,11 @@ resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; }; + refgen: regulator@88e7000 { + compatible = "qcom,sm8250-refgen-regulator"; + reg = <0x0 0x088e7000 0x0 0x84>; + }; + usb_1_qmpphy: phy@88e8000 { compatible = "qcom,sm8250-qmp-usb3-dp-phy"; reg = <0 0x088e8000 0 0x3000>; @@ -4679,6 +4684,8 @@ iommus = <&apps_smmu 0x820 0x402>; + resets = <&dispcc DISP_CC_MDSS_CORE_BCR>; + status = "disabled"; #address-cells = <2>; @@ -4873,6 +4880,8 @@ phys = <&mdss_dsi0_phy>; + refgen-supply = <&refgen>; + status = "disabled"; #address-cells = <1>; @@ -4967,6 +4976,8 @@ phys = <&mdss_dsi1_phy>; + refgen-supply = <&refgen>; + status = "disabled"; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts index 24a8c91e9f70f..5f975d0094658 100644 --- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts +++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts @@ -403,10 +403,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/sm8350/a660_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8350/a660_zap.mbn"; }; &i2c13 { diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index fc4ce9d4977e8..5c8fe213f5e4e 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -2051,7 +2051,7 @@ status = "disabled"; - zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&pil_gpu_mem>; }; diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts index 0c6aa7ddf4326..268ae0cd642a7 100644 --- a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts +++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts @@ -643,10 +643,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/sm8450/a730_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8450/a730_zap.mbn"; }; &i2c9 { diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index 23420e6924728..920a2d1c04d0c 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -2047,25 +2047,28 @@ pcie0_opp_table: opp-table { compatible = "operating-points-v2"; - /* GEN 1 x1 */ + /* 2.5 GT/s x1 */ opp-2500000 { opp-hz = /bits/ 64 <2500000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <250000 1>; + opp-level = <1>; }; - /* GEN 2 x1 */ + /* 5 GT/s x1 */ opp-5000000 { opp-hz = /bits/ 64 <5000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <500000 1>; + opp-level = <2>; }; - /* GEN 3 x1 */ + /* 8 GT/s x1 */ opp-8000000 { opp-hz = /bits/ 64 <8000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <984500 1>; + opp-level = <3>; }; }; @@ -2209,46 +2212,68 @@ pcie1_opp_table: opp-table { compatible = "operating-points-v2"; - /* GEN 1 x1 */ - opp-2500000 { + /* 2.5 GT/s x1 */ + opp-2500000-1 { opp-hz = /bits/ 64 <2500000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <250000 1>; + opp-level = <1>; }; - /* GEN 1 x2 and GEN 2 x1 */ - opp-5000000 { + /* 2.5 GT/s x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* 5 GT/s x1 */ + opp-5000000-2 { opp-hz = /bits/ 64 <5000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <500000 1>; + opp-level = <2>; }; - /* GEN 2 x2 */ - opp-10000000 { + /* 5 GT/s x2 */ + opp-10000000-2 { opp-hz = /bits/ 64 <10000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <1000000 1>; + opp-level = <2>; }; - /* GEN 3 x1 */ - opp-8000000 { + /* 8 GT/s x1 */ + opp-8000000-3 { opp-hz = /bits/ 64 <8000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* 8 GT/s x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; }; - /* GEN 3 x2 and GEN 4 x1 */ - opp-16000000 { + /* 16 GT/s x1 */ + opp-16000000-4 { opp-hz = /bits/ 64 <16000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <1969000 1>; + opp-level = <4>; }; - /* GEN 4 x2 */ - opp-32000000 { + /* 16 GT/s x2 */ + opp-32000000-4 { opp-hz = /bits/ 64 <32000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <3938000 1>; + opp-level = <4>; }; }; @@ -2434,7 +2459,7 @@ status = "disabled"; - zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&gpu_micro_code_mem>; }; diff --git a/arch/arm64/boot/dts/qcom/sm8550-hdk-rear-camera-card.dtso b/arch/arm64/boot/dts/qcom/sm8550-hdk-rear-camera-card.dtso new file mode 100644 index 0000000000000..66bec0fef7665 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm8550-hdk-rear-camera-card.dtso @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * SM8550-HDK Rear Camera Card overlay + * + * Copyright (c) 2025, Linaro Limited + */ + +#include +#include +#include + +/dts-v1/; +/plugin/; + +&camss { + status = "okay"; + + vdda-phy-supply = <&vreg_l1e_0p88>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@3 { + reg = <3>; + + csiphy3_ep: endpoint { + clock-lanes = <4>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&cam_tele>; + }; + }; + }; +}; + +&cci1 { + status = "okay"; +}; + +&cci1_i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + sensor@10 { + compatible = "samsung,s5k3m5"; + reg = <0x10>; + clocks = <&camcc CAM_CC_MCLK3_CLK>; + assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>; + assigned-clock-rates = <24000000>; + reset-gpios = <&tlmm 119 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&cam3_default>; + pinctrl-names = "default"; + afvdd-supply = <&vreg_l7n_2p96>; + avdd-supply = <&vreg_l4m_2p8>; + dovdd-supply = <&vreg_l5n_1p8>; + dvdd-supply = <&vreg_l2m_1p056>; + + port { + cam_tele: endpoint { + link-frequencies = /bits/ 64 <602500000>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&csiphy3_ep>; + }; + }; + }; +}; + +&pm8550_flash { + status = "okay"; + + led-0 { + function = LED_FUNCTION_FLASH; + color = ; + led-sources = <1>, <4>; + led-max-microamp = <500000>; + flash-max-microamp = <2000000>; + flash-max-timeout-us = <1280000>; + function-enumerator = <0>; + }; + + led-1 { + function = LED_FUNCTION_FLASH; + color = ; + led-sources = <2>, <3>; + led-max-microamp = <500000>; + flash-max-microamp = <2000000>; + flash-max-timeout-us = <1280000>; + function-enumerator = <1>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8550-hdk.dts b/arch/arm64/boot/dts/qcom/sm8550-hdk.dts index b5d7f0cd443a1..599850c48494b 100644 --- a/arch/arm64/boot/dts/qcom/sm8550-hdk.dts +++ b/arch/arm64/boot/dts/qcom/sm8550-hdk.dts @@ -955,10 +955,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/sm8550/a740_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8550/a740_zap.mbn"; }; &lpass_tlmm { diff --git a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts index 38f2928f23cc3..f430038bd402c 100644 --- a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts @@ -642,10 +642,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/sm8550/a740_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8550/a740_zap.mbn"; }; &i2c_master_hub_0 { diff --git a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts index a3f4200a1145d..05c98fe2c25be 100644 --- a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts +++ b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts @@ -716,6 +716,52 @@ }; }; +&camss { + status = "okay"; + + vdda-phy-supply = <&vreg_l1e_0p88>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + ports { + port@3 { + csiphy3_ep: endpoint { + clock-lanes = <4>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&cam_tele>; + }; + }; + }; +}; + +&cci1 { + status = "okay"; +}; + +&cci1_i2c0 { + sensor@10 { + compatible = "samsung,s5k3m5"; + reg = <0x10>; + clocks = <&camcc CAM_CC_MCLK3_CLK>; + assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>; + assigned-clock-rates = <24000000>; + reset-gpios = <&tlmm 119 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&cam3_default>; + pinctrl-names = "default"; + afvdd-supply = <&vreg_l7n_2p96>; + avdd-supply = <&vreg_l4m_2p8>; + dovdd-supply = <&vreg_l5n_1p8>; + dvdd-supply = <&vreg_l2m_1p056>; + + port { + cam_tele: endpoint { + link-frequencies = /bits/ 64 <602500000>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&csiphy3_ep>; + }; + }; + }; +}; + &i2c_master_hub_0 { status = "okay"; }; @@ -789,10 +835,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/sm8550/a740_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8550/a740_zap.mbn"; }; &lpass_tlmm { diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index 7724dba75db79..2ca9e50ef5994 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -2027,39 +2027,52 @@ pcie0_opp_table: opp-table { compatible = "operating-points-v2"; - /* GEN 1 x1 */ - opp-2500000 { + /* 2.5 GT/s x1 */ + opp-2500000-1 { opp-hz = /bits/ 64 <2500000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <250000 1>; + opp-level = <1>; }; - /* GEN 1 x2 and GEN 2 x1 */ - opp-5000000 { + /* 2.5 GT/s x2 */ + opp-5000000-1 { opp-hz = /bits/ 64 <5000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <500000 1>; + opp-level = <1>; }; - /* GEN 2 x2 */ - opp-10000000 { + /* 5 GT/s x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* 5 GT/s x2 */ + opp-10000000-2 { opp-hz = /bits/ 64 <10000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <1000000 1>; + opp-level = <2>; }; - /* GEN 3 x1 */ - opp-8000000 { + /* 8 GT/s x1 */ + opp-8000000-3 { opp-hz = /bits/ 64 <8000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <984500 1>; + opp-level = <3>; }; - /* GEN 3 x2 */ - opp-16000000 { + /* 8 GT/s x2 */ + opp-16000000-3 { opp-hz = /bits/ 64 <16000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <1969000 1>; + opp-level = <3>; }; }; @@ -2194,46 +2207,68 @@ pcie1_opp_table: opp-table { compatible = "operating-points-v2"; - /* GEN 1 x1 */ - opp-2500000 { + /* 2.5 GT/s x1 */ + opp-2500000-1 { opp-hz = /bits/ 64 <2500000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* 2.5 GT/s x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; }; - /* GEN 1 x2 and GEN 2 x1 */ - opp-5000000 { + /* 5 GT/s x1 */ + opp-5000000-2 { opp-hz = /bits/ 64 <5000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <500000 1>; + opp-level = <2>; }; - /* GEN 2 x2 */ - opp-10000000 { + /* 5 GT/s x2 */ + opp-10000000-2 { opp-hz = /bits/ 64 <10000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <1000000 1>; + opp-level = <2>; }; - /* GEN 3 x1 */ - opp-8000000 { + /* 8 GT/s x1 */ + opp-8000000-3 { opp-hz = /bits/ 64 <8000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* 8 GT/s x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; }; - /* GEN 3 x2 and GEN 4 x1 */ - opp-16000000 { + /* 16 GT/s x1 */ + opp-16000000-4 { opp-hz = /bits/ 64 <16000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <1969000 1>; + opp-level = <4>; }; - /* GEN 4 x2 */ - opp-32000000 { + /* 16 GT/s x2 */ + opp-32000000-4 { opp-hz = /bits/ 64 <32000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <3938000 1>; + opp-level = <4>; }; }; @@ -2456,7 +2491,7 @@ status = "disabled"; - zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&gpu_micro_code_mem>; }; @@ -3189,6 +3224,7 @@ &config_noc SLAVE_SDCC_2 QCOM_ICC_TAG_ACTIVE_ONLY>; interconnect-names = "sdhc-ddr", "cpu-sdhc"; bus-width = <4>; + max-sd-hs-hz = <37500000>; dma-coherent; /* Forbid SDR104/SDR50 - broken hw! */ @@ -4277,6 +4313,150 @@ gpio-ranges = <&tlmm 0 0 211>; wakeup-parent = <&pdc>; + cam0_default: cam0-default-state { + mclk-pins { + pins = "gpio100"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + }; + + cam0_sleep: cam0-sleep-state { + mclk-pins { + pins = "gpio100"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cam1_default: cam1-default-state { + mclk-pins { + pins = "gpio101"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + }; + + cam1_sleep: cam1-sleep-state { + mclk-pins { + pins = "gpio101"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cam2_default: cam2-default-state { + mclk-pins { + pins = "gpio102"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + }; + + cam2_sleep: cam2-sleep-state { + mclk-pins { + pins = "gpio102"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cam3_default: cam3-default-state { + mclk-pins { + pins = "gpio103"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + }; + + cam3_sleep: cam3-sleep-state { + mclk-pins { + pins = "gpio103"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cam4_default: cam4-default-state { + mclk-pins { + pins = "gpio104"; + function = "cam_aon_mclk4"; + drive-strength = <2>; + bias-disable; + }; + }; + + cam4_sleep: cam4-sleep-state { + mclk-pins { + pins = "gpio104"; + function = "cam_aon_mclk4"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cam5_default: cam5-default-state { + mclk-pins { + pins = "gpio105"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + }; + + cam5_sleep: cam5-sleep-state { + mclk-pins { + pins = "gpio105"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cam6_default: cam6-default-state { + mclk-pins { + pins = "gpio106"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + }; + + cam6_sleep: cam6-sleep-state { + mclk-pins { + pins = "gpio106"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + cam7_default: cam7-default-state { + mclk-pins { + pins = "gpio107"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + }; + + cam7_sleep: cam7-sleep-state { + mclk-pins { + pins = "gpio107"; + function = "cam_mclk"; + drive-strength = <2>; + bias-pull-down; + }; + }; + cci0_0_default: cci0-0-default-state { sda-pins { pins = "gpio110"; diff --git a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts index 87d7190dc991b..5bf1af3308ceb 100644 --- a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts +++ b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts @@ -900,10 +900,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/sm8650/gen70900_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8650/gen70900_zap.mbn"; }; &lpass_tlmm { diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts index 9e790cf44804d..b2feac61a89f2 100644 --- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts +++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts @@ -830,10 +830,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/sm8650/gen70900_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/sm8650/gen70900_zap.mbn"; }; &lpass_tlmm { diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi index ebf1971b1bfbe..07ae74851621f 100644 --- a/arch/arm64/boot/dts/qcom/sm8650.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi @@ -3659,39 +3659,52 @@ pcie0_opp_table: opp-table { compatible = "operating-points-v2"; - /* GEN 1 x1 */ - opp-2500000 { + /* 2.5 GT/s x1 */ + opp-2500000-1 { opp-hz = /bits/ 64 <2500000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <250000 1>; + opp-level = <1>; }; - /* GEN 1 x2 and GEN 2 x1 */ - opp-5000000 { + /* 2.5 GT/s x2 */ + opp-5000000-1 { opp-hz = /bits/ 64 <5000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <500000 1>; + opp-level = <1>; }; - /* GEN 2 x2 */ - opp-10000000 { + /* 5 GT/s x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* 5 GT/s x2 */ + opp-10000000-2 { opp-hz = /bits/ 64 <10000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <1000000 1>; + opp-level = <2>; }; - /* GEN 3 x1 */ - opp-8000000 { + /* 8 GT/s x1 */ + opp-8000000-3 { opp-hz = /bits/ 64 <8000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <984500 1>; + opp-level = <3>; }; - /* GEN 3 x2 */ - opp-16000000 { + /* 8 GT/s x2 */ + opp-16000000-3 { opp-hz = /bits/ 64 <16000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <1969000 1>; + opp-level = <3>; }; }; @@ -3839,46 +3852,68 @@ pcie1_opp_table: opp-table { compatible = "operating-points-v2"; - /* GEN 1 x1 */ - opp-2500000 { + /* 2.5 GT/s x1 */ + opp-2500000-1 { opp-hz = /bits/ 64 <2500000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <250000 1>; + opp-level = <1>; }; - /* GEN 1 x2 and GEN 2 x1 */ - opp-5000000 { + /* 2.5 GT/s x2 */ + opp-5000000-1 { opp-hz = /bits/ 64 <5000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <500000 1>; + opp-level = <1>; }; - /* GEN 2 x2 */ - opp-10000000 { + /* 5 GT/s x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* 5 GT/s x2 */ + opp-10000000-2 { opp-hz = /bits/ 64 <10000000>; required-opps = <&rpmhpd_opp_low_svs>; opp-peak-kBps = <1000000 1>; + opp-level = <2>; }; - /* GEN 3 x1 */ - opp-8000000 { + /* 8 GT/s x1 */ + opp-8000000-3 { opp-hz = /bits/ 64 <8000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* 8 GT/s x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; }; - /* GEN 3 x2 and GEN 4 x1 */ - opp-16000000 { + /* 16 GT/s x1 */ + opp-16000000-4 { opp-hz = /bits/ 64 <16000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <1969000 1>; + opp-level = <4>; }; - /* GEN 4 x2 */ - opp-32000000 { + /* 16 GT/s x2 */ + opp-32000000-4 { opp-hz = /bits/ 64 <32000000>; required-opps = <&rpmhpd_opp_nom>; opp-peak-kBps = <3938000 1>; + opp-level = <4>; }; }; @@ -3988,6 +4023,8 @@ iommus = <&apps_smmu 0x60 0>; + dma-coherent; + lanes-per-direction = <2>; qcom,ice = <&ice>; @@ -4121,7 +4158,7 @@ status = "disabled"; - zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&gpu_micro_code_mem>; }; diff --git a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts index 3bbb53b7c71f3..c8cb521b4c26c 100644 --- a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts @@ -191,6 +191,51 @@ }; }; + pmic-glink { + compatible = "qcom,sm8750-pmic-glink", + "qcom,sm8550-pmic-glink", + "qcom,pmic-glink"; + #address-cells = <1>; + #size-cells = <0>; + orientation-gpios = <&tlmm 61 GPIO_ACTIVE_HIGH>; + + connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&usb_dp_qmpphy_out>; + }; + }; + + port@2 { + reg = <2>; + + pmic_glink_sbu: endpoint { + }; + }; + }; + }; + }; + vph_pwr: vph-pwr-regulator { compatible = "regulator-fixed"; @@ -960,9 +1005,6 @@ }; &pcie0 { - wake-gpios = <&tlmm 104 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -977,6 +1019,9 @@ }; &pcieport0 { + wake-gpios = <&tlmm 104 GPIO_ACTIVE_HIGH>; + reset-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; + wifi@0 { compatible = "pci17cb,1107"; reg = <0x10000 0x0 0x0 0x0 0x0>; @@ -1200,3 +1245,31 @@ status = "okay"; }; + +&usb { + status = "okay"; +}; + +&usb_dp_qmpphy { + vdda-phy-supply = <&vreg_l3g_1p2>; + vdda-pll-supply = <&vreg_l2d_0p88>; + + status = "okay"; +}; + +&usb_dp_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +}; + +&usb_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_hsphy { + vdd-supply = <&vreg_l2d_0p88>; + vdda12-supply = <&vreg_l3g_1p2>; + + phys = <&pmih0108_eusb2_repeater>; + + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts index 13c7b9664c89c..b0cb61c5a6034 100644 --- a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts +++ b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts @@ -193,6 +193,51 @@ }; }; + pmic-glink { + compatible = "qcom,sm8750-pmic-glink", + "qcom,sm8550-pmic-glink", + "qcom,pmic-glink"; + #address-cells = <1>; + #size-cells = <0>; + orientation-gpios = <&tlmm 61 GPIO_ACTIVE_HIGH>; + + connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&usb_dp_qmpphy_out>; + }; + }; + + port@2 { + reg = <2>; + + pmic_glink_sbu: endpoint { + }; + }; + }; + }; + }; + vph_pwr: vph-pwr-regulator { compatible = "regulator-fixed"; @@ -1054,3 +1099,31 @@ status = "okay"; }; + +&usb { + status = "okay"; +}; + +&usb_dp_qmpphy { + vdda-phy-supply = <&vreg_l3g_1p2>; + vdda-pll-supply = <&vreg_l2d_0p88>; + + status = "okay"; +}; + +&usb_dp_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +}; + +&usb_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_hsphy { + vdd-supply = <&vreg_l2d_0p88>; + vdda12-supply = <&vreg_l3g_1p2>; + + phys = <&pmih0108_eusb2_repeater>; + + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index a82d9867c7cb6..3f0b57f428bbb 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -635,7 +636,7 @@ <0>, <0>, <0>, - <0>; + <&usb_dp_qmpphy QMP_USB43DP_USB3_PIPE_CLK>; #clock-cells = <1>; #reset-cells = <1>; @@ -2581,6 +2582,164 @@ }; }; + usb_hsphy: phy@88e3000 { + compatible = "qcom,sm8750-m31-eusb2-phy"; + reg = <0x0 0x88e3000 0x0 0x29c>; + + clocks = <&tcsrcc TCSR_USB2_CLKREF_EN>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; + + #phy-cells = <0>; + + status = "disabled"; + }; + + usb_dp_qmpphy: phy@88e8000 { + compatible = "qcom,sm8750-qmp-usb3-dp-phy"; + reg = <0x0 0x088e8000 0x0 0x4000>; + + clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, + <&tcsrcc TCSR_USB3_CLKREF_EN>, + <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; + clock-names = "aux", + "ref", + "com_aux", + "usb3_pipe"; + + resets = <&gcc GCC_USB3_PHY_PRIM_BCR>, + <&gcc GCC_USB3_DP_PHY_PRIM_BCR>; + reset-names = "phy", + "common"; + + power-domains = <&gcc GCC_USB3_PHY_GDSC>; + + #clock-cells = <1>; + #phy-cells = <1>; + + orientation-switch; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_dp_qmpphy_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_dp_qmpphy_usb_ss_in: endpoint { + remote-endpoint = <&usb_dwc3_ss>; + }; + }; + + port@2 { + reg = <2>; + + usb_dp_qmpphy_dp_in: endpoint { + }; + }; + }; + }; + + usb: usb@a600000 { + compatible = "qcom,sm8750-dwc3", "qcom,snps-dwc3"; + reg = <0x0 0x0a600000 0x0 0xfc100>; + + clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>, + <&gcc GCC_USB30_PRIM_MASTER_CLK>, + <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>, + <&gcc GCC_USB30_PRIM_SLEEP_CLK>, + <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>; + clock-names = "cfg_noc", + "core", + "iface", + "sleep", + "mock_utmi"; + + assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_PRIM_MASTER_CLK>; + assigned-clock-rates = <19200000>, + <200000000>; + + interrupts-extended = <&intc GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 14 IRQ_TYPE_EDGE_BOTH>, + <&pdc 15 IRQ_TYPE_EDGE_BOTH>, + <&pdc 17 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "dwc_usb3", + "pwr_event", + "hs_phy_irq", + "dp_hs_phy_irq", + "dm_hs_phy_irq", + "ss_phy_irq"; + + power-domains = <&gcc GCC_USB30_PRIM_GDSC>; + required-opps = <&rpmhpd_opp_nom>; + + resets = <&gcc GCC_USB30_PRIM_BCR>; + + interconnects = <&aggre1_noc MASTER_USB3_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_USB3_0 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "usb-ddr", "apps-usb"; + + iommus = <&apps_smmu 0x40 0x0>; + + phys = <&usb_hsphy>, + <&usb_dp_qmpphy QMP_USB43DP_USB3_PHY>; + phy-names = "usb2-phy", + "usb3-phy"; + + snps,hird-threshold = /bits/ 8 <0x0>; + snps,usb2-gadget-lpm-disable; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + snps,is-utmi-l1-suspend; + snps,usb3_lpm_capable; + snps,usb2-lpm-disable; + snps,has-lpm-erratum; + tx-fifo-resize; + + dma-coherent; + usb-role-switch; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_dwc3_hs: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_dwc3_ss: endpoint { + remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>; + }; + }; + }; + }; + pdc: interrupt-controller@b220000 { compatible = "qcom,sm8750-pdc", "qcom,pdc"; reg = <0x0 0x0b220000 0x0 0x10000>, <0x0 0x164400f0 0x0 0x64>; diff --git a/arch/arm64/boot/dts/qcom/sm6150.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi similarity index 92% rename from arch/arm64/boot/dts/qcom/sm6150.dtsi rename to arch/arm64/boot/dts/qcom/talos.dtsi index 3d2a1cb02b628..d1dbfa3bd81c3 100644 --- a/arch/arm64/boot/dts/qcom/sm6150.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi @@ -3,6 +3,7 @@ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. */ +#include #include #include #include @@ -11,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +41,10 @@ clocks = <&cpufreq_hw 0>; qcom,freq-domain = <&cpufreq_hw 0>; #cooling-cells = <2>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; l2_0: l2-cache { compatible = "cache"; @@ -60,6 +66,10 @@ next-level-cache = <&l2_100>; clocks = <&cpufreq_hw 0>; qcom,freq-domain = <&cpufreq_hw 0>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; l2_100: l2-cache { compatible = "cache"; @@ -81,6 +91,10 @@ next-level-cache = <&l2_200>; clocks = <&cpufreq_hw 0>; qcom,freq-domain = <&cpufreq_hw 0>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; l2_200: l2-cache { compatible = "cache"; @@ -102,6 +116,10 @@ next-level-cache = <&l2_300>; clocks = <&cpufreq_hw 0>; qcom,freq-domain = <&cpufreq_hw 0>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; l2_300: l2-cache { compatible = "cache"; @@ -123,6 +141,10 @@ next-level-cache = <&l2_400>; clocks = <&cpufreq_hw 0>; qcom,freq-domain = <&cpufreq_hw 0>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; l2_400: l2-cache { compatible = "cache"; @@ -144,6 +166,10 @@ next-level-cache = <&l2_500>; clocks = <&cpufreq_hw 0>; qcom,freq-domain = <&cpufreq_hw 0>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; l2_500: l2-cache { compatible = "cache"; @@ -166,6 +192,10 @@ clocks = <&cpufreq_hw 1>; qcom,freq-domain = <&cpufreq_hw 1>; #cooling-cells = <2>; + operating-points-v2 = <&cpu6_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; l2_600: l2-cache { compatible = "cache"; @@ -187,6 +217,10 @@ next-level-cache = <&l2_700>; clocks = <&cpufreq_hw 1>; qcom,freq-domain = <&cpufreq_hw 1>; + operating-points-v2 = <&cpu6_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; l2_700: l2-cache { compatible = "cache"; @@ -239,6 +273,111 @@ }; }; + cpu0_opp_table: opp-table-cpu0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-peak-kBps = <(300000 * 4) (300000 * 16)>; + }; + + opp-576000000 { + opp-hz = /bits/ 64 <576000000>; + opp-peak-kBps = <(300000 * 4) (576000 * 16)>; + }; + + opp-748800000 { + opp-hz = /bits/ 64 <748800000>; + opp-peak-kBps = <(300000 * 4) (576000 * 16)>; + }; + + opp-998400000 { + opp-hz = /bits/ 64 <998400000>; + opp-peak-kBps = <(451000 * 4) (806400 * 16)>; + }; + + opp-1209600000 { + opp-hz = /bits/ 64 <1209600000>; + opp-peak-kBps = <(547000 * 4) (1017600 * 16)>; + }; + + opp-1363200000 { + opp-hz = /bits/ 64 <1363200000>; + opp-peak-kBps = <(768000 * 4) (1209600 * 16)>; + }; + + opp-1516800000 { + opp-hz = /bits/ 64 <1516800000>; + opp-peak-kBps = <(768000 * 4) (1209600 * 16)>; + }; + + opp-1593600000 { + opp-hz = /bits/ 64 <1593600000>; + opp-peak-kBps = <(1017000 * 4) (1363200 * 16)>; + }; + }; + + cpu6_opp_table: opp-table-cpu6 { + compatible = "operating-points-v2"; + opp-shared; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-peak-kBps = <(451000 * 4) (300000 * 16)>; + }; + + opp-652800000 { + opp-hz = /bits/ 64 <652800000>; + opp-peak-kBps = <(451000 * 4) (576000 * 16)>; + }; + + opp-768000000 { + opp-hz = /bits/ 64 <768000000>; + opp-peak-kBps = <(451000 * 4) (576000 * 16)>; + }; + + opp-979200000 { + opp-hz = /bits/ 64 <979200000>; + opp-peak-kBps = <(547000 * 4) (806400 * 16)>; + }; + + opp-1017600000 { + opp-hz = /bits/ 64 <1017600000>; + opp-peak-kBps = <(547000 * 4) (806400 * 16)>; + }; + + opp-1094400000 { + opp-hz = /bits/ 64 <109440000>; + opp-peak-kBps = <(1017600 * 4) (940800 * 16)>; + }; + + opp-1209600000 { + opp-hz = /bits/ 64 <1209600000>; + opp-peak-kBps = <(1017600 * 4) (1017600 * 16)>; + }; + + opp-1363200000 { + opp-hz = /bits/ 64 <1363200000>; + opp-peak-kBps = <(1555000 * 4) (1209600 * 16)>; + }; + + opp-1516800000 { + opp-hz = /bits/ 64 <1516800000>; + opp-peak-kBps = <(1555000 * 4) (1209600 * 16)>; + }; + + opp-1708800000 { + opp-hz = /bits/ 64 <1708800000>; + opp-peak-kBps = <(1555000 * 4) (1363200 * 16)>; + }; + + opp-1900800000 { + opp-hz = /bits/ 64 <1900800000>; + opp-peak-kBps = <(1555000 * 4) (1363200 * 16)>; + }; + }; + dummy_eud: dummy-sink { compatible = "arm,coresight-dummy-sink"; @@ -3657,14 +3796,191 @@ #power-domain-cells = <1>; }; + mdss: display-subsystem@ae00000 { + compatible = "qcom,sm6150-mdss"; + reg = <0x0 0x0ae00000 0x0 0x1000>; + reg-names = "mdss"; + + interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "mdp0-mem", + "cpu-cfg"; + + power-domains = <&dispcc MDSS_CORE_GDSC>; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>; + + interrupts = ; + interrupt-controller; + #interrupt-cells = <1>; + + iommus = <&apps_smmu 0x800 0x0>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + status = "disabled"; + + mdss_mdp: display-controller@ae01000 { + compatible = "qcom,sm6150-dpu"; + reg = <0x0 0x0ae01000 0x0 0x8f000>, + <0x0 0x0aeb0000 0x0 0x2008>; + reg-names = "mdp", + "vbif"; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>, + <&dispcc DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "iface", + "bus", + "core", + "vsync"; + + operating-points-v2 = <&mdp_opp_table>; + power-domains = <&rpmhpd RPMHPD_CX>; + + interrupts-extended = <&mdss 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dpu_intf0_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + + dpu_intf1_out: endpoint { + remote-endpoint = <&mdss_dsi0_in>; + }; + }; + }; + + mdp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-192000000 { + opp-hz = /bits/ 64 <192000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-256000000 { + opp-hz = /bits/ 64 <256000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-307200000 { + opp-hz = /bits/ 64 <307200000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + mdss_dsi0: dsi@ae94000 { + compatible = "qcom,sm6150-dsi-ctrl", "qcom,mdss-dsi-ctrl"; + reg = <0x0 0x0ae94000 0x0 0x400>; + reg-names = "dsi_ctrl"; + + interrupts-extended = <&mdss 4>; + + clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>, + <&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>, + <&dispcc DISP_CC_MDSS_PCLK0_CLK>, + <&dispcc DISP_CC_MDSS_ESC0_CLK>, + <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>; + clock-names = "byte", + "byte_intf", + "pixel", + "core", + "iface", + "bus"; + + assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>, + <&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>; + assigned-clock-parents = <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>, + <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>; + + operating-points-v2 = <&dsi0_opp_table>; + power-domains = <&rpmhpd RPMHPD_CX>; + + phys = <&mdss_dsi0_phy>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + dsi0_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-164000000 { + opp-hz = /bits/ 64 <164000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mdss_dsi0_in: endpoint { + remote-endpoint = <&dpu_intf1_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dsi0_out: endpoint { + }; + }; + }; + }; + + mdss_dsi0_phy: phy@ae94400 { + compatible = "qcom,sm6150-dsi-phy-14nm"; + reg = <0x0 0x0ae94400 0x0 0x100>, + <0x0 0x0ae94500 0x0 0x300>, + <0x0 0x0ae94800 0x0 0x124>; + reg-names = "dsi_phy", + "dsi_phy_lane", + "dsi_pll"; + + #clock-cells = <1>; + #phy-cells = <0>; + + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&rpmhcc RPMH_CXO_CLK>; + clock-names = "iface", + "ref"; + + status = "disabled"; + }; + }; + dispcc: clock-controller@af00000 { compatible = "qcom,qcs615-dispcc"; reg = <0 0x0af00000 0 0x20000>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_DISP_GPLL0_DIV_CLK_SRC>, - <0>, - <0>, + <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>, + <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>, <0>, <0>, <0>; @@ -3978,6 +4294,16 @@ }; }; + osm_l3: interconnect@18321000 { + compatible = "qcom,qcs615-osm-l3", "qcom,sm8150-osm-l3", "qcom,osm-l3"; + reg = <0x0 0x18321000 0x0 0x1400>; + + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>; + clock-names = "xo", "alternate"; + + #interconnect-cells = <1>; + }; + usb_1_hsphy: phy@88e2000 { compatible = "qcom,qcs615-qusb2-phy"; reg = <0x0 0x88e2000 0x0 0x180>; diff --git a/arch/arm64/boot/dts/qcom/x1-asus-zenbook-a14.dtsi b/arch/arm64/boot/dts/qcom/x1-asus-zenbook-a14.dtsi index ee3c8c5e2c50c..8e5c5575a5320 100644 --- a/arch/arm64/boot/dts/qcom/x1-asus-zenbook-a14.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-asus-zenbook-a14.dtsi @@ -11,10 +11,9 @@ #include #include -#include "x1e80100-pmics.dtsi" +#include "hamoa-pmics.dtsi" / { - model = "ASUS Zenbook A14"; chassis-type = "laptop"; aliases { @@ -1005,14 +1004,10 @@ status = "okay"; aux-bus { - panel { + panel: panel { compatible = "edp-panel"; - enable-gpios = <&pmc8380_3_gpios 4 GPIO_ACTIVE_HIGH>; power-supply = <&vreg_edp_3p3>; - pinctrl-0 = <&edp_bl_en>; - pinctrl-names = "default"; - port { edp_panel_in: endpoint { remote-endpoint = <&mdss_dp3_out>; diff --git a/arch/arm64/boot/dts/qcom/x1-crd.dtsi b/arch/arm64/boot/dts/qcom/x1-crd.dtsi index 3c9455fede5c0..ded96fb43489b 100644 --- a/arch/arm64/boot/dts/qcom/x1-crd.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-crd.dtsi @@ -9,7 +9,7 @@ #include #include -#include "x1e80100-pmics.dtsi" +#include "hamoa-pmics.dtsi" / { model = "Qualcomm Technologies, Inc. X1E80100 CRD"; @@ -82,6 +82,13 @@ <&tlmm 123 GPIO_ACTIVE_HIGH>, <&tlmm 125 GPIO_ACTIVE_HIGH>; + nvmem-cells = <&charge_limit_en>, + <&charge_limit_end>, + <&charge_limit_delta>; + nvmem-cell-names = "charge_limit_en", + "charge_limit_end", + "charge_limit_delta"; + /* Left-side rear port */ connector@0 { compatible = "usb-c-connector"; diff --git a/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi b/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi index cc64558ed5e6f..bf04a12b16bc9 100644 --- a/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi @@ -12,7 +12,7 @@ #include #include -#include "x1e80100-pmics.dtsi" +#include "hamoa-pmics.dtsi" / { chassis-type = "laptop"; @@ -1023,7 +1023,6 @@ }; &mdss_dp0_out { - data-lanes = <0 1>; link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; }; @@ -1032,13 +1031,15 @@ }; &mdss_dp1_out { - data-lanes = <0 1>; link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; }; &mdss_dp3 { /delete-property/ #sound-dai-cells; + pinctrl-0 = <&edp0_hpd_default>; + pinctrl-names = "default"; + status = "okay"; aux-bus { diff --git a/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts b/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts index bfc649d4b643c..a9643cd746d50 100644 --- a/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts +++ b/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts @@ -8,8 +8,8 @@ #include #include -#include "x1e80100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "hamoa.dtsi" +#include "hamoa-pmics.dtsi" / { model = "Qualcomm Technologies, Inc. X1E001DE Snapdragon Devkit for Windows"; @@ -763,10 +763,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/x1e80100/Thundercomm/DEVKIT/qcdxkmsuc8380.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/x1e80100/Thundercomm/DEVKIT/qcdxkmsuc8380.mbn"; }; &i2c1 { diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi index 654cbce9d6ecb..80ece9db875a5 100644 --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi @@ -12,8 +12,8 @@ #include #include -#include "x1e80100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "hamoa.dtsi" +#include "hamoa-pmics.dtsi" / { model = "Lenovo ThinkPad T14s Gen 6"; @@ -722,10 +722,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/x1e80100/LENOVO/21N1/qcdxkmsuc8380.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/x1e80100/LENOVO/21N1/qcdxkmsuc8380.mbn"; }; &i2c0 { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts b/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts index 0113d856b3ad4..d4df21de0d959 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts @@ -11,8 +11,8 @@ #include #include -#include "x1e80100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "hamoa.dtsi" +#include "hamoa-pmics.dtsi" / { model = "ASUS Vivobook S 15"; @@ -479,10 +479,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/x1e80100/ASUSTeK/vivobook-s15/qcdxkmsuc8380.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/x1e80100/ASUSTeK/vivobook-s15/qcdxkmsuc8380.mbn"; }; &i2c0 { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-asus-zenbook-a14.dts b/arch/arm64/boot/dts/qcom/x1e80100-asus-zenbook-a14.dts index 0d0bcc50207d7..0408ade7150fc 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-asus-zenbook-a14.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-asus-zenbook-a14.dts @@ -6,12 +6,71 @@ /dts-v1/; -#include "x1e80100.dtsi" +#include "hamoa.dtsi" #include "x1-asus-zenbook-a14.dtsi" / { model = "ASUS Zenbook A14 (UX3407RA)"; compatible = "asus,zenbook-a14-ux3407ra", "qcom,x1e80100"; + + wcn7850-pmu { + compatible = "qcom,wcn7850-pmu"; + + vdd-supply = <&vreg_wcn_0p95>; + vddio-supply = <&vreg_l15b_1p8>; + vddaon-supply = <&vreg_wcn_0p95>; + vdddig-supply = <&vreg_wcn_0p95>; + vddrfa1p2-supply = <&vreg_wcn_1p9>; + vddrfa1p8-supply = <&vreg_wcn_1p9>; + + bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; + wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&wcn_bt_en>, <&wcn_wlan_en>; + pinctrl-names = "default"; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; }; &gpu { @@ -22,6 +81,31 @@ firmware-name = "qcom/x1e80100/ASUSTeK/zenbook-a14/qcdxkmsuc8380.mbn"; }; +&pcie4_port0 { + wifi@0 { + compatible = "pci17cb,1107"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + }; +}; + +&panel { + compatible = "samsung,atna40cu11", "samsung,atna33xc20"; + enable-gpios = <&pmc8380_3_gpios 4 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&edp_bl_en>; + pinctrl-names = "default"; +}; + &remoteproc_adsp { firmware-name = "qcom/x1e80100/ASUSTeK/zenbook-a14/qcadsp8380.mbn", "qcom/x1e80100/ASUSTeK/zenbook-a14/adsp_dtbs.elf"; @@ -35,3 +119,21 @@ status = "okay"; }; + +&uart14 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn7850-bt"; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + + max-speed = <3000000>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts index dfc378e1a056a..429deffcf3e9d 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts @@ -5,7 +5,7 @@ /dts-v1/; -#include "x1e80100.dtsi" +#include "hamoa.dtsi" #include "x1-crd.dtsi" / { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-dell-inspiron-14-plus-7441.dts b/arch/arm64/boot/dts/qcom/x1e80100-dell-inspiron-14-plus-7441.dts index cf2a7c2628881..75e10d97c3867 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-dell-inspiron-14-plus-7441.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-dell-inspiron-14-plus-7441.dts @@ -4,7 +4,7 @@ */ /dts-v1/; -#include "x1e80100.dtsi" +#include "hamoa.dtsi" #include "x1-dell-thena.dtsi" / { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-dell-latitude-7455.dts b/arch/arm64/boot/dts/qcom/x1e80100-dell-latitude-7455.dts index 32ad9679550ef..a8ff7ef258a13 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-dell-latitude-7455.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-dell-latitude-7455.dts @@ -4,7 +4,7 @@ */ /dts-v1/; -#include "x1e80100.dtsi" +#include "hamoa.dtsi" #include "x1-dell-thena.dtsi" / { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts b/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts index 58f8caaa72580..2f533e56c8c84 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts @@ -12,8 +12,8 @@ #include #include -#include "x1e80100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "hamoa.dtsi" +#include "hamoa-pmics.dtsi" / { model = "Dell XPS 13 9345"; @@ -676,10 +676,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/x1e80100/dell/xps13-9345/qcdxkmsuc8380.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/x1e80100/dell/xps13-9345/qcdxkmsuc8380.mbn"; }; &i2c0 { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-hp-elitebook-ultra-g1q.dts b/arch/arm64/boot/dts/qcom/x1e80100-hp-elitebook-ultra-g1q.dts index 4ea00d8236935..0b3b6cb23e1ab 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-hp-elitebook-ultra-g1q.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-hp-elitebook-ultra-g1q.dts @@ -9,10 +9,8 @@ compatible = "hp,elitebook-ultra-g1q", "qcom,x1e80100"; }; -&gpu { - zap-shader { - firmware-name = "qcom/x1e80100/hp/elitebook-ultra-g1q/qcdxkmsuc8380.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/x1e80100/hp/elitebook-ultra-g1q/qcdxkmsuc8380.mbn"; }; &remoteproc_adsp { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-hp-omnibook-x14.dts b/arch/arm64/boot/dts/qcom/x1e80100-hp-omnibook-x14.dts index e5a839d458402..b79e59e1c413a 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-hp-omnibook-x14.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-hp-omnibook-x14.dts @@ -6,8 +6,8 @@ /dts-v1/; -#include "x1e80100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "hamoa.dtsi" +#include "hamoa-pmics.dtsi" #include "x1-hp-omnibook-x14.dtsi" / { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts b/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts index e0642fe8343f6..4c31d14a07bc6 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts @@ -9,8 +9,8 @@ #include #include -#include "x1e80100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "hamoa.dtsi" +#include "hamoa-pmics.dtsi" / { model = "Lenovo Yoga Slim 7x"; @@ -799,10 +799,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/x1e80100/LENOVO/83ED/qcdxkmsuc8380.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/x1e80100/LENOVO/83ED/qcdxkmsuc8380.mbn"; }; &i2c0 { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi b/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi index ed468b93ba50e..7e1e808ea983b 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi @@ -9,8 +9,8 @@ #include #include -#include "x1e80100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "hamoa.dtsi" +#include "hamoa-pmics.dtsi" / { aliases { @@ -861,11 +861,11 @@ &gpu { status = "okay"; +}; - zap-shader { - memory-region = <&gpu_microcode_mem>; - firmware-name = "qcom/x1e80100/microsoft/qcdxkmsuc8380.mbn"; - }; +&gpu_zap_shader { + memory-region = <&gpu_microcode_mem>; + firmware-name = "qcom/x1e80100/microsoft/qcdxkmsuc8380.mbn"; }; &i2c0 { diff --git a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts index 4a9b6d791e7f4..b742aabd9c049 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts @@ -8,8 +8,8 @@ #include #include -#include "x1e80100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "hamoa.dtsi" +#include "hamoa-pmics.dtsi" / { model = "Qualcomm Technologies, Inc. X1E80100 QCP"; @@ -831,10 +831,10 @@ &gpu { status = "okay"; +}; - zap-shader { - firmware-name = "qcom/x1e80100/gen70500_zap.mbn"; - }; +&gpu_zap_shader { + firmware-name = "qcom/x1e80100/gen70500_zap.mbn"; }; &i2c5 { diff --git a/arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14-lcd.dts b/arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14-lcd.dts new file mode 100644 index 0000000000000..be756069131d7 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14-lcd.dts @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2025 Aleksandrs Vinarskis + */ + +/dts-v1/; + +#include "x1p42100-asus-zenbook-a14.dtsi" + +/ { + model = "ASUS Zenbook A14 (UX3407QA, LCD)"; + compatible = "asus,zenbook-a14-ux3407qa-lcd", "asus,zenbook-a14-ux3407qa", "qcom,x1p42100"; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pmk8550_pwm 0 416667>; + enable-gpios = <&pmc8380_3_gpios 4 GPIO_ACTIVE_HIGH>; + power-supply = <&vreg_edp_bl>; + + pinctrl-0 = <&edp_bl_en>, <&edp_bl_pwm>; + pinctrl-names = "default"; + }; + + vreg_edp_bl: regulator-edp-bl { + compatible = "regulator-fixed"; + + regulator-name = "VBL9"; + regulator-min-microvolt = <3600000>; + regulator-max-microvolt = <3600000>; + + gpio = <&pmc8380_3_gpios 10 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&edp_bl_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; +}; + +&panel { + backlight = <&backlight>; +}; + +&pmc8380_3_gpios { + edp_bl_reg_en: edp-bl-reg-en-state { + pins = "gpio10"; + function = "normal"; + }; +}; + +&pmk8550_gpios { + edp_bl_pwm: edp-bl-pwm-state { + pins = "gpio5"; + function = "func3"; + }; +}; + +&pmk8550_pwm { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14.dts b/arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14.dts index bd75ff898601a..68cd318d69073 100644 --- a/arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14.dts +++ b/arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14.dts @@ -6,136 +6,17 @@ /dts-v1/; -#include "x1p42100.dtsi" -#include "x1-asus-zenbook-a14.dtsi" - -/delete-node/ &pmc8380_6; -/delete-node/ &pmc8380_6_thermal; +#include "x1p42100-asus-zenbook-a14.dtsi" / { model = "ASUS Zenbook A14 (UX3407QA)"; - compatible = "asus,zenbook-a14-ux3407qa", "qcom,x1p42100"; - - wcn6855-pmu { - compatible = "qcom,wcn6855-pmu"; - - vddaon-supply = <&vreg_wcn_0p95>; - vddio-supply = <&vreg_wcn_1p9>; - vddpcie1p3-supply = <&vreg_wcn_1p9>; - vddpcie1p9-supply = <&vreg_wcn_1p9>; - vddpmu-supply = <&vreg_wcn_0p95>; - vddpmucx-supply = <&vreg_wcn_0p95>; - vddpmumx-supply = <&vreg_wcn_0p95>; - vddrfa0p95-supply = <&vreg_wcn_0p95>; - vddrfa1p3-supply = <&vreg_wcn_1p9>; - vddrfa1p9-supply = <&vreg_wcn_1p9>; - - bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; - wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; - - pinctrl-0 = <&wcn_bt_en>, <&wcn_wlan_en>; - pinctrl-names = "default"; - - regulators { - vreg_pmu_rfa_cmn_0p8: ldo0 { - regulator-name = "vreg_pmu_rfa_cmn_0p8"; - }; - - vreg_pmu_aon_0p8: ldo1 { - regulator-name = "vreg_pmu_aon_0p8"; - }; - - vreg_pmu_wlcx_0p8: ldo2 { - regulator-name = "vreg_pmu_wlcx_0p8"; - }; - - vreg_pmu_wlmx_0p8: ldo3 { - regulator-name = "vreg_pmu_wlmx_0p8"; - }; - - vreg_pmu_btcmx_0p8: ldo4 { - regulator-name = "vreg_pmu_btcmx_0p8"; - }; - - vreg_pmu_pcie_1p8: ldo5 { - regulator-name = "vreg_pmu_pcie_1p8"; - }; - - vreg_pmu_pcie_0p9: ldo6 { - regulator-name = "vreg_pmu_pcie_0p9"; - }; - - vreg_pmu_rfa_0p8: ldo7 { - regulator-name = "vreg_pmu_rfa_0p8"; - }; - - vreg_pmu_rfa_1p2: ldo8 { - regulator-name = "vreg_pmu_rfa_1p2"; - }; - - vreg_pmu_rfa_1p7: ldo9 { - regulator-name = "vreg_pmu_rfa_1p7"; - }; - }; - }; + compatible = "asus,zenbook-a14-ux3407qa-oled", "asus,zenbook-a14-ux3407qa", "qcom,x1p42100"; }; -&gpu { - status = "okay"; -}; - -&gpu_zap_shader { - firmware-name = "qcom/x1p42100/ASUSTeK/zenbook-a14/qcdxkmsucpurwa.mbn"; -}; - -&pcie4_port0 { - wifi@0 { - compatible = "pci17cb,1103"; - reg = <0x10000 0x0 0x0 0x0 0x0>; - - vddaon-supply = <&vreg_pmu_aon_0p8>; - vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; - vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; - vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>; - vddrfacmn-supply = <&vreg_pmu_rfa_cmn_0p8>; - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; - vddwlmx-supply = <&vreg_pmu_wlmx_0p8>; - - qcom,calibration-variant = "UX3407Q"; - }; -}; - -&remoteproc_adsp { - firmware-name = "qcom/x1p42100/ASUSTeK/zenbook-a14/qcadsp8380.mbn", - "qcom/x1p42100/ASUSTeK/zenbook-a14/adsp_dtbs.elf"; - - status = "okay"; -}; - -&remoteproc_cdsp { - firmware-name = "qcom/x1p42100/ASUSTeK/zenbook-a14/qccdsp8380.mbn", - "qcom/x1p42100/ASUSTeK/zenbook-a14/cdsp_dtbs.elf"; - - status = "okay"; -}; - -&uart14 { - status = "okay"; - - bluetooth { - compatible = "qcom,wcn6855-bt"; - - vddaon-supply = <&vreg_pmu_aon_0p8>; - vddbtcmx-supply = <&vreg_pmu_btcmx_0p8>; - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; - vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>; - vddrfacmn-supply = <&vreg_pmu_rfa_cmn_0p8>; - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; - vddwlmx-supply = <&vreg_pmu_wlmx_0p8>; +&panel { + compatible = "samsung,atna40ct06", "samsung,atna33xc20"; + enable-gpios = <&pmc8380_3_gpios 4 GPIO_ACTIVE_HIGH>; - max-speed = <3000000>; - }; + pinctrl-0 = <&edp_bl_en>; + pinctrl-names = "default"; }; diff --git a/arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14.dtsi b/arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14.dtsi new file mode 100644 index 0000000000000..22470a97e1e39 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14.dtsi @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2025 Aleksandrs Vinarskis + */ + +/dts-v1/; + +#include "purwa.dtsi" +#include "x1-asus-zenbook-a14.dtsi" + +/delete-node/ &pmc8380_6; +/delete-node/ &pmc8380_6_thermal; + +/ { + wcn6855-pmu { + compatible = "qcom,wcn6855-pmu"; + + vddaon-supply = <&vreg_wcn_0p95>; + vddio-supply = <&vreg_wcn_1p9>; + vddpcie1p3-supply = <&vreg_wcn_1p9>; + vddpcie1p9-supply = <&vreg_wcn_1p9>; + vddpmu-supply = <&vreg_wcn_0p95>; + vddpmucx-supply = <&vreg_wcn_0p95>; + vddpmumx-supply = <&vreg_wcn_0p95>; + vddrfa0p95-supply = <&vreg_wcn_0p95>; + vddrfa1p3-supply = <&vreg_wcn_1p9>; + vddrfa1p9-supply = <&vreg_wcn_1p9>; + + bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; + wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&wcn_bt_en>, <&wcn_wlan_en>; + pinctrl-names = "default"; + + regulators { + vreg_pmu_rfa_cmn_0p8: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn_0p8"; + }; + + vreg_pmu_aon_0p8: ldo1 { + regulator-name = "vreg_pmu_aon_0p8"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p8: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p8"; + }; + + vreg_pmu_btcmx_0p8: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p8"; + }; + + vreg_pmu_pcie_1p8: ldo5 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo6 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_rfa_0p8: ldo7 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo8 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p7: ldo9 { + regulator-name = "vreg_pmu_rfa_1p7"; + }; + }; + }; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/x1p42100/ASUSTeK/zenbook-a14/qcdxkmsucpurwa.mbn"; +}; + +&pcie4_port0 { + wifi@0 { + compatible = "pci17cb,1103"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + vddaon-supply = <&vreg_pmu_aon_0p8>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn_0p8>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p8>; + + qcom,calibration-variant = "UX3407Q"; + }; +}; + +&remoteproc_adsp { + firmware-name = "qcom/x1p42100/ASUSTeK/zenbook-a14/qcadsp8380.mbn", + "qcom/x1p42100/ASUSTeK/zenbook-a14/adsp_dtbs.elf"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/x1p42100/ASUSTeK/zenbook-a14/qccdsp8380.mbn", + "qcom/x1p42100/ASUSTeK/zenbook-a14/cdsp_dtbs.elf"; + + status = "okay"; +}; + +&uart14 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn6855-bt"; + + vddaon-supply = <&vreg_pmu_aon_0p8>; + vddbtcmx-supply = <&vreg_pmu_btcmx_0p8>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn_0p8>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p8>; + + max-speed = <3000000>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/x1p42100-crd.dts b/arch/arm64/boot/dts/qcom/x1p42100-crd.dts index cf999c2cf8d4e..7ed4116b95904 100644 --- a/arch/arm64/boot/dts/qcom/x1p42100-crd.dts +++ b/arch/arm64/boot/dts/qcom/x1p42100-crd.dts @@ -5,7 +5,7 @@ /dts-v1/; -#include "x1p42100.dtsi" +#include "purwa.dtsi" #include "x1-crd.dtsi" /delete-node/ &pmc8380_6; diff --git a/arch/arm64/boot/dts/qcom/x1p42100-hp-omnibook-x14.dts b/arch/arm64/boot/dts/qcom/x1p42100-hp-omnibook-x14.dts index 6696cab2de3ec..0f338e457abda 100644 --- a/arch/arm64/boot/dts/qcom/x1p42100-hp-omnibook-x14.dts +++ b/arch/arm64/boot/dts/qcom/x1p42100-hp-omnibook-x14.dts @@ -2,8 +2,8 @@ /dts-v1/; -#include "x1p42100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "purwa.dtsi" +#include "hamoa-pmics.dtsi" #include "x1-hp-omnibook-x14.dtsi" /delete-node/ &pmc8380_6; /delete-node/ &pmc8380_6_thermal; diff --git a/arch/arm64/boot/dts/qcom/x1p42100-lenovo-thinkbook-16.dts b/arch/arm64/boot/dts/qcom/x1p42100-lenovo-thinkbook-16.dts index 1ac46cdc43861..3186e79e862de 100644 --- a/arch/arm64/boot/dts/qcom/x1p42100-lenovo-thinkbook-16.dts +++ b/arch/arm64/boot/dts/qcom/x1p42100-lenovo-thinkbook-16.dts @@ -13,8 +13,8 @@ #include #include -#include "x1p42100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "purwa.dtsi" +#include "hamoa-pmics.dtsi" /delete-node/ &pmc8380_6; /delete-node/ &pmc8380_6_thermal; diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile index ccdf7aaeca13e..1fab1b50f20e6 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile @@ -108,9 +108,18 @@ dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-camera-j2-imx219.dtb dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-camera-j2-imx462.dtbo r8a779g3-sparrow-hawk-camera-j2-imx462-dtbs := r8a779g3-sparrow-hawk.dtb r8a779g3-sparrow-hawk-camera-j2-imx462.dtbo dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-camera-j2-imx462.dtb +dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-fan-argon40.dtbo +r8a779g3-sparrow-hawk-fan-argon40-dtbs := r8a779g3-sparrow-hawk.dtb r8a779g3-sparrow-hawk-fan-argon40.dtbo +dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-fan-argon40.dtb dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-fan-pwm.dtbo r8a779g3-sparrow-hawk-fan-pwm-dtbs := r8a779g3-sparrow-hawk.dtb r8a779g3-sparrow-hawk-fan-pwm.dtbo dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-fan-pwm.dtb +dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-rpi-display-2-5in.dtbo +r8a779g3-sparrow-hawk-rpi-display-2-5in-dtbs := r8a779g3-sparrow-hawk.dtb r8a779g3-sparrow-hawk-rpi-display-2-5in.dtbo +dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-rpi-display-2-5in.dtb +dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-rpi-display-2-7in.dtbo +r8a779g3-sparrow-hawk-rpi-display-2-7in-dtbs := r8a779g3-sparrow-hawk.dtb r8a779g3-sparrow-hawk-rpi-display-2-7in.dtbo +dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-rpi-display-2-7in.dtb dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-white-hawk-single.dtb r8a779g3-white-hawk-single-ard-audio-da7212-dtbs := r8a779g3-white-hawk-single.dtb white-hawk-ard-audio-da7212.dtbo @@ -136,6 +145,8 @@ dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-salvator-xs.dtb r8a779m5-salvator-xs-panel-aa104xd12-dtbs := r8a779m5-salvator-xs.dtb salvator-panel-aa104xd12.dtbo dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-salvator-xs-panel-aa104xd12.dtb +dtb-$(CONFIG_ARCH_R8A78000) += r8a78000-ironhide.dtb + dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc.dtb dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc-cru-csi-ov5645.dtbo dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc-du-adv7513.dtbo diff --git a/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi b/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi index 7cb5c958aecec..529388f6bf2b7 100644 --- a/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi +++ b/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi @@ -66,7 +66,6 @@ compatible = "ovti,ov5645"; reg = <0x3c>; clocks = <&osc25250_clk>; - clock-frequency = <24000000>; vdddo-supply = <&ov5645_vdddo_1v8>; vdda-supply = <&ov5645_vdda_2v8>; vddd-supply = <&ov5645_vddd_1v5>; diff --git a/arch/arm64/boot/dts/renesas/draak.dtsi b/arch/arm64/boot/dts/renesas/draak.dtsi index 71d9f277c966f..733a55f77cfb0 100644 --- a/arch/arm64/boot/dts/renesas/draak.dtsi +++ b/arch/arm64/boot/dts/renesas/draak.dtsi @@ -722,6 +722,11 @@ shared-pin; }; +/* Firmware should reserve it but sadly doesn't */ +&swdt { + status = "reserved"; +}; + &usb2_phy0 { pinctrl-0 = <&usb0_pins>; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/renesas/ebisu.dtsi b/arch/arm64/boot/dts/renesas/ebisu.dtsi index c4c86344fb905..adc4449b809ad 100644 --- a/arch/arm64/boot/dts/renesas/ebisu.dtsi +++ b/arch/arm64/boot/dts/renesas/ebisu.dtsi @@ -858,6 +858,11 @@ shared-pin; }; +/* Firmware should reserve it but sadly doesn't */ +&swdt { + status = "reserved"; +}; + &usb2_phy0 { pinctrl-0 = <&usb0_pins>; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi index 6b737d91b320f..f0729a482cefa 100644 --- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r8a774a1"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -235,17 +236,17 @@ pmu_a53 { compatible = "arm,cortex-a53-pmu"; - interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>; }; pmu_a57 { compatible = "arm,cortex-a57-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts= , + ; interrupt-affinity = <&a57_0>, <&a57_1>; }; @@ -263,7 +264,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -2863,10 +2863,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi index 3f15d656215e1..c9857ea944edf 100644 --- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r8a774b1"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -128,8 +129,8 @@ pmu_a57 { compatible = "arm,cortex-a57-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&a57_0>, <&a57_1>; }; @@ -147,7 +148,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -2734,10 +2734,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi index 55df063cb3232..3858f4328e961 100644 --- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r8a774c0"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -119,8 +120,8 @@ pmu_a53 { compatible = "arm,cortex-a53-pmu"; - interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts= , + ; interrupt-affinity = <&a53_0>, <&a53_1>; }; @@ -138,7 +139,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -2000,10 +2000,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi index 5d730b488d46f..52920a6bf592e 100644 --- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r8a774e1"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -297,19 +298,19 @@ pmu_a53 { compatible = "arm,cortex-a53-pmu"; - interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>; }; pmu_a57 { compatible = "arm,cortex-a57-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&a57_0>, <&a57_1>, <&a57_2>, <&a57_3>; }; @@ -327,7 +328,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -2997,10 +2997,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi index c389ebc7e6ce8..9ad700bde4ba6 100644 --- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi @@ -18,6 +18,7 @@ compatible = "renesas,r8a7795"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -312,10 +313,10 @@ pmu_a53 { compatible = "arm,cortex-a53-pmu"; - interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, @@ -324,10 +325,10 @@ pmu_a57 { compatible = "arm,cortex-a57-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&a57_0>, <&a57_1>, <&a57_2>, @@ -348,7 +349,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -365,6 +365,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a7795-wdt", "renesas,rcar-gen3-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A7795_CLK_OSC>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 401>; + status = "disabled"; + }; + gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7795", "renesas,rcar-gen3-gpio"; @@ -3476,10 +3486,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi index 6d039019905de..e03b1f7cbfd6f 100644 --- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r8a7796"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -284,17 +285,17 @@ pmu_a53 { compatible = "arm,cortex-a53-pmu"; - interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>; }; pmu_a57 { compatible = "arm,cortex-a57-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&a57_0>, <&a57_1>; }; @@ -312,7 +313,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -330,6 +330,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a7796-wdt", "renesas,rcar-gen3-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A7796_CLK_OSC>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 401>; + status = "disabled"; + }; + gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7796", "renesas,rcar-gen3-gpio"; @@ -2565,6 +2575,23 @@ resets = <&cpg 408>; }; + gpu: gpu@fd000000 { + compatible = "renesas,r8a7796-gpu", + "img,img-gx6250", + "img,img-rogue"; + reg = <0 0xfd000000 0 0x40000>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A7796_CLK_ZG>, + <&cpg CPG_CORE R8A7796_CLK_S2D1>, + <&cpg CPG_MOD 112>; + clock-names = "core", "mem", "sys"; + power-domains = <&sysc R8A7796_PD_3DG_A>, + <&sysc R8A7796_PD_3DG_B>; + power-domain-names = "a", "b"; + resets = <&cpg 112>; + status = "disabled"; + }; + pciec0: pcie@fe000000 { compatible = "renesas,pcie-r8a7796", "renesas,pcie-rcar-gen3"; @@ -3074,10 +3101,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi index 1637b534fc68b..31b11bdab69b9 100644 --- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r8a77961"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -284,17 +285,17 @@ pmu_a53 { compatible = "arm,cortex-a53-pmu"; - interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>; }; pmu_a57 { compatible = "arm,cortex-a57-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&a57_0>, <&a57_1>; }; @@ -312,7 +313,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -330,6 +330,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a77961-wdt", "renesas,rcar-gen3-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A77961_CLK_OSC>; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 401>; + status = "disabled"; + }; + gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a77961", "renesas,rcar-gen3-gpio"; @@ -2445,6 +2455,23 @@ resets = <&cpg 408>; }; + gpu: gpu@fd000000 { + compatible = "renesas,r8a77961-gpu", + "img,img-gx6250", + "img,img-rogue"; + reg = <0 0xfd000000 0 0x40000>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A77961_CLK_ZG>, + <&cpg CPG_CORE R8A77961_CLK_S2D1>, + <&cpg CPG_MOD 112>; + clock-names = "core", "mem", "sys"; + power-domains = <&sysc R8A77961_PD_3DG_A>, + <&sysc R8A77961_PD_3DG_B>; + power-domain-names = "a", "b"; + resets = <&cpg 112>; + status = "disabled"; + }; + pciec0: pcie@fe000000 { compatible = "renesas,pcie-r8a77961", "renesas,pcie-rcar-gen3"; @@ -2895,10 +2922,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi index 353a771870893..4e730144e5fd8 100644 --- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi @@ -18,6 +18,7 @@ compatible = "renesas,r8a77965"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -163,8 +164,8 @@ pmu_a57 { compatible = "arm,cortex-a57-pmu"; - interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&a57_0>, <&a57_1>; }; @@ -183,7 +184,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -201,6 +201,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a77965-wdt", "renesas,rcar-gen3-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A77965_CLK_OSC>; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + resets = <&cpg 401>; + status = "disabled"; + }; + gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a77965", "renesas,rcar-gen3-gpio"; @@ -2440,6 +2450,23 @@ resets = <&cpg 408>; }; + gpu: gpu@fd000000 { + compatible = "renesas,r8a77965-gpu", + "img,img-ge7800", + "img,img-rogue"; + reg = <0 0xfd000000 0 0x40000>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A77965_CLK_ZG>, + <&cpg CPG_CORE R8A77965_CLK_S2D1>, + <&cpg CPG_MOD 112>; + clock-names = "core", "mem", "sys"; + power-domains = <&sysc R8A77965_PD_3DG_A>, + <&sysc R8A77965_PD_3DG_B>; + power-domain-names = "a", "b"; + resets = <&cpg 112>; + status = "disabled"; + }; + pciec0: pcie@fe000000 { compatible = "renesas,pcie-r8a77965", "renesas,pcie-rcar-gen3"; @@ -2903,10 +2930,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso index 0c005660d8dd3..ecb35257b9ae1 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso +++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso @@ -170,7 +170,24 @@ }; }; +&mmc0 { + pinctrl-0 = <&mmc_pins>; + pinctrl-names = "default"; + + vmmc-supply = <&d3p3>; + vqmmc-supply = <&d1p8>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + &pfc { + mmc_pins: mmc { + groups = "mmc_data8", "mmc_ctrl"; + function = "mmc"; + power-source = <1800>; + }; + vin0_pins_parallel: vin0 { groups = "vin0_data12", "vin0_sync", "vin0_clk", "vin0_clkenb"; function = "vin0"; diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts index 8b594e9e9dc10..b7328f9f7d4ba 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts +++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts @@ -417,3 +417,8 @@ &scif_clk { clock-frequency = <14745600>; }; + +/* Firmware should reserve it but sadly doesn't */ +&swdt { + status = "reserved"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts index 445f5dd7c983f..f18d26360610e 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts +++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts @@ -146,7 +146,6 @@ hdmi@39 { compatible = "adi,adv7511w"; - #sound-dai-cells = <0>; reg = <0x39>; interrupts-extended = <&gpio1 20 IRQ_TYPE_LEVEL_LOW>; avdd-supply = <&vcc_d1_8v>; @@ -293,6 +292,11 @@ }; }; +&rwdt { + timeout-sec = <60>; + status = "okay"; +}; + &scif0 { pinctrl-0 = <&scif0_pins>; pinctrl-names = "default"; @@ -300,3 +304,8 @@ status = "okay"; }; + +/* Firmware should reserve it but sadly doesn't */ +&swdt { + status = "reserved"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index e7a5800bf7421..1007ee48adc3e 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -15,6 +15,7 @@ compatible = "renesas,r8a77970"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* External CAN clock - to be overridden by boards that provide it */ can_clk: can { @@ -73,8 +74,8 @@ pmu_a53 { compatible = "arm,cortex-a53-pmu"; - interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&a53_0>, <&a53_1>; }; @@ -92,7 +93,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -110,6 +110,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a77970-wdt", "renesas,rcar-gen3-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A77970_CLK_OSC>; + power-domains = <&sysc R8A77970_PD_ALWAYS_ON>; + resets = <&cpg 401>; + status = "disabled"; + }; + gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a77970", "renesas,rcar-gen3-gpio"; @@ -1227,10 +1237,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts index c2692d6fd00d7..2da63b4daa0ac 100644 --- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts +++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts @@ -138,7 +138,6 @@ hdmi@39 { compatible = "adi,adv7511w"; - #sound-dai-cells = <0>; reg = <0x39>; interrupts-extended = <&gpio1 20 IRQ_TYPE_LEVEL_LOW>; avdd-supply = <&vcc1v8_d4>; diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi index 964aa14f3e65d..8cd7f68d026b6 100644 --- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi @@ -15,6 +15,7 @@ compatible = "renesas,r8a77980"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* External CAN clock - to be overridden by boards that provide it */ can_clk: can { @@ -100,10 +101,10 @@ pmu_a53 { compatible = "arm,cortex-a53-pmu"; - interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>; }; @@ -121,7 +122,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -1631,14 +1631,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | - IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | - IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | - IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | - IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index e16ede6eb3791..d3698f7e494df 100644 --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r8a77990"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -134,8 +135,8 @@ pmu_a53 { compatible = "arm,cortex-a53-pmu"; - interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, - <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-affinity = <&a53_0>, <&a53_1>; }; @@ -153,7 +154,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -171,6 +171,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a77990-wdt", "renesas,rcar-gen3-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A77990_CLK_OSC>; + power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; + resets = <&cpg 401>; + status = "disabled"; + }; + gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a77990", "renesas,rcar-gen3-gpio"; @@ -2164,10 +2174,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi index b66cd7c90d53f..5f3fcef7560cb 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi @@ -14,6 +14,7 @@ compatible = "renesas,r8a77995"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* * The external audio clocks are configured as 0 Hz fixed frequency @@ -70,7 +71,7 @@ pmu_a53 { compatible = "arm,cortex-a53-pmu"; - interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; psci { @@ -86,7 +87,6 @@ soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -104,6 +104,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a77995-wdt", "renesas,rcar-gen3-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A77995_CLK_OSC>; + power-domains = <&sysc R8A77995_PD_ALWAYS_ON>; + resets = <&cpg 401>; + status = "disabled"; + }; + gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a77995", "renesas,rcar-gen3-gpio"; @@ -1479,10 +1489,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; }; diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi index 2c3fb34abb28e..4b101a6dc49dd 100644 --- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r8a779a0"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* External CAN clock - to be overridden by boards that provide it */ can_clk: can { @@ -60,7 +61,7 @@ pmu_a76 { compatible = "arm,cortex-a76-pmu"; - interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; + interrupts = ; }; /* External SCIF clock - to be overridden by boards that provide it */ @@ -72,7 +73,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -90,6 +90,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a779a0-wdt", "renesas,rcar-gen4-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A779A0_CLK_OSC>; + power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>; + resets = <&cpg 1128>; + status = "disabled"; + }; + pfc: pinctrl@e6050000 { compatible = "renesas,pfc-r8a779a0"; reg = <0 0xe6050000 0 0x16c>, <0 0xe6050800 0 0x16c>, @@ -2327,6 +2337,23 @@ interrupts = ; }; + gpu: gpu@fd000000 { + compatible = "renesas,r8a779a0-gpu", + "img,img-ge7800", + "img,img-rogue"; + reg = <0 0xfd000000 0 0x40000>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A779A0_CLK_ZG>, + <&cpg CPG_CORE R8A779A0_CLK_S3D1>, + <&cpg CPG_MOD 0>; + clock-names = "core", "mem", "sys"; + power-domains = <&sysc R8A779A0_PD_3DG_A>, + <&sysc R8A779A0_PD_3DG_B>; + power-domain-names = "a", "b"; + resets = <&cpg 0>; + status = "disabled"; + }; + fcpvd0: fcp@fea10000 { compatible = "renesas,fcpv"; reg = <0 0xfea10000 0 0x200>; @@ -3086,11 +3113,11 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi index b496495c59a6d..0ebf8e5dd2f94 100644 --- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r8a779f0"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; cluster01_opp: opp-table-0 { compatible = "operating-points-v2"; @@ -280,7 +281,7 @@ pmu_a55 { compatible = "arm,cortex-a55-pmu"; - interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; + interrupts = ; }; psci { @@ -297,7 +298,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -315,6 +315,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a779f0-wdt", "renesas,rcar-gen4-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A779F0_CLK_OSC>; + power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>; + resets = <&cpg 1128>; + status = "disabled"; + }; + pfc: pinctrl@e6050000 { compatible = "renesas,pfc-r8a779f0"; reg = <0 0xe6050000 0 0x16c>, <0 0xe6050800 0 0x16c>, @@ -1340,11 +1350,11 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi index 4fae063bf91b6..ff2bd1908a451 100644 --- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r8a779g0"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* External Audio clock - to be overridden by boards that provide it */ audio_clkin: audio_clkin { @@ -193,7 +194,7 @@ pmu_a76 { compatible = "arm,cortex-a76-pmu"; - interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; + interrupts = ; }; psci { @@ -216,7 +217,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -234,6 +234,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a779g0-wdt", "renesas,rcar-gen4-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A779G0_CLK_OSC>; + power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; + resets = <&cpg 1128>; + status = "disabled"; + }; + pfc: pinctrl@e6050000 { compatible = "renesas,pfc-r8a779g0"; reg = <0 0xe6050000 0 0x16c>, <0 0xe6050800 0 0x16c>, @@ -2601,11 +2611,11 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-fan-argon40.dtso b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-fan-argon40.dtso new file mode 100644 index 0000000000000..c730ef39c7d7d --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-fan-argon40.dtso @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Overlay for the Argon40 HAT blower fan on connector CN7 + * on R-Car V4H ES3.0 Sparrow Hawk board + * + * Copyright (C) 2025 Marek Vasut + * + * Example usage: + * + * # Localize hwmon sysfs directory that matches the PWM fan, + * # enable the PWM fan, and configure the fan speed manually. + * r8a779g3-sparrow-hawk$ ls -1 /sys/devices/platform/pwm-fan-ext/hwmon/hwmon?/pwm?_enable + * /sys/devices/platform/pwm-fan-ext/hwmon/hwmon0/pwm1_enable + * + * # Select mode 2 , enable fan PWM and regulator and keep them enabled. + * # For details, see Linux Documentation/hwmon/pwm-fan.rst + * r8a779g3-sparrow-hawk$ echo 2 > /sys/devices/platform/pwm-fan-ext/hwmon/hwmon0/pwm1_enable + * + * # Configure PWM fan speed in range 0..255 , 0 is stopped , 255 is full speed . + * # Fan speed 101 is about 2/5 of the PWM fan speed: + * r8a779g3-sparrow-hawk$ echo 101 > /sys/devices/platform/pwm-fan-ext/hwmon/hwmon0/pwm1 + */ + +/dts-v1/; +/plugin/; + +&{/} { + pwm-fan-ext { + compatible = "pwm-fan"; + #cooling-cells = <2>; + /* PWM period: 33us ~= 30 kHz */ + pwms = <&pwmhat 0 33334 0>; + /* Available cooling levels */ + cooling-levels = <0 50 100 150 200 255>; + fan-shutdown-percent = <100>; + }; +}; + +/* Page 31 / IO_CN */ +&i2c3 { + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + status = "okay"; + + pwmhat: pwm@1a { + compatible = "argon40,fan-hat"; + reg = <0x1a>; + #pwm-cells = <3>; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-rpi-display-2-5in.dtso b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-rpi-display-2-5in.dtso new file mode 100644 index 0000000000000..bf7b531ae9d9b --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-rpi-display-2-5in.dtso @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Overlay for the RPi Display 2 5" MIPI DSI panel connected + * to J4:DSI on R-Car V4H ES3.0 Sparrow Hawk board + * + * Copyright (C) 2025 Marek Vasut + */ + +#include "r8a779g3-sparrow-hawk-rpi-display-2.dtsi" + +&panel { + compatible = "raspberrypi,dsi-5inch", "ilitek,ili9881c"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-rpi-display-2-7in.dtso b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-rpi-display-2-7in.dtso new file mode 100644 index 0000000000000..6ec47f213c0ff --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-rpi-display-2-7in.dtso @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Overlay for the RPi Display 2 7" MIPI DSI panel connected + * to J4:DSI on R-Car V4H ES3.0 Sparrow Hawk board + * + * Copyright (C) 2025 Marek Vasut + */ + +#include "r8a779g3-sparrow-hawk-rpi-display-2.dtsi" + +&panel { + compatible = "raspberrypi,dsi-7inch", "ilitek,ili9881c"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-rpi-display-2.dtsi b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-rpi-display-2.dtsi new file mode 100644 index 0000000000000..733333b85a9d2 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-rpi-display-2.dtsi @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Overlay for the RPi Display 2 MIPI DSI panel connected + * to J4:DSI on R-Car V4H ES3.0 Sparrow Hawk board + * + * Copyright (C) 2025 Marek Vasut + */ + +/dts-v1/; +/plugin/; + +#include + +&{/} { + display_bl: backlight { + compatible = "pwm-backlight"; + pwms = <&mcu 0 255 0>; + }; + + reg_display: regulator-display { + compatible = "regulator-fixed"; + regulator-name = "rpi-display"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_dsi_touch: regulator-dsi-touch { + compatible = "regulator-fixed"; + gpio = <&mcu 1 GPIO_ACTIVE_HIGH>; + regulator-name = "rpi-touch"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <50000>; + enable-active-high; + }; +}; + +&i2c0_mux3 { + #address-cells = <1>; + #size-cells = <0>; + + mcu: gpio@45 { + compatible = "raspberrypi,touchscreen-panel-regulator-v2"; + reg = <0x45>; + gpio-controller; + #gpio-cells = <2>; + #pwm-cells = <3>; + }; + + touchscreen@5d { + compatible = "goodix,gt911"; + reg = <0x5d>; + AVDD28-supply = <®_dsi_touch>; + touchscreen-size-x = <720>; + touchscreen-size-y = <1280>; + }; +}; + +&dsi0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + dsi0_out: endpoint { + remote-endpoint = <&panel_in>; + data-lanes = <1 2>; + }; + }; + }; + + panel: panel@0 { + reg = <0>; + backlight = <&display_bl>; + power-supply = <®_display>; + reset-gpios = <&mcu 0 GPIO_ACTIVE_LOW>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts index 1da8e476b2193..ff07d984cbf29 100644 --- a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts +++ b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts @@ -119,13 +119,13 @@ }; /* Page 27 / DSI to Display */ - mini-dp-con { + dp-con { compatible = "dp-connector"; label = "CN6"; type = "full-size"; port { - mini_dp_con_in: endpoint { + dp_con_in: endpoint { remote-endpoint = <&sn65dsi86_out>; }; }; @@ -407,7 +407,7 @@ port@1 { reg = <1>; sn65dsi86_out: endpoint { - remote-endpoint = <&mini_dp_con_in>; + remote-endpoint = <&dp_con_in>; }; }; }; diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi index 0f20a2d239834..4dc0e5304f721 100644 --- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r8a779h0"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* External Audio clock - to be overridden by boards that provide it */ audio_clkin: audio_clkin { @@ -158,7 +159,7 @@ pmu-a76 { compatible = "arm,cortex-a76-pmu"; - interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; + interrupts = ; }; psci { @@ -181,7 +182,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; bootph-all; #address-cells = <2>; @@ -199,6 +199,16 @@ status = "disabled"; }; + swdt: watchdog@e6030000 { + compatible = "renesas,r8a779h0-wdt", "renesas,rcar-gen4-wdt"; + reg = <0 0xe6030000 0 0x0c>; + interrupts = ; + clocks = <&cpg CPG_CORE R8A779H0_CLK_OSC>; + power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>; + resets = <&cpg 1128>; + status = "disabled"; + }; + pfc: pinctrl@e6050000 { compatible = "renesas,pfc-r8a779h0"; reg = <0 0xe6050000 0 0x16c>, <0 0xe6050800 0 0x16c>, @@ -2212,11 +2222,11 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; diff --git a/arch/arm64/boot/dts/renesas/r8a78000-ironhide.dts b/arch/arm64/boot/dts/renesas/r8a78000-ironhide.dts new file mode 100644 index 0000000000000..a721734fbd5d0 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a78000-ironhide.dts @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source for the Ironhide board + * + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +/dts-v1/; +#include "r8a78000.dtsi" + +/ { + model = "Renesas Ironhide board based on r8a78000"; + compatible = "renesas,ironhide", "renesas,r8a78000"; + + aliases { + serial0 = &hscif0; + }; + + chosen { + stdout-path = "serial0:1843200n8"; + }; + + memory@60600000 { + device_type = "memory"; + /* first 518MiB is reserved for other purposes. */ + reg = <0x0 0x60600000 0x0 0x5fa00000>; + }; + + memory@1080000000 { + device_type = "memory"; + reg = <0x10 0x80000000 0x0 0x80000000>; + }; + + memory@1200000000 { + device_type = "memory"; + reg = <0x12 0x00000000 0x1 0x00000000>; + }; + + memory@1400000000 { + device_type = "memory"; + reg = <0x14 0x00000000 0x1 0x00000000>; + }; + + memory@1600000000 { + device_type = "memory"; + reg = <0x16 0x00000000 0x1 0x00000000>; + }; + + memory@1800000000 { + device_type = "memory"; + reg = <0x18 0x00000000 0x1 0x00000000>; + }; + + memory@1a00000000 { + device_type = "memory"; + reg = <0x1a 0x00000000 0x1 0x00000000>; + }; + + memory@1c00000000 { + device_type = "memory"; + reg = <0x1c 0x00000000 0x1 0x00000000>; + }; + + memory@1e00000000 { + device_type = "memory"; + reg = <0x1e 0x00000000 0x1 0x00000000>; + }; +}; + +&extal_clk { + clock-frequency = <16666600>; +}; + +&extalr_clk { + clock-frequency = <32768>; +}; + +&hscif0 { + uart-has-rtscts; + status = "okay"; +}; + +&scif_clk { + clock-frequency = <26000000>; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a78000.dtsi b/arch/arm64/boot/dts/renesas/r8a78000.dtsi new file mode 100644 index 0000000000000..4c97298fa7634 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a78000.dtsi @@ -0,0 +1,787 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source for the R-Car X5H (R8A78000) SoC + * + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +#include + +/ { + compatible = "renesas,r8a78000"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&a720_0>; + }; + core1 { + cpu = <&a720_1>; + }; + core2 { + cpu = <&a720_2>; + }; + core3 { + cpu = <&a720_3>; + }; + }; + + cluster1 { + core0 { + cpu = <&a720_4>; + }; + core1 { + cpu = <&a720_5>; + }; + core2 { + cpu = <&a720_6>; + }; + core3 { + cpu = <&a720_7>; + }; + }; + + cluster2 { + core0 { + cpu = <&a720_8>; + }; + core1 { + cpu = <&a720_9>; + }; + core2 { + cpu = <&a720_10>; + }; + core3 { + cpu = <&a720_11>; + }; + }; + + cluster3 { + core0 { + cpu = <&a720_12>; + }; + core1 { + cpu = <&a720_13>; + }; + core2 { + cpu = <&a720_14>; + }; + core3 { + cpu = <&a720_15>; + }; + }; + + cluster4 { + core0 { + cpu = <&a720_16>; + }; + core1 { + cpu = <&a720_17>; + }; + core2 { + cpu = <&a720_18>; + }; + core3 { + cpu = <&a720_19>; + }; + }; + + cluster5 { + core0 { + cpu = <&a720_20>; + }; + core1 { + cpu = <&a720_21>; + }; + core2 { + cpu = <&a720_22>; + }; + core3 { + cpu = <&a720_23>; + }; + }; + + cluster6 { + core0 { + cpu = <&a720_24>; + }; + core1 { + cpu = <&a720_25>; + }; + core2 { + cpu = <&a720_26>; + }; + core3 { + cpu = <&a720_27>; + }; + }; + + cluster7 { + core0 { + cpu = <&a720_28>; + }; + core1 { + cpu = <&a720_29>; + }; + core2 { + cpu = <&a720_30>; + }; + core3 { + cpu = <&a720_31>; + }; + }; + }; + + a720_0: cpu@0 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x0>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_0>; + }; + + a720_1: cpu@100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_1>; + }; + + a720_2: cpu@200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_2>; + }; + + a720_3: cpu@300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_3>; + }; + + a720_4: cpu@10000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x10000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_4>; + }; + + a720_5: cpu@10100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x10100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_5>; + }; + + a720_6: cpu@10200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x10200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_6>; + }; + + a720_7: cpu@10300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x10300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_7>; + }; + + a720_8: cpu@20000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x20000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_8>; + }; + + a720_9: cpu@20100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x20100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_9>; + }; + + a720_10: cpu@20200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x20200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_10>; + }; + + a720_11: cpu@20300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x20300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_11>; + }; + + a720_12: cpu@30000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x30000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_12>; + }; + + a720_13: cpu@30100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x30100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_13>; + }; + + a720_14: cpu@30200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x30200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_14>; + }; + + a720_15: cpu@30300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x30300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_15>; + }; + + a720_16: cpu@40000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x40000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_16>; + }; + + a720_17: cpu@40100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x40100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_17>; + }; + + a720_18: cpu@40200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x40200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_18>; + }; + + a720_19: cpu@40300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x40300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_19>; + }; + + a720_20: cpu@50000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x50000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_20>; + }; + + a720_21: cpu@50100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x50100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_21>; + }; + + a720_22: cpu@50200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x50200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_22>; + }; + + a720_23: cpu@50300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x50300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_23>; + }; + + a720_24: cpu@60000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x60000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_24>; + }; + + a720_25: cpu@60100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x60100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_25>; + }; + + a720_26: cpu@60200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x60200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_26>; + }; + + a720_27: cpu@60300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x60300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_27>; + }; + + a720_28: cpu@70000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x70000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_28>; + }; + + a720_29: cpu@70100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x70100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_29>; + }; + + a720_30: cpu@70200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x70200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_30>; + }; + + a720_31: cpu@70300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x70300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_31>; + }; + + L2_CA720_0: cache-controller-200 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_0>; + }; + + L2_CA720_1: cache-controller-201 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_0>; + }; + + L2_CA720_2: cache-controller-202 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_0>; + }; + + L2_CA720_3: cache-controller-203 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_0>; + }; + + L2_CA720_4: cache-controller-204 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_1>; + }; + + L2_CA720_5: cache-controller-205 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_1>; + }; + + L2_CA720_6: cache-controller-206 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_1>; + }; + + L2_CA720_7: cache-controller-207 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_1>; + }; + + L2_CA720_8: cache-controller-208 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_2>; + }; + + L2_CA720_9: cache-controller-209 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_2>; + }; + + L2_CA720_10: cache-controller-210 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_2>; + }; + + L2_CA720_11: cache-controller-211 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_2>; + }; + + L2_CA720_12: cache-controller-212 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_3>; + }; + + L2_CA720_13: cache-controller-213 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_3>; + }; + + L2_CA720_14: cache-controller-214 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_3>; + }; + + L2_CA720_15: cache-controller-215 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_3>; + }; + + L2_CA720_16: cache-controller-216 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_4>; + }; + + L2_CA720_17: cache-controller-217 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_4>; + }; + + L2_CA720_18: cache-controller-218 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_4>; + }; + + L2_CA720_19: cache-controller-219 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_4>; + }; + + L2_CA720_20: cache-controller-220 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_5>; + }; + + L2_CA720_21: cache-controller-221 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_5>; + }; + + L2_CA720_22: cache-controller-222 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_5>; + }; + + L2_CA720_23: cache-controller-223 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_5>; + }; + + L2_CA720_24: cache-controller-224 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_6>; + }; + + L2_CA720_25: cache-controller-225 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_6>; + }; + + L2_CA720_26: cache-controller-226 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_6>; + }; + + L2_CA720_27: cache-controller-227 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_6>; + }; + + L2_CA720_28: cache-controller-228 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_7>; + }; + + L2_CA720_29: cache-controller-229 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_7>; + }; + + L2_CA720_30: cache-controller-230 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_7>; + }; + + L2_CA720_31: cache-controller-231 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_7>; + }; + + L3_CA720_0: cache-controller-30 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_1: cache-controller-31 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_2: cache-controller-32 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_3: cache-controller-33 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_4: cache-controller-34 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_5: cache-controller-35 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_6: cache-controller-36 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_7: cache-controller-37 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + }; + + /* + * In the early phase, there is no clock control support, + * so assume that the clocks are enabled by default. + * Therefore, dummy clocks are used. + */ + dummy_clk_sgasyncd16: dummy-clk-sgasyncd16 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <66666000>; + }; + + dummy_clk_sgasyncd4: dummy-clk-sgasyncd4 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <266660000>; + }; + + extal_clk: extal-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* clock-frequency must be set on board */ + }; + + extalr_clk: extalr-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* clock-frequency must be set on board */ + }; + + /* External SCIF clock - to be overridden by boards that provide it */ + scif_clk: scif-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; /* optional */ + }; + + soc: soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + prr: chipid@189e0044 { + compatible = "renesas,prr"; + reg = <0 0x189e0044 0 4>; + }; + + /* Application Processors manage View-1 of a GIC-720AE */ + gic: interrupt-controller@39000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0 0x39000000 0 0x10000>, + <0 0x39080000 0 0x800000>; + interrupts = ; + }; + + scif0: serial@c0700000 { + compatible = "renesas,scif-r8a78000", + "renesas,rcar-gen5-scif", "renesas,scif"; + reg = <0 0xc0700000 0 0x40>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + scif1: serial@c0704000 { + compatible = "renesas,scif-r8a78000", + "renesas,rcar-gen5-scif", "renesas,scif"; + reg = <0 0xc0704000 0 0x40>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + scif3: serial@c0708000 { + compatible = "renesas,scif-r8a78000", + "renesas,rcar-gen5-scif", "renesas,scif"; + reg = <0 0xc0708000 0 0x40>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + scif4: serial@c070c000 { + compatible = "renesas,scif-r8a78000", + "renesas,rcar-gen5-scif", "renesas,scif"; + reg = <0 0xc070c000 0 0x40>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + hscif0: serial@c0710000 { + compatible = "renesas,hscif-r8a78000", + "renesas,rcar-gen5-hscif", "renesas,hscif"; + reg = <0 0xc0710000 0 0x60>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + hscif1: serial@c0714000 { + compatible = "renesas,hscif-r8a78000", + "renesas,rcar-gen5-hscif", "renesas,hscif"; + reg = <0 0xc0714000 0 0x60>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + hscif2: serial@c0718000 { + compatible = "renesas,hscif-r8a78000", + "renesas,rcar-gen5-hscif", "renesas,hscif"; + reg = <0 0xc0718000 0 0x60>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + hscif3: serial@c071c000 { + compatible = "renesas,hscif-r8a78000", + "renesas,rcar-gen5-hscif", "renesas,hscif"; + reg = <0 0xc071c000 0 0x60>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + , + ; + interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi index a3998e5928f7c..5f5d1b0c31c63 100644 --- a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi @@ -12,6 +12,8 @@ #include "r9a07g043.dtsi" / { + interrupt-parent = <&gic>; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -37,7 +39,7 @@ pmu { compatible = "arm,cortex-a55-pmu"; - interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; + interrupts = ; }; psci { @@ -47,19 +49,17 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; }; &soc { - interrupt-parent = <&gic>; - cru: video@10830000 { compatible = "renesas,r9a07g043-cru", "renesas,rzg2l-cru"; reg = <0 0x10830000 0 0x400>; diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi index ecaa9c4f305c2..bd52d60bafb9c 100644 --- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi @@ -12,6 +12,7 @@ compatible = "renesas,r9a07g044"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; audio_clk1: audio1-clk { compatible = "fixed-clock"; @@ -159,7 +160,7 @@ pmu { compatible = "arm,cortex-a55-pmu"; - interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; + interrupts = ; }; psci { @@ -169,7 +170,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; ranges; @@ -1450,11 +1450,11 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi index 669eca74da0a6..4e0256d3201d6 100644 --- a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi @@ -12,6 +12,7 @@ compatible = "renesas,r9a07g054"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; audio_clk1: audio1-clk { compatible = "fixed-clock"; @@ -159,7 +160,7 @@ pmu { compatible = "arm,cortex-a55-pmu"; - interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; + interrupts = ; }; psci { @@ -169,7 +170,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; ranges; @@ -1458,11 +1458,11 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; diff --git a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi index 16e6ac6144178..876de634908ef 100644 --- a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi @@ -13,6 +13,7 @@ compatible = "renesas,r9a08g045"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; audio_clk1: audio1-clk { compatible = "fixed-clock"; @@ -92,7 +93,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; ranges; @@ -233,7 +233,6 @@ #address-cells = <1>; #size-cells = <0>; #io-channel-cells = <1>; - status = "disabled"; channel@0 { reg = <0>; @@ -272,6 +271,17 @@ }; }; + tsu: thermal@10059000 { + compatible = "renesas,r9a08g045-tsu"; + reg = <0 0x10059000 0 0x1000>; + clocks = <&cpg CPG_MOD R9A08G045_TSU_PCLK>; + resets = <&cpg R9A08G045_TSU_PRESETN>; + power-domains = <&cpg>; + #thermal-sensor-cells = <0>; + io-channels = <&adc 8>; + io-channel-names = "tsu"; + }; + i3c: i3c@1005b000 { compatible = "renesas,r9a08g045-i3c"; reg = <0 0x1005b000 0 0x1000>; @@ -717,6 +727,124 @@ status = "disabled"; }; + phyrst: usbphy-ctrl@11e00000 { + compatible = "renesas,r9a08g045-usbphy-ctrl"; + reg = <0 0x11e00000 0 0x10000>; + clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>; + resets = <&cpg R9A08G045_USB_PRESETN>; + power-domains = <&cpg>; + #reset-cells = <1>; + renesas,sysc-pwrrdy = <&sysc 0xd70 0x1>; + status = "disabled"; + + usb0_vbus_otg: regulator-vbus { + regulator-name = "vbus"; + }; + }; + + ohci0: usb@11e10000 { + compatible = "generic-ohci"; + reg = <0 0x11e10000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>, + <&cpg CPG_MOD R9A08G045_USB_U2H0_HCLK>; + resets = <&phyrst 0>, + <&cpg R9A08G045_USB_U2H0_HRESETN>; + phys = <&usb2_phy0 1>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ohci1: usb@11e30000 { + compatible = "generic-ohci"; + reg = <0 0x11e30000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>, + <&cpg CPG_MOD R9A08G045_USB_U2H1_HCLK>; + resets = <&phyrst 1>, + <&cpg R9A08G045_USB_U2H1_HRESETN>; + phys = <&usb2_phy1 1>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ehci0: usb@11e10100 { + compatible = "generic-ehci"; + reg = <0 0x11e10100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>, + <&cpg CPG_MOD R9A08G045_USB_U2H0_HCLK>; + resets = <&phyrst 0>, + <&cpg R9A08G045_USB_U2H0_HRESETN>; + phys = <&usb2_phy0 2>; + phy-names = "usb"; + companion = <&ohci0>; + power-domains = <&cpg>; + status = "disabled"; + }; + + ehci1: usb@11e30100 { + compatible = "generic-ehci"; + reg = <0 0x11e30100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>, + <&cpg CPG_MOD R9A08G045_USB_U2H1_HCLK>; + resets = <&phyrst 1>, + <&cpg R9A08G045_USB_U2H1_HRESETN>; + phys = <&usb2_phy1 2>; + phy-names = "usb"; + companion = <&ohci1>; + power-domains = <&cpg>; + status = "disabled"; + }; + + usb2_phy0: usb-phy@11e10200 { + compatible = "renesas,usb2-phy-r9a08g045"; + reg = <0 0x11e10200 0 0x700>; + interrupts = ; + clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>, + <&cpg CPG_MOD R9A08G045_USB_U2H0_HCLK>; + resets = <&phyrst 0>, + <&cpg R9A08G045_USB_U2H0_HRESETN>; + #phy-cells = <1>; + power-domains = <&cpg>; + status = "disabled"; + }; + + usb2_phy1: usb-phy@11e30200 { + compatible = "renesas,usb2-phy-r9a08g045"; + reg = <0 0x11e30200 0 0x700>; + interrupts = ; + clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>, + <&cpg CPG_MOD R9A08G045_USB_U2H1_HCLK>; + resets = <&phyrst 1>, + <&cpg R9A08G045_USB_U2H1_HRESETN>; + #phy-cells = <1>; + power-domains = <&cpg>; + status = "disabled"; + }; + + hsusb: usb@11e20000 { + compatible = "renesas,usbhs-r9a08g045", + "renesas,rzg2l-usbhs"; + reg = <0 0x11e20000 0 0x10000>; + interrupts = , + , + , + ; + clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>, + <&cpg CPG_MOD R9A08G045_USB_U2P_EXR_CPUCLK>; + resets = <&phyrst 0>, + <&cpg R9A08G045_USB_U2P_EXL_SYSRST>; + renesas,buswait = <7>; + phys = <&usb2_phy0 3>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + gic: interrupt-controller@12400000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; @@ -744,15 +872,52 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&tsu>; + sustainable-power = <423>; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = <&cpu0 0 2>; + contribution = <1024>; + }; + }; + + trips { + cpu_crit: cpu-critical { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + + cpu_alert1: trip-point1 { + temperature = <90000>; + hysteresis = <1000>; + type = "passive"; + }; + + cpu_alert0: trip-point0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + }; + vbattb_xtal: vbattb-xtal { compatible = "fixed-clock"; #clock-cells = <0>; diff --git a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi index 9a4cbef704c10..42462c138dd23 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi @@ -12,6 +12,7 @@ compatible = "renesas,r9a09g011"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; /* clock can be either from exclk or crystal oscillator (XIN/XOUT) */ extal_clk: extal { @@ -50,7 +51,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; ranges; @@ -368,10 +368,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, - <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; }; }; diff --git a/arch/arm64/boot/dts/renesas/r9a09g047.dtsi b/arch/arm64/boot/dts/renesas/r9a09g047.dtsi index 47d843c790212..7a469de3bb62a 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g047.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g047.dtsi @@ -12,6 +12,7 @@ compatible = "renesas,r9a09g047"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; audio_extal_clk: audio-clk { compatible = "fixed-clock"; @@ -64,6 +65,7 @@ next-level-cache = <&L3_CA55>; enable-method = "psci"; clocks = <&cpg CPG_CORE R9A09G047_CA55_0_CORECLK0>; + #cooling-cells = <2>; operating-points-v2 = <&cluster0_opp>; }; @@ -74,6 +76,7 @@ next-level-cache = <&L3_CA55>; enable-method = "psci"; clocks = <&cpg CPG_CORE R9A09G047_CA55_0_CORECLK1>; + #cooling-cells = <2>; operating-points-v2 = <&cluster0_opp>; }; @@ -84,6 +87,7 @@ next-level-cache = <&L3_CA55>; enable-method = "psci"; clocks = <&cpg CPG_CORE R9A09G047_CA55_0_CORECLK2>; + #cooling-cells = <2>; operating-points-v2 = <&cluster0_opp>; }; @@ -94,6 +98,7 @@ next-level-cache = <&L3_CA55>; enable-method = "psci"; clocks = <&cpg CPG_CORE R9A09G047_CA55_0_CORECLK3>; + #cooling-cells = <2>; operating-points-v2 = <&cluster0_opp>; }; @@ -155,7 +160,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; ranges; @@ -617,6 +621,19 @@ status = "disabled"; }; + tsu: thermal@14002000 { + compatible = "renesas,r9a09g047-tsu"; + reg = <0 0x14002000 0 0x1000>; + interrupts = , + ; + interrupt-names = "adi", "adcmpi"; + clocks = <&cpg CPG_MOD 0x10a>; + resets = <&cpg 0xf8>; + power-domains = <&cpg>; + #thermal-sensor-cells = <0>; + renesas,tsu-trim = <&sys 0x330>; + }; + i2c0: i2c@14400400 { compatible = "renesas,riic-r9a09g047", "renesas,riic-r9a09g057"; reg = <0 0x14400400 0 0x400>; @@ -1173,13 +1190,44 @@ snps,blen = <16 8 4 0 0 0 0>; }; + thermal-zones { + cpu-thermal { + polling-delay = <1000>; + polling-delay-passive = <250>; + thermal-sensors = <&tsu>; + + cooling-maps { + map0 { + trip = <&target>; + cooling-device = <&cpu0 0 3>, <&cpu1 0 3>, + <&cpu2 0 3>, <&cpu3 0 3>; + contribution = <1024>; + }; + }; + + trips { + target: trip-point { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + + sensor_crit: sensor-crit { + temperature = <120000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + }; + timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; }; diff --git a/arch/arm64/boot/dts/renesas/r9a09g056.dtsi b/arch/arm64/boot/dts/renesas/r9a09g056.dtsi index 8871108789060..8781c2fa73135 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g056.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g056.dtsi @@ -30,6 +30,7 @@ compatible = "renesas,r9a09g056"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; audio_extal_clk: audio-clk { compatible = "fixed-clock"; @@ -152,6 +153,11 @@ }; }; + pmu { + compatible = "arm,cortex-a55-pmu"; + interrupts = ; + }; + psci { compatible = "arm,psci-1.0", "arm,psci-0.2"; method = "smc"; @@ -173,7 +179,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; ranges; @@ -961,11 +966,11 @@ timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; }; diff --git a/arch/arm64/boot/dts/renesas/r9a09g057.dtsi b/arch/arm64/boot/dts/renesas/r9a09g057.dtsi index 630f7a98df386..4df32d7e99981 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g057.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g057.dtsi @@ -12,6 +12,7 @@ compatible = "renesas,r9a09g057"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; audio_extal_clk: audio-clk { compatible = "fixed-clock"; @@ -64,6 +65,7 @@ next-level-cache = <&L3_CA55>; enable-method = "psci"; clocks = <&cpg CPG_CORE R9A09G057_CA55_0_CORE_CLK0>; + #cooling-cells = <2>; operating-points-v2 = <&cluster0_opp>; }; @@ -74,6 +76,7 @@ next-level-cache = <&L3_CA55>; enable-method = "psci"; clocks = <&cpg CPG_CORE R9A09G057_CA55_0_CORE_CLK1>; + #cooling-cells = <2>; operating-points-v2 = <&cluster0_opp>; }; @@ -84,6 +87,7 @@ next-level-cache = <&L3_CA55>; enable-method = "psci"; clocks = <&cpg CPG_CORE R9A09G057_CA55_0_CORE_CLK2>; + #cooling-cells = <2>; operating-points-v2 = <&cluster0_opp>; }; @@ -94,6 +98,7 @@ next-level-cache = <&L3_CA55>; enable-method = "psci"; clocks = <&cpg CPG_CORE R9A09G057_CA55_0_CORE_CLK3>; + #cooling-cells = <2>; operating-points-v2 = <&cluster0_opp>; }; @@ -134,6 +139,11 @@ }; }; + pmu { + compatible = "arm,cortex-a55-pmu"; + interrupts = ; + }; + psci { compatible = "arm,psci-1.0", "arm,psci-0.2"; method = "smc"; @@ -155,7 +165,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; ranges; @@ -280,6 +289,32 @@ resets = <&cpg 0x30>; }; + tsu0: thermal@11000000 { + compatible = "renesas,r9a09g057-tsu", "renesas,r9a09g047-tsu"; + reg = <0 0x11000000 0 0x1000>; + interrupts = , + ; + interrupt-names = "adi", "adcmpi"; + clocks = <&cpg CPG_MOD 0x109>; + resets = <&cpg 0xf7>; + power-domains = <&cpg>; + #thermal-sensor-cells = <0>; + renesas,tsu-trim = <&sys 0x320>; + }; + + tsu1: thermal@14002000 { + compatible = "renesas,r9a09g057-tsu", "renesas,r9a09g047-tsu"; + reg = <0 0x14002000 0 0x1000>; + interrupts = , + ; + interrupt-names = "adi", "adcmpi"; + clocks = <&cpg CPG_MOD 0x10a>; + resets = <&cpg 0xf8>; + power-domains = <&cpg>; + #thermal-sensor-cells = <0>; + renesas,tsu-trim = <&sys 0x330>; + }; + xspi: spi@11030000 { compatible = "renesas,r9a09g057-xspi", "renesas,r9a09g047-xspi"; reg = <0 0x11030000 0 0x10000>, @@ -586,6 +621,21 @@ status = "disabled"; }; + rtc: rtc@11c00800 { + compatible = "renesas,r9a09g057-rtca3", "renesas,rz-rtca3"; + reg = <0 0x11c00800 0 0x400>; + interrupts = , + , + ; + interrupt-names = "alarm", "period", "carry"; + clocks = <&cpg CPG_MOD 0x53>, <&rtxin_clk>; + clock-names = "bus", "counter"; + power-domains = <&cpg>; + resets = <&cpg 0x79>, <&cpg 0x7a>; + reset-names = "rtc", "rtest"; + status = "disabled"; + }; + scif: serial@11c01400 { compatible = "renesas,scif-r9a09g057"; reg = <0 0x11c01400 0 0x400>; @@ -1307,13 +1357,58 @@ snps,blen = <16 8 4 0 0 0 0>; }; + thermal-zones { + sensor1_thermal: sensor1-thermal { + polling-delay = <1000>; + polling-delay-passive = <250>; + thermal-sensors = <&tsu0>; + + trips { + sensor1_crit: sensor1-crit { + temperature = <120000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + sensor2_thermal: sensor2-thermal { + polling-delay = <1000>; + polling-delay-passive = <250>; + thermal-sensors = <&tsu1>; + + cooling-maps { + map0 { + trip = <&sensor2_target>; + cooling-device = <&cpu0 0 3>, <&cpu1 0 3>, + <&cpu2 0 3>, <&cpu3 0 3>; + contribution = <1024>; + }; + }; + + trips { + sensor2_target: trip-point { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + + sensor2_crit: sensor2-crit { + temperature = <120000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + }; + timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; }; diff --git a/arch/arm64/boot/dts/renesas/r9a09g057h44-rzv2h-evk.dts b/arch/arm64/boot/dts/renesas/r9a09g057h44-rzv2h-evk.dts index 5c06bce3d5b4f..445fce156f730 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g057h44-rzv2h-evk.dts +++ b/arch/arm64/boot/dts/renesas/r9a09g057h44-rzv2h-evk.dts @@ -9,6 +9,7 @@ #include #include +#include #include "r9a09g057.dtsi" / { @@ -34,6 +35,18 @@ stdout-path = "serial0:115200n8"; }; + keys: keys { + compatible = "gpio-keys"; + + key-wakeup { + interrupts-extended = <&icu 0 IRQ_TYPE_EDGE_FALLING>; + linux,code = ; + label = "NMI_SW"; + debounce-interval = <20>; + wakeup-source; + }; + }; + memory@48000000 { device_type = "memory"; /* first 128MB is reserved for secure area. */ @@ -388,6 +401,10 @@ clock-frequency = <24000000>; }; +&rtc { + status = "okay"; +}; + &rtxin_clk { clock-frequency = <32768>; }; diff --git a/arch/arm64/boot/dts/renesas/r9a09g077.dtsi b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi index 7f1aca218c9fb..f5fa6ca064097 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g077.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi @@ -12,6 +12,7 @@ compatible = "renesas,r9a09g077"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; cpus { #address-cells = <1>; @@ -64,6 +65,11 @@ clock-frequency = <0>; }; + pmu { + compatible = "arm,cortex-a55-pmu"; + interrupts = ; + }; + psci { compatible = "arm,psci-1.0", "arm,psci-0.2"; method = "smc"; @@ -71,7 +77,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; ranges; @@ -265,6 +270,481 @@ status = "disabled"; }; + gmac0: ethernet@80100000 { + compatible = "renesas,r9a09g077-gbeth", "snps,dwmac-5.20"; + reg = <0 0x80100000 0 0x10000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "macirq", "eth_wake_irq", "eth_lpi", + "rx-queue-0", "rx-queue-1", "rx-queue-2", + "rx-queue-3", "rx-queue-4", "rx-queue-5", + "rx-queue-6", "rx-queue-7", "tx-queue-0", + "tx-queue-1", "tx-queue-2", "tx-queue-3", + "tx-queue-4", "tx-queue-5", "tx-queue-6", + "tx-queue-7"; + clocks = <&cpg CPG_MOD 400>, + <&cpg CPG_CORE R9A09G077_CLK_PCLKH>, + <&cpg CPG_CORE R9A09G077_ETCLKB>; + clock-names = "stmmaceth", "pclk", "tx"; + resets = <&cpg 400>, <&cpg 401>; + reset-names = "stmmaceth", "ahb"; + power-domains = <&cpg>; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <32>; + rx-fifo-depth = <8192>; + tx-fifo-depth = <8192>; + snps,fixed-burst; + snps,no-pbl-x8; + snps,force_thresh_dma_mode; + snps,axi-config = <&stmmac_axi_setup>; + snps,mtl-rx-config = <&mtl_rx_setup0>; + snps,mtl-tx-config = <&mtl_tx_setup0>; + snps,txpbl = <16>; + snps,rxpbl = <16>; + status = "disabled"; + + mdio0: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mtl_rx_setup0: rx-queues-config { + snps,rx-queues-to-use = <8>; + snps,rx-sched-sp; + + queue0 { + snps,dcb-algorithm; + snps,priority = <0x1>; + snps,map-to-dma-channel = <0>; + }; + + queue1 { + snps,dcb-algorithm; + snps,priority = <0x2>; + snps,map-to-dma-channel = <1>; + }; + + queue2 { + snps,dcb-algorithm; + snps,priority = <0x4>; + snps,map-to-dma-channel = <2>; + }; + + queue3 { + snps,dcb-algorithm; + snps,priority = <0x8>; + snps,map-to-dma-channel = <3>; + }; + + queue4 { + snps,dcb-algorithm; + snps,priority = <0x10>; + snps,map-to-dma-channel = <4>; + }; + + queue5 { + snps,dcb-algorithm; + snps,priority = <0x20>; + snps,map-to-dma-channel = <5>; + }; + + queue6 { + snps,dcb-algorithm; + snps,priority = <0x40>; + snps,map-to-dma-channel = <6>; + }; + + queue7 { + snps,dcb-algorithm; + snps,priority = <0x80>; + snps,map-to-dma-channel = <7>; + }; + }; + + mtl_tx_setup0: tx-queues-config { + snps,tx-queues-to-use = <8>; + + queue0 { + snps,dcb-algorithm; + }; + + queue1 { + snps,dcb-algorithm; + }; + + queue2 { + snps,dcb-algorithm; + }; + + queue3 { + snps,dcb-algorithm; + }; + + queue4 { + snps,dcb-algorithm; + }; + + queue5 { + snps,dcb-algorithm; + }; + + queue6 { + snps,dcb-algorithm; + }; + + queue7 { + snps,dcb-algorithm; + }; + }; + }; + + gmac1: ethernet@92000000 { + compatible = "renesas,r9a09g077-gbeth", "snps,dwmac-5.20"; + reg = <0 0x92000000 0 0x10000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "macirq", "eth_wake_irq", "eth_lpi", + "rx-queue-0", "rx-queue-1", "rx-queue-2", + "rx-queue-3", "rx-queue-4", "rx-queue-5", + "rx-queue-6", "rx-queue-7", "tx-queue-0", + "tx-queue-1", "tx-queue-2", "tx-queue-3", + "tx-queue-4", "tx-queue-5", "tx-queue-6", + "tx-queue-7"; + clocks = <&cpg CPG_MOD 416>, + <&cpg CPG_CORE R9A09G077_CLK_PCLKAH>, + <&cpg CPG_CORE R9A09G077_ETCLKB>; + clock-names = "stmmaceth", "pclk", "tx"; + resets = <&cpg 416>, <&cpg 417>; + reset-names = "stmmaceth", "ahb"; + power-domains = <&cpg>; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <32>; + rx-fifo-depth = <8192>; + tx-fifo-depth = <8192>; + snps,fixed-burst; + snps,no-pbl-x8; + snps,force_thresh_dma_mode; + snps,axi-config = <&stmmac_axi_setup>; + snps,mtl-rx-config = <&mtl_rx_setup1>; + snps,mtl-tx-config = <&mtl_tx_setup1>; + snps,txpbl = <16>; + snps,rxpbl = <16>; + status = "disabled"; + + mdio1: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mtl_rx_setup1: rx-queues-config { + snps,rx-queues-to-use = <8>; + snps,rx-sched-sp; + + queue0 { + snps,dcb-algorithm; + snps,priority = <0x1>; + snps,map-to-dma-channel = <0>; + }; + + queue1 { + snps,dcb-algorithm; + snps,priority = <0x2>; + snps,map-to-dma-channel = <1>; + }; + + queue2 { + snps,dcb-algorithm; + snps,priority = <0x4>; + snps,map-to-dma-channel = <2>; + }; + + queue3 { + snps,dcb-algorithm; + snps,priority = <0x8>; + snps,map-to-dma-channel = <3>; + }; + + queue4 { + snps,dcb-algorithm; + snps,priority = <0x10>; + snps,map-to-dma-channel = <4>; + }; + + queue5 { + snps,dcb-algorithm; + snps,priority = <0x20>; + snps,map-to-dma-channel = <5>; + }; + + queue6 { + snps,dcb-algorithm; + snps,priority = <0x40>; + snps,map-to-dma-channel = <6>; + }; + + queue7 { + snps,dcb-algorithm; + snps,priority = <0x80>; + snps,map-to-dma-channel = <7>; + }; + }; + + mtl_tx_setup1: tx-queues-config { + snps,tx-queues-to-use = <8>; + + queue0 { + snps,dcb-algorithm; + }; + + queue1 { + snps,dcb-algorithm; + }; + + queue2 { + snps,dcb-algorithm; + }; + + queue3 { + snps,dcb-algorithm; + }; + + queue4 { + snps,dcb-algorithm; + }; + + queue5 { + snps,dcb-algorithm; + }; + + queue6 { + snps,dcb-algorithm; + }; + + queue7 { + snps,dcb-algorithm; + }; + }; + }; + + gmac2: ethernet@92010000 { + compatible = "renesas,r9a09g077-gbeth", "snps,dwmac-5.20"; + reg = <0 0x92010000 0 0x10000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "macirq", "eth_wake_irq", "eth_lpi", + "rx-queue-0", "rx-queue-1", "rx-queue-2", + "rx-queue-3", "rx-queue-4", "rx-queue-5", + "rx-queue-6", "rx-queue-7", "tx-queue-0", + "tx-queue-1", "tx-queue-2", "tx-queue-3", + "tx-queue-4", "tx-queue-5", "tx-queue-6", + "tx-queue-7"; + clocks = <&cpg CPG_MOD 417>, + <&cpg CPG_CORE R9A09G077_CLK_PCLKAH>, + <&cpg CPG_CORE R9A09G077_ETCLKB>; + clock-names = "stmmaceth", "pclk", "tx"; + resets = <&cpg 418>, <&cpg 419>; + reset-names = "stmmaceth", "ahb"; + power-domains = <&cpg>; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <32>; + rx-fifo-depth = <8192>; + tx-fifo-depth = <8192>; + snps,fixed-burst; + snps,no-pbl-x8; + snps,force_thresh_dma_mode; + snps,axi-config = <&stmmac_axi_setup>; + snps,mtl-rx-config = <&mtl_rx_setup2>; + snps,mtl-tx-config = <&mtl_tx_setup2>; + snps,txpbl = <16>; + snps,rxpbl = <16>; + status = "disabled"; + + mdio2: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mtl_rx_setup2: rx-queues-config { + snps,rx-queues-to-use = <8>; + snps,rx-sched-sp; + + queue0 { + snps,dcb-algorithm; + snps,priority = <0x1>; + snps,map-to-dma-channel = <0>; + }; + + queue1 { + snps,dcb-algorithm; + snps,priority = <0x2>; + snps,map-to-dma-channel = <1>; + }; + + queue2 { + snps,dcb-algorithm; + snps,priority = <0x4>; + snps,map-to-dma-channel = <2>; + }; + + queue3 { + snps,dcb-algorithm; + snps,priority = <0x8>; + snps,map-to-dma-channel = <3>; + }; + + queue4 { + snps,dcb-algorithm; + snps,priority = <0x10>; + snps,map-to-dma-channel = <4>; + }; + + queue5 { + snps,dcb-algorithm; + snps,priority = <0x20>; + snps,map-to-dma-channel = <5>; + }; + + queue6 { + snps,dcb-algorithm; + snps,priority = <0x40>; + snps,map-to-dma-channel = <6>; + }; + + queue7 { + snps,dcb-algorithm; + snps,priority = <0x80>; + snps,map-to-dma-channel = <7>; + }; + }; + + mtl_tx_setup2: tx-queues-config { + snps,tx-queues-to-use = <8>; + + queue0 { + snps,dcb-algorithm; + }; + + queue1 { + snps,dcb-algorithm; + }; + + queue2 { + snps,dcb-algorithm; + }; + + queue3 { + snps,dcb-algorithm; + }; + + queue4 { + snps,dcb-algorithm; + }; + + queue5 { + snps,dcb-algorithm; + }; + + queue6 { + snps,dcb-algorithm; + }; + + queue7 { + snps,dcb-algorithm; + }; + }; + }; + + ethss: ethss@80110000 { + compatible = "renesas,r9a09g077-miic"; + reg = <0 0x80110000 0 0x10000>; + clocks = <&cpg CPG_CORE R9A09G077_ETCLKE>, + <&cpg CPG_CORE R9A09G077_ETCLKB>, + <&cpg CPG_CORE R9A09G077_ETCLKD>, + <&cpg CPG_MOD 403>; + clock-names = "mii_ref", "rgmii_ref", "rmii_ref", "hclk"; + resets = <&cpg 405>, <&cpg 406>; + reset-names = "rst", "crst"; + power-domains = <&cpg>; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + + mii_conv0: mii-conv@0 { + reg = <0>; + status = "disabled"; + }; + + mii_conv1: mii-conv@1 { + reg = <1>; + status = "disabled"; + }; + + mii_conv2: mii-conv@2 { + reg = <2>; + status = "disabled"; + }; + + mii_conv3: mii-conv@3 { + reg = <3>; + status = "disabled"; + }; + }; + cpg: clock-controller@80280000 { compatible = "renesas,r9a09g077-cpg-mssr"; reg = <0 0x80280000 0 0x1000>, @@ -299,6 +779,72 @@ interrupts = ; }; + adc0: adc@90014000 { + compatible = "renesas,r9a09g077-adc"; + reg = <0 0x90014000 0 0x400>; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "adi", "gbadi", "gcadi", + "cmpai", "cmpbi", "wcmpm", "wcmpum"; + clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKL>, + <&cpg CPG_MOD 206>; + clock-names = "adclk", "pclk"; + power-domains = <&cpg>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + status = "disabled"; + }; + + adc1: adc@90014400 { + compatible = "renesas,r9a09g077-adc"; + reg = <0 0x90014400 0 0x400>; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "adi", "gbadi", "gcadi", + "cmpai", "cmpbi", "wcmpm", "wcmpum"; + clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKL>, + <&cpg CPG_MOD 207>; + clock-names = "adclk", "pclk"; + power-domains = <&cpg>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + status = "disabled"; + }; + + adc2: adc@80008000 { + compatible = "renesas,r9a09g077-adc"; + reg = <0 0x80008000 0 0x400>; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "adi", "gbadi", "gcadi", + "cmpai", "cmpbi", "wcmpm", "wcmpum"; + clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKL>, + <&cpg CPG_MOD 225>; + clock-names = "adclk", "pclk"; + power-domains = <&cpg>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + status = "disabled"; + }; + ohci: usb@92040000 { compatible = "generic-ohci"; reg = <0 0x92040000 0 0x100>; @@ -387,13 +933,20 @@ }; }; + stmmac_axi_setup: stmmac-axi-config { + snps,lpi_en; + snps,wr_osr_lmt = <0xf>; + snps,rd_osr_lmt = <0xf>; + snps,blen = <16 8 4 0 0 0 0>; + }; + timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; }; diff --git a/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts b/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts index 2bf867273ad0b..b7706d0bc3aa1 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts +++ b/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts @@ -149,7 +149,77 @@ status = "okay"; }; +&mdio1_phy { + reset-gpios = <&pinctrl RZT2H_GPIO(32, 3) GPIO_ACTIVE_LOW>; +}; + +&mdio2_phy { + /* + * PHY2 Reset Configuration: + * + * SW6[1] OFF; SW6[2] ON; SW6[3] OFF - use pin P17_5 for GMAC_RESETOUT2# + */ + reset-gpios = <&pinctrl RZT2H_GPIO(17, 5) GPIO_ACTIVE_LOW>; +}; + &pinctrl { + /* + * GMAC2 Pin Configuration: + * + * SW2[6] OFF - connect MDC/MDIO of Ethernet port 2 to GMAC2 + * SW2[7] ON - use pins P29_1-P29_7, P30_0-P30_4, and P31_2-P31_5 + * for Ethernet port 2 + */ + gmac2_pins: gmac2-pins { + pinmux = , /* ETH2_TXCLK */ + , /* ETH2_TXD0 */ + , /* ETH2_TXD1 */ + , /* ETH2_TXD2 */ + , /* ETH2_TXD3 */ + , /* ETH2_TXEN */ + , /* ETH2_RXCLK */ + , /* ETH2_RXD0 */ + , /* ETH2_RXD1 */ + , /* ETH2_RXD2 */ + , /* ETH2_RXD3 */ + , /* ETH2_RXDV */ + , /* ETH2_TXER */ + , /* ETH2_RXER */ + , /* ETH2_CRS */ + , /* ETH2_COL */ + , /* GMAC2_MDC */ + , /* GMAC2_MDIO */ + ; /* ETH2_REFCLK */ + }; + + /* + * GMAC1 Pin Configuration: + * + * SW2[8] ON - use pins P33_2-P33_7, P34_0-P34_5, P34_7 and + * P35_0-P35_2 for Ethernet port 3 + */ + gmac1_pins: gmac1-pins { + pinmux = , /* ETH3_TXCLK */ + , /* ETH3_TXD0 */ + , /* ETH3_TXD1 */ + , /* ETH3_TXD2 */ + , /* ETH3_TXD3 */ + , /* ETH3_TXEN */ + , /* ETH3_RXCLK */ + , /* ETH3_RXD0 */ + , /* ETH3_RXD1 */ + , /* ETH3_RXD2 */ + , /* ETH3_RXD3 */ + , /* ETH3_RXDV */ + , /* ETH3_TXER */ + , /* ETH3_RXER */ + , /* ETH3_CRS */ + , /* ETH3_COL */ + , /* GMAC1_MDC */ + , /* GMAC1_MDIO */ + ; /* ETH3_REFCLK */ + }; + /* * I2C0 Pin Configuration: * ------------------------ @@ -182,3 +252,31 @@ ; /* OVRCUR */ }; }; + +&adc2 { + status = "okay"; + + channel@0 { + reg = <0x0>; + }; + + channel@1 { + reg = <0x1>; + }; + + channel@2 { + reg = <0x2>; + }; + + channel@3 { + reg = <0x3>; + }; + + channel@4 { + reg = <0x4>; + }; + + channel@5 { + reg = <0x5>; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/r9a09g087.dtsi b/arch/arm64/boot/dts/renesas/r9a09g087.dtsi index f06c19c73adb8..361a9235f00d9 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g087.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g087.dtsi @@ -12,6 +12,7 @@ compatible = "renesas,r9a09g087"; #address-cells = <2>; #size-cells = <2>; + interrupt-parent = <&gic>; cpus { #address-cells = <1>; @@ -64,6 +65,11 @@ clock-frequency = <0>; }; + pmu { + compatible = "arm,cortex-a55-pmu"; + interrupts = ; + }; + psci { compatible = "arm,psci-1.0", "arm,psci-0.2"; method = "smc"; @@ -71,7 +77,6 @@ soc: soc { compatible = "simple-bus"; - interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; ranges; @@ -265,6 +270,484 @@ status = "disabled"; }; + gmac0: ethernet@80100000 { + compatible = "renesas,r9a09g087-gbeth", "renesas,r9a09g077-gbeth", + "snps,dwmac-5.20"; + reg = <0 0x80100000 0 0x10000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "macirq", "eth_wake_irq", "eth_lpi", + "rx-queue-0", "rx-queue-1", "rx-queue-2", + "rx-queue-3", "rx-queue-4", "rx-queue-5", + "rx-queue-6", "rx-queue-7", "tx-queue-0", + "tx-queue-1", "tx-queue-2", "tx-queue-3", + "tx-queue-4", "tx-queue-5", "tx-queue-6", + "tx-queue-7"; + clocks = <&cpg CPG_MOD 400>, + <&cpg CPG_CORE R9A09G087_CLK_PCLKH>, + <&cpg CPG_CORE R9A09G087_ETCLKB>; + clock-names = "stmmaceth", "pclk", "tx"; + resets = <&cpg 400>, <&cpg 401>; + reset-names = "stmmaceth", "ahb"; + power-domains = <&cpg>; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <32>; + rx-fifo-depth = <8192>; + tx-fifo-depth = <8192>; + snps,fixed-burst; + snps,no-pbl-x8; + snps,force_thresh_dma_mode; + snps,axi-config = <&stmmac_axi_setup>; + snps,mtl-rx-config = <&mtl_rx_setup0>; + snps,mtl-tx-config = <&mtl_tx_setup0>; + snps,txpbl = <16>; + snps,rxpbl = <16>; + status = "disabled"; + + mdio0: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mtl_rx_setup0: rx-queues-config { + snps,rx-queues-to-use = <8>; + snps,rx-sched-sp; + + queue0 { + snps,dcb-algorithm; + snps,priority = <0x1>; + snps,map-to-dma-channel = <0>; + }; + + queue1 { + snps,dcb-algorithm; + snps,priority = <0x2>; + snps,map-to-dma-channel = <1>; + }; + + queue2 { + snps,dcb-algorithm; + snps,priority = <0x4>; + snps,map-to-dma-channel = <2>; + }; + + queue3 { + snps,dcb-algorithm; + snps,priority = <0x8>; + snps,map-to-dma-channel = <3>; + }; + + queue4 { + snps,dcb-algorithm; + snps,priority = <0x10>; + snps,map-to-dma-channel = <4>; + }; + + queue5 { + snps,dcb-algorithm; + snps,priority = <0x20>; + snps,map-to-dma-channel = <5>; + }; + + queue6 { + snps,dcb-algorithm; + snps,priority = <0x40>; + snps,map-to-dma-channel = <6>; + }; + + queue7 { + snps,dcb-algorithm; + snps,priority = <0x80>; + snps,map-to-dma-channel = <7>; + }; + }; + + mtl_tx_setup0: tx-queues-config { + snps,tx-queues-to-use = <8>; + + queue0 { + snps,dcb-algorithm; + }; + + queue1 { + snps,dcb-algorithm; + }; + + queue2 { + snps,dcb-algorithm; + }; + + queue3 { + snps,dcb-algorithm; + }; + + queue4 { + snps,dcb-algorithm; + }; + + queue5 { + snps,dcb-algorithm; + }; + + queue6 { + snps,dcb-algorithm; + }; + + queue7 { + snps,dcb-algorithm; + }; + }; + }; + + gmac1: ethernet@92000000 { + compatible = "renesas,r9a09g087-gbeth", "renesas,r9a09g077-gbeth", + "snps,dwmac-5.20"; + reg = <0 0x92000000 0 0x10000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "macirq", "eth_wake_irq", "eth_lpi", + "rx-queue-0", "rx-queue-1", "rx-queue-2", + "rx-queue-3", "rx-queue-4", "rx-queue-5", + "rx-queue-6", "rx-queue-7", "tx-queue-0", + "tx-queue-1", "tx-queue-2", "tx-queue-3", + "tx-queue-4", "tx-queue-5", "tx-queue-6", + "tx-queue-7"; + clocks = <&cpg CPG_MOD 416>, + <&cpg CPG_CORE R9A09G087_CLK_PCLKAH>, + <&cpg CPG_CORE R9A09G087_ETCLKB>; + clock-names = "stmmaceth", "pclk", "tx"; + resets = <&cpg 416>, <&cpg 417>; + reset-names = "stmmaceth", "ahb"; + power-domains = <&cpg>; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <32>; + rx-fifo-depth = <8192>; + tx-fifo-depth = <8192>; + snps,fixed-burst; + snps,no-pbl-x8; + snps,force_thresh_dma_mode; + snps,axi-config = <&stmmac_axi_setup>; + snps,mtl-rx-config = <&mtl_rx_setup1>; + snps,mtl-tx-config = <&mtl_tx_setup1>; + snps,txpbl = <16>; + snps,rxpbl = <16>; + status = "disabled"; + + mdio1: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mtl_rx_setup1: rx-queues-config { + snps,rx-queues-to-use = <8>; + snps,rx-sched-sp; + + queue0 { + snps,dcb-algorithm; + snps,priority = <0x1>; + snps,map-to-dma-channel = <0>; + }; + + queue1 { + snps,dcb-algorithm; + snps,priority = <0x2>; + snps,map-to-dma-channel = <1>; + }; + + queue2 { + snps,dcb-algorithm; + snps,priority = <0x4>; + snps,map-to-dma-channel = <2>; + }; + + queue3 { + snps,dcb-algorithm; + snps,priority = <0x8>; + snps,map-to-dma-channel = <3>; + }; + + queue4 { + snps,dcb-algorithm; + snps,priority = <0x10>; + snps,map-to-dma-channel = <4>; + }; + + queue5 { + snps,dcb-algorithm; + snps,priority = <0x20>; + snps,map-to-dma-channel = <5>; + }; + + queue6 { + snps,dcb-algorithm; + snps,priority = <0x40>; + snps,map-to-dma-channel = <6>; + }; + + queue7 { + snps,dcb-algorithm; + snps,priority = <0x80>; + snps,map-to-dma-channel = <7>; + }; + }; + + mtl_tx_setup1: tx-queues-config { + snps,tx-queues-to-use = <8>; + + queue0 { + snps,dcb-algorithm; + }; + + queue1 { + snps,dcb-algorithm; + }; + + queue2 { + snps,dcb-algorithm; + }; + + queue3 { + snps,dcb-algorithm; + }; + + queue4 { + snps,dcb-algorithm; + }; + + queue5 { + snps,dcb-algorithm; + }; + + queue6 { + snps,dcb-algorithm; + }; + + queue7 { + snps,dcb-algorithm; + }; + }; + }; + + gmac2: ethernet@92010000 { + compatible = "renesas,r9a09g087-gbeth", "renesas,r9a09g077-gbeth", + "snps,dwmac-5.20"; + reg = <0 0x92010000 0 0x10000>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "macirq", "eth_wake_irq", "eth_lpi", + "rx-queue-0", "rx-queue-1", "rx-queue-2", + "rx-queue-3", "rx-queue-4", "rx-queue-5", + "rx-queue-6", "rx-queue-7", "tx-queue-0", + "tx-queue-1", "tx-queue-2", "tx-queue-3", + "tx-queue-4", "tx-queue-5", "tx-queue-6", + "tx-queue-7"; + clocks = <&cpg CPG_MOD 417>, + <&cpg CPG_CORE R9A09G087_CLK_PCLKAH>, + <&cpg CPG_CORE R9A09G087_ETCLKB>; + clock-names = "stmmaceth", "pclk", "tx"; + resets = <&cpg 418>, <&cpg 419>; + reset-names = "stmmaceth", "ahb"; + power-domains = <&cpg>; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <32>; + rx-fifo-depth = <8192>; + tx-fifo-depth = <8192>; + snps,fixed-burst; + snps,no-pbl-x8; + snps,force_thresh_dma_mode; + snps,axi-config = <&stmmac_axi_setup>; + snps,mtl-rx-config = <&mtl_rx_setup2>; + snps,mtl-tx-config = <&mtl_tx_setup2>; + snps,txpbl = <16>; + snps,rxpbl = <16>; + status = "disabled"; + + mdio2: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mtl_rx_setup2: rx-queues-config { + snps,rx-queues-to-use = <8>; + snps,rx-sched-sp; + + queue0 { + snps,dcb-algorithm; + snps,priority = <0x1>; + snps,map-to-dma-channel = <0>; + }; + + queue1 { + snps,dcb-algorithm; + snps,priority = <0x2>; + snps,map-to-dma-channel = <1>; + }; + + queue2 { + snps,dcb-algorithm; + snps,priority = <0x4>; + snps,map-to-dma-channel = <2>; + }; + + queue3 { + snps,dcb-algorithm; + snps,priority = <0x8>; + snps,map-to-dma-channel = <3>; + }; + + queue4 { + snps,dcb-algorithm; + snps,priority = <0x10>; + snps,map-to-dma-channel = <4>; + }; + + queue5 { + snps,dcb-algorithm; + snps,priority = <0x20>; + snps,map-to-dma-channel = <5>; + }; + + queue6 { + snps,dcb-algorithm; + snps,priority = <0x40>; + snps,map-to-dma-channel = <6>; + }; + + queue7 { + snps,dcb-algorithm; + snps,priority = <0x80>; + snps,map-to-dma-channel = <7>; + }; + }; + + mtl_tx_setup2: tx-queues-config { + snps,tx-queues-to-use = <8>; + + queue0 { + snps,dcb-algorithm; + }; + + queue1 { + snps,dcb-algorithm; + }; + + queue2 { + snps,dcb-algorithm; + }; + + queue3 { + snps,dcb-algorithm; + }; + + queue4 { + snps,dcb-algorithm; + }; + + queue5 { + snps,dcb-algorithm; + }; + + queue6 { + snps,dcb-algorithm; + }; + + queue7 { + snps,dcb-algorithm; + }; + }; + }; + + ethss: ethss@80110000 { + compatible = "renesas,r9a09g087-miic", "renesas,r9a09g077-miic"; + reg = <0 0x80110000 0 0x10000>; + clocks = <&cpg CPG_CORE R9A09G087_ETCLKE>, + <&cpg CPG_CORE R9A09G087_ETCLKB>, + <&cpg CPG_CORE R9A09G087_ETCLKD>, + <&cpg CPG_MOD 403>; + clock-names = "mii_ref", "rgmii_ref", "rmii_ref", "hclk"; + resets = <&cpg 405>, <&cpg 406>; + reset-names = "rst", "crst"; + power-domains = <&cpg>; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + + mii_conv0: mii-conv@0 { + reg = <0>; + status = "disabled"; + }; + + mii_conv1: mii-conv@1 { + reg = <1>; + status = "disabled"; + }; + + mii_conv2: mii-conv@2 { + reg = <2>; + status = "disabled"; + }; + + mii_conv3: mii-conv@3 { + reg = <3>; + status = "disabled"; + }; + }; + cpg: clock-controller@80280000 { compatible = "renesas,r9a09g087-cpg-mssr"; reg = <0 0x80280000 0 0x1000>, @@ -299,6 +782,72 @@ interrupts = ; }; + adc0: adc@90014000 { + compatible = "renesas,r9a09g087-adc", "renesas,r9a09g077-adc"; + reg = <0 0x90014000 0 0x400>; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "adi", "gbadi", "gcadi", + "cmpai", "cmpbi", "wcmpm", "wcmpum"; + clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKL>, + <&cpg CPG_MOD 206>; + clock-names = "adclk", "pclk"; + power-domains = <&cpg>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + status = "disabled"; + }; + + adc1: adc@90014400 { + compatible = "renesas,r9a09g087-adc", "renesas,r9a09g077-adc"; + reg = <0 0x90014400 0 0x400>; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "adi", "gbadi", "gcadi", + "cmpai", "cmpbi", "wcmpm", "wcmpum"; + clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKL>, + <&cpg CPG_MOD 207>; + clock-names = "adclk", "pclk"; + power-domains = <&cpg>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + status = "disabled"; + }; + + adc2: adc@80008000 { + compatible = "renesas,r9a09g087-adc", "renesas,r9a09g077-adc"; + reg = <0 0x80008000 0 0x400>; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "adi", "gbadi", "gcadi", + "cmpai", "cmpbi", "wcmpm", "wcmpum"; + clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKL>, + <&cpg CPG_MOD 225>; + clock-names = "adclk", "pclk"; + power-domains = <&cpg>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + status = "disabled"; + }; + ohci: usb@92040000 { compatible = "generic-ohci"; reg = <0 0x92040000 0 0x100>; @@ -387,13 +936,20 @@ }; }; + stmmac_axi_setup: stmmac-axi-config { + snps,lpi_en; + snps,wr_osr_lmt = <0xf>; + snps,rd_osr_lmt = <0xf>; + snps,blen = <16 8 4 0 0 0 0>; + }; + timer { compatible = "arm,armv8-timer"; - interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, - <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; + interrupts = , + , + , + , + ; interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; }; }; diff --git a/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts b/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts index 084b3a0c80524..17c0c79fbd96b 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts +++ b/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts @@ -186,7 +186,85 @@ status = "okay"; }; +&mdio1_phy { + /* + * PHY3 Reset Configuration: + * + * DSW12[5] OFF; DSW12[6] ON - use pin P03_2 for GMAC_RESETOUT3# + */ + reset-gpios = <&pinctrl RZT2H_GPIO(3, 2) GPIO_ACTIVE_LOW>; +}; + +&mdio2_phy { + /* + * PHY2 Reset Configuration: + * + * DSW8[1] ON; DSW8[2] OFF; DSW12[7] OFF; DSW12[8] ON - use pin + * P03_1 for GMAC_RESETOUT2# + */ + reset-gpios = <&pinctrl RZT2H_GPIO(3, 1) GPIO_ACTIVE_LOW>; +}; + &pinctrl { + /* + * GMAC2 Pin Configuration: + * + * DSW5[6] OFF - connect MDC/MDIO of Ethernet port 2 to GMAC2 + * DSW5[7] ON - use pins P29_1-P29_7, P30_0-P30_4, P30_7, + * P31_2, P31_4 and P31_5 are used for Ethernet port 2 + */ + gmac2_pins: gmac2-pins { + pinmux = , /* ETH2_TXCLK */ + , /* ETH2_TXD0 */ + , /* ETH2_TXD1 */ + , /* ETH2_TXD2 */ + , /* ETH2_TXD3 */ + , /* ETH2_TXEN */ + , /* ETH2_RXCLK */ + , /* ETH2_RXD0 */ + , /* ETH2_RXD1 */ + , /* ETH2_RXD2 */ + , /* ETH2_RXD3 */ + , /* ETH2_RXDV */ + , /* ETH2_TXER */ + , /* ETH2_RXER */ + , /* ETH2_CRS */ + , /* ETH2_COL */ + , /* GMAC2_MDC */ + , /* GMAC2_MDIO */ + ; /* ETH2_REFCLK */ + + }; + + /* + * GMAC2 Pin Configuration: + * + * DSW5[8] ON - use pins P00_0-P00_2, P33_2-P33_7, P34_0-P34_6 + * for Ethernet port 3 + * DSW12[1] OFF; DSW12[2] ON - use pin P00_3 for Ethernet port 3 + */ + gmac1_pins: gmac1-pins { + pinmux = , /* ETH3_TXCLK */ + , /* ETH3_TXD0 */ + , /* ETH3_TXD0 */ + , /* ETH3_TXD2 */ + , /* ETH3_TXD3 */ + , /* ETH3_TXEN */ + , /* ETH3_RXCLK */ + , /* ETH3_RXD0 */ + , /* ETH3_RXD1 */ + , /* ETH3_RXD2 */ + , /* ETH3_RXD3 */ + , /* ETH3_RXDV */ + , /* ETH3_TXER */ + , /* ETH3_RXER */ + , /* ETH3_CRS */ + , /* ETH3_COL */ + , /* GMAC1_MDC */ + , /* GMAC1_MDIO */ + ; /* ETH3_REFCLK */ + }; + /* * I2C0 Pin Configuration: * ------------------------ @@ -227,3 +305,67 @@ ; /* OVRCUR */ }; }; + +&adc2 { + status = "okay"; + + channel@0 { + reg = <0x0>; + }; + + channel@1 { + reg = <0x1>; + }; + + channel@2 { + reg = <0x2>; + }; + + channel@3 { + reg = <0x3>; + }; + + channel@4 { + reg = <0x4>; + }; + + channel@5 { + reg = <0x5>; + }; + + channel@6 { + reg = <0x6>; + }; + + channel@7 { + reg = <0x7>; + }; + + channel@8 { + reg = <0x8>; + }; + + channel@9 { + reg = <0x9>; + }; + + channel@a { + reg = <0xa>; + }; + + channel@b { + reg = <0xb>; + }; + + channel@c { + reg = <0xc>; + }; + + channel@d { + reg = <0xd>; + }; + + channel@e { + reg = <0xe>; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/rz-smarc-cru-csi-ov5645.dtsi b/arch/arm64/boot/dts/renesas/rz-smarc-cru-csi-ov5645.dtsi index c5bb63c63b470..4d2b0655859ab 100644 --- a/arch/arm64/boot/dts/renesas/rz-smarc-cru-csi-ov5645.dtsi +++ b/arch/arm64/boot/dts/renesas/rz-smarc-cru-csi-ov5645.dtsi @@ -64,7 +64,6 @@ compatible = "ovti,ov5645"; reg = <0x3c>; clocks = <&ov5645_fixed_clk>; - clock-frequency = <24000000>; vdddo-supply = <&ov5645_vdddo_1v8>; vdda-supply = <&ov5645_vdda_2v8>; vddd-supply = <&ov5645_vddd_1v5>; diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi index 39845faec8943..6f25ab6179829 100644 --- a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi @@ -84,10 +84,6 @@ }; }; -&adc { - status = "okay"; -}; - #if SW_CONFIG3 == SW_ON ð0 { pinctrl-0 = <ð0_pins>; diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi index 5e044a4d02343..6b0bb2c441af5 100644 --- a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi @@ -92,6 +92,20 @@ clock-frequency = <12288000>; }; +&ehci0 { + dr_mode = "otg"; + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&hsusb { + dr_mode = "otg"; + status = "okay"; +}; + &i2c0 { status = "okay"; @@ -132,6 +146,19 @@ }; }; +&ohci0 { + dr_mode = "otg"; + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&phyrst { + status = "okay"; +}; + &pinctrl { audio_clock_pins: audio-clock { pins = "AUDIO_CLK1", "AUDIO_CLK2"; @@ -207,6 +234,23 @@ , /* TXD */ ; /* RXD */ }; + + usb0_pins: usb0 { + peri { + pinmux = , /* VBUS */ + ; /* OVC */ + }; + + otg { + pinmux = ; /* OTG_ID */ + bias-pull-up; + }; + }; + + usb1_pins: usb1 { + pinmux = , /* OVC */ + ; /* VBUS */ + }; }; &scif0 { @@ -242,3 +286,16 @@ pinctrl-0 = <&ssi3_pins>, <&audio_clock_pins>; status = "okay"; }; + +&usb2_phy0 { + pinctrl-0 = <&usb0_pins>; + pinctrl-names = "default"; + vbus-supply = <&usb0_vbus_otg>; + status = "okay"; +}; + +&usb2_phy1 { + pinctrl-0 = <&usb1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-common.dtsi b/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-common.dtsi index 5c91002c99c48..3eed1f3948e8e 100644 --- a/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-common.dtsi +++ b/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-common.dtsi @@ -7,10 +7,14 @@ #include #include +#include +#include #include / { aliases { + ethernet3 = &gmac1; + ethernet2 = &gmac2; i2c0 = &i2c0; i2c1 = &i2c1; mmc0 = &sdhi0; @@ -70,10 +74,34 @@ status = "okay"; }; +ðss { + status = "okay"; + + renesas,miic-switch-portin = ; +}; + &extal_clk { clock-frequency = <25000000>; }; +&gmac1 { + pinctrl-0 = <&gmac1_pins>; + pinctrl-names = "default"; + phy-handle = <&mdio1_phy>; + phy-mode = "rgmii-id"; + pcs-handle = <&mii_conv3>; + status = "okay"; +}; + +&gmac2 { + pinctrl-0 = <&gmac2_pins>; + pinctrl-names = "default"; + phy-handle = <&mdio2_phy>; + phy-mode = "rgmii-id"; + pcs-handle = <&mii_conv2>; + status = "okay"; +}; + &hsusb { dr_mode = "otg"; status = "okay"; @@ -87,6 +115,48 @@ }; }; +&mdio1 { + mdio1_phy: ethernet-phy@3 { + compatible = "ethernet-phy-id0007.0772", "ethernet-phy-ieee802.3-c22"; + reg = <3>; + vsc8531,led-0-mode = ; + vsc8531,led-1-mode = ; + reset-assert-us = <2000>; + reset-deassert-us = <15000>; + }; +}; + +&mdio2 { + mdio2_phy: ethernet-phy@2 { + compatible = "ethernet-phy-id0007.0772", "ethernet-phy-ieee802.3-c22"; + reg = <2>; + vsc8531,led-0-mode = ; + vsc8531,led-1-mode = ; + reset-assert-us = <2000>; + reset-deassert-us = <15000>; + }; +}; + +&mii_conv0 { + renesas,miic-input = ; + status = "okay"; +}; + +&mii_conv1 { + renesas,miic-input = ; + status = "okay"; +}; + +&mii_conv2 { + renesas,miic-input = ; + status = "okay"; +}; + +&mii_conv3 { + renesas,miic-input = ; + status = "okay"; +}; + &ohci { dr_mode = "otg"; status = "okay"; @@ -244,3 +314,82 @@ status = "okay"; timeout-sec = <60>; }; + +/* + * ADC0 AN000 can be connected to a potentiometer on the board or + * exposed on ADC header. + * + * T2H: + * SW17[1] = ON, SW17[2] = OFF - Potentiometer + * SW17[1] = OFF, SW17[2] = ON - CN41 header + * N2H: + * DSW6[1] = OFF, DSW6[2] = ON - Potentiometer + * DSW6[1] = ON, DSW6[2] = OFF - CN3 header + */ +&adc0 { + status = "okay"; + + channel@0 { + reg = <0x0>; + }; + + channel@1 { + reg = <0x1>; + }; + + channel@2 { + reg = <0x2>; + }; + + channel@3 { + reg = <0x3>; + }; +}; + +/* + * ADC1 AN100 can be exposed on ADC header or on mikroBUS connector. + * + * T2H: + * SW18[1] = ON, SW18[2] = OFF - CN42 header + * SW18[1] = OFF, SW18[2] = ON - mikroBUS + * N2H: + * DSW6[3] = ON, DSW6[4] = OFF - CN4 header + * DSW6[3] = OFF, DSW6[4] = ON - mikroBUS + * + * ADC1 AN101 can be exposed on ADC header or on Grove2 connector. + * + * T2H: + * SW18[3] = ON, SW18[4] = OFF - CN42 header + * SW18[3] = OFF, SW18[4] = ON - Grove2 + * N2H: + * DSW6[5] = ON, DSW6[6] = OFF - CN4 header + * DSW6[5] = OFF, DSW6[6] = ON - Grove2 + * + * ADC1 AN102 can be exposed on ADC header or on Grove2 connector. + * + * T2H: + * SW18[5] = ON, SW18[6] = OFF - CN42 header + * SW18[5] = OFF, SW18[6] = ON - Grove2 + * N2H: + * DSW6[7] = ON, DSW6[8] = OFF - CN4 header + * DSW6[7] = OFF, DSW6[8] = ON - Grove2 + */ +&adc1 { + status = "okay"; + + channel@0 { + reg = <0x0>; + }; + + channel@1 { + reg = <0x1>; + }; + + channel@2 { + reg = <0x2>; + }; + + channel@3 { + reg = <0x3>; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi index bbb3583372d04..fa8bfee07b3c8 100644 --- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi +++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi @@ -1004,6 +1004,11 @@ shared-pin; }; +/* Firmware should reserve it but sadly doesn't */ +&swdt { + status = "reserved"; +}; + &usb_extal_clk { clock-frequency = <50000000>; }; diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi index 8a30908992ab0..a9e53b36f1d9c 100644 --- a/arch/arm64/boot/dts/renesas/ulcb.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi @@ -495,6 +495,11 @@ shared-pin; }; +/* Firmware should reserve it but sadly doesn't */ +&swdt { + status = "reserved"; +}; + &usb2_phy1 { pinctrl-0 = <&usb1_pins>; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index ad684e3831bc7..dbdda9783e939 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -130,7 +130,11 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-lubancat-1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-nanopi-r3s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-cb2-manta.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-pi2.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-tinker-board-3.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-tinker-board-3s.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-easepi-r1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r68s.dtb @@ -142,6 +146,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5c.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-odroid-m1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-photonicat.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-qnap-ts233.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-qnap-ts433.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-radxa-e25.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-roc-pc.dtb @@ -150,11 +155,13 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3b.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-display-vz.dtbo dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-io-expander.dtbo +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-100ask-dshanpi-a1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-armsom-sige5.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-armsom-sige5-v1.2-wifibt.dtbo dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-luckfox-omni3576.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-nanopi-m5.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-nanopi-r76s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-roc-pc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-rock-4d.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3582-radxa-e52c.dtb diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi index 46f64cd33b9b2..6d457da6fa038 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -1241,6 +1241,18 @@ status = "disabled"; }; + cif: video-capture@ff490000 { + compatible = "rockchip,px30-vip"; + reg = <0x0 0xff490000 0x0 0x200>; + interrupts = ; + clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>; + clock-names = "aclk", "hclk", "pclk"; + power-domains = <&power PX30_PD_VI>; + resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>; + reset-names = "axi", "ahb", "pclkin"; + status = "disabled"; + }; + isp: isp@ff4a0000 { compatible = "rockchip,px30-cif-isp"; /*rk3326-rkisp1*/ reg = <0x0 0xff4a0000 0x0 0x8000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts index 7a32972bc2496..c1e3098b9a7bc 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts +++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts @@ -35,7 +35,6 @@ function = LED_FUNCTION_POWER; gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; label = "rockpis:green:power"; - linux,default-trigger = "default-on"; }; blue-led { diff --git a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts index 96c27fc5005d1..3566c14850c66 100644 --- a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts +++ b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts @@ -184,7 +184,7 @@ &gmac2phy { assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; - assigned-clock-rate = <50000000>; + assigned-clock-rates = <50000000>; assigned-clocks = <&cru SCLK_MAC2PHY>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts index 3707df6acf1fc..76715de886e2d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts @@ -101,7 +101,7 @@ &gmac2phy { phy-supply = <&vcc_phy>; clock_in_out = "output"; - assigned-clock-rate = <50000000>; + assigned-clock-rates = <50000000>; assigned-clocks = <&cru SCLK_MAC2PHY>; assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; status = "okay"; diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index 73618df7a8898..ce4b112b082ba 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -140,6 +140,12 @@ }; }; + display_subsystem: display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <&vop_out>; + status = "disabled"; + }; + arm-pmu { compatible = "arm,cortex-a53-pmu"; interrupts = , @@ -847,6 +853,31 @@ status = "disabled"; }; + vop: vop@ff930000 { + compatible = "rockchip,rk3368-vop"; + reg = <0x0 0xff930000 0x0 0x2fc>, <0x0 0xff931000 0x0 0x400>; + interrupts = ; + assigned-clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>; + assigned-clock-rates = <400000000>, <200000000>; + clocks = <&cru ACLK_VOP>, <&cru DCLK_VOP>, <&cru HCLK_VOP>; + clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; + iommus = <&vop_mmu>; + power-domains = <&power RK3368_PD_VIO>; + resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>; + reset-names = "axi", "ahb", "dclk"; + status = "disabled"; + + vop_out: port { + #address-cells = <1>; + #size-cells = <0>; + + vop_out_dsi: endpoint@0 { + reg = <0>; + remote-endpoint = <&dsi_in_vop>; + }; + }; + }; + vop_mmu: iommu@ff930300 { compatible = "rockchip,iommu"; reg = <0x0 0xff930300 0x0 0x100>; @@ -858,6 +889,50 @@ status = "disabled"; }; + mipi_dsi: dsi@ff960000 { + compatible = "rockchip,rk3368-mipi-dsi", "snps,dw-mipi-dsi"; + reg = <0x0 0xff960000 0x0 0x4000>; + interrupts = ; + clocks = <&cru PCLK_MIPI_DSI0>; + clock-names = "pclk"; + phys = <&dphy>; + phy-names = "dphy"; + power-domains = <&power RK3368_PD_VIO>; + resets = <&cru SRST_MIPIDSI0>; + reset-names = "apb"; + rockchip,grf = <&grf>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + mipi_in: port@0 { + reg = <0>; + + dsi_in_vop: endpoint { + remote-endpoint = <&vop_out_dsi>; + }; + }; + + mipi_out: port@1 { + reg = <1>; + }; + + }; + }; + + dphy: phy@ff968000 { + compatible = "rockchip,rk3368-dsi-dphy"; + reg = <0x0 0xff968000 0x0 0x4000>; + clocks = <&cru SCLK_MIPIDSI_24M>, <&cru PCLK_DPHYTX0>; + clock-names = "ref", "pclk"; + #phy-cells = <0>; + resets = <&cru SRST_MIPIDPHYTX>; + reset-names = "apb"; + status = "disabled"; + }; + hevc_mmu: iommu@ff9a0440 { compatible = "rockchip,iommu"; reg = <0x0 0xff9a0440 0x0 0x40>, diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts index 962b8b231c960..74160cf891885 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts @@ -39,8 +39,8 @@ led-0 { function = LED_FUNCTION_POWER; color = ; + default-state = "on"; gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-on"; }; /* USER_LED2 */ diff --git a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts index 12eec2c1db22a..b324527561558 100644 --- a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts +++ b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts @@ -171,6 +171,10 @@ }; }; +&combphy { + status = "okay"; +}; + &cpu0 { cpu-supply = <&vdd_arm>; }; @@ -229,6 +233,14 @@ }; }; +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pciem1_pins>; + reset-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3>; + status = "okay"; +}; + &pinctrl { ethernet { gmac1_rstn_l: gmac1-rstn-l { diff --git a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts index c03ae1dd34560..0b696d49b71fa 100644 --- a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts +++ b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts @@ -45,7 +45,6 @@ default-state = "on"; function = LED_FUNCTION_STATUS; gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-on"; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3528.dtsi b/arch/arm64/boot/dts/rockchip/rk3528.dtsi index d5f8f7b9bf019..d402f28288142 100644 --- a/arch/arm64/boot/dts/rockchip/rk3528.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3528.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -278,10 +279,63 @@ soc { compatible = "simple-bus"; - ranges = <0x0 0xfe000000 0x0 0xfe000000 0x0 0x2000000>; + ranges = <0x0 0xfc000000 0x0 0xfc000000 0x0 0x44000000>; #address-cells = <2>; #size-cells = <2>; + pcie: pcie@fe000000 { + compatible = "rockchip,rk3528-pcie", + "rockchip,rk3568-pcie"; + reg = <0x0 0xfe000000 0x0 0x400000>, + <0x0 0xfe4f0000 0x0 0x010000>, + <0x0 0xfc000000 0x0 0x100000>; + reg-names = "dbi", "apb", "config"; + bus-range = <0x0 0xff>; + clocks = <&cru ACLK_PCIE>, <&cru HCLK_PCIE_SLV>, + <&cru HCLK_PCIE_DBI>, <&cru PCLK_PCIE>, + <&cru CLK_PCIE_AUX>; + clock-names = "aclk_mst", "aclk_slv", + "aclk_dbi", "pclk", + "aux"; + device_type = "pci"; + interrupts = , + , + , + , + , + ; + interrupt-names = "sys", "pmc", "msg", "legacy", "err", + "msi"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc 0>, + <0 0 0 2 &pcie_intc 1>, + <0 0 0 3 &pcie_intc 2>, + <0 0 0 4 &pcie_intc 3>; + linux,pci-domain = <0>; + max-link-speed = <2>; + num-lanes = <1>; + phys = <&combphy PHY_TYPE_PCIE>; + phy-names = "pcie-phy"; + power-domains = <&power RK3528_PD_VPU>; + ranges = <0x01000000 0x0 0xfc100000 0x0 0xfc100000 0x0 0x00100000>, + <0x02000000 0x0 0xfc200000 0x0 0xfc200000 0x0 0x01e00000>, + <0x03000000 0x1 0x00000000 0x1 0x00000000 0x0 0x40000000>; + resets = <&cru SRST_PCIE_POWER_UP>, <&cru SRST_P_PCIE>; + reset-names = "pwr", "pipe"; + #address-cells = <3>; + #size-cells = <2>; + status = "disabled"; + + pcie_intc: legacy-interrupt-controller { + interrupt-controller; + interrupt-parent = <&gic>; + interrupts = ; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + gic: interrupt-controller@fed01000 { compatible = "arm,gic-400"; reg = <0x0 0xfed01000 0 0x1000>, diff --git a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi index d539570f531e1..e2f0ccc6dbe7a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi @@ -435,6 +435,11 @@ }; }; +&i2c2 { + pinctrl-0 = <&i2c2m1_xfer>; + status = "okay"; +}; + &i2s0_8ch { status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts index 6224d72813e59..80ac40555e023 100644 --- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts +++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts @@ -466,6 +466,7 @@ compatible = "belling,bl24c16a", "atmel,24c16"; reg = <0x50>; pagesize = <16>; + vcc-supply = <&vcca1v8_pmu>; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts new file mode 100644 index 0000000000000..9f3cdaad1c9ac --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 Michael Opdenacker + */ + +/dts-v1/; + +#include "rk3566-tinker-board-3.dtsi" + +/ { + model = "Asus Tinker Board 3"; + compatible = "asus,rk3566-tinker-board-3", "rockchip,rk3566"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi new file mode 100644 index 0000000000000..d9cb73e71d561 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 Michael Opdenacker + */ + +#include +#include +#include +#include +#include "rk3566.dtsi" + +/ { + aliases { + i2c0 = &i2c0; + i2c2 = &i2c2; + mmc1 = &sdmmc0; + serial2 = &uart2; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + gpio_leds: gpio-leds { + compatible = "gpio-leds"; + + act-led { + gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; + linux,default-trigger="mmc1"; + }; + + rsv-led { + gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>; + linux,default-trigger="none"; + }; + }; + + vcc3v3_sys: regulator-3v3-vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_sys: regulator-5v0-vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc5v0_usb_host: regulator-5v0-vcc-usb-host { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&u2_a_vbus_en>; + regulator-name = "vcc5v0_usb_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&i2c0 { + status = "okay"; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + assigned-clocks = <&cru I2S1_MCLKOUT_TX>; + assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; + #clock-cells = <1>; + clocks = <&cru I2S1_MCLKOUT_TX>; + clock-names = "mclk"; + clock-output-names = "rk809-clkout1", "rk809-clkout2"; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>; + #sound-dai-cells = <0>; + system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + + regulators { + vcc_1v8: DCDC_REG5 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + regulator-name = "vcc3v3_sd"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_cpu: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <830000>; + regulator-max-microvolt = <1200000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc3v3_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c2 { + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c08"; + reg = <0x50>; + pinctrl-names = "default"; + pinctrl-0 = <&eeprom_wc_n>; + }; + + rtc_isl1208: rtc@6f { + compatible = "isil,isl1208"; + reg = <0x6f>; + interrupt-names = "irq"; + interrupts-extended = <&gpio0 RK_PD3 IRQ_TYPE_EDGE_FALLING>; + pinctrl-names = "default"; + pinctrl-0 = <&rtcic_int_l>; + }; +}; + +&pinctrl { + eeprom { + eeprom_wc_n: eeprom-wc-n { + rockchip,pins = <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + rtc { + rtcic_int_l: rtcic-int-l { + rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + u2_a_vbus_en: u2-a-vbus-en { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + u3_a_vbus_en: u3-a-vbus-en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&sdmmc0 { + bus-width = <4>; + cap-sd-highspeed; + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy0_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts new file mode 100644 index 0000000000000..3624ebc8a26f9 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 Michael Opdenacker + */ + +/dts-v1/; + +#include "rk3566-tinker-board-3.dtsi" + +/ { + model = "Asus Tinker Board 3S"; + compatible = "asus,rk3566-tinker-board-3s", "rockchip,rk3566"; + + aliases { + mmc0 = &sdhci; + }; +}; + +&sdhci { + bus-width = <8>; + cap-mmc-highspeed; + max-frequency = <200000000>; + mmc-hs200-1_8v; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts new file mode 100644 index 0000000000000..4db00489be40f --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts @@ -0,0 +1,880 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; +#include +#include +#include +#include +#include +#include "rk3568.dtsi" + +/ { + model = "9Tripod X3568 v4"; + compatible = "9tripod,x3568-v4", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc0 = &sdhci; + mmc1 = &sdmmc0; + mmc2 = &sdmmc2; + rtc0 = &rtc0; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-vol-up { + label = "volume up"; + linux,code = ; + press-threshold-microvolt = <50000>; + }; + + button-vol-down { + label = "volume down"; + linux,code = ; + press-threshold-microvolt = <500000>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_work: led-0 { + gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; + function = LED_FUNCTION_HEARTBEAT; + color = ; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&led_work_en>; + }; + }; + + rk809-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "Analog RK809"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,cpu { + sound-dai = <&i2s1_8ch>; + }; + simple-audio-card,codec { + sound-dai = <&rk809>; + }; + }; + + pdm_codec: pdm-codec { + compatible = "dmic-codec"; + num-channels = <2>; + #sound-dai-cells = <0>; + }; + + pdm_sound: pdm-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "microphone"; + + simple-audio-card,cpu { + sound-dai = <&pdm>; + }; + + simple-audio-card,codec { + sound-dai = <&pdm_codec>; + }; + }; + + spdif_dit: spdif-dit { + compatible = "linux,spdif-dit"; + #sound-dai-cells = <0>; + }; + + spdif_sound: spdif-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "SPDIF"; + + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; + simple-audio-card,codec { + sound-dai = <&spdif_dit>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk809 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable>; + post-power-on-delay-ms = <100>; + power-off-delay-us = <300>; + reset-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; + }; + + dc_12v: regulator-dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + pcie30_avdd0v9: regulator-pcie30-avdd0v9 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc3v3_sys>; + }; + + pcie30_avdd1v8: regulator-pcie30-avdd1v8 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_sys: regulator-vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + + vcc3v3_pcie: regulator-vcc3v3-pcie { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc3v3_pcie_en_pin>; + regulator-name = "vcc3v3_pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <5000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_usb: regulator-vcc5v0-usb { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_usb_host: regulator-vcc5v0-usb-host { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_host_en>; + regulator-name = "vcc5v0_usb_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_usb_otg: regulator-vcc5v0-usb-otg { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_otg_en>; + regulator-name = "vcc5v0_usb_otg"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; +}; + +&can1 { + assigned-clocks = <&cru CLK_CAN1>; + assigned-clock-rates = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&can1m1_pins>; + status = "okay"; +}; + +/* used for usb_host0_xhci */ +&combphy0 { + status = "okay"; +}; + +/* used for usb_host1_xhci */ +&combphy1 { + status = "okay"; +}; + +/* connected to sata2 */ +&combphy2 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gmac0 { + assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; + assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_miim + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; + phy-handle = <&rgmii_phy0>; + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&gmac1 { + assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; + assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1m1_miim + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&hdmi { + avdd-0v9-supply = <&vdda0v9_image>; + avdd-1v8-supply = <&vcca1v8_image>; + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + vdd_cpu: regulator@1c { + compatible = "tcs,tcs4525"; + reg = <0x1c>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + assigned-clocks = <&cru I2S1_MCLKOUT_TX>; + assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; + #clock-cells = <1>; + clock-names = "mclk"; + clocks = <&cru I2S1_MCLKOUT_TX>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>; + system-power-controller; + #sound-dai-cells = <0>; + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + wakeup-source; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_npu: DCDC_REG4 { + regulator-name = "vdd_npu"; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG5 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_image: LDO_REG1 { + regulator-name = "vdda0v9_image"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v9: LDO_REG2 { + regulator-name = "vdda_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + regulator-name = "vdda0v9_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + regulator-name = "vccio_acodec"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + regulator-name = "vcc3v3_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca_1v8: LDO_REG7 { + regulator-name = "vcca_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pmu: LDO_REG8 { + regulator-name = "vcca1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_image: LDO_REG9 { + regulator-name = "vcca1v8_image"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + regulator-name = "vcc3v3_sd"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + + codec { + rockchip,mic-in-differential; + }; + }; +}; + +&i2c5 { + status = "okay"; + + rtc0: rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + #clock-cells = <0>; + }; +}; + +&i2s0_8ch { + status = "okay"; +}; + +&i2s1_8ch { + pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>; + rockchip,trcm-sync-tx-only; + status = "okay"; +}; + +/* used for AP6275S Bluetooth Sound */ +&i2s3_2ch { + status = "okay"; +}; + +&mdio0 { + rgmii_phy0: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + + /* Note: The LED polarity is inverted */ + led@2 { + reg = <2>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + + /* Note: The LED polarity is inverted */ + led@2 { + reg = <2>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; +}; + +&pcie30phy { + status = "okay"; +}; + +&pcie3x2 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_reset_pin>; + reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; +}; + +&pdm { + status = "okay"; +}; + +&pinctrl { + leds { + led_work_en: led_work_en { + rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdio-pwrseq { + wifi_enable: wifi-enable { + rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + vcc5v0_usb_host_en: vcc5v0_usb_host_en { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + vcc5v0_usb_otg_en: vcc5v0_usb_otg_en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie_reset_pin: pcie-reset-pin { + rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + vcc3v3_pcie_en_pin: vcc3v3-pcie-en-pin { + rockchip,pins = <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio2-supply = <&vcc_1v8>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +/* Required remotectl for IR receiver */ +&pwm7 { + status = "disabled"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sata2 { + status = "okay"; +}; + +/* used for eMMC */ +&sdhci { + bus-width = <8>; + max-frequency = <200000000>; + mmc-hs200-1_8v; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; + status = "okay"; +}; + +/* used for microSD (TF) Slot */ +&sdmmc0 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +/* used for AP6275S WiFi */ +&sdmmc2 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sys>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; + +&spdif { + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +/* used for Debug */ +&uart2 { + status = "okay"; +}; + +&uart3 { + pinctrl-0 = <&uart3m1_xfer>; + status = "okay"; +}; + +&uart4 { + pinctrl-0 = <&uart4m1_xfer>; + status = "okay"; +}; + +/* used for WiFi/BT AP6275S */ +&uart8 { + pinctrl-0 = <&uart8m0_xfer &uart8m0_ctsn>; + status = "okay"; +}; + +&uart9 { + pinctrl-0 = <&uart9m1_xfer>; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + extcon = <&usb2phy0>; + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host1_xhci { + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy0_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&usb2phy0_otg { + phy-supply = <&vcc5v0_usb_otg>; + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&usb2phy1_otg { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&vop { + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-easepi-r1.dts b/arch/arm64/boot/dts/rockchip/rk3568-easepi-r1.dts new file mode 100644 index 0000000000000..12225b631eb6e --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3568-easepi-r1.dts @@ -0,0 +1,623 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +/dts-v1/; + +#include +#include +#include +#include +#include +#include "rk3568.dtsi" + +/ { + model = "LinkEase EasePi R1"; + compatible = "linkease,easepi-r1", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc0 = &sdhci; + }; + + chosen: chosen { + stdout-path = "serial2:1500000n8"; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + + button-recovery { + label = "Recovery"; + linux,code = ; + press-threshold-microvolt = <1750>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&status_led_pin>; + + status_led: led-status { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio2 RK_PD7 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + dc_12v: regulator-dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc3v3_sys: regulator-vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + + pcie30_avdd0v9: regulator-pcie30-avdd0v9 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc3v3_sys>; + }; + + pcie30_avdd1v8: regulator-pcie30-avdd1v8 { + compatible = "regulator-fixed"; + regulator-name = "pcie30_avdd1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + regulator-vdd0v95-25glan { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vdd0v95_25glan_en>; + regulator-name = "vdd0v95_25glan"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_nvme: regulator-vcc3v3-nvme { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc3v3_nvme_en>; + regulator-name = "vcc3v3_nvme"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + +}; + +&combphy1 { + status = "okay"; +}; + +&combphy2 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gmac0 { + assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; + assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + phy-handle = <&rgmii_phy0>; + phy-mode = "rgmii-id"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_miim + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; + status = "okay"; +}; + +&gmac1 { + assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; + assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii-id"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1m1_miim + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&hdmi { + avdd-0v9-supply = <&vdda0v9_image>; + avdd-1v8-supply = <&vcca1v8_image>; + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + vdd_cpu: regulator@1c { + compatible = "tcs,tcs4525"; + reg = <0x1c>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + #clock-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>; + system-power-controller; + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + wakeup-source; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_npu: DCDC_REG4 { + regulator-name = "vdd_npu"; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG5 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_image: LDO_REG1 { + regulator-name = "vdda0v9_image"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v9: LDO_REG2 { + regulator-name = "vdda_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + regulator-name = "vdda0v9_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + regulator-name = "vccio_acodec"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + regulator-name = "vcc3v3_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca_1v8: LDO_REG7 { + regulator-name = "vcca_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pmu: LDO_REG8 { + regulator-name = "vcca1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_image: LDO_REG9 { + regulator-name = "vcca1v8_image"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + regulator-name = "vcc3v3_sd"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&i2s0_8ch { + status = "okay"; +}; + +&mdio0 { + rgmii_phy0: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1>; + pinctrl-0 = <ð_phy0_reset_pin>; + pinctrl-names = "default"; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; + }; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1>; + pinctrl-0 = <ð_phy1_reset_pin>; + pinctrl-names = "default"; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>; + }; +}; + +/* ETH3 */ +&pcie2x1 { + reset-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_sys>; + status = "okay"; +}; + +&pcie30phy { + data-lanes = <1 2>; + status = "okay"; +}; + +/* ETH2 */ +&pcie3x1 { + num-lanes = <1>; + reset-gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_sys>; + status = "okay"; +}; + +/* M.2 Key for 2280 NVMe */ +&pcie3x2 { + num-lanes = <1>; + reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_nvme>; + status = "okay"; +}; + +&pinctrl { + gmac0 { + eth_phy0_reset_pin: eth-phy0-reset-pin { + rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gmac1 { + eth_phy1_reset_pin: eth-phy1-reset-pin { + rockchip,pins = <2 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-leds { + status_led_pin: status-led-pin { + rockchip,pins = <2 RK_PD7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + nvme { + vcc3v3_nvme_en: vcc3v3-nvme-en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie-nic { + vdd0v95_25glan_en: vdd0v95-25glan-en { + rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic-int { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc3v3_pmu>; + pmuio2-supply = <&vcc3v3_pmu>; + vccio1-supply = <&vccio_acodec>; + vccio3-supply = <&vccio_sd>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + max-frequency = <200000000>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +/* OTG Only USB2.0, Only device mode */ +&usb_host0_xhci { + dr_mode = "peripheral"; + extcon = <&usb2phy0>; + maximum-speed = "high-speed"; + phys = <&usb2phy0_otg>; + phy-names = "usb2-phy"; + status = "okay"; +}; + +&usb_host1_xhci { + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy0_host { + phy-supply = <&vcc5v0_sys>; + status = "okay"; +}; + +&usb2phy0_otg { + status = "okay"; +}; + +&vop { + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts233.dts b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts233.dts new file mode 100644 index 0000000000000..f16d1c6287939 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts233.dts @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2021 Rockchip Electronics Co., Ltd. + * Copyright (c) 2024 Heiko Stuebner + */ + +/dts-v1/; + +#include "rk3568-qnap-tsx33.dtsi" + +/ { + model = "Qnap TS-233-2G NAS System 2-Bay"; + compatible = "qnap,ts233", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac0; + }; +}; + +/* connected to sata2 */ +&combphy2 { + status = "okay"; +}; + +&gmac0 { + assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; + assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + phy-handle = <&rgmii_phy0>; + phy-mode = "rgmii-id"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_miim + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; + status = "okay"; +}; + +&i2c1 { + /* eeprom for vital-product-data on the backplane */ + eeprom@56 { + compatible = "giantec,gt24c04a", "atmel,24c04"; + reg = <0x56>; + label = "VPD_BP"; + num-addresses = <2>; + pagesize = <16>; + read-only; + }; +}; + +&leds { + led-1 { + color = ; + function = LED_FUNCTION_DISK; + gpios = <&gpio1 RK_PD6 GPIO_ACTIVE_LOW>; + label = "hdd2:green:disk"; + linux,default-trigger = "disk-activity"; + pinctrl-names = "default"; + pinctrl-0 = <&hdd2_led_pin>; + }; +}; + +&mcu { + compatible = "qnap,ts233-mcu"; +}; + +&mdio0 { + rgmii_phy0: ethernet-phy@3 { + /* Motorcomm YT8521 phy */ + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x3>; + pinctrl-0 = <ð_phy0_reset_pin>; + pinctrl-names = "default"; + reset-assert-us = <10000>; + reset-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_LOW>; + }; +}; + +&pinctrl { + gmac0 { + eth_phy0_reset_pin: eth-phy0-reset-pin { + rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + leds { + hdd2_led_pin: hdd2-led-pin { + rockchip,pins = <1 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&sata2 { + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +/* connected to usb_host1_ehci/ohci */ +&usb2phy1_host { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + +/* connected to usb_host0_ehci/ohci */ +&usb2phy1_otg { + phy-supply = <&vcc5v0_host>; + status = "okay"; +}; + +/* right port backside */ +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +/* left port backside */ +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts index 6ae4316761c43..d1e3b7e7a280a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts @@ -6,10 +6,7 @@ /dts-v1/; -#include -#include -#include -#include "rk3568.dtsi" +#include "rk3568-qnap-tsx33.dtsi" / { model = "Qnap TS-433-4G NAS System 4-Bay"; @@ -17,83 +14,6 @@ aliases { ethernet0 = &gmac0; - mmc0 = &sdhci; - rtc0 = &rtc_rv8263; - }; - - chosen { - stdout-path = "serial2:115200n8"; - }; - - keys { - compatible = "gpio-keys"; - pinctrl-0 = <©_button_pin>, <&reset_button_pin>; - pinctrl-names = "default"; - - key-copy { - label = "copy"; - gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>; - linux,code = ; - }; - - key-reset { - label = "reset"; - gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_LOW>; - linux,code = ; - }; - }; - - leds { - compatible = "gpio-leds"; - - led-0 { - color = ; - function = LED_FUNCTION_DISK; - gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>; - label = "hdd1:green:disk"; - linux,default-trigger = "disk-activity"; - pinctrl-names = "default"; - pinctrl-0 = <&hdd1_led_pin>; - }; - - led-1 { - color = ; - function = LED_FUNCTION_DISK; - gpios = <&gpio1 RK_PD6 GPIO_ACTIVE_LOW>; - label = "hdd2:green:disk"; - linux,default-trigger = "disk-activity"; - pinctrl-names = "default"; - pinctrl-0 = <&hdd2_led_pin>; - }; - - led-2 { - color = ; - function = LED_FUNCTION_DISK; - gpios = <&gpio1 RK_PD7 GPIO_ACTIVE_LOW>; - label = "hdd3:green:disk"; - linux,default-trigger = "disk-activity"; - pinctrl-names = "default"; - pinctrl-0 = <&hdd3_led_pin>; - }; - - led-3 { - color = ; - function = LED_FUNCTION_DISK; - gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; - label = "hdd4:green:disk"; - linux,default-trigger = "disk-activity"; - pinctrl-names = "default"; - pinctrl-0 = <&hdd4_led_pin>; - }; - }; - - dc_12v: regulator-dc-12v { - compatible = "regulator-fixed"; - regulator-name = "dc_12v"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <12000000>; - regulator-max-microvolt = <12000000>; }; vcc3v3_pcie: regulator-vcc3v3-pcie { @@ -105,74 +25,6 @@ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; vin-supply = <&dc_12v>; }; - - vcc3v3_sys: regulator-vcc3v3-sys { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3_sys"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&dc_12v>; - }; - - vcc5v0_host: regulator-vcc5v0-host { - compatible = "regulator-fixed"; - enable-active-high; - pinctrl-names = "default"; - pinctrl-0 = <&vcc5v0_host_en>; - gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; - regulator-name = "vcc5v0_host"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc5v0_usb>; - }; - - vcc5v0_otg: regulator-vcc5v0-otg { - compatible = "regulator-fixed"; - enable-active-high; - gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&vcc5v0_otg_en>; - regulator-name = "vcc5v0_otg"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc5v0_usb>; - }; - - vcc5v0_sys: regulator-vcc5v0-sys { - compatible = "regulator-fixed"; - regulator-name = "vcc5v0_sys"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&dc_12v>; - }; - - vcc5v0_usb: regulator-vcc5v0-usb { - compatible = "regulator-fixed"; - regulator-name = "vcc5v0_usb"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&dc_12v>; - }; -}; - -/* connected to usb_host0_xhci */ -&combphy0 { - status = "okay"; -}; - -/* connected to sata1 */ -&combphy1 { - status = "okay"; }; /* connected to sata2 */ @@ -180,22 +32,6 @@ status = "okay"; }; -&cpu0 { - cpu-supply = <&vdd_cpu>; -}; - -&cpu1 { - cpu-supply = <&vdd_cpu>; -}; - -&cpu2 { - cpu-supply = <&vdd_cpu>; -}; - -&cpu3 { - cpu-supply = <&vdd_cpu>; -}; - &gmac0 { assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>; @@ -212,263 +48,7 @@ status = "okay"; }; -&gpu { - mali-supply = <&vdd_gpu>; - status = "okay"; -}; - -&i2c0 { - status = "okay"; - - pmic@20 { - compatible = "rockchip,rk809"; - reg = <0x20>; - interrupt-parent = <&gpio0>; - interrupts = ; - #clock-cells = <1>; - pinctrl-names = "default"; - pinctrl-0 = <&pmic_int_l>; - system-power-controller; - vcc1-supply = <&vcc3v3_sys>; - vcc2-supply = <&vcc3v3_sys>; - vcc3-supply = <&vcc3v3_sys>; - vcc4-supply = <&vcc3v3_sys>; - vcc5-supply = <&vcc3v3_sys>; - vcc6-supply = <&vcc3v3_sys>; - vcc7-supply = <&vcc3v3_sys>; - vcc8-supply = <&vcc3v3_sys>; - vcc9-supply = <&vcc3v3_sys>; - wakeup-source; - - regulators { - vdd_logic: DCDC_REG1 { - regulator-name = "vdd_logic"; - regulator-always-on; - regulator-boot-on; - regulator-initial-mode = <0x2>; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1350000>; - regulator-ramp-delay = <6001>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdd_gpu: DCDC_REG2 { - regulator-name = "vdd_gpu"; - regulator-always-on; - regulator-initial-mode = <0x2>; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1350000>; - regulator-ramp-delay = <6001>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc_ddr: DCDC_REG3 { - regulator-name = "vcc_ddr"; - regulator-always-on; - regulator-boot-on; - regulator-initial-mode = <0x2>; - - regulator-state-mem { - regulator-on-in-suspend; - }; - }; - - vdd_npu: DCDC_REG4 { - regulator-name = "vdd_npu"; - regulator-initial-mode = <0x2>; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1350000>; - regulator-ramp-delay = <6001>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc_1v8: DCDC_REG5 { - regulator-name = "vcc_1v8"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdda0v9_image: LDO_REG1 { - regulator-name = "vdda0v9_image"; - regulator-always-on; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <900000>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdda_0v9: LDO_REG2 { - regulator-name = "vdda_0v9"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <900000>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdda0v9_pmu: LDO_REG3 { - regulator-name = "vdda0v9_pmu"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <900000>; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <900000>; - }; - }; - - vccio_acodec: LDO_REG4 { - regulator-name = "vccio_acodec"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vccio_sd: LDO_REG5 { - regulator-name = "vccio_sd"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc3v3_pmu: LDO_REG6 { - regulator-name = "vcc3v3_pmu"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3300000>; - }; - }; - - vcca_1v8: LDO_REG7 { - regulator-name = "vcca_1v8"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcca1v8_pmu: LDO_REG8 { - regulator-name = "vcca1v8_pmu"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1800000>; - }; - }; - - vcca1v8_image: LDO_REG9 { - regulator-name = "vcca1v8_image"; - regulator-always-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc_3v3: SWITCH_REG1 { - regulator-name = "vcc_3v3"; - regulator-always-on; - regulator-boot-on; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc3v3_sd: SWITCH_REG2 { - regulator-name = "vcc3v3_sd"; - /* - * turning this off, breaks access to both - * PCIe controllers, refclk generator perhaps - */ - regulator-always-on; - regulator-boot-on; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - }; - }; - - vdd_cpu: regulator@40 { - compatible = "silergy,syr827"; - reg = <0x40>; - fcs,suspend-voltage-selector = <1>; - regulator-name = "vdd_cpu"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <712500>; - regulator-max-microvolt = <1390000>; - regulator-ramp-delay = <2300>; - vin-supply = <&vcc5v0_sys>; - }; -}; - &i2c1 { - status = "okay"; - - rtc_rv8263: rtc@51 { - compatible = "microcrystal,rv8263"; - reg = <0x51>; - wakeup-source; - }; - - /* eeprom for vital-product-data on the mainboard */ - eeprom@54 { - compatible = "giantec,gt24c04a", "atmel,24c04"; - reg = <0x54>; - label = "VPD_MB"; - num-addresses = <2>; - pagesize = <16>; - read-only; - }; - /* eeprom for vital-product-data on the backplane */ eeprom@56 { compatible = "giantec,gt24c04a", "atmel,24c04"; @@ -480,6 +60,42 @@ }; }; +&leds { + led-1 { + color = ; + function = LED_FUNCTION_DISK; + gpios = <&gpio1 RK_PD6 GPIO_ACTIVE_LOW>; + label = "hdd2:green:disk"; + linux,default-trigger = "disk-activity"; + pinctrl-names = "default"; + pinctrl-0 = <&hdd2_led_pin>; + }; + + led-2 { + color = ; + function = LED_FUNCTION_DISK; + gpios = <&gpio1 RK_PD7 GPIO_ACTIVE_LOW>; + label = "hdd3:green:disk"; + linux,default-trigger = "disk-activity"; + pinctrl-names = "default"; + pinctrl-0 = <&hdd3_led_pin>; + }; + + led-3 { + color = ; + function = LED_FUNCTION_DISK; + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "hdd4:green:disk"; + linux,default-trigger = "disk-activity"; + pinctrl-names = "default"; + pinctrl-0 = <&hdd4_led_pin>; + }; +}; + +&mcu { + compatible = "qnap,ts433-mcu"; +}; + &mdio0 { rgmii_phy0: ethernet-phy@3 { /* Motorcomm YT8521 phy */ @@ -492,54 +108,6 @@ }; }; -/* - * The MCU can provide system temperature too, but only by polling and of - * course also cannot set trip points. So attach to the cpu thermal-zone - * instead to control the fan. - */ -&cpu_thermal { - trips { - case_fan0: case-fan0 { - hysteresis = <2000>; - temperature = <35000>; - type = "active"; - }; - - case_fan1: case-fan1 { - hysteresis = <2000>; - temperature = <45000>; - type = "active"; - }; - - case_fan2: case-fan2 { - hysteresis = <2000>; - temperature = <65000>; - type = "active"; - }; - }; - - cooling-maps { - /* - * Always provide some air movement, due to small case - * full of harddrives. - */ - map1 { - cooling-device = <&fan THERMAL_NO_LIMIT 1>; - trip = <&case_fan0>; - }; - - map2 { - cooling-device = <&fan 2 3>; - trip = <&case_fan1>; - }; - - map3 { - cooling-device = <&fan 4 THERMAL_NO_LIMIT>; - trip = <&case_fan2>; - }; - }; -}; - &pcie30phy { data-lanes = <1 2>; status = "okay"; @@ -567,21 +135,7 @@ }; }; - keys { - copy_button_pin: copy-button-pin { - rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>; - }; - - reset_button_pin: reset-button-pin { - rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - leds { - hdd1_led_pin: hdd1-led-pin { - rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>; - }; - hdd2_led_pin: hdd2-led-pin { rockchip,pins = <1 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; }; @@ -594,90 +148,12 @@ rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>; }; }; - - pmic { - pmic_int_l: pmic-int-l { - rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - - usb { - vcc5v0_host_en: vcc5v0-host-en { - rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - vcc5v0_otg_en: vcc5v0-otg-en { - rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; -}; - -&pmu_io_domains { - vccio4-supply = <&vcc_1v8>; - vccio6-supply = <&vcc_1v8>; - status = "okay"; -}; - -&sata1 { - status = "okay"; }; &sata2 { status = "okay"; }; -&sdhci { - bus-width = <8>; - max-frequency = <200000000>; - non-removable; - pinctrl-names = "default"; - pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; - status = "okay"; -}; - -&tsadc { - rockchip,hw-tshut-mode = <1>; - rockchip,hw-tshut-polarity = <0>; - status = "okay"; -}; - -/* - * Connected to an MCU, that provides access to more LEDs, - * buzzer, fan control and more. - */ -&uart0 { - status = "okay"; - - mcu { - compatible = "qnap,ts433-mcu"; - - fan: fan-0 { - #cooling-cells = <2>; - cooling-levels = <0 64 89 128 166 204 221 238>; - }; - }; -}; - -/* - * Pins available on CN3 connector at TTL voltage level (3V3). - * ,_ _. - * |1234| 1=TX 2=VCC - * `----' 3=RX 4=GND - */ -&uart2 { - status = "okay"; -}; - -&usb2phy0 { - status = "okay"; -}; - -/* connected to usb_host0_xhci */ -&usb2phy0_otg { - phy-supply = <&vcc5v0_otg>; - status = "okay"; -}; - &usb2phy1 { status = "okay"; }; @@ -703,12 +179,6 @@ status = "okay"; }; -/* front port */ -&usb_host0_xhci { - dr_mode = "host"; - status = "okay"; -}; - /* left port backside */ &usb_host1_ehci { status = "okay"; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-qnap-tsx33.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-qnap-tsx33.dtsi new file mode 100644 index 0000000000000..f009275c72c8b --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3568-qnap-tsx33.dtsi @@ -0,0 +1,608 @@ +#include +#include +#include +#include "rk3568.dtsi" + +/ { + aliases { + mmc0 = &sdhci; + rtc0 = &rtc_rv8263; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <©_button_pin>, <&reset_button_pin>; + pinctrl-names = "default"; + + key-copy { + label = "copy"; + gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + key-reset { + label = "reset"; + gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds: leds { + compatible = "gpio-leds"; + + led-0 { + color = ; + function = LED_FUNCTION_DISK; + gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>; + label = "hdd1:green:disk"; + linux,default-trigger = "disk-activity"; + pinctrl-names = "default"; + pinctrl-0 = <&hdd1_led_pin>; + }; + }; + + dc_12v: regulator-dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc3v3_sys: regulator-vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_host: regulator-vcc5v0-host { + compatible = "regulator-fixed"; + enable-active-high; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + regulator-name = "vcc5v0_host"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_otg: regulator-vcc5v0-otg { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_otg_en>; + regulator-name = "vcc5v0_otg"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_usb: regulator-vcc5v0-usb { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_usb"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; +}; + +/* connected to usb_host0_xhci */ +&combphy0 { + status = "okay"; +}; + +/* connected to sata1 */ +&combphy1 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +/* + * The MCU can provide system temperature too, but only by polling and of + * course also cannot set trip points. So attach to the cpu thermal-zone + * instead to control the fan. + */ +&cpu_thermal { + trips { + case_fan0: case-fan0 { + hysteresis = <2000>; + temperature = <35000>; + type = "active"; + }; + + case_fan1: case-fan1 { + hysteresis = <2000>; + temperature = <45000>; + type = "active"; + }; + + case_fan2: case-fan2 { + hysteresis = <2000>; + temperature = <65000>; + type = "active"; + }; + }; + + cooling-maps { + /* + * Always provide some air movement, due to small case + * full of harddrives. + */ + map1 { + cooling-device = <&fan THERMAL_NO_LIMIT 1>; + trip = <&case_fan0>; + }; + + map2 { + cooling-device = <&fan 2 3>; + trip = <&case_fan1>; + }; + + map3 { + cooling-device = <&fan 4 THERMAL_NO_LIMIT>; + trip = <&case_fan2>; + }; + }; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = ; + #clock-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + system-power-controller; + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; + vcc4-supply = <&vcc3v3_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc3v3_sys>; + wakeup-source; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_npu: DCDC_REG4 { + regulator-name = "vdd_npu"; + regulator-initial-mode = <0x2>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG5 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_image: LDO_REG1 { + regulator-name = "vdda0v9_image"; + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v9: LDO_REG2 { + regulator-name = "vdda_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + regulator-name = "vdda0v9_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + regulator-name = "vccio_acodec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + regulator-name = "vcc3v3_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca_1v8: LDO_REG7 { + regulator-name = "vcca_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pmu: LDO_REG8 { + regulator-name = "vcca1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_image: LDO_REG9 { + regulator-name = "vcca1v8_image"; + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_sd: SWITCH_REG2 { + regulator-name = "vcc3v3_sd"; + /* + * turning this off, breaks access to both + * PCIe controllers, refclk generator perhaps + */ + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_cpu: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1390000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + }; +}; + +&i2c1 { + status = "okay"; + + rtc_rv8263: rtc@51 { + compatible = "microcrystal,rv8263"; + reg = <0x51>; + wakeup-source; + }; + + /* eeprom for vital-product-data on the mainboard */ + eeprom@54 { + compatible = "giantec,gt24c04a", "atmel,24c04"; + reg = <0x54>; + label = "VPD_MB"; + num-addresses = <2>; + pagesize = <16>; + read-only; + }; +}; + +&pinctrl { + keys { + copy_button_pin: copy-button-pin { + rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + reset_button_pin: reset-button-pin { + rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + leds { + hdd1_led_pin: hdd1-led-pin { + rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc5v0_otg_en: vcc5v0-otg-en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + vccio4-supply = <&vcc_1v8>; + vccio6-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sata1 { + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + max-frequency = <200000000>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +/* + * Connected to an MCU, that provides access to more LEDs, + * buzzer, fan control and more. + */ +&uart0 { + status = "okay"; + + mcu: mcu { + fan: fan-0 { + #cooling-cells = <2>; + cooling-levels = <0 64 89 128 166 204 221 238>; + }; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + serial-number@0 { + reg = <0x0 0x13>; + }; + + ext-port@22 { + reg = <0x22 0x2>; + }; + + mac0: mac@24 { + compatible = "mac-base"; + reg = <0x24 0x11>; + #nvmem-cell-cells = <1>; + }; + + mac1: mac@35 { + compatible = "mac-base"; + reg = <0x35 0x11>; + #nvmem-cell-cells = <1>; + }; + + mac2: mac@46 { + compatible = "mac-base"; + reg = <0x46 0x11>; + #nvmem-cell-cells = <1>; + }; + + mac3: mac@57 { + compatible = "mac-base"; + reg = <0x57 0x11>; + #nvmem-cell-cells = <1>; + }; + + mac4: mac@68 { + compatible = "mac-base"; + reg = <0x68 0x11>; + #nvmem-cell-cells = <1>; + }; + + mac5: mac@79 { + compatible = "mac-base"; + reg = <0x79 0x11>; + #nvmem-cell-cells = <1>; + }; + + mac6: mac@8a { + compatible = "mac-base"; + reg = <0x8a 0x11>; + #nvmem-cell-cells = <1>; + }; + + mac7: mac@9b { + compatible = "mac-base"; + reg = <0x9b 0x11>; + #nvmem-cell-cells = <1>; + }; + }; + }; +}; + +/* + * Pins available on CN3 connector at TTL voltage level (3V3). + * ,_ _. + * |1234| 1=TX 2=VCC + * `----' 3=RX 4=GND + */ +&uart2 { + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +/* connected to usb_host0_xhci */ +&usb2phy0_otg { + phy-supply = <&vcc5v0_otg>; + status = "okay"; +}; + +/* front port */ +&usb_host0_xhci { + dr_mode = "host"; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi index fd2214b6fad40..8893b7b6cc9ff 100644 --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi @@ -53,7 +53,7 @@ device_type = "cpu"; compatible = "arm,cortex-a55"; reg = <0x0 0x0>; - clocks = <&scmi_clk 0>; + clocks = <&scmi_clk SCMI_CLK_CPU>; #cooling-cells = <2>; enable-method = "psci"; i-cache-size = <0x8000>; @@ -69,6 +69,7 @@ device_type = "cpu"; compatible = "arm,cortex-a55"; reg = <0x0 0x100>; + clocks = <&scmi_clk SCMI_CLK_CPU>; #cooling-cells = <2>; enable-method = "psci"; i-cache-size = <0x8000>; @@ -84,6 +85,7 @@ device_type = "cpu"; compatible = "arm,cortex-a55"; reg = <0x0 0x200>; + clocks = <&scmi_clk SCMI_CLK_CPU>; #cooling-cells = <2>; enable-method = "psci"; i-cache-size = <0x8000>; @@ -99,6 +101,7 @@ device_type = "cpu"; compatible = "arm,cortex-a55"; reg = <0x0 0x300>; + clocks = <&scmi_clk SCMI_CLK_CPU>; #cooling-cells = <2>; enable-method = "psci"; i-cache-size = <0x8000>; @@ -557,7 +560,7 @@ , ; interrupt-names = "job", "mmu", "gpu"; - clocks = <&scmi_clk 1>, <&cru CLK_GPU>; + clocks = <&scmi_clk SCMI_CLK_GPU>, <&cru CLK_GPU>; clock-names = "gpu", "bus"; #cooling-cells = <2>; power-domains = <&power RK3568_PD_GPU>; @@ -616,6 +619,50 @@ #iommu-cells = <0>; }; + vicap: video-capture@fdfe0000 { + compatible = "rockchip,rk3568-vicap"; + reg = <0x0 0xfdfe0000 0x0 0x200>; + interrupts = ; + assigned-clocks = <&cru DCLK_VICAP>; + assigned-clock-rates = <300000000>; + clocks = <&cru ACLK_VICAP>, <&cru HCLK_VICAP>, + <&cru DCLK_VICAP>, <&cru ICLK_VICAP_G>; + clock-names = "aclk", "hclk", "dclk", "iclk"; + iommus = <&vicap_mmu>; + power-domains = <&power RK3568_PD_VI>; + resets = <&cru SRST_A_VICAP>, <&cru SRST_H_VICAP>, + <&cru SRST_D_VICAP>, <&cru SRST_P_VICAP>, + <&cru SRST_I_VICAP>; + reset-names = "arst", "hrst", "drst", "prst", "irst"; + rockchip,grf = <&grf>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + vicap_dvp: port@0 { + reg = <0>; + }; + + vicap_mipi: port@1 { + reg = <1>; + }; + }; + }; + + vicap_mmu: iommu@fdfe0800 { + compatible = "rockchip,rk3568-iommu"; + reg = <0x0 0xfdfe0800 0x0 0x100>; + interrupts = ; + clocks = <&cru ACLK_VICAP>, <&cru HCLK_VICAP>; + clock-names = "aclk", "iface"; + #iommu-cells = <0>; + power-domains = <&power RK3568_PD_VI>; + rockchip,disable-mmu-reset; + status = "disabled"; + }; + sdmmc2: mmc@fe000000 { compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xfe000000 0x0 0x4000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts new file mode 100644 index 0000000000000..b19f9b6be6bf8 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts @@ -0,0 +1,838 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + * + */ + +/dts-v1/; + +#include +#include +#include +#include +#include +#include "rk3576.dtsi" + +/ { + model = "100ASK DshanPi A1 board"; + compatible = "100ask,dshanpi-a1", "rockchip,rk3576"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc0 = &sdhci; + mmc1 = &sdmmc; + }; + + chosen { + stdout-path = "serial0:1500000n8"; + }; + + es8388_sound: es8388-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "On-board Analog ES8388"; + simple-audio-card,widgets = "Microphone", "Headphone Mic", + "Microphone", "Mic Pads", + "Headphone", "Headphone", + "Line Out", "Line Out"; + simple-audio-card,routing = "Headphone", "LOUT1", + "Headphone", "ROUT1", + "Line Out", "LOUT2", + "Line Out", "ROUT2", + "RINPUT1", "Headphone Mic", + "LINPUT2", "Mic Pads", + "RINPUT2", "Mic Pads"; + simple-audio-card,pin-switches = "Headphone", "Line Out"; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + + simple-audio-card,codec { + sound-dai = <&es8388>; + system-clock-frequency = <12288000>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + keys-0 { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-maskrom { + label = "MASKROM"; + linux,code = ; + press-threshold-microvolt = <0>; + }; + }; + + keys-1 { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-recovery { + label = "RECOVERY"; + linux,code = ; + press-threshold-microvolt = <0>; + }; + }; + + keys-2 { + compatible = "adc-keys"; + io-channels = <&saradc 4>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-user2 { + label = "USER2"; + linux,code = ; + press-threshold-microvolt = <0>; + }; + }; + + keys-3 { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_a0_d>; + + button-user1 { + gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; + label = "USER1"; + linux,code = ; + wakeup-source; + }; + }; + + vcc_in: regulator-vcc-12v0-dcin { + compatible = "regulator-fixed"; + regulator-name = "vcc_in"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v1_nldo_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + vin-supply = <&vcc_5v0_sys>; + }; + + vcc_1v8_s0: regulator-vcc-1v8-s0 { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_1v8_s3>; + }; + + vcc_2v0_pldo_s3: regulator-vcc-2v0-pldo-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc_2v0_pldo_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + vin-supply = <&vcc_5v0_sys>; + }; + + vcc_3v3_m2: regulator-vcc-3v3-m2 { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3_m2"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_5v0_sys>; + }; + + vcc_3v3_s0: regulator-vcc-3v3-s0 { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3v3_s3>; + }; + + vcc_5v0_sys: regulator-vcc-5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_in>; + }; + + vbus5v0_typec: regulator-vbus5v0-typec { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&typec5v_pwren_h>; + regulator-name = "vbus5v0_typec"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_5v0_sys>; + }; +}; + +&combphy0_ps { + status = "okay"; +}; + +&combphy1_psu { + status = "okay"; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_b2 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_b3 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&gmac0 { + clock_in_out = "output"; + phy-mode = "rgmii-id"; + phy-handle = <&rgmii_phy0>; + phy-supply = <&vcc_3v3_s0>; + pinctrl-names = "default"; + pinctrl-0 = <ð0m0_miim + ð0m0_tx_bus2 + ð0m0_rx_bus2 + ð0m0_rgmii_clk + ð0m0_rgmii_bus>; + status = "okay"; +}; + +&gmac1 { + clock_in_out = "output"; + phy-mode = "rgmii-id"; + phy-handle = <&rgmii_phy1>; + phy-supply = <&vcc_3v3_s0>; + pinctrl-names = "default"; + pinctrl-0 = <ð1m0_miim + ð1m0_tx_bus2 + ð1m0_rx_bus2 + ð1m0_rgmii_clk + ð1m0_rgmii_bus>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_gpu_s0>; + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; + +&hdptxphy { + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + pmic@23 { + compatible = "rockchip,rk806"; + reg = <0x23>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio0>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_pins + &rk806_dvs1_null + &rk806_dvs2_null + &rk806_dvs3_null>; + system-power-controller; + vcc1-supply = <&vcc_5v0_sys>; + vcc2-supply = <&vcc_5v0_sys>; + vcc3-supply = <&vcc_5v0_sys>; + vcc4-supply = <&vcc_5v0_sys>; + vcc5-supply = <&vcc_5v0_sys>; + vcc6-supply = <&vcc_5v0_sys>; + vcc7-supply = <&vcc_5v0_sys>; + vcc8-supply = <&vcc_5v0_sys>; + vcc9-supply = <&vcc_5v0_sys>; + vcc10-supply = <&vcc_5v0_sys>; + vcc11-supply = <&vcc_2v0_pldo_s3>; + vcc12-supply = <&vcc_5v0_sys>; + vcc13-supply = <&vcc_1v1_nldo_s3>; + vcc14-supply = <&vcc_1v1_nldo_s3>; + vcca-supply = <&vcc_5v0_sys>; + + rk806_dvs1_null: dvs1-null-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun0"; + }; + + rk806_dvs2_null: dvs2-null-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun0"; + }; + + rk806_dvs3_null: dvs3-null-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun0"; + }; + + rk806_dvs1_slp: dvs1-slp-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun1"; + }; + + rk806_dvs1_pwrdn: dvs1-pwrdn-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun2"; + }; + + rk806_dvs1_rst: dvs1-rst-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun3"; + }; + + rk806_dvs2_slp: dvs2-slp-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun1"; + }; + + rk806_dvs2_pwrdn: dvs2-pwrdn-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun2"; + }; + + rk806_dvs2_rst: dvs2-rst-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun3"; + }; + + rk806_dvs2_dvs: dvs2-dvs-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun4"; + }; + + rk806_dvs2_gpio: dvs2-gpio-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun5"; + }; + + rk806_dvs3_slp: dvs3-slp-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun1"; + }; + + rk806_dvs3_pwrdn: dvs3-pwrdn-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun2"; + }; + + rk806_dvs3_rst: dvs3-rst-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun3"; + }; + + rk806_dvs3_dvs: dvs3-dvs-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun4"; + }; + + rk806_dvs3_gpio: dvs3-gpio-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun5"; + }; + + regulators { + vdd_cpu_big_s0: dcdc-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_cpu_big_s0"; + regulator-enable-ramp-delay = <400>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_npu_s0: dcdc-reg2 { + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_npu_s0"; + regulator-enable-ramp-delay = <400>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_lit_s0: dcdc-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_cpu_lit_s0"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + vcc_3v3_s3: dcdc-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_3v3_s3"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vdd_gpu_s0: dcdc-reg5 { + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <900000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_gpu_s0"; + regulator-enable-ramp-delay = <400>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <850000>; + }; + }; + + vddq_ddr_s0: dcdc-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vddq_ddr_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_logic_s0: dcdc-reg7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <800000>; + regulator-name = "vdd_logic_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8_s3: dcdc-reg8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8_s3"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd2_ddr_s3: dcdc-reg9 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vdd2_ddr_s3"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_ddr_s0: dcdc-reg10 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vdd_ddr_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca_1v8_s0: pldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca_1v8_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pldo2_s0: pldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca1v8_pldo2_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_1v2_s0: pldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vdda_1v2_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca_3v3_s0: pldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcca_3v3_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd_s0: pldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vccio_sd_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pldo6_s3: pldo-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca1v8_pldo6_s3"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_0v75_s3: nldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "vdd_0v75_s3"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + vdda_ddr_pll_s0: nldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "vdda_ddr_pll_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v75_hdmi_s0: nldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <837500>; + regulator-max-microvolt = <837500>; + regulator-name = "vdda0v75_hdmi_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v85_s0: nldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "vdda_0v85_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v75_s0: nldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "vdda_0v75_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&i2c2 { + status = "okay"; + + rtc@68 { + compatible = "dallas,ds1338"; + reg = <0x68>; + }; +}; + +&i2c4 { + status = "okay"; + + es8388: audio-codec@11 { + compatible = "everest,es8388", "everest,es8328"; + reg = <0x11>; + clocks = <&cru CLK_SAI2_MCLKOUT_TO_IO>; + assigned-clocks = <&cru CLK_SAI2_MCLKOUT_TO_IO>; + assigned-clock-rates = <12288000>; + AVDD-supply = <&vcc_3v3_s0>; + DVDD-supply = <&vcc_3v3_s0>; + HPVDD-supply = <&vcc_3v3_s0>; + PVDD-supply = <&vcc_3v3_s0>; + pinctrl-names = "default"; + pinctrl-0 = <&sai2m0_mclk>; + #sound-dai-cells = <0>; + }; +}; + +&mdio0 { + rgmii_phy0: phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_rst>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>; + }; +}; + +&mdio1 { + rgmii_phy1: phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1_rst>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_LOW>; + }; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_reset>; + reset-gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3_m2>; + status = "okay"; +}; + +&pinctrl { + gmac { + gmac0_rst: gmac0-rst { + rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + gmac1_rst: gmac1-rst { + rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + gpio-keys { + gpio0_a0_d: gpio0-a0-d { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie_reset: pcie-reset { + rockchip,pins = <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + typec5v_pwren_h: typec5v-pwren-h { + rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&sai2 { + status = "okay"; +}; + +&sai6 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca1v8_pldo2_s0>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + full-pwr-cycle-in-suspend; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + no-sdio; + no-sd; + non-removable; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + sd-uhs-sdr104; + vmmc-supply = <&vcc_3v3_s0>; + vqmmc-supply = <&vccio_sd_s0>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&u2phy0_otg { + phy-supply = <&vbus5v0_typec>; + status = "okay"; +}; + +&u2phy1 { + status = "okay"; +}; + +&u2phy1_otg { + phy-supply = <&vcc_5v0_sys>; + status = "okay"; +}; + +&uart0 { + pinctrl-0 = <&uart0m0_xfer>; + status = "okay"; +}; + +&usbdp_phy { + status = "okay"; +}; + +&usb_drd0_dwc3 { + status = "okay"; +}; + +&usb_drd1_dwc3 { + dr_mode = "host"; + status = "okay"; +}; + +&vop { + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3576-nanopi-r76s.dts b/arch/arm64/boot/dts/rockchip/rk3576-nanopi-r76s.dts new file mode 100644 index 0000000000000..31fbefaeceab4 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3576-nanopi-r76s.dts @@ -0,0 +1,860 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (c) 2025 FriendlyElec Computer Tech. Co., Ltd. + * (http://www.friendlyelec.com) + * + * Copyright (c) 2025 Tianling Shen + */ + +/dts-v1/; +#include +#include +#include +#include +#include + +#include "rk3576.dtsi" + +/ { + model = "FriendlyElec NanoPi R76S"; + compatible = "friendlyarm,nanopi-r76s", "rockchip,rk3576"; + + aliases { + mmc0 = &sdhci; + mmc1 = &sdmmc; + mmc2 = &sdio; + }; + + chosen { + stdout-path = "serial0:1500000n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&user_but_pin>; + + button-reset { + label = "reset"; + gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_LOW>; + debounce-interval = <50>; + linux,code = ; + wakeup-source; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led1_h>, <&led_sys_h>, <&led2_h>; + + led-0 { + color = ; + function = LED_FUNCTION_LAN; + gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>; + }; + + led-1 { + color = ; + function = LED_FUNCTION_POWER; + gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + + led-2 { + color = ; + function = LED_FUNCTION_WAN; + gpios = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + hdmi-pwr-supply = <&vcc5v_hdmi_tx>; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&hym8563>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_reg_on_h>; + post-power-on-delay-ms = <200>; + reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + }; + + vcc3v3_rtc_s5: regulator-vcc3v3-rtc-s5 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3_rtc_s5"; + vin-supply = <&vcc5v0_sys_s5>; + }; + + vcc5v_dcin: regulator-vcc5v-dcin { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-name = "vcc5v_dcin"; + }; + + vcc5v_hdmi_tx: regulator-vcc5v-hdmi-tx { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_tx_on_h>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-name = "vcc5v_hdmi_tx"; + vin-supply = <&vcc5v0_sys_s5>; + }; + + vcc5v0_device_s0: regulator-vcc5v0-device-s0 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-name = "vcc5v0_device_s0"; + vin-supply = <&vcc5v_dcin>; + }; + + vcc5v0_sys_s5: regulator-vcc5v0-sys-s5 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-name = "vcc5v0_sys_s5"; + vin-supply = <&vcc5v_dcin>; + }; + + vcc5v0_usb_otg0: regulator-vcc5v0-usb-otg0 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PD1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_otg0_pwren_h>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-name = "vcc5v0_usb_otg0"; + vin-supply = <&vcc5v0_sys_s5>; + }; + + vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vcc_1v1_nldo_s3"; + vin-supply = <&vcc5v0_sys_s5>; + }; + + vcc_1v8_s0: regulator-vcc-1v8-s0 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8_s0"; + vin-supply = <&vcc_1v8_s3>; + }; + + vcc_2v0_pldo_s3: regulator-vcc-2v0-pldo-s3 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + regulator-name = "vcc_2v0_pldo_s3"; + vin-supply = <&vcc5v0_sys_s5>; + }; + + vcc_3v3_s0: regulator-vcc-3v3-s0 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_3v3_s0"; + vin-supply = <&vcc_3v3_s3>; + }; +}; + +&combphy0_ps { + status = "okay"; +}; + +&combphy1_psu { + status = "okay"; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_b2 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_b3 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&gpu { + mali-supply = <&vdd_gpu_s0>; + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; + +&hdptxphy { + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + pmic@23 { + compatible = "rockchip,rk806"; + reg = <0x23>; + #gpio-cells = <2>; + gpio-controller; + interrupt-parent = <&gpio0>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, + <&rk806_dvs2_null>, <&rk806_dvs3_null>; + system-power-controller; + + vcc1-supply = <&vcc5v0_sys_s5>; + vcc2-supply = <&vcc5v0_sys_s5>; + vcc3-supply = <&vcc5v0_sys_s5>; + vcc4-supply = <&vcc5v0_sys_s5>; + vcc5-supply = <&vcc5v0_sys_s5>; + vcc6-supply = <&vcc5v0_sys_s5>; + vcc7-supply = <&vcc5v0_sys_s5>; + vcc8-supply = <&vcc5v0_sys_s5>; + vcc9-supply = <&vcc5v0_sys_s5>; + vcc10-supply = <&vcc5v0_sys_s5>; + vcc11-supply = <&vcc_2v0_pldo_s3>; + vcc12-supply = <&vcc5v0_sys_s5>; + vcc13-supply = <&vcc_1v1_nldo_s3>; + vcc14-supply = <&vcc_1v1_nldo_s3>; + vcca-supply = <&vcc5v0_sys_s5>; + + rk806_dvs1_null: dvs1-null-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun0"; + }; + + rk806_dvs1_pwrdn: dvs1-pwrdn-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun2"; + }; + + rk806_dvs1_rst: dvs1-rst-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun3"; + }; + + rk806_dvs1_slp: dvs1-slp-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun1"; + }; + + rk806_dvs2_dvs: dvs2-dvs-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun4"; + }; + + rk806_dvs2_gpio: dvs2-gpio-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun5"; + }; + + rk806_dvs2_null: dvs2-null-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun0"; + }; + + rk806_dvs2_pwrdn: dvs2-pwrdn-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun2"; + }; + + rk806_dvs2_rst: dvs2-rst-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun3"; + }; + + rk806_dvs2_slp: dvs2-slp-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun1"; + }; + + rk806_dvs3_dvs: dvs3-dvs-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun4"; + }; + + rk806_dvs3_gpio: dvs3-gpio-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun5"; + }; + + rk806_dvs3_null: dvs3-null-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun0"; + }; + + rk806_dvs3_pwrdn: dvs3-pwrdn-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun2"; + }; + + rk806_dvs3_rst: dvs3-rst-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun3"; + }; + + rk806_dvs3_slp: dvs3-slp-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun1"; + }; + + regulators { + vdd_cpu_big_s0: dcdc-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-enable-ramp-delay = <400>; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-name = "vdd_cpu_big_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_npu_s0: dcdc-reg2 { + regulator-boot-on; + regulator-enable-ramp-delay = <400>; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-name = "vdd_npu_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_lit_s0: dcdc-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-name = "vdd_cpu_lit_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + vcc_3v3_s3: dcdc-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_3v3_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vdd_gpu_s0: dcdc-reg5 { + regulator-boot-on; + regulator-enable-ramp-delay = <400>; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd_gpu_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <850000>; + }; + }; + + vddq_ddr_s0: dcdc-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vddq_ddr_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_logic_s0: dcdc-reg7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <800000>; + regulator-name = "vdd_logic_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8_s3: dcdc-reg8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd2_ddr_s3: dcdc-reg9 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vdd2_ddr_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_ddr_s0: dcdc-reg10 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vdd_ddr_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca_1v8_s0: pldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca_1v8_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pldo2_s0: pldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca1v8_pldo2_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_1v2_s0: pldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vdda_1v2_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca_3v3_s0: pldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcca_3v3_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd_s0: pldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vccio_sd_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pldo6_s3: pldo-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca1v8_pldo6_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_0v75_s3: nldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "vdd_0v75_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + vdda_ddr_pll_s0: nldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "vdda_ddr_pll_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v75_hdmi_s0: nldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <837500>; + regulator-max-microvolt = <837500>; + regulator-name = "vdda0v75_hdmi_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v85_s0: nldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "vdda_0v85_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v75_s0: nldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "vdda_0v75_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&i2c2 { + status = "okay"; + + hym8563: rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + clock-output-names = "hym8563"; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_int_l>; + wakeup-source; + }; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_perstn>; + reset-gpios = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3_s3>; + status = "okay"; +}; + +&pcie1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie1_perstn>; + reset-gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3_s3>; + status = "okay"; +}; + +&pinctrl { + bt { + bt_reg_on_h: bt-reg-on-h { + rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + bt_wake_host_h: bt-wake-host-h { + rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + host_wake_bt_h: host-wake-bt-h { + rockchip,pins = <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-keys { + user_but_pin: user-but-pin { + rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-leds { + led_sys_h: led-sys-h { + rockchip,pins = <2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + led1_h: led1-h { + rockchip,pins = <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + led2_h: led2-h { + rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + hdmi { + hdmi_tx_on_h: hdmi-tx-on-h { + rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + hym8563 { + rtc_int_l: rtc-int-l { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pcie { + pcie0_perstn: pcie0-perstn { + rockchip,pins = <2 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + pcie1_perstn: pcie1-perstn { + rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + usb_otg0_pwren_h: usb-otg0-pwren-h { + rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wifi { + wifi_wake_host_h: wifi-wake-host-h { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + wifi_reg_on_h: wifi-reg-on-h { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&sai6 { + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + no-mmc; + no-sdio; + sd-uhs-sdr104; + vmmc-supply = <&vcc_3v3_s3>; + vqmmc-supply = <&vccio_sd_s0>; + status = "okay"; +}; + +&sdio { + #address-cells = <1>; + #size-cells = <0>; + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + disable-wp; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + no-mmc; + no-sd; + non-removable; + sd-uhs-sdr104; + vmmc-supply = <&vcc_3v3_s3>; + vqmmc-supply = <&vcc_1v8_s3>; + wakeup-source; + status = "okay"; + + rtl8822cs: wifi@1 { + reg = <1>; + interrupt-parent = <&gpio0>; + interrupts = ; + interrupt-names = "host-wake"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_wake_host_h>; + }; +}; + +&sdhci { + bus-width = <8>; + cap-mmc-highspeed; + full-pwr-cycle-in-suspend; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + no-sdio; + no-sd; + non-removable; + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca_1v8_s0>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&u2phy0_otg { + phy-supply = <&vcc5v0_usb_otg0>; + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&uart5m0_xfer &uart5m0_ctsn &uart5m0_rtsn>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "realtek,rtl8822cs-bt"; + enable-gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_HIGH>; + device-wake-gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_HIGH>; + host-wake-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&bt_wake_host_h &host_wake_bt_h &bt_reg_on_h>; + }; +}; + +&usbdp_phy { + status = "okay"; +}; + +&usb_drd0_dwc3 { + dr_mode = "host"; + extcon = <&u2phy0>; + status = "okay"; +}; + +&vop { + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts index 9bc33422ced50..7023dc326d0e8 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts @@ -52,9 +52,9 @@ power-led { color = ; + default-state = "on"; function = LED_FUNCTION_STATUS; gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-on"; }; user-led { diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi index e2500e31c434a..2a79217930206 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi @@ -2181,6 +2181,7 @@ <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>, <&cru SRST_T_EMMC>; reset-names = "core", "bus", "axi", "block", "timer"; + supports-cqe; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb2-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb2-v10.dts index 91fe810d38d85..60ba6ac55b239 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb2-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb2-v10.dts @@ -25,6 +25,18 @@ stdout-path = "serial2:1500000n8"; }; + dp-con { + compatible = "dp-connector"; + label = "DP OUT"; + type = "full-size"; + + port { + dp_con_in: endpoint { + remote-endpoint = <&dp0_out_con>; + }; + }; + }; + hdmi-con { compatible = "hdmi-connector"; type = "a"; @@ -106,6 +118,24 @@ }; }; +&dp0 { + pinctrl-0 = <&dp0m0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&dp0_in { + dp0_in_vp2: endpoint { + remote-endpoint = <&vp2_out_dp0>; + }; +}; + +&dp0_out { + dp0_out_con: endpoint { + remote-endpoint = <&dp_con_in>; + }; +}; + &gpu { mali-supply = <&vdd_gpu_s0>; sram-supply = <&vdd_gpu_mem_s0>; @@ -916,6 +946,17 @@ }; &vop { + /* + * If no dedicated PLL was specified, the GPLL would be automatically + * assigned as the PLL source for dclk_vop2. As the frequency of GPLL + * is 1188 MHz, we can only get typical clock frequencies such as + * 74.25MHz, 148.5MHz, 297MHz, 594MHz. + * + * So here we set the parent clock of VP2 to V0PLL so that we can get + * any frequency. + */ + assigned-clocks = <&cru DCLK_VOP2_SRC>; + assigned-clock-parents = <&cru PLL_V0PLL>; status = "okay"; }; @@ -929,3 +970,10 @@ remote-endpoint = <&hdmi0_in_vp0>; }; }; + +&vp2 { + vp2_out_dp0: endpoint@a { + reg = ; + remote-endpoint = <&dp0_in_vp2>; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts index bc8140883de47..172aeabba72a5 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts @@ -88,8 +88,8 @@ pinctrl-0 = <&led_pins>; power-led1 { + default-state = "on"; gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-on"; }; hdd-led2 { @@ -345,6 +345,10 @@ }; }; +&hdmi1_sound { + status = "okay"; +}; + &hdptxphy1 { status = "okay"; }; @@ -546,6 +550,11 @@ }; }; +/* HDMI1 ("HDMI TX1 8K") audio */ +&i2s6_8ch { + status = "okay"; +}; + &package_thermal { polling-delay = <1000>; @@ -670,6 +679,12 @@ }; }; + mmc { + sdmmc_det_pin: sdmmc-det-pin { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pcie { pcie20x1_2_perstn: pcie20x1-2-perstn { rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; @@ -795,12 +810,12 @@ bus-width = <4>; cap-mmc-highspeed; cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp; - max-frequency = <200000000>; no-sdio; no-mmc; pinctrl-names = "default"; - pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>; + pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_pin>; sd-uhs-sdr104; vmmc-supply = <&vcc_3v3_s3>; vqmmc-supply = <&vccio_sd_s0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi index 3bbe78810ec6f..b3e76ad2d8694 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi @@ -331,12 +331,12 @@ data-role = "dual"; /* fusb302 supports PD Rev 2.0 Ver 1.2 */ pd-revision = /bits/ 8 <0x2 0x0 0x1 0x2>; - power-role = "sink"; - try-power-role = "sink"; op-sink-microwatt = <1000000>; sink-pdos = , ; + source-pdos = + ; altmodes { displayport { @@ -509,6 +509,12 @@ }; }; + mmc { + sdmmc_det_pin: sdmmc-det-pin { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pcie2 { pcie2_0_rst: pcie2-0-rst { rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; @@ -590,7 +596,6 @@ }; &sdmmc { - max-frequency = <200000000>; no-sdio; no-mmc; bus-width = <4>; @@ -598,6 +603,8 @@ cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_pin>; sd-uhs-sdr104; vmmc-supply = <&vcc_3v3_s3>; vqmmc-supply = <&vccio_sd_s0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts index 5e984a44120e4..07a840d9b3859 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts @@ -110,6 +110,11 @@ }; }; +&usb_con { + power-role = "dual"; + try-power-role = "sink"; +}; + &usbdp_phy0 { pinctrl-names = "default"; pinctrl-0 = <&usbc_sbu_dc>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts index 8ef01010d985b..da13dafcbc823 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts @@ -49,6 +49,10 @@ }; }; +&usb_con { + power-role = "sink"; +}; + &usbdp_phy0 { pinctrl-names = "default"; pinctrl-0 = <&usbc_sbu_dc>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts index c1763835f53d4..0dd90c744380b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts @@ -130,6 +130,10 @@ }; }; +&usb_con { + power-role = "source"; +}; + &usbdp_phy0 { pinctrl-names = "default"; pinctrl-0 = <&usbc_sbu_dc>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts index 0df3e80f2dd91..f82050597ab31 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts @@ -465,7 +465,6 @@ cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp; - max-frequency = <150000000>; no-mmc; no-sdio; sd-uhs-sdr104; diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts index f5894672fcbd3..21eb003198fe0 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts @@ -796,6 +796,10 @@ domain-supply = <&vdd_gpu_s0>; }; +&pd_npu { + domain-supply = <&vdd_npu_s0>; +}; + &pinctrl { audio-amplifier { headphone_amplifier_en: headphone-amplifier-en { @@ -979,6 +983,36 @@ status = "okay"; }; +&rknn_core_0 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_1 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_2 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_mmu_0 { + status = "okay"; +}; + +&rknn_mmu_1 { + status = "okay"; +}; + +&rknn_mmu_2 { + status = "okay"; +}; + &saradc { vref-supply = <&vcc_1v8_s0>; status = "okay"; diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts index 4ec7bc4a9e960..174d299cc6bb9 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts @@ -11,6 +11,7 @@ / { model = "Indiedroid Nova"; + chassis-type = "embedded"; compatible = "indiedroid,nova", "rockchip,rk3588s"; adc-keys-0 { @@ -189,6 +190,22 @@ cpu-supply = <&vdd_cpu_big1_s0>; }; +&dp0 { + status = "okay"; +}; + +&dp0_in { + dp0_in_vp1: endpoint { + remote-endpoint = <&vp1_out_dp0>; + }; +}; + +&dp0_out { + dp0_out_con: endpoint { + remote-endpoint = <&usbdp_phy0_dp_in>; + }; +}; + /* * Add labels for each GPIO pin exposed on the 40 pin header. Note that * voltage of each GPIO pin could be either 3.3v or 1.8v (as noted by @@ -370,28 +387,36 @@ sink-pdos = ; op-sink-microwatt = <1000000>; + altmodes { + displayport { + svid = /bits/ 16 <0xff01>; + vdo = <0xffffffff>; + }; + }; + + ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; - usbc0_orien_sw: endpoint { - remote-endpoint = <&usbdp_phy0_orientation_switch>; + usbc0_hs: endpoint { + remote-endpoint = <&usb_host0_xhci_hs>; }; }; port@1 { reg = <1>; - usbc0_role_sw: endpoint { - remote-endpoint = <&dwc3_0_role_switch>; + usbc0_ss: endpoint { + remote-endpoint = <&usbdp_phy0_ss_out>; }; }; port@2 { reg = <2>; - dp_altmode_mux: endpoint { - remote-endpoint = <&usbdp_phy0_dp_altmode_mux>; + usbc0_sbu: endpoint { + remote-endpoint = <&usbdp_phy0_dp_out>; }; }; }; @@ -405,7 +430,7 @@ clock-output-names = "hym8563"; interrupt-parent = <&gpio0>; interrupts = ; - pinctrl-0 = <&hym8563_int>; + pinctrl-0 = <&hym8563_int>, <&clk32k_in>; pinctrl-names = "default"; wakeup-source; }; @@ -458,8 +483,11 @@ }; &pcie2x1l2 { - pinctrl-0 = <&rtl8111_perstb>; + pinctrl-0 = <&pcie20x1m0_perstn>, <&pcie20x1m0_clkreqn>, + <&pcie20x1m0_waken>; pinctrl-names = "default"; + reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3_s3>; status = "okay"; }; @@ -467,6 +495,10 @@ domain-supply = <&vdd_gpu_s0>; }; +&pd_npu { + domain-supply = <&vdd_npu_s0>; +}; + &pinctrl { bluetooth-pins { bt_reset: bt-reset { @@ -485,12 +517,6 @@ }; }; - ethernet-pins { - rtl8111_perstb: rtl8111-perstb { - rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - hym8563 { hym8563_int: hym8563-int { @@ -499,13 +525,6 @@ }; }; - sdio-pwrseq { - wifi_enable_h: wifi-enable-h { - rockchip,pins = - <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - usb-typec { usbc0_int: usbc0-int { rockchip,pins = @@ -517,6 +536,48 @@ <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; }; }; + + wifi { + wifi_enable_h: wifi-enable-h { + rockchip,pins = + <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wifi_host_wake_irq: wifi-host-wake-irq { + rockchip,pins = + <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; +}; + +&rknn_core_0 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_1 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_2 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_mmu_0 { + status = "okay"; +}; + +&rknn_mmu_1 { + status = "okay"; +}; + +&rknn_mmu_2 { + status = "okay"; }; &saradc { @@ -524,10 +585,10 @@ status = "okay"; }; -/* HS400 modes seemed to cause io errors. */ &sdhci { bus-width = <8>; - no-mmc-hs400; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; no-sd; no-sdio; non-removable; @@ -537,6 +598,7 @@ }; &sdio { + #address-cells = <1>; bus-width = <4>; cap-sd-highspeed; cap-sdio-irq; @@ -548,9 +610,19 @@ no-sd; non-removable; sd-uhs-sdr104; + #size-cells = <0>; vmmc-supply = <&vcc_3v3_s3>; vqmmc-supply = <&vcc_1v8_s3>; status = "okay"; + + sdio_wifi: wifi@1 { + reg = <1>; + interrupt-parent = <&gpio0>; + interrupts = ; + interrupt-names = "host-wake"; + pinctrl-0 = <&wifi_host_wake_irq>; + pinctrl-names = "default"; + }; }; &sdmmc { @@ -896,12 +968,9 @@ status = "okay"; }; -/* DMA seems to interfere with bluetooth device normal operation. */ &uart9 { pinctrl-0 = <&uart9m2_xfer>, <&uart9m2_ctsn>, <&uart9m2_rtsn>; pinctrl-names = "default"; - /delete-property/ dma-names; - /delete-property/ dmas; uart-has-rtscts; status = "okay"; @@ -928,9 +997,22 @@ usb-role-switch; status = "okay"; - port { - dwc3_0_role_switch: endpoint { - remote-endpoint = <&usbc0_role_sw>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usb_host0_xhci_hs: endpoint { + remote-endpoint = <&usbc0_hs>; + }; + }; + + port@1 { + reg = <1>; + usb_host0_xhci_ss: endpoint { + remote-endpoint = <&usbdp_phy0_ss_in>; + }; }; }; }; @@ -959,14 +1041,24 @@ #address-cells = <1>; #size-cells = <0>; - usbdp_phy0_orientation_switch: endpoint@0 { + usbdp_phy0_ss_out: endpoint@0 { reg = <0>; - remote-endpoint = <&usbc0_orien_sw>; + remote-endpoint = <&usbc0_ss>; }; - usbdp_phy0_dp_altmode_mux: endpoint@1 { + usbdp_phy0_ss_in: endpoint@1 { reg = <1>; - remote-endpoint = <&dp_altmode_mux>; + remote-endpoint = <&usb_host0_xhci_ss>; + }; + + usbdp_phy0_dp_in: endpoint@2 { + reg = <2>; + remote-endpoint = <&dp0_out_con>; + }; + + usbdp_phy0_dp_out: endpoint@3 { + reg = <3>; + remote-endpoint = <&usbc0_sbu>; }; }; }; @@ -985,3 +1077,10 @@ remote-endpoint = <&hdmi0_in_vp0>; }; }; + +&vp1 { + vp1_out_dp0: endpoint@a { + reg = ; + remote-endpoint = <&dp0_in_vp1>; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts index 19a08f7794e67..045a853d39ec7 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts @@ -61,9 +61,9 @@ power-led { color = ; + default-state = "on"; function = LED_FUNCTION_POWER; gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-on"; }; }; @@ -228,6 +228,13 @@ regulator-off-in-suspend; }; }; + + eeprom: eeprom@50 { + compatible = "belling,bl24c16a", "atmel,24c16"; + reg = <0x50>; + pagesize = <16>; + vcc-supply = <&vcc_3v3_pmu>; + }; }; &i2c2 { @@ -249,12 +256,6 @@ regulator-off-in-suspend; }; }; - - eeprom: eeprom@50 { - compatible = "belling,bl24c16a", "atmel,24c16"; - reg = <0x50>; - pagesize = <16>; - }; }; &i2c3 { @@ -377,6 +378,12 @@ }; }; + mmc { + sdmmc_det_pin: sdmmc-det-pin { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pcie { pow_en: pow-en { rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; @@ -436,6 +443,8 @@ max-frequency = <150000000>; no-sdio; no-mmc; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_pin>; sd-uhs-sdr104; vmmc-supply = <&vcc_3v3_s0>; vqmmc-supply = <&vccio_sd_s0>; @@ -600,7 +609,7 @@ }; }; - vcc_3v3_s3: dcdc-reg8 { + vcc_3v3_pmu: vcc_3v3_s3: dcdc-reg8 { regulator-name = "vcc_3v3_s3"; regulator-always-on; regulator-boot-on; diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts index dd7317bab6135..b837c4e08cec0 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts @@ -473,6 +473,12 @@ }; }; + mmc { + sdmmc_det_pin: sdmmc-det-pin { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pcie { pcie20x1_2_perstn_m0: pcie20x1-2-perstn-m0 { rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; @@ -533,9 +539,12 @@ bus-width = <4>; cap-mmc-highspeed; cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp; no-sdio; no-mmc; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_pin>; sd-uhs-sdr104; vmmc-supply = <&vcc_3v3_s3>; vqmmc-supply = <&vccio_sd_s0>; diff --git a/arch/arm64/boot/dts/sprd/sc9860.dtsi b/arch/arm64/boot/dts/sprd/sc9860.dtsi index d2456d633c39c..864ef0a17425c 100644 --- a/arch/arm64/boot/dts/sprd/sc9860.dtsi +++ b/arch/arm64/boot/dts/sprd/sc9860.dtsi @@ -184,20 +184,6 @@ | IRQ_TYPE_LEVEL_HIGH)>; }; - pmu_gate: pmu-gate { - compatible = "sprd,sc9860-pmu-gate"; - sprd,syscon = <&pmu_regs>; /* 0x402b0000 */ - clocks = <&ext_26m>; - #clock-cells = <1>; - }; - - pll: pll { - compatible = "sprd,sc9860-pll"; - sprd,syscon = <&ana_regs>; /* 0x40400000 */ - clocks = <&pmu_gate 0>; - #clock-cells = <1>; - }; - ap_clk: clock-controller@20000000 { compatible = "sprd,sc9860-ap-clk"; reg = <0 0x20000000 0 0x400>; @@ -214,19 +200,6 @@ #clock-cells = <1>; }; - apahb_gate: apahb-gate { - compatible = "sprd,sc9860-apahb-gate"; - sprd,syscon = <&ap_ahb_regs>; /* 0x20210000 */ - clocks = <&aon_prediv 0>; - #clock-cells = <1>; - }; - - aon_gate: aon-gate { - compatible = "sprd,sc9860-aon-gate"; - sprd,syscon = <&aon_regs>; /* 0x402e0000 */ - clocks = <&aon_prediv 0>; - #clock-cells = <1>; - }; aonsecure_clk: clock-controller@40880000 { compatible = "sprd,sc9860-aonsecure-clk"; @@ -235,13 +208,6 @@ #clock-cells = <1>; }; - agcp_gate: agcp-gate { - compatible = "sprd,sc9860-agcp-gate"; - sprd,syscon = <&agcp_regs>; /* 0x415e0000 */ - clocks = <&aon_prediv 0>; - #clock-cells = <1>; - }; - gpu_clk: clock-controller@60200000 { compatible = "sprd,sc9860-gpu-clk"; reg = <0 0x60200000 0 0x400>; @@ -256,13 +222,6 @@ #clock-cells = <1>; }; - vsp_gate: vsp-gate { - compatible = "sprd,sc9860-vsp-gate"; - sprd,syscon = <&vsp_regs>; /* 0x61100000 */ - clocks = <&vsp_clk 0>; - #clock-cells = <1>; - }; - cam_clk: clock-controller@62000000 { compatible = "sprd,sc9860-cam-clk"; reg = <0 0x62000000 0 0x4000>; @@ -270,13 +229,6 @@ #clock-cells = <1>; }; - cam_gate: cam-gate { - compatible = "sprd,sc9860-cam-gate"; - sprd,syscon = <&cam_regs>; /* 0x62100000 */ - clocks = <&cam_clk 0>; - #clock-cells = <1>; - }; - disp_clk: clock-controller@63000000 { compatible = "sprd,sc9860-disp-clk"; reg = <0 0x63000000 0 0x400>; @@ -284,20 +236,6 @@ #clock-cells = <1>; }; - disp_gate: disp-gate { - compatible = "sprd,sc9860-disp-gate"; - sprd,syscon = <&disp_regs>; /* 0x63100000 */ - clocks = <&disp_clk 0>; - #clock-cells = <1>; - }; - - apapb_gate: apapb-gate { - compatible = "sprd,sc9860-apapb-gate"; - sprd,syscon = <&ap_apb_regs>; /* 0x70b00000 */ - clocks = <&ap_clk 0>; - #clock-cells = <1>; - }; - funnel@10001000 { /* SoC Funnel */ compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; reg = <0 0x10001000 0 0x1000>; diff --git a/arch/arm64/boot/dts/sprd/whale2.dtsi b/arch/arm64/boot/dts/sprd/whale2.dtsi index a551e14ce8261..2ecaa56001b80 100644 --- a/arch/arm64/boot/dts/sprd/whale2.dtsi +++ b/arch/arm64/boot/dts/sprd/whale2.dtsi @@ -18,49 +18,67 @@ #size-cells = <2>; ranges; - ap_ahb_regs: syscon@20210000 { - compatible = "syscon"; + apahb_gate: clock-controller@20210000 { reg = <0 0x20210000 0 0x10000>; + compatible = "sprd,sc9860-apahb-gate"; + clocks = <&aon_prediv 0>; + #clock-cells = <1>; }; - pmu_regs: syscon@402b0000 { - compatible = "syscon"; + pmu_gate: clock-controller@402b0000 { reg = <0 0x402b0000 0 0x10000>; + compatible = "sprd,sc9860-pmu-gate"; + clocks = <&ext_26m>; + #clock-cells = <1>; }; - aon_regs: syscon@402e0000 { - compatible = "syscon"; + aon_gate: clock-controller@402e0000 { reg = <0 0x402e0000 0 0x10000>; + compatible = "sprd,sc9860-aon-gate"; + clocks = <&aon_prediv 0>; + #clock-cells = <1>; }; - ana_regs: syscon@40400000 { - compatible = "syscon"; + pll: clock-controller@40400000 { reg = <0 0x40400000 0 0x10000>; + compatible = "sprd,sc9860-pll"; + clocks = <&pmu_gate 0>; + #clock-cells = <1>; }; - agcp_regs: syscon@415e0000 { - compatible = "syscon"; + agcp_gate: clock-controller@415e0000 { reg = <0 0x415e0000 0 0x1000000>; + compatible = "sprd,sc9860-agcp-gate"; + clocks = <&aon_prediv 0>; + #clock-cells = <1>; }; - vsp_regs: syscon@61100000 { - compatible = "syscon"; + vsp_gate: clock-controller@61100000 { reg = <0 0x61100000 0 0x10000>; + compatible = "sprd,sc9860-vsp-gate"; + clocks = <&vsp_clk 0>; + #clock-cells = <1>; }; - cam_regs: syscon@62100000 { - compatible = "syscon"; + cam_gate: clock-controller@62100000 { reg = <0 0x62100000 0 0x10000>; + compatible = "sprd,sc9860-cam-gate"; + clocks = <&cam_clk 0>; + #clock-cells = <1>; }; - disp_regs: syscon@63100000 { - compatible = "syscon"; + disp_gate: clock-controller@63100000 { reg = <0 0x63100000 0 0x10000>; + compatible = "sprd,sc9860-disp-gate"; + clocks = <&disp_clk 0>; + #clock-cells = <1>; }; - ap_apb_regs: syscon@70b00000 { - compatible = "syscon"; + apapb_gate: clock-controller@70b00000 { reg = <0 0x70b00000 0 0x40000>; + compatible = "sprd,sc9860-apapb-gate"; + clocks = <&ap_clk 0>; + #clock-cells = <1>; }; ap-apb@70000000 { diff --git a/arch/arm64/boot/dts/st/stm32mp211.dtsi b/arch/arm64/boot/dts/st/stm32mp211.dtsi index bf888d60cd4f0..cd078a16065e6 100644 --- a/arch/arm64/boot/dts/st/stm32mp211.dtsi +++ b/arch/arm64/boot/dts/st/stm32mp211.dtsi @@ -94,18 +94,20 @@ #size-cells = <2>; rifsc: bus@42080000 { - compatible = "simple-bus"; + compatible = "st,stm32mp21-rifsc", "simple-bus"; reg = <0x42080000 0x0 0x1000>; ranges; dma-ranges; #address-cells = <1>; #size-cells = <2>; + #access-controller-cells = <1>; usart2: serial@400e0000 { compatible = "st,stm32h7-uart"; reg = <0x400e0000 0x0 0x400>; interrupts = ; clocks = <&ck_flexgen_08>; + access-controllers = <&rifsc 32>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi index e0d102eb61769..c34cd33cd855f 100644 --- a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi +++ b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi @@ -38,6 +38,7 @@ bias-disable; drive-push-pull; slew-rate = <3>; + st,io-sync = "data on both edges"; }; pins2 { pinmux = , /* ETH_RGMII_CLK125 */ @@ -53,6 +54,7 @@ , /* ETH_RGMII_RXD3 */ ; /* ETH_RGMII_RX_CTL */ bias-disable; + st,io-sync = "data on both edges"; }; pins4 { pinmux = ; /* ETH_RGMII_RX_CLK */ @@ -142,6 +144,7 @@ bias-disable; drive-push-pull; slew-rate = <3>; + st,io-sync = "data on both edges"; }; pins2 { pinmux = , /* ETH_RGMII_CLK125 */ @@ -164,6 +167,7 @@ , /* ETH_RGMII_RXD3 */ ; /* ETH_RGMII_RX_CTL */ bias-disable; + st,io-sync = "data on both edges"; }; pins5 { pinmux = ; /* ETH_RGMII_RX_CLK */ diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts index 6e165073f7329..bb6d6393d2e46 100644 --- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts +++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts @@ -266,6 +266,7 @@ &ommanager { memory-region = <&mm_ospi1>; + memory-region-names = "ospi1"; pinctrl-0 = <&ospi_port1_clk_pins_a &ospi_port1_io03_pins_a &ospi_port1_cs0_pins_a>; diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile index 743115b849a7a..ba01a929e06f2 100644 --- a/arch/arm64/boot/dts/ti/Makefile +++ b/arch/arm64/boot/dts/ti/Makefile @@ -37,6 +37,9 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62a7-phyboard-lyra-rdk.dtb # Boards with AM62Dx SoC dtb-$(CONFIG_ARCH_K3) += k3-am62d2-evm.dtb +# Boards with AM62Lx SoCs +dtb-$(CONFIG_ARCH_K3) += k3-am62l3-evm.dtb + # Boards with AM62Px SoC dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb dtb-$(CONFIG_ARCH_K3) += k3-am62p5-var-som-symphony.dtb @@ -116,9 +119,11 @@ dtb-$(CONFIG_ARCH_K3) += k3-j7200-evm-pcie1-ep.dtbo # Boards with J721e SoC k3-j721e-evm-dtbs := k3-j721e-common-proc-board.dtb k3-j721e-evm-quad-port-eth-exp.dtbo +k3-j721e-evm-gesi-dtbs := k3-j721e-common-proc-board.dtb k3-j721e-evm-gesi-exp-board.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64.dtb dtb-$(CONFIG_ARCH_K3) += k3-j721e-common-proc-board-infotainment.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm.dtb +dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi.dtb dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi-exp-board.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie1-ep.dtbo @@ -137,12 +142,24 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-pcie1-ep.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-usb0-type-a.dtbo # Boards with J722s SoC +k3-am67a-kontron-sa67-dtbs := k3-am67a-kontron-sa67-base.dtb \ + k3-am67a-kontron-sa67-rtc-rv8263.dtbo k3-am67a-kontron-sa67-gbe1.dtbo +k3-am67a-kontron-sa67-ads2-dtbs := k3-am67a-kontron-sa67.dtb k3-am67a-kontron-sa67-ads2.dtbo dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai.dtb +dtb-$(CONFIG_ARCH_K3) += k3-am67a-kontron-sa67.dtb +dtb-$(CONFIG_ARCH_K3) += k3-am67a-kontron-sa67-base.dtb +dtb-$(CONFIG_ARCH_K3) += k3-am67a-kontron-sa67-gbe1.dtbo +dtb-$(CONFIG_ARCH_K3) += k3-am67a-kontron-sa67-gpios.dtbo +dtb-$(CONFIG_ARCH_K3) += k3-am67a-kontron-sa67-rtc-rv8263.dtbo +dtb-$(CONFIG_ARCH_K3) += k3-am67a-kontron-sa67-ads2.dtb +dtb-$(CONFIG_ARCH_K3) += k3-am67a-kontron-sa67-ads2.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-tevi-ov5640.dtbo # Boards with J784s4 SoC +dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-clover.dtb +dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-dev.dtb dtb-$(CONFIG_ARCH_K3) += k3-am69-sk.dtb dtb-$(CONFIG_ARCH_K3) += k3-am69-sk-pcie0-ep.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm.dtb @@ -177,6 +194,17 @@ k3-am625-sk-csi2-tevi-ov5640-dtbs := k3-am625-sk.dtb \ k3-am62x-sk-csi2-tevi-ov5640.dtbo k3-am625-sk-hdmi-audio-dtbs := k3-am625-sk.dtb k3-am62x-sk-hdmi-audio.dtbo k3-am62-lp-sk-hdmi-audio-dtbs := k3-am62-lp-sk.dtb k3-am62x-sk-hdmi-audio.dtbo +k3-am62-lp-sk-nand-dtbs := k3-am62-lp-sk.dtb k3-am62-lp-sk-nand.dtbo +k3-am62a7-phyboard-lyra-disable-eth-phy-dtbs := k3-am62a7-phyboard-lyra-rdk.dtb \ + k3-am6xx-phycore-disable-eth-phy.dtbo +k3-am62a7-phyboard-lyra-disable-rtc-dtbs := k3-am62a7-phyboard-lyra-rdk.dtb \ + k3-am6xx-phycore-disable-rtc.dtbo +k3-am62a7-phyboard-lyra-disable-spi-nor-dtbs := k3-am62a7-phyboard-lyra-rdk.dtb \ + k3-am6xx-phycore-disable-spi-nor.dtbo +k3-am62a7-phyboard-lyra-gpio-fan-dtbs := k3-am62a7-phyboard-lyra-rdk.dtb \ + k3-am62x-phyboard-lyra-gpio-fan.dtbo +k3-am62a7-phyboard-lyra-qspi-nor-dtbs := k3-am62a7-phyboard-lyra-rdk.dtb \ + k3-am6xx-phycore-qspi-nor.dtbo k3-am62a7-sk-csi2-imx219-dtbs := k3-am62a7-sk.dtb \ k3-am62x-sk-csi2-imx219.dtbo k3-am62a7-sk-csi2-ov5640-dtbs := k3-am62a7-sk.dtb \ @@ -216,6 +244,8 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \ k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \ k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo +k3-am67a-kontron-sa67-base-gpios-dtbs := \ + k3-am67a-kontron-sa67-base.dtb k3-am67a-kontron-sa67-gpios.dtbo k3-am68-sk-base-board-csi2-dual-imx219-dtbs := k3-am68-sk-base-board.dtb \ k3-j721e-sk-csi2-dual-imx219.dtbo k3-am68-sk-base-board-pcie1-ep-dtbs := k3-am68-sk-base-board.dtb \ @@ -254,11 +284,22 @@ k3-j784s4-evm-usxgmii-exp1-exp2-dtbs := k3-j784s4-evm.dtb \ k3-j784s4-evm-usxgmii-exp1-exp2.dtbo dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \ k3-am625-beagleplay-csi2-tevi-ov5640.dtb \ + k3-am625-phyboard-lyra-disable-eth-phy.dtb \ + k3-am625-phyboard-lyra-disable-rtc.dtb \ + k3-am625-phyboard-lyra-disable-spi-nor.dtb \ + k3-am625-phyboard-lyra-gpio-fan.dtb \ + k3-am625-phyboard-lyra-qspi-nor.dtb \ k3-am625-sk-csi2-imx219.dtb \ k3-am625-sk-csi2-ov5640.dtb \ k3-am625-sk-csi2-tevi-ov5640.dtb \ k3-am625-sk-hdmi-audio.dtb \ k3-am62-lp-sk-hdmi-audio.dtb \ + k3-am62-lp-sk-nand.dtb \ + k3-am62a7-phyboard-lyra-disable-eth-phy.dtb \ + k3-am62a7-phyboard-lyra-disable-rtc.dtb \ + k3-am62a7-phyboard-lyra-disable-spi-nor.dtb \ + k3-am62a7-phyboard-lyra-gpio-fan.dtb \ + k3-am62a7-phyboard-lyra-qspi-nor.dtb \ k3-am62a7-sk-csi2-imx219.dtb \ k3-am62a7-sk-csi2-ov5640.dtb \ k3-am62a7-sk-hdmi-audio.dtb \ @@ -268,8 +309,16 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \ k3-am642-evm-icssg1-dualemac.dtb \ k3-am642-evm-icssg1-dualemac-mii.dtb \ k3-am642-evm-pcie0-ep.dtb \ + k3-am642-phyboard-electra-disable-eth-phy.dtb \ + k3-am642-phyboard-electra-disable-rtc.dtb \ + k3-am642-phyboard-electra-disable-spi-nor.dtb \ + k3-am642-phyboard-electra-gpio-fan.dtb \ + k3-am642-phyboard-electra-pcie-usb2.dtb \ + k3-am642-phyboard-electra-peb-c-010.dtb \ + k3-am642-phyboard-electra-x27-gpio1-spi1-uart3.dtb \ k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \ k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \ + k3-am67a-kontron-sa67-base-gpios.dtb \ k3-am68-sk-base-board-csi2-dual-imx219.dtb \ k3-am68-sk-base-board-pcie1-ep.dtb \ k3-am69-sk-csi2-dual-imx219.dtb \ diff --git a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts index ecfba05fe5c27..3e2d8f6695351 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts @@ -181,6 +181,10 @@ vqmmc-supply = <&vddshv_sdio>; }; +&cpsw3g { + status = "okay"; +}; + &cpsw_port2 { status = "disabled"; }; @@ -276,3 +280,63 @@ &gpmc0 { ranges = <0 0 0x00 0x51000000 0x01000000>; /* CS0 space. Min partition = 16MB */ }; + +&mcu_mcan0 { + pinctrl-names = "default", "wakeup"; + pinctrl-0 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_default>; + pinctrl-1 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_wakeup>; + wakeup-source = <&system_partial_io>, + <&system_deep_sleep>, + <&system_mcu_only>, + <&system_standby>; + status = "okay"; +}; + +&mcu_mcan1 { + pinctrl-names = "default", "wakeup"; + pinctrl-0 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_default>; + pinctrl-1 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_wakeup>; + wakeup-source = <&system_partial_io>, + <&system_deep_sleep>, + <&system_mcu_only>, + <&system_standby>; + status = "okay"; +}; + +&mcu_pmx0 { + mcu_mcan0_tx_pins_default: mcu-mcan0-tx-default-pins { + pinctrl-single,pins = < + AM62X_IOPAD(0x034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */ + >; + }; + + mcu_mcan0_rx_pins_default: mcu-mcan0-rx-default-pins { + pinctrl-single,pins = < + AM62X_IOPAD(0x038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */ + >; + }; + + mcu_mcan0_rx_pins_wakeup: mcu-mcan0-rx-wakeup-pins { + pinctrl-single,pins = < + AM62X_IOPAD(0x038, PIN_INPUT | PIN_WKUP_EN, 0) /* (B3) MCU_MCAN0_RX */ + >; + }; + + mcu_mcan1_tx_pins_default: mcu-mcan1-tx-default-pins { + pinctrl-single,pins = < + AM62X_IOPAD(0x03c, PIN_OUTPUT, 0) /* (E5) MCU_MCAN1_TX */ + >; + }; + + mcu_mcan1_rx_pins_default: mcu-mcan1-rx-default-pins { + pinctrl-single,pins = < + AM62X_IOPAD(0x040, PIN_INPUT, 0) /* (D4) MCU_MCAN1_RX */ + >; + }; + + mcu_mcan1_rx_pins_wakeup: mcu-mcan1-rx-wakeup-pins { + pinctrl-single,pins = < + AM62X_IOPAD(0x040, PIN_INPUT | PIN_WKUP_EN, 0) /* (D4) MCU_MCAN1_RX */ + >; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi index 40fb3c9e674c0..c5ee263d34a62 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi @@ -76,6 +76,11 @@ assigned-clock-parents = <&k3_clks 157 18>; #clock-cells = <0>; }; + + dss_oldi_io_ctrl: oldi-io-controller@8600 { + compatible = "ti,am625-dss-oldi-io-ctrl", "syscon"; + reg = <0x8600 0x200>; + }; }; dmss: bus@48000000 { @@ -209,6 +214,16 @@ dmas = <&main_pktdma 0xf501 0>, <&main_pktdma 0x7506 0>, <&main_pktdma 0x7507 0>; dma-names = "tx", "rx1", "rx2"; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x00 0x40900000 0x00 0x40900000 0x00 0x30000>; + + rng: rng@40910000 { + compatible = "inside-secure,safexcel-eip76"; + reg = <0x00 0x40910000 0x00 0x7d>; + interrupts = ; + status = "reserved"; /* Reserved for OP-TEE */ + }; }; secure_proxy_sa3: mailbox@43600000 { @@ -723,6 +738,8 @@ dma-names = "tx0", "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7", "rx"; + status = "disabled"; + ethernet-ports { #address-cells = <1>; #size-cells = <0>; @@ -788,6 +805,53 @@ interrupts = ; status = "disabled"; + oldi-transmitters { + #address-cells = <1>; + #size-cells = <0>; + + oldi0: oldi@0 { + reg = <0>; + clocks = <&k3_clks 186 0>; + clock-names = "serial"; + ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + oldi0_port0: port@0 { + reg = <0>; + }; + + oldi0_port1: port@1 { + reg = <1>; + }; + }; + }; + + oldi1: oldi@1 { + reg = <1>; + clocks = <&k3_clks 186 0>; + clock-names = "serial"; + ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + oldi1_port0: port@0 { + reg = <0>; + }; + + oldi1_port1: port@1 { + reg = <1>; + }; + }; + }; + }; + dss_ports: ports { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi index eeca643fedbe9..878d267bc663b 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi @@ -211,10 +211,11 @@ &cpsw3g { pinctrl-names = "default"; pinctrl-0 = <&main_rgmii1_pins_default>; + status = "okay"; }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy1>; bootph-all; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi index 5c1284b802ad7..3d1406acf680a 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi @@ -74,7 +74,7 @@ /* Verdin ETH_2_RGMII */ &cpsw_port2 { phy-handle = <&cpsw3g_phy1>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi index 71c29eab0eee7..844f59f772e18 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi @@ -268,7 +268,7 @@ /* Verdin ETH_2_RGMII */ &cpsw_port2 { phy-handle = <&cpsw3g_phy1>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi index dc4b228a9fd7e..2a7242a2fef87 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi @@ -845,7 +845,7 @@ /* Verdin ETH_1 (On-module PHY) */ &cpsw_port1 { phy-handle = <&cpsw3g_phy0>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62.dtsi b/arch/arm64/boot/dts/ti/k3-am62.dtsi index 59f6dff552ed4..b08b7062060ca 100644 --- a/arch/arm64/boot/dts/ti/k3-am62.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62.dtsi @@ -46,6 +46,28 @@ interrupts = ; }; + system-idle-states { + system_partial_io: system-partial-io { + compatible = "system-idle-state"; + idle-state-name = "off-wake"; + }; + + system_deep_sleep: system-deep-sleep { + compatible = "system-idle-state"; + idle-state-name = "mem"; + }; + + system_mcu_only: system-mcu-only { + compatible = "system-idle-state"; + idle-state-name = "mem-mcu-active"; + }; + + system_standby: system-standby { + compatible = "system-idle-state"; + idle-state-name = "standby"; + }; + }; + cbass_main: bus@f0000 { bootph-all; compatible = "simple-bus"; diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts index 7028d9835c4a8..c468b9c5fc09a 100644 --- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts +++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts @@ -590,10 +590,11 @@ <&gbe_pmx_obsclk>; assigned-clocks = <&k3_clks 157 70>, <&k3_clks 157 20>; assigned-clock-parents = <&k3_clks 157 72>, <&k3_clks 157 22>; + status = "okay"; }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy0>; }; diff --git a/arch/arm64/boot/dts/ti/k3-am625-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am625-sk-common.dtsi index fe0b98e1d1055..9c83626826453 100644 --- a/arch/arm64/boot/dts/ti/k3-am625-sk-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am625-sk-common.dtsi @@ -212,11 +212,11 @@ &cpsw3g { pinctrl-names = "default"; pinctrl-0 = <&main_rgmii1_pins_default>, <&main_rgmii2_pins_default>; + status = "okay"; }; &cpsw_port2 { - /* PCB provides an internal delay of 2ns */ - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy1>; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi index 829f00adea6e3..9e5b75a4e88e2 100644 --- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi @@ -247,6 +247,16 @@ dmas = <&main_pktdma 0xf501 0>, <&main_pktdma 0x7506 0>, <&main_pktdma 0x7507 0>; dma-names = "tx", "rx1", "rx2"; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x00 0x40900000 0x00 0x40900000 0x00 0x30000>; + + rng: rng@40910000 { + compatible = "inside-secure,safexcel-eip76"; + reg = <0x00 0x40910000 0x00 0x7d>; + interrupts = ; + status = "reserved"; /* Reserved for OP-TEE */ + }; }; secure_proxy_sa3: mailbox@43600000 { diff --git a/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi index b3d012a5a26aa..b24a63feeab83 100644 --- a/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi @@ -192,7 +192,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy1>; bootph-all; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62a.dtsi b/arch/arm64/boot/dts/ti/k3-am62a.dtsi index 4d79b3e9486af..31b2de035f0f7 100644 --- a/arch/arm64/boot/dts/ti/k3-am62a.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62a.dtsi @@ -46,6 +46,33 @@ interrupts = ; }; + system-idle-states { + system_partial_io: system-partial-io { + compatible = "system-idle-state"; + idle-state-name = "off-wake"; + }; + + system_io_ddr: system-io-ddr { + compatible = "system-idle-state"; + idle-state-name = "mem-deep"; + }; + + system_deep_sleep: system-deep-sleep { + compatible = "system-idle-state"; + idle-state-name = "mem"; + }; + + system_mcu_only: system-mcu-only { + compatible = "system-idle-state"; + idle-state-name = "mem-mcu-active"; + }; + + system_standby: system-standby { + compatible = "system-idle-state"; + idle-state-name = "standby"; + }; + }; + cbass_main: bus@f0000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts index af591fe6ae4f0..e99bdbc2e0cbd 100644 --- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts @@ -233,6 +233,10 @@ &wkup_uart0 { pinctrl-names = "default"; pinctrl-0 = <&wkup_uart0_pins_default>; + wakeup-source = <&system_io_ddr>, + <&system_deep_sleep>, + <&system_mcu_only>, + <&system_standby>; status = "reserved"; }; @@ -426,6 +430,42 @@ AM62AX_MCU_IOPAD(0x000, PIN_INPUT, 7) /* (E11) MCU_GPIO0_0 */ >; }; + + mcu_mcan0_tx_pins_default: mcu-mcan0-tx-default-pins { + pinctrl-single,pins = < + AM62AX_MCU_IOPAD(0x034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */ + >; + }; + + mcu_mcan0_rx_pins_default: mcu-mcan0-rx-default-pins { + pinctrl-single,pins = < + AM62AX_MCU_IOPAD(0x038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */ + >; + }; + + mcu_mcan0_rx_pins_wakeup: mcu-mcan0-rx-wakeup-pins { + pinctrl-single,pins = < + AM62AX_MCU_IOPAD(0x038, PIN_INPUT | PIN_WKUP_EN, 0) /* (B3) MCU_MCAN0_RX */ + >; + }; + + mcu_mcan1_tx_pins_default: mcu-mcan1-tx-default-pins { + pinctrl-single,pins = < + AM62AX_MCU_IOPAD(0x03c, PIN_OUTPUT, 0) /* (E5) MCU_MCAN1_TX */ + >; + }; + + mcu_mcan1_rx_pins_default: mcu-mcan1-rx-default-pins { + pinctrl-single,pins = < + AM62AX_MCU_IOPAD(0x040, PIN_INPUT, 0) /* (D4) MCU_MCAN1_RX */ + >; + }; + + mcu_mcan1_rx_pins_wakeup: mcu-mcan1-rx-wakeup-pins { + pinctrl-single,pins = < + AM62AX_MCU_IOPAD(0x040, PIN_INPUT | PIN_WKUP_EN, 0) /* (D4) MCU_MCAN1_RX */ + >; + }; }; &mcu_gpio0 { @@ -731,7 +771,7 @@ &cpsw_port1 { status = "okay"; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy0>; bootph-all; }; @@ -852,4 +892,33 @@ }; }; +&mcu_mcan0 { + pinctrl-names = "default", "wakeup"; + pinctrl-0 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_default>; + pinctrl-1 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_wakeup>; + wakeup-source = <&system_partial_io>, + <&system_io_ddr>, + <&system_deep_sleep>, + <&system_mcu_only>, + <&system_standby>; +}; + +&mcu_mcan1 { + pinctrl-names = "default", "wakeup"; + pinctrl-0 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_default>; + pinctrl-1 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_wakeup>; + wakeup-source = <&system_partial_io>, + <&system_io_ddr>, + <&system_deep_sleep>, + <&system_mcu_only>, + <&system_standby>; +}; + +&mcu_uart0 { + wakeup-source = <&system_io_ddr>, + <&system_deep_sleep>, + <&system_mcu_only>, + <&system_standby>; +}; + #include "k3-am62a-ti-ipc-firmware.dtsi" diff --git a/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts b/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts index 83af889e790ae..2b233bc0323dd 100644 --- a/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts +++ b/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts @@ -146,6 +146,7 @@ regulator-name = "vdd_mmc1"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3v3_sys>; regulator-boot-on; enable-active-high; gpio = <&exp1 3 GPIO_ACTIVE_HIGH>; @@ -165,14 +166,16 @@ }; vddshv_sdio: regulator-6 { + /* output of TLV7103318QDSERQ1 */ compatible = "regulator-gpio"; regulator-name = "vddshv_sdio"; pinctrl-names = "default"; pinctrl-0 = <&vddshv_sdio_pins_default>; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_5v0>; regulator-boot-on; - gpios = <&main_gpio1 31 GPIO_ACTIVE_HIGH>; + gpios = <&main_gpio0 59 GPIO_ACTIVE_HIGH>; states = <1800000 0x0>, <3300000 0x1>; bootph-all; @@ -198,7 +201,7 @@ pmic_irq_pins_default: pmic-irq-default-pins { pinctrl-single,pins = < - AM62DX_MCU_IOPAD(0x000, PIN_INPUT, 7) /* (E11) MCU_GPIO0_0 */ + AM62DX_IOPAD(0x01f4, PIN_INPUT, 7) /* (F17) EXTINTn.GPIO1_31 */ >; }; @@ -211,6 +214,14 @@ >; bootph-all; }; + + wkup_i2c0_pins_default: wkup-i2c0-default-pins { + pinctrl-single,pins = < + AM62DX_MCU_IOPAD(0x004c, PIN_INPUT, 0) /* (D13) WKUP_I2C0_SCL */ + AM62DX_MCU_IOPAD(0x0050, PIN_INPUT, 0) /* (E13) WKUP_I2C0_SDA */ + >; + bootph-all; + }; }; /* WKUP UART0 is used for DM firmware logs */ @@ -334,7 +345,7 @@ vddshv_sdio_pins_default: vddshv-sdio-default-pins { pinctrl-single,pins = < - AM62DX_IOPAD(0x1f4, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO1_31 */ + AM62DX_IOPAD(0x00f0, PIN_INPUT, 7) /* (Y21) GPIO0_59 */ >; bootph-all; }; @@ -355,9 +366,6 @@ pinctrl-single,pins = < AM62DX_IOPAD(0x0000, PIN_OUTPUT, 0) /* (L22) OSPI0_CLK */ AM62DX_IOPAD(0x002c, PIN_OUTPUT, 0) /* (H21) OSPI0_CSn0 */ - AM62DX_IOPAD(0x0030, PIN_OUTPUT, 0) /* (G19) OSPI0_CSn1 */ - AM62DX_IOPAD(0x0034, PIN_OUTPUT, 0) /* (K20) OSPI0_CSn2 */ - AM62DX_IOPAD(0x0038, PIN_OUTPUT, 0) /* (G20) OSPI0_CSn3 */ AM62DX_IOPAD(0x000c, PIN_INPUT, 0) /* (J21) OSPI0_D0 */ AM62DX_IOPAD(0x0010, PIN_INPUT, 0) /* (J18) OSPI0_D1 */ AM62DX_IOPAD(0x0014, PIN_INPUT, 0) /* (J19) OSPI0_D2 */ @@ -461,6 +469,89 @@ status = "okay"; }; +&wkup_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&wkup_i2c0_pins_default>; + clock-frequency = <400000>; + status = "okay"; + + tps65224: pmic@48 { + compatible = "ti,tps65224-q1"; + reg = <0x48>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_irq_pins_default>; + interrupt-parent = <&main_gpio1>; + interrupts = <31 IRQ_TYPE_EDGE_FALLING>; + ti,primary-pmic; + + gpio-controller; + #gpio-cells = <2>; + + buck12-supply = <&vcc_3v3_sys>; + buck3-supply = <&vcc_3v3_sys>; + buck4-supply = <&vcc_3v3_sys>; + ldo1-supply = <&vcc_3v3_sys>; + ldo2-supply = <&vcc_3v3_sys>; + ldo3-supply = <&vcc_3v3_sys>; + + regulators { + buck12: buck12 { + regulator-name = "vdd_core"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-boot-on; + regulator-always-on; + bootph-all; + }; + + buck3: buck3 { + regulator-name = "dvdd1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + bootph-all; + }; + + buck4: buck4 { + regulator-name = "vdds_ddr"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-boot-on; + regulator-always-on; + bootph-all; + }; + + ldo1: ldo1 { + regulator-name = "vdda_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + bootph-all; + }; + + ldo2: ldo2 { + regulator-name = "dvdd3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + bootph-all; + }; + + ldo3: ldo3 { + regulator-name = "vddr_core"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-boot-on; + regulator-always-on; + bootph-all; + }; + }; + }; +}; + &sdhci0 { /* eMMC */ non-removable; diff --git a/arch/arm64/boot/dts/ti/k3-am62l-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62l-main.dtsi new file mode 100644 index 0000000000000..883beb76ba9c4 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am62l-main.dtsi @@ -0,0 +1,580 @@ +// SPDX-License-Identifier: GPL-2.0-only or MIT +/* + * Device Tree file for the AM62L main domain peripherals + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ + * + * Technical Reference Manual: https://www.ti.com/lit/pdf/sprujb4 + */ + +&cbass_main { + gic500: interrupt-controller@1800000 { + compatible = "arm,gic-v3"; + reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */ + <0x00 0x01840000 0x00 0xc0000>, /* GICR */ + <0x01 0x00000000 0x00 0x2000>, /* GICC */ + <0x01 0x00010000 0x00 0x1000>, /* GICH */ + <0x01 0x00020000 0x00 0x2000>; /* GICV */ + ranges; + #address-cells = <2>; + #size-cells = <2>; + #interrupt-cells = <3>; + interrupt-controller; + /* + * vcpumntirq: + * virtual CPU interface maintenance interrupt + */ + interrupts = ; + + gic_its: msi-controller@1820000 { + compatible = "arm,gic-v3-its"; + reg = <0x00 0x01820000 0x00 0x10000>; + socionext,synquacer-pre-its = <0x1000000 0x400000>; + msi-controller; + #msi-cells = <1>; + }; + }; + + gpio0: gpio@600000 { + compatible = "ti,am64-gpio", "ti,keystone-gpio"; + reg = <0x00 0x00600000 0x00 0x100>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gic500>; + interrupts = , + , + , + , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + power-domains = <&scmi_pds 34>; + clocks = <&scmi_clk 140>; + clock-names = "gpio"; + ti,ngpio = <126>; + ti,davinci-gpio-unbanked = <0>; + }; + + gpio2: gpio@610000 { + compatible = "ti,am64-gpio", "ti,keystone-gpio"; + reg = <0x00 0x00610000 0x00 0x100>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gic500>; + interrupts = , + , + , + , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + power-domains = <&scmi_pds 35>; + clocks = <&scmi_clk 141>; + clock-names = "gpio"; + ti,ngpio = <79>; + ti,davinci-gpio-unbanked = <0>; + }; + + timer0: timer@2400000 { + compatible = "ti,am654-timer"; + reg = <0x00 0x2400000 0x00 0x400>; + interrupts = ; + clocks = <&scmi_clk 58>; + clock-names = "fck"; + power-domains = <&scmi_pds 15>; + ti,timer-pwm; + }; + + timer1: timer@2410000 { + compatible = "ti,am654-timer"; + reg = <0x00 0x2410000 0x00 0x400>; + interrupts = ; + clocks = <&scmi_clk 63>; + clock-names = "fck"; + power-domains = <&scmi_pds 16>; + ti,timer-pwm; + }; + + timer2: timer@2420000 { + compatible = "ti,am654-timer"; + reg = <0x00 0x2420000 0x00 0x400>; + interrupts = ; + clocks = <&scmi_clk 77>; + clock-names = "fck"; + power-domains = <&scmi_pds 17>; + ti,timer-pwm; + }; + + timer3: timer@2430000 { + compatible = "ti,am654-timer"; + reg = <0x00 0x2430000 0x00 0x400>; + interrupts = ; + clocks = <&scmi_clk 82>; + clock-names = "fck"; + power-domains = <&scmi_pds 18>; + ti,timer-pwm; + }; + + uart0: serial@2800000 { + compatible = "ti,am64-uart", "ti,am654-uart"; + reg = <0x00 0x02800000 0x00 0x100>; + interrupts = ; + power-domains = <&scmi_pds 89>; + clocks = <&scmi_clk 358>; + clock-names = "fclk"; + status = "disabled"; + }; + + uart1: serial@2810000 { + compatible = "ti,am64-uart", "ti,am654-uart"; + reg = <0x00 0x02810000 0x00 0x100>; + interrupts = ; + power-domains = <&scmi_pds 77>; + clocks = <&scmi_clk 312>; + clock-names = "fclk"; + status = "disabled"; + }; + + uart2: serial@2820000 { + compatible = "ti,am64-uart", "ti,am654-uart"; + reg = <0x00 0x02820000 0x00 0x100>; + interrupts = ; + power-domains = <&scmi_pds 78>; + clocks = <&scmi_clk 314>; + clock-names = "fclk"; + status = "disabled"; + }; + + uart3: serial@2830000 { + compatible = "ti,am64-uart", "ti,am654-uart"; + reg = <0x00 0x02830000 0x00 0x100>; + interrupts = ; + power-domains = <&scmi_pds 79>; + clocks = <&scmi_clk 316>; + clock-names = "fclk"; + status = "disabled"; + }; + + uart4: serial@2840000 { + compatible = "ti,am64-uart", "ti,am654-uart"; + reg = <0x00 0x02840000 0x00 0x100>; + interrupts = ; + power-domains = <&scmi_pds 80>; + clocks = <&scmi_clk 318>; + clock-names = "fclk"; + status = "disabled"; + }; + + uart5: serial@2850000 { + compatible = "ti,am64-uart", "ti,am654-uart"; + reg = <0x00 0x02850000 0x00 0x100>; + interrupts = ; + power-domains = <&scmi_pds 81>; + clocks = <&scmi_clk 320>; + clock-names = "fclk"; + status = "disabled"; + }; + + uart6: serial@2860000 { + compatible = "ti,am64-uart", "ti,am654-uart"; + reg = <0x00 0x02860000 0x00 0x100>; + interrupts = ; + power-domains = <&scmi_pds 82>; + clocks = <&scmi_clk 322>; + clock-names = "fclk"; + status = "disabled"; + }; + + conf: bus@9000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00 0x00 0x09000000 0x380000>; + + phy_gmii_sel: phy@1be000 { + compatible = "ti,am654-phy-gmii-sel"; + reg = <0x1be000 0x8>; + #phy-cells = <1>; + }; + + epwm_tbclk: clock-controller@1e9100 { + compatible = "ti,am62-epwm-tbclk"; + reg = <0x1e9100 0x4>; + #clock-cells = <1>; + }; + }; + + usbss0: dwc3-usb@f900000 { + compatible = "ti,am62-usb"; + reg = <0x00 0x0f900000 0x00 0x800>, + <0x00 0x0f908000 0x00 0x400>; + clocks = <&scmi_clk 331>; + clock-names = "ref"; + ti,syscon-phy-pll-refclk = <&usb_phy_ctrl 0x0>; + #address-cells = <2>; + #size-cells = <2>; + power-domains = <&scmi_pds 95>; + ranges; + status = "disabled"; + + usb0: usb@31000000 { + compatible = "snps,dwc3"; + reg = <0x00 0x31000000 0x00 0x50000>; + interrupts = , /* irq.0 */ + ; /* irq.0 */ + interrupt-names = "host", "peripheral"; + maximum-speed = "high-speed"; + dr_mode = "otg"; + snps,usb2-gadget-lpm-disable; + snps,usb2-lpm-disable; + }; + }; + + usbss1: dwc3-usb@f910000 { + compatible = "ti,am62-usb"; + reg = <0x00 0x0f910000 0x00 0x800>, + <0x00 0x0f918000 0x00 0x400>; + clocks = <&scmi_clk 338>; + clock-names = "ref"; + ti,syscon-phy-pll-refclk = <&usb_phy_ctrl 0x4>; + #address-cells = <2>; + #size-cells = <2>; + power-domains = <&scmi_pds 96>; + ranges; + status = "disabled"; + + usb1: usb@31100000 { + compatible = "snps,dwc3"; + reg = <0x00 0x31100000 0x00 0x50000>; + interrupts = , /* irq.0 */ + ; /* irq.0 */ + interrupt-names = "host", "peripheral"; + maximum-speed = "high-speed"; + dr_mode = "otg"; + snps,usb2-gadget-lpm-disable; + snps,usb2-lpm-disable; + }; + }; + + sdhci1: mmc@fa00000 { + compatible = "ti,j721e-sdhci-4bit"; + reg = <0x00 0x0fa00000 0x00 0x1000>, + <0x00 0x0fa08000 0x00 0x400>; + interrupts = ; + power-domains = <&scmi_pds 26>; + clocks = <&scmi_clk 106>, <&scmi_clk 109>; + clock-names = "clk_ahb", "clk_xin"; + assigned-clocks = <&scmi_clk 109>; + bus-width = <4>; + ti,clkbuf-sel = <0x7>; + ti,otap-del-sel-legacy = <0x0>; + ti,itap-del-sel-legacy = <0x0>; + status = "disabled"; + }; + + sdhci0: mmc@fa10000 { + compatible = "ti,am62-sdhci"; + reg = <0x00 0xfa10000 0x00 0x1000>, + <0x00 0xfa18000 0x00 0x400>; + interrupts = ; + power-domains = <&scmi_pds 28>; + clocks = <&scmi_clk 122>, <&scmi_clk 125>; + clock-names = "clk_ahb", "clk_xin"; + assigned-clocks = <&scmi_clk 125>; + bus-width = <8>; + ti,clkbuf-sel = <0x7>; + ti,otap-del-sel-legacy = <0x0>; + ti,otap-del-sel-mmc-hs = <0x0>; + ti,otap-del-sel-hs200 = <0x6>; + status = "disabled"; + }; + + sdhci2: mmc@fa20000 { + compatible = "ti,am62-sdhci"; + reg = <0x00 0x0fa20000 0x00 0x1000>, + <0x00 0x0fa28000 0x00 0x400>; + interrupts = ; + power-domains = <&scmi_pds 27>; + clocks = <&scmi_clk 114>, <&scmi_clk 117>; + clock-names = "clk_ahb", "clk_xin"; + assigned-clocks = <&scmi_clk 117>; + bus-width = <4>; + ti,clkbuf-sel = <0x7>; + ti,otap-del-sel-legacy = <0x0>; + ti,itap-del-sel-legacy = <0x0>; + status = "disabled"; + }; + + i2c0: i2c@20000000 { + compatible = "ti,am64-i2c", "ti,omap4-i2c"; + reg = <0x00 0x20000000 0x00 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 53>; + clocks = <&scmi_clk 246>; + clock-names = "fck"; + status = "disabled"; + }; + + i2c1: i2c@20010000 { + compatible = "ti,am64-i2c", "ti,omap4-i2c"; + reg = <0x00 0x20010000 0x00 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 54>; + clocks = <&scmi_clk 250>; + clock-names = "fck"; + status = "disabled"; + }; + + i2c2: i2c@20020000 { + compatible = "ti,am64-i2c", "ti,omap4-i2c"; + reg = <0x00 0x20020000 0x00 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 55>; + clocks = <&scmi_clk 254>; + clock-names = "fck"; + status = "disabled"; + }; + + i2c3: i2c@20030000 { + compatible = "ti,am64-i2c", "ti,omap4-i2c"; + reg = <0x00 0x20030000 0x00 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 56>; + clocks = <&scmi_clk 258>; + clock-names = "fck"; + status = "disabled"; + }; + + mcan0: can@20701000 { + compatible = "bosch,m_can"; + reg = <0x00 0x20701000 0x00 0x200>, + <0x00 0x20708000 0x00 0x8000>; + reg-names = "m_can", "message_ram"; + power-domains = <&scmi_pds 47>; + clocks = <&scmi_clk 179>, <&scmi_clk 178>; + clock-names = "hclk", "cclk"; + interrupts = , + ; + interrupt-names = "int0", "int1"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; + status = "disabled"; + }; + + mcan1: can@20711000 { + compatible = "bosch,m_can"; + reg = <0x00 0x20711000 0x00 0x200>, + <0x00 0x20718000 0x00 0x8000>; + reg-names = "m_can", "message_ram"; + power-domains = <&scmi_pds 48>; + clocks = <&scmi_clk 185>, <&scmi_clk 184>; + clock-names = "hclk", "cclk"; + interrupts = , + ; + interrupt-names = "int0", "int1"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; + status = "disabled"; + }; + + mcan2: can@20721000 { + compatible = "bosch,m_can"; + reg = <0x00 0x20721000 0x00 0x200>, + <0x00 0x20728000 0x00 0x8000>; + reg-names = "m_can", "message_ram"; + power-domains = <&scmi_pds 49>; + clocks = <&scmi_clk 191>, <&scmi_clk 190>; + clock-names = "hclk", "cclk"; + interrupts = , + ; + interrupt-names = "int0", "int1"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; + status = "disabled"; + }; + + spi0: spi@20100000 { + compatible = "ti,am654-mcspi", "ti,omap4-mcspi"; + reg = <0x00 0x20100000 0x00 0x400>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 72>; + clocks = <&scmi_clk 299>; + status = "disabled"; + }; + + spi1: spi@20110000 { + compatible = "ti,am654-mcspi","ti,omap4-mcspi"; + reg = <0x00 0x20110000 0x00 0x400>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 73>; + clocks = <&scmi_clk 302>; + status = "disabled"; + }; + + spi2: spi@20120000 { + compatible = "ti,am654-mcspi","ti,omap4-mcspi"; + reg = <0x00 0x20120000 0x00 0x400>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 74>; + clocks = <&scmi_clk 305>; + status = "disabled"; + }; + + spi3: spi@20130000 { + compatible = "ti,am654-mcspi","ti,omap4-mcspi"; + reg = <0x00 0x20130000 0x00 0x400>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 75>; + clocks = <&scmi_clk 308>; + status = "disabled"; + }; + + epwm0: pwm@23000000 { + compatible = "ti,am64-epwm", "ti,am3352-ehrpwm"; + reg = <0x00 0x23000000 0x00 0x100>; + power-domains = <&scmi_pds 40>; + clocks = <&epwm_tbclk 0>, <&scmi_clk 164>; + clock-names = "tbclk", "fck"; + #pwm-cells = <3>; + status = "disabled"; + }; + + epwm1: pwm@23010000 { + compatible = "ti,am64-epwm", "ti,am3352-ehrpwm"; + reg = <0x00 0x23010000 0x00 0x100>; + power-domains = <&scmi_pds 41>; + clocks = <&epwm_tbclk 1>, <&scmi_clk 165>; + clock-names = "tbclk", "fck"; + #pwm-cells = <3>; + status = "disabled"; + }; + + epwm2: pwm@23020000 { + compatible = "ti,am64-epwm", "ti,am3352-ehrpwm"; + reg = <0x00 0x23020000 0x00 0x100>; + power-domains = <&scmi_pds 42>; + clocks = <&epwm_tbclk 2>, <&scmi_clk 166>; + clock-names = "tbclk", "fck"; + #pwm-cells = <3>; + status = "disabled"; + }; + + ecap0: pwm@23100000 { + compatible = "ti,am3352-ecap"; + reg = <0x00 0x23100000 0x00 0x100>; + power-domains = <&scmi_pds 23>; + clocks = <&scmi_clk 99>; + clock-names = "fck"; + #pwm-cells = <3>; + status = "disabled"; + }; + + ecap1: pwm@23110000 { + compatible = "ti,am3352-ecap"; + reg = <0x00 0x23110000 0x00 0x100>; + power-domains = <&scmi_pds 24>; + clocks = <&scmi_clk 100>; + clock-names = "fck"; + #pwm-cells = <3>; + status = "disabled"; + }; + + ecap2: pwm@23120000 { + compatible = "ti,am3352-ecap"; + reg = <0x00 0x23120000 0x00 0x100>; + power-domains = <&scmi_pds 25>; + clocks = <&scmi_clk 101>; + clock-names = "fck"; + #pwm-cells = <3>; + status = "disabled"; + }; + + eqep0: counter@23200000 { + compatible = "ti,am62-eqep"; + reg = <0x00 0x23200000 0x00 0x100>; + power-domains = <&scmi_pds 29>; + clocks = <&scmi_clk 127>; + interrupts = ; + status = "disabled"; + }; + + eqep1: counter@23210000 { + compatible = "ti,am62-eqep"; + reg = <0x00 0x23210000 0x00 0x100>; + power-domains = <&scmi_pds 30>; + clocks = <&scmi_clk 128>; + interrupts = ; + status = "disabled"; + }; + + eqep2: counter@23220000 { + compatible = "ti,am62-eqep"; + reg = <0x00 0x23220000 0x00 0x100>; + power-domains = <&scmi_pds 31>; + clocks = <&scmi_clk 129>; + interrupts = ; + status = "disabled"; + }; + + elm0: ecc@25010000 { + compatible = "ti,am64-elm"; + reg = <0x00 0x25010000 0x00 0x2000>; + interrupts = ; + power-domains = <&scmi_pds 25>; + clocks = <&scmi_clk 102>; + clock-names = "fck"; + status = "disabled"; + }; + + gpmc0: memory-controller@3b000000 { + compatible = "ti,am64-gpmc"; + power-domains = <&scmi_pds 37>; + clocks = <&scmi_clk 149>; + clock-names = "fck"; + reg = <0x00 0x3b000000 0x00 0x400>, + <0x00 0x50000000 0x00 0x8000000>; + reg-names = "cfg", "data"; + interrupts = ; + gpmc,num-cs = <3>; + gpmc,num-waitpins = <2>; + #address-cells = <2>; + #size-cells = <1>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + oc_sram: sram@70800000 { + compatible = "mmio-sram"; + reg = <0x00 0x70800000 0x00 0x10000>; + ranges = <0x00 0x00 0x70800000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + scmi_shmem: sram@0 { + compatible = "arm,scmi-shmem"; + reg = <0x00 0x100>; + bootph-all; + }; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi new file mode 100644 index 0000000000000..61bfcdcfc66ea --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0-only or MIT +/* + * Device Tree file for the AM62L wakeup domain peripherals + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ + * + * Technical Reference Manual: https://www.ti.com/lit/pdf/sprujb4 + */ + +#include + +&cbass_wakeup { + vtm0: temperature-sensor@b00000 { + compatible = "ti,j7200-vtm"; + reg = <0x00 0xb00000 0x00 0x400>, + <0x00 0xb01000 0x00 0x400>; + power-domains = <&scmi_pds 46>; + #thermal-sensor-cells = <1>; + }; + + pmx0: pinctrl@4084000 { + compatible = "ti,am62l-padconf", "pinctrl-single"; + reg = <0x00 0x4084000 0x00 0x24c>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + #pinctrl-cells = <1>; + }; + + wkup_gpio0: gpio@4201000 { + compatible = "ti,am64-gpio", "ti,keystone-gpio"; + reg = <0x00 0x04201000 0x00 0x100>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gic500>; + interrupts = , + , + , + , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + power-domains = <&scmi_pds 36>; + clocks = <&scmi_clk 146>; + clock-names = "gpio"; + ti,ngpio = <7>; + ti,davinci-gpio-unbanked = <0>; + status = "disabled"; + }; + + wkup_timer0: timer@2b100000 { + compatible = "ti,am654-timer"; + reg = <0x00 0x2b100000 0x00 0x400>; + interrupts = ; + clocks = <&scmi_clk 93>; + clock-names = "fck"; + power-domains = <&scmi_pds 19>; + ti,timer-pwm; + }; + + wkup_timer1: timer@2b110000 { + compatible = "ti,am654-timer"; + reg = <0x00 0x2b110000 0x00 0x400>; + interrupts = ; + clocks = <&scmi_clk 98>; + clock-names = "fck"; + power-domains = <&scmi_pds 20>; + ti,timer-pwm; + }; + + wkup_i2c0: i2c@2b200000 { + compatible = "ti,am64-i2c", "ti,omap4-i2c"; + reg = <0x00 0x2b200000 0x00 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 57>; + clocks = <&scmi_clk 262>; + clock-names = "fck"; + status = "disabled"; + }; + + target-module@2b300050 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x00 0x2b300050 0x00 0x4>, + <0x00 0x2b300054 0x00 0x4>, + <0x00 0x2b300058 0x00 0x4>; + reg-names = "rev", "sysc", "syss"; + ranges = <0x00 0x00 0x2b300000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + power-domains = <&scmi_pds 83>; + clocks = <&scmi_clk 324>; + clock-names = "fck"; + ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP | + SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,sysc-sidle = , + , + , + ; + ti,syss-mask = <1>; + ti,no-reset-on-init; + status = "disabled"; + + wkup_uart0: serial@0 { + compatible = "ti,am64-uart", "ti,am654-uart"; + reg = <0x00 0x100>; + interrupts = ; + clocks = <&scmi_clk 324>; + assigned-clocks = <&scmi_clk 324>; + clock-names = "fclk"; + status = "disabled"; + }; + }; + + wkup_conf: bus@43000000 { + compatible = "simple-bus"; + ranges = <0x00 0x00 0x43000000 0x80000>; + #address-cells = <1>; + #size-cells = <1>; + + chipid: chipid@14 { + compatible = "ti,am654-chipid"; + reg = <0x14 0x4>; + bootph-all; + }; + + cpsw_mac_syscon: ethernet-mac-syscon@2000 { + compatible = "ti,am62p-cpsw-mac-efuse", "syscon"; + reg = <0x2000 0x8>; + }; + + usb_phy_ctrl: syscon@45000 { + compatible = "ti,am62-usb-phy-ctrl", "syscon"; + reg = <0x45000 0x1000>; + bootph-all; + }; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am62l.dtsi b/arch/arm64/boot/dts/ti/k3-am62l.dtsi new file mode 100644 index 0000000000000..23acdbb301fe3 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am62l.dtsi @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0-only or MIT +/* + * Device Tree Source for AM62L SoC Family + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ + * + * Technical Reference Manual: https://www.ti.com/lit/pdf/sprujb4 + */ + +#include +#include +#include + +#include "k3-pinctrl.h" + +/ { + model = "Texas Instruments K3 AM62L3 SoC"; + compatible = "ti,am62l3"; + interrupt-parent = <&gic500>; + #address-cells = <2>; + #size-cells = <2>; + + firmware { + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + + psci: psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + scmi: scmi { + compatible = "arm,scmi-smc"; + arm,smc-id = <0x82004000>; + shmem = <&scmi_shmem>; + #address-cells = <1>; + #size-cells = <0>; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + bootph-all; + }; + + scmi_pds: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + bootph-all; + }; + }; + }; + + a53_timer0: timer-cl0-cpu0 { + compatible = "arm,armv8-timer"; + interrupts = , /* cntpsirq */ + , /* cntpnsirq */ + , /* cntvirq */ + ; /* cnthpirq */ + }; + + pmu: pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = ; + }; + + cbass_main: bus@f0000 { + compatible = "simple-bus"; + ranges = <0x00 0x00600000 0x00 0x00600000 0x00 0x00010100>, /* GPIO */ + <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First Peripheral Window */ + <0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000400>, /* Timesync Router */ + <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* CPSW */ + <0x00 0x09000000 0x00 0x09000000 0x00 0x00400000>, /* CTRL MMRs */ + <0x00 0x0e000000 0x00 0x0e000000 0x00 0x1a001400>, /* Second Peripheral Window */ + <0x00 0x301c0000 0x00 0x301c0000 0x00 0x00001000>, /* DPHY-TX */ + <0x00 0x30200000 0x00 0x30200000 0x00 0x0000b000>, /* DSS */ + <0x00 0x30270000 0x00 0x30270000 0x00 0x00390000>, /* DSI Wrapper */ + <0x00 0x30500000 0x00 0x30500000 0x00 0x00100000>, /* DSI Config */ + <0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core Window */ + <0x00 0x31100000 0x00 0x31100000 0x00 0x00050000>, /* USB1 DWC3 Core Window */ + <0x00 0x3b000000 0x00 0x3b000000 0x00 0x00000400>, /* GPMC0 */ + <0x00 0x45810000 0x00 0x45810000 0x00 0x03170000>, /* DMSS */ + <0x00 0x50000000 0x00 0x50000000 0x00 0x08000000>, /* GPMC DATA */ + <0x00 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS DAT1 */ + <0x00 0x70800000 0x00 0x70800000 0x00 0x00018000>, /* OCSRAM */ + <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */ + <0x04 0x00000000 0x04 0x00000000 0x01 0x00000000>, /* FSS DAT0 */ + <0x05 0x00000000 0x05 0x00000000 0x01 0x00000000>, /* FSS DAT3 */ + + /* Wakeup Domain Range */ + <0x00 0x00a80000 0x00 0x00a80000 0x00 0x00034000>, /* GTC */ + <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00001400>, /* VTM */ + <0x00 0x04080000 0x00 0x04080000 0x00 0x00008000>, /* PDCFG */ + <0x00 0x04201000 0x00 0x04201000 0x00 0x00000100>, /* GPIO */ + <0x00 0x2b100000 0x00 0x2b100000 0x00 0x00100100>, /* Wakeup Peripheral Window */ + <0x00 0x40800000 0x00 0x40800000 0x00 0x00014000>, /* DMA */ + <0x00 0x43000000 0x00 0x43000000 0x00 0x00080000>; /* CTRL MMRs */ + #address-cells = <2>; + #size-cells = <2>; + + cbass_wakeup: bus@a80000 { + compatible = "simple-bus"; + ranges = <0x00 0x00a80000 0x00 0x00a80000 0x00 0x00034000>, /* GTC */ + <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00001400>, /* VTM */ + <0x00 0x04080000 0x00 0x04080000 0x00 0x00008000>, /* PDCFG */ + <0x00 0x04201000 0x00 0x04201000 0x00 0x00000100>, /* GPIO */ + <0x00 0x2b100000 0x00 0x2b100000 0x00 0x00100100>, /* Wakeup Peripheral Window */ + <0x00 0x40800000 0x00 0x40800000 0x00 0x00014000>, /* DMA */ + <0x00 0x43000000 0x00 0x43000000 0x00 0x00080000>; /* CTRL MMRs */ + #address-cells = <2>; + #size-cells = <2>; + }; + }; +}; + +/* Now include peripherals for each bus segment */ +#include "k3-am62l-main.dtsi" +#include "k3-am62l-wakeup.dtsi" diff --git a/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts b/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts new file mode 100644 index 0000000000000..cae04cce33736 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts @@ -0,0 +1,361 @@ +// SPDX-License-Identifier: GPL-2.0-only or MIT +/* + * Device Tree file for the AM62L3 Evaluation Module + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ + * + * Technical Reference Manual: https://www.ti.com/lit/pdf/sprujb4 + * Data Sheet: https://www.ti.com/lit/pdf/sprspa1 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include +#include "k3-am62l3.dtsi" +#include "k3-pinctrl.h" + +/ { + compatible = "ti,am62l3-evm", "ti,am62l3"; + model = "Texas Instruments AM62L3 Evaluation Module"; + + chosen { + stdout-path = &uart0; + }; + + memory@80000000 { + reg = <0x00000000 0x80000000 0x00000000 0x80000000>; + device_type = "memory"; + bootph-all; + }; + + gpio_keys: gpio-keys { + compatible = "gpio-keys"; + autorepeat; + pinctrl-names = "default"; + pinctrl-0 = <&usr_button_pins_default>; + + usr: button-usr { + label = "User Key"; + linux,code = ; + gpios = <&gpio0 90 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&usr_led_pins_default>; + + led-0 { + label = "am62-sk:green:heartbeat"; + gpios = <&gpio0 123 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + function = LED_FUNCTION_HEARTBEAT; + default-state = "on"; + }; + }; + + thermal-zones { + wkup0-thermal { + polling-delay-passive = <250>; /* milliSeconds */ + polling-delay = <500>; /* milliSeconds */ + thermal-sensors = <&vtm0 0>; + + trips { + crit0 { + temperature = <125000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; + + vmain_pd: regulator-0 { + /* TPS65988 PD CONTROLLER OUTPUT */ + compatible = "regulator-fixed"; + regulator-name = "vmain_pd"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + bootph-all; + }; + + vcc_3v3_sys: regulator-1 { + /* output of LM61460-Q1 */ + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3_sys"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vmain_pd>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_mmc1: regulator-2 { + /* TPS22918DBVR */ + compatible = "regulator-fixed"; + regulator-name = "vdd_mmc1"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + enable-active-high; + vin-supply = <&vcc_3v3_sys>; + gpio = <&exp1 3 GPIO_ACTIVE_HIGH>; + bootph-all; + }; + + vcc_1v8: regulator-3 { + /* output of TPS6282518DMQ */ + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3_sys>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&gpio0 { + bootph-all; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_default>; + clock-frequency = <400000>; + status = "okay"; + + eeprom@51 { + /* AT24C512C-MAHM-T or M24512-DFMC6TG */ + compatible = "atmel,24c512"; + reg = <0x51>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_default>; + clock-frequency = <100000>; + status = "okay"; + + exp1: gpio@22 { + compatible = "ti,tca6424"; + reg = <0x22>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "", "", + "UART1_FET_SEL", "MMC1_SD_EN", + "VPP_LDO_EN", "EXP_PS_3V3_EN", + "UART1_FET_BUF_EN", "", "", + "", "DSI_GPIO0", "DSI_GPIO1", + "", "BT_UART_WAKE_SOC_3V3", + "USB_TYPEA_OC_INDICATION", "", + "", "WLAN_ALERTn", "", "", + "HDMI_INTn", "TEST_GPIO2", + "MCASP0_FET_EN", "MCASP0_BUF_BT_EN", + "MCASP0_FET_SEL", "DSI_EDID", + "PD_I2C_IRQ", "IO_EXP_TEST_LED"; + + interrupt-parent = <&gpio0>; + interrupts = <91 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_ioexp_intr_pins_default>; + bootph-all; + }; + + exp2: gpio@23 { + compatible = "ti,tca6424"; + reg = <0x23>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "BT_EN_SOC", "VOUT0_FET_SEL0", + "", "", + "", "", + "", "", + "WL_LT_EN", "EXP_PS_5V0_EN", + "TP45", "TP48", + "TP46", "TP49", + "TP47", "TP50", + "GPIO_QSPI_NAND_RSTn", "GPIO_HDMI_RSTn", + "GPIO_CPSW1_RST", "GPIO_CPSW2_RST", + "", "GPIO_AUD_RSTn", + "GPIO_eMMC_RSTn", "SoC_WLAN_SDIO_RST"; + bootph-all; + }; + +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_default>; + clock-frequency = <400000>; + status = "okay"; + + typec_pd0: tps658x@3f { + compatible = "ti,tps6598x"; + reg = <0x3f>; + + connector { + compatible = "usb-c-connector"; + label = "USB-C"; + self-powered; + data-role = "dual"; + power-role = "sink"; + + port { + usb_con_hs: endpoint { + remote-endpoint = <&usb0_hs_ep>; + }; + }; + }; + }; +}; + +&pmx0 { + gpio0_ioexp_intr_pins_default: gpio0-ioexp-intr-default-pins { + pinctrl-single,pins = < + AM62LX_IOPAD(0x01b0, PIN_INPUT, 7) /* (B12) SPI0_D1.GPIO0_91 */ + >; + bootph-all; + }; + + i2c0_pins_default: i2c0-default-pins { + pinctrl-single,pins = < + AM62LX_IOPAD(0x01cc, PIN_INPUT_PULLUP, 0) /* (B7) I2C0_SCL */ + AM62LX_IOPAD(0x01d0, PIN_INPUT_PULLUP, 0) /* (A7) I2C0_SDA */ + >; + bootph-all; + }; + + i2c1_pins_default: i2c1-default-pins { + pinctrl-single,pins = < + AM62LX_IOPAD(0x01d4, PIN_INPUT_PULLUP, 0) /* (D7) I2C1_SCL */ + AM62LX_IOPAD(0x01d8, PIN_INPUT_PULLUP, 0) /* (A6) I2C1_SDA */ + >; + bootph-all; + }; + + i2c2_pins_default: i2c2-default-pins { + pinctrl-single,pins = < + AM62LX_IOPAD(0x01dc, PIN_INPUT_PULLUP, 0) /* (B8) I2C2_SCL */ + AM62LX_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (D8) I2C2_SDA */ + >; + }; + + mmc0_pins_default: mmc0-default-pins { + pinctrl-single,pins = < + AM62LX_IOPAD(0x0214, PIN_INPUT_PULLUP, 0) /* (D2) MMC0_CMD */ + AM62LX_IOPAD(0x020c, PIN_OUTPUT, 0) /* (B2) MMC0_CLK */ + AM62LX_IOPAD(0x0208, PIN_INPUT_PULLUP, 0) /* (D3) MMC0_DAT0 */ + AM62LX_IOPAD(0x0204, PIN_INPUT_PULLUP, 0) /* (D4) MMC0_DAT1 */ + AM62LX_IOPAD(0x0200, PIN_INPUT_PULLUP, 0) /* (C1) MMC0_DAT2 */ + AM62LX_IOPAD(0x01fc, PIN_INPUT_PULLUP, 0) /* (C2) MMC0_DAT3 */ + AM62LX_IOPAD(0x01f8, PIN_INPUT_PULLUP, 0) /* (C4) MMC0_DAT4 */ + AM62LX_IOPAD(0x01f4, PIN_INPUT_PULLUP, 0) /* (B3) MMC0_DAT5 */ + AM62LX_IOPAD(0x01f0, PIN_INPUT_PULLUP, 0) /* (A3) MMC0_DAT6 */ + AM62LX_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (B4) MMC0_DAT7 */ + >; + bootph-all; + }; + + mmc1_pins_default: mmc1-default-pins { + pinctrl-single,pins = < + AM62LX_IOPAD(0x0230, PIN_INPUT, 0) /* (Y3) MMC1_CMD */ + AM62LX_IOPAD(0x0228, PIN_OUTPUT, 0) /* (Y2) MMC1_CLK */ + AM62LX_IOPAD(0x0224, PIN_INPUT, 0) /* (AA1) MMC1_DAT0 */ + AM62LX_IOPAD(0x0220, PIN_INPUT_PULLUP, 0) /* (Y4) MMC1_DAT1 */ + AM62LX_IOPAD(0x021c, PIN_INPUT_PULLUP, 0) /* (AA2) MMC1_DAT2 */ + AM62LX_IOPAD(0x0218, PIN_INPUT_PULLUP, 0) /* (AB2) MMC1_DAT3 */ + AM62LX_IOPAD(0x0234, PIN_INPUT, 0) /* (B6) MMC1_SDCD */ + >; + bootph-all; + }; + + uart0_pins_default: uart0-default-pins { + pinctrl-single,pins = < + AM62LX_IOPAD(0x01b4, PIN_INPUT, 0) /* (D13) UART0_RXD */ + AM62LX_IOPAD(0x01b8, PIN_OUTPUT, 0) /* (C13) UART0_TXD */ + >; + bootph-all; + }; + + usb1_default_pins: usb1-default-pins { + pinctrl-single,pins = < + AM62LX_IOPAD(0x0248, PIN_INPUT | PIN_DS_PULLUD_ENABLE | PIN_DS_PULL_UP, 0) /* (A5) USB1_DRVVBUS */ + >; + }; + + usr_button_pins_default: usr-button-default-pins { + pinctrl-single,pins = < + AM62LX_IOPAD(0x01ac, PIN_INPUT, 7) /* (E12) SPI0_D0.GPIO0_90 */ + >; + }; + + usr_led_pins_default: usr-led-default-pins { + pinctrl-single,pins = < + AM62LX_IOPAD(0x0238, PIN_OUTPUT, 7) /* (D24) MMC1_SDWP.GPIO0_123 */ + >; + }; + +}; + +&sdhci0 { + /* eMMC */ + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + non-removable; + status = "okay"; + bootph-all; +}; + +&sdhci1 { + /* SD/MMC */ + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins_default>; + vmmc-supply = <&vdd_mmc1>; + disable-wp; + status = "okay"; + bootph-all; +}; + +&uart0 { + pinctrl-0 = <&uart0_pins_default>; + pinctrl-names = "default"; + status = "okay"; + bootph-all; +}; + +&usbss0 { + status = "okay"; + ti,vbus-divider; +}; + +&usb0 { + usb-role-switch; + + port { + usb0_hs_ep: endpoint { + remote-endpoint = <&usb_con_hs>; + }; + }; +}; + +&usbss1 { + status = "okay"; + ti,vbus-divider; +}; + +&usb1 { + dr_mode = "host"; + pinctrl-names = "default"; + pinctrl-0 = <&usb1_default_pins>; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am62l3.dtsi b/arch/arm64/boot/dts/ti/k3-am62l3.dtsi new file mode 100644 index 0000000000000..da220b8515122 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am62l3.dtsi @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0-only or MIT +/* + * Device Tree file for the AM62L3 SoC family (Dual Core A53) + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ + * + * Technical Reference Manual: https://www.ti.com/lit/pdf/sprujb4 + */ + +/dts-v1/; + +#include "k3-am62l.dtsi" + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu-map { + cluster0: cluster0 { + core0 { + cpu = <&cpu0>; + }; + + core1 { + cpu = <&cpu1>; + }; + }; + }; + + cpu0: cpu@0 { + compatible = "arm,cortex-a53"; + reg = <0x000>; + device_type = "cpu"; + enable-method = "psci"; + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&l2_0>; + }; + + cpu1: cpu@1 { + compatible = "arm,cortex-a53"; + reg = <0x001>; + device_type = "cpu"; + enable-method = "psci"; + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&l2_0>; + }; + }; + + l2_0: l2-cache0 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + cache-size = <0x40000>; + cache-line-size = <64>; + cache-sets = <256>; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi index 0c05bcf1d7768..3cf7c2b3ce2dd 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi @@ -46,6 +46,24 @@ #size-cells = <1>; ranges = <0x00 0x00 0x00100000 0x20000>; + audio_refclk0: clock-controller@82e0 { + compatible = "ti,am62-audio-refclk"; + reg = <0x82e0 0x4>; + clocks = <&k3_clks 157 0>; + assigned-clocks = <&k3_clks 157 0>; + assigned-clock-parents = <&k3_clks 157 16>; + #clock-cells = <0>; + }; + + audio_refclk1: clock-controller@82e4 { + compatible = "ti,am62-audio-refclk"; + reg = <0x82e4 0x4>; + clocks = <&k3_clks 157 18>; + assigned-clocks = <&k3_clks 157 18>; + assigned-clock-parents = <&k3_clks 157 34>; + #clock-cells = <0>; + }; + phy_gmii_sel: phy@4044 { compatible = "ti,am654-phy-gmii-sel"; reg = <0x4044 0x8>; diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi index 908cc0760e7d8..13d32cbff1867 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi @@ -42,26 +42,6 @@ ti,interrupt-ranges = <5 69 35>; }; -&main_conf { - audio_refclk0: clock-controller@82e0 { - compatible = "ti,am62-audio-refclk"; - reg = <0x82e0 0x4>; - clocks = <&k3_clks 157 0>; - assigned-clocks = <&k3_clks 157 0>; - assigned-clock-parents = <&k3_clks 157 16>; - #clock-cells = <0>; - }; - - audio_refclk1: clock-controller@82e4 { - compatible = "ti,am62-audio-refclk"; - reg = <0x82e4 0x4>; - clocks = <&k3_clks 157 18>; - assigned-clocks = <&k3_clks 157 18>; - assigned-clock-parents = <&k3_clks 157 34>; - #clock-cells = <0>; - }; -}; - &main_gpio0 { gpio-ranges = <&main_pmx0 0 0 32>, <&main_pmx0 32 33 38>, <&main_pmx0 70 72 22>; diff --git a/arch/arm64/boot/dts/ti/k3-am62p-verdin-dev.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-verdin-dev.dtsi index 0679d76f31bda..a0d5b15fc1478 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p-verdin-dev.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p-verdin-dev.dtsi @@ -78,7 +78,7 @@ /* Verdin ETH_2_RGMII */ &cpsw_port2 { phy-handle = <&carrier_eth_phy>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62p-verdin-ivy.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-verdin-ivy.dtsi index 317c8818f9ee9..04f13edcb166b 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p-verdin-ivy.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p-verdin-ivy.dtsi @@ -275,7 +275,7 @@ /* Verdin ETH_2_RGMII */ &cpsw_port2 { phy-handle = <&carrier_eth_phy>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62p-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-verdin.dtsi index 99810047614e3..5e050cbb9eaf3 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p-verdin.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p-verdin.dtsi @@ -813,7 +813,7 @@ /* Verdin ETH_1 (On-module PHY) */ &cpsw_port1 { phy-handle = <&som_eth_phy>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi index 75a15c368c11b..e2c01328eb298 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi @@ -44,6 +44,33 @@ interrupts = ; }; + system-idle-states { + system_partial_io: system-partial-io { + compatible = "system-idle-state"; + idle-state-name = "off-wake"; + }; + + system_io_ddr: system-io-ddr { + compatible = "system-idle-state"; + idle-state-name = "mem-deep"; + }; + + system_deep_sleep: system-deep-sleep { + compatible = "system-idle-state"; + idle-state-name = "mem"; + }; + + system_mcu_only: system-mcu-only { + compatible = "system-idle-state"; + idle-state-name = "mem-mcu-active"; + }; + + system_standby: system-standby { + compatible = "system-idle-state"; + idle-state-name = "standby"; + }; + }; + cbass_main: bus@f0000 { compatible = "simple-bus"; #address-cells = <2>; @@ -59,7 +86,7 @@ <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First peripheral window */ <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */ <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */ - <0x00 0x0fd00000 0x00 0x0fd00000 0x00 0x00020000>, /* GPU */ + <0x00 0x0fd80000 0x00 0x0fd80000 0x00 0x00080000>, /* GPU */ <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */ <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */ <0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */ diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts index a064a632680ec..ef719c6334fc0 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts @@ -541,14 +541,14 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy0>; status = "okay"; bootph-all; }; &cpsw_port2 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy1>; status = "okay"; }; @@ -716,12 +716,52 @@ >; bootph-all; }; + + mcu_mcan0_tx_pins_default: mcu-mcan0-tx-default-pins { + pinctrl-single,pins = < + AM62PX_MCU_IOPAD(0x034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */ + >; + }; + + mcu_mcan0_rx_pins_default: mcu-mcan0-rx-default-pins { + pinctrl-single,pins = < + AM62PX_MCU_IOPAD(0x038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */ + >; + }; + + mcu_mcan0_rx_pins_wakeup: mcu-mcan0-rx-wakeup-pins { + pinctrl-single,pins = < + AM62PX_MCU_IOPAD(0x038, PIN_INPUT | PIN_WKUP_EN, 0) /* (B3) MCU_MCAN0_RX */ + >; + }; + + mcu_mcan1_tx_pins_default: mcu-mcan1-tx-default-pins { + pinctrl-single,pins = < + AM62PX_MCU_IOPAD(0x03c, PIN_OUTPUT, 0) /* (E5) MCU_MCAN1_TX */ + >; + }; + + mcu_mcan1_rx_pins_default: mcu-mcan1-rx-default-pins { + pinctrl-single,pins = < + AM62PX_MCU_IOPAD(0x040, PIN_INPUT, 0) /* (D4) MCU_MCAN1_RX */ + >; + }; + + mcu_mcan1_rx_pins_wakeup: mcu-mcan1-rx-wakeup-pins { + pinctrl-single,pins = < + AM62PX_MCU_IOPAD(0x040, PIN_INPUT | PIN_WKUP_EN, 0) /* (D4) MCU_MCAN1_RX */ + >; + }; }; &wkup_uart0 { /* WKUP UART0 is used by DM firmware */ pinctrl-names = "default"; pinctrl-0 = <&wkup_uart0_pins_default>; + wakeup-source = <&system_io_ddr>, + <&system_deep_sleep>, + <&system_mcu_only>, + <&system_standby>; status = "reserved"; bootph-all; }; @@ -763,4 +803,33 @@ status = "okay"; }; +&mcu_mcan0 { + pinctrl-names = "default", "wakeup"; + pinctrl-0 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_default>; + pinctrl-1 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_wakeup>; + wakeup-source = <&system_partial_io>, + <&system_io_ddr>, + <&system_deep_sleep>, + <&system_mcu_only>, + <&system_standby>; +}; + +&mcu_mcan1 { + pinctrl-names = "default", "wakeup"; + pinctrl-0 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_default>; + pinctrl-1 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_wakeup>; + wakeup-source = <&system_partial_io>, + <&system_io_ddr>, + <&system_deep_sleep>, + <&system_mcu_only>, + <&system_standby>; +}; + +&mcu_uart0 { + wakeup-source = <&system_io_ddr>, + <&system_deep_sleep>, + <&system_mcu_only>, + <&system_standby>; +}; + #include "k3-am62p-ti-ipc-firmware.dtsi" diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-var-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62p5-var-som.dtsi index edaa4f99295dc..fc5a3942cde00 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p5-var-som.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p5-var-som.dtsi @@ -63,18 +63,6 @@ no-map; }; - mcu_r5fss0_core0_dma_memory_region: mcu-r5fss-dma-memory-region@9b800000 { - compatible = "shared-dma-pool"; - reg = <0x00 0x9b800000 0x00 0x00100000>; - no-map; - }; - - mcu_r5fss0_core0_memory_region: mcu-r5fss-memory-region@9b900000 { - compatible = "shared-dma-pool"; - reg = <0x00 0x9b900000 0x00 0x00f00000>; - no-map; - }; - wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9c800000 { compatible = "shared-dma-pool"; reg = <0x00 0x9c800000 0x00 0x00100000>; @@ -124,6 +112,38 @@ enable-active-high; regulator-always-on; }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&codec_dai>; + simple-audio-card,format = "dsp_b"; + simple-audio-card,frame-master = <&codec_dai>; + simple-audio-card,name = "wm8904-audio"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "IN1L", "Microphone Jack", + "IN1R", "Microphone Jack"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack", + "Line", "Line In Jack"; + + codec_dai: simple-audio-card,codec { + sound-dai = <&wm8904>; + }; + + simple-audio-card,cpu { + sound-dai = <&mcasp1>; + }; + }; +}; + +&audio_refclk1 { + assigned-clock-rates = <100000000>; }; &cpsw3g { @@ -161,6 +181,19 @@ pinctrl-0 = <&pinctrl_i2c2>; clock-frequency = <400000>; status = "okay"; + + wm8904: audio-codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + #sound-dai-cells = <0>; + clocks = <&audio_refclk1>; + clock-names = "mclk"; + AVDD-supply = <®_1v8>; + CPVDD-supply = <®_1v8>; + DBVDD-supply = <®_3v3>; + DCVDD-supply = <®_1v8>; + MICVDD-supply = <®_1v8>; + }; }; &main_i2c3 { @@ -191,6 +224,16 @@ >; }; + pinctrl_mcasp1: main-mcasp1-default-pins { + pinctrl-single,pins = < + AM62PX_IOPAD(0x0090, PIN_INPUT, 2) /* (U24) GPMC0_BE0n_CLE.MCASP1_ACLKX */ + AM62PX_IOPAD(0x0098, PIN_INPUT, 2) /* (AA24) GPMC0_WAIT0.MCASP1_AFSX */ + AM62PX_IOPAD(0x008c, PIN_OUTPUT, 2) /* (T25) GPMC0_WEn.MCASP1_AXR0 */ + AM62PX_IOPAD(0x0084, PIN_INPUT, 2) /* (R25) GPMC0_ADVn_ALE.MCASP1_AXR2 */ + AM62PX_IOPAD(0x00a0, PIN_OUTPUT, 1) /* (P24) GPMC0_WPn.AUDIO_EXT_REFCLK1 */ + >; + }; + pinctrl_mdio1: main-mdio1-default-pins { pinctrl-single,pins = < AM62PX_IOPAD(0x0160, PIN_OUTPUT, 0) /* (F17) MDIO0_MDC */ @@ -279,6 +322,30 @@ pinctrl-0 = <&pinctrl_spi0>; ti,pindir-d0-out-d1-in; status = "okay"; + + /* Resistive touch controller */ + ads7846: touchscreen@0 { + compatible = "ti,ads7846"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_restouch>; + interrupt-parent = <&main_gpio0>; + interrupts = <48 IRQ_TYPE_EDGE_FALLING>; + spi-max-frequency = <1500000>; + pendown-gpio = <&main_gpio0 48 GPIO_ACTIVE_LOW>; + ti,x-min = /bits/ 16 <125>; + ti,x-max = /bits/ 16 <4008>; + ti,y-min = /bits/ 16 <282>; + ti,y-max = /bits/ 16 <3864>; + ti,x-plate-ohms = /bits/ 16 <180>; + ti,pressure-max = /bits/ 16 <255>; + ti,debounce-max = /bits/ 16 <10>; + ti,debounce-tol = /bits/ 16 <3>; + ti,debounce-rep = /bits/ 16 <1>; + ti,settle-delay-usec = /bits/ 16 <150>; + ti,keep-vref-on; + wakeup-source; + }; }; &main_uart5 { @@ -292,6 +359,23 @@ }; }; +&mcasp1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcasp1>; + op-mode = <0>; /* MCASP_IIS_MODE */ + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 1 0 2 0 + 0 0 0 0 + 0 0 0 0 + 0 0 0 0 + >; + tdm-slots = <2>; + tx-num-evt = <0>; + rx-num-evt = <0>; + #sound-dai-cells = <0>; + status = "okay"; +}; + &sdhci0 { /* On-module eMMC */ ti,driver-strength-ohm = <50>; @@ -320,44 +404,6 @@ ti,vbus-divider; }; -&mailbox0_cluster0 { - status = "okay"; - - mbox_r5_0: mbox-r5-0 { - ti,mbox-rx = <0 0 0>; - ti,mbox-tx = <1 0 0>; - }; -}; - -&mailbox0_cluster1 { - status = "okay"; - - mbox_mcu_r5_0: mbox-mcu-r5-0 { - ti,mbox-rx = <0 0 0>; - ti,mbox-tx = <1 0 0>; - }; -}; - -&mcu_r5fss0 { - status = "okay"; -}; - -&mcu_r5fss0_core0 { - mboxes = <&mailbox0_cluster1 &mbox_mcu_r5_0>; - memory-region = <&mcu_r5fss0_core0_dma_memory_region>, - <&mcu_r5fss0_core0_memory_region>; -}; - -&wkup_r5fss0 { - status = "okay"; -}; - -&wkup_r5fss0_core0 { - mboxes = <&mailbox0_cluster0 &mbox_r5_0>; - memory-region = <&wkup_r5fss0_core0_dma_memory_region>, - <&wkup_r5fss0_core0_memory_region>; -}; - /* mcu_gpio0 and mcu_gpio_intr are reserved for mcu firmware usage */ &mcu_gpio0 { status = "reserved"; @@ -385,3 +431,5 @@ /* Main UART1 is used by TIFS firmware */ status = "reserved"; }; + +#include "k3-am62p-ti-ipc-firmware.dtsi" diff --git a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi index aab74d6019b0a..d6e70ee15938e 100644 --- a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi @@ -291,7 +291,7 @@ }; &cpsw_port2 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy3>; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi index 58f78c0de292d..50ed859ae06c4 100644 --- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi @@ -438,7 +438,7 @@ &cpsw_port1 { bootph-all; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy0>; }; diff --git a/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi index 02ef1dd92eaa8..d64fb81b04e24 100644 --- a/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi @@ -178,7 +178,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy1>; bootph-all; status = "okay"; diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts index 85dcff1049360..88093ab74502c 100644 --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts @@ -579,13 +579,13 @@ &cpsw_port1 { bootph-all; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy0>; status = "okay"; }; &cpsw_port2 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy3>; status = "okay"; }; @@ -608,6 +608,9 @@ /* ADC is reserved for R5 usage */ status = "reserved"; + dmas = <&main_bcdma 0 0x440f 0>, <&main_bcdma 0 0x4410 0>; + dma-names = "fifo0", "fifo1"; + adc { ti,adc-channels = <0 1 2 3 4 5 6 7>; }; diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts index 1fb1b91a1badb..34bfa99bd4b88 100644 --- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts @@ -499,13 +499,13 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy0>; status = "okay"; }; &cpsw_port2 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy1>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts index 8f64d6272b1ba..46be6824dd163 100644 --- a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts +++ b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts @@ -175,6 +175,7 @@ regulator-max-microvolt = <3300000>; gpio = <&main_gpio1 43 GPIO_ACTIVE_HIGH>; enable-active-high; + bootph-all; }; }; @@ -185,7 +186,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy0>; status = "okay"; }; @@ -260,6 +261,7 @@ "", "", "STATUS_OUT_3", "EN_DIG_OUT_4", /* 32-35 */ "", "", "STATUS_OUT_4", "DIG_IN_1", /* 36-39 */ "DIG_IN_2", "DIG_IN_3", "DIG_IN_4"; /* 40- */ + bootph-all; }; &main_gpio1 { @@ -285,6 +287,7 @@ "", "", "", "", /* 60-63 */ "", "", "", "ADC_INT#", /* 64-67 */ "BG95_PWRKEY", "BG95_RESET"; /* 68- */ + bootph-all; line50-hog { /* See also usb0 */ @@ -334,6 +337,7 @@ &main_uart0 { pinctrl-names = "default"; pinctrl-0 = <&main_uart0_pins>; + bootph-pre-ram; status = "okay"; }; @@ -493,6 +497,11 @@ &serdes_ln_ctrl { idle-states = ; + bootph-all; +}; + +&serdes_refclk { + bootph-all; }; &serdes0 { @@ -500,6 +509,7 @@ reg = <0>; #phy-cells = <0>; resets = <&serdes_wiz0 1>; + bootph-all; cdns,num-lanes = <1>; cdns,phy-type = ; }; @@ -512,6 +522,7 @@ cd-gpios = <&main_gpio1 77 GPIO_ACTIVE_LOW>; disable-wp; no-mmc; + bootph-all; ti,fails-without-test-cd; /* Enabled by overlay */ }; @@ -535,9 +546,11 @@ maximum-speed = "super-speed"; phys = <&serdes0_usb_link>; phy-names = "cdns3,usb3-phy"; + bootph-all; }; &usbss0 { + bootph-all; ti,vbus-divider; }; @@ -625,6 +638,7 @@ /* (P19) GPMC0_CSn2.GPIO0_43 - MMC1_CTRL */ AM64X_IOPAD(0x00b0, PIN_OUTPUT, 7) >; + bootph-all; }; main_gpio1_hog_pins: main-gpio1-hog-pins { @@ -748,6 +762,7 @@ /* (#N/A) MMC1_CLKLB */ AM64X_IOPAD(0x0290, PIN_INPUT, 0) >; + bootph-all; }; main_mmc1_reg_pins: main-mmc1-reg-pins { @@ -755,6 +770,7 @@ /* (C13) SPI0_CS1.GPIO1_43 - MMC1_SD_EN */ AM64X_IOPAD(0x020c, PIN_OUTPUT, 7) >; + bootph-all; }; main_mmc1_wifi_pwrseq_pins: main-mmc1-wifi-pwrseq-pins { @@ -797,6 +813,7 @@ /* (C16) UART0_TXD */ AM64X_IOPAD(0x0234, PIN_OUTPUT, 0) >; + bootph-pre-ram; }; main_uart1_pins: main-uart1-pins { @@ -865,6 +882,7 @@ /* (E19) USB0_DRVVBUS */ AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0) >; + bootph-all; }; pru_icssg1_mdio_pins: pru-icssg1-mdio-pins { diff --git a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi index ff3b2e0b8dd45..dde19d0784e31 100644 --- a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi @@ -17,7 +17,7 @@ device_type = "memory"; /* 1G RAM - default variant */ reg = <0x00000000 0x80000000 0x00000000 0x40000000>; - + bootph-pre-ram; }; reserved_memory: reserved-memory { @@ -54,10 +54,15 @@ }; }; +&fss { + bootph-all; +}; + &main_i2c0 { pinctrl-names = "default"; pinctrl-0 = <&main_i2c0_pins>; clock-frequency = <400000>; + bootph-pre-ram; status = "okay"; tmp1075: temperature-sensor@4a { @@ -72,6 +77,7 @@ vcc-supply = <®_1v8>; pagesize = <16>; read-only; + bootph-pre-ram; }; pcf85063: rtc@51 { @@ -89,9 +95,10 @@ }; &ospi0 { - status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&ospi0_pins>; + bootph-all; + status = "okay"; flash@0 { compatible = "jedec,spi-nor"; @@ -99,6 +106,7 @@ spi-tx-bus-width = <8>; spi-rx-bus-width = <8>; spi-max-frequency = <84000000>; + bootph-all; cdns,tshsl-ns = <60>; cdns,tsd2d-ns = <60>; cdns,tchsh-ns = <60>; @@ -121,6 +129,7 @@ disable-wp; no-sdio; no-sd; + bootph-all; ti,driver-strength-ohm = <50>; }; @@ -132,6 +141,7 @@ /* (B18) I2C0_SDA */ AM64X_IOPAD(0x0264, PIN_INPUT_PULLUP, 0) >; + bootph-pre-ram; }; ospi0_pins: ospi0-pins { @@ -159,6 +169,7 @@ /* (N19) OSPI0_DQS */ AM64X_IOPAD(0x0008, PIN_INPUT, 0) >; + bootph-all; }; }; diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi index 42ba3dab2fc1e..a9a4e7401a494 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi @@ -457,10 +457,6 @@ #size-cells = <0>; }; -&mcu_cpsw { - status = "disabled"; -}; - &sdhci1 { status = "okay"; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi index f6d9a57799188..74439e0c16a5a 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi @@ -354,6 +354,8 @@ "tx4", "tx5", "tx6", "tx7", "rx"; + status = "disabled"; + ethernet-ports { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts index 0c42c486d83a4..46c58162eca0d 100644 --- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts +++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts @@ -571,6 +571,7 @@ &mcu_cpsw { pinctrl-names = "default"; pinctrl-0 = <&mcu_cpsw_pins_default>; + status = "okay"; }; &davinci_mdio { @@ -586,7 +587,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&phy0>; }; diff --git a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts index b697035df04e5..5255e04b9ac76 100644 --- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts +++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts @@ -249,7 +249,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy0>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-ads2.dtso b/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-ads2.dtso new file mode 100644 index 0000000000000..ae5e2b52594bb --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-ads2.dtso @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Kontron SMARC-sa67 board on the Kontron Eval Carrier 2.2. + * + * Copyright (c) 2025 Kontron Europe GmbH + */ + +/dts-v1/; +/plugin/; + +#include +#include "k3-pinctrl.h" + +&{/} { + pwm-fan { + compatible = "pwm-fan"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm_fan_pins_default>; + interrupts-extended = <&main_gpio1 7 IRQ_TYPE_EDGE_FALLING>; + #cooling-cells = <2>; + pwms = <&epwm2 1 4000000 0>; + cooling-levels = <1 128 192 255>; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,widgets = + "Headphone", "Headphone Jack", + "Line", "Line Out Jack", + "Microphone", "Microphone Jack", + "Line", "Line In Jack"; + simple-audio-card,routing = + "Line Out Jack", "LINEOUTR", + "Line Out Jack", "LINEOUTL", + "Headphone Jack", "HPOUTR", + "Headphone Jack", "HPOUTL", + "IN1L", "Line In Jack", + "IN1R", "Line In Jack", + "Microphone Jack", "MICBIAS", + "IN2L", "Microphone Jack", + "IN2R", "Microphone Jack"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink0_master>; + simple-audio-card,frame-master = <&dailink0_master>; + + simple-audio-card,cpu { + sound-dai = <&mcasp0>; + }; + + dailink0_master: simple-audio-card,codec { + sound-dai = <&wm8904>; + clocks = <&audio_refclk0>; + }; + }; + + cvcc_1p8v_i2s: regulator-carrier-0 { + compatible = "regulator-fixed"; + regulator-name = "V_1V8_S0_I2S"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + cvcc_1p8v_s0: regulator-carrier-1 { + compatible = "regulator-fixed"; + regulator-name = "V_1V8_S0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + cvcc_3p3v_s0: regulator-carrier-2 { + compatible = "regulator-fixed"; + regulator-name = "V_3V3_S0"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; + +&audio_refclk0 { + status = "okay"; +}; + +&epwm2 { + status = "okay"; +}; + +&main_pmx0 { + pwm_fan_pins_default: pwm-fan-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1ec, PIN_OUTPUT, 8) /* (A22) I2C1_SDA.EHRPWM2_B */ + J722S_IOPAD(0x194, PIN_INPUT, 0) /* (A25) MCASP0_AXR3.GPIO1_7 */ + >; + }; +}; + +&mcasp0 { + #sound-dai-cells = <0>; + status = "okay"; +}; + +&mcu_i2c0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + wm8904: audio-codec@1a { + #sound-dai-cells = <0>; + compatible = "wlf,wm8904"; + reg = <0x1a>; + clocks = <&audio_refclk0>; + clock-names = "mclk"; + AVDD-supply = <&cvcc_1p8v_i2s>; + CPVDD-supply = <&cvcc_1p8v_i2s>; + DBVDD-supply = <&cvcc_1p8v_i2s>; + DCVDD-supply = <&cvcc_1p8v_i2s>; + MICVDD-supply = <&cvcc_1p8v_i2s>; + }; +}; + +&mcu_spi0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <104000000>; + m25p,fast-read; + vcc-supply = <&cvcc_1p8v_s0>; + }; +}; + +&wkup_i2c0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + /* SMARC Carrier EEPROM */ + eeprom@57 { + compatible = "atmel,24c32"; + reg = <0x57>; + pagesize = <32>; + vcc-supply = <&cvcc_3p3v_s0>; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-base.dts b/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-base.dts new file mode 100644 index 0000000000000..7169d934adac5 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-base.dts @@ -0,0 +1,1091 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Kontron SMARC-sAM67 module + * + * Copyright (c) 2025 Kontron Europe GmbH + */ + +/dts-v1/; + +#include +#include +#include +#include "k3-j722s.dtsi" +#include "k3-serdes.h" + +/ { + compatible = "kontron,sa67", "ti,j722s"; + model = "Kontron SMARC-sAM67"; + + aliases { + serial0 = &mcu_uart0; + serial1 = &main_uart0; + serial2 = &main_uart5; + serial3 = &wkup_uart0; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + rtc0 = &wkup_rtc0; + }; + + lcd0_backlight: backlight-1 { + compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <&lcd0_backlight_pins_default>; + pwms = <&epwm1 0 50000 0>; + brightness-levels = <0 32 64 96 128 160 192 224 255>; + default-brightness-level = <8>; + enable-gpios = <&main_gpio0 29 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + + lcd1_backlight: backlight-2 { + compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <&lcd1_backlight_pins_default>; + pwms = <&epwm1 1 50000 0>; + brightness-levels = <0 32 64 96 128 160 192 224 255>; + default-brightness-level = <8>; + enable-gpios = <&main_gpio1 18 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + + chosen { + stdout-path = "serial1:115200n8"; + }; + + connector-1 { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + pinctrl-names = "default"; + pinctrl-0 = <&usb0_connector_pins_default>; + type = "micro"; + id-gpios = <&main_gpio0 34 GPIO_ACTIVE_HIGH>; + vbus-supply = <&vcc_usb0_vbus>; + + port { + usb0_connector: endpoint { + remote-endpoint = <&usb0_hc>; + }; + }; + + }; + + memory@80000000 { + /* Filled in by bootloader */ + reg = <0x00000000 0x00000000 0x00000000 0x00000000>, + <0x00000000 0x00000000 0x00000000 0x00000000>; + device_type = "memory"; + bootph-pre-ram; + }; + + reserved_memory: reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x10000000>; + alignment = <0x2000>; + linux,cma-default; + }; + + secure_tfa_ddr: tfa@9e780000 { + reg = <0x00 0x9e780000 0x00 0x80000>; + no-map; + }; + + secure_ddr: optee@9e800000 { + reg = <0x00 0x9e800000 0x00 0x01800000>; + no-map; + }; + + wkup_r5fss0_core0_memory_region: r5f-memory@a0100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa0100000 0x00 0xf00000>; + no-map; + }; + }; + + vin_5p0: regulator-1 { + compatible = "regulator-fixed"; + regulator-name = "V_3V0_5V25_IN"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + bootph-all; + }; + + vcc_3p3_s5: regulator-2 { + compatible = "regulator-fixed"; + regulator-name = "V_3V3_S5"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vin_5p0>; + regulator-always-on; + regulator-boot-on; + bootph-all; + }; + + vcc_1p8_s5: regulator-3 { + compatible = "regulator-fixed"; + regulator-name = "V_1V8_S5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vin_5p0>; + regulator-always-on; + regulator-boot-on; + bootph-all; + }; + + vcc_3p3_s0: regulator-4 { + compatible = "regulator-fixed"; + regulator-name = "V_3V3_S0"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3p3_s5>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + gpios = <&tps652g1 1 GPIO_ACTIVE_HIGH>; + bootph-all; + }; + + vcc_3p3_sd_s0: regulator-5 { + compatible = "regulator-fixed"; + regulator-name = "SDIO_PWR_EN"; + pinctrl-names = "default"; + pinctrl-0 = <&vcc_3p3_sd_s0_pins_default>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + enable-active-high; + gpios = <&main_gpio0 7 GPIO_ACTIVE_HIGH>; + bootph-all; + }; + + vcc_3p3_sd_vio_s0: regulator-6 { + compatible = "regulator-gpio"; + regulator-name = "V_3V3_1V8_SD_S0"; + pinctrl-names = "default"; + pinctrl-0 = <&vcc_3p3_sd_vio_s0_pins_default>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3p3_s0>; + regulator-boot-on; + enable-gpios = <&main_gpio0 7 GPIO_ACTIVE_HIGH>; + gpios = <&main_gpio0 8 GPIO_ACTIVE_HIGH>; + states = <3300000 0x0>, + <1800000 0x1>; + bootph-all; + }; + + vcc_3p3_cam_s0: regulator-7 { + compatible = "regulator-fixed"; + regulator-name = "V_3V3_CAM_S0"; + pinctrl-names = "default"; + pinctrl-0 = <&vcc_3p3_cam_s0_pins_default>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3p3_s5>; + enable-active-high; + interrupts-extended = <&main_gpio1 30 IRQ_TYPE_EDGE_FALLING>; + bootph-all; + }; + + vcc_1p1_s0: regulator-8 { + compatible = "regulator-fixed"; + regulator-name = "V_1V1_S0"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + vin-supply = <&vcc_1p1_s3>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + /* shared with V_0V75_0V85_CORE_S0 */ + gpios = <&tps652g1 4 GPIO_ACTIVE_HIGH>; + bootph-all; + }; + + vcc_0p85_vcore_s0: regulator-9 { + compatible = "regulator-fixed"; + regulator-name = "V_0V75_0V85_CORE_S0"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + vin-supply = <&vin_5p0>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + gpios = <&tps652g1 4 GPIO_ACTIVE_HIGH>; + bootph-all; + }; + + vcc_lcd0_panel: regulator-10 { + compatible = "regulator-fixed"; + regulator-name = "LCD0_VDD_EN"; + pinctrl-names = "default"; + pinctrl-0 = <&vcc_lcd0_panel_pins_default>; + enable-active-high; + gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>; + }; + + vcc_lcd1_panel: regulator-11 { + compatible = "regulator-fixed"; + regulator-name = "LCD1_VDD_EN"; + pinctrl-names = "default"; + pinctrl-0 = <&vcc_lcd1_panel_pins_default>; + enable-active-high; + gpios = <&main_gpio1 19 GPIO_ACTIVE_HIGH>; + }; + + vcc_usb0_vbus: regulator-12 { + compatible = "regulator-fixed"; + regulator-name = "USB0_EN_OC#"; + pinctrl-names = "default"; + pinctrl-0 = <&vcc_usb0_vbus_pins_default>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpios = <&main_gpio1 50 GPIO_ACTIVE_HIGH>; + }; +}; + +&audio_refclk0 { + pinctrl-names = "default"; + pinctrl-0 = <&audio_refclk0_pins_default>; + status = "disabled"; +}; + +&audio_refclk1 { + pinctrl-names = "default"; + pinctrl-0 = <&audio_refclk1_pins_default>; + status = "disabled"; +}; + +&cpsw3g { + pinctrl-names = "default"; + pinctrl-0 = <&cpsw3g_pins_default>, <&rgmii1_pins_default>, + <&rgmii2_pins_default>; + status = "okay"; +}; + +&cpsw3g_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&cpsw3g_mdio_pins_default>; + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + +&cpsw_port1 { + phy-connection-type = "rgmii-id"; + phy-handle = <&phy0>; + nvmem-cells = <&base_mac_address 0>; + nvmem-cell-names = "mac-address"; + status = "okay"; +}; + +&main_gpio0 { + gpio-line-names = + "", "", "", "", "", "", "", "SOC_SDIO_PWR_EN", "VSD_SEL", + "RESET_OUT#", "I2C_MUX_RST#", "SPI_FLASH_CS#", "QPSI_CS0#", + "QSPI_CS1#", "BOOT_SEL1", "BRDCFG0", "BRDCFG1", "BRDCFG2", + "BRDCFG3", "BRDCFG4", "", "BRDREV0", "BRDREV1", "", "", "", "", + "", "", "LCD0_BKLT_EN", "LCD0_VDD_EN", "GBE_INT#", "DSI0_TE", + "CHARGING#", "USB0_OTG_ID", "PMIC_INT#", "RTC_INT#", + "EDP_BRIDGE_EN", "EDP_BRIDGE_IRQ#", "", "CHARGER_PRSNT#", "", + "", "", "", "BOOT_SEL2#", "CAM2_RST#", "CAM2_PWR#", "", + "CAM3_RST#", "CAM3_PWR#", "GPIO0", "GPIO1", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "GPIO10", "GPIO11", + "SLEEP#", "LID#"; + + bootph-all; + status = "okay"; +}; + +&main_gpio1 { + gpio-line-names = + "", "", "", "", "", "", "", "GPIO6", "GPIO7", "", "", "", "", + "GPIO8", "GPIO9", "PCIE_A_RST#", "", "BATLOW#", "LCD1_BKLT_EN", + "LCD1_VDD_EN", "", "", "", "", "GPIO2", "GPIO3", "", "", + "GPIO4", "GPIO5", "CAM_S0_FAULT#", "BOOT_SEL0#", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "SDIO_CD#", "", + "USB0_DRVVBUS", "USB1_DRVVBUS"; + + bootph-all; + status = "okay"; +}; + +/* I2C_LOCAL */ +&main_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c0_pins_default>; + clock-frequency = <100000>; + bootph-all; + status = "okay"; + + tps652g1: pmic@44 { + compatible = "ti,tps652g1"; + reg = <0x44>; + ti,primary-pmic; + system-power-controller; + + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "LPM_EN#", "EN_3V3_S0", "POWER_BTN#", "CARRIER_STBY#", + "EN_0V75_0V85_VCORE_S0", "PMIC_WAKEUP"; + + pinctrl-names = "default"; + pinctrl-0 = <&pmic_irq_pins_default>; + interrupts-extended = <&main_gpio0 35 IRQ_TYPE_EDGE_FALLING>; + + buck1-supply = <&vin_5p0>; + buck2-supply = <&vin_5p0>; + buck3-supply = <&vin_5p0>; + buck4-supply = <&vin_5p0>; + ldo1-supply = <&vin_5p0>; + ldo2-supply = <&vin_5p0>; + ldo3-supply = <&vin_5p0>; + + bootph-all; + + regulators { + vcc_0p85_s0: buck1 { + regulator-name = "V_0V85_S0"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-boot-on; + regulator-always-on; + }; + + vcc_1p1_s3: buck2 { + regulator-name = "V_1V1_S3"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-boot-on; + regulator-always-on; + }; + + vcc_1p8_s0: buck3 { + regulator-name = "V_1V8_S0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + vcc_1p2_s0: buck4 { + regulator-name = "V_1V2_S0"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-boot-on; + regulator-always-on; + }; + + vcc_1p8_vda_pll_s0: ldo1 { + regulator-name = "V_1V8_VDA_PLL_S0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + vcc_1p8_s3: ldo2 { + regulator-name = "V_1V8_S3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + vcc_1p8_ret_s5: ldo3 { + regulator-name = "V_1V8_RET_S5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + system-controller@4a { + compatible = "kontron,sa67mcu", "kontron,sl28cpld"; + reg = <0x4a>; + #address-cells = <1>; + #size-cells = <0>; + + watchdog@4 { + compatible = "kontron,sa67mcu-wdt", "kontron,sl28cpld-wdt"; + reg = <0x4>; + kontron,assert-wdt-timeout-pin; + }; + + hwmon@8 { + compatible = "kontron,sa67mcu-hwmon"; + reg = <0x8>; + }; + }; +}; + +/* I2C_CAM */ +&main_i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c2_pins_default>; + clock-frequency = <100000>; + status = "okay"; + + i2c-mux@70 { + compatible = "nxp,pca9546"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-names = "default"; + pinctrl-0 = <&i2c_mux_pins_default>; + + vdd-supply = <&vcc_1p8_s0>; + reset-gpios = <&main_gpio0 10 GPIO_ACTIVE_LOW>; + + i2c_cam0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + i2c_cam1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + i2c_cam2: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + i2c_cam3: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + }; +}; + +/* I2C_LCD */ +&main_i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c3_pins_default>; + clock-frequency = <100000>; + status = "okay"; +}; + +&main_pmx0 { + audio_refclk0_pins_default: audio-refclk0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0c4, PIN_OUTPUT, 5) /* (W23) VOUT0_DATA3.AUDIO_EXT_REFCLK0 */ + >; + }; + + audio_refclk1_pins_default: audio-refclk1-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0a0, PIN_OUTPUT, 1) /* (N24) GPMC0_WPn.AUDIO_EXT_REFCLK1 */ + >; + }; + + cpsw3g_mdio_pins_default: cpsw3g-mdio-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x160, PIN_OUTPUT, 0) /* (AC24) MDIO0_MDC */ + J722S_IOPAD(0x15c, PIN_INPUT, 0) /* (AD25) MDIO0_MDIO */ + >; + }; + + cpsw3g_pins_default: cpsw3g-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1b8, PIN_OUTPUT, 1) /* (C20) SPI0_CS1.CP_GEMAC_CPTS0_TS_COMP */ + >; + }; + + edp_bridge_pins_default: edp-bridge-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x098, PIN_OUTPUT, 7) /* (V21) GPMC0_WAIT0.GPIO0_37 */ + J722S_IOPAD(0x09c, PIN_INPUT, 7) /* (W26) GPMC0_WAIT1.GPIO0_38 */ + >; + }; + + i2c_mux_pins_default: i2c-mux-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x028, PIN_OUTPUT, 7) /* (M27) OSPI0_D7.GPIO0_10 */ + >; + }; + + lcd0_backlight_pins_default: lcd0-backlight-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x074, PIN_OUTPUT, 7) /* (V22) GPMC0_AD14.GPIO0_29 */ + J722S_IOPAD(0x110, PIN_OUTPUT, 4) /* (G27) MMC2_DAT1.EHRPWM1_A */ + >; + }; + + lcd1_backlight_pins_default: lcd1-backlight-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1c0, PIN_OUTPUT, 7) /* (E19) SPI0_D0.GPIO1_18 */ + J722S_IOPAD(0x114, PIN_OUTPUT, 4) /* (G26) MMC2_DAT0.EHRPWM1_B */ + >; + }; + + main_i2c0_pins_default: main-i2c0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1e0, PIN_INPUT, 0) /* (D23) I2C0_SCL */ + J722S_IOPAD(0x1e4, PIN_INPUT, 0) /* (B22) I2C0_SDA */ + >; + bootph-all; + }; + + main_i2c2_pins_default: main-i2c2-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0b0, PIN_INPUT, 1) /* (P22) GPMC0_CSn2.I2C2_SCL */ + J722S_IOPAD(0x0b4, PIN_INPUT, 1) /* (P23) GPMC0_CSn3.I2C2_SDA */ + >; + }; + + main_i2c3_pins_default: main-i2c3-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1d0, PIN_INPUT, 2) /* (E22) UART0_CTSn.I2C3_SCL */ + J722S_IOPAD(0x1d4, PIN_INPUT, 2) /* (B21) UART0_RTSn.I2C3_SDA */ + >; + }; + + main_i2c4_pins_default: main-i2c4-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0a8, PIN_INPUT, 1) /* (R27) GPMC0_CSn0.I2C4_SCL */ + J722S_IOPAD(0x0ac, PIN_INPUT, 1) /* (P21) GPMC0_CSn1.I2C4_SDA */ + >; + }; + + main_uart0_pins_default: main-uart0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1c8, PIN_INPUT, 0) /* (F19) UART0_RXD */ + J722S_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (F20) UART0_TXD */ + >; + bootph-all; + }; + + main_uart5_pins_default: main-uart5-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x108, PIN_INPUT, 3) /* (J27) MMC2_DAT3.UART5_RXD */ + J722S_IOPAD(0x10c, PIN_OUTPUT, 3) /* (H27) MMC2_DAT2.UART5_TXD */ + J722S_IOPAD(0x008, PIN_INPUT, 5) /* (L22) OSPI0_DQS.UART5_CTSn */ + J722S_IOPAD(0x004, PIN_OUTPUT, 5) /* (L23) OSPI0_LBCLKO.UART5_RTSn */ + >; + }; + + mcasp0_pins_default: mcasp0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1a4, PIN_INPUT, 0) /* (D25) MCASP0_ACLKX */ + J722S_IOPAD(0x1a8, PIN_INPUT, 0) /* (C26) MCASP0_AFSX */ + J722S_IOPAD(0x1a0, PIN_INPUT, 0) /* (F23) MCASP0_AXR0 */ + J722S_IOPAD(0x19c, PIN_OUTPUT, 0) /* (B25) MCASP0_AXR1 */ + >; + }; + + mcasp2_pins_default: mcasp2-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x070, PIN_INPUT, 3) /* (V24) GPMC0_AD13.MCASP2_ACLKX */ + J722S_IOPAD(0x06c, PIN_INPUT, 3) /* (V26) GPMC0_AD12.MCASP2_AFSX */ + J722S_IOPAD(0x05c, PIN_INPUT, 3) /* (U27) GPMC0_AD8.MCASP2_AXR0 */ + J722S_IOPAD(0x060, PIN_OUTPUT, 3) /* (U26) GPMC0_AD9.MCASP2_AXR1 */ + >; + }; + + oldi0_pins_default: oldi0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x260, PIN_OUTPUT, 0) /* (AF23) OLDI0_A0N */ + J722S_IOPAD(0x25c, PIN_OUTPUT, 0) /* (AG24) OLDI0_A0P */ + J722S_IOPAD(0x268, PIN_OUTPUT, 0) /* (AG22) OLDI0_A1N */ + J722S_IOPAD(0x264, PIN_OUTPUT, 0) /* (AG23) OLDI0_A1P */ + J722S_IOPAD(0x270, PIN_OUTPUT, 0) /* (AB20) OLDI0_A2N */ + J722S_IOPAD(0x26c, PIN_OUTPUT, 0) /* (AB21) OLDI0_A2P */ + J722S_IOPAD(0x278, PIN_OUTPUT, 0) /* (AG20) OLDI0_A3N */ + J722S_IOPAD(0x274, PIN_OUTPUT, 0) /* (AG21) OLDI0_A3P */ + J722S_IOPAD(0x2a0, PIN_OUTPUT, 0) /* (AF21) OLDI0_CLK0N */ + J722S_IOPAD(0x29c, PIN_OUTPUT, 0) /* (AE20) OLDI0_CLK0P */ + >; + }; + + oldi1_pins_default: oldi1-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x280, PIN_OUTPUT, 0) /* (AD21) OLDI0_A4N */ + J722S_IOPAD(0x27c, PIN_OUTPUT, 0) /* (AC21) OLDI0_A4P */ + J722S_IOPAD(0x288, PIN_OUTPUT, 0) /* (AF19) OLDI0_A5N */ + J722S_IOPAD(0x284, PIN_OUTPUT, 0) /* (AF18) OLDI0_A5P */ + J722S_IOPAD(0x290, PIN_OUTPUT, 0) /* (AG17) OLDI0_A6N */ + J722S_IOPAD(0x28c, PIN_OUTPUT, 0) /* (AG18) OLDI0_A6P */ + J722S_IOPAD(0x298, PIN_OUTPUT, 0) /* (AB19) OLDI0_A7N */ + J722S_IOPAD(0x294, PIN_OUTPUT, 0) /* (AA20) OLDI0_A7P */ + J722S_IOPAD(0x2a8, PIN_OUTPUT, 0) /* (AD20) OLDI0_CLK1N */ + J722S_IOPAD(0x2a4, PIN_OUTPUT, 0) /* (AE19) OLDI0_CLK1P */ + >; + }; + + ospi0_pins_default: ospi0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x000, PIN_OUTPUT, 0) /* (L24) OSPI0_CLK */ + J722S_IOPAD(0x02c, PIN_OUTPUT, 0) /* (K26) OSPI0_CSn0 */ + J722S_IOPAD(0x030, PIN_OUTPUT, 0) /* (K23) OSPI0_CSn1 */ + J722S_IOPAD(0x034, PIN_OUTPUT, 0) /* (K22) OSPI0_CSn2 */ + J722S_IOPAD(0x00c, PIN_INPUT, 0) /* (K27) OSPI0_D0 */ + J722S_IOPAD(0x010, PIN_INPUT, 0) /* (L27) OSPI0_D1 */ + J722S_IOPAD(0x014, PIN_INPUT, 0) /* (L26) OSPI0_D2 */ + J722S_IOPAD(0x018, PIN_INPUT, 0) /* (L25) OSPI0_D3 */ + >; + bootph-all; + }; + + pcie0_rc_pins_default: pcie0-rc-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x2ac, PIN_OUTPUT, 0) /* (F25) PCIE0_CLKREQn */ + J722S_IOPAD(0x1b4, PIN_OUTPUT, 7) /* (B20) SPI0_CS0.GPIO1_15 */ + >; + }; + + pmic_irq_pins_default: pmic-irq-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x090, PIN_INPUT, 7) /* (P27) GPMC0_BE0n_CLE.GPIO0_35 */ + >; + }; + + rgmii1_pins_default: rgmii1-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x14c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */ + J722S_IOPAD(0x150, PIN_INPUT, 0) /* (AD27) RGMII1_RD1 */ + J722S_IOPAD(0x154, PIN_INPUT, 0) /* (AE24) RGMII1_RD2 */ + J722S_IOPAD(0x158, PIN_INPUT, 0) /* (AE26) RGMII1_RD3 */ + J722S_IOPAD(0x148, PIN_INPUT, 0) /* (AE27) RGMII1_RXC */ + J722S_IOPAD(0x144, PIN_INPUT, 0) /* (AD23) RGMII1_RX_CTL */ + J722S_IOPAD(0x134, PIN_OUTPUT, 0) /* (AF27) RGMII1_TD0 */ + J722S_IOPAD(0x138, PIN_OUTPUT, 0) /* (AE23) RGMII1_TD1 */ + J722S_IOPAD(0x13c, PIN_OUTPUT, 0) /* (AG25) RGMII1_TD2 */ + J722S_IOPAD(0x140, PIN_OUTPUT, 0) /* (AF24) RGMII1_TD3 */ + J722S_IOPAD(0x130, PIN_OUTPUT, 0) /* (AG26) RGMII1_TXC */ + J722S_IOPAD(0x12c, PIN_OUTPUT, 0) /* (AF25) RGMII1_TX_CTL */ + >; + }; + + rgmii2_pins_default: rgmii2-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0f8, PIN_INPUT, 2) /* (AB24) VOUT0_HSYNC.RGMII2_RD0 */ + J722S_IOPAD(0x0fc, PIN_INPUT, 2) /* (AC27) VOUT0_DE.RGMII2_RD1 */ + J722S_IOPAD(0x100, PIN_INPUT, 2) /* (AB23) VOUT0_VSYNC.RGMII2_RD2 */ + J722S_IOPAD(0x104, PIN_INPUT, 2) /* (AC26) VOUT0_PCLK.RGMII2_RD3 */ + J722S_IOPAD(0x0f4, PIN_INPUT, 2) /* (AB27) VOUT0_DATA15.RGMII2_RXC */ + J722S_IOPAD(0x0f0, PIN_INPUT, 2) /* (AB26) VOUT0_DATA14.RGMII2_RX_CTL */ + J722S_IOPAD(0x0e0, PIN_OUTPUT, 2) /* (AA25) VOUT0_DATA10.RGMII2_TD0 */ + J722S_IOPAD(0x0e4, PIN_OUTPUT, 2) /* (AB25) VOUT0_DATA11.RGMII2_TD1 */ + J722S_IOPAD(0x0e8, PIN_OUTPUT, 2) /* (AA23) VOUT0_DATA12.RGMII2_TD2 */ + J722S_IOPAD(0x0ec, PIN_OUTPUT, 2) /* (AA22) VOUT0_DATA13.RGMII2_TD3 */ + J722S_IOPAD(0x0dc, PIN_OUTPUT, 2) /* (AA27) VOUT0_DATA9.RGMII2_TXC */ + J722S_IOPAD(0x0d8, PIN_OUTPUT, 2) /* (AA24) VOUT0_DATA8.RGMII2_TX_CTL */ + >; + }; + + rtc_pins_default: rtc-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x094, PIN_INPUT, 7) /* (P26) GPMC0_BE1n.GPIO0_36 */ + >; + }; + + sdhci1_pins_default: sdhci1-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x23c, PIN_INPUT, 0) /* (H22) MMC1_CMD */ + J722S_IOPAD(0x234, PIN_OUTPUT, 0) /* (H24) MMC1_CLK */ + J722S_IOPAD(0x230, PIN_INPUT, 0) /* (H23) MMC1_DAT0 */ + J722S_IOPAD(0x22c, PIN_INPUT, 0) /* (H20) MMC1_DAT1 */ + J722S_IOPAD(0x228, PIN_INPUT, 0) /* (J23) MMC1_DAT2 */ + J722S_IOPAD(0x224, PIN_INPUT, 0) /* (H25) MMC1_DAT3 */ + J722S_IOPAD(0x240, PIN_INPUT, 0) /* (B24) MMC1_SDCD */ + J722S_IOPAD(0x244, PIN_INPUT, 0) /* (A24) MMC1_SDWP */ + >; + bootph-all; + }; + + usb0_connector_pins_default: usb0-connector-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x08c, PIN_INPUT_PULLUP, 7) /* (N23) GPMC0_WEn.GPIO0_34 */ + >; + }; + + usb1_pins_default: usb1-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x258, PIN_OUTPUT, 0) /* (B27) USB1_DRVVBUS */ + >; + }; + + vcc_3p3_sd_s0_pins_default: vcc-3p3-sd-s0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x01c, PIN_OUTPUT, 7) /* (L21) OSPI0_D4.GPIO0_7 */ + >; + bootph-all; + }; + + vcc_3p3_sd_vio_s0_pins_default: vcc-3p3-sd-vio-s0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x020, PIN_OUTPUT, 7) /* (M26) OSPI0_D5.GPIO0_8 */ + >; + bootph-all; + }; + + vcc_3p3_cam_s0_pins_default: vcc-3p3-cam-s0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1f0, PIN_OUTPUT, 7) /* (A23) EXT_REFCLK1.GPIO1_30 */ + >; + }; + + vcc_lcd0_panel_pins_default: vcc-lcd0-panel-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x078, PIN_OUTPUT, 7) /* (V23) GPMC0_AD15.GPIO0_30 */ + >; + }; + + vcc_lcd1_panel_pins_default: vcc-lcd1-panel-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1c4, PIN_OUTPUT, 7) /* (E20) SPI0_D1.GPIO1_19 */ + >; + }; + + vcc_usb0_vbus_pins_default: vcc-usb0-vbus-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x254, PIN_OUTPUT, 7) /* (E25) USB0_DRVVBUS.GPIO1_50 */ + >; + }; +}; + +/* SER1 */ +&main_uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_uart0_pins_default>; + bootph-all; + status = "okay"; +}; + +/* SER2 */ +&main_uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&main_uart5_pins_default>; + bootph-all; + status = "okay"; +}; + +/* I2S0 */ +&mcasp0 { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&mcasp0_pins_default>; + op-mode = <0>; /* I2S */ + tdm-slots = <2>; + serial-dir = <2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; +}; + +/* I2S2 */ +&mcasp2 { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&mcasp2_pins_default>; + op-mode = <0>; /* I2S */ + tdm-slots = <2>; + serial-dir = <2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; +}; + +/* CAN0 */ +&mcu_mcan0 { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_mcan0_pins_default>; + status = "okay"; +}; + +/* CAN1 */ +&mcu_mcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_mcan1_pins_default>; + status = "okay"; +}; + +&mcu_gpio0 { + gpio-line-names = + "", "", "", "", "", "", "", "", "", "", "", /* 10 */ "GPIO12", + "MCU_INT#", "", "", "", "", "", "", "", "", "", "", "GPIO13"; +}; + +/* I2C_GP */ +&mcu_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_i2c0_pins_default>; + clock-frequency = <100000>; + status = "okay"; + + /* SMARC Module EEPROM */ + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + vcc-supply = <&vcc_1p8_s0>; + }; +}; + +&mcu_pmx0 { + mcu_i2c0_pins_default: mcu-i2c0-default-pins { + pinctrl-single,pins = < + J722S_MCU_IOPAD(0x044, PIN_INPUT, 0) /* (B13) MCU_I2C0_SCL */ + J722S_MCU_IOPAD(0x048, PIN_INPUT, 0) /* (E11) MCU_I2C0_SDA */ + >; + }; + mcu_mcan0_pins_default: mcu-mcan0-default-pins { + pinctrl-single,pins = < + J722S_MCU_IOPAD(0x038, PIN_INPUT, 0) /* (D8) MCU_MCAN0_RX */ + J722S_MCU_IOPAD(0x034, PIN_OUTPUT, 0) /* (B2) MCU_MCAN0_TX */ + >; + }; + + mcu_mcan1_pins_default: mcu-mcan1-default-pins { + pinctrl-single,pins = < + J722S_MCU_IOPAD(0x040, PIN_INPUT, 0) /* (B1) MCU_MCAN1_RX */ + J722S_MCU_IOPAD(0x03c, PIN_OUTPUT, 0) /* (C1) MCU_MCAN1_TX */ + >; + }; + + mcu_uart0_pins_default: mcu-uart0-default-pins { + pinctrl-single,pins = < + J722S_MCU_IOPAD(0x014, PIN_INPUT, 0) /* (B8) MCU_UART0_RXD */ + J722S_MCU_IOPAD(0x018, PIN_OUTPUT, 0) /* (B4) MCU_UART0_TXD */ + J722S_MCU_IOPAD(0x01c, PIN_INPUT, 0) /* (B5) MCU_UART0_CTSn */ + J722S_MCU_IOPAD(0x020, PIN_OUTPUT, 0) /* (C5) MCU_UART0_RTSn */ + >; + bootph-all; + }; + + mcu_spi0_pins_default: mcu-spi0-default-pins { + pinctrl-single,pins = < + J722S_MCU_IOPAD(0x008, PIN_OUTPUT, 0) /* (A9) MCU_SPI0_CLK */ + J722S_MCU_IOPAD(0x000, PIN_OUTPUT, 0) /* (C12) MCU_SPI0_CS0 */ + J722S_MCU_IOPAD(0x004, PIN_OUTPUT, 0) /* (A10) MCU_SPI0_CS1 */ + J722S_MCU_IOPAD(0x00c, PIN_INPUT, 0) /* (B12) MCU_SPI0_D0 */ + J722S_MCU_IOPAD(0x010, PIN_OUTPUT, 0) /* (C11) MCU_SPI0_D1 */ + >; + }; + + wkup_uart0_pins_default: wkup-uart0-default-pins { + pinctrl-single,pins = < + J722S_MCU_IOPAD(0x024, PIN_INPUT, 0) /* (B3) WKUP_UART0_RXD */ + J722S_MCU_IOPAD(0x028, PIN_OUTPUT, 0) /* (C8) WKUP_UART0_TXD */ + >; + bootph-all; + }; + + wkup_i2c0_pins_default: wkup-i2c0-default-pins { + pinctrl-single,pins = < + J722S_MCU_IOPAD(0x04c, PIN_INPUT, 0) /* (B9) WKUP_I2C0_SCL */ + J722S_MCU_IOPAD(0x050, PIN_INPUT, 0) /* (D11) WKUP_I2C0_SDA */ + >; + }; +}; + +/* SPI0 */ +&mcu_spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_spi0_pins_default>; +}; + +/* SER0 */ +&mcu_uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_uart0_pins_default>; + bootph-all; + status = "okay"; +}; + +/* QSPI0 */ +&ospi0 { + pinctrl-0 = <&ospi0_pins_default>; + pinctrl-names = "default"; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <104000000>; + spi-rx-bus-width = <2>; + spi-tx-bus-width = <2>; + m25p,fast-read; + cdns,tshsl-ns = <60>; + cdns,tsd2d-ns = <60>; + cdns,tchsh-ns = <60>; + cdns,tslch-ns = <60>; + cdns,read-delay = <3>; + vcc-supply = <&vcc_1p8_s0>; + bootph-all; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x000000 0x400000>; + label = "failsafe bootloader"; + read-only; + }; + }; + + otp-1 { + compatible = "user-otp"; + + nvmem-layout { + compatible = "kontron,sa67-vpd", "kontron,sl28-vpd"; + + serial_number: serial-number { + }; + + base_mac_address: base-mac-address { + #nvmem-cell-cells = <1>; + }; + }; + }; + }; +}; + +&pcie0_rc { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_rc_pins_default>; + + /* + * This is low active, but the driver itself is broken and already + * inverts the logic. + */ + reset-gpios = <&main_gpio1 15 GPIO_ACTIVE_HIGH>; + phys = <&serdes1_pcie>; + phy-names = "pcie-phy"; + status = "okay"; +}; + +&sdhci0 { + disable-wp; + bootph-all; + ti,driver-strength-ohm = <50>; + status = "okay"; +}; + +/* SDIO */ +&sdhci1 { + pinctrl-names = "default"; + pinctrl-0 = <&sdhci1_pins_default>; + vmmc-supply = <&vcc_3p3_sd_s0>; + vqmmc-supply = <&vcc_3p3_sd_vio_s0>; + bootph-all; + cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>; + cd-debounce-delay-ms = <100>; + ti,fails-without-test-cd; + ti,driver-strength-ohm = <50>; + status = "okay"; +}; + +&serdes_ln_ctrl { + idle-states = , + ; +}; + +&serdes_wiz0 { + status = "okay"; +}; + +&serdes_wiz1 { + status = "okay"; +}; + +&serdes0 { + serdes0_usb3: phy@0 { + reg = <0>; + #phy-cells = <0>; + resets = <&serdes_wiz0 1>; + cdns,num-lanes = <1>; + cdns,phy-type = ; + }; +}; + +&serdes1 { + serdes1_pcie: phy@0 { + reg = <0>; + #phy-cells = <0>; + resets = <&serdes_wiz1 1>; + cdns,num-lanes = <1>; + cdns,phy-type = ; + }; +}; + +&usb0 { + /* dual role is implemented but not a full featured OTG */ + adp-disable; + hnp-disable; + srp-disable; + dr_mode = "otg"; + usb-role-switch; + role-switch-default-mode = "peripheral"; + status = "okay"; + + port { + usb0_hc: endpoint { + remote-endpoint = <&usb0_connector>; + }; + }; +}; + +&usb0_phy_ctrl { + /* + * Keep this node in the SPL to be able to use the USB controller to + * boot via DFU. + */ + bootph-all; +}; + +&usb1 { + pinctrl-names = "default"; + pinctrl-0 = <&usb1_pins_default>; + + dr_mode = "host"; + maximum-speed = "super-speed"; + phys = <&serdes0_usb3>; + phy-names = "cdns3,usb3-phy"; +}; + +&usbss0 { + ti,vbus-divider; + status = "okay"; +}; + +&usbss1 { + ti,vbus-divider; + status = "okay"; +}; + +/* I2C_PM */ +&wkup_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&wkup_i2c0_pins_default>; + clock-frequency = <100000>; + status = "okay"; +}; + +/* SER3 */ +&wkup_uart0 { + /* WKUP UART0 is used by Device Manager firmware */ + pinctrl-names = "default"; + pinctrl-0 = <&wkup_uart0_pins_default>; + bootph-all; + status = "reserved"; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-gbe1.dtso b/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-gbe1.dtso new file mode 100644 index 0000000000000..5dfb0b8f10d2c --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-gbe1.dtso @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Second ethernet port GBE1. + * + * Copyright (c) 2025 Kontron Europe GmbH + */ + +/dts-v1/; +/plugin/; + +&cpsw3g_mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + +&cpsw_port2 { + phy-connection-type = "rgmii-id"; + phy-handle = <&phy1>; + nvmem-cells = <&base_mac_address 1>; + nvmem-cell-names = "mac-address"; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-gpios.dtso b/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-gpios.dtso new file mode 100644 index 0000000000000..a6ae758e0b3a9 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-gpios.dtso @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * SMARC GPIOs. + * + * Copyright (c) 2025 Kontron Europe GmbH + */ + +/dts-v1/; +/plugin/; + +#include +#include "k3-pinctrl.h" + +&main_gpio0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_gpio0_pins_default>; +}; + +&main_gpio1 { + pinctrl-names = "default"; + pinctrl-0 = <&main_gpio1_pins_default>; +}; + +&main_pmx0 { + main_gpio0_pins_default: main-gpio0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0d0, PIN_INPUT, 7) /* (Y26) VOUT0_DATA6.GPIO0_51 */ + J722S_IOPAD(0x0d4, PIN_INPUT, 7) /* (Y27) VOUT0_DATA7.GPIO0_52 */ + J722S_IOPAD(0x118, PIN_INPUT, 7) /* (H26) MMC2_CLK.GPIO0_69 */ + J722S_IOPAD(0x120, PIN_INPUT, 7) /* (F27) MMC2_CMD.GPIO0_70 */ + >; + }; + + main_gpio1_pins_default: main-gpio1-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x194, PIN_INPUT, 7) /* (A25) MCASP0_AXR3.GPIO1_7 */ + J722S_IOPAD(0x198, PIN_INPUT, 7) /* (A26) MCASP0_AXR2.GPIO1_8 */ + J722S_IOPAD(0x1ac, PIN_INPUT, 7) /* (C27) MCASP0_AFSR.GPIO1_13 */ + J722S_IOPAD(0x1b0, PIN_INPUT, 7) /* (F24) MCASP0_ACLKR.GPIO1_14 */ + J722S_IOPAD(0x1d8, PIN_INPUT, 7) /* (D22) MCAN0_TX.GPIO1_24 */ + J722S_IOPAD(0x1dc, PIN_INPUT, 7) /* (C22) MCAN0_RX.GPIO1_25 */ + J722S_IOPAD(0x1e8, PIN_INPUT, 7) /* (C24) I2C1_SCL.GPIO1_28 */ + J722S_IOPAD(0x1ec, PIN_INPUT, 7) /* (A22) I2C1_SDA.GPIO1_29 */ + >; + }; +}; + +&mcu_gpio0 { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_gpio0_pins_default>; +}; + +&mcu_pmx0 { + mcu_gpio0_pins_default: mcu-gpio0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x02c, PIN_INPUT, 7) /* (C4) WKUP_UART0_CTSn.MCU_GPIO0_11 */ + J722S_IOPAD(0x084, PIN_INPUT, 7) /* (F12) WKUP_CLKOUT0.MCU_GPIO0_23 */ + >; + }; + +}; diff --git a/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-rtc-rv8263.dtso b/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-rtc-rv8263.dtso new file mode 100644 index 0000000000000..0a3e9f614c4c9 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-rtc-rv8263.dtso @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Microcrystal RV8263 RTC variant. + * + * Copyright (c) 2025 Kontron Europe GmbH + */ + +/dts-v1/; +/plugin/; + +#include + +&{/} { + aliases { + rtc0 = "/bus@f0000/i2c@20000000/rtc@51"; /* &rtc */ + rtc1 = "/bus@f0000/bus@b00000/rtc@2b1f0000"; /* &wkup_rtc0 */ + }; +}; + +&main_i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + rtc: rtc@51 { + compatible = "microcrystal,rv8263"; + reg = <0x51>; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_pins_default>; + interrupts-extended = <&main_gpio0 36 IRQ_TYPE_EDGE_FALLING>; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am68-phyboard-izar.dts b/arch/arm64/boot/dts/ti/k3-am68-phyboard-izar.dts index 41c8f8526e15d..e221ccb30e952 100644 --- a/arch/arm64/boot/dts/ti/k3-am68-phyboard-izar.dts +++ b/arch/arm64/boot/dts/ti/k3-am68-phyboard-izar.dts @@ -281,7 +281,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&phy0>; }; @@ -422,6 +422,7 @@ &mcu_cpsw { pinctrl-names = "default"; pinctrl-0 = <&mcu_cpsw_pins_default>; + status = "okay"; }; &mcu_i2c1 { diff --git a/arch/arm64/boot/dts/ti/k3-am68-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am68-phycore-som.dtsi index adef02bd80408..0ff511028f81f 100644 --- a/arch/arm64/boot/dts/ti/k3-am68-phycore-som.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am68-phycore-som.dtsi @@ -175,7 +175,7 @@ &main_cpsw_port1 { phy-handle = <&phy1>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; status = "okay"; }; @@ -258,7 +258,7 @@ bootph-pre-ram; }; - pmic@48 { + pmic: pmic@48 { compatible = "ti,tps6594-q1"; reg = <0x48>; system-power-controller; diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts index 75a107456ce1d..88f202f266c65 100644 --- a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts +++ b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts @@ -692,6 +692,7 @@ &mcu_cpsw { pinctrl-names = "default"; pinctrl-0 = <&mcu_cpsw_pins_default>, <&mcu_mdio_pins_default>; + status = "okay"; }; &davinci_mdio { @@ -705,7 +706,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&phy0>; bootph-all; }; diff --git a/arch/arm64/boot/dts/ti/k3-am69-aquila-clover.dts b/arch/arm64/boot/dts/ti/k3-am69-aquila-clover.dts new file mode 100644 index 0000000000000..55fd214a82e44 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am69-aquila-clover.dts @@ -0,0 +1,451 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 Toradex + * + * https://www.toradex.com/computer-on-modules/aquila-arm-family/ti-am69 + * https://www.toradex.com/products/carrier-board/clover + */ + +/dts-v1/; + +#include +#include "k3-am69-aquila.dtsi" + +/ { + model = "Toradex Aquila AM69 on Clover Board"; + compatible = "toradex,aquila-am69-clover", + "toradex,aquila-am69", + "ti,j784s4"; + + aliases { + eeprom1 = &carrier_eeprom; + }; + + reg_3v3_dp: regulator-3v3-dp { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_21_dp>; + /* Aquila GPIO_21_DP (AQUILA B57) */ + gpio = <&main_gpio0 37 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "DP_3V3"; + startup-delay-us = <10000>; + }; + + /* Aquila DP_1 */ + dp-connector { + compatible = "dp-connector"; + dp-pwr-supply = <®_3v3_dp>; + label = "Display Port"; + type = "full-size"; + + port { + dp_connector_in: endpoint { + remote-endpoint = <&dp0_out>; + }; + }; + }; +}; + +/* On-module ETH_1 MDIO */ +&davinci_mdio { + status = "okay"; +}; + +&dp0_ports { + port@4 { + reg = <4>; + dp0_out: endpoint { + remote-endpoint = <&dp_connector_in>; + }; + }; +}; + +&dss { + status = "okay"; +}; + +&main0_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&main0_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&main0_alert1>; + }; + }; +}; + +&main1_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&main1_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&main1_alert1>; + }; + }; +}; + +&main2_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&main2_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&main2_alert1>; + }; + }; +}; + +&main3_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&main3_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&main3_alert1>; + }; + }; +}; + +&main4_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&main4_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&main4_alert1>; + }; + }; +}; + +/* Aquila ETH_2 */ +&main_cpsw0 { + status = "okay"; +}; + +/* Aquila ETH_2 SGMII PHY */ +&main_cpsw0_port8 { + phy-handle = <&cpsw0_port8_phy4>; + status = "okay"; +}; + +/* Aquila ETH_2_XGMII_MDIO */ +&main_cpsw0_mdio { + status = "okay"; + + cpsw0_port8_phy4: ethernet-phy@4 { + reg = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_eth2_int>; + interrupt-parent = <&main_gpio0>; + interrupts = <44 IRQ_TYPE_EDGE_FALLING>; + }; +}; + +/* Aquila PWM_1 */ +&main_ehrpwm0 { + status = "okay"; +}; + +/* Aquila PWM_2 */ +&main_ehrpwm1 { + status = "okay"; +}; + +&main_gpio0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_01>, /* Aquila GPIO_01 */ + <&pinctrl_gpio_02>, /* Aquila GPIO_02 */ + <&pinctrl_gpio_03>; /* Aquila GPIO_03 */ +}; + +/* Aquila I2C_6 */ +&main_i2c5 { + status = "okay"; +}; + +/* Aquila CAN_1 */ +&main_mcan10 { + status = "okay"; +}; + +/* Aquila CAN_3 */ +&main_mcan13 { + status = "okay"; +}; + +/* Aquila SD_1 */ +&main_sdhci1 { + status = "okay"; +}; + +/* Aquila SPI_2 */ +&main_spi0 { + status = "okay"; +}; + +/* Aquila SPI_1 */ +&main_spi2 { + pinctrl-0 = <&pinctrl_main_spi2>, + <&pinctrl_main_spi2_cs0>, + <&pinctrl_gpio_05>; + cs-gpios = <0>, <&wkup_gpio0 29 GPIO_ACTIVE_LOW>; + status = "okay"; + + tpm@1 { + compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; + reg = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_06>; + interrupt-parent = <&wkup_gpio0>; + interrupts = <30 IRQ_TYPE_EDGE_FALLING>; + spi-max-frequency = <18500000>; + }; +}; + +/* Aquila UART_1 */ +&main_uart4 { + status = "okay"; +}; + +/* Aquila UART_3, used as the Linux console */ +&main_uart8 { + status = "okay"; +}; + +&mcu_cpsw { + status = "okay"; +}; + +/* On-module ETH_1 RGMII */ +&mcu_cpsw_port1 { + status = "okay"; +}; + +/* Aquila I2C_1 */ +&mcu_i2c0 { + clock-frequency = <100000>; + status = "okay"; + + fan_controller: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + #pwm-cells = <2>; + + fan: fan { + cooling-levels = <102 179 255>; + #cooling-cells = <2>; + pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED>; + }; + }; + + temperature-sensor@4f { + compatible = "ti,tmp1075"; + reg = <0x4f>; + }; + + /* USB-C OTG (TCPC USB PD PHY) */ + tcpc@52 { + compatible = "nxp,ptn5110", "tcpci"; + reg = <0x52>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1_int>; + interrupt-parent = <&main_gpio0>; + interrupts = <28 IRQ_TYPE_EDGE_FALLING>; + + connector { + compatible = "usb-c-connector"; + data-role = "dual"; + label = "USB-C OTG"; + power-role = "dual"; + try-power-role = "sink"; + self-powered; + source-pdos = ; + sink-pdos = ; + op-sink-microwatt = <1000000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_1_con_hs: endpoint { + remote-endpoint = <&usb0_hs>; + }; + }; + + port@1 { + reg = <1>; + + usb_1_con_ss: endpoint { + remote-endpoint = <&usb0_ss_mux>; + }; + }; + }; + }; + }; + + carrier_eeprom: eeprom@57 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + }; +}; + +/* Aquila I2C_2 */ +&mcu_i2c1 { + status = "okay"; +}; + +/* Aquila CAN_2 */ +&mcu_mcan0 { + status = "okay"; +}; + +/* Aquila CAN_4 */ +&mcu_mcan1 { + status = "okay"; +}; + +/* Aquila UART_4 */ +&mcu_uart0 { + status = "okay"; +}; + +&mhdp { + status = "okay"; +}; + +/* Aquila QSPI_1 */ +&ospi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_ospi0_4bit>, <&pinctrl_mcu_ospi0_cs0>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <66000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + cdns,read-delay = <0>; + cdns,tchsh-ns = <3>; + cdns,tsd2d-ns = <10>; + cdns,tshsl-ns = <30>; + cdns,tslch-ns = <8>; + }; +}; + +/* Aquila PCIE_1 */ +&pcie0_rc { + status = "okay"; +}; + +/* Aquila PCIE_2 */ +&pcie1_rc { + status = "okay"; +}; + +&serdes2 { + status = "okay"; +}; + +&serdes4 { + status = "okay"; +}; + +&serdes_wiz2 { + status = "okay"; +}; + +&serdes_wiz4 { + status = "okay"; +}; + +/* Aquila ADC_[1-4] */ +&tscadc0 { + status = "okay"; +}; + +&usbss0 { + status = "okay"; +}; + +&usb0ss_mux { + status = "okay"; + + port { + usb0_ss_mux: endpoint { + remote-endpoint = <&usb_1_con_ss>; + }; + }; +}; + +&usb0 { + status = "okay"; + + port { + usb0_hs: endpoint { + remote-endpoint = <&usb_1_con_hs>; + }; + }; +}; + +&wkup0_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&wkup0_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&wkup0_alert1>; + }; + }; +}; + +&wkup1_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&wkup1_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&wkup1_alert1>; + }; + }; +}; + +&wkup_gpio0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_04>; /* Aquila GPIO_04 */ +}; + +/* Aquila UART_2 */ +&wkup_uart0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am69-aquila-dev.dts b/arch/arm64/boot/dts/ti/k3-am69-aquila-dev.dts new file mode 100644 index 0000000000000..c7ce804eac703 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am69-aquila-dev.dts @@ -0,0 +1,576 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 Toradex + * + * https://www.toradex.com/computer-on-modules/aquila-arm-family/ti-am69 + * https://www.toradex.com/products/carrier-board/aquila-development-board-kit + */ + +/dts-v1/; + +#include +#include "k3-am69-aquila.dtsi" + +/ { + model = "Toradex Aquila AM69 on Aquila Development Board"; + compatible = "toradex,aquila-am69-dev", + "toradex,aquila-am69", + "ti,j784s4"; + + aliases { + eeprom1 = &carrier_eeprom; + }; + + reg_1v8_sw: regulator-1v8-sw { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "Carrier_1V8"; + }; + + reg_3v3_dp: regulator-3v3-dp { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_21_dp>; + /* Aquila GPIO_21_DP (AQUILA B57) */ + gpio = <&main_gpio0 37 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "DP_3V3"; + startup-delay-us = <10000>; + }; + + dp0-connector { + compatible = "dp-connector"; + dp-pwr-supply = <®_3v3_dp>; + label = "Display Port"; + type = "full-size"; + + port { + dp0_connector_in: endpoint { + remote-endpoint = <&dp0_out>; + }; + }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&codec_dai>; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&codec_dai>; + simple-audio-card,name = "aquila-wm8904"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "Microphone Jack", "MICBIAS", + "IN1L", "Microphone Jack", + "IN1R", "Digital Mic"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Microphone", "Digital Mic", + "Headphone", "Headphone Jack", + "Line", "Line In Jack"; + + codec_dai: simple-audio-card,codec { + sound-dai = <&wm8904_1a>; + }; + + simple-audio-card,cpu { + sound-dai = <&mcasp4>; + }; + }; +}; + +/* Aquila CTRL_PWR_BTN_MICO# */ +&aquila_key_power { + status = "okay"; +}; + +/* Aquila CTRL_WAKE1_MICO# */ +&aquila_key_wake { + status = "okay"; +}; + +/* On-module ETH_1 MDIO */ +&davinci_mdio { + status = "okay"; +}; + +&dp0_ports { + port@4 { + reg = <4>; + dp0_out: endpoint { + remote-endpoint = <&dp0_connector_in>; + }; + }; +}; + +&dss { + status = "okay"; +}; + +&main0_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&main0_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&main0_alert1>; + }; + }; +}; + +&main1_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&main1_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&main1_alert1>; + }; + }; +}; + +&main2_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&main2_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&main2_alert1>; + }; + }; +}; + +&main3_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&main3_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&main3_alert1>; + }; + }; +}; + +&main4_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&main4_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&main4_alert1>; + }; + }; +}; + +/* Aquila ETH_2 */ +&main_cpsw0 { + status = "okay"; +}; + +/* Aquila ETH_2 SGMII PHY */ +&main_cpsw0_port8 { + phy-handle = <&cpsw0_port8_phy4>; + status = "okay"; +}; + +/* Aquila ETH_2_XGMII_MDIO */ +&main_cpsw0_mdio { + status = "okay"; + + cpsw0_port8_phy4: ethernet-phy@4 { + reg = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_eth2_int>; + interrupt-parent = <&main_gpio0>; + interrupts = <44 IRQ_TYPE_EDGE_FALLING>; + }; +}; + +/* Aquila PWM_1 */ +&main_ehrpwm0 { + status = "okay"; +}; + +/* Aquila PWM_4_DP */ +&main_ehrpwm2 { + status = "okay"; +}; + +/* Aquila PWM_2 */ +&main_ehrpwm1 { + status = "okay"; +}; + +/* Aquila PWM_3_DSI */ +&main_ehrpwm5 { + status = "okay"; +}; + +&main_gpio0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_01>, /* Aquila GPIO_01 */ + <&pinctrl_gpio_02>, /* Aquila GPIO_02 */ + <&pinctrl_gpio_03>; /* Aquila GPIO_03 */ +}; + +/* Aquila I2C_3_DSI1 */ +&main_i2c0 { + status = "okay"; + + i2c-mux@70 { + compatible = "nxp,pca9543"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + /* I2C on DSI Connector Pin #4 and #6 */ + i2c_dsi_0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* I2C on DSI Connector Pin #52 and #54 */ + i2c_dsi_1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +/* Aquila I2C_4_CSI1 */ +&main_i2c1 { + status = "okay"; +}; + +/* Aquila I2C_5_CSI2 */ +&main_i2c2 { + status = "okay"; +}; + +/* Aquila I2C_6 */ +&main_i2c5 { + status = "okay"; +}; + +/* Aquila CAN_1 */ +&main_mcan10 { + status = "okay"; +}; + +/* Aquila CAN_3 */ +&main_mcan13 { + status = "okay"; +}; + +/* Aquila SD_1 */ +&main_sdhci1 { + status = "okay"; +}; + +/* Aquila SPI_2 */ +&main_spi0 { + status = "okay"; +}; + +/* Aquila SPI_1 */ +&main_spi2 { + status = "okay"; +}; + +/* Aquila UART_1 */ +&main_uart4 { + status = "okay"; +}; + +/* Aquila UART_3, used as the Linux console */ +&main_uart8 { + status = "okay"; +}; + +/* Aquila I2S_1 */ +&mcasp4 { + status = "okay"; +}; + +&mcu_cpsw { + status = "okay"; +}; + +/* On-module ETH_1 RGMII */ +&mcu_cpsw_port1 { + status = "okay"; +}; + +/* Aquila I2C_1 */ +&mcu_i2c0 { + clock-frequency = <100000>; + status = "okay"; + + fan_controller: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + #pwm-cells = <2>; + + fan: fan { + cooling-levels = <102 179 255>; + #cooling-cells = <2>; + pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED>; + }; + }; + + wm8904_1a: audio-codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audio_extrefclk1>; + #sound-dai-cells = <0>; + clocks = <&audio_refclk1>; + clock-names = "mclk"; + AVDD-supply = <®_1v8_sw>; + CPVDD-supply = <®_1v8_sw>; + DBVDD-supply = <®_1v8_sw>; + DCVDD-supply = <®_1v8_sw>; + MICVDD-supply = <®_1v8_sw>; + + wlf,drc-cfg-names = "default", "peaklimiter"; + /* + * Config registers per name, respectively: + * KNEE_IP = 0, KNEE_OP = 0, HI_COMP = 1, LO_COMP = 1 + * KNEE_IP = -24, KNEE_OP = -6, HI_COMP = 1/4, LO_COMP = 1 + */ + wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>, + /bits/ 16 <0x04af 0x324b 0x0010 0x0408>; + + /* GPIO1 = DMIC_CLK, don't touch others */ + wlf,gpio-cfg = <0x0018>, <0xffff>, <0xffff>, <0xffff>; + + wlf,in1r-as-dmicdat2; + }; + + /* Current measurement into module VCC */ + hwmon@41 { + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + + temperature-sensor@4f { + compatible = "ti,tmp1075"; + reg = <0x4f>; + }; + + /* USB-C OTG (TCPC USB PD PHY) */ + tcpc@52 { + compatible = "nxp,ptn5110", "tcpci"; + reg = <0x52>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1_int>; + interrupt-parent = <&main_gpio0>; + interrupts = <28 IRQ_TYPE_EDGE_FALLING>; + + connector { + compatible = "usb-c-connector"; + data-role = "dual"; + label = "USB-C OTG"; + power-role = "dual"; + try-power-role = "sink"; + self-powered; + source-pdos = ; + sink-pdos = ; + op-sink-microwatt = <1000000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_1_con_hs: endpoint { + remote-endpoint = <&usb0_hs>; + }; + }; + + port@1 { + reg = <1>; + + usb_1_con_ss: endpoint { + remote-endpoint = <&usb0_ss_mux>; + }; + }; + }; + }; + }; + + carrier_eeprom: eeprom@57 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + }; +}; + +/* Aquila I2C_2 */ +&mcu_i2c1 { + status = "okay"; +}; + +/* Aquila CAN_2 */ +&mcu_mcan0 { + status = "okay"; +}; + +/* Aquila CAN_4 */ +&mcu_mcan1 { + status = "okay"; +}; + +/* Aquila UART_4 */ +&mcu_uart0 { + status = "okay"; +}; + +&mhdp { + status = "okay"; +}; + +/* Aquila QSPI_1 */ +&ospi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_ospi0_4bit>, <&pinctrl_mcu_ospi0_cs0>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <66000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + cdns,read-delay = <0>; + cdns,tchsh-ns = <3>; + cdns,tsd2d-ns = <10>; + cdns,tshsl-ns = <30>; + cdns,tslch-ns = <8>; + }; +}; + +/* Aquila PCIE_1 */ +&pcie0_rc { + status = "okay"; +}; + +/* Aquila PCIE_2 */ +&pcie1_rc { + status = "okay"; +}; + +&serdes2 { + status = "okay"; +}; + +&serdes4 { + status = "okay"; +}; + +&serdes_wiz2 { + status = "okay"; +}; + +&serdes_wiz4 { + status = "okay"; +}; + +/* Aquila ADC_[1-4] */ +&tscadc0 { + status = "okay"; +}; + +&usbss0 { + status = "okay"; +}; + +&usb0ss_mux { + status = "okay"; + + port { + usb0_ss_mux: endpoint { + remote-endpoint = <&usb_1_con_ss>; + }; + }; +}; + +&usb0 { + status = "okay"; + + port { + usb0_hs: endpoint { + remote-endpoint = <&usb_1_con_hs>; + }; + }; +}; + +&wkup0_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&wkup0_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&wkup0_alert1>; + }; + }; +}; + +&wkup1_thermal { + cooling-maps { + map0 { + cooling-device = <&fan 1 1>; + trip = <&wkup1_alert0>; + }; + + map1 { + cooling-device = <&fan 2 2>; + trip = <&wkup1_alert1>; + }; + }; +}; + +&wkup_gpio0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_04>, /* Aquila GPIO_04 */ + <&pinctrl_gpio_05>, /* Aquila GPIO_05 */ + <&pinctrl_gpio_06>, /* Aquila GPIO_06 */ + <&pinctrl_gpio_07>, /* Aquila GPIO_07 */ + <&pinctrl_gpio_08>; /* Aquila GPIO_08 */ +}; + +/* Aquila UART_2, through RS485 transceiver */ +&wkup_uart0 { + linux,rs485-enabled-at-boot-time; + rs485-rx-during-tx; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am69-aquila.dtsi b/arch/arm64/boot/dts/ti/k3-am69-aquila.dtsi new file mode 100644 index 0000000000000..0866eb8a6f348 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am69-aquila.dtsi @@ -0,0 +1,1840 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2025 Toradex + * + * https://www.toradex.com/computer-on-modules/aquila-arm-family/ti-am69 + */ + +#include +#include +#include +#include +#include +#include "k3-j784s4.dtsi" + +/ { + chosen { + stdout-path = "serial2:115200n8"; + }; + + aliases { + can0 = &main_mcan10; + can1 = &mcu_mcan0; + can2 = &main_mcan13; + can3 = &mcu_mcan1; + eeprom0 = &som_eeprom; + ethernet0 = &mcu_cpsw_port1; + ethernet1 = &main_cpsw0_port8; + i2c0 = &wkup_i2c0; + i2c1 = &mcu_i2c0; + i2c2 = &mcu_i2c1; + i2c3 = &main_i2c0; + i2c4 = &main_i2c1; + i2c5 = &main_i2c2; + i2c6 = &main_i2c5; + mmc0 = &main_sdhci0; + mmc1 = &main_sdhci1; + rtc0 = &rtc_i2c; + serial0 = &main_uart4; + serial1 = &wkup_uart0; + serial2 = &main_uart8; + serial3 = &mcu_uart0; + usb0 = &usb0; + }; + + aquila_key_power: gpio-key-power { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwr_btn_int>; + status = "disabled"; + + key-power { + /* Aquila CTRL_PWR_BTN_MICO# (AQUILA B93) */ + gpios = <&wkup_gpio0 36 GPIO_ACTIVE_LOW>; + label = "Power Button"; + linux,code = ; + }; + }; + + aquila_key_wake: gpio-key-wakeup { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ctrl_wake1_mico>; + status = "disabled"; + + key-wakeup { + /* Aquila CTRL_WAKE1_MICO# (AQUILA D6) */ + gpios = <&wkup_gpio0 49 GPIO_ACTIVE_LOW>; + label = "Wake Up"; + linux,code = ; + wakeup-source; + }; + }; + + /* Aquila CTRL_RESET_MICO# (AQUILA B92) */ + gpio-restart { + compatible = "gpio-restart"; + /* COLD_RESET_REQ */ + gpios = <&som_gpio_expander 1 GPIO_ACTIVE_HIGH>; + priority = <192>; + }; + + /* PWR_DOWN_REQ */ + gpio-poweroff { + compatible = "gpio-poweroff"; + /* PWR_DOWN_REQ */ + gpios = <&som_gpio_expander 2 GPIO_ACTIVE_HIGH>; + timeout-ms = <3000>; + }; + + memory@80000000 { + device_type = "memory"; + /* 32G RAM */ + reg = <0x00 0x80000000 0x00 0x80000000>, + <0x08 0x80000000 0x07 0x80000000>; + }; + + reserved_memory: reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + secure_ddr: optee@9e800000 { + reg = <0x00 0x9e800000 0x00 0x01800000>; + no-map; + }; + + mcu_r5fss0_core0_dma_memory_region: memory@a0000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa0000000 0x00 0x100000>; + no-map; + }; + + mcu_r5fss0_core0_memory_region: memory@a0100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa0100000 0x00 0xf00000>; + no-map; + }; + }; + + /* Module Power Supply (VCC) */ + reg_vin: regulator-vin { + compatible = "regulator-fixed"; + regulator-name = "+V_IN"; + }; + + /* Enabled by EN_3V3_VIO (PMIC_GPIO_9) */ + reg_1v1_usb_bridge: regulator-1v1-vio { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1100000>; + regulator-name = "+V1.1_VIO"; + vin-supply = <®_vin>; + }; + + reg_3v3_wifi: regulator-3v3-wifi { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_en_3v3_wifi>; + gpio = <&wkup_gpio0 57 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "+V3.3_WIFI"; + startup-delay-us = <20000>; + vin-supply = <®_vin>; + }; + + reg_1v8_stby: regulator-1v8-stby { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V1.8_STBY"; + vin-supply = <®_vin>; + }; + + /* Aquila SD_1_PWR_EN */ + reg_sdhc1_vmmc: regulator-sdhci1 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sd1_pwr_en>; + /* Aquila SD_1_PWR_EN (AQUILA A6) */ + gpio = <&main_gpio0 52 GPIO_ACTIVE_HIGH>; + enable-active-high; + off-on-delay-us = <100000>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "+3V3_SD"; + startup-delay-us = <20000>; + }; + + reg_sdhc1_vqmmc: regulator-sdhci1-vqmmc { + compatible = "regulator-gpio"; + /* SDIO_PWR_SEL_3.3V */ + gpios = <&som_gpio_expander 7 GPIO_ACTIVE_HIGH>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+VDD_SD_DV"; + states = <1800000 0x0>, + <3300000 0x1>; + }; + + /* On-module USB_1_SS mux */ + usb0ss_mux: gpio-sbu-mux { + compatible = "ti,tmuxhs4212", "gpio-sbu-mux"; + orientation-switch; + /* USB_MUX_SEL */ + select-gpios = <&som_gpio_expander 0 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; +}; + +&main_pmx0 { + /* Aquila DP_1_HPD */ + pinctrl_main_dp0_hpd: main-dp0-hpd-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x014, PIN_INPUT, 13) /* (AG33) MCAN14_TX.DP0_HPD */ /* AQUILA B59 */ + >; + }; + + /* Aquila PWM_1 */ + pinctrl_main_ehrpwm0_b: main-ehrpwm0b-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x064, PIN_OUTPUT, 9) /* (AF38) MCAN0_TX.EHRPWM0_B */ /* AQUILA C25 */ + >; + }; + + /* Aquila PWM_2 */ + pinctrl_main_ehrpwm1_a: main-ehrpwm1a-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x060, PIN_OUTPUT, 9) /* (AE36) MCASP2_AXR1.EHRPWM1_A */ /* AQUILA C26 */ + >; + }; + + /* Aquila PWM_3_DSI */ + pinctrl_main_ehrpwm5_a: main-ehrpwm5a-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x084, PIN_OUTPUT, 9) /* (AG38) MCASP0_AXR5.EHRPWM5_A */ /* AQUILA B46 */ + >; + }; + + /* Aquila PWM_4_DP */ + pinctrl_main_ehrpwm2_a: main-ehrpwm2a-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x040, PIN_INPUT, 9) /* (AF37) MCASP0_AXR0.EHRPWM2_A */ /* AQUILA B58 */ + >; + }; + + /* PMIC_INT# */ + pinctrl_pmic_int: main-gpio0-0-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x000, PIN_INPUT, 7) /* (AN35) EXTINTn.GPIO0_0 */ + >; + }; + + /* Aquila GPIO_09_CSI_1 */ + pinctrl_gpio_09_csi_1: main-gpio0-1-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x004, PIN_INPUT, 7) /* (AG36) MCAN12_TX.GPIO0_1 */ /* AQUILA B17 */ + >; + }; + + /* Aquila GPIO_10_CSI_1 */ + pinctrl_gpio_10_csi_1: main-gpio0-2-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x008, PIN_INPUT, 7) /* (AJ33) MCAN12_RX.GPIO0_2 */ /* AQUILA B18 */ + >; + }; + + /* Aquila USB_1_OC# */ + pinctrl_usb1_oc: main-gpio0-10-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x028, PIN_INPUT, 7) /* (AE33) MCAN16_RX.GPIO0_10 */ /* AQUILA B75 */ + >; + }; + + /* Aquila USB_1_EN */ + pinctrl_usb1_en_gpio: main-gpio0-11-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x02c, PIN_INPUT, 7) /* (AL32) GPIO0_11 */ /* AQUILA B77 */ + >; + }; + + /* Aquila GPIO_17_DSI_1 */ + pinctrl_gpio_17_dsi_1: main-gpio0-12-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x030, PIN_INPUT, 7) /* (AK37) GPIO0_12 */ /* AQUILA B42 */ + >; + }; + + /* Aquila GPIO_19_DSI_1 */ + pinctrl_gpio_19_dsi_1: main-gpio0-13-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x034, PIN_INPUT, 7) /* (AJ34) PMIC_WAKE0n.GPIO0_13 */ /* AQUILA B44 */ + >; + }; + + /* Aquila GPIO_02 */ + pinctrl_gpio_02: main-gpio0-17-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x044, PIN_INPUT, 7) /* (AG37) MCASP0_AXR1.GPIO0_17 */ /* AQUILA D24 */ + >; + }; + + /* Aquila GPIO_20_DSI_1 */ + pinctrl_gpio_20_dsi_1: main-gpio0-18-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x048, PIN_INPUT, 7) /* (AK33) MCASP0_AXR2.GPIO0_18 */ /* AQUILA B45 */ + >; + }; + + /* Aquila GPIO_21_DP */ + pinctrl_gpio_21_dp: main-gpio0-21-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x054, PIN_INPUT, 7) /* (AD37) MCASP2_ACLKX.GPIO0_21 */ /* AQUILA B57 */ + >; + }; + + /* Aquila USB_1_INT# */ + pinctrl_usb1_int: main-gpio0-28-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x070, PIN_INPUT, 7) /* (AH38) MCAN1_RX.GPIO0_28 */ /* AQUILA B74 */ + >; + }; + + /* Aquila GPIO_03 */ + pinctrl_gpio_03: main-gpio0-29-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x074, PIN_INPUT, 7) /* (AC33) MCAN2_TX.GPIO0_29 */ /* AQUILA D25 */ + >; + }; + + /* Aquila GPIO_18_DSI_1 */ + pinctrl_gpio_18_dsi_1: main-gpio0-31-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x07c, PIN_INPUT, 7) /* (AJ38) MCASP0_AXR3.GPIO0_31 */ /* AQUILA B43 */ + >; + }; + + /* Aquila PCIE_1_RESET# */ + pinctrl_pcie0_reset: main-gpio0-32-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x080, PIN_INPUT, 7) /* (AK34) MCASP0_AXR4.GPIO0_32 */ /* AQUILA C38 */ + >; + }; + + /* Aquila PWM_3_DSI as GPIO */ + pinctrl_pwm3_dsi_gpio: main-gpio0-33-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x084, PIN_INPUT, 7) /* (AG38) MCASP0_AXR5.GPIO0_33 */ /* AQUILA B46 */ + >; + }; + + /* Aquila GPIO_01 */ + pinctrl_gpio_01: main-gpio0-34-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x088, PIN_INPUT, 7) /* (AF36) MCASP0_AXR6.GPIO0_34 */ /* AQUILA D23 */ + >; + }; + + /* Aquila PCIE_2_RESET# */ + pinctrl_pcie1_reset: main-gpio0-41-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0a4, PIN_INPUT, 7) /* (AJ36) MCASP0_AXR13.GPIO0_41 */ /* AQUILA C35 */ + >; + }; + + /* Aquila ETH_2_xGMII_INT# */ + pinctrl_eth2_int: main-gpio0-44-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0b0, PIN_INPUT_PULLUP, 7) /* (AL33) MCASP1_AXR3.GPIO0_44 */ /* AQUILA B81 */ + >; + }; + + /* Aquila GPIO_11_CSI_1 */ + pinctrl_gpio_11_csi_1: main-gpio0-47-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0bc, PIN_INPUT, 7) /* (AD33) MCASP1_AFSX.GPIO0_47 */ /* AQUILA A11 */ + >; + }; + + /* Aquila GPIO_12_CSI_1 */ + pinctrl_gpio_12_csi_1: main-gpio0-48-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0c0, PIN_INPUT, 7) /* (AD38) MCASP1_AXR0.GPIO0_48 */ /* AQUILA B19 */ + >; + }; + + /* Aquila SD_1_PWR_EN */ + pinctrl_sd1_pwr_en: main-gpio0-52-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0d0, PIN_INPUT, 7) /* (AP38) SPI0_CS1.GPIO0_52 */ /* AQUILA A6 */ + >; + }; + + /* Aquila SD_1_CD# as GPIO */ + pinctrl_sd1_cd_gpio: main-gpio0-58-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0e8, PIN_INPUT_PULLUP, 7) /* (AR38) TIMER_IO0.GPIO0_58 */ /* AQUILA A1 */ + >; + }; + + /* Aquila I2C_3_DSI1 */ + pinctrl_main_i2c0: main-i2c0-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0e0, PIN_INPUT, 0) /* (AN36) I2C0_SCL */ /* AQUILA B41 */ + J784S4_IOPAD(0x0e4, PIN_INPUT, 0) /* (AP37) I2C0_SDA */ /* AQUILA B40 */ + >; + }; + + /* Aquila I2C_4_CSI1 */ + pinctrl_main_i2c1: main-i2c1-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x020, PIN_INPUT_PULLUP, 12) /* (AJ35) MCAN15_RX.I2C1_SCL */ /* AQUILA A13 */ + J784S4_IOPAD(0x024, PIN_INPUT_PULLUP, 12) /* (AH34) MCAN16_TX.I2C1_SDA */ /* AQUILA A12 */ + >; + }; + + /* Aquila I2C_5_CSI2 */ + pinctrl_main_i2c2: main-i2c2-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x04c, PIN_INPUT_PULLUP, 13) /* (AC32) MCASP1_AXR1.I2C2_SCL */ /* AQUILA C6 */ + J784S4_IOPAD(0x050, PIN_INPUT_PULLUP, 13) /* (AC37) MCASP1_AXR2.I2C2_SDA */ /* AQUILA C5 */ + >; + }; + + /* Aquila I2C_6 */ + pinctrl_main_i2c5: main-i2c5-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x01c, PIN_INPUT_PULLUP, 8) /* (AG34) MCAN15_TX.I2C5_SCL */ /* AQUILA C19 */ + J784S4_IOPAD(0x018, PIN_INPUT_PULLUP, 8) /* (AK36) MCAN14_RX.I2C5_SDA */ /* AQUILA C18 */ + >; + }; + + /* Aquila I2S_1_MCLK */ + pinctrl_audio_extrefclk1: audio-extrefclk1-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x078, PIN_OUTPUT, 1) /* (AH37) MCAN2_RX.AUDIO_EXT_REFCLK1 */ /* AQUILA B24 */ + >; + }; + + /* Aquila CAN_1 */ + pinctrl_main_mcan10: main-mcan10-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0b8, PIN_INPUT, 0) /* (AC34) MCASP1_ACLKX.MCAN10_RX */ /* AQUILA B49 */ + J784S4_IOPAD(0x0b4, PIN_OUTPUT, 0) /* (AL34) MCASP1_AXR4.MCAN10_TX */ /* AQUILA B48 */ + >; + }; + + /* Aquila CAN_3 */ + pinctrl_main_mcan13: main-mcan13-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x010, PIN_INPUT, 0) /* (AH33) MCAN13_RX */ /* AQUILA B54 */ + J784S4_IOPAD(0x00c, PIN_OUTPUT, 0) /* (AF33) MCAN13_TX */ /* AQUILA B53 */ + >; + }; + + /* Aquila I2S_1 */ + pinctrl_main_mcasp4: main-mcasp4-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0c8, PIN_INPUT, 1) /* (AJ32) EXT_REFCLK1.MCASP4_ACLKX */ /* AQUILA B20 */ + J784S4_IOPAD(0x06c, PIN_INPUT, 1) /* (AJ37) MCAN1_TX.MCASP4_AFSX */ /* AQUILA B21 */ + J784S4_IOPAD(0x068, PIN_OUTPUT, 1) /* (AE38) MCAN0_RX.MCASP4_AXR1 */ /* AQUILA B22 */ + J784S4_IOPAD(0x0c4, PIN_INPUT, 1) /* (AD36) ECAP0_IN_APWM_OUT.MCASP4_AXR2 */ /* AQUILA B23 */ + >; + }; + + /* Aquila ETH_2_XGMII_MDIO */ + pinctrl_main_mdio1: main-mdio1-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x058, PIN_OUTPUT, 4) /* (AE37) MCASP2_AFSX.MDIO1_MDC */ /* AQUILA B90 */ + J784S4_IOPAD(0x05c, PIN_INPUT, 4) /* (AC36) MCASP2_AXR0.MDIO1_MDIO */ /* AQUILA B89 */ + >; + }; + + /* Aquila SD_1 */ + pinctrl_main_mmc1: main-mmc1-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x104, PIN_INPUT, 0) /* (AB38) MMC1_CLK */ /* AQUILA A5 */ + J784S4_IOPAD(0x108, PIN_INPUT, 0) /* (AB36) MMC1_CMD */ /* AQUILA A7 */ + J784S4_IOPAD(0x100, PIN_INPUT, 0) /* (No Pin) MMC1_CLKLB */ + J784S4_IOPAD(0x0fc, PIN_INPUT, 0) /* (AA33) MMC1_DAT0 */ /* AQUILA A3 */ + J784S4_IOPAD(0x0f8, PIN_INPUT, 0) /* (AB34) MMC1_DAT1 */ /* AQUILA A2 */ + J784S4_IOPAD(0x0f4, PIN_INPUT, 0) /* (AA32) MMC1_DAT2 */ /* AQUILA A10 */ + J784S4_IOPAD(0x0f0, PIN_INPUT, 0) /* (AC38) MMC1_DAT3 */ /* AQUILA A8 */ + >; + }; + + /* Aquila SPI_2 */ + pinctrl_main_spi0: main-spi0-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0d4, PIN_OUTPUT, 0) /* (AN38) SPI0_CLK */ /* AQUILA D14 */ + J784S4_IOPAD(0x0d8, PIN_INPUT, 0) /* (AM35) SPI0_D0 */ /* AQUILA D15 */ + J784S4_IOPAD(0x0dc, PIN_OUTPUT, 0) /* (AM36) SPI0_D1 */ /* AQUILA D17 */ + >; + }; + + /* Aquila SPI_2 CS */ + pinctrl_main_spi0_cs0: main-spi0-cs0-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0cc, PIN_OUTPUT, 0) /* (AM37) SPI0_CS0 */ /* AQUILA D16 */ + >; + }; + + /* Aquila SPI_1 */ + pinctrl_main_spi2: main-spi2-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x0a0, PIN_OUTPUT, 10) /* (AD34) MCASP0_AXR12.SPI2_CLK */ /* AQUILA D12 */ + J784S4_IOPAD(0x0a8, PIN_INPUT, 10) /* (AF34) MCASP0_AXR14.SPI2_D0 */ /* AQUILA D10 */ + J784S4_IOPAD(0x0ac, PIN_OUTPUT, 10) /* (AE34) MCASP0_AXR15.SPI2_D1 */ /* AQUILA D11 */ + >; + }; + + /* Aquila SPI_1 CS */ + pinctrl_main_spi2_cs0: main-spi2-cs0-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x09c, PIN_OUTPUT, 10) /* (AF35) MCASP0_AXR11.SPI2_CS1 */ /* AQUILA D9 */ + >; + }; + + /* Aquila UART_1 */ + pinctrl_main_uart4: main-uart4-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x094, PIN_INPUT, 11) /* (AG35) MCASP0_AXR9.UART4_CTSn */ /* AQUILA B36 */ + J784S4_IOPAD(0x098, PIN_OUTPUT, 11) /* (AH36) MCASP0_AXR10.UART4_RTSn */ /* AQUILA B38 */ + J784S4_IOPAD(0x08c, PIN_INPUT, 11) /* (AE35) MCASP0_AXR7.UART4_RXD */ /* AQUILA B35 */ + J784S4_IOPAD(0x090, PIN_OUTPUT, 11) /* (AC35) MCASP0_AXR8.UART4_TXD */ /* AQUILA B37 */ + >; + }; + + /* Aquila UART_3, used as the Linux console */ + pinctrl_main_uart8: main-uart8-default-pins { + pinctrl-single,pins = < + J784S4_IOPAD(0x038, PIN_INPUT, 11) /* (AK35) MCASP0_ACLKX.UART8_RXD */ /* AQUILA D19 */ + J784S4_IOPAD(0x03c, PIN_OUTPUT, 11) /* (AK38) MCASP0_AFSX.UART8_TXD */ /* AQUILA D20 */ + >; + }; +}; + +&wkup_pmx0 { + /* Aquila QSPI_1 (4-bit) */ + pinctrl_mcu_ospi0_4bit: mcu-ospi0-4bit-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (E32) MCU_OSPI0_CLK */ /* AQUILA B65 */ + J784S4_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (B33) MCU_OSPI0_D0 */ /* AQUILA B68 */ + J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (B32) MCU_OSPI0_D1 */ /* AQUILA B67 */ + J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (C33) MCU_OSPI0_D2 */ /* AQUILA B61 */ + J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (C35) MCU_OSPI0_D3 */ /* AQUILA B60 */ + J784S4_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (C34) MCU_OSPI0_DQS */ /* AQUILA B63 */ + >; + }; + + /* Aquila QSPI_1 (8-bit) */ + pinctrl_mcu_ospi0_8bit: mcu-ospi0-8bit-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (E32) MCU_OSPI0_CLK */ /* AQUILA B65 */ + J784S4_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (B33) MCU_OSPI0_D0 */ /* AQUILA B68 */ + J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (B32) MCU_OSPI0_D1 */ /* AQUILA B67 */ + J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (C33) MCU_OSPI0_D2 */ /* AQUILA B61 */ + J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (C35) MCU_OSPI0_D3 */ /* AQUILA B60 */ + J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (D33) MCU_OSPI0_D4 */ /* AQUILA B70 */ + J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D34) MCU_OSPI0_D5 */ /* AQUILA B71 */ + J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (E34) MCU_OSPI0_D6 */ /* AQUILA B72 */ + J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (E33) MCU_OSPI0_D7 */ /* AQUILA B73 */ + J784S4_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (C34) MCU_OSPI0_DQS */ /* AQUILA B63 */ + >; + }; + + /* Aquila QSPI_1_CS1# */ + pinctrl_mcu_ospi0_cs0: mcu-ospi0-cs0-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (A32) MCU_OSPI0_CSn0 */ /* AQUILA B66 */ + >; + }; + + /* Aquila QSPI_1_CS2# */ + pinctrl_mcu_ospi0_cs1: mcu-ospi0-cs1-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x030, PIN_OUTPUT, 0) /* (A33) MCU_OSPI0_CSn1 */ /* AQUILA B62 */ + >; + }; + + /* Aquila QSPI_1_SCK as GPIO */ + pinctrl_wkup_gpio_16: wkup-gpio0-16-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x000, PIN_INPUT, 7) /* (E32) MCU_OSPI0_CLK.WKUP_GPIO0_16 */ /* AQUILA B65 */ + >; + }; + + /* Aquila GPIO_04 */ + pinctrl_gpio_04: wkup-gpio0-17-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x004, PIN_INPUT, 7) /* (D32) MCU_OSPI0_LBCLKO.WKUP_GPIO0_17 */ /* AQUILA C20 */ + >; + }; + + /* Aquila QSPI_1_DQS as GPIO */ + pinctrl_wkup_gpio_18: wkup-gpio0-18-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x008, PIN_INPUT, 7) /* (C34) MCU_OSPI0_DQS.WKUP_GPIO0_18 */ /* AQUILA B63 */ + >; + }; + + /* Aquila QSPI_1_IO0 as GPIO */ + pinctrl_wkup_gpio_19: wkup-gpio0-19-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x00c, PIN_INPUT, 7) /* (B33) MCU_OSPI0_D0.WKUP_GPIO0_19 */ /* AQUILA B68 */ + >; + }; + + /* Aquila QSPI_1_IO1 as GPIO */ + pinctrl_wkup_gpio_20: wkup-gpio0-20-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 7) /* (B32) MCU_OSPI0_D1.WKUP_GPIO0_20 */ /* AQUILA B67 */ + >; + }; + + /* Aquila QSPI_1_IO2 as GPIO */ + pinctrl_wkup_gpio_21: wkup-gpio0-21-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 7) /* (C33) MCU_OSPI0_D2.WKUP_GPIO0_21 */ /* AQUILA B61 */ + >; + }; + + /* Aquila QSPI_1_IO3 as GPIO */ + pinctrl_wkup_gpio_22: wkup-gpio0-22-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 7) /* (C35) MCU_OSPI0_D3.WKUP_GPIO0_22 */ /* AQUILA B60 */ + >; + }; + + /* Aquila QSPI_1_IO4 as GPIO */ + pinctrl_wkup_gpio_23: wkup-gpio0-23-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 7) /* (D33) MCU_OSPI0_D4.WKUP_GPIO0_23 */ /* AQUILA B70 */ + >; + }; + + /* Aquila QSPI_1_IO5 as GPIO */ + pinctrl_wkup_gpio_24: wkup-gpio0-24-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 7) /* (D34) MCU_OSPI0_D5.WKUP_GPIO0_24 */ /* AQUILA B71 */ + >; + }; + + /* Aquila QSPI_1_IO6 as GPIO */ + pinctrl_wkup_gpio_25: wkup-gpio0-25-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 7) /* (E34) MCU_OSPI0_D6.WKUP_GPIO0_25 */ /* AQUILA B72 */ + >; + }; + + /* Aquila QSPI_1_IO7 as GPIO */ + pinctrl_wkup_gpio_26: wkup-gpio0-26-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 7) /* (E33) MCU_OSPI0_D7.WKUP_GPIO0_26 */ /* AQUILA B73 */ + >; + }; + + /* Aquila QSPI_1_CS#1 as GPIO */ + pinctrl_wkup_gpio_27: wkup-gpio0-27-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x02c, PIN_INPUT, 7) /* (A32) MCU_OSPI0_CSn0.WKUP_GPIO0_27 */ /* AQUILA B66 */ + >; + }; + + /* Aquila QSPI_1_CS#2 as GPIO */ + pinctrl_wkup_gpio_28: wkup-gpio0-28-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x030, PIN_INPUT, 7) /* (A33) MCU_OSPI0_CSn1.WKUP_GPIO0_28 */ /* AQUILA B62 */ + >; + }; +}; + +&wkup_pmx1 { + /* Aquila UART_4 (RXD) */ + pinctrl_mcu_uart0_rx: mcu-uart0-rx-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 4) /* (D31) MCU_OSPI1_D1.MCU_UART0_RXD */ /* AQUILA D21 */ + >; + }; + + /* Aquila GPIO_05 */ + pinctrl_gpio_05: wkup-gpio0-29-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x000, PIN_INPUT, 7) /* (B34) MCU_OSPI0_CSn2.WKUP_GPIO0_29 */ /* AQUILA C21 */ + >; + }; + + /* Aquila GPIO_06 */ + pinctrl_gpio_06: wkup-gpio0-30-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x004, PIN_INPUT, 7) /* (C32) MCU_OSPI0_CSn3.WKUP_GPIO0_30 */ /* AQUILA C22 */ + >; + }; + + /* Aquila GPIO_07 */ + pinctrl_gpio_07: wkup-gpio0-31-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x008, PIN_INPUT, 7) /* (F32) MCU_OSPI1_CLK.WKUP_GPIO0_31 */ /* AQUILA C23 */ + >; + }; + + /* Aquila GPIO_13_CSI_2 */ + pinctrl_gpio_13_csi_2: wkup-gpio0-32-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x00c, PIN_INPUT, 7) /* (C31) MCU_OSPI1_LBCLKO.WKUP_GPIO0_32 */ /* AQUILA C1 */ + >; + }; + + /* Aquila GPIO_14_CSI_2 */ + pinctrl_gpio_14_csi_2: wkup-gpio0-33-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 7) /* (F31) MCU_OSPI1_DQS.WKUP_GPIO0_33 */ /* AQUILA C2 */ + >; + }; + + /* RTC_IRQ# */ + pinctrl_rtc_irq: wkup-gpio0-34-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 7) /* (E35) MCU_OSPI1_D0.WKUP_GPIO0_34 */ + >; + }; + + /* Aquila CTRL_PWR_BTN_MICO# (PWR_BTN_INT#) */ + pinctrl_pwr_btn_int: wkup-gpio0-36-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x01c, PIN_INPUT_PULLUP, 7) /* (G31) MCU_OSPI1_D2.WKUP_GPIO0_36 */ /* AQUILA B92 */ + >; + }; + + /* Aquila GPIO_15_CSI_2 */ + pinctrl_gpio_15_csi_2: wkup-gpio0-37-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 7) /* (F33) MCU_OSPI1_D3.WKUP_GPIO0_37 */ /* AQUILA C3 */ + >; + }; + + /* Aquila GPIO_08 */ + pinctrl_gpio_08: wkup-gpio0-38-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 7) /* (G32) MCU_OSPI1_CSn0.WKUP_GPIO0_38 */ /* AQUILA C24 */ + >; + }; + + /* Aquila GPIO_16_CSI_2 */ + pinctrl_gpio_16_csi_2: wkup-gpio0-39-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 7) /* (G33) MCU_OSPI1_CSn1.WKUP_GPIO0_39 */ /* AQUILA C4 */ + >; + }; +}; + +&wkup_pmx2 { + /* Aquila ADC_[1-4] */ + pinctrl_mcu_adc0: mcu-adc0-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x0cc, PIN_OUTPUT, 0) /* (P36) MCU_ADC0_AIN0 */ /* AQUILA D1 */ + J784S4_WKUP_IOPAD(0x0d0, PIN_OUTPUT, 0) /* (V36) MCU_ADC0_AIN1 */ /* AQUILA D2 */ + J784S4_WKUP_IOPAD(0x0d4, PIN_OUTPUT, 0) /* (T34) MCU_ADC0_AIN2 */ /* AQUILA D3 */ + J784S4_WKUP_IOPAD(0x0d8, PIN_OUTPUT, 0) /* (T36) MCU_ADC0_AIN3 */ /* AQUILA D4 */ + >; + }; + + /* Aquila CTRL_MCLK_MOCI */ + pinctrl_mcu_clkout0: mcu-clkout0-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x084, PIN_OUTPUT, 6) /* (M38) WKUP_GPIO0_11.MCU_CLKOUT0 */ /* AQUILA A14 */ + >; + }; + + /* Aquila I2C_1 */ + pinctrl_mcu_i2c0: mcu-i2c0-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x0a0, PIN_INPUT, 0) /* (M35) MCU_I2C0_SCL */ /* AQUILA D8 */ + J784S4_WKUP_IOPAD(0x0a4, PIN_INPUT, 0) /* (G34) MCU_I2C0_SDA */ /* AQUILA D7 */ + >; + }; + + /* Aquila I2C_2 */ + pinctrl_mcu_i2c1: mcu-i2c1-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x078, PIN_INPUT_PULLUP, 0) /* (L35) WKUP_GPIO0_8.MCU_I2C1_SCL */ /* AQUILA C17 */ + J784S4_WKUP_IOPAD(0x07c, PIN_INPUT_PULLUP, 0) /* (L34) WKUP_GPIO0_9.MCU_I2C1_SDA */ /* AQUILA C16 */ + >; + }; + + /* Aquila CAN_2 */ + pinctrl_mcu_mcan0: mcu-mcan0-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x054, PIN_INPUT, 0) /* (F38) MCU_MCAN0_RX */ /* AQUILA B51 */ + J784S4_WKUP_IOPAD(0x050, PIN_OUTPUT, 0) /* (K33) MCU_MCAN0_TX */ /* AQUILA B50 */ + >; + }; + + /* Aquila CAN_4 */ + pinctrl_mcu_mcan1: mcu-mcan1-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (K36) WKUP_GPIO0_5.MCU_MCAN1_RX */ /* AQUILA B56 */ + J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0) /* (H35) WKUP_GPIO0_4.MCU_MCAN1_TX */ /* AQUILA B55 */ + >; + }; + + /* On-module ETH_1 MDIO */ + pinctrl_mcu_mdio: mcu-mdio-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x034, PIN_OUTPUT, 0) /* (A36) MCU_MDIO0_MDC */ + J784S4_WKUP_IOPAD(0x030, PIN_INPUT, 0) /* (B35) MCU_MDIO0_MDIO */ + >; + }; + + /* On-module ETH_1 RGMII */ + pinctrl_mcu_rgmii1: mcu-rgmii1-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x02c, PIN_INPUT, 0) /* (A35) MCU_RGMII1_RD0 */ + J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (B36) MCU_RGMII1_RD1 */ + J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (C36) MCU_RGMII1_RD2 */ + J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D36) MCU_RGMII1_RD3 */ + J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (B37) MCU_RGMII1_RXC */ + J784S4_WKUP_IOPAD(0x004, PIN_INPUT, 0) /* (C37) MCU_RGMII1_RX_CTL */ + J784S4_WKUP_IOPAD(0x014, PIN_OUTPUT, 0) /* (D37) MCU_RGMII1_TD0 */ + J784S4_WKUP_IOPAD(0x010, PIN_OUTPUT, 0) /* (D38) MCU_RGMII1_TD1 */ + J784S4_WKUP_IOPAD(0x00c, PIN_OUTPUT, 0) /* (E37) MCU_RGMII1_TD2 */ + J784S4_WKUP_IOPAD(0x008, PIN_OUTPUT, 0) /* (E38) MCU_RGMII1_TD3 */ + J784S4_WKUP_IOPAD(0x018, PIN_OUTPUT, 0) /* (E36) MCU_RGMII1_TXC */ + J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (C38) MCU_RGMII1_TX_CTL */ + >; + }; + + /* On-module SPI (TPM_SPI) */ + pinctrl_mcu_spi0: mcu-spi0-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x038, PIN_OUTPUT, 0) /* (G38) MCU_SPI0_CLK */ + J784S4_WKUP_IOPAD(0x044, PIN_OUTPUT, 0) /* (F37) MCU_SPI0_CS0 */ + J784S4_WKUP_IOPAD(0x03c, PIN_INPUT, 0) /* (H36) MCU_SPI0_D0 */ + J784S4_WKUP_IOPAD(0x040, PIN_OUTPUT, 0) /* (J38) MCU_SPI0_D1 */ + >; + }; + + /* Aquila UART_4 (TX) */ + pinctrl_mcu_uart0_tx: mcu-uart0-tx-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x080, PIN_OUTPUT, 2) /* (L33) WKUP_GPIO0_10.MCU_UART0_TXD */ /* AQUILA D22 */ + >; + }; + + /* On-module Wi-Fi Power Enable */ + pinctrl_en_3v3_wifi: wkup-gpio0-57-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x114, PIN_INPUT, 7) /* (M36) WKUP_GPIO0_57 */ + >; + }; + + /* On-module TPM IRQ# */ + pinctrl_tpm_irq: wkup-gpio0-81-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x0f4, PIN_INPUT, 7) /* (V34) MCU_ADC1_AIN2.WKUP_GPIO0_81 */ + >; + }; + + /* On-module I2C - WKUP_I2C0 */ + pinctrl_wkup_i2c0: wkup-i2c0-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x098, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */ + J784S4_WKUP_IOPAD(0x09c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */ + >; + }; + + /* Aquila UART_2 */ + pinctrl_wkup_uart0: wkup-uart0-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_GPIO0_6.WKUP_UART0_CTSn */ /* AQUILA B32 */ + J784S4_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (L36) WKUP_GPIO0_7.WKUP_UART0_RTSn */ /* AQUILA B34 */ + J784S4_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */ /* AQUILA B31 */ + J784S4_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (K34) WKUP_UART0_TXD */ /* AQUILA B33 */ + >; + }; +}; + +&wkup_pmx3 { + /* Aquila CTRL_WAKE1_MICO# */ + pinctrl_ctrl_wake1_mico: wkup-gpio0-49-default-pins { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x000, PIN_INPUT_PULLUP, 7) /* (M33) WKUP_GPIO0_49 */ /* AQUILA D6 */ + >; + }; +}; + +/* Aquila I2S_1_MCLK */ +&audio_refclk1 { + assigned-clock-rates = <24576000>; +}; + +/* On-module ETH_1 MDIO */ +&davinci_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_mdio>; + status = "disabled"; + + mcu_phy0: ethernet-phy@0 { + reg = <0>; + interrupt-parent = <&wkup_gpio0>; + interrupts = <79 IRQ_TYPE_EDGE_FALLING>; + ti,rx-internal-delay = ; + ti,fifo-depth = ; + }; +}; + +&dss { + assigned-clocks = <&k3_clks 218 2>, + <&k3_clks 218 5>; + assigned-clock-parents = <&k3_clks 218 3>, + <&k3_clks 218 7>; + status = "disabled"; +}; + +&dss_ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dpi0_out: endpoint { + remote-endpoint = <&dp0_in>; + }; + }; +}; + +&dp0_ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dp0_in: endpoint { + remote-endpoint = <&dpi0_out>; + }; + }; +}; + +&main0_crit { + temperature = <105000>; +}; + +&main0_thermal { + trips { + main0_alert0: trip-point0 { + temperature = <70000>; + hysteresis = <2000>; + type = "active"; + }; + + main0_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "active"; + }; + }; +}; + +&main1_crit { + temperature = <105000>; +}; + +&main1_thermal { + trips { + main1_alert0: trip-point0 { + temperature = <70000>; + hysteresis = <2000>; + type = "active"; + }; + + main1_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "active"; + }; + }; +}; + +&main2_crit { + temperature = <105000>; +}; + +&main2_thermal { + trips { + main2_alert0: trip-point0 { + temperature = <70000>; + hysteresis = <2000>; + type = "active"; + }; + + main2_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "active"; + }; + }; +}; + +&main3_crit { + temperature = <105000>; +}; + +&main3_thermal { + trips { + main3_alert0: trip-point0 { + temperature = <70000>; + hysteresis = <2000>; + type = "active"; + }; + + main3_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "active"; + }; + }; +}; + +&main4_crit { + temperature = <105000>; +}; + +&main4_thermal { + trips { + main4_alert0: trip-point0 { + temperature = <70000>; + hysteresis = <2000>; + type = "active"; + }; + + main4_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "active"; + }; + }; +}; + +/* Aquila ETH_2 SGMII PHY */ +&main_cpsw0_port8 { + phy-mode = "sgmii"; + phys = <&cpsw0_phy_gmii_sel 8>, <&serdes2_sgmii_link>; + phy-names = "mac", "serdes"; + status = "disabled"; +}; + +/* Aquila ETH_2_XGMII_MDIO */ +&main_cpsw0_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_mdio1>; +}; + +/* Aquila PWM_1 */ +&main_ehrpwm0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_ehrpwm0_b>; + status = "disabled"; +}; + +/* Aquila PWM_2 */ +&main_ehrpwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_ehrpwm1_a>; + status = "disabled"; +}; + +/* Aquila PWM_4_DP */ +&main_ehrpwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_ehrpwm2_a>; + status = "disabled"; +}; + +/* Aquila PWM_3_DSI */ +&main_ehrpwm5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_ehrpwm5_a>; + status = "disabled"; +}; + +&main_gpio0 { + gpio-line-names = + "", /* 0 */ + "AQUILA_B17", + "AQUILA_B18", + "AQUILA_B53", + "AQUILA_B54", + "AQUILA_B59", + "AQUILA_C18", + "AQUILA_C19", + "AQUILA_A13", + "AQUILA_A12", + "AQUILA_B75", /* 10 */ + "AQUILA_B77", + "AQUILA_B42", + "AQUILA_B44", + "AQUILA_D19", + "AQUILA_D20", + "AQUILA_B58", + "AQUILA_D24", + "AQUILA_B45", + "AQUILA_C06", + "AQUILA_C05", /* 20 */ + "AQUILA_B57", + "AQUILA_B90", + "AQUILA_B89", + "AQUILA_C26", + "AQUILA_C25", + "AQUILA_B22", + "AQUILA_B21", + "AQUILA_B74", + "AQUILA_D25", + "AQUILA_B24", /* 30 */ + "AQUILA_B43", + "AQUILA_C38", + "AQUILA_B46", + "AQUILA_D23", + "AQUILA_B35", + "AQUILA_B37", + "AQUILA_B36", + "AQUILA_B38", + "AQUILA_D09", + "AQUILA_D12", /* 40 */ + "AQUILA_C35", + "AQUILA_D10", + "AQUILA_D11", + "AQUILA_B81", + "AQUILA_B48", + "AQUILA_B49", + "AQUILA_A11", + "AQUILA_B19", + "AQUILA_B23", + "AQUILA_B20", /* 50 */ + "AQUILA_D16", + "AQUILA_A06", + "AQUILA_D14", + "AQUILA_D15", + "AQUILA_D17", + "AQUILA_B41", + "AQUILA_B40", + "AQUILA_A01", + "", + "AQUILA_A08", /* 60 */ + "AQUILA_A10", + "AQUILA_A02", + "AQUILA_A03", + "AQUILA_A05", + "AQUILA_A07"; + + status = "okay"; +}; + +/* Aquila I2C_3_DSI1 */ +&main_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_i2c0>; + clock-frequency = <100000>; + status = "disabled"; +}; + +/* Aquila I2C_4_CSI1 */ +&main_i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_i2c1>; + clock-frequency = <400000>; + status = "disabled"; +}; + +/* Aquila I2C_5_CSI2 */ +&main_i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_i2c2>; + clock-frequency = <400000>; + status = "disabled"; +}; + +/* Aquila I2C_6 */ +&main_i2c5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_i2c5>; + clock-frequency = <400000>; + status = "disabled"; +}; + +/* Aquila CAN_1 */ +&main_mcan10 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_mcan10>; + status = "disabled"; +}; + +/* Aquila CAN_3 */ +&main_mcan13 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_mcan13>; + status = "disabled"; +}; + +/* On-module eMMC */ +&main_sdhci0 { + disable-wp; + non-removable; + ti,driver-strength-ohm = <50>; + status = "okay"; +}; + +/* Aquila SD_1 */ +&main_sdhci1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_mmc1>, <&pinctrl_sd1_cd_gpio>; + cd-gpios = <&main_gpio0 58 GPIO_ACTIVE_LOW>; + disable-wp; + vmmc-supply = <®_sdhc1_vmmc>; + vqmmc-supply = <®_sdhc1_vqmmc>; + ti,driver-strength-ohm = <50>; + ti,fails-without-test-cd; + status = "disabled"; +}; + +/* Aquila SPI_2 */ +&main_spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_spi0>, <&pinctrl_main_spi0_cs0>; + status = "disabled"; +}; + +/* Aquila SPI_1 */ +&main_spi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_spi2>, <&pinctrl_main_spi2_cs0>; + status = "disabled"; +}; + +/* Aquila UART_1 */ +&main_uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_uart4>; + status = "disabled"; +}; + +/* Aquila UART_3, used as the Linux console */ +&main_uart8 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_uart8>; + status = "disabled"; +}; + +/* Aquila I2S_1 */ +&mcasp4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_mcasp4>; + op-mode = <0>; /* MCASP_I2S_MODE */ + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 1 2 0 + 0 0 0 0 + 0 0 0 0 + 0 0 0 0 + >; + tdm-slots = <2>; + #sound-dai-cells = <0>; + status = "disabled"; +}; + +&mcu_cpsw { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_rgmii1>; + status = "disabled"; +}; + +/* On-module ETH_1 RGMII */ +&mcu_cpsw_port1 { + phy-handle = <&mcu_phy0>; + phy-mode = "rgmii-id"; + status = "disabled"; +}; + +/* Aquila I2C_1 */ +&mcu_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_i2c0>; + clock-frequency = <400000>; + status = "disabled"; +}; + +/* Aquila I2C_2 */ +&mcu_i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_i2c1>; + clock-frequency = <400000>; + status = "disabled"; +}; + +/* Aquila CAN_2 */ +&mcu_mcan0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_mcan0>; + status = "disabled"; +}; + +/* Aquila CAN_4 */ +&mcu_mcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_mcan1>; + status = "disabled"; +}; + +/* On-module SPI (TPM_SPI) */ +&mcu_spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_spi0>; + status = "okay"; + + tpm@0 { + compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tpm_irq>; + interrupt-parent = <&wkup_gpio0>; + interrupts = <81 IRQ_TYPE_EDGE_FALLING>; + spi-max-frequency = <33000000>; + }; +}; + +/* Aquila UART_4 */ +&mcu_uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_uart0_rx>, <&pinctrl_mcu_uart0_tx>; + status = "disabled"; +}; + +&mhdp { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_main_dp0_hpd>; + phy-names = "dpphy"; + phys = <&serdes4_dp0_link>; + status = "disabled"; +}; + +/* Aquila QSPI_1 */ +&ospi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_ospi0_8bit>, <&pinctrl_mcu_ospi0_cs0>; + status = "disabled"; +}; + +/* Aquila PCIE_1 */ +&pcie0_rc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie0_reset>; + clocks = <&k3_clks 332 0>, <&serdes1 CDNS_TORRENT_REFCLK_DRIVER>; + clock-names = "fck", "pcie_refclk"; + num-lanes = <2>; + phy-names = "pcie-phy"; + phys = <&serdes1_pcie0_2l_link>; + reset-gpios = <&main_gpio0 32 GPIO_ACTIVE_HIGH>; + ti,syscon-acspcie-proxy-ctrl = <&acspcie1_proxy_ctrl 0x3>; + status = "disabled"; +}; + +/* Aquila PCIE_2 */ +&pcie1_rc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie1_reset>; + clocks = <&k3_clks 333 0>, <&serdes0 CDNS_TORRENT_REFCLK_DRIVER>; + clock-names = "fck", "pcie_refclk"; + num-lanes = <2>; + phy-names = "pcie-phy"; + phys = <&serdes0_pcie1_2l_link>; + reset-gpios = <&main_gpio0 41 GPIO_ACTIVE_HIGH>; + ti,syscon-acspcie-proxy-ctrl = <&acspcie0_proxy_ctrl 0x3>; + status = "disabled"; +}; + +/* On-module PCIe USB Bridge */ +&pcie2_rc { + clocks = <&k3_clks 334 0>, <&serdes1 CDNS_TORRENT_REFCLK_DRIVER>; + clock-names = "fck", "pcie_refclk"; + num-lanes = <1>; + phy-names = "pcie-phy"; + phys = <&serdes1_pcie2_1l_link>; + reset-gpios = <&som_gpio_expander 3 GPIO_ACTIVE_HIGH>; + ti,syscon-acspcie-proxy-ctrl = <&acspcie1_proxy_ctrl 0x3>; + status = "okay"; + + pci@0,0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + + usb@0 { + compatible = "pci104c,8241"; + reg = <0x0 0x0 0x0 0x0 0x0>; + ti,pwron-active-high; + }; + }; +}; + +/* PCIE for On-module Wi-Fi */ +&pcie3_rc { + clocks = <&k3_clks 335 0>, <&serdes0 CDNS_TORRENT_REFCLK_DRIVER>; + clock-names = "fck", "pcie_refclk"; + num-lanes = <1>; + phy-names = "pcie-phy"; + phys = <&serdes0_pcie3_1l_link>; + reset-gpios = <&som_gpio_expander 4 GPIO_ACTIVE_HIGH>; + ti,syscon-acspcie-proxy-ctrl = <&acspcie0_proxy_ctrl 0x3>; + status = "okay"; +}; + +&serdes0 { + status = "okay"; + + /* Aquila PCIE_2 */ + serdes0_pcie1_2l_link: phy@0 { + reg = <0>; + #phy-cells = <0>; + resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>; + cdns,num-lanes = <2>; + cdns,phy-type = ; + }; + + /* On-module PCIe Wi-Fi */ + serdes0_pcie3_1l_link: phy@2 { + reg = <2>; + #phy-cells = <0>; + resets = <&serdes_wiz0 3>; + cdns,num-lanes = <1>; + cdns,phy-type = ; + }; + + /* Aquila USB0 SS */ + serdes0_usb0_ss_link: phy@3 { + reg = <3>; + #phy-cells = <0>; + resets = <&serdes_wiz0 4>; + cdns,num-lanes = <1>; + cdns,phy-type = ; + }; +}; + +&serdes1 { + status = "okay"; + + /* Aquila PCIE_1 */ + serdes1_pcie0_2l_link: phy@0 { + reg = <0>; + #phy-cells = <0>; + resets = <&serdes_wiz1 1>, <&serdes_wiz1 2>; + cdns,num-lanes = <2>; + cdns,phy-type = ; + }; + + /* On-module PCIe USB Bridge */ + serdes1_pcie2_1l_link: phy@2 { + reg = <2>; + #phy-cells = <0>; + resets = <&serdes_wiz1 3>; + cdns,num-lanes = <1>; + cdns,phy-type = ; + }; +}; + +&serdes2 { + status = "disabled"; + + /* Aquila ETH_2 xGMII */ + serdes2_sgmii_link: phy@3 { + reg = <3>; + #phy-cells = <0>; + resets = <&serdes_wiz2 4>; + cdns,num-lanes = <1>; + cdns,phy-type = ; + }; +}; + +&serdes4 { + status = "disabled"; + + /* Aquila DP_1 */ + serdes4_dp0_link: phy@0 { + reg = <0>; + #phy-cells = <0>; + resets = <&serdes_wiz4 1>, <&serdes_wiz4 2>, + <&serdes_wiz4 3>, <&serdes_wiz4 4>; + cdns,max-bit-rate = <5400>; + cdns,num-lanes = <4>; + cdns,phy-type = ; + }; +}; + +&serdes_refclk { + clock-frequency = <100000000>; + status = "okay"; +}; + +&serdes_ln_ctrl { + idle-states = , /* Aquila PCIE_2 L0 */ + , /* Aquila PCIE_2 L1 */ + , /* On-module PCIe Wi-Fi */ + , /* Aquila USB0 SS */ + , /* Aquila PCIE_1 L0 */ + , /* Aquila PCIE_1 L1 */ + , /* On-module PCIe USB Bridge */ + , /* Aquila SGMII MSP_9 */ + , /* Aquila SGMII MSP_6 */ + , /* Aquila SGMII MSP_7 */ + , /* Aquila SGMII MSP_8 */ + , /* Aquila ETH_2 xGMII */ + , /* Aquila DP L0 */ + , /* Aquila DP L1 */ + , /* Aquila DP L2 */ + ; /* Aquila DP L3 */ +}; + +&serdes_wiz0 { + status = "okay"; +}; + +&serdes_wiz1 { + status = "okay"; +}; + +&serdes_wiz2 { + status = "disabled"; +}; + +&serdes_wiz4 { + status = "disabled"; +}; + +/* Aquila ADC_[1-4] */ +&tscadc0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mcu_adc0>; + status = "disabled"; + + adc { + ti,adc-channels = <0 1 2 3>; + }; +}; + +&usb0 { + phys = <&serdes0_usb0_ss_link>; + phy-names = "cdns3,usb3-phy"; + dr_mode = "otg"; + maximum-speed = "super-speed"; + usb-role-switch; + status = "disabled"; +}; + +&usb_serdes_mux { + idle-states = <0>; /* USB0 to SERDES lane 3 */ +}; + +&usbss0 { + ti,vbus-divider; + status = "disabled"; +}; + +&wkup_gpio0 { + gpio-line-names = + "", /* 0 */ + "", + "", + "AQUILA_C53", + "AQUILA_B55", + "AQUILA_B56", + "AQUILA_B32", + "AQUILA_B34", + "AQUILA_C17", + "AQUILA_C16", + "AQUILA_D22", /* 10 */ + "", + "", + "", + "", + "", + "AQUILA_B65", + "AQUILA_C20", + "AQUILA_B63", + "AQUILA_B68", + "AQUILA_B67", /* 20 */ + "AQUILA_B61", + "AQUILA_B60", + "AQUILA_B70", + "AQUILA_B71", + "AQUILA_B72", + "AQUILC_B73", + "AQUILA_B66", + "AQUILA_B62", + "AQUILA_C21", + "AQUILA_C22", /* 30 */ + "AQUILA_C23", + "AQUILA_C01", + "AQUILA_C02", + "", + "AQUILA_D21", + "", + "AQUILA_C03", + "AQUILA_C24", + "AQUILA_C04", + "AQUILA_B84", /* 40 */ + "", + "AQUILA_B86", + "AQUILA_B87", + "", + "", + "AQUILA_B83", + "", + "", + "", + "", /* 50 */ + "", + "", + "", + "", + "", + "", + "", + "AQUILA_B31", + "AQUILA_B33", + "AQUILA_B50", /* 60 */ + "AQUILA_B51", + "", + "", + "", + "AQUILA_D08", + "", + "", + "", + "", + "", /* 70 */ + "AQUILA_D01", + "AQUILA_D02", + "AQUILA_D03", + "AQUILA_D04", + "AQUILA_D54", + "AQUILA_D55", + "AQUILA_C55", + "AQUILA_C56", + "", + "AQUILA_C36", /* 80 */ + "", + "", + "", + "", + "", + "", + "AQUILA_D07", + ""; + + status = "okay"; +}; + +/* On-module I2C - WKUP_I2C0 */ +&wkup_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wkup_i2c0>; + clock-frequency = <400000>; + status = "okay"; + + som_gpio_expander: gpio@21 { + compatible = "ti,tca6408"; + reg = <0x21>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "USB_MUX_SEL", + "COLD_RESET_REQ", + "PWR_DOWN_REQ", + "PCIE_3_RESET#", + "PCIE_4_RESET#", + "WIFI_DISABLE", + "BT_DISABLE", + "SDIO_PWR_SEL_3.3V"; + }; + + rtc_i2c: rtc@32 { + compatible = "epson,rx8130"; + reg = <0x32>; + }; + + tps62873a: regulator@40 { + compatible = "ti,tps62873"; + reg = <0x40>; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <900000>; + regulator-min-microvolt = <600000>; + regulator-name = "+VDD_CPU_AVS"; + }; + + tps62873b: regulator@43 { + compatible = "ti,tps62873"; + reg = <0x43>; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <840000>; + regulator-min-microvolt = <760000>; + regulator-name = "+V0.8_VDD_CORE"; + }; + + pmic_tps6594: pmic@48 { + compatible = "ti,tps6594-q1"; + reg = <0x48>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic_int>; + interrupt-parent = <&main_gpio0>; + interrupts = <0 IRQ_TYPE_EDGE_FALLING>; + #gpio-cells = <2>; + gpio-controller; + buck12-supply = <®_vin>; + buck3-supply = <®_vin>; + buck4-supply = <®_vin>; + buck5-supply = <®_vin>; + ldo1-supply = <®_vin>; + ldo2-supply = <®_vin>; + ldo3-supply = <®_vin>; + ldo4-supply = <®_vin>; + system-power-controller; + ti,primary-pmic; + + regulators { + reg_vdd_ddr: buck12 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1100000>; + regulator-name = "+V1.1_VDD_DDR (PMIC BUCK12)"; + }; + + reg_vdd_ram: buck3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <850000>; + regulator-min-microvolt = <850000>; + regulator-name = "+V0.85_VDD_RAM (PMIC BUCK3)"; + }; + + reg_vdd_io: buck4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V1.8_VDD_IO (PMIC BUCK4)"; + }; + + reg_3v3_vio: buck5 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "+V3.3_VIO (PMIC BUCK5)"; + }; + + reg_vda_phy: ldo1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V1.8_VDA_PHY (PMIC LDO1)"; + }; + + reg_2v5_eth: ldo2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <2500000>; + regulator-min-microvolt = <2500000>; + regulator-name = "+V2.5_ETH (PMIC LDO2)"; + }; + + reg_vda_dll: ldo3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <800000>; + regulator-min-microvolt = <800000>; + regulator-name = "+V0.8_VDA_DLL (PMIC LDO3)"; + }; + + reg_vda_pll: ldo4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V0.8_VDA_PLL (PMIC LDO4)"; + }; + }; + }; + + temperature-sensor@4f { + compatible = "ti,tmp1075"; + reg = <0x4f>; + }; + + som_eeprom: eeprom@50 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&wkup0_crit { + temperature = <105000>; +}; + +&wkup0_thermal { + trips { + wkup0_alert0: trip-point0 { + temperature = <70000>; + hysteresis = <2000>; + type = "active"; + }; + + wkup0_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "active"; + }; + }; +}; + +&wkup1_crit { + temperature = <105000>; +}; + +&wkup1_thermal { + trips { + wkup1_alert0: trip-point0 { + temperature = <70000>; + hysteresis = <2000>; + type = "active"; + }; + + wkup1_alert1: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "active"; + }; + }; +}; + +&wkup_gpio_intr { + status = "okay"; +}; + +/* Aquila UART_2 */ +&wkup_uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wkup_uart0>; + status = "disabled"; +}; + +#include "k3-j784s4-j742s2-ti-ipc-firmware-common.dtsi" +#include "k3-j784s4-ti-ipc-firmware.dtsi" diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts index 5896e57b5b9ed..abe2f21e0e1db 100644 --- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts @@ -236,8 +236,8 @@ main_i2c0_pins_default: main-i2c0-default-pins { pinctrl-single,pins = < - J784S4_IOPAD(0x0e0, PIN_INPUT_PULLUP, 0) /* (AN36) I2C0_SCL */ - J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */ + J784S4_IOPAD(0x0e0, PIN_INPUT, 0) /* (AN36) I2C0_SCL */ + J784S4_IOPAD(0x0e4, PIN_INPUT, 0) /* (AP37) I2C0_SDA */ >; }; @@ -416,8 +416,8 @@ mcu_i2c0_pins_default: mcu-i2c0-default-pins { pinctrl-single,pins = < - J784S4_WKUP_IOPAD(0x0a0, PIN_INPUT_PULLUP, 0) /* (M35) MCU_I2C0_SCL */ - J784S4_WKUP_IOPAD(0x0a4, PIN_INPUT_PULLUP, 0) /* (G34) MCU_I2C0_SDA */ + J784S4_WKUP_IOPAD(0x0a0, PIN_INPUT, 0) /* (M35) MCU_I2C0_SCL */ + J784S4_WKUP_IOPAD(0x0a4, PIN_INPUT, 0) /* (G34) MCU_I2C0_SDA */ >; }; @@ -771,7 +771,7 @@ &mcu_cpsw_port1 { status = "okay"; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&mcu_phy0>; bootph-all; }; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts index f684ce6ad9ad2..3e5efdfe87f15 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts @@ -323,6 +323,7 @@ &mcu_cpsw { pinctrl-names = "default"; pinctrl-0 = <&mcu_cpsw_pins_default>, <&mcu_mdio_pins_default>; + status = "okay"; }; &davinci_mdio { @@ -334,7 +335,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&phy0>; }; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi index 692c4745040e1..fec1db8b133d3 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi @@ -432,6 +432,8 @@ "tx4", "tx5", "tx6", "tx7", "rx"; + status = "disabled"; + ethernet-ports { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts index 352fb60e6ce83..8040b6528c188 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts @@ -663,6 +663,7 @@ &mcu_cpsw { pinctrl-names = "default"; pinctrl-0 = <&mcu_cpsw_pins_default>; + status = "okay"; }; &davinci_mdio { @@ -677,7 +678,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&phy0>; }; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts index 45311438315f2..47702fb279a4a 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts @@ -769,6 +769,7 @@ &mcu_cpsw { pinctrl-names = "default"; pinctrl-0 = <&mcu_cpsw_pins_default>, <&mcu_mdio_pins_default>; + status = "okay"; }; &davinci_mdio { @@ -780,7 +781,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&phy0>; }; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-evm-gesi-exp-board.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-gesi-exp-board.dtso index f84aa9f945479..3bfe6036a8e6f 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-evm-gesi-exp-board.dtso +++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-gesi-exp-board.dtso @@ -37,7 +37,7 @@ &cpsw0_port1 { status = "okay"; phy-handle = <&cpsw9g_phy12>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; mac-address = [00 00 00 00 00 00]; phys = <&cpsw0_phy_gmii_sel 1>; }; @@ -45,7 +45,7 @@ &cpsw0_port2 { status = "okay"; phy-handle = <&cpsw9g_phy15>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; mac-address = [00 00 00 00 00 00]; phys = <&cpsw0_phy_gmii_sel 2>; }; @@ -53,7 +53,7 @@ &cpsw0_port3 { status = "okay"; phy-handle = <&cpsw9g_phy0>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; mac-address = [00 00 00 00 00 00]; phys = <&cpsw0_phy_gmii_sel 3>; }; @@ -61,7 +61,7 @@ &cpsw0_port4 { status = "okay"; phy-handle = <&cpsw9g_phy3>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; mac-address = [00 00 00 00 00 00]; phys = <&cpsw0_phy_gmii_sel 4>; }; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi index 42a21398e3893..d5e5e89be5e9f 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi @@ -551,6 +551,8 @@ "tx4", "tx5", "tx6", "tx7", "rx"; + status = "disabled"; + ethernet-ports { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts index 5e5784ef6f858..050776cb4df8f 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts @@ -474,6 +474,12 @@ J721E_IOPAD(0x234, PIN_INPUT, 7) /* (U3) EXT_REFCLK1.GPIO1_12 */ >; }; + + vdd_sd_dv_pins_default: vdd-sd-dv-default-pins { + pinctrl-single,pins = < + J721E_IOPAD(0x1dc, PIN_OUTPUT, 7) /* (Y1) SPI1_CLK.GPIO0_118 */ + >; + }; }; &wkup_pmx0 { @@ -536,12 +542,6 @@ >; }; - vdd_sd_dv_pins_default: vdd-sd-dv-default-pins { - pinctrl-single,pins = < - J721E_IOPAD(0x1dc, PIN_OUTPUT, 7) /* (Y1) SPI1_CLK.GPIO0_118 */ - >; - }; - wkup_uart0_pins_default: wkup-uart0-default-pins { pinctrl-single,pins = < J721E_WKUP_IOPAD(0xa0, PIN_INPUT, 0) /* (J29) WKUP_UART0_RXD */ @@ -1034,6 +1034,7 @@ &mcu_cpsw { pinctrl-names = "default"; pinctrl-0 = <&mcu_cpsw_pins_default>, <&mcu_mdio_pins_default>; + status = "okay"; }; &davinci_mdio { @@ -1045,7 +1046,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&phy0>; }; diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts index 9e43dcff8ef22..4fea995191136 100644 --- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts @@ -457,6 +457,7 @@ &mcu_cpsw { pinctrl-names = "default"; pinctrl-0 = <&mcu_cpsw_pins_default>, <&mcu_mdio_pins_default>; + status = "okay"; }; &davinci_mdio { @@ -469,7 +470,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&phy0>; }; diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-evm-gesi-exp-board.dtso b/arch/arm64/boot/dts/ti/k3-j721s2-evm-gesi-exp-board.dtso index 8583178fa1f3e..6869a95c62146 100644 --- a/arch/arm64/boot/dts/ti/k3-j721s2-evm-gesi-exp-board.dtso +++ b/arch/arm64/boot/dts/ti/k3-j721s2-evm-gesi-exp-board.dtso @@ -80,6 +80,6 @@ &main_cpsw_port1 { status = "okay"; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&main_cpsw_phy0>; }; diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi index 837097751c183..2a7f9c519735a 100644 --- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi @@ -552,6 +552,8 @@ "tx4", "tx5", "tx6", "tx7", "rx"; + status = "disabled"; + ethernet-ports { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts index e0e303da7e150..7baf5764862b1 100644 --- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts +++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts @@ -228,6 +228,11 @@ }; }; +&audio_refclk1 { + assigned-clocks = <&k3_clks 157 0>; + assigned-clock-parents = <&k3_clks 157 15>; +}; + &cpsw_mac_syscon { bootph-all; }; @@ -388,7 +393,7 @@ }; &cpsw_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&cpsw3g_phy0>; status = "okay"; bootph-all; diff --git a/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi b/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi index d57fdd38bdceb..873415ec4fa37 100644 --- a/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi @@ -437,24 +437,6 @@ mux-reg-masks = <0x00 0x3>, /* SERDES0 lane0 select */ <0x10 0x3>; /* SERDES1 lane0 select */ }; - - audio_refclk0: clock@82e0 { - compatible = "ti,am62-audio-refclk"; - reg = <0x82e0 0x4>; - clocks = <&k3_clks 157 0>; - assigned-clocks = <&k3_clks 157 0>; - assigned-clock-parents = <&k3_clks 157 15>; - #clock-cells = <0>; - }; - - audio_refclk1: clock@82e4 { - compatible = "ti,am62-audio-refclk"; - reg = <0x82e4 0x4>; - clocks = <&k3_clks 157 18>; - assigned-clocks = <&k3_clks 157 18>; - assigned-clock-parents = <&k3_clks 157 33>; - #clock-cells = <0>; - }; }; &wkup_conf { diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm-pcie0-pcie1-ep.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-evm-pcie0-pcie1-ep.dtso index 685305092bd88..22533d678f79c 100644 --- a/arch/arm64/boot/dts/ti/k3-j784s4-evm-pcie0-pcie1-ep.dtso +++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm-pcie0-pcie1-ep.dtso @@ -75,5 +75,6 @@ dma-coherent; phys = <&serdes0_pcie1_link>; phy-names = "pcie-phy"; + bootph-all; }; }; diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi index 419c1a70e028d..e507355777371 100644 --- a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi @@ -270,8 +270,8 @@ main_i2c0_pins_default: main-i2c0-default-pins { pinctrl-single,pins = < - J784S4_IOPAD(0x0e0, PIN_INPUT_PULLUP, 0) /* (AN36) I2C0_SCL */ - J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */ + J784S4_IOPAD(0x0e0, PIN_INPUT, 0) /* (AN36) I2C0_SCL */ + J784S4_IOPAD(0x0e4, PIN_INPUT, 0) /* (AP37) I2C0_SDA */ >; }; @@ -920,7 +920,7 @@ &mcu_cpsw_port1 { status = "okay"; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&mcu_phy0>; }; @@ -944,7 +944,7 @@ }; &main_cpsw1_port1 { - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&main_cpsw1_phy0>; status = "okay"; }; @@ -970,6 +970,7 @@ &serdes_refclk { status = "okay"; clock-frequency = <100000000>; + bootph-all; }; &dss { @@ -984,6 +985,14 @@ <&k3_clks 218 22>; }; +&pcie1_ctrl { + bootph-all; +}; + +&serdes_ln_ctrl { + bootph-all; +}; + &serdes0 { status = "okay"; @@ -993,6 +1002,7 @@ #phy-cells = <0>; cdns,phy-type = ; resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>; + bootph-all; }; serdes0_usb_link: phy@3 { diff --git a/arch/arm64/boot/dts/ti/k3-pinctrl.h b/arch/arm64/boot/dts/ti/k3-pinctrl.h index e46f7bf527019..dc8e03ae74c89 100644 --- a/arch/arm64/boot/dts/ti/k3-pinctrl.h +++ b/arch/arm64/boot/dts/ti/k3-pinctrl.h @@ -123,6 +123,8 @@ #define AM62PX_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) #define AM62PX_MCU_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) +#define AM62LX_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) + #define AM62X_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) #define AM62X_MCU_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 94d372e3b9bda..45288ec9eaf73 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -47,6 +47,7 @@ CONFIG_ARCH_BCMBCA=y CONFIG_ARCH_BRCMSTB=y CONFIG_ARCH_BERLIN=y CONFIG_ARCH_BLAIZE=y +CONFIG_ARCH_BST=y CONFIG_ARCH_CIX=y CONFIG_ARCH_EXYNOS=y CONFIG_ARCH_SPARX5=y @@ -82,8 +83,6 @@ CONFIG_ARCH_VEXPRESS=y CONFIG_ARCH_VISCONTI=y CONFIG_ARCH_XGENE=y CONFIG_ARCH_ZYNQMP=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_SMT=y CONFIG_NUMA=y CONFIG_XEN=y CONFIG_COMPAT=y @@ -211,6 +210,8 @@ CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y CONFIG_NFC=m CONFIG_NFC_NCI=m +CONFIG_NFC_NXP_NCI=m +CONFIG_NFC_NXP_NCI_I2C=m CONFIG_NFC_S3FWRN5_I2C=m CONFIG_PCI=y CONFIG_PCIEPORTBUS=y @@ -265,6 +266,7 @@ CONFIG_GOOGLE_FIRMWARE=y CONFIG_GOOGLE_CBMEM=m CONFIG_GOOGLE_COREBOOT_TABLE=m CONFIG_EFI_CAPSULE_LOADER=y +CONFIG_IMX_AIPSTZ=m CONFIG_IMX_SCU=y CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y CONFIG_QCOM_QSEECOM=y @@ -354,8 +356,10 @@ CONFIG_FSL_FMAN=y CONFIG_FSL_DPAA_ETH=y CONFIG_FSL_DPAA2_ETH=y CONFIG_FSL_ENETC=y +CONFIG_NXP_ENETC4=m CONFIG_FSL_ENETC_VF=y CONFIG_FSL_ENETC_QOS=y +CONFIG_NXP_NETC_BLK_CTRL=m CONFIG_HIX5HD2_GMAC=y CONFIG_HNS_DSAF=y CONFIG_HNS_ENET=y @@ -465,7 +469,9 @@ CONFIG_TOUCHSCREEN_GOODIX=m CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI=m CONFIG_TOUCHSCREEN_ELAN=m CONFIG_TOUCHSCREEN_EDT_FT5X06=m +CONFIG_TOUCHSCREEN_HIMAX_HX83112B=m CONFIG_INPUT_MISC=y +CONFIG_INPUT_AW86927=m CONFIG_INPUT_BBNSM_PWRKEY=m CONFIG_INPUT_PM8941_PWRKEY=y CONFIG_INPUT_PM8XXX_VIBRATOR=m @@ -602,6 +608,7 @@ CONFIG_PINCTRL_DA9062=m CONFIG_PINCTRL_MAX77620=y CONFIG_PINCTRL_RK805=m CONFIG_PINCTRL_SINGLE=y +CONFIG_PINCTRL_SX150X=m CONFIG_PINCTRL_OWL=y CONFIG_PINCTRL_S700=y CONFIG_PINCTRL_S900=y @@ -615,6 +622,7 @@ CONFIG_PINCTRL_IMX8DXL=y CONFIG_PINCTRL_IMX8ULP=y CONFIG_PINCTRL_IMX91=y CONFIG_PINCTRL_IMX93=y +CONFIG_PINCTRL_IMX_SCMI=y CONFIG_PINCTRL_MSM=y CONFIG_PINCTRL_IPQ5018=y CONFIG_PINCTRL_IPQ5332=y @@ -735,6 +743,8 @@ CONFIG_ROCKCHIP_THERMAL=m CONFIG_RCAR_THERMAL=y CONFIG_RCAR_GEN3_THERMAL=y CONFIG_RZG2L_THERMAL=y +CONFIG_RZG3E_THERMAL=y +CONFIG_RZG3S_THERMAL=m CONFIG_ARMADA_THERMAL=y CONFIG_MTK_THERMAL=m CONFIG_MTK_LVTS_THERMAL=m @@ -803,6 +813,7 @@ CONFIG_MFD_STM32_LPTIMER=m CONFIG_MFD_STM32_TIMERS=m CONFIG_MFD_WCD934X=m CONFIG_MFD_KHADAS_MCU=m +CONFIG_MFD_QCOM_PM8008=m CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_BD718XX=y @@ -828,6 +839,7 @@ CONFIG_REGULATOR_PCA9450=y CONFIG_REGULATOR_PF8X00=y CONFIG_REGULATOR_PFUZE100=y CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_QCOM_PM8008=m CONFIG_REGULATOR_QCOM_REFGEN=m CONFIG_REGULATOR_QCOM_RPMH=y CONFIG_REGULATOR_QCOM_SMD_RPM=y @@ -883,6 +895,7 @@ CONFIG_VIDEO_RENESAS_FCP=m CONFIG_VIDEO_RENESAS_FDP1=m CONFIG_VIDEO_RENESAS_VSP1=m CONFIG_VIDEO_RCAR_DRIF=m +CONFIG_VIDEO_ROCKCHIP_CIF=m CONFIG_VIDEO_ROCKCHIP_RGA=m CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m @@ -913,6 +926,7 @@ CONFIG_DRM_ROCKCHIP=m CONFIG_ROCKCHIP_VOP2=y CONFIG_ROCKCHIP_ANALOGIX_DP=y CONFIG_ROCKCHIP_CDN_DP=y +CONFIG_ROCKCHIP_DW_DP=y CONFIG_ROCKCHIP_DW_HDMI=y CONFIG_ROCKCHIP_DW_HDMI_QP=y CONFIG_ROCKCHIP_DW_MIPI_DSI=y @@ -934,11 +948,16 @@ CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m CONFIG_DRM_PANEL_EDP=m CONFIG_DRM_PANEL_HIMAX_HX8279=m +CONFIG_DRM_PANEL_HIMAX_HX83112A=m +CONFIG_DRM_PANEL_HIMAX_HX83112B=m CONFIG_DRM_PANEL_ILITEK_ILI9882T=m CONFIG_DRM_PANEL_KHADAS_TS050=m CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m +CONFIG_DRM_PANEL_NOVATEK_NT36672A=m CONFIG_DRM_PANEL_NOVATEK_NT36672E=m +CONFIG_DRM_PANEL_NOVATEK_NT37801=m CONFIG_DRM_PANEL_RAYDIUM_RM67191=m +CONFIG_DRM_PANEL_RAYDIUM_RM692E5=m CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=m CONFIG_DRM_PANEL_SITRONIX_ST7703=m CONFIG_DRM_PANEL_STARTEK_KD070FHFID015=m @@ -970,6 +989,7 @@ CONFIG_DRM_CDNS_MHDP8546=m CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE=m CONFIG_DRM_DW_HDMI_AHB_AUDIO=m CONFIG_DRM_DW_HDMI_CEC=m +CONFIG_DRM_DW_HDMI_QP_CEC=y CONFIG_DRM_IMX_DCSS=m CONFIG_DRM_V3D=m CONFIG_DRM_VC4=m @@ -992,6 +1012,7 @@ CONFIG_FB=y CONFIG_FB_EFI=y CONFIG_FB_MODE_HELPERS=y CONFIG_BACKLIGHT_PWM=m +CONFIG_BACKLIGHT_QCOM_WLED=m CONFIG_BACKLIGHT_LP855X=m CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set @@ -1001,7 +1022,10 @@ CONFIG_SND=m CONFIG_SND_ALOOP=m CONFIG_SND_HDA_TEGRA=m CONFIG_SND_HDA_CODEC_HDMI=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_AUDIO_QMI=m CONFIG_SND_SOC=m +CONFIG_SND_SOC_USB=m CONFIG_SND_BCM2835_SOC_I2S=m CONFIG_SND_SOC_FSL_ASRC=m CONFIG_SND_SOC_FSL_MICFIL=m @@ -1025,6 +1049,7 @@ CONFIG_SND_MESON_AXG_SOUND_CARD=m CONFIG_SND_MESON_GX_SOUND_CARD=m CONFIG_SND_SOC_QCOM=m CONFIG_SND_SOC_APQ8016_SBC=m +CONFIG_SND_SOC_QDSP6_USB=m CONFIG_SND_SOC_MSM8996=m CONFIG_SND_SOC_SDM845=m CONFIG_SND_SOC_SM8250=m @@ -1117,6 +1142,7 @@ CONFIG_USB_OTG=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI_RENESAS=m CONFIG_USB_XHCI_RZV2M=y +CONFIG_USB_XHCI_SIDEBAND=y CONFIG_USB_XHCI_TEGRA=y CONFIG_USB_BRCMSTB=m CONFIG_USB_EHCI_HCD=y @@ -1188,6 +1214,7 @@ CONFIG_TYPEC_MUX_GPIO_SBU=m CONFIG_TYPEC_MUX_IT5205=m CONFIG_TYPEC_MUX_NB7VPQ904M=m CONFIG_TYPEC_MUX_PS883X=m +CONFIG_TYPEC_MUX_PTN36502=m CONFIG_TYPEC_MUX_WCD939X_USBSS=m CONFIG_TYPEC_DP_ALTMODE=m CONFIG_MMC=y @@ -1225,19 +1252,24 @@ CONFIG_SCSI_UFS_BSG=y CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_UFS_CDNS_PLATFORM=m CONFIG_SCSI_UFS_QCOM=m +CONFIG_SCSI_UFS_MEDIATEK=y CONFIG_SCSI_UFS_HISI=y CONFIG_SCSI_UFS_RENESAS=m CONFIG_SCSI_UFS_TI_J721E=m CONFIG_SCSI_UFS_EXYNOS=y CONFIG_SCSI_UFS_ROCKCHIP=y +CONFIG_BLK_INLINE_ENCRYPTION=y +CONFIG_SCSI_UFS_CRYPTO=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=m CONFIG_LEDS_CLASS_MULTICOLOR=m CONFIG_LEDS_LM3692X=m CONFIG_LEDS_PCA9532=m CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_QCOM_FLASH=m CONFIG_LEDS_QCOM_LPG=m CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_DISK=y @@ -1283,6 +1315,7 @@ CONFIG_RTC_DRV_MT6397=m CONFIG_RTC_DRV_XGENE=y CONFIG_RTC_DRV_TI_K3=m CONFIG_RTC_DRV_RENESAS_RTCA3=m +CONFIG_RTC_DRV_NVIDIA_VRS10=m CONFIG_DMADEVICES=y CONFIG_DMA_BCM2835=y CONFIG_DMA_SUN6I=m @@ -1349,6 +1382,7 @@ CONFIG_CLK_IMX8MQ=y CONFIG_CLK_IMX8QXP=y CONFIG_CLK_IMX8ULP=y CONFIG_CLK_IMX93=y +CONFIG_CLK_IMX95_BLK_CTL=y CONFIG_TI_SCI_CLK=y CONFIG_COMMON_CLK_MT8192_AUDSYS=y CONFIG_COMMON_CLK_MT8192_CAMSYS=y @@ -1384,8 +1418,10 @@ CONFIG_IPQ_GCC_5424=y CONFIG_IPQ_GCC_6018=y CONFIG_IPQ_GCC_8074=y CONFIG_IPQ_GCC_9574=y +CONFIG_IPQ_NSSCC_5424=m CONFIG_IPQ_NSSCC_9574=m CONFIG_MSM_GCC_8916=y +CONFIG_MSM_GCC_8953=y CONFIG_MSM_MMCC_8994=m CONFIG_MSM_GCC_8994=y CONFIG_MSM_GCC_8996=y @@ -1425,22 +1461,26 @@ CONFIG_SDM_VIDEOCC_845=y CONFIG_SDM_DISPCC_845=y CONFIG_SDM_LPASSCC_845=m CONFIG_SDX_GCC_75=y +CONFIG_SM_CAMCC_6350=m CONFIG_SM_CAMCC_8250=m CONFIG_SM_CAMCC_8550=m CONFIG_SM_CAMCC_8650=m CONFIG_SM_DISPCC_6115=m CONFIG_SM_DISPCC_8250=y +CONFIG_SM_DISPCC_6350=m CONFIG_SM_DISPCC_8450=m CONFIG_SM_DISPCC_8550=m CONFIG_SM_DISPCC_8750=m CONFIG_SM_GCC_4450=y CONFIG_SM_GCC_6115=y +CONFIG_SM_GCC_6350=y CONFIG_SM_GCC_8350=y CONFIG_SM_GCC_8450=y CONFIG_SM_GCC_8550=y CONFIG_SM_GCC_8650=y CONFIG_SM_GCC_8750=y CONFIG_SM_GPUCC_6115=m +CONFIG_SM_GPUCC_6350=m CONFIG_SM_GPUCC_8150=y CONFIG_SM_GPUCC_8250=y CONFIG_SM_GPUCC_8350=m @@ -1451,6 +1491,7 @@ CONFIG_SM_TCSRCC_8550=y CONFIG_SM_TCSRCC_8650=y CONFIG_SM_TCSRCC_8750=m CONFIG_SA_VIDEOCC_8775P=m +CONFIG_SM_VIDEOCC_6350=m CONFIG_SM_VIDEOCC_8250=y CONFIG_SM_VIDEOCC_8550=m CONFIG_QCOM_HFPLL=y @@ -1458,6 +1499,7 @@ CONFIG_CLK_GFM_LPASS_SM8250=m CONFIG_SM_VIDEOCC_8450=m CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y CONFIG_CLK_RENESAS_VBATTB=m +CONFIG_EXYNOS_ACPM_CLK=m CONFIG_CLK_SOPHGO_CV1800=y CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_OMAP=m @@ -1567,6 +1609,7 @@ CONFIG_QCOM_SPMI_VADC=m CONFIG_QCOM_SPMI_ADC5=m CONFIG_ROCKCHIP_SARADC=m CONFIG_RZG2L_ADC=m +CONFIG_RZT2H_ADC=m CONFIG_SOPHGO_CV1800B_ADC=m CONFIG_TI_ADS1015=m CONFIG_TI_AM335X_ADC=m @@ -1641,6 +1684,7 @@ CONFIG_PHY_QCOM_QMP=m CONFIG_PHY_QCOM_QUSB2=m CONFIG_PHY_QCOM_EUSB2_REPEATER=m CONFIG_PHY_QCOM_M31_USB=m +CONFIG_PHY_QCOM_M31_EUSB=m CONFIG_PHY_QCOM_USB_HS=m CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=m CONFIG_PHY_QCOM_USB_HS_28NM=m @@ -1719,6 +1763,7 @@ CONFIG_INTERCONNECT_IMX8MQ=m CONFIG_INTERCONNECT_IMX8MP=y CONFIG_INTERCONNECT_QCOM=y CONFIG_INTERCONNECT_QCOM_MSM8916=m +CONFIG_INTERCONNECT_QCOM_MSM8953=y CONFIG_INTERCONNECT_QCOM_MSM8996=y CONFIG_INTERCONNECT_QCOM_OSM_L3=m CONFIG_INTERCONNECT_QCOM_QCM2290=y @@ -1734,6 +1779,7 @@ CONFIG_INTERCONNECT_QCOM_SC8280XP=y CONFIG_INTERCONNECT_QCOM_SDM845=y CONFIG_INTERCONNECT_QCOM_SDX75=y CONFIG_INTERCONNECT_QCOM_SM6115=y +CONFIG_INTERCONNECT_QCOM_SM6350=y CONFIG_INTERCONNECT_QCOM_SM8150=y CONFIG_INTERCONNECT_QCOM_SM8250=y CONFIG_INTERCONNECT_QCOM_SM8350=y diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c index b087b900d2790..c51d4487e9e9b 100644 --- a/arch/arm64/crypto/aes-glue.c +++ b/arch/arm64/crypto/aes-glue.c @@ -549,38 +549,37 @@ static int __maybe_unused xts_encrypt(struct skcipher_request *req) tail = 0; } - for (first = 1; walk.nbytes >= AES_BLOCK_SIZE; first = 0) { - int nbytes = walk.nbytes; + scoped_ksimd() { + for (first = 1; walk.nbytes >= AES_BLOCK_SIZE; first = 0) { + int nbytes = walk.nbytes; - if (walk.nbytes < walk.total) - nbytes &= ~(AES_BLOCK_SIZE - 1); + if (walk.nbytes < walk.total) + nbytes &= ~(AES_BLOCK_SIZE - 1); - scoped_ksimd() aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr, ctx->key1.key_enc, rounds, nbytes, ctx->key2.key_enc, walk.iv, first); - err = skcipher_walk_done(&walk, walk.nbytes - nbytes); - } + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } - if (err || likely(!tail)) - return err; + if (err || likely(!tail)) + return err; - dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); - if (req->dst != req->src) - dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); + dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); + if (req->dst != req->src) + dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); - skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, - req->iv); + skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, + req->iv); - err = skcipher_walk_virt(&walk, &subreq, false); - if (err) - return err; + err = skcipher_walk_virt(&walk, &subreq, false); + if (err) + return err; - scoped_ksimd() aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr, ctx->key1.key_enc, rounds, walk.nbytes, ctx->key2.key_enc, walk.iv, first); - + } return skcipher_walk_done(&walk, 0); } @@ -619,39 +618,37 @@ static int __maybe_unused xts_decrypt(struct skcipher_request *req) tail = 0; } - for (first = 1; walk.nbytes >= AES_BLOCK_SIZE; first = 0) { - int nbytes = walk.nbytes; + scoped_ksimd() { + for (first = 1; walk.nbytes >= AES_BLOCK_SIZE; first = 0) { + int nbytes = walk.nbytes; - if (walk.nbytes < walk.total) - nbytes &= ~(AES_BLOCK_SIZE - 1); + if (walk.nbytes < walk.total) + nbytes &= ~(AES_BLOCK_SIZE - 1); - scoped_ksimd() aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr, ctx->key1.key_dec, rounds, nbytes, ctx->key2.key_enc, walk.iv, first); - err = skcipher_walk_done(&walk, walk.nbytes - nbytes); - } + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } - if (err || likely(!tail)) - return err; - - dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); - if (req->dst != req->src) - dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); + if (err || likely(!tail)) + return err; - skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, - req->iv); + dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); + if (req->dst != req->src) + dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); - err = skcipher_walk_virt(&walk, &subreq, false); - if (err) - return err; + skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, + req->iv); + err = skcipher_walk_virt(&walk, &subreq, false); + if (err) + return err; - scoped_ksimd() aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr, ctx->key1.key_dec, rounds, walk.nbytes, ctx->key2.key_enc, walk.iv, first); - + } return skcipher_walk_done(&walk, 0); } diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c index d496effb0a5b7..cb87c8fc66b3b 100644 --- a/arch/arm64/crypto/aes-neonbs-glue.c +++ b/arch/arm64/crypto/aes-neonbs-glue.c @@ -312,13 +312,13 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt, if (err) return err; - while (walk.nbytes >= AES_BLOCK_SIZE) { - int blocks = (walk.nbytes / AES_BLOCK_SIZE) & ~7; - out = walk.dst.virt.addr; - in = walk.src.virt.addr; - nbytes = walk.nbytes; + scoped_ksimd() { + while (walk.nbytes >= AES_BLOCK_SIZE) { + int blocks = (walk.nbytes / AES_BLOCK_SIZE) & ~7; + out = walk.dst.virt.addr; + in = walk.src.virt.addr; + nbytes = walk.nbytes; - scoped_ksimd() { if (blocks >= 8) { if (first == 1) neon_aes_ecb_encrypt(walk.iv, walk.iv, @@ -344,30 +344,28 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt, ctx->twkey, walk.iv, first); nbytes = first = 0; } + err = skcipher_walk_done(&walk, nbytes); } - err = skcipher_walk_done(&walk, nbytes); - } - if (err || likely(!tail)) - return err; + if (err || likely(!tail)) + return err; - /* handle ciphertext stealing */ - dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); - if (req->dst != req->src) - dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); + /* handle ciphertext stealing */ + dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); + if (req->dst != req->src) + dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); - skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, - req->iv); + skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, + req->iv); - err = skcipher_walk_virt(&walk, req, false); - if (err) - return err; + err = skcipher_walk_virt(&walk, req, false); + if (err) + return err; - out = walk.dst.virt.addr; - in = walk.src.virt.addr; - nbytes = walk.nbytes; + out = walk.dst.virt.addr; + in = walk.src.virt.addr; + nbytes = walk.nbytes; - scoped_ksimd() { if (encrypt) neon_aes_xts_encrypt(out, in, ctx->cts.key_enc, ctx->key.rounds, nbytes, ctx->twkey, diff --git a/arch/arm64/crypto/ghash-ce-glue.c b/arch/arm64/crypto/ghash-ce-glue.c index 7951557a285a9..ef249d06c92cc 100644 --- a/arch/arm64/crypto/ghash-ce-glue.c +++ b/arch/arm64/crypto/ghash-ce-glue.c @@ -133,7 +133,7 @@ static int ghash_finup(struct shash_desc *desc, const u8 *src, u8 buf[GHASH_BLOCK_SIZE] = {}; memcpy(buf, src, len); - ghash_do_simd_update(1, ctx->digest, src, key, NULL, + ghash_do_simd_update(1, ctx->digest, buf, key, NULL, pmull_ghash_update_p8); memzero_explicit(buf, sizeof(buf)); } diff --git a/arch/arm64/crypto/sm4-ce-glue.c b/arch/arm64/crypto/sm4-ce-glue.c index 5569cece5a0b8..0eeabfa9ef25e 100644 --- a/arch/arm64/crypto/sm4-ce-glue.c +++ b/arch/arm64/crypto/sm4-ce-glue.c @@ -346,11 +346,11 @@ static int sm4_xts_crypt(struct skcipher_request *req, bool encrypt) tail = 0; } - while ((nbytes = walk.nbytes) >= SM4_BLOCK_SIZE) { - if (nbytes < walk.total) - nbytes &= ~(SM4_BLOCK_SIZE - 1); + scoped_ksimd() { + while ((nbytes = walk.nbytes) >= SM4_BLOCK_SIZE) { + if (nbytes < walk.total) + nbytes &= ~(SM4_BLOCK_SIZE - 1); - scoped_ksimd() { if (encrypt) sm4_ce_xts_enc(ctx->key1.rkey_enc, walk.dst.virt.addr, walk.src.virt.addr, walk.iv, nbytes, @@ -359,32 +359,30 @@ static int sm4_xts_crypt(struct skcipher_request *req, bool encrypt) sm4_ce_xts_dec(ctx->key1.rkey_dec, walk.dst.virt.addr, walk.src.virt.addr, walk.iv, nbytes, rkey2_enc); - } - rkey2_enc = NULL; + rkey2_enc = NULL; - err = skcipher_walk_done(&walk, walk.nbytes - nbytes); - if (err) - return err; - } + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + if (err) + return err; + } - if (likely(tail == 0)) - return 0; + if (likely(tail == 0)) + return 0; - /* handle ciphertext stealing */ + /* handle ciphertext stealing */ - dst = src = scatterwalk_ffwd(sg_src, req->src, subreq.cryptlen); - if (req->dst != req->src) - dst = scatterwalk_ffwd(sg_dst, req->dst, subreq.cryptlen); + dst = src = scatterwalk_ffwd(sg_src, req->src, subreq.cryptlen); + if (req->dst != req->src) + dst = scatterwalk_ffwd(sg_dst, req->dst, subreq.cryptlen); - skcipher_request_set_crypt(&subreq, src, dst, SM4_BLOCK_SIZE + tail, - req->iv); + skcipher_request_set_crypt(&subreq, src, dst, + SM4_BLOCK_SIZE + tail, req->iv); - err = skcipher_walk_virt(&walk, &subreq, false); - if (err) - return err; + err = skcipher_walk_virt(&walk, &subreq, false); + if (err) + return err; - scoped_ksimd() { if (encrypt) sm4_ce_xts_enc(ctx->key1.rkey_enc, walk.dst.virt.addr, walk.src.virt.addr, walk.iv, walk.nbytes, diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 1da290aeedce7..e500600e4b9b8 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -111,6 +111,7 @@ #define TCR_EL2_DS (1UL << 32) #define TCR_EL2_RES1 ((1U << 31) | (1 << 23)) #define TCR_EL2_HPD (1 << 24) +#define TCR_EL2_HA (1 << 21) #define TCR_EL2_TBI (1 << 20) #define TCR_EL2_PS_SHIFT 16 #define TCR_EL2_PS_MASK (7 << TCR_EL2_PS_SHIFT) diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 4b34f7b7ed2fc..a1ad12c72ebf1 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -79,7 +79,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_range, __KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context, __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff, - __KVM_HOST_SMCCC_FUNC___vgic_v3_save_vmcr_aprs, + __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs, __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs, __KVM_HOST_SMCCC_FUNC___pkvm_reserve_vm, __KVM_HOST_SMCCC_FUNC___pkvm_unreserve_vm, @@ -246,9 +246,9 @@ extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu); extern int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding); extern void __kvm_timer_set_cntvoff(u64 cntvoff); -extern void __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr); -extern void __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr); -extern void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr); +extern int __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr); +extern int __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr); +extern int __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr); extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 64302c438355c..ac7f970c78830 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -54,6 +54,7 @@ #define KVM_REQ_NESTED_S2_UNMAP KVM_ARCH_REQ(8) #define KVM_REQ_GUEST_HYP_IRQ_PENDING KVM_ARCH_REQ(9) #define KVM_REQ_MAP_L1_VNCR_EL2 KVM_ARCH_REQ(10) +#define KVM_REQ_VGIC_PROCESS_UPDATE KVM_ARCH_REQ(11) #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ KVM_DIRTY_LOG_INITIALLY_SET) @@ -350,6 +351,8 @@ struct kvm_arch { #define KVM_ARCH_FLAG_GUEST_HAS_SVE 9 /* MIDR_EL1, REVIDR_EL1, and AIDR_EL1 are writable from userspace */ #define KVM_ARCH_FLAG_WRITABLE_IMP_ID_REGS 10 + /* Unhandled SEAs are taken to userspace */ +#define KVM_ARCH_FLAG_EXIT_SEA 11 unsigned long flags; /* VM-wide vCPU feature set */ diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h index e6be1f5d0967f..76ce2b94bd97e 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -77,12 +77,13 @@ DECLARE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params); int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu); u64 __gic_v3_get_lr(unsigned int lr); +void __gic_v3_set_lr(u64 val, int lr); void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if); void __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if); void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if); void __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if); -void __vgic_v3_save_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if); +void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if); void __vgic_v3_restore_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if); int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h index f7c06a840963d..905c658057a43 100644 --- a/arch/arm64/include/asm/kvm_nested.h +++ b/arch/arm64/include/asm/kvm_nested.h @@ -120,9 +120,42 @@ static inline bool kvm_s2_trans_writable(struct kvm_s2_trans *trans) return trans->writable; } -static inline bool kvm_s2_trans_executable(struct kvm_s2_trans *trans) +static inline bool kvm_has_xnx(struct kvm *kvm) { - return !(trans->desc & BIT(54)); + return cpus_have_final_cap(ARM64_HAS_XNX) && + kvm_has_feat(kvm, ID_AA64MMFR1_EL1, XNX, IMP); +} + +static inline bool kvm_s2_trans_exec_el0(struct kvm *kvm, struct kvm_s2_trans *trans) +{ + u8 xn = FIELD_GET(KVM_PTE_LEAF_ATTR_HI_S2_XN, trans->desc); + + if (!kvm_has_xnx(kvm)) + xn &= FIELD_PREP(KVM_PTE_LEAF_ATTR_HI_S2_XN, 0b10); + + switch (xn) { + case 0b00: + case 0b01: + return true; + default: + return false; + } +} + +static inline bool kvm_s2_trans_exec_el1(struct kvm *kvm, struct kvm_s2_trans *trans) +{ + u8 xn = FIELD_GET(KVM_PTE_LEAF_ATTR_HI_S2_XN, trans->desc); + + if (!kvm_has_xnx(kvm)) + xn &= FIELD_PREP(KVM_PTE_LEAF_ATTR_HI_S2_XN, 0b10); + + switch (xn) { + case 0b00: + case 0b11: + return true; + default: + return false; + } } extern int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa, @@ -320,6 +353,7 @@ struct s1_walk_info { bool be; bool s2; bool pa52bit; + bool ha; }; struct s1_walk_result { @@ -370,4 +404,6 @@ void kvm_handle_s1e2_tlbi(struct kvm_vcpu *vcpu, u32 inst, u64 val); (FIX_VNCR - __c); \ }) +int __kvm_at_swap_desc(struct kvm *kvm, gpa_t ipa, u64 old, u64 new); + #endif /* __ARM64_KVM_NESTED_H */ diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index 2888b5d037573..fc02de43c68dd 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -89,7 +89,7 @@ typedef u64 kvm_pte_t; #define KVM_PTE_LEAF_ATTR_HI_S1_XN BIT(54) -#define KVM_PTE_LEAF_ATTR_HI_S2_XN BIT(54) +#define KVM_PTE_LEAF_ATTR_HI_S2_XN GENMASK(54, 53) #define KVM_PTE_LEAF_ATTR_HI_S1_GP BIT(50) @@ -240,7 +240,9 @@ enum kvm_pgtable_stage2_flags { /** * enum kvm_pgtable_prot - Page-table permissions and attributes. - * @KVM_PGTABLE_PROT_X: Execute permission. + * @KVM_PGTABLE_PROT_UX: Unprivileged execute permission. + * @KVM_PGTABLE_PROT_PX: Privileged execute permission. + * @KVM_PGTABLE_PROT_X: Privileged and unprivileged execute permission. * @KVM_PGTABLE_PROT_W: Write permission. * @KVM_PGTABLE_PROT_R: Read permission. * @KVM_PGTABLE_PROT_DEVICE: Device attributes. @@ -251,12 +253,15 @@ enum kvm_pgtable_stage2_flags { * @KVM_PGTABLE_PROT_SW3: Software bit 3. */ enum kvm_pgtable_prot { - KVM_PGTABLE_PROT_X = BIT(0), - KVM_PGTABLE_PROT_W = BIT(1), - KVM_PGTABLE_PROT_R = BIT(2), + KVM_PGTABLE_PROT_PX = BIT(0), + KVM_PGTABLE_PROT_UX = BIT(1), + KVM_PGTABLE_PROT_X = KVM_PGTABLE_PROT_PX | + KVM_PGTABLE_PROT_UX, + KVM_PGTABLE_PROT_W = BIT(2), + KVM_PGTABLE_PROT_R = BIT(3), - KVM_PGTABLE_PROT_DEVICE = BIT(3), - KVM_PGTABLE_PROT_NORMAL_NC = BIT(4), + KVM_PGTABLE_PROT_DEVICE = BIT(4), + KVM_PGTABLE_PROT_NORMAL_NC = BIT(5), KVM_PGTABLE_PROT_SW0 = BIT(55), KVM_PGTABLE_PROT_SW1 = BIT(56), @@ -355,6 +360,11 @@ static inline kvm_pte_t *kvm_dereference_pteref(struct kvm_pgtable_walker *walke return pteref; } +static inline kvm_pte_t *kvm_dereference_pteref_raw(kvm_pteref_t pteref) +{ + return pteref; +} + static inline int kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker) { /* @@ -384,6 +394,11 @@ static inline kvm_pte_t *kvm_dereference_pteref(struct kvm_pgtable_walker *walke return rcu_dereference_check(pteref, !(walker->flags & KVM_PGTABLE_WALK_SHARED)); } +static inline kvm_pte_t *kvm_dereference_pteref_raw(kvm_pteref_t pteref) +{ + return rcu_dereference_raw(pteref); +} + static inline int kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker) { if (walker->flags & KVM_PGTABLE_WALK_SHARED) @@ -551,6 +566,26 @@ static inline int kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2 */ void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt); +/** + * kvm_pgtable_stage2_destroy_range() - Destroy the unlinked range of addresses. + * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*(). + * @addr: Intermediate physical address at which to place the mapping. + * @size: Size of the mapping. + * + * The page-table is assumed to be unreachable by any hardware walkers prior + * to freeing and therefore no TLB invalidation is performed. + */ +void kvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt, + u64 addr, u64 size); + +/** + * kvm_pgtable_stage2_destroy_pgd() - Destroy the PGD of guest stage-2 page-table. + * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*(). + * + * It is assumed that the rest of the page-table is freed before this operation. + */ +void kvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt); + /** * kvm_pgtable_stage2_free_unlinked() - Free an unlinked stage-2 paging structure. * @mm_ops: Memory management callbacks. diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h index 08be89c95466e..0aecd4ac5f45d 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -180,7 +180,9 @@ struct pkvm_mapping { int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops); -void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt); +void pkvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt, + u64 addr, u64 size); +void pkvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt); int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys, enum kvm_pgtable_prot prot, void *mc, enum kvm_pgtable_walk_flags flags); diff --git a/arch/arm64/include/asm/simd.h b/arch/arm64/include/asm/simd.h index 0941f6f58a146..69ecbd69ca8cc 100644 --- a/arch/arm64/include/asm/simd.h +++ b/arch/arm64/include/asm/simd.h @@ -48,6 +48,13 @@ DEFINE_LOCK_GUARD_1(ksimd, kernel_neon_begin(_T->lock), kernel_neon_end(_T->lock)) -#define scoped_ksimd() scoped_guard(ksimd, &(struct user_fpsimd_state){}) +#define __scoped_ksimd(_label) \ + for (struct user_fpsimd_state __uninitialized __st; \ + true; ({ goto _label; })) \ + if (0) { \ +_label: break; \ + } else scoped_guard(ksimd, &__st) + +#define scoped_ksimd() __scoped_ksimd(__UNIQUE_ID(label)) #endif diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h index 341174bf91063..b9eaf4ad70850 100644 --- a/arch/arm64/include/asm/topology.h +++ b/arch/arm64/include/asm/topology.h @@ -36,6 +36,9 @@ void update_freq_counters_refs(void); #define arch_scale_hw_pressure topology_get_hw_pressure #define arch_update_hw_pressure topology_update_hw_pressure +#undef arch_cpu_is_threaded +#define arch_cpu_is_threaded() (read_cpuid_mpidr() & MPIDR_MT_BITMASK) + #include #endif /* _ASM_ARM_TOPOLOGY_H */ diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h index 530af9620fdba..b51ab6840f9c4 100644 --- a/arch/arm64/include/asm/virt.h +++ b/arch/arm64/include/asm/virt.h @@ -40,8 +40,13 @@ */ #define HVC_FINALISE_EL2 3 +/* + * HVC_GET_ICH_VTR_EL2 - Retrieve the ICH_VTR_EL2 value + */ +#define HVC_GET_ICH_VTR_EL2 4 + /* Max number of HYP stub hypercalls */ -#define HVC_STUB_HCALL_NR 4 +#define HVC_STUB_HCALL_NR 5 /* Error returned when an invalid stub number is passed into x0 */ #define HVC_STUB_ERR 0xbadca11 diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 42b182cfa4045..c840a93b9ef95 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2304,6 +2304,49 @@ static bool has_gic_prio_relaxed_sync(const struct arm64_cpu_capabilities *entry } #endif +static bool can_trap_icv_dir_el1(const struct arm64_cpu_capabilities *entry, + int scope) +{ + static const struct midr_range has_vgic_v3[] = { + MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM), + MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM), + MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM_PRO), + MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM_PRO), + MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM_MAX), + MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM_MAX), + MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD), + MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE), + MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_PRO), + MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_PRO), + MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_MAX), + MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_MAX), + {}, + }; + struct arm_smccc_res res = {}; + + BUILD_BUG_ON(ARM64_HAS_ICH_HCR_EL2_TDIR <= ARM64_HAS_GICV3_CPUIF); + BUILD_BUG_ON(ARM64_HAS_ICH_HCR_EL2_TDIR <= ARM64_HAS_GICV5_LEGACY); + if (!this_cpu_has_cap(ARM64_HAS_GICV3_CPUIF) && + !is_midr_in_range_list(has_vgic_v3)) + return false; + + if (!is_hyp_mode_available()) + return false; + + if (this_cpu_has_cap(ARM64_HAS_GICV5_LEGACY)) + return true; + + if (is_kernel_in_hyp_mode()) + res.a1 = read_sysreg_s(SYS_ICH_VTR_EL2); + else + arm_smccc_1_1_hvc(HVC_GET_ICH_VTR_EL2, &res); + + if (res.a0 == HVC_STUB_ERR) + return false; + + return res.a1 & ICH_VTR_EL2_TDS; +} + #ifdef CONFIG_ARM64_BTI static void bti_enable(const struct arm64_cpu_capabilities *__unused) { @@ -2815,6 +2858,15 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .matches = has_gic_prio_relaxed_sync, }, #endif + { + /* + * Depends on having GICv3 + */ + .desc = "ICV_DIR_EL1 trapping", + .capability = ARM64_HAS_ICH_HCR_EL2_TDIR, + .type = ARM64_CPUCAP_EARLY_LOCAL_CPU_FEATURE, + .matches = can_trap_icv_dir_el1, + }, #ifdef CONFIG_ARM64_E0PD { .desc = "E0PD", @@ -3089,6 +3141,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .capability = ARM64_HAS_GICV5_LEGACY, .matches = test_has_gicv5_legacy, }, + { + .desc = "XNX", + .capability = ARM64_HAS_XNX, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = has_cpuid_feature, + ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, XNX, IMP) + }, {}, }; diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index c154f72634e02..9de1d8a604cbf 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -180,13 +180,6 @@ static inline void set_sve_default_vl(int val) set_default_vl(ARM64_VEC_SVE, val); } -static u8 *efi_sve_state; - -#else /* ! CONFIG_ARM64_SVE */ - -/* Dummy declaration for code that will be optimised out: */ -extern u8 *efi_sve_state; - #endif /* ! CONFIG_ARM64_SVE */ #ifdef CONFIG_ARM64_SME @@ -1095,36 +1088,6 @@ int vec_verify_vq_map(enum vec_type type) return 0; } -static void __init sve_efi_setup(void) -{ - int max_vl = 0; - int i; - - if (!IS_ENABLED(CONFIG_EFI)) - return; - - for (i = 0; i < ARRAY_SIZE(vl_info); i++) - max_vl = max(vl_info[i].max_vl, max_vl); - - /* - * alloc_percpu() warns and prints a backtrace if this goes wrong. - * This is evidence of a crippled system and we are returning void, - * so no attempt is made to handle this situation here. - */ - if (!sve_vl_valid(max_vl)) - goto fail; - - efi_sve_state = kmalloc(SVE_SIG_REGS_SIZE(sve_vq_from_vl(max_vl)), - GFP_KERNEL); - if (!efi_sve_state) - goto fail; - - return; - -fail: - panic("Cannot allocate memory for EFI SVE save/restore"); -} - void cpu_enable_sve(const struct arm64_cpu_capabilities *__always_unused p) { write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_ZEN_EL1EN, CPACR_EL1); @@ -1185,8 +1148,6 @@ void __init sve_setup(void) if (sve_max_virtualisable_vl() < sve_max_vl()) pr_warn("%s: unvirtualisable vector lengths present\n", info->name); - - sve_efi_setup(); } /* @@ -1947,9 +1908,6 @@ EXPORT_SYMBOL_GPL(kernel_neon_end); #ifdef CONFIG_EFI static struct user_fpsimd_state efi_fpsimd_state; -static bool efi_fpsimd_state_used; -static bool efi_sve_state_used; -static bool efi_sm_state; /* * EFI runtime services support functions @@ -1976,43 +1934,26 @@ void __efi_fpsimd_begin(void) if (may_use_simd()) { kernel_neon_begin(&efi_fpsimd_state); } else { - WARN_ON(preemptible()); - /* - * If !efi_sve_state, SVE can't be in use yet and doesn't need - * preserving: + * We are running in hardirq or NMI context, and the only + * legitimate case where this might happen is when EFI pstore + * is attempting to record the system's dying gasps into EFI + * variables. This could be due to an oops, a panic or a call + * to emergency_restart(), and in none of those cases, we can + * expect the current task to ever return to user space again, + * or for the kernel to resume any normal execution, for that + * matter (an oops in hardirq context triggers a panic too). + * + * Therefore, there is no point in attempting to preserve any + * SVE/SME state here. On the off chance that we might have + * ended up here for a different reason inadvertently, kill the + * task and preserve/restore the base FP/SIMD state, which + * might belong to kernel mode FP/SIMD. */ - if (system_supports_sve() && efi_sve_state != NULL) { - bool ffr = true; - u64 svcr; - - efi_sve_state_used = true; - - if (system_supports_sme()) { - svcr = read_sysreg_s(SYS_SVCR); - - efi_sm_state = svcr & SVCR_SM_MASK; - - /* - * Unless we have FA64 FFR does not - * exist in streaming mode. - */ - if (!system_supports_fa64()) - ffr = !(svcr & SVCR_SM_MASK); - } - - sve_save_state(efi_sve_state + sve_ffr_offset(sve_max_vl()), - &efi_fpsimd_state.fpsr, ffr); - - if (system_supports_sme()) - sysreg_clear_set_s(SYS_SVCR, - SVCR_SM_MASK, 0); - - } else { - fpsimd_save_state(&efi_fpsimd_state); - } - - efi_fpsimd_state_used = true; + pr_warn_ratelimited("Calling EFI runtime from %s context\n", + in_nmi() ? "NMI" : "hardirq"); + force_signal_inject(SIGKILL, SI_KERNEL, 0, 0); + fpsimd_save_state(&efi_fpsimd_state); } } @@ -2024,41 +1965,10 @@ void __efi_fpsimd_end(void) if (!system_supports_fpsimd()) return; - if (!efi_fpsimd_state_used) { + if (may_use_simd()) { kernel_neon_end(&efi_fpsimd_state); } else { - if (system_supports_sve() && efi_sve_state_used) { - bool ffr = true; - - /* - * Restore streaming mode; EFI calls are - * normal function calls so should not return in - * streaming mode. - */ - if (system_supports_sme()) { - if (efi_sm_state) { - sysreg_clear_set_s(SYS_SVCR, - 0, - SVCR_SM_MASK); - - /* - * Unless we have FA64 FFR does not - * exist in streaming mode. - */ - if (!system_supports_fa64()) - ffr = false; - } - } - - sve_load_state(efi_sve_state + sve_ffr_offset(sve_max_vl()), - &efi_fpsimd_state.fpsr, ffr); - - efi_sve_state_used = false; - } else { - fpsimd_load_state(&efi_fpsimd_state); - } - - efi_fpsimd_state_used = false; + fpsimd_load_state(&efi_fpsimd_state); } } diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S index 36e2d26b54f5c..085bc9972f6bb 100644 --- a/arch/arm64/kernel/hyp-stub.S +++ b/arch/arm64/kernel/hyp-stub.S @@ -54,6 +54,11 @@ SYM_CODE_START_LOCAL(elx_sync) 1: cmp x0, #HVC_FINALISE_EL2 b.eq __finalise_el2 + cmp x0, #HVC_GET_ICH_VTR_EL2 + b.ne 2f + mrs_s x1, SYS_ICH_VTR_EL2 + b 9f + 2: cmp x0, #HVC_SOFT_RESTART b.ne 3f mov x0, x2 diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index 5369763606e71..85bc629270bd9 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -91,6 +91,7 @@ KVM_NVHE_ALIAS(spectre_bhb_patch_loop_mitigation_enable); KVM_NVHE_ALIAS(spectre_bhb_patch_wa3); KVM_NVHE_ALIAS(spectre_bhb_patch_clearbhb); KVM_NVHE_ALIAS(alt_cb_patch_nops); +KVM_NVHE_ALIAS(kvm_compute_ich_hcr_trap_bits); /* Global kernel state accessed by nVHE hyp code. */ KVM_NVHE_ALIAS(kvm_vgic_global_state); diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index fba7ca102a8c4..489554931231e 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -292,6 +292,7 @@ static void flush_gcs(void) current->thread.gcs_base = 0; current->thread.gcs_size = 0; current->thread.gcs_el0_mode = 0; + current->thread.gcs_el0_locked = 0; write_sysreg_s(GCSCRE0_EL1_nTR, SYS_GCSCRE0_EL1); write_sysreg_s(0, SYS_GCSPR_EL0); } diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index 5d07ee85bdae4..5d24dc53799b7 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -25,107 +25,6 @@ #include #include -#ifdef CONFIG_ACPI -static bool __init acpi_cpu_is_threaded(int cpu) -{ - int is_threaded = acpi_pptt_cpu_is_thread(cpu); - - /* - * if the PPTT doesn't have thread information, assume a homogeneous - * machine and return the current CPU's thread state. - */ - if (is_threaded < 0) - is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK; - - return !!is_threaded; -} - -struct cpu_smt_info { - unsigned int thread_num; - int core_id; -}; - -/* - * Propagate the topology information of the processor_topology_node tree to the - * cpu_topology array. - */ -int __init parse_acpi_topology(void) -{ - unsigned int max_smt_thread_num = 1; - struct cpu_smt_info *entry; - struct xarray hetero_cpu; - unsigned long hetero_id; - int cpu, topology_id; - - if (acpi_disabled) - return 0; - - xa_init(&hetero_cpu); - - for_each_possible_cpu(cpu) { - topology_id = find_acpi_cpu_topology(cpu, 0); - if (topology_id < 0) - return topology_id; - - if (acpi_cpu_is_threaded(cpu)) { - cpu_topology[cpu].thread_id = topology_id; - topology_id = find_acpi_cpu_topology(cpu, 1); - cpu_topology[cpu].core_id = topology_id; - - /* - * In the PPTT, CPUs below a node with the 'identical - * implementation' flag have the same number of threads. - * Count the number of threads for only one CPU (i.e. - * one core_id) among those with the same hetero_id. - * See the comment of find_acpi_cpu_topology_hetero_id() - * for more details. - * - * One entry is created for each node having: - * - the 'identical implementation' flag - * - its parent not having the flag - */ - hetero_id = find_acpi_cpu_topology_hetero_id(cpu); - entry = xa_load(&hetero_cpu, hetero_id); - if (!entry) { - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - WARN_ON_ONCE(!entry); - - if (entry) { - entry->core_id = topology_id; - entry->thread_num = 1; - xa_store(&hetero_cpu, hetero_id, - entry, GFP_KERNEL); - } - } else if (entry->core_id == topology_id) { - entry->thread_num++; - } - } else { - cpu_topology[cpu].thread_id = -1; - cpu_topology[cpu].core_id = topology_id; - } - topology_id = find_acpi_cpu_topology_cluster(cpu); - cpu_topology[cpu].cluster_id = topology_id; - topology_id = find_acpi_cpu_topology_package(cpu); - cpu_topology[cpu].package_id = topology_id; - } - - /* - * This is a short loop since the number of XArray elements is the - * number of heterogeneous CPU clusters. On a homogeneous system - * there's only one entry in the XArray. - */ - xa_for_each(&hetero_cpu, hetero_id, entry) { - max_smt_thread_num = max(max_smt_thread_num, entry->thread_num); - xa_erase(&hetero_cpu, hetero_id); - kfree(entry); - } - - cpu_smt_set_num_threads(max_smt_thread_num, max_smt_thread_num); - xa_destroy(&hetero_cpu); - return 0; -} -#endif - #ifdef CONFIG_ARM64_AMU_EXTN #define read_corecnt() read_sysreg_s(SYS_AMEVCNTR0_CORE_EL0) #define read_constcnt() read_sysreg_s(SYS_AMEVCNTR0_CONST_EL0) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 12acc024f7a87..4f80da0c0d1de 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -132,6 +132,10 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, } mutex_unlock(&kvm->lock); break; + case KVM_CAP_ARM_SEA_TO_USER: + r = 0; + set_bit(KVM_ARCH_FLAG_EXIT_SEA, &kvm->arch.flags); + break; default: break; } @@ -327,6 +331,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_IRQFD_RESAMPLE: case KVM_CAP_COUNTER_OFFSET: case KVM_CAP_ARM_WRITABLE_IMP_ID_REGS: + case KVM_CAP_ARM_SEA_TO_USER: r = 1; break; case KVM_CAP_SET_GUEST_DEBUG2: @@ -440,7 +445,7 @@ struct kvm *kvm_arch_alloc_vm(void) if (!has_vhe()) return kzalloc(sz, GFP_KERNEL_ACCOUNT); - return __vmalloc(sz, GFP_KERNEL_ACCOUNT | __GFP_HIGHMEM | __GFP_ZERO); + return kvzalloc(sz, GFP_KERNEL_ACCOUNT); } int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id) @@ -659,8 +664,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { if (is_protected_kvm_enabled()) { - kvm_call_hyp(__vgic_v3_save_vmcr_aprs, - &vcpu->arch.vgic_cpu.vgic_v3); + kvm_call_hyp(__vgic_v3_save_aprs, &vcpu->arch.vgic_cpu.vgic_v3); kvm_call_hyp_nvhe(__pkvm_vcpu_put); } @@ -1042,6 +1046,10 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu) */ kvm_check_request(KVM_REQ_IRQ_PENDING, vcpu); + /* Process interrupts deactivated through a trap */ + if (kvm_check_request(KVM_REQ_VGIC_PROCESS_UPDATE, vcpu)) + kvm_vgic_process_async_update(vcpu); + if (kvm_check_request(KVM_REQ_RECORD_STEAL, vcpu)) kvm_update_stolen_time(vcpu); @@ -1835,6 +1843,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp, return r; } +long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) +{ + return -ENOIOCTLCMD; +} + void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot) { diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c index be26d5aa668c3..53bf70126f81d 100644 --- a/arch/arm64/kvm/at.c +++ b/arch/arm64/kvm/at.c @@ -346,6 +346,11 @@ static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi, wi->baddr &= GENMASK_ULL(wi->max_oa_bits - 1, x); + wi->ha = kvm_has_feat(vcpu->kvm, ID_AA64MMFR1_EL1, HAFDBS, AF); + wi->ha &= (wi->regime == TR_EL2 ? + FIELD_GET(TCR_EL2_HA, tcr) : + FIELD_GET(TCR_HA, tcr)); + return 0; addrsz: @@ -362,10 +367,42 @@ static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi, return -EFAULT; } +static int kvm_read_s1_desc(struct kvm_vcpu *vcpu, u64 pa, u64 *desc, + struct s1_walk_info *wi) +{ + u64 val; + int r; + + r = kvm_read_guest(vcpu->kvm, pa, &val, sizeof(val)); + if (r) + return r; + + if (wi->be) + *desc = be64_to_cpu((__force __be64)val); + else + *desc = le64_to_cpu((__force __le64)val); + + return 0; +} + +static int kvm_swap_s1_desc(struct kvm_vcpu *vcpu, u64 pa, u64 old, u64 new, + struct s1_walk_info *wi) +{ + if (wi->be) { + old = (__force u64)cpu_to_be64(old); + new = (__force u64)cpu_to_be64(new); + } else { + old = (__force u64)cpu_to_le64(old); + new = (__force u64)cpu_to_le64(new); + } + + return __kvm_at_swap_desc(vcpu->kvm, pa, old, new); +} + static int walk_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi, struct s1_walk_result *wr, u64 va) { - u64 va_top, va_bottom, baddr, desc; + u64 va_top, va_bottom, baddr, desc, new_desc, ipa; int level, stride, ret; level = wi->sl; @@ -375,7 +412,7 @@ static int walk_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi, va_top = get_ia_size(wi) - 1; while (1) { - u64 index, ipa; + u64 index; va_bottom = (3 - level) * stride + wi->pgshift; index = (va & GENMASK_ULL(va_top, va_bottom)) >> (va_bottom - 3); @@ -414,16 +451,13 @@ static int walk_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi, return ret; } - ret = kvm_read_guest(vcpu->kvm, ipa, &desc, sizeof(desc)); + ret = kvm_read_s1_desc(vcpu, ipa, &desc, wi); if (ret) { fail_s1_walk(wr, ESR_ELx_FSC_SEA_TTW(level), false); return ret; } - if (wi->be) - desc = be64_to_cpu((__force __be64)desc); - else - desc = le64_to_cpu((__force __le64)desc); + new_desc = desc; /* Invalid descriptor */ if (!(desc & BIT(0))) @@ -477,6 +511,17 @@ static int walk_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi, if (check_output_size(baddr & GENMASK(52, va_bottom), wi)) goto addrsz; + if (wi->ha) + new_desc |= PTE_AF; + + if (new_desc != desc) { + ret = kvm_swap_s1_desc(vcpu, ipa, desc, new_desc, wi); + if (ret) + return ret; + + desc = new_desc; + } + if (!(desc & PTE_AF)) { fail_s1_walk(wr, ESR_ELx_FSC_ACCESS_L(level), false); return -EACCES; @@ -1221,7 +1266,7 @@ static void compute_s1_permissions(struct kvm_vcpu *vcpu, wr->pr &= !pan; } -static u64 handle_at_slow(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) +static int handle_at_slow(struct kvm_vcpu *vcpu, u32 op, u64 vaddr, u64 *par) { struct s1_walk_result wr = {}; struct s1_walk_info wi = {}; @@ -1246,6 +1291,11 @@ static u64 handle_at_slow(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) srcu_read_unlock(&vcpu->kvm->srcu, idx); + /* + * Race to update a descriptor -- restart the walk. + */ + if (ret == -EAGAIN) + return ret; if (ret) goto compute_par; @@ -1279,7 +1329,8 @@ static u64 handle_at_slow(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) fail_s1_walk(&wr, ESR_ELx_FSC_PERM_L(wr.level), false); compute_par: - return compute_par_s1(vcpu, &wi, &wr); + *par = compute_par_s1(vcpu, &wi, &wr); + return 0; } /* @@ -1407,9 +1458,10 @@ static bool par_check_s1_access_fault(u64 par) !(par & SYS_PAR_EL1_S)); } -void __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) +int __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) { u64 par = __kvm_at_s1e01_fast(vcpu, op, vaddr); + int ret; /* * If PAR_EL1 reports that AT failed on a S1 permission or access @@ -1421,15 +1473,20 @@ void __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) */ if ((par & SYS_PAR_EL1_F) && !par_check_s1_perm_fault(par) && - !par_check_s1_access_fault(par)) - par = handle_at_slow(vcpu, op, vaddr); + !par_check_s1_access_fault(par)) { + ret = handle_at_slow(vcpu, op, vaddr, &par); + if (ret) + return ret; + } vcpu_write_sys_reg(vcpu, par, PAR_EL1); + return 0; } -void __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) +int __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) { u64 par; + int ret; /* * We've trapped, so everything is live on the CPU. As we will be @@ -1476,13 +1533,17 @@ void __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) } /* We failed the translation, let's replay it in slow motion */ - if ((par & SYS_PAR_EL1_F) && !par_check_s1_perm_fault(par)) - par = handle_at_slow(vcpu, op, vaddr); + if ((par & SYS_PAR_EL1_F) && !par_check_s1_perm_fault(par)) { + ret = handle_at_slow(vcpu, op, vaddr, &par); + if (ret) + return ret; + } vcpu_write_sys_reg(vcpu, par, PAR_EL1); + return 0; } -void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) +int __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) { struct kvm_s2_trans out = {}; u64 ipa, par; @@ -1509,13 +1570,13 @@ void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) break; default: WARN_ON_ONCE(1); - return; + return 0; } __kvm_at_s1e01(vcpu, op, vaddr); par = vcpu_read_sys_reg(vcpu, PAR_EL1); if (par & SYS_PAR_EL1_F) - return; + return 0; /* * If we only have a single stage of translation (EL2&0), exit @@ -1523,14 +1584,14 @@ void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) */ if (compute_translation_regime(vcpu, op) == TR_EL20 || !(vcpu_read_sys_reg(vcpu, HCR_EL2) & (HCR_VM | HCR_DC))) - return; + return 0; /* Do the stage-2 translation */ ipa = (par & GENMASK_ULL(47, 12)) | (vaddr & GENMASK_ULL(11, 0)); out.esr = 0; ret = kvm_walk_nested_s2(vcpu, ipa, &out); if (ret < 0) - return; + return ret; /* Check the access permission */ if (!out.esr && @@ -1539,6 +1600,7 @@ void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) par = compute_par_s12(vcpu, par, &out); vcpu_write_sys_reg(vcpu, par, PAR_EL1); + return 0; } /* @@ -1637,3 +1699,97 @@ int __kvm_find_s1_desc_level(struct kvm_vcpu *vcpu, u64 va, u64 ipa, int *level) return ret; } } + +#ifdef CONFIG_ARM64_LSE_ATOMICS +static int __lse_swap_desc(u64 __user *ptep, u64 old, u64 new) +{ + u64 tmp = old; + int ret = 0; + + uaccess_enable_privileged(); + + asm volatile(__LSE_PREAMBLE + "1: cas %[old], %[new], %[addr]\n" + "2:\n" + _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %w[ret]) + : [old] "+r" (old), [addr] "+Q" (*ptep), [ret] "+r" (ret) + : [new] "r" (new) + : "memory"); + + uaccess_disable_privileged(); + + if (ret) + return ret; + if (tmp != old) + return -EAGAIN; + + return ret; +} +#else +static int __lse_swap_desc(u64 __user *ptep, u64 old, u64 new) +{ + return -EINVAL; +} +#endif + +static int __llsc_swap_desc(u64 __user *ptep, u64 old, u64 new) +{ + int ret = 1; + u64 tmp; + + uaccess_enable_privileged(); + + asm volatile("prfm pstl1strm, %[addr]\n" + "1: ldxr %[tmp], %[addr]\n" + "sub %[tmp], %[tmp], %[old]\n" + "cbnz %[tmp], 3f\n" + "2: stlxr %w[ret], %[new], %[addr]\n" + "3:\n" + _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %w[ret]) + _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %w[ret]) + : [ret] "+r" (ret), [addr] "+Q" (*ptep), [tmp] "=&r" (tmp) + : [old] "r" (old), [new] "r" (new) + : "memory"); + + uaccess_disable_privileged(); + + /* STLXR didn't update the descriptor, or the compare failed */ + if (ret == 1) + return -EAGAIN; + + return ret; +} + +int __kvm_at_swap_desc(struct kvm *kvm, gpa_t ipa, u64 old, u64 new) +{ + struct kvm_memory_slot *slot; + unsigned long hva; + u64 __user *ptep; + bool writable; + int offset; + gfn_t gfn; + int r; + + lockdep_assert(srcu_read_lock_held(&kvm->srcu)); + + gfn = ipa >> PAGE_SHIFT; + offset = offset_in_page(ipa); + slot = gfn_to_memslot(kvm, gfn); + hva = gfn_to_hva_memslot_prot(slot, gfn, &writable); + if (kvm_is_error_hva(hva)) + return -EINVAL; + if (!writable) + return -EPERM; + + ptep = (u64 __user *)hva + offset; + if (cpus_have_final_cap(ARM64_HAS_LSE_ATOMICS)) + r = __lse_swap_desc(ptep, old, new); + else + r = __llsc_swap_desc(ptep, old, new); + + if (r < 0) + return r; + + mark_page_dirty_in_slot(kvm, slot, gfn); + return 0; +} diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index 29430c031095a..a7c689152f686 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -157,6 +157,7 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu) host_vcpu->arch.iflags = hyp_vcpu->vcpu.arch.iflags; host_cpu_if->vgic_hcr = hyp_cpu_if->vgic_hcr; + host_cpu_if->vgic_vmcr = hyp_cpu_if->vgic_vmcr; for (i = 0; i < hyp_cpu_if->used_lrs; ++i) host_cpu_if->vgic_lr[i] = hyp_cpu_if->vgic_lr[i]; } @@ -464,11 +465,11 @@ static void handle___vgic_v3_init_lrs(struct kvm_cpu_context *host_ctxt) __vgic_v3_init_lrs(); } -static void handle___vgic_v3_save_vmcr_aprs(struct kvm_cpu_context *host_ctxt) +static void handle___vgic_v3_save_aprs(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1); - __vgic_v3_save_vmcr_aprs(kern_hyp_va(cpu_if)); + __vgic_v3_save_aprs(kern_hyp_va(cpu_if)); } static void handle___vgic_v3_restore_vmcr_aprs(struct kvm_cpu_context *host_ctxt) @@ -616,7 +617,7 @@ static const hcall_t host_hcall[] = { HANDLE_FUNC(__kvm_tlb_flush_vmid_range), HANDLE_FUNC(__kvm_flush_cpu_context), HANDLE_FUNC(__kvm_timer_set_cntvoff), - HANDLE_FUNC(__vgic_v3_save_vmcr_aprs), + HANDLE_FUNC(__vgic_v3_save_aprs), HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs), HANDLE_FUNC(__pkvm_reserve_vm), HANDLE_FUNC(__pkvm_unreserve_vm), diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index 43bde061b65de..8911338961c5b 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -337,6 +337,9 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc /* CTR_EL0 is always under host control, even for protected VMs. */ hyp_vm->kvm.arch.ctr_el0 = host_kvm->arch.ctr_el0; + /* Preserve the vgic model so that GICv3 emulation works */ + hyp_vm->kvm.arch.vgic.vgic_model = host_kvm->arch.vgic.vgic_model; + if (test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &host_kvm->arch.flags)) set_bit(KVM_ARCH_FLAG_MTE_ENABLED, &kvm->arch.flags); diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c index 82da9b03692d4..3108b5185c204 100644 --- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c @@ -444,6 +444,8 @@ static const struct sys_reg_desc pvm_sys_reg_descs[] = { /* Scalable Vector Registers are restricted. */ + HOST_HANDLED(SYS_ICC_PMR_EL1), + RAZ_WI(SYS_ERRIDR_EL1), RAZ_WI(SYS_ERRSELR_EL1), RAZ_WI(SYS_ERXFR_EL1), @@ -457,9 +459,12 @@ static const struct sys_reg_desc pvm_sys_reg_descs[] = { /* Limited Ordering Regions Registers are restricted. */ + HOST_HANDLED(SYS_ICC_DIR_EL1), + HOST_HANDLED(SYS_ICC_RPR_EL1), HOST_HANDLED(SYS_ICC_SGI1R_EL1), HOST_HANDLED(SYS_ICC_ASGI1R_EL1), HOST_HANDLED(SYS_ICC_SGI0R_EL1), + HOST_HANDLED(SYS_ICC_CTLR_EL1), { SYS_DESC(SYS_ICC_SRE_EL1), .access = pvm_gic_read_sre, }, HOST_HANDLED(SYS_CCSIDR_EL1), diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index c351b4abd5dbf..947ac1a951a5b 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -661,11 +661,37 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu, #define KVM_S2_MEMATTR(pgt, attr) PAGE_S2_MEMATTR(attr, stage2_has_fwb(pgt)) +static int stage2_set_xn_attr(enum kvm_pgtable_prot prot, kvm_pte_t *attr) +{ + bool px, ux; + u8 xn; + + px = prot & KVM_PGTABLE_PROT_PX; + ux = prot & KVM_PGTABLE_PROT_UX; + + if (!cpus_have_final_cap(ARM64_HAS_XNX) && px != ux) + return -EINVAL; + + if (px && ux) + xn = 0b00; + else if (!px && ux) + xn = 0b01; + else if (!px && !ux) + xn = 0b10; + else + xn = 0b11; + + *attr &= ~KVM_PTE_LEAF_ATTR_HI_S2_XN; + *attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_HI_S2_XN, xn); + return 0; +} + static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot, kvm_pte_t *ptep) { kvm_pte_t attr; u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS; + int r; switch (prot & (KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC)) { @@ -685,8 +711,9 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p attr = KVM_S2_MEMATTR(pgt, NORMAL); } - if (!(prot & KVM_PGTABLE_PROT_X)) - attr |= KVM_PTE_LEAF_ATTR_HI_S2_XN; + r = stage2_set_xn_attr(prot, &attr); + if (r) + return r; if (prot & KVM_PGTABLE_PROT_R) attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R; @@ -715,8 +742,20 @@ enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte) prot |= KVM_PGTABLE_PROT_R; if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W) prot |= KVM_PGTABLE_PROT_W; - if (!(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN)) - prot |= KVM_PGTABLE_PROT_X; + + switch (FIELD_GET(KVM_PTE_LEAF_ATTR_HI_S2_XN, pte)) { + case 0b00: + prot |= KVM_PGTABLE_PROT_PX | KVM_PGTABLE_PROT_UX; + break; + case 0b01: + prot |= KVM_PGTABLE_PROT_UX; + break; + case 0b11: + prot |= KVM_PGTABLE_PROT_PX; + break; + default: + break; + } return prot; } @@ -1290,9 +1329,9 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot, enum kvm_pgtable_walk_flags flags) { - int ret; + kvm_pte_t xn = 0, set = 0, clr = 0; s8 level; - kvm_pte_t set = 0, clr = 0; + int ret; if (prot & KVM_PTE_LEAF_ATTR_HI_SW) return -EINVAL; @@ -1303,8 +1342,12 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, if (prot & KVM_PGTABLE_PROT_W) set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W; - if (prot & KVM_PGTABLE_PROT_X) - clr |= KVM_PTE_LEAF_ATTR_HI_S2_XN; + ret = stage2_set_xn_attr(prot, &xn); + if (ret) + return ret; + + set |= xn & KVM_PTE_LEAF_ATTR_HI_S2_XN; + clr |= ~xn & KVM_PTE_LEAF_ATTR_HI_S2_XN; ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level, flags); if (!ret || ret == -EAGAIN) @@ -1535,37 +1578,80 @@ size_t kvm_pgtable_stage2_pgd_size(u64 vtcr) return kvm_pgd_pages(ia_bits, start_level) * PAGE_SIZE; } -static int stage2_free_walker(const struct kvm_pgtable_visit_ctx *ctx, - enum kvm_pgtable_walk_flags visit) +static int stage2_free_leaf(const struct kvm_pgtable_visit_ctx *ctx) { struct kvm_pgtable_mm_ops *mm_ops = ctx->mm_ops; - if (!stage2_pte_is_counted(ctx->old)) + mm_ops->put_page(ctx->ptep); + return 0; +} + +static int stage2_free_table_post(const struct kvm_pgtable_visit_ctx *ctx) +{ + struct kvm_pgtable_mm_ops *mm_ops = ctx->mm_ops; + kvm_pte_t *childp = kvm_pte_follow(ctx->old, mm_ops); + + if (mm_ops->page_count(childp) != 1) return 0; + /* + * Drop references and clear the now stale PTE to avoid rewalking the + * freed page table. + */ mm_ops->put_page(ctx->ptep); + mm_ops->put_page(childp); + kvm_clear_pte(ctx->ptep); + return 0; +} - if (kvm_pte_table(ctx->old, ctx->level)) - mm_ops->put_page(kvm_pte_follow(ctx->old, mm_ops)); +static int stage2_free_walker(const struct kvm_pgtable_visit_ctx *ctx, + enum kvm_pgtable_walk_flags visit) +{ + if (!stage2_pte_is_counted(ctx->old)) + return 0; - return 0; + switch (visit) { + case KVM_PGTABLE_WALK_LEAF: + return stage2_free_leaf(ctx); + case KVM_PGTABLE_WALK_TABLE_POST: + return stage2_free_table_post(ctx); + default: + return -EINVAL; + } } -void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt) +void kvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt, + u64 addr, u64 size) { - size_t pgd_sz; struct kvm_pgtable_walker walker = { .cb = stage2_free_walker, .flags = KVM_PGTABLE_WALK_LEAF | KVM_PGTABLE_WALK_TABLE_POST, }; - WARN_ON(kvm_pgtable_walk(pgt, 0, BIT(pgt->ia_bits), &walker)); + WARN_ON(kvm_pgtable_walk(pgt, addr, size, &walker)); +} + +void kvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt) +{ + size_t pgd_sz; + pgd_sz = kvm_pgd_pages(pgt->ia_bits, pgt->start_level) * PAGE_SIZE; - pgt->mm_ops->free_pages_exact(kvm_dereference_pteref(&walker, pgt->pgd), pgd_sz); + + /* + * Since the pgtable is unlinked at this point, and not shared with + * other walkers, safely deference pgd with kvm_dereference_pteref_raw() + */ + pgt->mm_ops->free_pages_exact(kvm_dereference_pteref_raw(pgt->pgd), pgd_sz); pgt->pgd = NULL; } +void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt) +{ + kvm_pgtable_stage2_destroy_range(pgt, 0, BIT(pgt->ia_bits)); + kvm_pgtable_stage2_destroy_pgd(pgt); +} + void kvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level) { kvm_pteref_t ptep = (kvm_pteref_t)pgtable; diff --git a/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c index 78579b31a4205..5fd99763b54de 100644 --- a/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c +++ b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c @@ -63,6 +63,10 @@ int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu) return -1; } + /* Handle deactivation as a normal exit */ + if ((fault_ipa - vgic->vgic_cpu_base) >= GIC_CPU_DEACTIVATE) + return 0; + rd = kvm_vcpu_dabt_get_rd(vcpu); addr = kvm_vgic_global_state.vcpu_hyp_va; addr += fault_ipa - vgic->vgic_cpu_base; diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c index acd909b7f2257..0b670a033fd87 100644 --- a/arch/arm64/kvm/hyp/vgic-v3-sr.c +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c @@ -14,6 +14,8 @@ #include #include +#include "../../vgic/vgic.h" + #define vtr_to_max_lr_idx(v) ((v) & 0xf) #define vtr_to_nr_pre_bits(v) ((((u32)(v) >> 26) & 7) + 1) #define vtr_to_nr_apr_regs(v) (1 << (vtr_to_nr_pre_bits(v) - 5)) @@ -58,7 +60,7 @@ u64 __gic_v3_get_lr(unsigned int lr) unreachable(); } -static void __gic_v3_set_lr(u64 val, int lr) +void __gic_v3_set_lr(u64 val, int lr) { switch (lr & 0xf) { case 0: @@ -196,6 +198,11 @@ static u32 __vgic_v3_read_ap1rn(int n) return val; } +static u64 compute_ich_hcr(struct vgic_v3_cpu_if *cpu_if) +{ + return cpu_if->vgic_hcr | vgic_ich_hcr_trap_bits(); +} + void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if) { u64 used_lrs = cpu_if->used_lrs; @@ -212,14 +219,12 @@ void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if) } } - if (used_lrs || cpu_if->its_vpe.its_vm) { + if (used_lrs) { int i; u32 elrsr; elrsr = read_gicreg(ICH_ELRSR_EL2); - write_gicreg(cpu_if->vgic_hcr & ~ICH_HCR_EL2_En, ICH_HCR_EL2); - for (i = 0; i < used_lrs; i++) { if (elrsr & (1 << i)) cpu_if->vgic_lr[i] &= ~ICH_LR_STATE; @@ -229,6 +234,23 @@ void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if) __gic_v3_set_lr(0, i); } } + + cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2); + + if (cpu_if->vgic_hcr & ICH_HCR_EL2_LRENPIE) { + u64 val = read_gicreg(ICH_HCR_EL2); + cpu_if->vgic_hcr &= ~ICH_HCR_EL2_EOIcount; + cpu_if->vgic_hcr |= val & ICH_HCR_EL2_EOIcount; + } + + write_gicreg(0, ICH_HCR_EL2); + + /* + * Hack alert: On NV, this results in a trap so that the above write + * actually takes effect... No synchronisation is necessary, as we + * only care about the effects when this traps. + */ + read_gicreg(ICH_MISR_EL2); } void __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if) @@ -236,12 +258,10 @@ void __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if) u64 used_lrs = cpu_if->used_lrs; int i; - if (used_lrs || cpu_if->its_vpe.its_vm) { - write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2); + write_gicreg(compute_ich_hcr(cpu_if), ICH_HCR_EL2); - for (i = 0; i < used_lrs; i++) - __gic_v3_set_lr(cpu_if->vgic_lr[i], i); - } + for (i = 0; i < used_lrs; i++) + __gic_v3_set_lr(cpu_if->vgic_lr[i], i); /* * Ensure that writes to the LRs, and on non-VHE systems ensure that @@ -307,24 +327,20 @@ void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if) } /* - * If we need to trap system registers, we must write - * ICH_HCR_EL2 anyway, even if no interrupts are being - * injected. Note that this also applies if we don't expect - * any system register access (no vgic at all). + * If we need to trap system registers, we must write ICH_HCR_EL2 + * anyway, even if no interrupts are being injected. Note that this + * also applies if we don't expect any system register access (no + * vgic at all). In any case, no need to provide MI configuration. */ if (static_branch_unlikely(&vgic_v3_cpuif_trap) || cpu_if->its_vpe.its_vm || !cpu_if->vgic_sre) - write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2); + write_gicreg(vgic_ich_hcr_trap_bits() | ICH_HCR_EL2_En, ICH_HCR_EL2); } void __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if) { u64 val; - if (!cpu_if->vgic_sre) { - cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2); - } - /* Only restore SRE if the host implements the GICv2 interface */ if (static_branch_unlikely(&vgic_v3_has_v2_compat)) { val = read_gicreg(ICC_SRE_EL2); @@ -346,7 +362,7 @@ void __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if) write_gicreg(0, ICH_HCR_EL2); } -static void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if) +void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if) { u64 val; u32 nr_pre_bits; @@ -507,13 +523,6 @@ static void __vgic_v3_write_vmcr(u32 vmcr) write_gicreg(vmcr, ICH_VMCR_EL2); } -void __vgic_v3_save_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if) -{ - __vgic_v3_save_aprs(cpu_if); - if (cpu_if->vgic_sre) - cpu_if->vgic_vmcr = __vgic_v3_read_vmcr(); -} - void __vgic_v3_restore_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if) { __vgic_v3_compat_mode_enable(); @@ -790,7 +799,7 @@ static void __vgic_v3_bump_eoicount(void) write_gicreg(hcr, ICH_HCR_EL2); } -static void __vgic_v3_write_dir(struct kvm_vcpu *vcpu, u32 vmcr, int rt) +static int ___vgic_v3_write_dir(struct kvm_vcpu *vcpu, u32 vmcr, int rt) { u32 vid = vcpu_get_reg(vcpu, rt); u64 lr_val; @@ -798,19 +807,25 @@ static void __vgic_v3_write_dir(struct kvm_vcpu *vcpu, u32 vmcr, int rt) /* EOImode == 0, nothing to be done here */ if (!(vmcr & ICH_VMCR_EOIM_MASK)) - return; + return 1; /* No deactivate to be performed on an LPI */ if (vid >= VGIC_MIN_LPI) - return; + return 1; lr = __vgic_v3_find_active_lr(vcpu, vid, &lr_val); - if (lr == -1) { - __vgic_v3_bump_eoicount(); - return; + if (lr != -1) { + __vgic_v3_clear_active_lr(lr, lr_val); + return 1; } - __vgic_v3_clear_active_lr(lr, lr_val); + return 0; +} + +static void __vgic_v3_write_dir(struct kvm_vcpu *vcpu, u32 vmcr, int rt) +{ + if (!___vgic_v3_write_dir(vcpu, vmcr, rt)) + __vgic_v3_bump_eoicount(); } static void __vgic_v3_write_eoir(struct kvm_vcpu *vcpu, u32 vmcr, int rt) @@ -1245,6 +1260,21 @@ int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu) case SYS_ICC_DIR_EL1: if (unlikely(is_read)) return 0; + /* + * Full exit if required to handle overflow deactivation, + * unless we can emulate it in the LRs (likely the majority + * of the cases). + */ + if (vcpu->arch.vgic_cpu.vgic_v3.vgic_hcr & ICH_HCR_EL2_TDIR) { + int ret; + + ret = ___vgic_v3_write_dir(vcpu, __vgic_v3_read_vmcr(), + kvm_vcpu_sys_get_rt(vcpu)); + if (ret) + __kvm_skip_instr(vcpu); + + return ret; + } fn = __vgic_v3_write_dir; break; case SYS_ICC_RPR_EL1: diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 9a6a80c3fbe52..48d7c372a4cd0 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -904,6 +904,38 @@ static int kvm_init_ipa_range(struct kvm_s2_mmu *mmu, unsigned long type) return 0; } +/* + * Assume that @pgt is valid and unlinked from the KVM MMU to free the + * page-table without taking the kvm_mmu_lock and without performing any + * TLB invalidations. + * + * Also, the range of addresses can be large enough to cause need_resched + * warnings, for instance on CONFIG_PREEMPT_NONE kernels. Hence, invoke + * cond_resched() periodically to prevent hogging the CPU for a long time + * and schedule something else, if required. + */ +static void stage2_destroy_range(struct kvm_pgtable *pgt, phys_addr_t addr, + phys_addr_t end) +{ + u64 next; + + do { + next = stage2_range_addr_end(addr, end); + KVM_PGT_FN(kvm_pgtable_stage2_destroy_range)(pgt, addr, + next - addr); + if (next != end) + cond_resched(); + } while (addr = next, addr != end); +} + +static void kvm_stage2_destroy(struct kvm_pgtable *pgt) +{ + unsigned int ia_bits = VTCR_EL2_IPA(pgt->mmu->vtcr); + + stage2_destroy_range(pgt, 0, BIT(ia_bits)); + KVM_PGT_FN(kvm_pgtable_stage2_destroy_pgd)(pgt); +} + /** * kvm_init_stage2_mmu - Initialise a S2 MMU structure * @kvm: The pointer to the KVM structure @@ -980,7 +1012,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t return 0; out_destroy_pgtable: - KVM_PGT_FN(kvm_pgtable_stage2_destroy)(pgt); + kvm_stage2_destroy(pgt); out_free_pgtable: kfree(pgt); return err; @@ -1081,7 +1113,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu) write_unlock(&kvm->mmu_lock); if (pgt) { - KVM_PGT_FN(kvm_pgtable_stage2_destroy)(pgt); + kvm_stage2_destroy(pgt); kfree(pgt); } } @@ -1521,6 +1553,16 @@ static void adjust_nested_fault_perms(struct kvm_s2_trans *nested, *prot |= kvm_encode_nested_level(nested); } +static void adjust_nested_exec_perms(struct kvm *kvm, + struct kvm_s2_trans *nested, + enum kvm_pgtable_prot *prot) +{ + if (!kvm_s2_trans_exec_el0(kvm, nested)) + *prot &= ~KVM_PGTABLE_PROT_UX; + if (!kvm_s2_trans_exec_el1(kvm, nested)) + *prot &= ~KVM_PGTABLE_PROT_PX; +} + #define KVM_PGTABLE_WALK_MEMABORT_FLAGS (KVM_PGTABLE_WALK_HANDLE_FAULT | KVM_PGTABLE_WALK_SHARED) static int gmem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, @@ -1572,11 +1614,12 @@ static int gmem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (writable) prot |= KVM_PGTABLE_PROT_W; - if (exec_fault || - (cpus_have_final_cap(ARM64_HAS_CACHE_DIC) && - (!nested || kvm_s2_trans_executable(nested)))) + if (exec_fault || cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) prot |= KVM_PGTABLE_PROT_X; + if (nested) + adjust_nested_exec_perms(kvm, nested, &prot); + kvm_fault_lock(kvm); if (mmu_invalidate_retry(kvm, mmu_seq)) { ret = -EAGAIN; @@ -1851,11 +1894,13 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, prot |= KVM_PGTABLE_PROT_NORMAL_NC; else prot |= KVM_PGTABLE_PROT_DEVICE; - } else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC) && - (!nested || kvm_s2_trans_executable(nested))) { + } else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) { prot |= KVM_PGTABLE_PROT_X; } + if (nested) + adjust_nested_exec_perms(kvm, nested, &prot); + /* * Under the premise of getting a FSC_PERM fault, we just need to relax * permissions only if vma_pagesize equals fault_granule. Otherwise, @@ -1899,8 +1944,48 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa) read_unlock(&vcpu->kvm->mmu_lock); } +/* + * Returns true if the SEA should be handled locally within KVM if the abort + * is caused by a kernel memory allocation (e.g. stage-2 table memory). + */ +static bool host_owns_sea(struct kvm_vcpu *vcpu, u64 esr) +{ + /* + * Without FEAT_RAS HCR_EL2.TEA is RES0, meaning any external abort + * taken from a guest EL to EL2 is due to a host-imposed access (e.g. + * stage-2 PTW). + */ + if (!cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) + return true; + + /* KVM owns the VNCR when the vCPU isn't in a nested context. */ + if (is_hyp_ctxt(vcpu) && !kvm_vcpu_trap_is_iabt(vcpu) && (esr & ESR_ELx_VNCR)) + return true; + + /* + * Determining if an external abort during a table walk happened at + * stage-2 is only possible with S1PTW is set. Otherwise, since KVM + * sets HCR_EL2.TEA, SEAs due to a stage-1 walk (i.e. accessing the + * PA of the stage-1 descriptor) can reach here and are reported + * with a TTW ESR value. + */ + return (esr_fsc_is_sea_ttw(esr) && (esr & ESR_ELx_S1PTW)); +} + int kvm_handle_guest_sea(struct kvm_vcpu *vcpu) { + struct kvm *kvm = vcpu->kvm; + struct kvm_run *run = vcpu->run; + u64 esr = kvm_vcpu_get_esr(vcpu); + u64 esr_mask = ESR_ELx_EC_MASK | + ESR_ELx_IL | + ESR_ELx_FnV | + ESR_ELx_EA | + ESR_ELx_CM | + ESR_ELx_WNR | + ESR_ELx_FSC; + u64 ipa; + /* * Give APEI the opportunity to claim the abort before handling it * within KVM. apei_claim_sea() expects to be called with IRQs enabled. @@ -1909,7 +1994,33 @@ int kvm_handle_guest_sea(struct kvm_vcpu *vcpu) if (apei_claim_sea(NULL) == 0) return 1; - return kvm_inject_serror(vcpu); + if (host_owns_sea(vcpu, esr) || + !test_bit(KVM_ARCH_FLAG_EXIT_SEA, &vcpu->kvm->arch.flags)) + return kvm_inject_serror(vcpu); + + /* ESR_ELx.SET is RES0 when FEAT_RAS isn't implemented. */ + if (kvm_has_ras(kvm)) + esr_mask |= ESR_ELx_SET_MASK; + + /* + * Exit to userspace, and provide faulting guest virtual and physical + * addresses in case userspace wants to emulate SEA to guest by + * writing to FAR_ELx and HPFAR_ELx registers. + */ + memset(&run->arm_sea, 0, sizeof(run->arm_sea)); + run->exit_reason = KVM_EXIT_ARM_SEA; + run->arm_sea.esr = esr & esr_mask; + + if (!(esr & ESR_ELx_FnV)) + run->arm_sea.gva = kvm_vcpu_get_hfar(vcpu); + + ipa = kvm_vcpu_get_fault_ipa(vcpu); + if (ipa != INVALID_GPA) { + run->arm_sea.flags |= KVM_EXIT_ARM_SEA_FLAG_GPA_VALID; + run->arm_sea.gpa = ipa; + } + + return 0; } /** @@ -1999,6 +2110,11 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) u32 esr; ret = kvm_walk_nested_s2(vcpu, fault_ipa, &nested_trans); + if (ret == -EAGAIN) { + ret = 1; + goto out_unlock; + } + if (ret) { esr = kvm_s2_trans_esr(&nested_trans); kvm_inject_s2_fault(vcpu, esr); diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c index be6bbd1677709..cdeeb8f09e722 100644 --- a/arch/arm64/kvm/nested.c +++ b/arch/arm64/kvm/nested.c @@ -124,14 +124,13 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu) } struct s2_walk_info { - int (*read_desc)(phys_addr_t pa, u64 *desc, void *data); - void *data; - u64 baddr; - unsigned int max_oa_bits; - unsigned int pgshift; - unsigned int sl; - unsigned int t0sz; - bool be; + u64 baddr; + unsigned int max_oa_bits; + unsigned int pgshift; + unsigned int sl; + unsigned int t0sz; + bool be; + bool ha; }; static u32 compute_fsc(int level, u32 fsc) @@ -199,6 +198,42 @@ static int check_output_size(struct s2_walk_info *wi, phys_addr_t output) return 0; } +static int read_guest_s2_desc(struct kvm_vcpu *vcpu, phys_addr_t pa, u64 *desc, + struct s2_walk_info *wi) +{ + u64 val; + int r; + + r = kvm_read_guest(vcpu->kvm, pa, &val, sizeof(val)); + if (r) + return r; + + /* + * Handle reversedescriptors if endianness differs between the + * host and the guest hypervisor. + */ + if (wi->be) + *desc = be64_to_cpu((__force __be64)val); + else + *desc = le64_to_cpu((__force __le64)val); + + return 0; +} + +static int swap_guest_s2_desc(struct kvm_vcpu *vcpu, phys_addr_t pa, u64 old, u64 new, + struct s2_walk_info *wi) +{ + if (wi->be) { + old = (__force u64)cpu_to_be64(old); + new = (__force u64)cpu_to_be64(new); + } else { + old = (__force u64)cpu_to_le64(old); + new = (__force u64)cpu_to_le64(new); + } + + return __kvm_at_swap_desc(vcpu->kvm, pa, old, new); +} + /* * This is essentially a C-version of the pseudo code from the ARM ARM * AArch64.TranslationTableWalk function. I strongly recommend looking at @@ -206,13 +241,13 @@ static int check_output_size(struct s2_walk_info *wi, phys_addr_t output) * * Must be called with the kvm->srcu read lock held */ -static int walk_nested_s2_pgd(phys_addr_t ipa, +static int walk_nested_s2_pgd(struct kvm_vcpu *vcpu, phys_addr_t ipa, struct s2_walk_info *wi, struct kvm_s2_trans *out) { int first_block_level, level, stride, input_size, base_lower_bound; phys_addr_t base_addr; unsigned int addr_top, addr_bottom; - u64 desc; /* page table entry */ + u64 desc, new_desc; /* page table entry */ int ret; phys_addr_t paddr; @@ -257,28 +292,30 @@ static int walk_nested_s2_pgd(phys_addr_t ipa, >> (addr_bottom - 3); paddr = base_addr | index; - ret = wi->read_desc(paddr, &desc, wi->data); + ret = read_guest_s2_desc(vcpu, paddr, &desc, wi); if (ret < 0) return ret; - /* - * Handle reversedescriptors if endianness differs between the - * host and the guest hypervisor. - */ - if (wi->be) - desc = be64_to_cpu((__force __be64)desc); - else - desc = le64_to_cpu((__force __le64)desc); + new_desc = desc; /* Check for valid descriptor at this point */ - if (!(desc & 1) || ((desc & 3) == 1 && level == 3)) { + if (!(desc & KVM_PTE_VALID)) { out->esr = compute_fsc(level, ESR_ELx_FSC_FAULT); out->desc = desc; return 1; } - /* We're at the final level or block translation level */ - if ((desc & 3) == 1 || level == 3) + if (FIELD_GET(KVM_PTE_TYPE, desc) == KVM_PTE_TYPE_BLOCK) { + if (level < 3) + break; + + out->esr = compute_fsc(level, ESR_ELx_FSC_FAULT); + out->desc = desc; + return 1; + } + + /* We're at the final level */ + if (level == 3) break; if (check_output_size(wi, desc)) { @@ -305,7 +342,18 @@ static int walk_nested_s2_pgd(phys_addr_t ipa, return 1; } - if (!(desc & BIT(10))) { + if (wi->ha) + new_desc |= KVM_PTE_LEAF_ATTR_LO_S2_AF; + + if (new_desc != desc) { + ret = swap_guest_s2_desc(vcpu, paddr, desc, new_desc, wi); + if (ret) + return ret; + + desc = new_desc; + } + + if (!(desc & KVM_PTE_LEAF_ATTR_LO_S2_AF)) { out->esr = compute_fsc(level, ESR_ELx_FSC_ACCESS); out->desc = desc; return 1; @@ -318,20 +366,13 @@ static int walk_nested_s2_pgd(phys_addr_t ipa, (ipa & GENMASK_ULL(addr_bottom - 1, 0)); out->output = paddr; out->block_size = 1UL << ((3 - level) * stride + wi->pgshift); - out->readable = desc & (0b01 << 6); - out->writable = desc & (0b10 << 6); + out->readable = desc & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R; + out->writable = desc & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W; out->level = level; out->desc = desc; return 0; } -static int read_guest_s2_desc(phys_addr_t pa, u64 *desc, void *data) -{ - struct kvm_vcpu *vcpu = data; - - return kvm_read_guest(vcpu->kvm, pa, desc, sizeof(*desc)); -} - static void vtcr_to_walk_info(u64 vtcr, struct s2_walk_info *wi) { wi->t0sz = vtcr & TCR_EL2_T0SZ_MASK; @@ -350,6 +391,8 @@ static void vtcr_to_walk_info(u64 vtcr, struct s2_walk_info *wi) /* Global limit for now, should eventually be per-VM */ wi->max_oa_bits = min(get_kvm_ipa_limit(), ps_to_output_size(FIELD_GET(VTCR_EL2_PS_MASK, vtcr), false)); + + wi->ha = vtcr & VTCR_EL2_HA; } int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa, @@ -364,15 +407,13 @@ int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa, if (!vcpu_has_nv(vcpu)) return 0; - wi.read_desc = read_guest_s2_desc; - wi.data = vcpu; wi.baddr = vcpu_read_sys_reg(vcpu, VTTBR_EL2); vtcr_to_walk_info(vtcr, &wi); wi.be = vcpu_read_sys_reg(vcpu, SCTLR_EL2) & SCTLR_ELx_EE; - ret = walk_nested_s2_pgd(gipa, &wi, result); + ret = walk_nested_s2_pgd(vcpu, gipa, &wi, result); if (ret) result->esr |= (kvm_vcpu_get_esr(vcpu) & ~ESR_ELx_FSC); @@ -788,7 +829,10 @@ int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, struct kvm_s2_trans *trans) return 0; if (kvm_vcpu_trap_is_iabt(vcpu)) { - forward_fault = !kvm_s2_trans_executable(trans); + if (vcpu_mode_priv(vcpu)) + forward_fault = !kvm_s2_trans_exec_el1(vcpu->kvm, trans); + else + forward_fault = !kvm_s2_trans_exec_el0(vcpu->kvm, trans); } else { bool write_fault = kvm_is_write_fault(vcpu); @@ -1555,12 +1599,13 @@ u64 limit_nv_id_reg(struct kvm *kvm, u32 reg, u64 val) case SYS_ID_AA64MMFR1_EL1: val &= ~(ID_AA64MMFR1_EL1_CMOW | ID_AA64MMFR1_EL1_nTLBPA | - ID_AA64MMFR1_EL1_ETS | - ID_AA64MMFR1_EL1_XNX | - ID_AA64MMFR1_EL1_HAFDBS); + ID_AA64MMFR1_EL1_ETS); + /* FEAT_E2H0 implies no VHE */ if (test_bit(KVM_ARM_VCPU_HAS_EL2_E2H0, kvm->arch.vcpu_features)) val &= ~ID_AA64MMFR1_EL1_VH; + + val = ID_REG_LIMIT_FIELD_ENUM(val, ID_AA64MMFR1_EL1, HAFDBS, AF); break; case SYS_ID_AA64MMFR2_EL1: diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 24f0f8a8c943c..d7a0f69a99821 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -344,9 +344,16 @@ static int __pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 start, u64 e return 0; } -void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt) +void pkvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt, + u64 addr, u64 size) { - __pkvm_pgtable_stage2_unmap(pgt, 0, ~(0ULL)); + __pkvm_pgtable_stage2_unmap(pgt, addr, addr + size); +} + +void pkvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt) +{ + /* Expected to be called after all pKVM mappings have been released. */ + WARN_ON_ONCE(!RB_EMPTY_ROOT(&pgt->pkvm_mappings.rb_root)); } int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c index dc5acfb00af91..6cbe018fd6fda 100644 --- a/arch/arm64/kvm/ptdump.c +++ b/arch/arm64/kvm/ptdump.c @@ -31,27 +31,46 @@ static const struct ptdump_prot_bits stage2_pte_bits[] = { .val = PTE_VALID, .set = " ", .clear = "F", - }, { + }, + { .mask = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R, .val = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R, .set = "R", .clear = " ", - }, { + }, + { .mask = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W, .val = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W, .set = "W", .clear = " ", - }, { + }, + { .mask = KVM_PTE_LEAF_ATTR_HI_S2_XN, - .val = KVM_PTE_LEAF_ATTR_HI_S2_XN, - .set = "NX", - .clear = "x ", - }, { + .val = 0b00UL << __bf_shf(KVM_PTE_LEAF_ATTR_HI_S2_XN), + .set = "px ux ", + }, + { + .mask = KVM_PTE_LEAF_ATTR_HI_S2_XN, + .val = 0b01UL << __bf_shf(KVM_PTE_LEAF_ATTR_HI_S2_XN), + .set = "PXNux ", + }, + { + .mask = KVM_PTE_LEAF_ATTR_HI_S2_XN, + .val = 0b10UL << __bf_shf(KVM_PTE_LEAF_ATTR_HI_S2_XN), + .set = "PXNUXN", + }, + { + .mask = KVM_PTE_LEAF_ATTR_HI_S2_XN, + .val = 0b11UL << __bf_shf(KVM_PTE_LEAF_ATTR_HI_S2_XN), + .set = "px UXN", + }, + { .mask = KVM_PTE_LEAF_ATTR_LO_S2_AF, .val = KVM_PTE_LEAF_ATTR_LO_S2_AF, .set = "AF", .clear = " ", - }, { + }, + { .mask = PMD_TYPE_MASK, .val = PMD_TYPE_SECT, .set = "BLK", diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index ec3fbe0b8d525..c8fd7c6a12a13 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -666,6 +666,21 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu, return true; } +static bool access_gic_dir(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (!kvm_has_gicv3(vcpu->kvm)) + return undef_access(vcpu, p, r); + + if (!p->is_write) + return undef_access(vcpu, p, r); + + vgic_v3_deactivate(vcpu, p->regval); + + return true; +} + static bool trap_raz_wi(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) @@ -3373,7 +3388,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_ICC_AP1R1_EL1), undef_access }, { SYS_DESC(SYS_ICC_AP1R2_EL1), undef_access }, { SYS_DESC(SYS_ICC_AP1R3_EL1), undef_access }, - { SYS_DESC(SYS_ICC_DIR_EL1), undef_access }, + { SYS_DESC(SYS_ICC_DIR_EL1), access_gic_dir }, { SYS_DESC(SYS_ICC_RPR_EL1), undef_access }, { SYS_DESC(SYS_ICC_SGI1R_EL1), access_gic_sgi }, { SYS_DESC(SYS_ICC_ASGI1R_EL1), access_gic_sgi }, @@ -3770,7 +3785,8 @@ static bool handle_at_s1e01(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { u32 op = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2); - __kvm_at_s1e01(vcpu, op, p->regval); + if (__kvm_at_s1e01(vcpu, op, p->regval)) + return false; return true; } @@ -3787,7 +3803,8 @@ static bool handle_at_s1e2(struct kvm_vcpu *vcpu, struct sys_reg_params *p, return false; } - __kvm_at_s1e2(vcpu, op, p->regval); + if (__kvm_at_s1e2(vcpu, op, p->regval)) + return false; return true; } @@ -3797,7 +3814,8 @@ static bool handle_at_s12(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { u32 op = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2); - __kvm_at_s12(vcpu, op, p->regval); + if (__kvm_at_s12(vcpu, op, p->regval)) + return false; return true; } @@ -4498,7 +4516,7 @@ static const struct sys_reg_desc cp15_regs[] = { { CP15_SYS_DESC(SYS_ICC_AP1R1_EL1), undef_access }, { CP15_SYS_DESC(SYS_ICC_AP1R2_EL1), undef_access }, { CP15_SYS_DESC(SYS_ICC_AP1R3_EL1), undef_access }, - { CP15_SYS_DESC(SYS_ICC_DIR_EL1), undef_access }, + { CP15_SYS_DESC(SYS_ICC_DIR_EL1), access_gic_dir }, { CP15_SYS_DESC(SYS_ICC_RPR_EL1), undef_access }, { CP15_SYS_DESC(SYS_ICC_IAR1_EL1), undef_access }, { CP15_SYS_DESC(SYS_ICC_EOIR1_EL1), undef_access }, diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index da62edbc1205a..dc9f9db310264 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -198,6 +198,7 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis) struct kvm_vcpu *vcpu0 = kvm_get_vcpu(kvm, 0); int i; + dist->active_spis = (atomic_t)ATOMIC_INIT(0); dist->spis = kcalloc(nr_spis, sizeof(struct vgic_irq), GFP_KERNEL_ACCOUNT); if (!dist->spis) return -ENOMEM; @@ -363,12 +364,12 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) return ret; } -static void kvm_vgic_vcpu_enable(struct kvm_vcpu *vcpu) +static void kvm_vgic_vcpu_reset(struct kvm_vcpu *vcpu) { if (kvm_vgic_global_state.type == VGIC_V2) - vgic_v2_enable(vcpu); + vgic_v2_reset(vcpu); else - vgic_v3_enable(vcpu); + vgic_v3_reset(vcpu); } /* @@ -415,7 +416,7 @@ int vgic_init(struct kvm *kvm) } kvm_for_each_vcpu(idx, vcpu, kvm) - kvm_vgic_vcpu_enable(vcpu); + kvm_vgic_vcpu_reset(vcpu); ret = kvm_vgic_setup_default_irq_routing(kvm); if (ret) diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v2.c b/arch/arm64/kvm/vgic/vgic-mmio-v2.c index f25fccb1f8e63..406845b3117cf 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v2.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v2.c @@ -359,6 +359,16 @@ static void vgic_mmio_write_vcpuif(struct kvm_vcpu *vcpu, vgic_set_vmcr(vcpu, &vmcr); } +static void vgic_mmio_write_dir(struct kvm_vcpu *vcpu, + gpa_t addr, unsigned int len, + unsigned long val) +{ + if (kvm_vgic_global_state.type == VGIC_V2) + vgic_v2_deactivate(vcpu, val); + else + vgic_v3_deactivate(vcpu, val); +} + static unsigned long vgic_mmio_read_apr(struct kvm_vcpu *vcpu, gpa_t addr, unsigned int len) { @@ -482,6 +492,10 @@ static const struct vgic_register_region vgic_v2_cpu_registers[] = { REGISTER_DESC_WITH_LENGTH(GIC_CPU_IDENT, vgic_mmio_read_vcpuif, vgic_mmio_write_vcpuif, 4, VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_LENGTH_UACCESS(GIC_CPU_DEACTIVATE, + vgic_mmio_read_raz, vgic_mmio_write_dir, + vgic_mmio_read_raz, vgic_mmio_uaccess_write_wi, + 4, VGIC_ACCESS_32bit), }; unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev) @@ -494,6 +508,16 @@ unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev) return SZ_4K; } +unsigned int vgic_v2_init_cpuif_iodev(struct vgic_io_device *dev) +{ + dev->regions = vgic_v2_cpu_registers; + dev->nr_regions = ARRAY_SIZE(vgic_v2_cpu_registers); + + kvm_iodevice_init(&dev->dev, &kvm_io_gic_ops); + + return KVM_VGIC_V2_CPU_SIZE; +} + int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr) { const struct vgic_register_region *region; diff --git a/arch/arm64/kvm/vgic/vgic-mmio.h b/arch/arm64/kvm/vgic/vgic-mmio.h index 5b490a4dfa5e9..50dc80220b0f3 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio.h +++ b/arch/arm64/kvm/vgic/vgic-mmio.h @@ -213,6 +213,7 @@ void vgic_write_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid, const u32 val); unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev); +unsigned int vgic_v2_init_cpuif_iodev(struct vgic_io_device *dev); unsigned int vgic_v3_init_dist_iodev(struct vgic_io_device *dev); diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c index 381673f03c395..585491fbda807 100644 --- a/arch/arm64/kvm/vgic/vgic-v2.c +++ b/arch/arm64/kvm/vgic/vgic-v2.c @@ -9,6 +9,7 @@ #include #include +#include "vgic-mmio.h" #include "vgic.h" static inline void vgic_v2_write_lr(int lr, u32 val) @@ -26,11 +27,24 @@ void vgic_v2_init_lrs(void) vgic_v2_write_lr(i, 0); } -void vgic_v2_set_underflow(struct kvm_vcpu *vcpu) +void vgic_v2_configure_hcr(struct kvm_vcpu *vcpu, + struct ap_list_summary *als) { struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2; - cpuif->vgic_hcr |= GICH_HCR_UIE; + cpuif->vgic_hcr = GICH_HCR_EN; + + if (irqs_pending_outside_lrs(als)) + cpuif->vgic_hcr |= GICH_HCR_NPIE; + if (irqs_active_outside_lrs(als)) + cpuif->vgic_hcr |= GICH_HCR_LRENPIE; + if (irqs_outside_lrs(als)) + cpuif->vgic_hcr |= GICH_HCR_UIE; + + cpuif->vgic_hcr |= (cpuif->vgic_vmcr & GICH_VMCR_ENABLE_GRP0_MASK) ? + GICH_HCR_VGrp0DIE : GICH_HCR_VGrp0EIE; + cpuif->vgic_hcr |= (cpuif->vgic_vmcr & GICH_VMCR_ENABLE_GRP1_MASK) ? + GICH_HCR_VGrp1DIE : GICH_HCR_VGrp1EIE; } static bool lr_signals_eoi_mi(u32 lr_val) @@ -39,43 +53,23 @@ static bool lr_signals_eoi_mi(u32 lr_val) !(lr_val & GICH_LR_HW); } -/* - * transfer the content of the LRs back into the corresponding ap_list: - * - active bit is transferred as is - * - pending bit is - * - transferred as is in case of edge sensitive IRQs - * - set to the line-level (resample time) for level sensitive IRQs - */ -void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) +static void vgic_v2_fold_lr(struct kvm_vcpu *vcpu, u32 val) { - struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; - struct vgic_v2_cpu_if *cpuif = &vgic_cpu->vgic_v2; - int lr; - - DEBUG_SPINLOCK_BUG_ON(!irqs_disabled()); - - cpuif->vgic_hcr &= ~GICH_HCR_UIE; - - for (lr = 0; lr < vgic_cpu->vgic_v2.used_lrs; lr++) { - u32 val = cpuif->vgic_lr[lr]; - u32 cpuid, intid = val & GICH_LR_VIRTUALID; - struct vgic_irq *irq; - bool deactivated; - - /* Extract the source vCPU id from the LR */ - cpuid = val & GICH_LR_PHYSID_CPUID; - cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT; - cpuid &= 7; + u32 cpuid, intid = val & GICH_LR_VIRTUALID; + struct vgic_irq *irq; + bool deactivated; - /* Notify fds when the guest EOI'ed a level-triggered SPI */ - if (lr_signals_eoi_mi(val) && vgic_valid_spi(vcpu->kvm, intid)) - kvm_notify_acked_irq(vcpu->kvm, 0, - intid - VGIC_NR_PRIVATE_IRQS); + /* Extract the source vCPU id from the LR */ + cpuid = FIELD_GET(GICH_LR_PHYSID_CPUID, val) & 7; - irq = vgic_get_vcpu_irq(vcpu, intid); + /* Notify fds when the guest EOI'ed a level-triggered SPI */ + if (lr_signals_eoi_mi(val) && vgic_valid_spi(vcpu->kvm, intid)) + kvm_notify_acked_irq(vcpu->kvm, 0, + intid - VGIC_NR_PRIVATE_IRQS); - raw_spin_lock(&irq->irq_lock); + irq = vgic_get_vcpu_irq(vcpu, intid); + scoped_guard(raw_spinlock, &irq->irq_lock) { /* Always preserve the active bit, note deactivation */ deactivated = irq->active && !(val & GICH_LR_ACTIVE_BIT); irq->active = !!(val & GICH_LR_ACTIVE_BIT); @@ -101,29 +95,139 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) /* Handle resampling for mapped interrupts if required */ vgic_irq_handle_resampling(irq, deactivated, val & GICH_LR_PENDING_BIT); - raw_spin_unlock(&irq->irq_lock); - vgic_put_irq(vcpu->kvm, irq); + irq->on_lr = false; } - cpuif->used_lrs = 0; + vgic_put_irq(vcpu->kvm, irq); } +static u32 vgic_v2_compute_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq); + /* - * Populates the particular LR with the state of a given IRQ: - * - for an edge sensitive IRQ the pending state is cleared in struct vgic_irq - * - for a level sensitive IRQ the pending state value is unchanged; - * it is dictated directly by the input level - * - * If @irq describes an SGI with multiple sources, we choose the - * lowest-numbered source VCPU and clear that bit in the source bitmap. - * - * The irq_lock must be held by the caller. + * transfer the content of the LRs back into the corresponding ap_list: + * - active bit is transferred as is + * - pending bit is + * - transferred as is in case of edge sensitive IRQs + * - set to the line-level (resample time) for level sensitive IRQs */ -void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) +void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) +{ + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + struct vgic_v2_cpu_if *cpuif = &vgic_cpu->vgic_v2; + u32 eoicount = FIELD_GET(GICH_HCR_EOICOUNT, cpuif->vgic_hcr); + struct vgic_irq *irq; + + DEBUG_SPINLOCK_BUG_ON(!irqs_disabled()); + + for (int lr = 0; lr < vgic_cpu->vgic_v2.used_lrs; lr++) + vgic_v2_fold_lr(vcpu, cpuif->vgic_lr[lr]); + + /* See the GICv3 equivalent for the EOIcount handling rationale */ + list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { + u32 lr; + + if (!eoicount) { + break; + } else { + guard(raw_spinlock)(&irq->irq_lock); + + if (!(likely(vgic_target_oracle(irq) == vcpu) && + irq->active)) + continue; + + lr = vgic_v2_compute_lr(vcpu, irq) & ~GICH_LR_ACTIVE_BIT; + } + + if (lr & GICH_LR_HW) + writel_relaxed(FIELD_GET(GICH_LR_PHYSID_CPUID, lr), + kvm_vgic_global_state.gicc_base + GIC_CPU_DEACTIVATE); + vgic_v2_fold_lr(vcpu, lr); + eoicount--; + } + + cpuif->used_lrs = 0; +} + +void vgic_v2_deactivate(struct kvm_vcpu *vcpu, u32 val) +{ + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + struct vgic_v2_cpu_if *cpuif = &vgic_cpu->vgic_v2; + struct kvm_vcpu *target_vcpu = NULL; + bool mmio = false; + struct vgic_irq *irq; + unsigned long flags; + u64 lr = 0; + u8 cpuid; + + /* Snapshot CPUID, and remove it from the INTID */ + cpuid = FIELD_GET(GENMASK_ULL(12, 10), val); + val &= ~GENMASK_ULL(12, 10); + + /* We only deal with DIR when EOIMode==1 */ + if (!(cpuif->vgic_vmcr & GICH_VMCR_EOI_MODE_MASK)) + return; + + /* Make sure we're in the same context as LR handling */ + local_irq_save(flags); + + irq = vgic_get_vcpu_irq(vcpu, val); + if (WARN_ON_ONCE(!irq)) + goto out; + + /* See the corresponding v3 code for the rationale */ + scoped_guard(raw_spinlock, &irq->irq_lock) { + target_vcpu = irq->vcpu; + + /* Not on any ap_list? */ + if (!target_vcpu) + goto put; + + /* + * Urgh. We're deactivating something that we cannot + * observe yet... Big hammer time. + */ + if (irq->on_lr) { + mmio = true; + goto put; + } + + /* SGI: check that the cpuid matches */ + if (val < VGIC_NR_SGIS && irq->active_source != cpuid) { + target_vcpu = NULL; + goto put; + } + + /* (with a Dalek voice) DEACTIVATE!!!! */ + lr = vgic_v2_compute_lr(vcpu, irq) & ~GICH_LR_ACTIVE_BIT; + } + + if (lr & GICH_LR_HW) + writel_relaxed(FIELD_GET(GICH_LR_PHYSID_CPUID, lr), + kvm_vgic_global_state.gicc_base + GIC_CPU_DEACTIVATE); + + vgic_v2_fold_lr(vcpu, lr); + +put: + vgic_put_irq(vcpu->kvm, irq); + +out: + local_irq_restore(flags); + + if (mmio) + vgic_mmio_write_cactive(vcpu, (val / 32) * 4, 4, BIT(val % 32)); + + /* Force the ap_list to be pruned */ + if (target_vcpu) + kvm_make_request(KVM_REQ_VGIC_PROCESS_UPDATE, target_vcpu); +} + +static u32 vgic_v2_compute_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq) { u32 val = irq->intid; bool allow_pending = true; + WARN_ON(irq->on_lr); + if (irq->active) { val |= GICH_LR_ACTIVE_BIT; if (vgic_irq_is_sgi(irq->intid)) @@ -163,22 +267,52 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) if (allow_pending && irq_is_pending(irq)) { val |= GICH_LR_PENDING_BIT; - if (irq->config == VGIC_CONFIG_EDGE) - irq->pending_latch = false; - if (vgic_irq_is_sgi(irq->intid)) { u32 src = ffs(irq->source); if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n", irq->intid)) - return; + return 0; val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; - irq->source &= ~(1 << (src - 1)); - if (irq->source) { - irq->pending_latch = true; + if (irq->source & ~BIT(src - 1)) val |= GICH_LR_EOI; - } + } + } + + /* The GICv2 LR only holds five bits of priority. */ + val |= (irq->priority >> 3) << GICH_LR_PRIORITY_SHIFT; + + return val; +} + +/* + * Populates the particular LR with the state of a given IRQ: + * - for an edge sensitive IRQ the pending state is cleared in struct vgic_irq + * - for a level sensitive IRQ the pending state value is unchanged; + * it is dictated directly by the input level + * + * If @irq describes an SGI with multiple sources, we choose the + * lowest-numbered source VCPU and clear that bit in the source bitmap. + * + * The irq_lock must be held by the caller. + */ +void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) +{ + u32 val = vgic_v2_compute_lr(vcpu, irq); + + vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = val; + + if (val & GICH_LR_PENDING_BIT) { + if (irq->config == VGIC_CONFIG_EDGE) + irq->pending_latch = false; + + if (vgic_irq_is_sgi(irq->intid)) { + u32 src = ffs(irq->source); + + irq->source &= ~BIT(src - 1); + if (irq->source) + irq->pending_latch = true; } } @@ -194,7 +328,7 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) /* The GICv2 LR only holds five bits of priority. */ val |= (irq->priority >> 3) << GICH_LR_PRIORITY_SHIFT; - vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = val; + irq->on_lr = true; } void vgic_v2_clear_lr(struct kvm_vcpu *vcpu, int lr) @@ -257,7 +391,7 @@ void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) GICH_VMCR_PRIMASK_SHIFT) << GICV_PMR_PRIORITY_SHIFT; } -void vgic_v2_enable(struct kvm_vcpu *vcpu) +void vgic_v2_reset(struct kvm_vcpu *vcpu) { /* * By forcing VMCR to zero, the GIC will restore the binary @@ -265,9 +399,6 @@ void vgic_v2_enable(struct kvm_vcpu *vcpu) * anyway. */ vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0; - - /* Get the show on the road... */ - vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN; } /* check for overlapping regions and for regions crossing the end of memory */ @@ -289,6 +420,7 @@ static bool vgic_v2_check_base(gpa_t dist_base, gpa_t cpu_base) int vgic_v2_map_resources(struct kvm *kvm) { struct vgic_dist *dist = &kvm->arch.vgic; + unsigned int len; int ret = 0; if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) || @@ -312,10 +444,20 @@ int vgic_v2_map_resources(struct kvm *kvm) return ret; } + len = vgic_v2_init_cpuif_iodev(&dist->cpuif_iodev); + dist->cpuif_iodev.base_addr = dist->vgic_cpu_base; + dist->cpuif_iodev.iodev_type = IODEV_CPUIF; + dist->cpuif_iodev.redist_vcpu = NULL; + + ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, dist->vgic_cpu_base, + len, &dist->cpuif_iodev.dev); + if (ret) + return ret; + if (!static_branch_unlikely(&vgic_v2_cpuif_trap)) { ret = kvm_phys_addr_ioremap(kvm, dist->vgic_cpu_base, kvm_vgic_global_state.vcpu_base, - KVM_VGIC_V2_CPU_SIZE, true); + KVM_VGIC_V2_CPU_SIZE - SZ_4K, true); if (ret) { kvm_err("Unable to remap VGIC CPU to VCPU\n"); return ret; @@ -385,6 +527,7 @@ int vgic_v2_probe(const struct gic_kvm_info *info) kvm_vgic_global_state.can_emulate_gicv2 = true; kvm_vgic_global_state.vcpu_base = info->vcpu.start; + kvm_vgic_global_state.gicc_base = info->gicc_base; kvm_vgic_global_state.type = VGIC_V2; kvm_vgic_global_state.max_gic_vcpus = VGIC_V2_MAX_CPUS; @@ -423,16 +566,26 @@ static void save_lrs(struct kvm_vcpu *vcpu, void __iomem *base) void vgic_v2_save_state(struct kvm_vcpu *vcpu) { + struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; void __iomem *base = kvm_vgic_global_state.vctrl_base; u64 used_lrs = vcpu->arch.vgic_cpu.vgic_v2.used_lrs; if (!base) return; - if (used_lrs) { + cpu_if->vgic_vmcr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VMCR); + + if (used_lrs) save_lrs(vcpu, base); - writel_relaxed(0, base + GICH_HCR); + + if (cpu_if->vgic_hcr & GICH_HCR_LRENPIE) { + u32 val = readl_relaxed(base + GICH_HCR); + + cpu_if->vgic_hcr &= ~GICH_HCR_EOICOUNT; + cpu_if->vgic_hcr |= val & GICH_HCR_EOICOUNT; } + + writel_relaxed(0, base + GICH_HCR); } void vgic_v2_restore_state(struct kvm_vcpu *vcpu) @@ -445,13 +598,10 @@ void vgic_v2_restore_state(struct kvm_vcpu *vcpu) if (!base) return; - if (used_lrs) { - writel_relaxed(cpu_if->vgic_hcr, base + GICH_HCR); - for (i = 0; i < used_lrs; i++) { - writel_relaxed(cpu_if->vgic_lr[i], - base + GICH_LR0 + (i * 4)); - } - } + writel_relaxed(cpu_if->vgic_hcr, base + GICH_HCR); + + for (i = 0; i < used_lrs; i++) + writel_relaxed(cpu_if->vgic_lr[i], base + GICH_LR0 + (i * 4)); } void vgic_v2_load(struct kvm_vcpu *vcpu) @@ -468,6 +618,5 @@ void vgic_v2_put(struct kvm_vcpu *vcpu) { struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; - cpu_if->vgic_vmcr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VMCR); cpu_if->vgic_apr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_APR); } diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c index 7f1259b49c505..61b44f3f2bf14 100644 --- a/arch/arm64/kvm/vgic/vgic-v3-nested.c +++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c @@ -70,13 +70,14 @@ static int lr_map_idx_to_shadow_idx(struct shadow_if *shadow_if, int idx) * - on L2 put: perform the inverse transformation, so that the result of L2 * running becomes visible to L1 in the VNCR-accessible registers. * - * - there is nothing to do on L2 entry, as everything will have happened - * on load. However, this is the point where we detect that an interrupt - * targeting L1 and prepare the grand switcheroo. + * - there is nothing to do on L2 entry apart from enabling the vgic, as + * everything will have happened on load. However, this is the point where + * we detect that an interrupt targeting L1 and prepare the grand + * switcheroo. * - * - on L2 exit: emulate the HW bit, and deactivate corresponding the L1 - * interrupt. The L0 active state will be cleared by the HW if the L1 - * interrupt was itself backed by a HW interrupt. + * - on L2 exit: resync the LRs and VMCR, emulate the HW bit, and deactivate + * corresponding the L1 interrupt. The L0 active state will be cleared by + * the HW if the L1 interrupt was itself backed by a HW interrupt. * * Maintenance Interrupt (MI) management: * @@ -93,8 +94,10 @@ static int lr_map_idx_to_shadow_idx(struct shadow_if *shadow_if, int idx) * * - because most of the ICH_*_EL2 registers live in the VNCR page, the * quality of emulation is poor: L1 can setup the vgic so that an MI would - * immediately fire, and not observe anything until the next exit. Trying - * to read ICH_MISR_EL2 would do the trick, for example. + * immediately fire, and not observe anything until the next exit. + * Similarly, a pending MI is not immediately disabled by clearing + * ICH_HCR_EL2.En. Trying to read ICH_MISR_EL2 would do the trick, for + * example. * * System register emulation: * @@ -265,16 +268,37 @@ static void vgic_v3_create_shadow_lr(struct kvm_vcpu *vcpu, s_cpu_if->used_lrs = hweight16(shadow_if->lr_map); } +void vgic_v3_flush_nested(struct kvm_vcpu *vcpu) +{ + u64 val = __vcpu_sys_reg(vcpu, ICH_HCR_EL2); + + write_sysreg_s(val | vgic_ich_hcr_trap_bits(), SYS_ICH_HCR_EL2); +} + void vgic_v3_sync_nested(struct kvm_vcpu *vcpu) { struct shadow_if *shadow_if = get_shadow_if(); int i; for_each_set_bit(i, &shadow_if->lr_map, kvm_vgic_global_state.nr_lr) { - u64 lr = __vcpu_sys_reg(vcpu, ICH_LRN(i)); - struct vgic_irq *irq; + u64 val, host_lr, lr; + + host_lr = __gic_v3_get_lr(lr_map_idx_to_shadow_idx(shadow_if, i)); + + /* Propagate the new LR state */ + lr = __vcpu_sys_reg(vcpu, ICH_LRN(i)); + val = lr & ~ICH_LR_STATE; + val |= host_lr & ICH_LR_STATE; + __vcpu_assign_sys_reg(vcpu, ICH_LRN(i), val); - if (!(lr & ICH_LR_HW) || !(lr & ICH_LR_STATE)) + /* + * Deactivation of a HW interrupt: the LR must have the HW + * bit set, have been in a non-invalid state before the run, + * and now be in an invalid state. If any of that doesn't + * hold, we're done with this LR. + */ + if (!((lr & ICH_LR_HW) && (lr & ICH_LR_STATE) && + !(host_lr & ICH_LR_STATE))) continue; /* @@ -282,35 +306,27 @@ void vgic_v3_sync_nested(struct kvm_vcpu *vcpu) * need to emulate the HW effect between the guest hypervisor * and the nested guest. */ - irq = vgic_get_vcpu_irq(vcpu, FIELD_GET(ICH_LR_PHYS_ID_MASK, lr)); - if (WARN_ON(!irq)) /* Shouldn't happen as we check on load */ - continue; + vgic_v3_deactivate(vcpu, FIELD_GET(ICH_LR_PHYS_ID_MASK, lr)); + } - lr = __gic_v3_get_lr(lr_map_idx_to_shadow_idx(shadow_if, i)); - if (!(lr & ICH_LR_STATE)) - irq->active = false; + /* We need these to be synchronised to generate the MI */ + __vcpu_assign_sys_reg(vcpu, ICH_VMCR_EL2, read_sysreg_s(SYS_ICH_VMCR_EL2)); + __vcpu_rmw_sys_reg(vcpu, ICH_HCR_EL2, &=, ~ICH_HCR_EL2_EOIcount); + __vcpu_rmw_sys_reg(vcpu, ICH_HCR_EL2, |=, read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EL2_EOIcount); - vgic_put_irq(vcpu->kvm, irq); - } + write_sysreg_s(0, SYS_ICH_HCR_EL2); + isb(); + + vgic_v3_nested_update_mi(vcpu); } static void vgic_v3_create_shadow_state(struct kvm_vcpu *vcpu, struct vgic_v3_cpu_if *s_cpu_if) { struct vgic_v3_cpu_if *host_if = &vcpu->arch.vgic_cpu.vgic_v3; - u64 val = 0; int i; - /* - * If we're on a system with a broken vgic that requires - * trapping, propagate the trapping requirements. - * - * Ah, the smell of rotten fruits... - */ - if (static_branch_unlikely(&vgic_v3_cpuif_trap)) - val = host_if->vgic_hcr & (ICH_HCR_EL2_TALL0 | ICH_HCR_EL2_TALL1 | - ICH_HCR_EL2_TC | ICH_HCR_EL2_TDIR); - s_cpu_if->vgic_hcr = __vcpu_sys_reg(vcpu, ICH_HCR_EL2) | val; + s_cpu_if->vgic_hcr = __vcpu_sys_reg(vcpu, ICH_HCR_EL2); s_cpu_if->vgic_vmcr = __vcpu_sys_reg(vcpu, ICH_VMCR_EL2); s_cpu_if->vgic_sre = host_if->vgic_sre; @@ -334,7 +350,8 @@ void vgic_v3_load_nested(struct kvm_vcpu *vcpu) __vgic_v3_restore_vmcr_aprs(cpu_if); __vgic_v3_activate_traps(cpu_if); - __vgic_v3_restore_state(cpu_if); + for (int i = 0; i < cpu_if->used_lrs; i++) + __gic_v3_set_lr(cpu_if->vgic_lr[i], i); /* * Propagate the number of used LRs for the benefit of the HYP @@ -347,36 +364,19 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu) { struct shadow_if *shadow_if = get_shadow_if(); struct vgic_v3_cpu_if *s_cpu_if = &shadow_if->cpuif; - u64 val; int i; - __vgic_v3_save_vmcr_aprs(s_cpu_if); - __vgic_v3_deactivate_traps(s_cpu_if); - __vgic_v3_save_state(s_cpu_if); - - /* - * Translate the shadow state HW fields back to the virtual ones - * before copying the shadow struct back to the nested one. - */ - val = __vcpu_sys_reg(vcpu, ICH_HCR_EL2); - val &= ~ICH_HCR_EL2_EOIcount_MASK; - val |= (s_cpu_if->vgic_hcr & ICH_HCR_EL2_EOIcount_MASK); - __vcpu_assign_sys_reg(vcpu, ICH_HCR_EL2, val); - __vcpu_assign_sys_reg(vcpu, ICH_VMCR_EL2, s_cpu_if->vgic_vmcr); + __vgic_v3_save_aprs(s_cpu_if); for (i = 0; i < 4; i++) { __vcpu_assign_sys_reg(vcpu, ICH_AP0RN(i), s_cpu_if->vgic_ap0r[i]); __vcpu_assign_sys_reg(vcpu, ICH_AP1RN(i), s_cpu_if->vgic_ap1r[i]); } - for_each_set_bit(i, &shadow_if->lr_map, kvm_vgic_global_state.nr_lr) { - val = __vcpu_sys_reg(vcpu, ICH_LRN(i)); - - val &= ~ICH_LR_STATE; - val |= s_cpu_if->vgic_lr[lr_map_idx_to_shadow_idx(shadow_if, i)] & ICH_LR_STATE; + for (i = 0; i < s_cpu_if->used_lrs; i++) + __gic_v3_set_lr(0, i); - __vcpu_assign_sys_reg(vcpu, ICH_LRN(i), val); - } + __vgic_v3_deactivate_traps(s_cpu_if); vcpu->arch.vgic_cpu.vgic_v3.used_lrs = 0; } diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index 2f75ef14d3399..1d6dd1b545bdd 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -12,6 +12,7 @@ #include #include +#include "vgic-mmio.h" #include "vgic.h" static bool group0_trap; @@ -20,11 +21,48 @@ static bool common_trap; static bool dir_trap; static bool gicv4_enable; -void vgic_v3_set_underflow(struct kvm_vcpu *vcpu) +void vgic_v3_configure_hcr(struct kvm_vcpu *vcpu, + struct ap_list_summary *als) { struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3; - cpuif->vgic_hcr |= ICH_HCR_EL2_UIE; + if (!irqchip_in_kernel(vcpu->kvm)) + return; + + cpuif->vgic_hcr = ICH_HCR_EL2_En; + + if (irqs_pending_outside_lrs(als)) + cpuif->vgic_hcr |= ICH_HCR_EL2_NPIE; + if (irqs_active_outside_lrs(als)) + cpuif->vgic_hcr |= ICH_HCR_EL2_LRENPIE; + if (irqs_outside_lrs(als)) + cpuif->vgic_hcr |= ICH_HCR_EL2_UIE; + + if (!als->nr_sgi) + cpuif->vgic_hcr |= ICH_HCR_EL2_vSGIEOICount; + + cpuif->vgic_hcr |= (cpuif->vgic_vmcr & ICH_VMCR_ENG0_MASK) ? + ICH_HCR_EL2_VGrp0DIE : ICH_HCR_EL2_VGrp0EIE; + cpuif->vgic_hcr |= (cpuif->vgic_vmcr & ICH_VMCR_ENG1_MASK) ? + ICH_HCR_EL2_VGrp1DIE : ICH_HCR_EL2_VGrp1EIE; + + /* + * Dealing with EOImode=1 is a massive source of headache. Not + * only do we need to track that we have active interrupts + * outside of the LRs and force DIR to be trapped, we also + * need to deal with SPIs that can be deactivated on another + * CPU. + * + * On systems that do not implement TDIR, force the bit in the + * shadow state anyway to avoid IPI-ing on these poor sods. + * + * Note that we set the trap irrespective of EOIMode, as that + * can change behind our back without any warning... + */ + if (!cpus_have_final_cap(ARM64_HAS_ICH_HCR_EL2_TDIR) || + irqs_active_outside_lrs(als) || + atomic_read(&vcpu->kvm->arch.vgic.active_spis)) + cpuif->vgic_hcr |= ICH_HCR_EL2_TDIR; } static bool lr_signals_eoi_mi(u64 lr_val) @@ -33,84 +71,238 @@ static bool lr_signals_eoi_mi(u64 lr_val) !(lr_val & ICH_LR_HW); } +static void vgic_v3_fold_lr(struct kvm_vcpu *vcpu, u64 val) +{ + struct vgic_irq *irq; + bool is_v2_sgi = false; + bool deactivated; + u32 intid; + + if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { + intid = val & ICH_LR_VIRTUAL_ID_MASK; + } else { + intid = val & GICH_LR_VIRTUALID; + is_v2_sgi = vgic_irq_is_sgi(intid); + } + + irq = vgic_get_vcpu_irq(vcpu, intid); + if (!irq) /* An LPI could have been unmapped. */ + return; + + scoped_guard(raw_spinlock, &irq->irq_lock) { + /* Always preserve the active bit for !LPIs, note deactivation */ + if (irq->intid >= VGIC_MIN_LPI) + val &= ~ICH_LR_ACTIVE_BIT; + deactivated = irq->active && !(val & ICH_LR_ACTIVE_BIT); + irq->active = !!(val & ICH_LR_ACTIVE_BIT); + + /* Edge is the only case where we preserve the pending bit */ + if (irq->config == VGIC_CONFIG_EDGE && + (val & ICH_LR_PENDING_BIT)) + irq->pending_latch = true; + + /* + * Clear soft pending state when level irqs have been acked. + */ + if (irq->config == VGIC_CONFIG_LEVEL && !(val & ICH_LR_STATE)) + irq->pending_latch = false; + + if (is_v2_sgi) { + u8 cpuid = FIELD_GET(GICH_LR_PHYSID_CPUID, val); + + if (irq->active) + irq->active_source = cpuid; + + if (val & ICH_LR_PENDING_BIT) + irq->source |= BIT(cpuid); + } + + /* Handle resampling for mapped interrupts if required */ + vgic_irq_handle_resampling(irq, deactivated, val & ICH_LR_PENDING_BIT); + + irq->on_lr = false; + } + + /* Notify fds when the guest EOI'ed a level-triggered SPI, and drop the refcount */ + if (deactivated && lr_signals_eoi_mi(val) && vgic_valid_spi(vcpu->kvm, intid)) { + kvm_notify_acked_irq(vcpu->kvm, 0, + intid - VGIC_NR_PRIVATE_IRQS); + atomic_dec_if_positive(&vcpu->kvm->arch.vgic.active_spis); + } + + vgic_put_irq(vcpu->kvm, irq); +} + +static u64 vgic_v3_compute_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq); + +static void vgic_v3_deactivate_phys(u32 intid) +{ + if (cpus_have_final_cap(ARM64_HAS_GICV5_LEGACY)) + gic_insn(intid | FIELD_PREP(GICV5_GIC_CDDI_TYPE_MASK, 1), CDDI); + else + gic_write_dir(intid); +} + void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; struct vgic_v3_cpu_if *cpuif = &vgic_cpu->vgic_v3; - u32 model = vcpu->kvm->arch.vgic.vgic_model; - int lr; + u32 eoicount = FIELD_GET(ICH_HCR_EL2_EOIcount, cpuif->vgic_hcr); + struct vgic_irq *irq; DEBUG_SPINLOCK_BUG_ON(!irqs_disabled()); - cpuif->vgic_hcr &= ~ICH_HCR_EL2_UIE; - - for (lr = 0; lr < cpuif->used_lrs; lr++) { - u64 val = cpuif->vgic_lr[lr]; - u32 intid, cpuid; - struct vgic_irq *irq; - bool is_v2_sgi = false; - bool deactivated; + for (int lr = 0; lr < cpuif->used_lrs; lr++) + vgic_v3_fold_lr(vcpu, cpuif->vgic_lr[lr]); - cpuid = val & GICH_LR_PHYSID_CPUID; - cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT; + /* + * EOIMode=0: use EOIcount to emulate deactivation. We are + * guaranteed to deactivate in reverse order of the activation, so + * just pick one active interrupt after the other in the ap_list, + * and replay the deactivation as if the CPU was doing it. We also + * rely on priority drop to have taken place, and the list to be + * sorted by priority. + */ + list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { + u64 lr; - if (model == KVM_DEV_TYPE_ARM_VGIC_V3) { - intid = val & ICH_LR_VIRTUAL_ID_MASK; + /* + * I would have loved to write this using a scoped_guard(), + * but using 'continue' here is a total train wreck. + */ + if (!eoicount) { + break; } else { - intid = val & GICH_LR_VIRTUALID; - is_v2_sgi = vgic_irq_is_sgi(intid); + guard(raw_spinlock)(&irq->irq_lock); + + if (!(likely(vgic_target_oracle(irq) == vcpu) && + irq->active)) + continue; + + lr = vgic_v3_compute_lr(vcpu, irq) & ~ICH_LR_ACTIVE_BIT; } - /* Notify fds when the guest EOI'ed a level-triggered IRQ */ - if (lr_signals_eoi_mi(val) && vgic_valid_spi(vcpu->kvm, intid)) - kvm_notify_acked_irq(vcpu->kvm, 0, - intid - VGIC_NR_PRIVATE_IRQS); + if (lr & ICH_LR_HW) + vgic_v3_deactivate_phys(FIELD_GET(ICH_LR_PHYS_ID_MASK, lr)); - irq = vgic_get_vcpu_irq(vcpu, intid); - if (!irq) /* An LPI could have been unmapped. */ - continue; + vgic_v3_fold_lr(vcpu, lr); + eoicount--; + } - raw_spin_lock(&irq->irq_lock); + cpuif->used_lrs = 0; +} - /* Always preserve the active bit, note deactivation */ - deactivated = irq->active && !(val & ICH_LR_ACTIVE_BIT); - irq->active = !!(val & ICH_LR_ACTIVE_BIT); +void vgic_v3_deactivate(struct kvm_vcpu *vcpu, u64 val) +{ + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + struct vgic_v3_cpu_if *cpuif = &vgic_cpu->vgic_v3; + u32 model = vcpu->kvm->arch.vgic.vgic_model; + struct kvm_vcpu *target_vcpu = NULL; + bool mmio = false, is_v2_sgi; + struct vgic_irq *irq; + unsigned long flags; + u64 lr = 0; + u8 cpuid; - if (irq->active && is_v2_sgi) - irq->active_source = cpuid; + /* Snapshot CPUID, and remove it from the INTID */ + cpuid = FIELD_GET(GENMASK_ULL(12, 10), val); + val &= ~GENMASK_ULL(12, 10); - /* Edge is the only case where we preserve the pending bit */ - if (irq->config == VGIC_CONFIG_EDGE && - (val & ICH_LR_PENDING_BIT)) { - irq->pending_latch = true; + is_v2_sgi = (model == KVM_DEV_TYPE_ARM_VGIC_V2 && + val < VGIC_NR_SGIS); - if (is_v2_sgi) - irq->source |= (1 << cpuid); - } + /* + * We only deal with DIR when EOIMode==1, and only for SGI, + * PPI or SPI. + */ + if (!(cpuif->vgic_vmcr & ICH_VMCR_EOIM_MASK) || + val >= vcpu->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS) + return; + + /* Make sure we're in the same context as LR handling */ + local_irq_save(flags); + + irq = vgic_get_vcpu_irq(vcpu, val); + if (WARN_ON_ONCE(!irq)) + goto out; + + /* + * EOIMode=1: we must rely on traps to handle deactivate of + * overflowing interrupts, as there is no ordering guarantee and + * EOIcount isn't being incremented. Priority drop will have taken + * place, as ICV_EOIxR_EL1 only affects the APRs and not the LRs. + * + * Three possibities: + * + * - The irq is not queued on any CPU, and there is nothing to + * do, + * + * - Or the irq is in an LR, meaning that its state is not + * directly observable. Treat it bluntly by making it as if + * this was a write to GICD_ICACTIVER, which will force an + * exit on all vcpus. If it hurts, don't do that. + * + * - Or the irq is active, but not in an LR, and we can + * directly deactivate it by building a pseudo-LR, fold it, + * and queue a request to prune the resulting ap_list, + * + * Special care must be taken to match the source CPUID when + * deactivating a GICv2 SGI. + */ + scoped_guard(raw_spinlock, &irq->irq_lock) { + target_vcpu = irq->vcpu; + + /* Not on any ap_list? */ + if (!target_vcpu) + goto put; /* - * Clear soft pending state when level irqs have been acked. + * Urgh. We're deactivating something that we cannot + * observe yet... Big hammer time. */ - if (irq->config == VGIC_CONFIG_LEVEL && !(val & ICH_LR_STATE)) - irq->pending_latch = false; + if (irq->on_lr) { + mmio = true; + goto put; + } - /* Handle resampling for mapped interrupts if required */ - vgic_irq_handle_resampling(irq, deactivated, val & ICH_LR_PENDING_BIT); + /* GICv2 SGI: check that the cpuid matches */ + if (is_v2_sgi && irq->active_source != cpuid) { + target_vcpu = NULL; + goto put; + } - raw_spin_unlock(&irq->irq_lock); - vgic_put_irq(vcpu->kvm, irq); + /* (with a Dalek voice) DEACTIVATE!!!! */ + lr = vgic_v3_compute_lr(vcpu, irq) & ~ICH_LR_ACTIVE_BIT; } - cpuif->used_lrs = 0; + if (lr & ICH_LR_HW) + vgic_v3_deactivate_phys(FIELD_GET(ICH_LR_PHYS_ID_MASK, lr)); + + vgic_v3_fold_lr(vcpu, lr); + +put: + vgic_put_irq(vcpu->kvm, irq); + +out: + local_irq_restore(flags); + + if (mmio) + vgic_mmio_write_cactive(vcpu, (val / 32) * 4, 4, BIT(val % 32)); + + /* Force the ap_list to be pruned */ + if (target_vcpu) + kvm_make_request(KVM_REQ_VGIC_PROCESS_UPDATE, target_vcpu); } /* Requires the irq to be locked already */ -void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) +static u64 vgic_v3_compute_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq) { u32 model = vcpu->kvm->arch.vgic.vgic_model; u64 val = irq->intid; bool allow_pending = true, is_v2_sgi; + WARN_ON(irq->on_lr); + is_v2_sgi = (vgic_irq_is_sgi(irq->intid) && model == KVM_DEV_TYPE_ARM_VGIC_V2); @@ -150,6 +342,35 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) if (allow_pending && irq_is_pending(irq)) { val |= ICH_LR_PENDING_BIT; + if (is_v2_sgi) { + u32 src = ffs(irq->source); + + if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n", + irq->intid)) + return 0; + + val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; + if (irq->source & ~BIT(src - 1)) + val |= ICH_LR_EOI; + } + } + + if (irq->group) + val |= ICH_LR_GROUP; + + val |= (u64)irq->priority << ICH_LR_PRIORITY_SHIFT; + + return val; +} + +void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) +{ + u32 model = vcpu->kvm->arch.vgic.vgic_model; + u64 val = vgic_v3_compute_lr(vcpu, irq); + + vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[lr] = val; + + if (val & ICH_LR_PENDING_BIT) { if (irq->config == VGIC_CONFIG_EDGE) irq->pending_latch = false; @@ -157,16 +378,9 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) model == KVM_DEV_TYPE_ARM_VGIC_V2) { u32 src = ffs(irq->source); - if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n", - irq->intid)) - return; - - val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; - irq->source &= ~(1 << (src - 1)); - if (irq->source) { + irq->source &= ~BIT(src - 1); + if (irq->source) irq->pending_latch = true; - val |= ICH_LR_EOI; - } } } @@ -179,12 +393,7 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) if (vgic_irq_is_mapped_level(irq) && (val & ICH_LR_PENDING_BIT)) irq->line_level = false; - if (irq->group) - val |= ICH_LR_GROUP; - - val |= (u64)irq->priority << ICH_LR_PRIORITY_SHIFT; - - vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[lr] = val; + irq->on_lr = true; } void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr) @@ -258,7 +467,7 @@ void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) GIC_BASER_CACHEABILITY(GICR_PENDBASER, OUTER, SameAsInner) | \ GIC_BASER_SHAREABILITY(GICR_PENDBASER, InnerShareable)) -void vgic_v3_enable(struct kvm_vcpu *vcpu) +void vgic_v3_reset(struct kvm_vcpu *vcpu) { struct vgic_v3_cpu_if *vgic_v3 = &vcpu->arch.vgic_cpu.vgic_v3; @@ -288,9 +497,6 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu) kvm_vgic_global_state.ich_vtr_el2); vcpu->arch.vgic_cpu.num_pri_bits = FIELD_GET(ICH_VTR_EL2_PRIbits, kvm_vgic_global_state.ich_vtr_el2) + 1; - - /* Get the show on the road... */ - vgic_v3->vgic_hcr = ICH_HCR_EL2_En; } void vcpu_set_ich_hcr(struct kvm_vcpu *vcpu) @@ -302,20 +508,9 @@ void vcpu_set_ich_hcr(struct kvm_vcpu *vcpu) /* Hide GICv3 sysreg if necessary */ if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2 || - !irqchip_in_kernel(vcpu->kvm)) { + !irqchip_in_kernel(vcpu->kvm)) vgic_v3->vgic_hcr |= (ICH_HCR_EL2_TALL0 | ICH_HCR_EL2_TALL1 | ICH_HCR_EL2_TC); - return; - } - - if (group0_trap) - vgic_v3->vgic_hcr |= ICH_HCR_EL2_TALL0; - if (group1_trap) - vgic_v3->vgic_hcr |= ICH_HCR_EL2_TALL1; - if (common_trap) - vgic_v3->vgic_hcr |= ICH_HCR_EL2_TC; - if (dir_trap) - vgic_v3->vgic_hcr |= ICH_HCR_EL2_TDIR; } int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq) @@ -636,8 +831,53 @@ static const struct midr_range broken_seis[] = { static bool vgic_v3_broken_seis(void) { - return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_EL2_SEIS) && - is_midr_in_range_list(broken_seis)); + return (is_kernel_in_hyp_mode() && + is_midr_in_range_list(broken_seis) && + (read_sysreg_s(SYS_ICH_VTR_EL2) & ICH_VTR_EL2_SEIS)); +} + +void noinstr kvm_compute_ich_hcr_trap_bits(struct alt_instr *alt, + __le32 *origptr, __le32 *updptr, + int nr_inst) +{ + u32 insn, oinsn, rd; + u64 hcr = 0; + + if (cpus_have_cap(ARM64_WORKAROUND_CAVIUM_30115)) { + group0_trap = true; + group1_trap = true; + } + + if (vgic_v3_broken_seis()) { + /* We know that these machines have ICH_HCR_EL2.TDIR */ + group0_trap = true; + group1_trap = true; + dir_trap = true; + } + + if (!cpus_have_cap(ARM64_HAS_ICH_HCR_EL2_TDIR)) + common_trap = true; + + if (group0_trap) + hcr |= ICH_HCR_EL2_TALL0; + if (group1_trap) + hcr |= ICH_HCR_EL2_TALL1; + if (common_trap) + hcr |= ICH_HCR_EL2_TC; + if (dir_trap) + hcr |= ICH_HCR_EL2_TDIR; + + /* Compute target register */ + oinsn = le32_to_cpu(*origptr); + rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, oinsn); + + /* movz rd, #(val & 0xffff) */ + insn = aarch64_insn_gen_movewide(rd, + (u16)hcr, + 0, + AARCH64_INSN_VARIANT_64BIT, + AARCH64_INSN_MOVEWIDE_ZERO); + *updptr = cpu_to_le32(insn); } /** @@ -651,6 +891,7 @@ int vgic_v3_probe(const struct gic_kvm_info *info) { u64 ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_gic_config); bool has_v2; + u64 traps; int ret; has_v2 = ich_vtr_el2 >> 63; @@ -709,29 +950,18 @@ int vgic_v3_probe(const struct gic_kvm_info *info) if (has_v2) static_branch_enable(&vgic_v3_has_v2_compat); - if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_30115)) { - group0_trap = true; - group1_trap = true; - } - if (vgic_v3_broken_seis()) { kvm_info("GICv3 with broken locally generated SEI\n"); - kvm_vgic_global_state.ich_vtr_el2 &= ~ICH_VTR_EL2_SEIS; - group0_trap = true; - group1_trap = true; - if (ich_vtr_el2 & ICH_VTR_EL2_TDS) - dir_trap = true; - else - common_trap = true; } - if (group0_trap || group1_trap || common_trap | dir_trap) { + traps = vgic_ich_hcr_trap_bits(); + if (traps) { kvm_info("GICv3 sysreg trapping enabled ([%s%s%s%s], reduced performance)\n", - group0_trap ? "G0" : "", - group1_trap ? "G1" : "", - common_trap ? "C" : "", - dir_trap ? "D" : ""); + (traps & ICH_HCR_EL2_TALL0) ? "G0" : "", + (traps & ICH_HCR_EL2_TALL1) ? "G1" : "", + (traps & ICH_HCR_EL2_TC) ? "C" : "", + (traps & ICH_HCR_EL2_TDIR) ? "D" : ""); static_branch_enable(&vgic_v3_cpuif_trap); } @@ -771,7 +1001,7 @@ void vgic_v3_put(struct kvm_vcpu *vcpu) } if (likely(!is_protected_kvm_enabled())) - kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if); + kvm_call_hyp(__vgic_v3_save_aprs, cpu_if); WARN_ON(vgic_v4_put(vcpu)); if (has_vhe()) diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c index 548aec9d5a728..09c3e9eb23f89 100644 --- a/arch/arm64/kvm/vgic/vgic-v4.c +++ b/arch/arm64/kvm/vgic/vgic-v4.c @@ -163,6 +163,7 @@ static void vgic_v4_disable_vsgis(struct kvm_vcpu *vcpu) struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, i); struct irq_desc *desc; unsigned long flags; + bool pending; int ret; raw_spin_lock_irqsave(&irq->irq_lock, flags); @@ -173,9 +174,11 @@ static void vgic_v4_disable_vsgis(struct kvm_vcpu *vcpu) irq->hw = false; ret = irq_get_irqchip_state(irq->host_irq, IRQCHIP_STATE_PENDING, - &irq->pending_latch); + &pending); WARN_ON(ret); + irq->pending_latch = pending; + desc = irq_to_desc(irq->host_irq); irq_domain_deactivate_irq(irq_desc_get_irq_data(desc)); unlock: diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index 8d20c53faef02..430aa98888fda 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -244,7 +244,7 @@ void vgic_irq_set_phys_active(struct vgic_irq *irq, bool active) * * Requires the IRQ lock to be held. */ -static struct kvm_vcpu *vgic_target_oracle(struct vgic_irq *irq) +struct kvm_vcpu *vgic_target_oracle(struct vgic_irq *irq) { lockdep_assert_held(&irq->irq_lock); @@ -272,17 +272,20 @@ static struct kvm_vcpu *vgic_target_oracle(struct vgic_irq *irq) return NULL; } +struct vgic_sort_info { + struct kvm_vcpu *vcpu; + struct vgic_vmcr vmcr; +}; + /* * The order of items in the ap_lists defines how we'll pack things in LRs as * well, the first items in the list being the first things populated in the * LRs. * - * A hard rule is that active interrupts can never be pushed out of the LRs - * (and therefore take priority) since we cannot reliably trap on deactivation - * of IRQs and therefore they have to be present in the LRs. - * + * Pending, non-active interrupts must be placed at the head of the list. * Otherwise things should be sorted by the priority field and the GIC * hardware support will take care of preemption of priority groups etc. + * Interrupts that are not deliverable should be at the end of the list. * * Return negative if "a" sorts before "b", 0 to preserve order, and positive * to sort "b" before "a". @@ -292,6 +295,8 @@ static int vgic_irq_cmp(void *priv, const struct list_head *a, { struct vgic_irq *irqa = container_of(a, struct vgic_irq, ap_list); struct vgic_irq *irqb = container_of(b, struct vgic_irq, ap_list); + struct vgic_sort_info *info = priv; + struct kvm_vcpu *vcpu = info->vcpu; bool penda, pendb; int ret; @@ -305,21 +310,32 @@ static int vgic_irq_cmp(void *priv, const struct list_head *a, raw_spin_lock(&irqa->irq_lock); raw_spin_lock_nested(&irqb->irq_lock, SINGLE_DEPTH_NESTING); - if (irqa->active || irqb->active) { - ret = (int)irqb->active - (int)irqa->active; + /* Undeliverable interrupts should be last */ + ret = (int)(vgic_target_oracle(irqb) == vcpu) - (int)(vgic_target_oracle(irqa) == vcpu); + if (ret) + goto out; + + /* Same thing for interrupts targeting a disabled group */ + ret = (int)(irqb->group ? info->vmcr.grpen1 : info->vmcr.grpen0); + ret -= (int)(irqa->group ? info->vmcr.grpen1 : info->vmcr.grpen0); + if (ret) goto out; - } - penda = irqa->enabled && irq_is_pending(irqa); - pendb = irqb->enabled && irq_is_pending(irqb); + penda = irqa->enabled && irq_is_pending(irqa) && !irqa->active; + pendb = irqb->enabled && irq_is_pending(irqb) && !irqb->active; - if (!penda || !pendb) { - ret = (int)pendb - (int)penda; + ret = (int)pendb - (int)penda; + if (ret) goto out; - } - /* Both pending and enabled, sort by priority */ - ret = irqa->priority - irqb->priority; + /* Both pending and enabled, sort by priority (lower number first) */ + ret = (int)irqa->priority - (int)irqb->priority; + if (ret) + goto out; + + /* Finally, HW bit active interrupts have priority over non-HW ones */ + ret = (int)irqb->hw - (int)irqa->hw; + out: raw_spin_unlock(&irqb->irq_lock); raw_spin_unlock(&irqa->irq_lock); @@ -330,10 +346,12 @@ static int vgic_irq_cmp(void *priv, const struct list_head *a, static void vgic_sort_ap_list(struct kvm_vcpu *vcpu) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + struct vgic_sort_info info = { .vcpu = vcpu, }; lockdep_assert_held(&vgic_cpu->ap_list_lock); - list_sort(NULL, &vgic_cpu->ap_list_head, vgic_irq_cmp); + vgic_get_vmcr(vcpu, &info.vmcr); + list_sort(&info, &vgic_cpu->ap_list_head, vgic_irq_cmp); } /* @@ -356,6 +374,20 @@ static bool vgic_validate_injection(struct vgic_irq *irq, bool level, void *owne return false; } +static bool vgic_model_needs_bcst_kick(struct kvm *kvm) +{ + /* + * A GICv3 (or GICv3-like) system exposing a GICv3 to the guest + * needs a broadcast kick to set TDIR globally. + * + * For systems that do not have TDIR (ARM's own v8.0 CPUs), the + * shadow TDIR bit is always set, and so is the register's TC bit, + * so no need to kick the CPUs. + */ + return (cpus_have_final_cap(ARM64_HAS_ICH_HCR_EL2_TDIR) && + kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3); +} + /* * Check whether an IRQ needs to (and can) be queued to a VCPU's ap list. * Do the queuing if necessary, taking the right locks in the right order. @@ -368,6 +400,7 @@ bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq, unsigned long flags) __releases(&irq->irq_lock) { struct kvm_vcpu *vcpu; + bool bcast; lockdep_assert_held(&irq->irq_lock); @@ -442,11 +475,20 @@ bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq, list_add_tail(&irq->ap_list, &vcpu->arch.vgic_cpu.ap_list_head); irq->vcpu = vcpu; + /* A new SPI may result in deactivation trapping on all vcpus */ + bcast = (vgic_model_needs_bcst_kick(vcpu->kvm) && + vgic_valid_spi(vcpu->kvm, irq->intid) && + atomic_fetch_inc(&vcpu->kvm->arch.vgic.active_spis) == 0); + raw_spin_unlock(&irq->irq_lock); raw_spin_unlock_irqrestore(&vcpu->arch.vgic_cpu.ap_list_lock, flags); - kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu); - kvm_vcpu_kick(vcpu); + if (!bcast) { + kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu); + kvm_vcpu_kick(vcpu); + } else { + kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_IRQ_PENDING); + } return true; } @@ -798,98 +840,148 @@ static inline void vgic_clear_lr(struct kvm_vcpu *vcpu, int lr) vgic_v3_clear_lr(vcpu, lr); } -static inline void vgic_set_underflow(struct kvm_vcpu *vcpu) -{ - if (kvm_vgic_global_state.type == VGIC_V2) - vgic_v2_set_underflow(vcpu); - else - vgic_v3_set_underflow(vcpu); -} - -/* Requires the ap_list_lock to be held. */ -static int compute_ap_list_depth(struct kvm_vcpu *vcpu, - bool *multi_sgi) +static void summarize_ap_list(struct kvm_vcpu *vcpu, + struct ap_list_summary *als) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; struct vgic_irq *irq; - int count = 0; - - *multi_sgi = false; lockdep_assert_held(&vgic_cpu->ap_list_lock); + *als = (typeof(*als)){}; + list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { - int w; + guard(raw_spinlock)(&irq->irq_lock); - raw_spin_lock(&irq->irq_lock); - /* GICv2 SGIs can count for more than one... */ - w = vgic_irq_get_lr_count(irq); - raw_spin_unlock(&irq->irq_lock); + if (unlikely(vgic_target_oracle(irq) != vcpu)) + continue; + + if (!irq->active) + als->nr_pend++; + else + als->nr_act++; - count += w; - *multi_sgi |= (w > 1); + if (irq->intid < VGIC_NR_SGIS) + als->nr_sgi++; } - return count; } -/* Requires the VCPU's ap_list_lock to be held. */ +/* + * Dealing with LR overflow is close to black magic -- dress accordingly. + * + * We have to present an almost infinite number of interrupts through a very + * limited number of registers. Therefore crucial decisions must be made to + * ensure we feed the most relevant interrupts into the LRs, and yet have + * some facilities to let the guest interact with those that are not there. + * + * All considerations below are in the context of interrupts targeting a + * single vcpu with non-idle state (either pending, active, or both), + * colloquially called the ap_list: + * + * - Pending interrupts must have priority over active interrupts. This also + * excludes pending+active interrupts. This ensures that a guest can + * perform priority drops on any number of interrupts, and yet be + * presented the next pending one. + * + * - Deactivation of interrupts outside of the LRs must be tracked by using + * either the EOIcount-driven maintenance interrupt, and sometimes by + * trapping the DIR register. + * + * - For EOImode=0, a non-zero EOIcount means walking the ap_list past the + * point that made it into the LRs, and deactivate interrupts that would + * have made it onto the LRs if we had the space. + * + * - The MI-generation bits must be used to try and force an exit when the + * guest has done enough changes to the LRs that we want to reevaluate the + * situation: + * + * - if the total number of pending interrupts exceeds the number of + * LR, NPIE must be set in order to exit once no pending interrupts + * are present in the LRs, allowing us to populate the next batch. + * + * - if there are active interrupts outside of the LRs, then LRENPIE + * must be set so that we exit on deactivation of one of these, and + * work out which one is to be deactivated. Note that this is not + * enough to deal with EOImode=1, see below. + * + * - if the overall number of interrupts exceeds the number of LRs, + * then UIE must be set to allow refilling of the LRs once the + * majority of them has been processed. + * + * - as usual, MI triggers are only an optimisation, since we cannot + * rely on the MI being delivered in timely manner... + * + * - EOImode=1 creates some additional problems: + * + * - deactivation can happen in any order, and we cannot rely on + * EOImode=0's coupling of priority-drop and deactivation which + * imposes strict reverse Ack order. This means that DIR must + * trap if we have active interrupts outside of the LRs. + * + * - deactivation of SPIs can occur on any CPU, while the SPI is only + * present in the ap_list of the CPU that actually ack-ed it. In that + * case, EOIcount doesn't provide enough information, and we must + * resort to trapping DIR even if we don't overflow the LRs. Bonus + * point for not trapping DIR when no SPIs are pending or active in + * the whole VM. + * + * - LPIs do not suffer the same problem as SPIs on deactivation, as we + * have to essentially discard the active state, see below. + * + * - Virtual LPIs have an active state (surprise!), which gets removed on + * priority drop (EOI). However, EOIcount doesn't get bumped when the LPI + * is not present in the LR (surprise again!). Special care must therefore + * be taken to remove the active state from any activated LPI when exiting + * from the guest. This is in a way no different from what happens on the + * physical side. We still rely on the running priority to have been + * removed from the APRs, irrespective of the LPI being present in the LRs + * or not. + * + * - Virtual SGIs directly injected via GICv4.1 must not affect EOIcount, as + * they are not managed in SW and don't have a true active state. So only + * set vSGIEOICount when no SGIs are in the ap_list. + * + * - GICv2 SGIs with multiple sources are injected one source at a time, as + * if they were made pending sequentially. This may mean that we don't + * always present the HPPI if other interrupts with lower priority are + * pending in the LRs. Big deal. + */ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + struct ap_list_summary als; struct vgic_irq *irq; - int count; - bool multi_sgi; - u8 prio = 0xff; - int i = 0; + int count = 0; lockdep_assert_held(&vgic_cpu->ap_list_lock); - count = compute_ap_list_depth(vcpu, &multi_sgi); - if (count > kvm_vgic_global_state.nr_lr || multi_sgi) - vgic_sort_ap_list(vcpu); + summarize_ap_list(vcpu, &als); - count = 0; + if (irqs_outside_lrs(&als)) + vgic_sort_ap_list(vcpu); list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { - raw_spin_lock(&irq->irq_lock); - - /* - * If we have multi-SGIs in the pipeline, we need to - * guarantee that they are all seen before any IRQ of - * lower priority. In that case, we need to filter out - * these interrupts by exiting early. This is easy as - * the AP list has been sorted already. - */ - if (multi_sgi && irq->priority > prio) { - raw_spin_unlock(&irq->irq_lock); - break; - } - - if (likely(vgic_target_oracle(irq) == vcpu)) { - vgic_populate_lr(vcpu, irq, count++); - - if (irq->source) - prio = irq->priority; + scoped_guard(raw_spinlock, &irq->irq_lock) { + if (likely(vgic_target_oracle(irq) == vcpu)) { + vgic_populate_lr(vcpu, irq, count++); + } } - raw_spin_unlock(&irq->irq_lock); - - if (count == kvm_vgic_global_state.nr_lr) { - if (!list_is_last(&irq->ap_list, - &vgic_cpu->ap_list_head)) - vgic_set_underflow(vcpu); + if (count == kvm_vgic_global_state.nr_lr) break; - } } /* Nuke remaining LRs */ - for (i = count ; i < kvm_vgic_global_state.nr_lr; i++) + for (int i = count ; i < kvm_vgic_global_state.nr_lr; i++) vgic_clear_lr(vcpu, i); - if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) + if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) { vcpu->arch.vgic_cpu.vgic_v2.used_lrs = count; - else + vgic_v2_configure_hcr(vcpu, &als); + } else { vcpu->arch.vgic_cpu.vgic_v3.used_lrs = count; + vgic_v3_configure_hcr(vcpu, &als); + } } static inline bool can_access_vgic_from_kernel(void) @@ -913,8 +1005,6 @@ static inline void vgic_save_state(struct kvm_vcpu *vcpu) /* Sync back the hardware VGIC state into our emulation after a guest's run. */ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { - int used_lrs; - /* If nesting, emulate the HW effect from L0 to L1 */ if (vgic_state_is_nested(vcpu)) { vgic_v3_sync_nested(vcpu); @@ -924,21 +1014,22 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) if (vcpu_has_nv(vcpu)) vgic_v3_nested_update_mi(vcpu); - /* An empty ap_list_head implies used_lrs == 0 */ - if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head)) - return; - if (can_access_vgic_from_kernel()) vgic_save_state(vcpu); - if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) - used_lrs = vcpu->arch.vgic_cpu.vgic_v2.used_lrs; - else - used_lrs = vcpu->arch.vgic_cpu.vgic_v3.used_lrs; + vgic_fold_lr_state(vcpu); + vgic_prune_ap_list(vcpu); +} + +/* Sync interrupts that were deactivated through a DIR trap */ +void kvm_vgic_process_async_update(struct kvm_vcpu *vcpu) +{ + unsigned long flags; - if (used_lrs) - vgic_fold_lr_state(vcpu); + /* Make sure we're in the same context as LR handling */ + local_irq_save(flags); vgic_prune_ap_list(vcpu); + local_irq_restore(flags); } static inline void vgic_restore_state(struct kvm_vcpu *vcpu) @@ -965,8 +1056,9 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) * abort the entry procedure and inject the exception at the * beginning of the run loop. * - * - Otherwise, do exactly *NOTHING*. The guest state is - * already loaded, and we can carry on with running it. + * - Otherwise, do exactly *NOTHING* apart from enabling the virtual + * CPU interface. The guest state is already loaded, and we can + * carry on with running it. * * If we have NV, but are not in a nested state, compute the * maintenance interrupt state, as it may fire. @@ -975,35 +1067,17 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) if (kvm_vgic_vcpu_pending_irq(vcpu)) kvm_make_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu); + vgic_v3_flush_nested(vcpu); return; } if (vcpu_has_nv(vcpu)) vgic_v3_nested_update_mi(vcpu); - /* - * If there are no virtual interrupts active or pending for this - * VCPU, then there is no work to do and we can bail out without - * taking any lock. There is a potential race with someone injecting - * interrupts to the VCPU, but it is a benign race as the VCPU will - * either observe the new interrupt before or after doing this check, - * and introducing additional synchronization mechanism doesn't change - * this. - * - * Note that we still need to go through the whole thing if anything - * can be directly injected (GICv4). - */ - if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head) && - !vgic_supports_direct_irqs(vcpu->kvm)) - return; - DEBUG_SPINLOCK_BUG_ON(!irqs_disabled()); - if (!list_empty(&vcpu->arch.vgic_cpu.ap_list_head)) { - raw_spin_lock(&vcpu->arch.vgic_cpu.ap_list_lock); + scoped_guard(raw_spinlock, &vcpu->arch.vgic_cpu.ap_list_lock) vgic_flush_lr_state(vcpu); - raw_spin_unlock(&vcpu->arch.vgic_cpu.ap_list_lock); - } if (can_access_vgic_from_kernel()) vgic_restore_state(vcpu); diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index ac5f9c5d2b980..5f0fc96b4dc29 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -164,6 +164,22 @@ static inline int vgic_write_guest_lock(struct kvm *kvm, gpa_t gpa, return ret; } +void kvm_compute_ich_hcr_trap_bits(struct alt_instr *alt, + __le32 *origptr, __le32 *updptr, int nr_inst); + +static inline u64 vgic_ich_hcr_trap_bits(void) +{ + u64 hcr; + + /* All the traps are in the bottom 16bits */ + asm volatile(ALTERNATIVE_CB("movz %0, #0\n", + ARM64_ALWAYS_SYSTEM, + kvm_compute_ich_hcr_trap_bits) + : "=r" (hcr)); + + return hcr; +} + /* * This struct provides an intermediate representation of the fields contained * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC @@ -220,6 +236,21 @@ struct its_ite { u32 event_id; }; +struct ap_list_summary { + unsigned int nr_pend; /* purely pending, not active */ + unsigned int nr_act; /* active, or active+pending */ + unsigned int nr_sgi; /* any SGI */ +}; + +#define irqs_outside_lrs(s) \ + (((s)->nr_pend + (s)->nr_act) > kvm_vgic_global_state.nr_lr) + +#define irqs_pending_outside_lrs(s) \ + ((s)->nr_pend > kvm_vgic_global_state.nr_lr) + +#define irqs_active_outside_lrs(s) \ + ((s)->nr_act && irqs_outside_lrs(s)) + int vgic_v3_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr, struct vgic_reg_attr *reg_attr); int vgic_v2_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr, @@ -230,6 +261,7 @@ vgic_get_mmio_region(struct kvm_vcpu *vcpu, struct vgic_io_device *iodev, struct vgic_irq *vgic_get_irq(struct kvm *kvm, u32 intid); struct vgic_irq *vgic_get_vcpu_irq(struct kvm_vcpu *vcpu, u32 intid); void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq); +struct kvm_vcpu *vgic_target_oracle(struct vgic_irq *irq); bool vgic_get_phys_line_level(struct vgic_irq *irq); void vgic_irq_set_phys_pending(struct vgic_irq *irq, bool pending); void vgic_irq_set_phys_active(struct vgic_irq *irq, bool active); @@ -245,8 +277,9 @@ int vgic_check_iorange(struct kvm *kvm, phys_addr_t ioaddr, void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu); void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr); +void vgic_v2_deactivate(struct kvm_vcpu *vcpu, u32 val); void vgic_v2_clear_lr(struct kvm_vcpu *vcpu, int lr); -void vgic_v2_set_underflow(struct kvm_vcpu *vcpu); +void vgic_v2_configure_hcr(struct kvm_vcpu *vcpu, struct ap_list_summary *als); int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr); int vgic_v2_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write, int offset, u32 *val); @@ -254,7 +287,7 @@ int vgic_v2_cpuif_uaccess(struct kvm_vcpu *vcpu, bool is_write, int offset, u32 *val); void vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); -void vgic_v2_enable(struct kvm_vcpu *vcpu); +void vgic_v2_reset(struct kvm_vcpu *vcpu); int vgic_v2_probe(const struct gic_kvm_info *info); int vgic_v2_map_resources(struct kvm *kvm); int vgic_register_dist_iodev(struct kvm *kvm, gpa_t dist_base_address, @@ -286,10 +319,11 @@ static inline void vgic_get_irq_ref(struct vgic_irq *irq) void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu); void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr); void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr); -void vgic_v3_set_underflow(struct kvm_vcpu *vcpu); +void vgic_v3_deactivate(struct kvm_vcpu *vcpu, u64 val); +void vgic_v3_configure_hcr(struct kvm_vcpu *vcpu, struct ap_list_summary *als); void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); -void vgic_v3_enable(struct kvm_vcpu *vcpu); +void vgic_v3_reset(struct kvm_vcpu *vcpu); int vgic_v3_probe(const struct gic_kvm_info *info); int vgic_v3_map_resources(struct kvm *kvm); int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq); @@ -412,6 +446,7 @@ static inline bool kvm_has_gicv3(struct kvm *kvm) return kvm_has_feat(kvm, ID_AA64PFR0_EL1, GIC, IMP); } +void vgic_v3_flush_nested(struct kvm_vcpu *vcpu); void vgic_v3_sync_nested(struct kvm_vcpu *vcpu); void vgic_v3_load_nested(struct kvm_vcpu *vcpu); void vgic_v3_put_nested(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index c8d24b7cdd627..8e1d80a7033e3 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -49,8 +49,6 @@ #define NO_CONT_MAPPINGS BIT(1) #define NO_EXEC_MAPPINGS BIT(2) /* assumes FEAT_HPDS is not used */ -#define INVALID_PHYS_ADDR (-1ULL) - DEFINE_STATIC_KEY_FALSE(arm64_ptdump_lock_key); u64 kimage_voffset __ro_after_init; @@ -769,18 +767,6 @@ static inline bool force_pte_mapping(void) return rodata_full || arm64_kfence_can_set_direct_map() || is_realm_world(); } -static inline bool split_leaf_mapping_possible(void) -{ - /* - * !BBML2_NOABORT systems should never run into scenarios where we would - * have to split. So exit early and let calling code detect it and raise - * a warning. - */ - if (!system_supports_bbml2_noabort()) - return false; - return !force_pte_mapping(); -} - static DEFINE_MUTEX(pgtable_split_lock); int split_kernel_leaf_mapping(unsigned long start, unsigned long end) @@ -788,11 +774,22 @@ int split_kernel_leaf_mapping(unsigned long start, unsigned long end) int ret; /* - * Exit early if the region is within a pte-mapped area or if we can't - * split. For the latter case, the permission change code will raise a - * warning if not already pte-mapped. + * !BBML2_NOABORT systems should not be trying to change permissions on + * anything that is not pte-mapped in the first place. Just return early + * and let the permission change code raise a warning if not already + * pte-mapped. */ - if (!split_leaf_mapping_possible() || is_kfence_address((void *)start)) + if (!system_supports_bbml2_noabort()) + return 0; + + /* + * If the region is within a pte-mapped area, there is no need to try to + * split. Additionally, CONFIG_DEBUG_PAGEALLOC and CONFIG_KFENCE may + * change permissions from atomic context so for those cases (which are + * always pte-mapped), we must not go any further because taking the + * mutex below may sleep. + */ + if (force_pte_mapping() || is_kfence_address((void *)start)) return 0; /* @@ -1091,7 +1088,7 @@ bool arch_kfence_init_pool(void) int ret; /* Exit early if we know the linear map is already pte-mapped. */ - if (!split_leaf_mapping_possible()) + if (force_pte_mapping()) return true; /* Kfence pool is already pte-mapped for the early init case. */ diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index 74dd29816f36a..b6eb7a465ad24 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -1004,7 +1004,7 @@ static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx) arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) return; - if (capable(CAP_SYS_ADMIN)) + if (ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) return; if (supports_clearbhb(SCOPE_SYSTEM)) { diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 1b32c1232d28d..0fac75f015343 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -40,6 +40,7 @@ HAS_GICV5_CPUIF HAS_GICV5_LEGACY HAS_GIC_PRIO_MASKING HAS_GIC_PRIO_RELAXED_SYNC +HAS_ICH_HCR_EL2_TDIR HAS_HCR_NV1 HAS_HCX HAS_LDAPR @@ -64,6 +65,7 @@ HAS_TLB_RANGE HAS_VA52 HAS_VIRT_HOST_EXTN HAS_WFXT +HAS_XNX HAFT HW_DBM KVM_HVHE diff --git a/arch/csky/abiv1/inc/abi/regdef.h b/arch/csky/abiv1/inc/abi/regdef.h index 7b386fd670702..c75ecf2cafd7c 100644 --- a/arch/csky/abiv1/inc/abi/regdef.h +++ b/arch/csky/abiv1/inc/abi/regdef.h @@ -3,7 +3,7 @@ #ifndef __ASM_CSKY_REGDEF_H #define __ASM_CSKY_REGDEF_H -#ifdef __ASSEMBLY__ +#ifdef __ASSEMBLER__ #define syscallid r1 #else #define syscallid "r1" diff --git a/arch/csky/abiv2/inc/abi/regdef.h b/arch/csky/abiv2/inc/abi/regdef.h index 0933addbc27b7..fc08d56ccdbe1 100644 --- a/arch/csky/abiv2/inc/abi/regdef.h +++ b/arch/csky/abiv2/inc/abi/regdef.h @@ -3,7 +3,7 @@ #ifndef __ASM_CSKY_REGDEF_H #define __ASM_CSKY_REGDEF_H -#ifdef __ASSEMBLY__ +#ifdef __ASSEMBLER__ #define syscallid r7 #else #define syscallid "r7" diff --git a/arch/csky/include/asm/barrier.h b/arch/csky/include/asm/barrier.h index 15de58b10aece..c33fdcfe3770c 100644 --- a/arch/csky/include/asm/barrier.h +++ b/arch/csky/include/asm/barrier.h @@ -3,7 +3,7 @@ #ifndef __ASM_CSKY_BARRIER_H #define __ASM_CSKY_BARRIER_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #define nop() asm volatile ("nop\n":::"memory") @@ -84,5 +84,5 @@ #include -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __ASM_CSKY_BARRIER_H */ diff --git a/arch/csky/include/asm/cache.h b/arch/csky/include/asm/cache.h index 4b5c09bf1d25e..d575482e0fcec 100644 --- a/arch/csky/include/asm/cache.h +++ b/arch/csky/include/asm/cache.h @@ -10,7 +10,7 @@ #define ARCH_DMA_MINALIGN L1_CACHE_BYTES -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ void dcache_wb_line(unsigned long start); diff --git a/arch/csky/include/asm/ftrace.h b/arch/csky/include/asm/ftrace.h index 00f9f7647e3f3..21532f2180587 100644 --- a/arch/csky/include/asm/ftrace.h +++ b/arch/csky/include/asm/ftrace.h @@ -11,7 +11,7 @@ #define MCOUNT_ADDR ((unsigned long)_mcount) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ extern void _mcount(unsigned long); @@ -28,5 +28,5 @@ struct dyn_arch_ftrace { void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, unsigned long frame_pointer); -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ #endif /* __ASM_CSKY_FTRACE_H */ diff --git a/arch/csky/include/asm/jump_label.h b/arch/csky/include/asm/jump_label.h index ef2e37a10a0fe..603b0caa80249 100644 --- a/arch/csky/include/asm/jump_label.h +++ b/arch/csky/include/asm/jump_label.h @@ -3,7 +3,7 @@ #ifndef __ASM_CSKY_JUMP_LABEL_H #define __ASM_CSKY_JUMP_LABEL_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include @@ -48,5 +48,5 @@ void arch_jump_label_transform_static(struct jump_entry *entry, enum jump_label_type type); #define arch_jump_label_transform_static arch_jump_label_transform_static -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __ASM_CSKY_JUMP_LABEL_H */ diff --git a/arch/csky/include/asm/page.h b/arch/csky/include/asm/page.h index 4911d0892b71d..76774dbce8697 100644 --- a/arch/csky/include/asm/page.h +++ b/arch/csky/include/asm/page.h @@ -26,7 +26,7 @@ #define PHYS_OFFSET_OFFSET (CONFIG_DRAM_BASE & (SSEG_SIZE - 1)) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include @@ -84,5 +84,5 @@ static inline unsigned long virt_to_pfn(const void *kaddr) #include #include -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ #endif /* __ASM_CSKY_PAGE_H */ diff --git a/arch/csky/include/asm/pgtable.h b/arch/csky/include/asm/pgtable.h index 5a394be09c35b..d606afbabce19 100644 --- a/arch/csky/include/asm/pgtable.h +++ b/arch/csky/include/asm/pgtable.h @@ -263,7 +263,4 @@ void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma, #define update_mmu_cache(vma, addr, ptep) \ update_mmu_cache_range(NULL, vma, addr, ptep, 1) -#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ - remap_pfn_range(vma, vaddr, pfn, size, prot) - #endif /* __ASM_CSKY_PGTABLE_H */ diff --git a/arch/csky/include/asm/ptrace.h b/arch/csky/include/asm/ptrace.h index 0634b7895d81d..5f01839e11843 100644 --- a/arch/csky/include/asm/ptrace.h +++ b/arch/csky/include/asm/ptrace.h @@ -8,7 +8,7 @@ #include #include -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #define PS_S 0x80000000 /* Supervisor Mode */ @@ -98,5 +98,5 @@ static inline unsigned long regs_get_register(struct pt_regs *regs, asmlinkage int syscall_trace_enter(struct pt_regs *regs); asmlinkage void syscall_trace_exit(struct pt_regs *regs); -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __ASM_CSKY_PTRACE_H */ diff --git a/arch/csky/include/asm/sections.h b/arch/csky/include/asm/sections.h index 83e82b7c0f6c4..ee5cdf226a9b1 100644 --- a/arch/csky/include/asm/sections.h +++ b/arch/csky/include/asm/sections.h @@ -8,5 +8,6 @@ extern char _start[]; asmlinkage void csky_start(unsigned int unused, void *dtb_start); +asmlinkage void csky_start_secondary(void); #endif /* __ASM_SECTIONS_H */ diff --git a/arch/csky/include/asm/string.h b/arch/csky/include/asm/string.h index a0d81e9d6b8f6..82e99f52b547c 100644 --- a/arch/csky/include/asm/string.h +++ b/arch/csky/include/asm/string.h @@ -3,7 +3,7 @@ #ifndef _CSKY_STRING_MM_H_ #define _CSKY_STRING_MM_H_ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include #include #include diff --git a/arch/csky/include/asm/thread_info.h b/arch/csky/include/asm/thread_info.h index b5ed788f0c681..fdd4f8ad45acf 100644 --- a/arch/csky/include/asm/thread_info.h +++ b/arch/csky/include/asm/thread_info.h @@ -3,7 +3,7 @@ #ifndef _ASM_CSKY_THREAD_INFO_H #define _ASM_CSKY_THREAD_INFO_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include #include @@ -51,7 +51,7 @@ static inline struct thread_info *current_thread_info(void) return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); } -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ #define TIF_SIGPENDING 0 /* signal pending */ #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ diff --git a/arch/csky/include/uapi/asm/ptrace.h b/arch/csky/include/uapi/asm/ptrace.h index 3be9c14334a6e..90a5c36e4345d 100644 --- a/arch/csky/include/uapi/asm/ptrace.h +++ b/arch/csky/include/uapi/asm/ptrace.h @@ -3,7 +3,7 @@ #ifndef _CSKY_PTRACE_H #define _CSKY_PTRACE_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ struct pt_regs { unsigned long tls; @@ -47,5 +47,5 @@ struct user_fp { unsigned long reserved; }; -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* _CSKY_PTRACE_H */ diff --git a/arch/csky/mm/fault.c b/arch/csky/mm/fault.c index a6ca7dff42153..7ff4011089850 100644 --- a/arch/csky/mm/fault.c +++ b/arch/csky/mm/fault.c @@ -45,8 +45,8 @@ static inline void csky_cmpxchg_fixup(struct pt_regs *regs) if (trap_no(regs) != VEC_TLBMODIFIED) return; - if (instruction_pointer(regs) == csky_cmpxchg_stw) - instruction_pointer_set(regs, csky_cmpxchg_ldw); + if (instruction_pointer(regs) == (unsigned long)&csky_cmpxchg_stw) + instruction_pointer_set(regs, (unsigned long)&csky_cmpxchg_ldw); return; } #endif diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 5b1116733d881..730f342145197 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -115,6 +115,7 @@ config LOONGARCH select GPIOLIB select HAS_IOPORT select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_BITREVERSE select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_JUMP_LABEL_RELATIVE select HAVE_ARCH_KASAN @@ -567,6 +568,10 @@ config ARCH_STRICT_ALIGN to run kernel only on systems with h/w unaligned access support in order to optimise for performance. +config CPU_HAS_AMO + bool + default 64BIT + config CPU_HAS_FPU bool default y diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile index 96ca1a688984e..8d45b860fe562 100644 --- a/arch/loongarch/Makefile +++ b/arch/loongarch/Makefile @@ -5,7 +5,12 @@ boot := arch/loongarch/boot -KBUILD_DEFCONFIG := loongson3_defconfig +ifeq ($(shell uname -m),loongarch32) +KBUILD_DEFCONFIG := loongson32_defconfig +else +KBUILD_DEFCONFIG := loongson64_defconfig +endif + KBUILD_DTBS := dtbs image-name-y := vmlinux diff --git a/arch/loongarch/boot/dts/loongson-2k0500.dtsi b/arch/loongarch/boot/dts/loongson-2k0500.dtsi index 588ebc3bded40..357de4ca75550 100644 --- a/arch/loongarch/boot/dts/loongson-2k0500.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k0500.dtsi @@ -380,7 +380,7 @@ }; uart0: serial@1ff40800 { - compatible = "ns16550a"; + compatible = "loongson,ls2k0500-uart", "ns16550a"; reg = <0x0 0x1ff40800 0x0 0x10>; clock-frequency = <100000000>; interrupt-parent = <&eiointc>; diff --git a/arch/loongarch/boot/dts/loongson-2k1000.dtsi b/arch/loongarch/boot/dts/loongson-2k1000.dtsi index d8e01e2534dde..60ab425f793fe 100644 --- a/arch/loongarch/boot/dts/loongson-2k1000.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k1000.dtsi @@ -297,7 +297,7 @@ }; uart0: serial@1fe20000 { - compatible = "ns16550a"; + compatible = "loongson,ls2k1000-uart", "loongson,ls2k0500-uart", "ns16550a"; reg = <0x0 0x1fe20000 0x0 0x10>; clock-frequency = <125000000>; interrupt-parent = <&liointc0>; diff --git a/arch/loongarch/boot/dts/loongson-2k2000.dtsi b/arch/loongarch/boot/dts/loongson-2k2000.dtsi index 00cc485b753b1..6c77b86ee06c8 100644 --- a/arch/loongarch/boot/dts/loongson-2k2000.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k2000.dtsi @@ -250,7 +250,7 @@ }; uart0: serial@1fe001e0 { - compatible = "ns16550a"; + compatible = "loongson,ls2k2000-uart", "loongson,ls2k1500-uart", "ns16550a"; reg = <0x0 0x1fe001e0 0x0 0x10>; clock-frequency = <100000000>; interrupt-parent = <&liointc>; diff --git a/arch/loongarch/configs/loongson32_defconfig b/arch/loongarch/configs/loongson32_defconfig new file mode 100644 index 0000000000000..276b1577e0be9 --- /dev/null +++ b/arch/loongarch/configs/loongson32_defconfig @@ -0,0 +1,1105 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_KERNEL_ZSTD=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_SYSCALL=y +CONFIG_PREEMPT=y +CONFIG_PREEMPT_DYNAMIC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_PSI=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_IKHEADERS=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_RDMA=y +CONFIG_CGROUP_DMEM=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +CONFIG_CGROUP_MISC=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PERF_EVENTS=y +CONFIG_KEXEC=y +CONFIG_LOONGARCH=y +CONFIG_32BIT=y +CONFIG_32BIT_STANDARD=y +CONFIG_MACH_LOONGSON32=y +CONFIG_PAGE_SIZE_16KB=y +CONFIG_HZ_250=y +CONFIG_DMI=y +CONFIG_EFI=y +CONFIG_SUSPEND=y +CONFIG_HIBERNATION=y +CONFIG_ACPI=y +CONFIG_ACPI_SPCR_TABLE=y +CONFIG_ACPI_TAD=y +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_IPMI=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_PCI_SLOT=y +CONFIG_ACPI_HOTPLUG_MEMORY=y +CONFIG_ACPI_BGRT=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_VIRTUALIZATION=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_COMPRESS=y +CONFIG_MODULE_COMPRESS_ZSTD=y +CONFIG_MODULE_DECOMPRESS=y +CONFIG_BLK_DEV_ZONED=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_BLK_WBT=y +CONFIG_BLK_CGROUP_IOLATENCY=y +CONFIG_BLK_CGROUP_FC_APPID=y +CONFIG_BLK_CGROUP_IOCOST=y +CONFIG_BLK_CGROUP_IOPRIO=y +CONFIG_BLK_INLINE_ENCRYPTION=y +CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_BSD_DISKLABEL=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_CMDLINE_PARTITION=y +CONFIG_IOSCHED_BFQ=y +CONFIG_BFQ_GROUP_IOSCHED=y +CONFIG_BINFMT_MISC=m +CONFIG_ZSWAP=y +CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y +CONFIG_ZSMALLOC=y +# CONFIG_COMPAT_BRK is not set +CONFIG_MEMORY_HOTPLUG=y +# CONFIG_MHP_DEFAULT_ONLINE_TYPE_OFFLINE is not set +CONFIG_MHP_DEFAULT_ONLINE_TYPE_ONLINE_AUTO=y +# CONFIG_MHP_DEFAULT_ONLINE_TYPE_ONLINE_KERNEL is not set +# CONFIG_MHP_DEFAULT_ONLINE_TYPE_ONLINE_MOVABLE is not set +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_KSM=y +CONFIG_CMA=y +CONFIG_CMA_SYSFS=y +CONFIG_USERFAULTFD=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_TLS=m +CONFIG_TLS_DEVICE=y +CONFIG_XFRM_USER=y +CONFIG_NET_KEY=y +CONFIG_XDP_SOCKETS=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=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_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_ESP_OFFLOAD=m +CONFIG_INET_ESPINTCP=y +CONFIG_INET_IPCOMP=m +CONFIG_INET_UDP_DIAG=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_NV=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_DCTCP=m +CONFIG_TCP_CONG_CDG=m +CONFIG_TCP_CONG_BBR=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_ESP_OFFLOAD=m +CONFIG_INET6_ESPINTCP=y +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_MROUTE=y +CONFIG_MPTCP=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NFT_CT=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_FIB_INET=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_NFCT=y +CONFIG_NF_TABLES_IPV4=y +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SYNPROXY=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NF_TABLES_IPV6=y +CONFIG_NFT_FIB_IPV6=m +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_IP_SCTP=m +CONFIG_RDS=y +CONFIG_L2TP=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_LLC2=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_CBS=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_SKBPRIO=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_CAKE=m +CONFIG_NET_SCH_FQ=m +CONFIG_NET_SCH_PIE=m +CONFIG_NET_SCH_FQ_PIE=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_DEFAULT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_CLS_BPF=m +CONFIG_NET_CLS_FLOWER=m +CONFIG_NET_CLS_MATCHALL=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_BPF=m +CONFIG_OPENVSWITCH=m +CONFIG_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS=m +CONFIG_NETLINK_DIAG=y +CONFIG_CGROUP_NET_PRIO=y +CONFIG_BPF_STREAM_PARSER=y +CONFIG_BT=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_HS=y +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y +CONFIG_BT_HCIBTUSB_MTK=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIUART_AG6XX=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_ATH3K=m +CONFIG_BT_VIRTIO=m +CONFIG_CFG80211=m +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=y +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_CEPH_LIB=m +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=y +CONFIG_PCIEAER=y +# CONFIG_PCIEASPM is not set +CONFIG_PCI_IOV=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_SHPC=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCCARD=m +CONFIG_YENTA=m +CONFIG_RAPIDIO=y +CONFIG_RAPIDIO_TSI721=y +CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS=y +CONFIG_RAPIDIO_ENUM_BASIC=m +CONFIG_RAPIDIO_CHMAN=m +CONFIG_RAPIDIO_MPORT_CDEV=m +CONFIG_UEVENT_HELPER=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_FW_LOADER_COMPRESS=y +CONFIG_FW_LOADER_COMPRESS_ZSTD=y +CONFIG_EFI_ZBOOT=y +CONFIG_EFI_BOOTLOADER_CONTROL=m +CONFIG_EFI_CAPSULE_LOADER=m +CONFIG_EFI_TEST=m +CONFIG_MTD=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_RAW_NAND=m +CONFIG_MTD_NAND_PLATFORM=m +CONFIG_MTD_NAND_LOONGSON=m +CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC=y +CONFIG_MTD_NAND_ECC_SW_BCH=y +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BLOCK=y +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_SERIAL=y +CONFIG_PARPORT_PC_FIFO=y +CONFIG_ZRAM=m +CONFIG_ZRAM_BACKEND_LZ4=y +CONFIG_ZRAM_BACKEND_LZ4HC=y +CONFIG_ZRAM_BACKEND_ZSTD=y +CONFIG_ZRAM_BACKEND_DEFLATE=y +CONFIG_ZRAM_BACKEND_842=y +CONFIG_ZRAM_BACKEND_LZO=y +CONFIG_ZRAM_DEF_COMP_ZSTD=y +CONFIG_ZRAM_WRITEBACK=y +CONFIG_ZRAM_MEMORY_TRACKING=y +CONFIG_ZRAM_MULTI_COMP=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_DRBD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_VIRTIO_BLK=y +CONFIG_BLK_DEV_RBD=m +CONFIG_BLK_DEV_NVME=y +CONFIG_NVME_MULTIPATH=y +CONFIG_NVME_RDMA=m +CONFIG_NVME_FC=m +CONFIG_NVME_TCP=m +CONFIG_NVME_TARGET=m +CONFIG_NVME_TARGET_PASSTHRU=y +CONFIG_NVME_TARGET_LOOP=m +CONFIG_NVME_TARGET_RDMA=m +CONFIG_NVME_TARGET_FC=m +CONFIG_NVME_TARGET_TCP=m +CONFIG_EEPROM_AT24=m +CONFIG_PVPANIC=y +CONFIG_PVPANIC_MMIO=m +CONFIG_PVPANIC_PCI=m +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_ISCSI_TCP=m +CONFIG_SCSI_MVSAS=y +# CONFIG_SCSI_MVSAS_DEBUG is not set +CONFIG_SCSI_MVSAS_TASKLET=y +CONFIG_SCSI_MVUMI=y +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=y +CONFIG_MEGARAID_MAILBOX=y +CONFIG_MEGARAID_LEGACY=y +CONFIG_MEGARAID_SAS=y +CONFIG_SCSI_MPT2SAS=y +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +CONFIG_FCOE=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_TCM_QLA2XXX=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_VIRTIO=m +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_DWC=y +CONFIG_PATA_ATIIXP=y +CONFIG_PATA_PCMCIA=m +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LLBITMAP=y +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_BCACHE=m +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m +CONFIG_DM_WRITECACHE=m +CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_MULTIPATH_HST=m +CONFIG_DM_MULTIPATH_IOA=m +CONFIG_DM_INIT=y +CONFIG_DM_UEVENT=y +CONFIG_DM_VERITY=m +CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y +CONFIG_DM_VERITY_FEC=y +CONFIG_DM_INTEGRITY=m +CONFIG_DM_ZONED=m +CONFIG_DM_VDO=m +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m +CONFIG_TCM_USER2=m +CONFIG_LOOPBACK_TARGET=m +CONFIG_ISCSI_TARGET=m +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=y +CONFIG_WIREGUARD=m +CONFIG_IFB=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_RANDOM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN=m +CONFIG_VXLAN=y +CONFIG_RIONET=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_AGERE is not set +# CONFIG_NET_VENDOR_ALACRITECH is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_NET_VENDOR_AMAZON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_AQUANTIA is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +CONFIG_BNX2=y +# CONFIG_NET_VENDOR_CAVIUM is not set +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHELSIO_T4=m +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_NET_VENDOR_DEC is not set +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_I825XX is not set +CONFIG_E1000=y +CONFIG_E1000E=y +CONFIG_IGB=y +CONFIG_IXGBE=y +CONFIG_I40E=y +CONFIG_ICE=y +CONFIG_FM10K=y +CONFIG_IGC=y +CONFIG_IDPF=y +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_RDC is not set +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_R8169=y +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_SOLARFLARE is not set +# CONFIG_NET_VENDOR_SMSC is not set +CONFIG_STMMAC_ETH=y +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set +# CONFIG_NET_VENDOR_VIA is not set +CONFIG_NGBE=y +CONFIG_TXGBE=y +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +CONFIG_MOTORCOMM_PHY=y +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_USBNET=m +# CONFIG_USB_NET_AX8817X is not set +# CONFIG_USB_NET_AX88179_178A is not set +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +# CONFIG_USB_NET_NET1080 is not set +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_BELKIN is not set +# CONFIG_USB_ARMLINUX is not set +# CONFIG_USB_NET_ZAURUS is not set +CONFIG_ATH9K=m +CONFIG_ATH9K_HTC=m +CONFIG_IWLWIFI=m +CONFIG_IWLDVM=m +CONFIG_IWLMVM=m +CONFIG_MT7601U=m +CONFIG_RT2X00=m +CONFIG_RT2800USB=m +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8723BE=m +CONFIG_RTL8188EE=m +CONFIG_RTL8192EE=m +CONFIG_RTL8821AE=m +CONFIG_RTL8192CU=m +CONFIG_RTL8192DU=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8XXXU=m +CONFIG_RTW88=m +CONFIG_RTW88_8822BE=m +CONFIG_RTW88_8822BU=m +CONFIG_RTW88_8822CE=m +CONFIG_RTW88_8822CU=m +CONFIG_RTW88_8723DE=m +CONFIG_RTW88_8723DU=m +CONFIG_RTW88_8821CE=m +CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m +CONFIG_RTW88_8814AE=m +CONFIG_RTW88_8814AU=m +CONFIG_RTW89=m +CONFIG_RTW89_8851BE=m +CONFIG_RTW89_8852AE=m +CONFIG_RTW89_8852BE=m +CONFIG_RTW89_8852BTE=m +CONFIG_RTW89_8852CE=m +CONFIG_RTW89_8922AE=m +CONFIG_ZD1211RW=m +CONFIG_USB4_NET=m +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_GPIO_POLLED=m +CONFIG_KEYBOARD_MATRIX=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_MOUSE_PS2_SENTELIC=y +CONFIG_MOUSE_SERIAL=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=m +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_RAW=m +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=16 +CONFIG_SERIAL_8250_RUNTIME_UARTS=16 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_LOONGSON=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_PRINTER=m +CONFIG_VIRTIO_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_PIIX4=y +CONFIG_I2C_DESIGNWARE_CORE=y +CONFIG_I2C_DESIGNWARE_SLAVE=y +CONFIG_I2C_DESIGNWARE_PCI=y +CONFIG_I2C_GPIO=y +CONFIG_SPI=y +CONFIG_SPI_LOONGSON_PCI=m +CONFIG_SPI_LOONGSON_PLATFORM=m +CONFIG_PINCTRL=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_LOONGSON1=y +CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_GPIO_PCA9570=m +CONFIG_GPIO_PCF857X=m +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_RESTART=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_W83795=m +CONFIG_SENSORS_W83627HF=m +CONFIG_WATCHDOG=y +CONFIG_LOONGSON1_WDT=m +CONFIG_RC_CORE=m +CONFIG_LIRC=y +CONFIG_RC_DECODERS=y +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_MEDIA_PCI_SUPPORT=y +CONFIG_VIDEO_BT848=m +CONFIG_DVB_BT8XX=m +CONFIG_DRM=y +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_EFIDRM=y +CONFIG_DRM_SIMPLEDRM=y +CONFIG_DRM_RADEON=m +CONFIG_DRM_RADEON_USERPTR=y +CONFIG_DRM_QXL=m +CONFIG_DRM_VIRTIO_GPU=m +CONFIG_DRM_LOONGSON=y +CONFIG_FB=y +CONFIG_FB_RADEON=y +CONFIG_FIRMWARE_EDID=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_PLATFORM=m +# CONFIG_VGA_CONSOLE is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_LOGO=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_BT87X=m +CONFIG_SND_BT87X_OVERCLOCK=y +CONFIG_SND_HDA_INTEL=y +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_REALTEK_LIB=y +CONFIG_SND_HDA_CODEC_ALC260=y +CONFIG_SND_HDA_CODEC_ALC262=y +CONFIG_SND_HDA_CODEC_ALC268=y +CONFIG_SND_HDA_CODEC_ALC269=y +CONFIG_SND_HDA_CODEC_ALC662=y +CONFIG_SND_HDA_CODEC_ALC680=y +CONFIG_SND_HDA_CODEC_ALC861=y +CONFIG_SND_HDA_CODEC_ALC861VD=y +CONFIG_SND_HDA_CODEC_ALC880=y +CONFIG_SND_HDA_CODEC_ALC882=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_HDMI=y +CONFIG_SND_HDA_CODEC_HDMI_GENERIC=y +CONFIG_SND_HDA_CODEC_HDMI_INTEL=y +CONFIG_SND_HDA_CODEC_HDMI_ATI=y +CONFIG_SND_HDA_CODEC_HDMI_NVIDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_AUDIO_MIDI_V2=y +CONFIG_SND_SOC=m +CONFIG_SND_SOC_LOONGSON_CARD=m +CONFIG_SND_LOONGSON1_AC97=m +CONFIG_SND_SOC_ES7134=m +CONFIG_SND_SOC_ES7241=m +CONFIG_SND_SOC_ES8311=m +CONFIG_SND_SOC_ES8316=m +CONFIG_SND_SOC_ES8323=m +CONFIG_SND_SOC_ES8326=m +CONFIG_SND_SOC_ES8328_I2C=m +CONFIG_SND_SOC_ES8328_SPI=m +CONFIG_SND_SOC_UDA1334=m +CONFIG_SND_SOC_UDA1342=m +CONFIG_SND_VIRTIO=m +CONFIG_HIDRAW=y +CONFIG_UHID=m +CONFIG_HID_A4TECH=m +CONFIG_HID_CHERRY=m +CONFIG_HID_ELAN=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_LOGITECH_DJ=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MULTITOUCH=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_WACOM=m +CONFIG_USB_HIDDEV=y +CONFIG_I2C_HID_ACPI=m +CONFIG_I2C_HID_OF=m +CONFIG_I2C_HID_OF_ELAN=m +CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_MON=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_USB_UAS=m +CONFIG_USB_DWC2=y +CONFIG_USB_DWC2_HOST=y +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_GADGET=y +CONFIG_TYPEC=m +CONFIG_TYPEC_TCPM=m +CONFIG_TYPEC_TCPCI=m +CONFIG_TYPEC_UCSI=m +CONFIG_UCSI_ACPI=m +CONFIG_MMC=y +CONFIG_INFINIBAND=m +CONFIG_EDAC=y +# CONFIG_EDAC_LEGACY_SYSFS is not set +CONFIG_EDAC_LOONGSON=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_LOONGSON=y +CONFIG_DMADEVICES=y +CONFIG_LOONGSON1_APB_DMA=y +CONFIG_UDMABUF=y +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_UIO=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_UIO_DMEM_GENIRQ=m +CONFIG_UIO_PCI_GENERIC=m +CONFIG_VFIO=m +CONFIG_VFIO_PCI=m +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_INPUT=m +CONFIG_VIRTIO_MMIO=m +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +CONFIG_VHOST_NET=m +CONFIG_VHOST_SCSI=m +CONFIG_VHOST_VSOCK=m +CONFIG_COMEDI=m +CONFIG_COMEDI_PCI_DRIVERS=m +CONFIG_COMEDI_8255_PCI=m +CONFIG_COMEDI_ADL_PCI6208=m +CONFIG_COMEDI_ADL_PCI7X3X=m +CONFIG_COMEDI_ADL_PCI8164=m +CONFIG_COMEDI_ADL_PCI9111=m +CONFIG_COMEDI_ADL_PCI9118=m +CONFIG_COMEDI_ADV_PCI1710=m +CONFIG_COMEDI_ADV_PCI1720=m +CONFIG_COMEDI_ADV_PCI1723=m +CONFIG_COMEDI_ADV_PCI1724=m +CONFIG_COMEDI_ADV_PCI1760=m +CONFIG_COMEDI_ADV_PCI_DIO=m +CONFIG_COMEDI_NI_LABPC_PCI=m +CONFIG_COMEDI_NI_PCIDIO=m +CONFIG_COMEDI_NI_PCIMIO=m +CONFIG_STAGING=y +CONFIG_CLKSRC_LOONGSON1_PWM=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_PM_DEVFREQ=y +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_NTB=m +CONFIG_NTB_MSI=y +CONFIG_NTB_IDT=m +CONFIG_NTB_EPF=m +CONFIG_NTB_SWITCHTEC=m +CONFIG_NTB_PERF=m +CONFIG_NTB_TRANSPORT=m +CONFIG_PWM=y +CONFIG_GENERIC_PHY=y +CONFIG_USB4=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_XFS_FS=y +CONFIG_XFS_SUPPORT_V4=y +CONFIG_XFS_SUPPORT_ASCII_CI=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=y +CONFIG_OCFS2_FS=m +CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_F2FS_FS=m +CONFIG_F2FS_FS_SECURITY=y +CONFIG_F2FS_CHECK_FS=y +CONFIG_F2FS_FS_COMPRESSION=y +CONFIG_FS_ENCRYPTION=y +CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y +CONFIG_FS_VERITY=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +# CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_VIRTIO_FS=m +CONFIG_OVERLAY_FS=y +CONFIG_OVERLAY_FS_INDEX=y +CONFIG_OVERLAY_FS_XINO_AUTO=y +CONFIG_OVERLAY_FS_METACOPY=y +CONFIG_FSCACHE=y +CONFIG_CACHEFILES=m +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=y +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=936 +CONFIG_FAT_DEFAULT_IOCHARSET="gb2312" +CONFIG_EXFAT_FS=m +CONFIG_NTFS3_FS=m +CONFIG_NTFS3_LZX_XPRESS=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_CONFIGFS_FS=y +CONFIG_ORANGEFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_UBIFS_FS=m +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +CONFIG_MINIX_FS=m +CONFIG_ROMFS_FS=m +CONFIG_PSTORE=m +CONFIG_PSTORE_COMPRESS=y +CONFIG_UFS_FS=m +CONFIG_EROFS_FS=m +CONFIG_EROFS_FS_ZIP_LZMA=y +CONFIG_EROFS_FS_ZIP_DEFLATE=y +CONFIG_EROFS_FS_ZIP_ZSTD=y +CONFIG_EROFS_FS_ONDEMAND=y +CONFIG_EROFS_FS_PCPU_KTHREAD=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_NFSD=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_BLOCKLAYOUT=y +CONFIG_CEPH_FS=m +CONFIG_CEPH_FSCACHE=y +CONFIG_CEPH_FS_POSIX_ACL=y +CONFIG_CEPH_FS_SECURITY_LABEL=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set +CONFIG_9P_FS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_DLM=m +CONFIG_KEY_DH_OPERATIONS=y +CONFIG_SECURITY=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_YAMA=y +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_SELFTESTS=y +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SM4_GENERIC=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_CHACHA20POLY1305=m +CONFIG_CRYPTO_SM3_GENERIC=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_842=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_DEV_VIRTIO=m +CONFIG_CRYPTO_DEV_LOONGSON_RNG=m +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=0 +CONFIG_PRINTK_TIME=y +CONFIG_STRIP_ASM_SYMS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_FTRACE is not set diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson64_defconfig similarity index 99% rename from arch/loongarch/configs/loongson3_defconfig rename to arch/loongarch/configs/loongson64_defconfig index 50e1304e7a6f4..a14db1a95e7e4 100644 --- a/arch/loongarch/configs/loongson3_defconfig +++ b/arch/loongarch/configs/loongson64_defconfig @@ -435,7 +435,6 @@ CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_FW_LOADER_COMPRESS=y CONFIG_FW_LOADER_COMPRESS_ZSTD=y -CONFIG_SYSFB_SIMPLEFB=y CONFIG_EFI_ZBOOT=y CONFIG_EFI_BOOTLOADER_CONTROL=m CONFIG_EFI_CAPSULE_LOADER=m @@ -530,6 +529,7 @@ CONFIG_PATA_ATIIXP=y CONFIG_PATA_PCMCIA=m CONFIG_MD=y CONFIG_BLK_DEV_MD=m +CONFIG_MD_LLBITMAP=y CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m @@ -738,6 +738,7 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_LOONGSON=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_NONSTANDARD=y CONFIG_PRINTER=m @@ -801,6 +802,8 @@ CONFIG_VIDEO_BT848=m CONFIG_DVB_BT8XX=m CONFIG_DRM=y CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_EFIDRM=y +CONFIG_DRM_SIMPLEDRM=y CONFIG_DRM_RADEON=m CONFIG_DRM_RADEON_USERPTR=y CONFIG_DRM_AMDGPU=m @@ -811,9 +814,7 @@ CONFIG_DRM_AST=y CONFIG_DRM_QXL=m CONFIG_DRM_VIRTIO_GPU=m CONFIG_DRM_LOONGSON=y -CONFIG_DRM_SIMPLEDRM=y CONFIG_FB=y -CONFIG_FB_EFI=y CONFIG_FB_RADEON=y CONFIG_FIRMWARE_EDID=y CONFIG_LCD_CLASS_DEVICE=y diff --git a/arch/loongarch/include/asm/Kbuild b/arch/loongarch/include/asm/Kbuild index b04d2cef935f6..9034b583a88a6 100644 --- a/arch/loongarch/include/asm/Kbuild +++ b/arch/loongarch/include/asm/Kbuild @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +syscall-y += syscall_table_32.h syscall-y += syscall_table_64.h generated-y += orc_hash.h diff --git a/arch/loongarch/include/asm/addrspace.h b/arch/loongarch/include/asm/addrspace.h index e739dbc6329dc..d6472cafb32cd 100644 --- a/arch/loongarch/include/asm/addrspace.h +++ b/arch/loongarch/include/asm/addrspace.h @@ -38,11 +38,20 @@ extern unsigned long vm_map_base; #endif #ifndef WRITECOMBINE_BASE +#ifdef CONFIG_32BIT +#define WRITECOMBINE_BASE CSR_DMW0_BASE +#else #define WRITECOMBINE_BASE CSR_DMW2_BASE #endif +#endif +#ifdef CONFIG_32BIT +#define DMW_PABITS 29 +#define TO_PHYS_MASK ((_UL(1) << _UL(DMW_PABITS)) - 1) +#else #define DMW_PABITS 48 -#define TO_PHYS_MASK ((1ULL << DMW_PABITS) - 1) +#define TO_PHYS_MASK ((_ULL(1) << _ULL(DMW_PABITS)) - 1) +#endif /* * Memory above this physical address will be considered highmem. @@ -112,7 +121,11 @@ extern unsigned long vm_map_base; /* * Returns the physical address of a KPRANGEx / XKPRANGE address */ +#ifdef CONFIG_32BIT +#define PHYSADDR(a) ((_ACAST32_(a)) & TO_PHYS_MASK) +#else #define PHYSADDR(a) ((_ACAST64_(a)) & TO_PHYS_MASK) +#endif /* * On LoongArch, I/O ports mappring is following: diff --git a/arch/loongarch/include/asm/asm.h b/arch/loongarch/include/asm/asm.h index f018d26fc995a..719cab1a0ad8c 100644 --- a/arch/loongarch/include/asm/asm.h +++ b/arch/loongarch/include/asm/asm.h @@ -72,11 +72,11 @@ #define INT_SUB sub.w #define INT_L ld.w #define INT_S st.w -#define INT_SLL slli.w +#define INT_SLLI slli.w #define INT_SLLV sll.w -#define INT_SRL srli.w +#define INT_SRLI srli.w #define INT_SRLV srl.w -#define INT_SRA srai.w +#define INT_SRAI srai.w #define INT_SRAV sra.w #endif @@ -86,11 +86,11 @@ #define INT_SUB sub.d #define INT_L ld.d #define INT_S st.d -#define INT_SLL slli.d +#define INT_SLLI slli.d #define INT_SLLV sll.d -#define INT_SRL srli.d +#define INT_SRLI srli.d #define INT_SRLV srl.d -#define INT_SRA srai.d +#define INT_SRAI srai.d #define INT_SRAV sra.d #endif @@ -100,15 +100,23 @@ #if (__SIZEOF_LONG__ == 4) #define LONG_ADD add.w #define LONG_ADDI addi.w +#define LONG_ALSL alsl.w +#define LONG_BSTRINS bstrins.w +#define LONG_BSTRPICK bstrpick.w #define LONG_SUB sub.w #define LONG_L ld.w +#define LONG_LI li.w +#define LONG_LPTR ld.w #define LONG_S st.w -#define LONG_SLL slli.w +#define LONG_SPTR st.w +#define LONG_SLLI slli.w #define LONG_SLLV sll.w -#define LONG_SRL srli.w +#define LONG_SRLI srli.w #define LONG_SRLV srl.w -#define LONG_SRA srai.w +#define LONG_SRAI srai.w #define LONG_SRAV sra.w +#define LONG_ROTR rotr.w +#define LONG_ROTRI rotri.w #ifdef __ASSEMBLER__ #define LONG .word @@ -121,15 +129,23 @@ #if (__SIZEOF_LONG__ == 8) #define LONG_ADD add.d #define LONG_ADDI addi.d +#define LONG_ALSL alsl.d +#define LONG_BSTRINS bstrins.d +#define LONG_BSTRPICK bstrpick.d #define LONG_SUB sub.d #define LONG_L ld.d +#define LONG_LI li.d +#define LONG_LPTR ldptr.d #define LONG_S st.d -#define LONG_SLL slli.d +#define LONG_SPTR stptr.d +#define LONG_SLLI slli.d #define LONG_SLLV sll.d -#define LONG_SRL srli.d +#define LONG_SRLI srli.d #define LONG_SRLV srl.d -#define LONG_SRA srai.d +#define LONG_SRAI srai.d #define LONG_SRAV sra.d +#define LONG_ROTR rotr.d +#define LONG_ROTRI rotri.d #ifdef __ASSEMBLER__ #define LONG .dword @@ -145,16 +161,23 @@ #if (__SIZEOF_POINTER__ == 4) #define PTR_ADD add.w #define PTR_ADDI addi.w +#define PTR_ALSL alsl.w +#define PTR_BSTRINS bstrins.w +#define PTR_BSTRPICK bstrpick.w #define PTR_SUB sub.w #define PTR_L ld.w -#define PTR_S st.w #define PTR_LI li.w -#define PTR_SLL slli.w +#define PTR_LPTR ld.w +#define PTR_S st.w +#define PTR_SPTR st.w +#define PTR_SLLI slli.w #define PTR_SLLV sll.w -#define PTR_SRL srli.w +#define PTR_SRLI srli.w #define PTR_SRLV srl.w -#define PTR_SRA srai.w +#define PTR_SRAI srai.w #define PTR_SRAV sra.w +#define PTR_ROTR rotr.w +#define PTR_ROTRI rotri.w #define PTR_SCALESHIFT 2 @@ -168,16 +191,23 @@ #if (__SIZEOF_POINTER__ == 8) #define PTR_ADD add.d #define PTR_ADDI addi.d +#define PTR_ALSL alsl.d +#define PTR_BSTRINS bstrins.d +#define PTR_BSTRPICK bstrpick.d #define PTR_SUB sub.d #define PTR_L ld.d -#define PTR_S st.d #define PTR_LI li.d -#define PTR_SLL slli.d +#define PTR_LPTR ldptr.d +#define PTR_S st.d +#define PTR_SPTR stptr.d +#define PTR_SLLI slli.d #define PTR_SLLV sll.d -#define PTR_SRL srli.d +#define PTR_SRLI srli.d #define PTR_SRLV srl.d -#define PTR_SRA srai.d +#define PTR_SRAI srai.d #define PTR_SRAV sra.d +#define PTR_ROTR rotr.d +#define PTR_ROTRI rotri.d #define PTR_SCALESHIFT 3 @@ -190,10 +220,17 @@ /* Annotate a function as being unsuitable for kprobes. */ #ifdef CONFIG_KPROBES +#ifdef CONFIG_32BIT +#define _ASM_NOKPROBE(name) \ + .pushsection "_kprobe_blacklist", "aw"; \ + .long name; \ + .popsection +#else #define _ASM_NOKPROBE(name) \ .pushsection "_kprobe_blacklist", "aw"; \ .quad name; \ .popsection +#endif #else #define _ASM_NOKPROBE(name) #endif diff --git a/arch/loongarch/include/asm/asmmacro.h b/arch/loongarch/include/asm/asmmacro.h index 8d7f501b0a124..a648be5f723fc 100644 --- a/arch/loongarch/include/asm/asmmacro.h +++ b/arch/loongarch/include/asm/asmmacro.h @@ -5,43 +5,55 @@ #ifndef _ASM_ASMMACRO_H #define _ASM_ASMMACRO_H +#include #include #include #include #include +#ifdef CONFIG_64BIT +#define TASK_STRUCT_OFFSET 0 +#else +#define TASK_STRUCT_OFFSET 2000 +#endif + .macro cpu_save_nonscratch thread - stptr.d s0, \thread, THREAD_REG23 - stptr.d s1, \thread, THREAD_REG24 - stptr.d s2, \thread, THREAD_REG25 - stptr.d s3, \thread, THREAD_REG26 - stptr.d s4, \thread, THREAD_REG27 - stptr.d s5, \thread, THREAD_REG28 - stptr.d s6, \thread, THREAD_REG29 - stptr.d s7, \thread, THREAD_REG30 - stptr.d s8, \thread, THREAD_REG31 - stptr.d sp, \thread, THREAD_REG03 - stptr.d fp, \thread, THREAD_REG22 + LONG_SPTR s0, \thread, (THREAD_REG23 - TASK_STRUCT_OFFSET) + LONG_SPTR s1, \thread, (THREAD_REG24 - TASK_STRUCT_OFFSET) + LONG_SPTR s2, \thread, (THREAD_REG25 - TASK_STRUCT_OFFSET) + LONG_SPTR s3, \thread, (THREAD_REG26 - TASK_STRUCT_OFFSET) + LONG_SPTR s4, \thread, (THREAD_REG27 - TASK_STRUCT_OFFSET) + LONG_SPTR s5, \thread, (THREAD_REG28 - TASK_STRUCT_OFFSET) + LONG_SPTR s6, \thread, (THREAD_REG29 - TASK_STRUCT_OFFSET) + LONG_SPTR s7, \thread, (THREAD_REG30 - TASK_STRUCT_OFFSET) + LONG_SPTR s8, \thread, (THREAD_REG31 - TASK_STRUCT_OFFSET) + LONG_SPTR ra, \thread, (THREAD_REG01 - TASK_STRUCT_OFFSET) + LONG_SPTR sp, \thread, (THREAD_REG03 - TASK_STRUCT_OFFSET) + LONG_SPTR fp, \thread, (THREAD_REG22 - TASK_STRUCT_OFFSET) .endm .macro cpu_restore_nonscratch thread - ldptr.d s0, \thread, THREAD_REG23 - ldptr.d s1, \thread, THREAD_REG24 - ldptr.d s2, \thread, THREAD_REG25 - ldptr.d s3, \thread, THREAD_REG26 - ldptr.d s4, \thread, THREAD_REG27 - ldptr.d s5, \thread, THREAD_REG28 - ldptr.d s6, \thread, THREAD_REG29 - ldptr.d s7, \thread, THREAD_REG30 - ldptr.d s8, \thread, THREAD_REG31 - ldptr.d ra, \thread, THREAD_REG01 - ldptr.d sp, \thread, THREAD_REG03 - ldptr.d fp, \thread, THREAD_REG22 + LONG_LPTR s0, \thread, (THREAD_REG23 - TASK_STRUCT_OFFSET) + LONG_LPTR s1, \thread, (THREAD_REG24 - TASK_STRUCT_OFFSET) + LONG_LPTR s2, \thread, (THREAD_REG25 - TASK_STRUCT_OFFSET) + LONG_LPTR s3, \thread, (THREAD_REG26 - TASK_STRUCT_OFFSET) + LONG_LPTR s4, \thread, (THREAD_REG27 - TASK_STRUCT_OFFSET) + LONG_LPTR s5, \thread, (THREAD_REG28 - TASK_STRUCT_OFFSET) + LONG_LPTR s6, \thread, (THREAD_REG29 - TASK_STRUCT_OFFSET) + LONG_LPTR s7, \thread, (THREAD_REG30 - TASK_STRUCT_OFFSET) + LONG_LPTR s8, \thread, (THREAD_REG31 - TASK_STRUCT_OFFSET) + LONG_LPTR ra, \thread, (THREAD_REG01 - TASK_STRUCT_OFFSET) + LONG_LPTR sp, \thread, (THREAD_REG03 - TASK_STRUCT_OFFSET) + LONG_LPTR fp, \thread, (THREAD_REG22 - TASK_STRUCT_OFFSET) .endm .macro fpu_save_csr thread tmp movfcsr2gr \tmp, fcsr0 +#ifdef CONFIG_32BIT + st.w \tmp, \thread, THREAD_FCSR +#else stptr.w \tmp, \thread, THREAD_FCSR +#endif #ifdef CONFIG_CPU_HAS_LBT /* TM bit is always 0 if LBT not supported */ andi \tmp, \tmp, FPU_CSR_TM @@ -56,7 +68,11 @@ .endm .macro fpu_restore_csr thread tmp0 tmp1 +#ifdef CONFIG_32BIT + ld.w \tmp0, \thread, THREAD_FCSR +#else ldptr.w \tmp0, \thread, THREAD_FCSR +#endif movgr2fcsr fcsr0, \tmp0 #ifdef CONFIG_CPU_HAS_LBT /* TM bit is always 0 if LBT not supported */ @@ -88,9 +104,52 @@ #endif .endm +#ifdef CONFIG_32BIT .macro fpu_save_cc thread tmp0 tmp1 movcf2gr \tmp0, $fcc0 - move \tmp1, \tmp0 + move \tmp1, \tmp0 + movcf2gr \tmp0, $fcc1 + bstrins.w \tmp1, \tmp0, 15, 8 + movcf2gr \tmp0, $fcc2 + bstrins.w \tmp1, \tmp0, 23, 16 + movcf2gr \tmp0, $fcc3 + bstrins.w \tmp1, \tmp0, 31, 24 + st.w \tmp1, \thread, THREAD_FCC + movcf2gr \tmp0, $fcc4 + move \tmp1, \tmp0 + movcf2gr \tmp0, $fcc5 + bstrins.w \tmp1, \tmp0, 15, 8 + movcf2gr \tmp0, $fcc6 + bstrins.w \tmp1, \tmp0, 23, 16 + movcf2gr \tmp0, $fcc7 + bstrins.w \tmp1, \tmp0, 31, 24 + st.w \tmp1, \thread, (THREAD_FCC + 4) + .endm + + .macro fpu_restore_cc thread tmp0 tmp1 + ld.w \tmp0, \thread, THREAD_FCC + bstrpick.w \tmp1, \tmp0, 7, 0 + movgr2cf $fcc0, \tmp1 + bstrpick.w \tmp1, \tmp0, 15, 8 + movgr2cf $fcc1, \tmp1 + bstrpick.w \tmp1, \tmp0, 23, 16 + movgr2cf $fcc2, \tmp1 + bstrpick.w \tmp1, \tmp0, 31, 24 + movgr2cf $fcc3, \tmp1 + ld.w \tmp0, \thread, (THREAD_FCC + 4) + bstrpick.w \tmp1, \tmp0, 7, 0 + movgr2cf $fcc4, \tmp1 + bstrpick.w \tmp1, \tmp0, 15, 8 + movgr2cf $fcc5, \tmp1 + bstrpick.w \tmp1, \tmp0, 23, 16 + movgr2cf $fcc6, \tmp1 + bstrpick.w \tmp1, \tmp0, 31, 24 + movgr2cf $fcc7, \tmp1 + .endm +#else + .macro fpu_save_cc thread tmp0 tmp1 + movcf2gr \tmp0, $fcc0 + move \tmp1, \tmp0 movcf2gr \tmp0, $fcc1 bstrins.d \tmp1, \tmp0, 15, 8 movcf2gr \tmp0, $fcc2 @@ -109,7 +168,7 @@ .endm .macro fpu_restore_cc thread tmp0 tmp1 - ldptr.d \tmp0, \thread, THREAD_FCC + ldptr.d \tmp0, \thread, THREAD_FCC bstrpick.d \tmp1, \tmp0, 7, 0 movgr2cf $fcc0, \tmp1 bstrpick.d \tmp1, \tmp0, 15, 8 @@ -127,6 +186,7 @@ bstrpick.d \tmp1, \tmp0, 63, 56 movgr2cf $fcc7, \tmp1 .endm +#endif .macro fpu_save_double thread tmp li.w \tmp, THREAD_FPR0 @@ -606,12 +666,14 @@ 766: lu12i.w \reg, 0 ori \reg, \reg, 0 +#ifdef CONFIG_64BIT lu32i.d \reg, 0 lu52i.d \reg, \reg, 0 +#endif .pushsection ".la_abs", "aw", %progbits - .p2align 3 - .dword 766b - .dword \sym + .p2align PTRLOG + PTR 766b + PTR \sym .popsection #endif .endm diff --git a/arch/loongarch/include/asm/atomic-amo.h b/arch/loongarch/include/asm/atomic-amo.h new file mode 100644 index 0000000000000..d5efa5252d567 --- /dev/null +++ b/arch/loongarch/include/asm/atomic-amo.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Atomic operations (AMO). + * + * Copyright (C) 2020-2025 Loongson Technology Corporation Limited + */ + +#ifndef _ASM_ATOMIC_AMO_H +#define _ASM_ATOMIC_AMO_H + +#include +#include +#include + +#define ATOMIC_OP(op, I, asm_op) \ +static inline void arch_atomic_##op(int i, atomic_t *v) \ +{ \ + __asm__ __volatile__( \ + "am"#asm_op".w" " $zero, %1, %0 \n" \ + : "+ZB" (v->counter) \ + : "r" (I) \ + : "memory"); \ +} + +#define ATOMIC_OP_RETURN(op, I, asm_op, c_op, mb, suffix) \ +static inline int arch_atomic_##op##_return##suffix(int i, atomic_t *v) \ +{ \ + int result; \ + \ + __asm__ __volatile__( \ + "am"#asm_op#mb".w" " %1, %2, %0 \n" \ + : "+ZB" (v->counter), "=&r" (result) \ + : "r" (I) \ + : "memory"); \ + \ + return result c_op I; \ +} + +#define ATOMIC_FETCH_OP(op, I, asm_op, mb, suffix) \ +static inline int arch_atomic_fetch_##op##suffix(int i, atomic_t *v) \ +{ \ + int result; \ + \ + __asm__ __volatile__( \ + "am"#asm_op#mb".w" " %1, %2, %0 \n" \ + : "+ZB" (v->counter), "=&r" (result) \ + : "r" (I) \ + : "memory"); \ + \ + return result; \ +} + +#define ATOMIC_OPS(op, I, asm_op, c_op) \ + ATOMIC_OP(op, I, asm_op) \ + ATOMIC_OP_RETURN(op, I, asm_op, c_op, _db, ) \ + ATOMIC_OP_RETURN(op, I, asm_op, c_op, , _relaxed) \ + ATOMIC_FETCH_OP(op, I, asm_op, _db, ) \ + ATOMIC_FETCH_OP(op, I, asm_op, , _relaxed) + +ATOMIC_OPS(add, i, add, +) +ATOMIC_OPS(sub, -i, add, +) + +#define arch_atomic_add_return arch_atomic_add_return +#define arch_atomic_add_return_acquire arch_atomic_add_return +#define arch_atomic_add_return_release arch_atomic_add_return +#define arch_atomic_add_return_relaxed arch_atomic_add_return_relaxed +#define arch_atomic_sub_return arch_atomic_sub_return +#define arch_atomic_sub_return_acquire arch_atomic_sub_return +#define arch_atomic_sub_return_release arch_atomic_sub_return +#define arch_atomic_sub_return_relaxed arch_atomic_sub_return_relaxed +#define arch_atomic_fetch_add arch_atomic_fetch_add +#define arch_atomic_fetch_add_acquire arch_atomic_fetch_add +#define arch_atomic_fetch_add_release arch_atomic_fetch_add +#define arch_atomic_fetch_add_relaxed arch_atomic_fetch_add_relaxed +#define arch_atomic_fetch_sub arch_atomic_fetch_sub +#define arch_atomic_fetch_sub_acquire arch_atomic_fetch_sub +#define arch_atomic_fetch_sub_release arch_atomic_fetch_sub +#define arch_atomic_fetch_sub_relaxed arch_atomic_fetch_sub_relaxed + +#undef ATOMIC_OPS + +#define ATOMIC_OPS(op, I, asm_op) \ + ATOMIC_OP(op, I, asm_op) \ + ATOMIC_FETCH_OP(op, I, asm_op, _db, ) \ + ATOMIC_FETCH_OP(op, I, asm_op, , _relaxed) + +ATOMIC_OPS(and, i, and) +ATOMIC_OPS(or, i, or) +ATOMIC_OPS(xor, i, xor) + +#define arch_atomic_fetch_and arch_atomic_fetch_and +#define arch_atomic_fetch_and_acquire arch_atomic_fetch_and +#define arch_atomic_fetch_and_release arch_atomic_fetch_and +#define arch_atomic_fetch_and_relaxed arch_atomic_fetch_and_relaxed +#define arch_atomic_fetch_or arch_atomic_fetch_or +#define arch_atomic_fetch_or_acquire arch_atomic_fetch_or +#define arch_atomic_fetch_or_release arch_atomic_fetch_or +#define arch_atomic_fetch_or_relaxed arch_atomic_fetch_or_relaxed +#define arch_atomic_fetch_xor arch_atomic_fetch_xor +#define arch_atomic_fetch_xor_acquire arch_atomic_fetch_xor +#define arch_atomic_fetch_xor_release arch_atomic_fetch_xor +#define arch_atomic_fetch_xor_relaxed arch_atomic_fetch_xor_relaxed + +#undef ATOMIC_OPS +#undef ATOMIC_FETCH_OP +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP + +#ifdef CONFIG_64BIT + +#define ATOMIC64_OP(op, I, asm_op) \ +static inline void arch_atomic64_##op(long i, atomic64_t *v) \ +{ \ + __asm__ __volatile__( \ + "am"#asm_op".d " " $zero, %1, %0 \n" \ + : "+ZB" (v->counter) \ + : "r" (I) \ + : "memory"); \ +} + +#define ATOMIC64_OP_RETURN(op, I, asm_op, c_op, mb, suffix) \ +static inline long arch_atomic64_##op##_return##suffix(long i, atomic64_t *v) \ +{ \ + long result; \ + __asm__ __volatile__( \ + "am"#asm_op#mb".d " " %1, %2, %0 \n" \ + : "+ZB" (v->counter), "=&r" (result) \ + : "r" (I) \ + : "memory"); \ + \ + return result c_op I; \ +} + +#define ATOMIC64_FETCH_OP(op, I, asm_op, mb, suffix) \ +static inline long arch_atomic64_fetch_##op##suffix(long i, atomic64_t *v) \ +{ \ + long result; \ + \ + __asm__ __volatile__( \ + "am"#asm_op#mb".d " " %1, %2, %0 \n" \ + : "+ZB" (v->counter), "=&r" (result) \ + : "r" (I) \ + : "memory"); \ + \ + return result; \ +} + +#define ATOMIC64_OPS(op, I, asm_op, c_op) \ + ATOMIC64_OP(op, I, asm_op) \ + ATOMIC64_OP_RETURN(op, I, asm_op, c_op, _db, ) \ + ATOMIC64_OP_RETURN(op, I, asm_op, c_op, , _relaxed) \ + ATOMIC64_FETCH_OP(op, I, asm_op, _db, ) \ + ATOMIC64_FETCH_OP(op, I, asm_op, , _relaxed) + +ATOMIC64_OPS(add, i, add, +) +ATOMIC64_OPS(sub, -i, add, +) + +#define arch_atomic64_add_return arch_atomic64_add_return +#define arch_atomic64_add_return_acquire arch_atomic64_add_return +#define arch_atomic64_add_return_release arch_atomic64_add_return +#define arch_atomic64_add_return_relaxed arch_atomic64_add_return_relaxed +#define arch_atomic64_sub_return arch_atomic64_sub_return +#define arch_atomic64_sub_return_acquire arch_atomic64_sub_return +#define arch_atomic64_sub_return_release arch_atomic64_sub_return +#define arch_atomic64_sub_return_relaxed arch_atomic64_sub_return_relaxed +#define arch_atomic64_fetch_add arch_atomic64_fetch_add +#define arch_atomic64_fetch_add_acquire arch_atomic64_fetch_add +#define arch_atomic64_fetch_add_release arch_atomic64_fetch_add +#define arch_atomic64_fetch_add_relaxed arch_atomic64_fetch_add_relaxed +#define arch_atomic64_fetch_sub arch_atomic64_fetch_sub +#define arch_atomic64_fetch_sub_acquire arch_atomic64_fetch_sub +#define arch_atomic64_fetch_sub_release arch_atomic64_fetch_sub +#define arch_atomic64_fetch_sub_relaxed arch_atomic64_fetch_sub_relaxed + +#undef ATOMIC64_OPS + +#define ATOMIC64_OPS(op, I, asm_op) \ + ATOMIC64_OP(op, I, asm_op) \ + ATOMIC64_FETCH_OP(op, I, asm_op, _db, ) \ + ATOMIC64_FETCH_OP(op, I, asm_op, , _relaxed) + +ATOMIC64_OPS(and, i, and) +ATOMIC64_OPS(or, i, or) +ATOMIC64_OPS(xor, i, xor) + +#define arch_atomic64_fetch_and arch_atomic64_fetch_and +#define arch_atomic64_fetch_and_acquire arch_atomic64_fetch_and +#define arch_atomic64_fetch_and_release arch_atomic64_fetch_and +#define arch_atomic64_fetch_and_relaxed arch_atomic64_fetch_and_relaxed +#define arch_atomic64_fetch_or arch_atomic64_fetch_or +#define arch_atomic64_fetch_or_acquire arch_atomic64_fetch_or +#define arch_atomic64_fetch_or_release arch_atomic64_fetch_or +#define arch_atomic64_fetch_or_relaxed arch_atomic64_fetch_or_relaxed +#define arch_atomic64_fetch_xor arch_atomic64_fetch_xor +#define arch_atomic64_fetch_xor_acquire arch_atomic64_fetch_xor +#define arch_atomic64_fetch_xor_release arch_atomic64_fetch_xor +#define arch_atomic64_fetch_xor_relaxed arch_atomic64_fetch_xor_relaxed + +#undef ATOMIC64_OPS +#undef ATOMIC64_FETCH_OP +#undef ATOMIC64_OP_RETURN +#undef ATOMIC64_OP + +#endif + +#endif /* _ASM_ATOMIC_AMO_H */ diff --git a/arch/loongarch/include/asm/atomic-llsc.h b/arch/loongarch/include/asm/atomic-llsc.h new file mode 100644 index 0000000000000..3ce500c882729 --- /dev/null +++ b/arch/loongarch/include/asm/atomic-llsc.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Atomic operations (LLSC). + * + * Copyright (C) 2024-2025 Loongson Technology Corporation Limited + */ + +#ifndef _ASM_ATOMIC_LLSC_H +#define _ASM_ATOMIC_LLSC_H + +#include +#include +#include + +#define ATOMIC_OP(op, I, asm_op) \ +static inline void arch_atomic_##op(int i, atomic_t *v) \ +{ \ + int temp; \ + \ + __asm__ __volatile__( \ + "1: ll.w %0, %1 #atomic_" #op " \n" \ + " " #asm_op " %0, %0, %2 \n" \ + " sc.w %0, %1 \n" \ + " beq %0, $r0, 1b \n" \ + :"=&r" (temp) , "+ZC"(v->counter) \ + :"r" (I) \ + ); \ +} + +#define ATOMIC_OP_RETURN(op, I, asm_op) \ +static inline int arch_atomic_##op##_return_relaxed(int i, atomic_t *v) \ +{ \ + int result, temp; \ + \ + __asm__ __volatile__( \ + "1: ll.w %1, %2 # atomic_" #op "_return \n" \ + " " #asm_op " %0, %1, %3 \n" \ + " sc.w %0, %2 \n" \ + " beq %0, $r0 ,1b \n" \ + " " #asm_op " %0, %1, %3 \n" \ + : "=&r" (result), "=&r" (temp), "+ZC"(v->counter) \ + : "r" (I)); \ + \ + return result; \ +} + +#define ATOMIC_FETCH_OP(op, I, asm_op) \ +static inline int arch_atomic_fetch_##op##_relaxed(int i, atomic_t *v) \ +{ \ + int result, temp; \ + \ + __asm__ __volatile__( \ + "1: ll.w %1, %2 # atomic_fetch_" #op " \n" \ + " " #asm_op " %0, %1, %3 \n" \ + " sc.w %0, %2 \n" \ + " beq %0, $r0 ,1b \n" \ + " add.w %0, %1 ,$r0 \n" \ + : "=&r" (result), "=&r" (temp), "+ZC" (v->counter) \ + : "r" (I)); \ + \ + return result; \ +} + +#define ATOMIC_OPS(op,I ,asm_op, c_op) \ + ATOMIC_OP(op, I, asm_op) \ + ATOMIC_OP_RETURN(op, I , asm_op) \ + ATOMIC_FETCH_OP(op, I, asm_op) + +ATOMIC_OPS(add, i , add.w ,+=) +ATOMIC_OPS(sub, -i , add.w ,+=) + +#define arch_atomic_add_return_relaxed arch_atomic_add_return_relaxed +#define arch_atomic_sub_return_relaxed arch_atomic_sub_return_relaxed +#define arch_atomic_fetch_add_relaxed arch_atomic_fetch_add_relaxed +#define arch_atomic_fetch_sub_relaxed arch_atomic_fetch_sub_relaxed + +#undef ATOMIC_OPS + +#define ATOMIC_OPS(op, I, asm_op) \ + ATOMIC_OP(op, I, asm_op) \ + ATOMIC_FETCH_OP(op, I, asm_op) + +ATOMIC_OPS(and, i, and) +ATOMIC_OPS(or, i, or) +ATOMIC_OPS(xor, i, xor) + +#define arch_atomic_fetch_and_relaxed arch_atomic_fetch_and_relaxed +#define arch_atomic_fetch_or_relaxed arch_atomic_fetch_or_relaxed +#define arch_atomic_fetch_xor_relaxed arch_atomic_fetch_xor_relaxed + +#undef ATOMIC_OPS +#undef ATOMIC_FETCH_OP +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP + +#ifdef CONFIG_64BIT +#error "64-bit LLSC atomic operations are not supported" +#endif + +#endif /* _ASM_ATOMIC_LLSC_H */ diff --git a/arch/loongarch/include/asm/atomic.h b/arch/loongarch/include/asm/atomic.h index c86f0ab922ec7..444b9ddcd0049 100644 --- a/arch/loongarch/include/asm/atomic.h +++ b/arch/loongarch/include/asm/atomic.h @@ -11,6 +11,16 @@ #include #include +#ifdef CONFIG_CPU_HAS_AMO +#include +#else +#include +#endif + +#ifdef CONFIG_GENERIC_ATOMIC64 +#include +#endif + #if __SIZEOF_LONG__ == 4 #define __LL "ll.w " #define __SC "sc.w " @@ -34,100 +44,6 @@ #define arch_atomic_read(v) READ_ONCE((v)->counter) #define arch_atomic_set(v, i) WRITE_ONCE((v)->counter, (i)) -#define ATOMIC_OP(op, I, asm_op) \ -static inline void arch_atomic_##op(int i, atomic_t *v) \ -{ \ - __asm__ __volatile__( \ - "am"#asm_op".w" " $zero, %1, %0 \n" \ - : "+ZB" (v->counter) \ - : "r" (I) \ - : "memory"); \ -} - -#define ATOMIC_OP_RETURN(op, I, asm_op, c_op, mb, suffix) \ -static inline int arch_atomic_##op##_return##suffix(int i, atomic_t *v) \ -{ \ - int result; \ - \ - __asm__ __volatile__( \ - "am"#asm_op#mb".w" " %1, %2, %0 \n" \ - : "+ZB" (v->counter), "=&r" (result) \ - : "r" (I) \ - : "memory"); \ - \ - return result c_op I; \ -} - -#define ATOMIC_FETCH_OP(op, I, asm_op, mb, suffix) \ -static inline int arch_atomic_fetch_##op##suffix(int i, atomic_t *v) \ -{ \ - int result; \ - \ - __asm__ __volatile__( \ - "am"#asm_op#mb".w" " %1, %2, %0 \n" \ - : "+ZB" (v->counter), "=&r" (result) \ - : "r" (I) \ - : "memory"); \ - \ - return result; \ -} - -#define ATOMIC_OPS(op, I, asm_op, c_op) \ - ATOMIC_OP(op, I, asm_op) \ - ATOMIC_OP_RETURN(op, I, asm_op, c_op, _db, ) \ - ATOMIC_OP_RETURN(op, I, asm_op, c_op, , _relaxed) \ - ATOMIC_FETCH_OP(op, I, asm_op, _db, ) \ - ATOMIC_FETCH_OP(op, I, asm_op, , _relaxed) - -ATOMIC_OPS(add, i, add, +) -ATOMIC_OPS(sub, -i, add, +) - -#define arch_atomic_add_return arch_atomic_add_return -#define arch_atomic_add_return_acquire arch_atomic_add_return -#define arch_atomic_add_return_release arch_atomic_add_return -#define arch_atomic_add_return_relaxed arch_atomic_add_return_relaxed -#define arch_atomic_sub_return arch_atomic_sub_return -#define arch_atomic_sub_return_acquire arch_atomic_sub_return -#define arch_atomic_sub_return_release arch_atomic_sub_return -#define arch_atomic_sub_return_relaxed arch_atomic_sub_return_relaxed -#define arch_atomic_fetch_add arch_atomic_fetch_add -#define arch_atomic_fetch_add_acquire arch_atomic_fetch_add -#define arch_atomic_fetch_add_release arch_atomic_fetch_add -#define arch_atomic_fetch_add_relaxed arch_atomic_fetch_add_relaxed -#define arch_atomic_fetch_sub arch_atomic_fetch_sub -#define arch_atomic_fetch_sub_acquire arch_atomic_fetch_sub -#define arch_atomic_fetch_sub_release arch_atomic_fetch_sub -#define arch_atomic_fetch_sub_relaxed arch_atomic_fetch_sub_relaxed - -#undef ATOMIC_OPS - -#define ATOMIC_OPS(op, I, asm_op) \ - ATOMIC_OP(op, I, asm_op) \ - ATOMIC_FETCH_OP(op, I, asm_op, _db, ) \ - ATOMIC_FETCH_OP(op, I, asm_op, , _relaxed) - -ATOMIC_OPS(and, i, and) -ATOMIC_OPS(or, i, or) -ATOMIC_OPS(xor, i, xor) - -#define arch_atomic_fetch_and arch_atomic_fetch_and -#define arch_atomic_fetch_and_acquire arch_atomic_fetch_and -#define arch_atomic_fetch_and_release arch_atomic_fetch_and -#define arch_atomic_fetch_and_relaxed arch_atomic_fetch_and_relaxed -#define arch_atomic_fetch_or arch_atomic_fetch_or -#define arch_atomic_fetch_or_acquire arch_atomic_fetch_or -#define arch_atomic_fetch_or_release arch_atomic_fetch_or -#define arch_atomic_fetch_or_relaxed arch_atomic_fetch_or_relaxed -#define arch_atomic_fetch_xor arch_atomic_fetch_xor -#define arch_atomic_fetch_xor_acquire arch_atomic_fetch_xor -#define arch_atomic_fetch_xor_release arch_atomic_fetch_xor -#define arch_atomic_fetch_xor_relaxed arch_atomic_fetch_xor_relaxed - -#undef ATOMIC_OPS -#undef ATOMIC_FETCH_OP -#undef ATOMIC_OP_RETURN -#undef ATOMIC_OP - static inline int arch_atomic_fetch_add_unless(atomic_t *v, int a, int u) { int prev, rc; @@ -194,99 +110,6 @@ static inline int arch_atomic_sub_if_positive(int i, atomic_t *v) #define arch_atomic64_read(v) READ_ONCE((v)->counter) #define arch_atomic64_set(v, i) WRITE_ONCE((v)->counter, (i)) -#define ATOMIC64_OP(op, I, asm_op) \ -static inline void arch_atomic64_##op(long i, atomic64_t *v) \ -{ \ - __asm__ __volatile__( \ - "am"#asm_op".d " " $zero, %1, %0 \n" \ - : "+ZB" (v->counter) \ - : "r" (I) \ - : "memory"); \ -} - -#define ATOMIC64_OP_RETURN(op, I, asm_op, c_op, mb, suffix) \ -static inline long arch_atomic64_##op##_return##suffix(long i, atomic64_t *v) \ -{ \ - long result; \ - __asm__ __volatile__( \ - "am"#asm_op#mb".d " " %1, %2, %0 \n" \ - : "+ZB" (v->counter), "=&r" (result) \ - : "r" (I) \ - : "memory"); \ - \ - return result c_op I; \ -} - -#define ATOMIC64_FETCH_OP(op, I, asm_op, mb, suffix) \ -static inline long arch_atomic64_fetch_##op##suffix(long i, atomic64_t *v) \ -{ \ - long result; \ - \ - __asm__ __volatile__( \ - "am"#asm_op#mb".d " " %1, %2, %0 \n" \ - : "+ZB" (v->counter), "=&r" (result) \ - : "r" (I) \ - : "memory"); \ - \ - return result; \ -} - -#define ATOMIC64_OPS(op, I, asm_op, c_op) \ - ATOMIC64_OP(op, I, asm_op) \ - ATOMIC64_OP_RETURN(op, I, asm_op, c_op, _db, ) \ - ATOMIC64_OP_RETURN(op, I, asm_op, c_op, , _relaxed) \ - ATOMIC64_FETCH_OP(op, I, asm_op, _db, ) \ - ATOMIC64_FETCH_OP(op, I, asm_op, , _relaxed) - -ATOMIC64_OPS(add, i, add, +) -ATOMIC64_OPS(sub, -i, add, +) - -#define arch_atomic64_add_return arch_atomic64_add_return -#define arch_atomic64_add_return_acquire arch_atomic64_add_return -#define arch_atomic64_add_return_release arch_atomic64_add_return -#define arch_atomic64_add_return_relaxed arch_atomic64_add_return_relaxed -#define arch_atomic64_sub_return arch_atomic64_sub_return -#define arch_atomic64_sub_return_acquire arch_atomic64_sub_return -#define arch_atomic64_sub_return_release arch_atomic64_sub_return -#define arch_atomic64_sub_return_relaxed arch_atomic64_sub_return_relaxed -#define arch_atomic64_fetch_add arch_atomic64_fetch_add -#define arch_atomic64_fetch_add_acquire arch_atomic64_fetch_add -#define arch_atomic64_fetch_add_release arch_atomic64_fetch_add -#define arch_atomic64_fetch_add_relaxed arch_atomic64_fetch_add_relaxed -#define arch_atomic64_fetch_sub arch_atomic64_fetch_sub -#define arch_atomic64_fetch_sub_acquire arch_atomic64_fetch_sub -#define arch_atomic64_fetch_sub_release arch_atomic64_fetch_sub -#define arch_atomic64_fetch_sub_relaxed arch_atomic64_fetch_sub_relaxed - -#undef ATOMIC64_OPS - -#define ATOMIC64_OPS(op, I, asm_op) \ - ATOMIC64_OP(op, I, asm_op) \ - ATOMIC64_FETCH_OP(op, I, asm_op, _db, ) \ - ATOMIC64_FETCH_OP(op, I, asm_op, , _relaxed) - -ATOMIC64_OPS(and, i, and) -ATOMIC64_OPS(or, i, or) -ATOMIC64_OPS(xor, i, xor) - -#define arch_atomic64_fetch_and arch_atomic64_fetch_and -#define arch_atomic64_fetch_and_acquire arch_atomic64_fetch_and -#define arch_atomic64_fetch_and_release arch_atomic64_fetch_and -#define arch_atomic64_fetch_and_relaxed arch_atomic64_fetch_and_relaxed -#define arch_atomic64_fetch_or arch_atomic64_fetch_or -#define arch_atomic64_fetch_or_acquire arch_atomic64_fetch_or -#define arch_atomic64_fetch_or_release arch_atomic64_fetch_or -#define arch_atomic64_fetch_or_relaxed arch_atomic64_fetch_or_relaxed -#define arch_atomic64_fetch_xor arch_atomic64_fetch_xor -#define arch_atomic64_fetch_xor_acquire arch_atomic64_fetch_xor -#define arch_atomic64_fetch_xor_release arch_atomic64_fetch_xor -#define arch_atomic64_fetch_xor_relaxed arch_atomic64_fetch_xor_relaxed - -#undef ATOMIC64_OPS -#undef ATOMIC64_FETCH_OP -#undef ATOMIC64_OP_RETURN -#undef ATOMIC64_OP - static inline long arch_atomic64_fetch_add_unless(atomic64_t *v, long a, long u) { long prev, rc; diff --git a/arch/loongarch/include/asm/bitops.h b/arch/loongarch/include/asm/bitops.h index 69e00f8d80341..411106bf99026 100644 --- a/arch/loongarch/include/asm/bitops.h +++ b/arch/loongarch/include/asm/bitops.h @@ -13,11 +13,22 @@ #include +#ifdef CONFIG_32BIT_REDUCED + +#include +#include +#include +#include + +#else /* CONFIG_32BIT_STANDARD || CONFIG_64BIT */ + #include #include #include #include +#endif + #include #include diff --git a/arch/loongarch/include/asm/bitrev.h b/arch/loongarch/include/asm/bitrev.h index 46f275b9cdf75..757738ea38d76 100644 --- a/arch/loongarch/include/asm/bitrev.h +++ b/arch/loongarch/include/asm/bitrev.h @@ -11,7 +11,7 @@ static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x) { u32 ret; - asm("bitrev.4b %0, %1" : "=r"(ret) : "r"(__swab32(x))); + asm("bitrev.w %0, %1" : "=r"(ret) : "r"(x)); return ret; } diff --git a/arch/loongarch/include/asm/checksum.h b/arch/loongarch/include/asm/checksum.h index cabbf6af44c43..cc2754e0aa251 100644 --- a/arch/loongarch/include/asm/checksum.h +++ b/arch/loongarch/include/asm/checksum.h @@ -9,6 +9,8 @@ #include #include +#ifdef CONFIG_64BIT + #define _HAVE_ARCH_IPV6_CSUM __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, @@ -61,6 +63,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) extern unsigned int do_csum(const unsigned char *buff, int len); #define do_csum do_csum +#endif + #include #endif /* __ASM_CHECKSUM_H */ diff --git a/arch/loongarch/include/asm/cmpxchg.h b/arch/loongarch/include/asm/cmpxchg.h index 979fde61bba8a..0494c2ab553e9 100644 --- a/arch/loongarch/include/asm/cmpxchg.h +++ b/arch/loongarch/include/asm/cmpxchg.h @@ -9,17 +9,33 @@ #include #include -#define __xchg_asm(amswap_db, m, val) \ +#define __xchg_amo_asm(amswap_db, m, val) \ ({ \ - __typeof(val) __ret; \ + __typeof(val) __ret; \ \ - __asm__ __volatile__ ( \ - " "amswap_db" %1, %z2, %0 \n" \ - : "+ZB" (*m), "=&r" (__ret) \ - : "Jr" (val) \ - : "memory"); \ + __asm__ __volatile__ ( \ + " "amswap_db" %1, %z2, %0 \n" \ + : "+ZB" (*m), "=&r" (__ret) \ + : "Jr" (val) \ + : "memory"); \ \ - __ret; \ + __ret; \ +}) + +#define __xchg_llsc_asm(ld, st, m, val) \ +({ \ + __typeof(val) __ret, __tmp; \ + \ + asm volatile ( \ + "1: ll.w %0, %3 \n" \ + " move %1, %z4 \n" \ + " sc.w %1, %2 \n" \ + " beqz %1, 1b \n" \ + : "=&r" (__ret), "=&r" (__tmp), "=ZC" (*m) \ + : "ZC" (*m), "Jr" (val) \ + : "memory"); \ + \ + __ret; \ }) static inline unsigned int __xchg_small(volatile void *ptr, unsigned int val, @@ -67,13 +83,23 @@ __arch_xchg(volatile void *ptr, unsigned long x, int size) switch (size) { case 1: case 2: - return __xchg_small(ptr, x, size); + return __xchg_small((volatile void *)ptr, x, size); case 4: - return __xchg_asm("amswap_db.w", (volatile u32 *)ptr, (u32)x); +#ifdef CONFIG_CPU_HAS_AMO + return __xchg_amo_asm("amswap_db.w", (volatile u32 *)ptr, (u32)x); +#else + return __xchg_llsc_asm("ll.w", "sc.w", (volatile u32 *)ptr, (u32)x); +#endif /* CONFIG_CPU_HAS_AMO */ +#ifdef CONFIG_64BIT case 8: - return __xchg_asm("amswap_db.d", (volatile u64 *)ptr, (u64)x); +#ifdef CONFIG_CPU_HAS_AMO + return __xchg_amo_asm("amswap_db.d", (volatile u64 *)ptr, (u64)x); +#else + return __xchg_llsc_asm("ll.d", "sc.d", (volatile u64 *)ptr, (u64)x); +#endif /* CONFIG_CPU_HAS_AMO */ +#endif /* CONFIG_64BIT */ default: BUILD_BUG(); diff --git a/arch/loongarch/include/asm/cpu-features.h b/arch/loongarch/include/asm/cpu-features.h index bd5f0457ad21d..3745d991a99a9 100644 --- a/arch/loongarch/include/asm/cpu-features.h +++ b/arch/loongarch/include/asm/cpu-features.h @@ -20,16 +20,13 @@ #define cpu_has_loongarch64 (cpu_data[0].isa_level & LOONGARCH_CPU_ISA_64BIT) #ifdef CONFIG_32BIT -# define cpu_has_64bits (cpu_data[0].isa_level & LOONGARCH_CPU_ISA_64BIT) # define cpu_vabits 31 # define cpu_pabits 31 #endif #ifdef CONFIG_64BIT -# define cpu_has_64bits 1 # define cpu_vabits cpu_data[0].vabits # define cpu_pabits cpu_data[0].pabits -# define __NEED_ADDRBITS_PROBE #endif /* diff --git a/arch/loongarch/include/asm/dmi.h b/arch/loongarch/include/asm/dmi.h index 605493417753c..11bb3c8a7179f 100644 --- a/arch/loongarch/include/asm/dmi.h +++ b/arch/loongarch/include/asm/dmi.h @@ -12,7 +12,7 @@ #define dmi_early_unmap(x, l) dmi_unmap(x) #define dmi_alloc(l) memblock_alloc(l, PAGE_SIZE) -static inline void *dmi_remap(u64 phys_addr, unsigned long size) +static inline void *dmi_remap(phys_addr_t phys_addr, unsigned long size) { return ((void *)TO_CACHE(phys_addr)); } diff --git a/arch/loongarch/include/asm/elf.h b/arch/loongarch/include/asm/elf.h index f16bd42456e4c..912c50cdd6b7c 100644 --- a/arch/loongarch/include/asm/elf.h +++ b/arch/loongarch/include/asm/elf.h @@ -120,6 +120,36 @@ #define R_LARCH_ADD_ULEB128 107 #define R_LARCH_SUB_ULEB128 108 #define R_LARCH_64_PCREL 109 +#define R_LARCH_CALL36 110 +#define R_LARCH_TLS_DESC_PC_HI20 111 +#define R_LARCH_TLS_DESC_PC_LO12 112 +#define R_LARCH_TLS_DESC64_PC_LO20 113 +#define R_LARCH_TLS_DESC64_PC_HI12 114 +#define R_LARCH_TLS_DESC_HI20 115 +#define R_LARCH_TLS_DESC_LO12 116 +#define R_LARCH_TLS_DESC64_LO20 117 +#define R_LARCH_TLS_DESC64_HI12 118 +#define R_LARCH_TLS_DESC_LD 119 +#define R_LARCH_TLS_DESC_CALL 120 +#define R_LARCH_TLS_LE_HI20_R 121 +#define R_LARCH_TLS_LE_ADD_R 122 +#define R_LARCH_TLS_LE_LO12_R 123 +#define R_LARCH_TLS_LD_PCREL20_S2 124 +#define R_LARCH_TLS_GD_PCREL20_S2 125 +#define R_LARCH_TLS_DESC_PCREL20_S2 126 +#define R_LARCH_CALL30 127 +#define R_LARCH_PCADD_HI20 128 +#define R_LARCH_PCADD_LO12 129 +#define R_LARCH_GOT_PCADD_HI20 130 +#define R_LARCH_GOT_PCADD_LO12 131 +#define R_LARCH_TLS_IE_PCADD_HI20 132 +#define R_LARCH_TLS_IE_PCADD_LO12 133 +#define R_LARCH_TLS_LD_PCADD_HI20 134 +#define R_LARCH_TLS_LD_PCADD_LO12 135 +#define R_LARCH_TLS_GD_PCADD_HI20 136 +#define R_LARCH_TLS_GD_PCADD_LO12 137 +#define R_LARCH_TLS_DESC_PCADD_HI20 138 +#define R_LARCH_TLS_DESC_PCADD_LO12 139 #ifndef ELF_ARCH @@ -156,6 +186,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; typedef double elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; +void loongarch_dump_regs32(u32 *uregs, const struct pt_regs *regs); void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs); #ifdef CONFIG_32BIT diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h index 55e64a12a124a..f9f207082d0e8 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -438,8 +438,10 @@ static inline bool is_branch_ins(union loongarch_instruction *ip) static inline bool is_ra_save_ins(union loongarch_instruction *ip) { - /* st.d $ra, $sp, offset */ - return ip->reg2i12_format.opcode == std_op && + const u32 opcode = IS_ENABLED(CONFIG_32BIT) ? stw_op : std_op; + + /* st.w / st.d $ra, $sp, offset */ + return ip->reg2i12_format.opcode == opcode && ip->reg2i12_format.rj == LOONGARCH_GPR_SP && ip->reg2i12_format.rd == LOONGARCH_GPR_RA && !is_imm12_negative(ip->reg2i12_format.immediate); @@ -447,8 +449,10 @@ static inline bool is_ra_save_ins(union loongarch_instruction *ip) static inline bool is_stack_alloc_ins(union loongarch_instruction *ip) { - /* addi.d $sp, $sp, -imm */ - return ip->reg2i12_format.opcode == addid_op && + const u32 opcode = IS_ENABLED(CONFIG_32BIT) ? addiw_op : addid_op; + + /* addi.w / addi.d $sp, $sp, -imm */ + return ip->reg2i12_format.opcode == opcode && ip->reg2i12_format.rj == LOONGARCH_GPR_SP && ip->reg2i12_format.rd == LOONGARCH_GPR_SP && is_imm12_negative(ip->reg2i12_format.immediate); diff --git a/arch/loongarch/include/asm/irq.h b/arch/loongarch/include/asm/irq.h index 12bd15578c336..3943647503a95 100644 --- a/arch/loongarch/include/asm/irq.h +++ b/arch/loongarch/include/asm/irq.h @@ -50,10 +50,22 @@ void spurious_interrupt(void); #define NR_LEGACY_VECTORS 16 #define IRQ_MATRIX_BITS NR_VECTORS +#define AVEC_IRQ_SHIFT 4 +#define AVEC_IRQ_BIT 8 +#define AVEC_IRQ_MASK GENMASK(AVEC_IRQ_BIT - 1, 0) +#define AVEC_CPU_SHIFT 12 +#define AVEC_CPU_BIT 16 +#define AVEC_CPU_MASK GENMASK(AVEC_CPU_BIT - 1, 0) + #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace void arch_trigger_cpumask_backtrace(const struct cpumask *mask, int exclude_cpu); +#ifdef CONFIG_32BIT +#define MAX_IO_PICS 1 +#else #define MAX_IO_PICS 8 +#endif + #define NR_IRQS (64 + NR_VECTORS * (NR_CPUS + MAX_IO_PICS)) struct acpi_vector_group { diff --git a/arch/loongarch/include/asm/jump_label.h b/arch/loongarch/include/asm/jump_label.h index 4000c7603d8e3..dcaecf69ea5a6 100644 --- a/arch/loongarch/include/asm/jump_label.h +++ b/arch/loongarch/include/asm/jump_label.h @@ -10,15 +10,23 @@ #ifndef __ASSEMBLER__ #include +#include +#include #define JUMP_LABEL_NOP_SIZE 4 +#ifdef CONFIG_32BIT +#define JUMP_LABEL_TYPE ".long " +#else +#define JUMP_LABEL_TYPE ".quad " +#endif + /* This macro is also expanded on the Rust side. */ #define JUMP_TABLE_ENTRY(key, label) \ ".pushsection __jump_table, \"aw\" \n\t" \ - ".align 3 \n\t" \ + ".align " __stringify(PTRLOG) " \n\t" \ ".long 1b - ., " label " - . \n\t" \ - ".quad " key " - . \n\t" \ + JUMP_LABEL_TYPE key " - . \n\t" \ ".popsection \n\t" #define ARCH_STATIC_BRANCH_ASM(key, label) \ diff --git a/arch/loongarch/include/asm/kvm_eiointc.h b/arch/loongarch/include/asm/kvm_eiointc.h index a3a40aba8acf2..8b7a2fa3f7f86 100644 --- a/arch/loongarch/include/asm/kvm_eiointc.h +++ b/arch/loongarch/include/asm/kvm_eiointc.h @@ -10,10 +10,7 @@ #define EIOINTC_IRQS 256 #define EIOINTC_ROUTE_MAX_VCPUS 256 -#define EIOINTC_IRQS_U8_NUMS (EIOINTC_IRQS / 8) -#define EIOINTC_IRQS_U16_NUMS (EIOINTC_IRQS_U8_NUMS / 2) -#define EIOINTC_IRQS_U32_NUMS (EIOINTC_IRQS_U8_NUMS / 4) -#define EIOINTC_IRQS_U64_NUMS (EIOINTC_IRQS_U8_NUMS / 8) +#define EIOINTC_IRQS_U64_NUMS (EIOINTC_IRQS / 64) /* map to ipnum per 32 irqs */ #define EIOINTC_IRQS_NODETYPE_COUNT 16 @@ -64,54 +61,18 @@ struct loongarch_eiointc { uint32_t status; /* hardware state */ - union nodetype { - u64 reg_u64[EIOINTC_IRQS_NODETYPE_COUNT / 4]; - u32 reg_u32[EIOINTC_IRQS_NODETYPE_COUNT / 2]; - u16 reg_u16[EIOINTC_IRQS_NODETYPE_COUNT]; - u8 reg_u8[EIOINTC_IRQS_NODETYPE_COUNT * 2]; - } nodetype; + u64 nodetype[EIOINTC_IRQS_NODETYPE_COUNT / 4]; /* one bit shows the state of one irq */ - union bounce { - u64 reg_u64[EIOINTC_IRQS_U64_NUMS]; - u32 reg_u32[EIOINTC_IRQS_U32_NUMS]; - u16 reg_u16[EIOINTC_IRQS_U16_NUMS]; - u8 reg_u8[EIOINTC_IRQS_U8_NUMS]; - } bounce; - - union isr { - u64 reg_u64[EIOINTC_IRQS_U64_NUMS]; - u32 reg_u32[EIOINTC_IRQS_U32_NUMS]; - u16 reg_u16[EIOINTC_IRQS_U16_NUMS]; - u8 reg_u8[EIOINTC_IRQS_U8_NUMS]; - } isr; - union coreisr { - u64 reg_u64[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U64_NUMS]; - u32 reg_u32[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U32_NUMS]; - u16 reg_u16[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U16_NUMS]; - u8 reg_u8[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U8_NUMS]; - } coreisr; - union enable { - u64 reg_u64[EIOINTC_IRQS_U64_NUMS]; - u32 reg_u32[EIOINTC_IRQS_U32_NUMS]; - u16 reg_u16[EIOINTC_IRQS_U16_NUMS]; - u8 reg_u8[EIOINTC_IRQS_U8_NUMS]; - } enable; + u64 bounce[EIOINTC_IRQS_U64_NUMS]; + u64 isr[EIOINTC_IRQS_U64_NUMS]; + u64 coreisr[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U64_NUMS]; + u64 enable[EIOINTC_IRQS_U64_NUMS]; /* use one byte to config ipmap for 32 irqs at once */ - union ipmap { - u64 reg_u64; - u32 reg_u32[EIOINTC_IRQS_U32_NUMS / 4]; - u16 reg_u16[EIOINTC_IRQS_U16_NUMS / 4]; - u8 reg_u8[EIOINTC_IRQS_U8_NUMS / 4]; - } ipmap; + u64 ipmap; /* use one byte to config coremap for one irq */ - union coremap { - u64 reg_u64[EIOINTC_IRQS / 8]; - u32 reg_u32[EIOINTC_IRQS / 4]; - u16 reg_u16[EIOINTC_IRQS / 2]; - u8 reg_u8[EIOINTC_IRQS]; - } coremap; + u64 coremap[EIOINTC_IRQS / 8]; DECLARE_BITMAP(sw_coreisr[EIOINTC_ROUTE_MAX_VCPUS][LOONGSON_IP_NUM], EIOINTC_IRQS); uint8_t sw_coremap[EIOINTC_IRQS]; diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h index 0cecbd038bb3c..e4fe5b8e8149f 100644 --- a/arch/loongarch/include/asm/kvm_host.h +++ b/arch/loongarch/include/asm/kvm_host.h @@ -126,6 +126,8 @@ struct kvm_arch { struct kvm_phyid_map *phyid_map; /* Enabled PV features */ unsigned long pv_features; + /* Supported KVM features */ + unsigned long kvm_features; s64 time_offset; struct kvm_context __percpu *vmcs; @@ -293,6 +295,12 @@ static inline int kvm_get_pmu_num(struct kvm_vcpu_arch *arch) return (arch->cpucfg[6] & CPUCFG6_PMNUM) >> CPUCFG6_PMNUM_SHIFT; } +/* Check whether KVM support this feature (VMM may disable it) */ +static inline bool kvm_vm_support(struct kvm_arch *arch, int feature) +{ + return !!(arch->kvm_features & BIT_ULL(feature)); +} + bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu); /* Debug: dump vcpu state */ diff --git a/arch/loongarch/include/asm/kvm_vcpu.h b/arch/loongarch/include/asm/kvm_vcpu.h index f1efd7cfbc20f..3784ab4ccdb50 100644 --- a/arch/loongarch/include/asm/kvm_vcpu.h +++ b/arch/loongarch/include/asm/kvm_vcpu.h @@ -15,6 +15,7 @@ #define CPU_PMU (_ULCAST_(1) << 10) #define CPU_TIMER (_ULCAST_(1) << 11) #define CPU_IPI (_ULCAST_(1) << 12) +#define CPU_AVEC (_ULCAST_(1) << 14) /* Controlled by 0x52 guest exception VIP aligned to estat bit 5~12 */ #define CPU_IP0 (_ULCAST_(1)) diff --git a/arch/loongarch/include/asm/local.h b/arch/loongarch/include/asm/local.h index f53ea653af76d..2d118b1a060e4 100644 --- a/arch/loongarch/include/asm/local.h +++ b/arch/loongarch/include/asm/local.h @@ -8,6 +8,7 @@ #include #include #include +#include #include typedef struct { @@ -27,6 +28,7 @@ typedef struct { /* * Same as above, but return the result value */ +#ifdef CONFIG_CPU_HAS_AMO static inline long local_add_return(long i, local_t *l) { unsigned long result; @@ -55,6 +57,41 @@ static inline long local_sub_return(long i, local_t *l) return result; } +#else +static inline long local_add_return(long i, local_t *l) +{ + unsigned long result, temp; + + __asm__ __volatile__( + "1:" __LL "%1, %2 # local_add_return \n" + __stringify(LONG_ADD) " %0, %1, %3 \n" + __SC "%0, %2 \n" + " beq %0, $r0, 1b \n" + __stringify(LONG_ADD) " %0, %1, %3 \n" + : "=&r" (result), "=&r" (temp), "=ZC" (l->a.counter) + : "r" (i), "ZC" (l->a.counter) + : "memory"); + + return result; +} + +static inline long local_sub_return(long i, local_t *l) +{ + unsigned long result, temp; + + __asm__ __volatile__( + "1:" __LL "%1, %2 # local_sub_return \n" + __stringify(LONG_SUB) " %0, %1, %3 \n" + __SC "%0, %2 \n" + " beq %0, $r0, 1b \n" + __stringify(LONG_SUB) " %0, %1, %3 \n" + : "=&r" (result), "=&r" (temp), "=ZC" (l->a.counter) + : "r" (i), "ZC" (l->a.counter) + : "memory"); + + return result; +} +#endif static inline long local_cmpxchg(local_t *l, long old, long new) { diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h index 3de03cb864b24..e6b8ff61c8cc6 100644 --- a/arch/loongarch/include/asm/loongarch.h +++ b/arch/loongarch/include/asm/loongarch.h @@ -182,6 +182,16 @@ #define csr_xchg32(val, mask, reg) __csrxchg_w(val, mask, reg) #define csr_xchg64(val, mask, reg) __csrxchg_d(val, mask, reg) +#ifdef CONFIG_32BIT +#define csr_read(reg) csr_read32(reg) +#define csr_write(val, reg) csr_write32(val, reg) +#define csr_xchg(val, mask, reg) csr_xchg32(val, mask, reg) +#else +#define csr_read(reg) csr_read64(reg) +#define csr_write(val, reg) csr_write64(val, reg) +#define csr_xchg(val, mask, reg) csr_xchg64(val, mask, reg) +#endif + /* IOCSR */ #define iocsr_read32(reg) __iocsrrd_w(reg) #define iocsr_read64(reg) __iocsrrd_d(reg) @@ -511,6 +521,8 @@ #define CSR_GCFG_GPERF_SHIFT 24 #define CSR_GCFG_GPERF_WIDTH 3 #define CSR_GCFG_GPERF (_ULCAST_(0x7) << CSR_GCFG_GPERF_SHIFT) +#define CSR_GCFG_GPMP_SHIFT 23 +#define CSR_GCFG_GPMP (_ULCAST_(0x1) << CSR_GCFG_GPMP_SHIFT) #define CSR_GCFG_GCI_SHIFT 20 #define CSR_GCFG_GCI_WIDTH 2 #define CSR_GCFG_GCI (_ULCAST_(0x3) << CSR_GCFG_GCI_SHIFT) @@ -902,6 +914,26 @@ #define LOONGARCH_CSR_DMWIN3 0x183 /* 64 direct map win3: MEM */ /* Direct Map window 0/1/2/3 */ + +#ifdef CONFIG_32BIT + +#define CSR_DMW0_PLV0 (1 << 0) +#define CSR_DMW0_VSEG (0x4) +#define CSR_DMW0_BASE (CSR_DMW0_VSEG << DMW_PABITS) +#define CSR_DMW0_INIT (CSR_DMW0_BASE | CSR_DMW0_PLV0) + +#define CSR_DMW1_PLV0 (1 << 0) +#define CSR_DMW1_MAT (1 << 4) +#define CSR_DMW1_VSEG (0x5) +#define CSR_DMW1_BASE (CSR_DMW1_VSEG << DMW_PABITS) +#define CSR_DMW1_INIT (CSR_DMW1_BASE | CSR_DMW1_MAT | CSR_DMW1_PLV0) + +#define CSR_DMW2_INIT 0x0 + +#define CSR_DMW3_INIT 0x0 + +#else + #define CSR_DMW0_PLV0 _CONST64_(1 << 0) #define CSR_DMW0_VSEG _CONST64_(0x8000) #define CSR_DMW0_BASE (CSR_DMW0_VSEG << DMW_PABITS) @@ -921,6 +953,8 @@ #define CSR_DMW3_INIT 0x0 +#endif + /* Performance Counter registers */ #define LOONGARCH_CSR_PERFCTRL0 0x200 /* 32 perf event 0 config */ #define LOONGARCH_CSR_PERFCNTR0 0x201 /* 64 perf event 0 count value */ @@ -1206,7 +1240,35 @@ #ifndef __ASSEMBLER__ -static __always_inline u64 drdtime(void) +#ifdef CONFIG_32BIT + +static __always_inline u32 rdtime_h(void) +{ + u32 val = 0; + + __asm__ __volatile__( + "rdtimeh.w %0, $zero\n\t" + : "=r"(val) + : + ); + return val; +} + +static __always_inline u32 rdtime_l(void) +{ + u32 val = 0; + + __asm__ __volatile__( + "rdtimel.w %0, $zero\n\t" + : "=r"(val) + : + ); + return val; +} + +#else + +static __always_inline u64 rdtime_d(void) { u64 val = 0; @@ -1218,11 +1280,14 @@ static __always_inline u64 drdtime(void) return val; } +#endif + static inline unsigned int get_csr_cpuid(void) { return csr_read32(LOONGARCH_CSR_CPUID); } +#ifdef CONFIG_64BIT static inline void csr_any_send(unsigned int addr, unsigned int data, unsigned int data_mask, unsigned int cpu) { @@ -1234,6 +1299,7 @@ static inline void csr_any_send(unsigned int addr, unsigned int data, val |= ((uint64_t)data << IOCSR_ANY_SEND_BUF_SHIFT); iocsr_write64(val, LOONGARCH_IOCSR_ANY_SEND); } +#endif static inline unsigned int read_csr_excode(void) { @@ -1257,22 +1323,22 @@ static inline void write_csr_pagesize(unsigned int size) static inline unsigned int read_csr_tlbrefill_pagesize(void) { - return (csr_read64(LOONGARCH_CSR_TLBREHI) & CSR_TLBREHI_PS) >> CSR_TLBREHI_PS_SHIFT; + return (csr_read(LOONGARCH_CSR_TLBREHI) & CSR_TLBREHI_PS) >> CSR_TLBREHI_PS_SHIFT; } static inline void write_csr_tlbrefill_pagesize(unsigned int size) { - csr_xchg64(size << CSR_TLBREHI_PS_SHIFT, CSR_TLBREHI_PS, LOONGARCH_CSR_TLBREHI); + csr_xchg(size << CSR_TLBREHI_PS_SHIFT, CSR_TLBREHI_PS, LOONGARCH_CSR_TLBREHI); } #define read_csr_asid() csr_read32(LOONGARCH_CSR_ASID) #define write_csr_asid(val) csr_write32(val, LOONGARCH_CSR_ASID) -#define read_csr_entryhi() csr_read64(LOONGARCH_CSR_TLBEHI) -#define write_csr_entryhi(val) csr_write64(val, LOONGARCH_CSR_TLBEHI) -#define read_csr_entrylo0() csr_read64(LOONGARCH_CSR_TLBELO0) -#define write_csr_entrylo0(val) csr_write64(val, LOONGARCH_CSR_TLBELO0) -#define read_csr_entrylo1() csr_read64(LOONGARCH_CSR_TLBELO1) -#define write_csr_entrylo1(val) csr_write64(val, LOONGARCH_CSR_TLBELO1) +#define read_csr_entryhi() csr_read(LOONGARCH_CSR_TLBEHI) +#define write_csr_entryhi(val) csr_write(val, LOONGARCH_CSR_TLBEHI) +#define read_csr_entrylo0() csr_read(LOONGARCH_CSR_TLBELO0) +#define write_csr_entrylo0(val) csr_write(val, LOONGARCH_CSR_TLBELO0) +#define read_csr_entrylo1() csr_read(LOONGARCH_CSR_TLBELO1) +#define write_csr_entrylo1(val) csr_write(val, LOONGARCH_CSR_TLBELO1) #define read_csr_ecfg() csr_read32(LOONGARCH_CSR_ECFG) #define write_csr_ecfg(val) csr_write32(val, LOONGARCH_CSR_ECFG) #define read_csr_estat() csr_read32(LOONGARCH_CSR_ESTAT) @@ -1282,20 +1348,20 @@ static inline void write_csr_tlbrefill_pagesize(unsigned int size) #define read_csr_euen() csr_read32(LOONGARCH_CSR_EUEN) #define write_csr_euen(val) csr_write32(val, LOONGARCH_CSR_EUEN) #define read_csr_cpuid() csr_read32(LOONGARCH_CSR_CPUID) -#define read_csr_prcfg1() csr_read64(LOONGARCH_CSR_PRCFG1) -#define write_csr_prcfg1(val) csr_write64(val, LOONGARCH_CSR_PRCFG1) -#define read_csr_prcfg2() csr_read64(LOONGARCH_CSR_PRCFG2) -#define write_csr_prcfg2(val) csr_write64(val, LOONGARCH_CSR_PRCFG2) -#define read_csr_prcfg3() csr_read64(LOONGARCH_CSR_PRCFG3) -#define write_csr_prcfg3(val) csr_write64(val, LOONGARCH_CSR_PRCFG3) +#define read_csr_prcfg1() csr_read(LOONGARCH_CSR_PRCFG1) +#define write_csr_prcfg1(val) csr_write(val, LOONGARCH_CSR_PRCFG1) +#define read_csr_prcfg2() csr_read(LOONGARCH_CSR_PRCFG2) +#define write_csr_prcfg2(val) csr_write(val, LOONGARCH_CSR_PRCFG2) +#define read_csr_prcfg3() csr_read(LOONGARCH_CSR_PRCFG3) +#define write_csr_prcfg3(val) csr_write(val, LOONGARCH_CSR_PRCFG3) #define read_csr_stlbpgsize() csr_read32(LOONGARCH_CSR_STLBPGSIZE) #define write_csr_stlbpgsize(val) csr_write32(val, LOONGARCH_CSR_STLBPGSIZE) #define read_csr_rvacfg() csr_read32(LOONGARCH_CSR_RVACFG) #define write_csr_rvacfg(val) csr_write32(val, LOONGARCH_CSR_RVACFG) #define write_csr_tintclear(val) csr_write32(val, LOONGARCH_CSR_TINTCLR) -#define read_csr_impctl1() csr_read64(LOONGARCH_CSR_IMPCTL1) -#define write_csr_impctl1(val) csr_write64(val, LOONGARCH_CSR_IMPCTL1) -#define write_csr_impctl2(val) csr_write64(val, LOONGARCH_CSR_IMPCTL2) +#define read_csr_impctl1() csr_read(LOONGARCH_CSR_IMPCTL1) +#define write_csr_impctl1(val) csr_write(val, LOONGARCH_CSR_IMPCTL1) +#define write_csr_impctl2(val) csr_write(val, LOONGARCH_CSR_IMPCTL2) #define read_csr_perfctrl0() csr_read64(LOONGARCH_CSR_PERFCTRL0) #define read_csr_perfcntr0() csr_read64(LOONGARCH_CSR_PERFCNTR0) @@ -1376,8 +1442,10 @@ __BUILD_CSR_OP(tlbidx) #define ENTRYLO_C_SHIFT 4 #define ENTRYLO_C (_ULCAST_(3) << ENTRYLO_C_SHIFT) #define ENTRYLO_G (_ULCAST_(1) << 6) +#ifdef CONFIG_64BIT #define ENTRYLO_NR (_ULCAST_(1) << 61) #define ENTRYLO_NX (_ULCAST_(1) << 62) +#endif /* Values for PageSize register */ #define PS_4K 0x0000000c diff --git a/arch/loongarch/include/asm/module.h b/arch/loongarch/include/asm/module.h index f33f3fd32ecc2..d56a968273dee 100644 --- a/arch/loongarch/include/asm/module.h +++ b/arch/loongarch/include/asm/module.h @@ -38,8 +38,10 @@ struct got_entry { struct plt_entry { u32 inst_lu12iw; +#ifdef CONFIG_64BIT u32 inst_lu32id; u32 inst_lu52id; +#endif u32 inst_jirl; }; @@ -57,6 +59,14 @@ static inline struct got_entry emit_got_entry(Elf_Addr val) static inline struct plt_entry emit_plt_entry(unsigned long val) { +#ifdef CONFIG_32BIT + u32 lu12iw, jirl; + + lu12iw = larch_insn_gen_lu12iw(LOONGARCH_GPR_T1, ADDR_IMM(val, LU12IW)); + jirl = larch_insn_gen_jirl(0, LOONGARCH_GPR_T1, ADDR_IMM(val, ORI)); + + return (struct plt_entry) { lu12iw, jirl }; +#else u32 lu12iw, lu32id, lu52id, jirl; lu12iw = larch_insn_gen_lu12iw(LOONGARCH_GPR_T1, ADDR_IMM(val, LU12IW)); @@ -65,6 +75,7 @@ static inline struct plt_entry emit_plt_entry(unsigned long val) jirl = larch_insn_gen_jirl(0, LOONGARCH_GPR_T1, ADDR_IMM(val, ORI)); return (struct plt_entry) { lu12iw, lu32id, lu52id, jirl }; +#endif } static inline struct plt_idx_entry emit_plt_idx_entry(unsigned long val) diff --git a/arch/loongarch/include/asm/page.h b/arch/loongarch/include/asm/page.h index a3aaf34fba16a..256d1ff7a1e36 100644 --- a/arch/loongarch/include/asm/page.h +++ b/arch/loongarch/include/asm/page.h @@ -10,7 +10,7 @@ #include -#define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) +#define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - PTRLOG) #define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) #define HPAGE_MASK (~(HPAGE_SIZE - 1)) #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) diff --git a/arch/loongarch/include/asm/percpu.h b/arch/loongarch/include/asm/percpu.h index 87be9b14e9dab..583f2466262fc 100644 --- a/arch/loongarch/include/asm/percpu.h +++ b/arch/loongarch/include/asm/percpu.h @@ -13,7 +13,7 @@ * the loading address of main kernel image, but far from where the modules are * loaded. Tell the compiler this fact when using explicit relocs. */ -#if defined(MODULE) && defined(CONFIG_AS_HAS_EXPLICIT_RELOCS) +#if defined(MODULE) && defined(CONFIG_AS_HAS_EXPLICIT_RELOCS) && defined(CONFIG_64BIT) # if __has_attribute(model) # define PER_CPU_ATTRIBUTES __attribute__((model("extreme"))) # else @@ -27,7 +27,7 @@ register unsigned long __my_cpu_offset __asm__("$r21"); static inline void set_my_cpu_offset(unsigned long off) { __my_cpu_offset = off; - csr_write64(off, PERCPU_BASE_KS); + csr_write(off, PERCPU_BASE_KS); } #define __my_cpu_offset \ @@ -36,6 +36,8 @@ static inline void set_my_cpu_offset(unsigned long off) __my_cpu_offset; \ }) +#ifdef CONFIG_CPU_HAS_AMO + #define PERCPU_OP(op, asm_op, c_op) \ static __always_inline unsigned long __percpu_##op(void *ptr, \ unsigned long val, int size) \ @@ -68,25 +70,9 @@ PERCPU_OP(and, and, &) PERCPU_OP(or, or, |) #undef PERCPU_OP -static __always_inline unsigned long __percpu_xchg(void *ptr, unsigned long val, int size) -{ - switch (size) { - case 1: - case 2: - return __xchg_small((volatile void *)ptr, val, size); - - case 4: - return __xchg_asm("amswap.w", (volatile u32 *)ptr, (u32)val); - - case 8: - return __xchg_asm("amswap.d", (volatile u64 *)ptr, (u64)val); +#endif - default: - BUILD_BUG(); - } - - return 0; -} +#ifdef CONFIG_64BIT #define __pcpu_op_1(op) op ".b " #define __pcpu_op_2(op) op ".h " @@ -115,6 +101,10 @@ do { \ : "memory"); \ } while (0) +#endif + +#define __percpu_xchg __arch_xchg + /* this_cpu_cmpxchg */ #define _protect_cmpxchg_local(pcp, o, n) \ ({ \ @@ -135,6 +125,8 @@ do { \ __retval; \ }) +#ifdef CONFIG_CPU_HAS_AMO + #define _percpu_add(pcp, val) \ _pcp_protect(__percpu_add, pcp, val) @@ -146,9 +138,6 @@ do { \ #define _percpu_or(pcp, val) \ _pcp_protect(__percpu_or, pcp, val) -#define _percpu_xchg(pcp, val) ((typeof(pcp)) \ - _pcp_protect(__percpu_xchg, pcp, (unsigned long)(val))) - #define this_cpu_add_4(pcp, val) _percpu_add(pcp, val) #define this_cpu_add_8(pcp, val) _percpu_add(pcp, val) @@ -161,6 +150,10 @@ do { \ #define this_cpu_or_4(pcp, val) _percpu_or(pcp, val) #define this_cpu_or_8(pcp, val) _percpu_or(pcp, val) +#endif + +#ifdef CONFIG_64BIT + #define this_cpu_read_1(pcp) _percpu_read(1, pcp) #define this_cpu_read_2(pcp) _percpu_read(2, pcp) #define this_cpu_read_4(pcp) _percpu_read(4, pcp) @@ -171,6 +164,11 @@ do { \ #define this_cpu_write_4(pcp, val) _percpu_write(4, pcp, val) #define this_cpu_write_8(pcp, val) _percpu_write(8, pcp, val) +#endif + +#define _percpu_xchg(pcp, val) ((typeof(pcp)) \ + _pcp_protect(__percpu_xchg, pcp, (unsigned long)(val))) + #define this_cpu_xchg_1(pcp, val) _percpu_xchg(pcp, val) #define this_cpu_xchg_2(pcp, val) _percpu_xchg(pcp, val) #define this_cpu_xchg_4(pcp, val) _percpu_xchg(pcp, val) diff --git a/arch/loongarch/include/asm/pgtable-bits.h b/arch/loongarch/include/asm/pgtable-bits.h index 2fc3789220ac6..b565573cd82ee 100644 --- a/arch/loongarch/include/asm/pgtable-bits.h +++ b/arch/loongarch/include/asm/pgtable-bits.h @@ -6,6 +6,26 @@ #define _ASM_PGTABLE_BITS_H /* Page table bits */ + +#ifdef CONFIG_32BIT +#define _PAGE_VALID_SHIFT 0 +#define _PAGE_ACCESSED_SHIFT 0 /* Reuse Valid for Accessed */ +#define _PAGE_DIRTY_SHIFT 1 +#define _PAGE_PLV_SHIFT 2 /* 2~3, two bits */ +#define _CACHE_SHIFT 4 /* 4~5, two bits */ +#define _PAGE_GLOBAL_SHIFT 6 +#define _PAGE_HUGE_SHIFT 6 /* HUGE is a PMD bit */ +#define _PAGE_PRESENT_SHIFT 7 +#define _PAGE_PFN_SHIFT 8 +#define _PAGE_HGLOBAL_SHIFT 12 /* HGlobal is a PMD bit */ +#define _PAGE_SWP_EXCLUSIVE_SHIFT 13 +#define _PAGE_PFN_END_SHIFT 28 +#define _PAGE_WRITE_SHIFT 29 +#define _PAGE_MODIFIED_SHIFT 30 +#define _PAGE_PRESENT_INVALID_SHIFT 31 +#endif + +#ifdef CONFIG_64BIT #define _PAGE_VALID_SHIFT 0 #define _PAGE_ACCESSED_SHIFT 0 /* Reuse Valid for Accessed */ #define _PAGE_DIRTY_SHIFT 1 @@ -18,14 +38,15 @@ #define _PAGE_MODIFIED_SHIFT 9 #define _PAGE_PROTNONE_SHIFT 10 #define _PAGE_SPECIAL_SHIFT 11 -#define _PAGE_HGLOBAL_SHIFT 12 /* HGlobal is a PMD bit */ #define _PAGE_PFN_SHIFT 12 +#define _PAGE_HGLOBAL_SHIFT 12 /* HGlobal is a PMD bit */ #define _PAGE_SWP_EXCLUSIVE_SHIFT 23 #define _PAGE_PFN_END_SHIFT 48 #define _PAGE_PRESENT_INVALID_SHIFT 60 #define _PAGE_NO_READ_SHIFT 61 #define _PAGE_NO_EXEC_SHIFT 62 #define _PAGE_RPLV_SHIFT 63 +#endif /* Used by software */ #define _PAGE_PRESENT (_ULCAST_(1) << _PAGE_PRESENT_SHIFT) @@ -33,10 +54,15 @@ #define _PAGE_WRITE (_ULCAST_(1) << _PAGE_WRITE_SHIFT) #define _PAGE_ACCESSED (_ULCAST_(1) << _PAGE_ACCESSED_SHIFT) #define _PAGE_MODIFIED (_ULCAST_(1) << _PAGE_MODIFIED_SHIFT) +#ifdef CONFIG_32BIT +#define _PAGE_PROTNONE 0 +#define _PAGE_SPECIAL 0 +#else #define _PAGE_PROTNONE (_ULCAST_(1) << _PAGE_PROTNONE_SHIFT) #define _PAGE_SPECIAL (_ULCAST_(1) << _PAGE_SPECIAL_SHIFT) +#endif -/* We borrow bit 23 to store the exclusive marker in swap PTEs. */ +/* We borrow bit 13/23 to store the exclusive marker in swap PTEs. */ #define _PAGE_SWP_EXCLUSIVE (_ULCAST_(1) << _PAGE_SWP_EXCLUSIVE_SHIFT) /* Used by TLB hardware (placed in EntryLo*) */ @@ -46,9 +72,15 @@ #define _PAGE_GLOBAL (_ULCAST_(1) << _PAGE_GLOBAL_SHIFT) #define _PAGE_HUGE (_ULCAST_(1) << _PAGE_HUGE_SHIFT) #define _PAGE_HGLOBAL (_ULCAST_(1) << _PAGE_HGLOBAL_SHIFT) +#ifdef CONFIG_32BIT +#define _PAGE_NO_READ 0 +#define _PAGE_NO_EXEC 0 +#define _PAGE_RPLV 0 +#else #define _PAGE_NO_READ (_ULCAST_(1) << _PAGE_NO_READ_SHIFT) #define _PAGE_NO_EXEC (_ULCAST_(1) << _PAGE_NO_EXEC_SHIFT) #define _PAGE_RPLV (_ULCAST_(1) << _PAGE_RPLV_SHIFT) +#endif #define _CACHE_MASK (_ULCAST_(3) << _CACHE_SHIFT) #define PFN_PTE_SHIFT (PAGE_SHIFT - 12 + _PAGE_PFN_SHIFT) diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h index 03fb60432fde7..f41a648a3d9e2 100644 --- a/arch/loongarch/include/asm/pgtable.h +++ b/arch/loongarch/include/asm/pgtable.h @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -23,37 +24,45 @@ #endif #if CONFIG_PGTABLE_LEVELS == 2 -#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3)) +#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTRLOG)) #elif CONFIG_PGTABLE_LEVELS == 3 -#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3)) +#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTRLOG)) #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -#define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT - 3)) +#define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT - PTRLOG)) #elif CONFIG_PGTABLE_LEVELS == 4 -#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3)) +#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTRLOG)) #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -#define PUD_SHIFT (PMD_SHIFT + (PAGE_SHIFT - 3)) +#define PUD_SHIFT (PMD_SHIFT + (PAGE_SHIFT - PTRLOG)) #define PUD_SIZE (1UL << PUD_SHIFT) #define PUD_MASK (~(PUD_SIZE-1)) -#define PGDIR_SHIFT (PUD_SHIFT + (PAGE_SHIFT - 3)) +#define PGDIR_SHIFT (PUD_SHIFT + (PAGE_SHIFT - PTRLOG)) #endif #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -#define VA_BITS (PGDIR_SHIFT + (PAGE_SHIFT - 3)) +#ifdef CONFIG_32BIT +#define VA_BITS 32 +#else +#define VA_BITS (PGDIR_SHIFT + (PAGE_SHIFT - PTRLOG)) +#endif -#define PTRS_PER_PGD (PAGE_SIZE >> 3) +#define PTRS_PER_PGD (PAGE_SIZE >> PTRLOG) #if CONFIG_PGTABLE_LEVELS > 3 -#define PTRS_PER_PUD (PAGE_SIZE >> 3) +#define PTRS_PER_PUD (PAGE_SIZE >> PTRLOG) #endif #if CONFIG_PGTABLE_LEVELS > 2 -#define PTRS_PER_PMD (PAGE_SIZE >> 3) +#define PTRS_PER_PMD (PAGE_SIZE >> PTRLOG) #endif -#define PTRS_PER_PTE (PAGE_SIZE >> 3) +#define PTRS_PER_PTE (PAGE_SIZE >> PTRLOG) +#ifdef CONFIG_32BIT +#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) +#else #define USER_PTRS_PER_PGD ((TASK_SIZE64 / PGDIR_SIZE)?(TASK_SIZE64 / PGDIR_SIZE):1) +#endif #ifndef __ASSEMBLER__ @@ -74,11 +83,15 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) -/* - * TLB refill handlers may also map the vmalloc area into xkvrange. - * Avoid the first couple of pages so NULL pointer dereferences will - * still reliably trap. - */ +#ifdef CONFIG_32BIT + +#define VMALLOC_START (vm_map_base + PCI_IOSIZE + (2 * PAGE_SIZE)) +#define VMALLOC_END (FIXADDR_START - (2 * PAGE_SIZE)) + +#endif + +#ifdef CONFIG_64BIT + #define MODULES_VADDR (vm_map_base + PCI_IOSIZE + (2 * PAGE_SIZE)) #define MODULES_END (MODULES_VADDR + SZ_256M) @@ -106,6 +119,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define KFENCE_AREA_START (VMEMMAP_END + 1) #define KFENCE_AREA_END (KFENCE_AREA_START + KFENCE_AREA_SIZE - 1) +#endif + #define ptep_get(ptep) READ_ONCE(*(ptep)) #define pmdp_get(pmdp) READ_ONCE(*(pmdp)) @@ -277,7 +292,16 @@ extern void kernel_pte_init(void *addr); * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that * are !pte_none() && !pte_present(). * - * Format of swap PTEs: + * Format of 32bit swap PTEs: + * + * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * <------------ offset -------------> E <- type -> <-- zeroes --> + * + * E is the exclusive marker that is not stored in swap entries. + * The zero'ed bits include _PAGE_PRESENT. + * + * Format of 64bit swap PTEs: * * 6 6 6 6 5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 4 4 4 3 3 3 3 3 3 3 3 * 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 @@ -290,16 +314,27 @@ extern void kernel_pte_init(void *addr); * E is the exclusive marker that is not stored in swap entries. * The zero'ed bits include _PAGE_PRESENT and _PAGE_PROTNONE. */ + +#define __SWP_TYPE_BITS (IS_ENABLED(CONFIG_32BIT) ? 5 : 7) +#define __SWP_TYPE_MASK ((1UL << __SWP_TYPE_BITS) - 1) +#define __SWP_TYPE_SHIFT (IS_ENABLED(CONFIG_32BIT) ? 8 : 16) +#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT + 1) + static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) -{ pte_t pte; pte_val(pte) = ((type & 0x7f) << 16) | (offset << 24); return pte; } +{ + pte_t pte; + pte_val(pte) = ((type & __SWP_TYPE_MASK) << __SWP_TYPE_SHIFT) | (offset << __SWP_OFFSET_SHIFT); + return pte; +} -#define __swp_type(x) (((x).val >> 16) & 0x7f) -#define __swp_offset(x) ((x).val >> 24) +#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK) +#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT) #define __swp_entry(type, offset) ((swp_entry_t) { pte_val(mk_swap_pte((type), (offset))) }) + +#define __swp_entry_to_pte(x) __pte((x).val) +#define __swp_entry_to_pmd(x) __pmd((x).val | _PAGE_HUGE) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) #define __pmd_to_swp_entry(pmd) ((swp_entry_t) { pmd_val(pmd) }) -#define __swp_entry_to_pmd(x) ((pmd_t) { (x).val | _PAGE_HUGE }) static inline bool pte_swp_exclusive(pte_t pte) { diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h index 5cb568a60cf8e..ecc8e50fffa87 100644 --- a/arch/loongarch/include/asm/stackframe.h +++ b/arch/loongarch/include/asm/stackframe.h @@ -38,22 +38,42 @@ cfi_restore \reg \offset \docfi .endm + .macro SETUP_TWINS temp + pcaddi t0, 0 + PTR_LI t1, ~TO_PHYS_MASK + and t0, t0, t1 + ori t0, t0, (1 << 4 | 1) + csrwr t0, LOONGARCH_CSR_DMWIN0 + PTR_LI t0, CSR_DMW1_INIT + csrwr t0, LOONGARCH_CSR_DMWIN1 + .endm + + .macro SETUP_MODES temp + /* Enable PG */ + li.w \temp, 0xb0 # PLV=0, IE=0, PG=1 + csrwr \temp, LOONGARCH_CSR_CRMD + li.w \temp, 0x04 # PLV=0, PIE=1, PWE=0 + csrwr \temp, LOONGARCH_CSR_PRMD + li.w \temp, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0 + csrwr \temp, LOONGARCH_CSR_EUEN + .endm + .macro SETUP_DMWINS temp - li.d \temp, CSR_DMW0_INIT # WUC, PLV0, 0x8000 xxxx xxxx xxxx + PTR_LI \temp, CSR_DMW0_INIT # SUC, PLV0, LA32: 0x8xxx xxxx, LA64: 0x8000 xxxx xxxx xxxx csrwr \temp, LOONGARCH_CSR_DMWIN0 - li.d \temp, CSR_DMW1_INIT # CAC, PLV0, 0x9000 xxxx xxxx xxxx + PTR_LI \temp, CSR_DMW1_INIT # CAC, PLV0, LA32: 0xaxxx xxxx, LA64: 0x9000 xxxx xxxx xxxx csrwr \temp, LOONGARCH_CSR_DMWIN1 - li.d \temp, CSR_DMW2_INIT # WUC, PLV0, 0xa000 xxxx xxxx xxxx + PTR_LI \temp, CSR_DMW2_INIT # WUC, PLV0, LA32: unavailable, LA64: 0xa000 xxxx xxxx xxxx csrwr \temp, LOONGARCH_CSR_DMWIN2 - li.d \temp, CSR_DMW3_INIT # 0x0, unused + PTR_LI \temp, CSR_DMW3_INIT # 0x0, unused csrwr \temp, LOONGARCH_CSR_DMWIN3 .endm /* Jump to the runtime virtual address. */ .macro JUMP_VIRT_ADDR temp1 temp2 - li.d \temp1, CACHE_BASE + PTR_LI \temp1, CACHE_BASE pcaddi \temp2, 0 - bstrins.d \temp1, \temp2, (DMW_PABITS - 1), 0 + PTR_BSTRINS \temp1, \temp2, (DMW_PABITS - 1), 0 jirl zero, \temp1, 0xc .endm @@ -171,7 +191,7 @@ andi t0, t0, 0x3 /* extract pplv bit */ beqz t0, 9f - li.d tp, ~_THREAD_MASK + LONG_LI tp, ~_THREAD_MASK and tp, tp, sp cfi_st u0, PT_R21, \docfi csrrd u0, PERCPU_BASE_KS diff --git a/arch/loongarch/include/asm/string.h b/arch/loongarch/include/asm/string.h index 5bb5a90d26815..bfa3fd879c7f3 100644 --- a/arch/loongarch/include/asm/string.h +++ b/arch/loongarch/include/asm/string.h @@ -5,6 +5,7 @@ #ifndef _ASM_STRING_H #define _ASM_STRING_H +#ifdef CONFIG_64BIT #define __HAVE_ARCH_MEMSET extern void *memset(void *__s, int __c, size_t __count); extern void *__memset(void *__s, int __c, size_t __count); @@ -16,6 +17,7 @@ extern void *__memcpy(void *__to, __const__ void *__from, size_t __n); #define __HAVE_ARCH_MEMMOVE extern void *memmove(void *__dest, __const__ void *__src, size_t __n); extern void *__memmove(void *__dest, __const__ void *__src, size_t __n); +#endif #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) diff --git a/arch/loongarch/include/asm/timex.h b/arch/loongarch/include/asm/timex.h index fb41e9e7a222c..9ea52fad96903 100644 --- a/arch/loongarch/include/asm/timex.h +++ b/arch/loongarch/include/asm/timex.h @@ -18,7 +18,38 @@ typedef unsigned long cycles_t; static inline cycles_t get_cycles(void) { - return drdtime(); +#ifdef CONFIG_32BIT + return rdtime_l(); +#else + return rdtime_d(); +#endif +} + +#ifdef CONFIG_32BIT + +#define get_cycles_hi get_cycles_hi + +static inline cycles_t get_cycles_hi(void) +{ + return rdtime_h(); +} + +#endif + +static inline u64 get_cycles64(void) +{ +#ifdef CONFIG_32BIT + u32 hi, lo; + + do { + hi = rdtime_h(); + lo = rdtime_l(); + } while (hi != rdtime_h()); + + return ((u64)hi << 32) | lo; +#else + return rdtime_d(); +#endif } #endif /* __KERNEL__ */ diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h index 0d22991ae430d..4e259d490e456 100644 --- a/arch/loongarch/include/asm/uaccess.h +++ b/arch/loongarch/include/asm/uaccess.h @@ -19,10 +19,16 @@ #include #include +#define __LSW 0 +#define __MSW 1 + extern u64 __ua_limit; -#define __UA_ADDR ".dword" +#ifdef CONFIG_64BIT #define __UA_LIMIT __ua_limit +#else +#define __UA_LIMIT 0x80000000UL +#endif /* * get_user: - Get a simple variable from user space. @@ -126,6 +132,7 @@ extern u64 __ua_limit; * * Returns zero on success, or -EFAULT on error. */ + #define __put_user(x, ptr) \ ({ \ int __pu_err = 0; \ @@ -146,7 +153,7 @@ do { \ case 1: __get_data_asm(val, "ld.b", ptr); break; \ case 2: __get_data_asm(val, "ld.h", ptr); break; \ case 4: __get_data_asm(val, "ld.w", ptr); break; \ - case 8: __get_data_asm(val, "ld.d", ptr); break; \ + case 8: __get_data_asm_8(val, ptr); break; \ default: BUILD_BUG(); break; \ } \ } while (0) @@ -167,13 +174,39 @@ do { \ (val) = (__typeof__(*(ptr))) __gu_tmp; \ } +#ifdef CONFIG_64BIT +#define __get_data_asm_8(val, ptr) \ + __get_data_asm(val, "ld.d", ptr) +#else /* !CONFIG_64BIT */ +#define __get_data_asm_8(val, ptr) \ +{ \ + u32 __lo, __hi; \ + u32 __user *__ptr = (u32 __user *)(ptr); \ + \ + __asm__ __volatile__ ( \ + "1:\n" \ + " ld.w %1, %3 \n" \ + "2:\n" \ + " ld.w %2, %4 \n" \ + "3:\n" \ + _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 3b, %0, %1) \ + _ASM_EXTABLE_UACCESS_ERR_ZERO(2b, 3b, %0, %1) \ + : "+r" (__gu_err), "=&r" (__lo), "=r" (__hi) \ + : "m" (__ptr[__LSW]), "m" (__ptr[__MSW])); \ + if (__gu_err) \ + __hi = 0; \ + (val) = (__typeof__(val))((__typeof__((val)-(val))) \ + ((((u64)__hi << 32) | __lo))); \ +} +#endif /* CONFIG_64BIT */ + #define __put_user_common(ptr, size) \ do { \ switch (size) { \ case 1: __put_data_asm("st.b", ptr); break; \ case 2: __put_data_asm("st.h", ptr); break; \ case 4: __put_data_asm("st.w", ptr); break; \ - case 8: __put_data_asm("st.d", ptr); break; \ + case 8: __put_data_asm_8(ptr); break; \ default: BUILD_BUG(); break; \ } \ } while (0) @@ -190,6 +223,30 @@ do { \ : "Jr" (__pu_val)); \ } +#ifdef CONFIG_64BIT +#define __put_data_asm_8(ptr) \ + __put_data_asm("st.d", ptr) +#else /* !CONFIG_64BIT */ +#define __put_data_asm_8(ptr) \ +{ \ + u32 __user *__ptr = (u32 __user *)(ptr); \ + u64 __x = (__typeof__((__pu_val)-(__pu_val)))(__pu_val); \ + \ + __asm__ __volatile__ ( \ + "1:\n" \ + " st.w %z3, %1 \n" \ + "2:\n" \ + " st.w %z4, %2 \n" \ + "3:\n" \ + _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0) \ + _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0) \ + : "+r" (__pu_err), \ + "=m" (__ptr[__LSW]), \ + "=m" (__ptr[__MSW]) \ + : "rJ" (__x), "rJ" (__x >> 32)); \ +} +#endif /* CONFIG_64BIT */ + #define __get_kernel_nofault(dst, src, type, err_label) \ do { \ int __gu_err = 0; \ diff --git a/arch/loongarch/include/asm/vdso/gettimeofday.h b/arch/loongarch/include/asm/vdso/gettimeofday.h index dcafabca9bb69..bae76767c693a 100644 --- a/arch/loongarch/include/asm/vdso/gettimeofday.h +++ b/arch/loongarch/include/asm/vdso/gettimeofday.h @@ -12,6 +12,8 @@ #include #include +#ifdef CONFIG_GENERIC_GETTIMEOFDAY + #define VDSO_HAS_CLOCK_GETRES 1 static __always_inline long gettimeofday_fallback( @@ -89,6 +91,8 @@ static inline bool loongarch_vdso_hres_capable(void) } #define __arch_vdso_hres_capable loongarch_vdso_hres_capable +#endif /* CONFIG_GENERIC_GETTIMEOFDAY */ + #endif /* !__ASSEMBLER__ */ #endif /* __ASM_VDSO_GETTIMEOFDAY_H */ diff --git a/arch/loongarch/include/uapi/asm/Kbuild b/arch/loongarch/include/uapi/asm/Kbuild index 517761419999a..89ac01faa5aef 100644 --- a/arch/loongarch/include/uapi/asm/Kbuild +++ b/arch/loongarch/include/uapi/asm/Kbuild @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 +syscall-y += unistd_32.h syscall-y += unistd_64.h diff --git a/arch/loongarch/include/uapi/asm/kvm.h b/arch/loongarch/include/uapi/asm/kvm.h index 57ba1a563bb1a..de6c3f18e40ab 100644 --- a/arch/loongarch/include/uapi/asm/kvm.h +++ b/arch/loongarch/include/uapi/asm/kvm.h @@ -104,6 +104,7 @@ struct kvm_fpu { #define KVM_LOONGARCH_VM_FEAT_PV_IPI 6 #define KVM_LOONGARCH_VM_FEAT_PV_STEALTIME 7 #define KVM_LOONGARCH_VM_FEAT_PTW 8 +#define KVM_LOONGARCH_VM_FEAT_MSGINT 9 /* Device Control API on vcpu fd */ #define KVM_LOONGARCH_VCPU_CPUCFG 0 diff --git a/arch/loongarch/include/uapi/asm/ptrace.h b/arch/loongarch/include/uapi/asm/ptrace.h index 215e0f9e8aa32..b35c794323bca 100644 --- a/arch/loongarch/include/uapi/asm/ptrace.h +++ b/arch/loongarch/include/uapi/asm/ptrace.h @@ -61,8 +61,13 @@ struct user_lbt_state { struct user_watch_state { __u64 dbg_info; struct { +#if __BITS_PER_LONG == 32 + __u32 addr; + __u32 mask; +#else __u64 addr; __u64 mask; +#endif __u32 ctrl; __u32 pad; } dbg_regs[8]; @@ -71,8 +76,13 @@ struct user_watch_state { struct user_watch_state_v2 { __u64 dbg_info; struct { +#if __BITS_PER_LONG == 32 + __u32 addr; + __u32 mask; +#else __u64 addr; __u64 mask; +#endif __u32 ctrl; __u32 pad; } dbg_regs[14]; diff --git a/arch/loongarch/include/uapi/asm/unistd.h b/arch/loongarch/include/uapi/asm/unistd.h index 1f01980f9c948..e19c7f2f9f87a 100644 --- a/arch/loongarch/include/uapi/asm/unistd.h +++ b/arch/loongarch/include/uapi/asm/unistd.h @@ -1,3 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#include + +#if __BITS_PER_LONG == 32 +#include +#else #include +#endif diff --git a/arch/loongarch/kernel/Makefile.syscalls b/arch/loongarch/kernel/Makefile.syscalls index ab7d9baa29152..cd46c2b69c7fd 100644 --- a/arch/loongarch/kernel/Makefile.syscalls +++ b/arch/loongarch/kernel/Makefile.syscalls @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 # No special ABIs on loongarch so far +syscall_abis_32 += syscall_abis_64 += diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c index a2060a24b39fd..08a227034042d 100644 --- a/arch/loongarch/kernel/cpu-probe.c +++ b/arch/loongarch/kernel/cpu-probe.c @@ -106,7 +106,11 @@ EXPORT_SYMBOL(vm_map_base); static void cpu_probe_addrbits(struct cpuinfo_loongarch *c) { -#ifdef __NEED_ADDRBITS_PROBE +#ifdef CONFIG_32BIT + c->pabits = cpu_pabits; + c->vabits = cpu_vabits; + vm_map_base = KVRANGE; +#else c->pabits = (read_cpucfg(LOONGARCH_CPUCFG1) & CPUCFG1_PABITS) >> 4; c->vabits = (read_cpucfg(LOONGARCH_CPUCFG1) & CPUCFG1_VABITS) >> 12; vm_map_base = 0UL - (1UL << c->vabits); @@ -298,8 +302,15 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int return; } +#ifdef CONFIG_64BIT *vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR); *cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME); +#else + *vendor = iocsr_read32(LOONGARCH_IOCSR_VENDOR) | + (u64)iocsr_read32(LOONGARCH_IOCSR_VENDOR + 4) << 32; + *cpuname = iocsr_read32(LOONGARCH_IOCSR_CPUNAME) | + (u64)iocsr_read32(LOONGARCH_IOCSR_CPUNAME + 4) << 32; +#endif if (!__cpu_full_name[cpu]) { if (((char *)vendor)[0] == 0) diff --git a/arch/loongarch/kernel/efi-header.S b/arch/loongarch/kernel/efi-header.S index ba0bdbf86aa85..6df56241cb95a 100644 --- a/arch/loongarch/kernel/efi-header.S +++ b/arch/loongarch/kernel/efi-header.S @@ -9,7 +9,11 @@ .macro __EFI_PE_HEADER .long IMAGE_NT_SIGNATURE .Lcoff_header: +#ifdef CONFIG_32BIT + .short IMAGE_FILE_MACHINE_LOONGARCH32 /* Machine */ +#else .short IMAGE_FILE_MACHINE_LOONGARCH64 /* Machine */ +#endif .short .Lsection_count /* NumberOfSections */ .long 0 /* TimeDateStamp */ .long 0 /* PointerToSymbolTable */ diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 860a3bc030e06..52c21c8953189 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -115,7 +115,9 @@ void __init efi_init(void) efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor); - set_bit(EFI_64BIT, &efi.flags); + if (IS_ENABLED(CONFIG_64BIT)) + set_bit(EFI_64BIT, &efi.flags); + efi_nr_tables = efi_systab->nr_tables; efi_config_table = (unsigned long)efi_systab->tables; diff --git a/arch/loongarch/kernel/entry.S b/arch/loongarch/kernel/entry.S index 47e1db9a1ce47..b53d333a7c427 100644 --- a/arch/loongarch/kernel/entry.S +++ b/arch/loongarch/kernel/entry.S @@ -23,24 +23,24 @@ SYM_CODE_START(handle_syscall) UNWIND_HINT_UNDEFINED csrrd t0, PERCPU_BASE_KS la.pcrel t1, kernelsp - add.d t1, t1, t0 + PTR_ADD t1, t1, t0 move t2, sp - ld.d sp, t1, 0 + PTR_L sp, t1, 0 - addi.d sp, sp, -PT_SIZE + PTR_ADDI sp, sp, -PT_SIZE cfi_st t2, PT_R3 cfi_rel_offset sp, PT_R3 - st.d zero, sp, PT_R0 + LONG_S zero, sp, PT_R0 csrrd t2, LOONGARCH_CSR_PRMD - st.d t2, sp, PT_PRMD + LONG_S t2, sp, PT_PRMD csrrd t2, LOONGARCH_CSR_CRMD - st.d t2, sp, PT_CRMD + LONG_S t2, sp, PT_CRMD csrrd t2, LOONGARCH_CSR_EUEN - st.d t2, sp, PT_EUEN + LONG_S t2, sp, PT_EUEN csrrd t2, LOONGARCH_CSR_ECFG - st.d t2, sp, PT_ECFG + LONG_S t2, sp, PT_ECFG csrrd t2, LOONGARCH_CSR_ESTAT - st.d t2, sp, PT_ESTAT + LONG_S t2, sp, PT_ESTAT cfi_st ra, PT_R1 cfi_st a0, PT_R4 cfi_st a1, PT_R5 @@ -51,7 +51,7 @@ SYM_CODE_START(handle_syscall) cfi_st a6, PT_R10 cfi_st a7, PT_R11 csrrd ra, LOONGARCH_CSR_ERA - st.d ra, sp, PT_ERA + LONG_S ra, sp, PT_ERA cfi_rel_offset ra, PT_ERA cfi_st tp, PT_R2 @@ -67,7 +67,7 @@ SYM_CODE_START(handle_syscall) #endif move u0, t0 - li.d tp, ~_THREAD_MASK + LONG_LI tp, ~_THREAD_MASK and tp, tp, sp move a0, sp diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c index 23bd5ae2212c2..841206fde3ab7 100644 --- a/arch/loongarch/kernel/env.c +++ b/arch/loongarch/kernel/env.c @@ -72,9 +72,12 @@ static int __init fdt_cpu_clk_init(void) clk = of_clk_get(np, 0); of_node_put(np); + cpu_clock_freq = 200 * 1000 * 1000; - if (IS_ERR(clk)) + if (IS_ERR(clk)) { + pr_warn("No valid CPU clock freq, assume 200MHz.\n"); return -ENODEV; + } cpu_clock_freq = clk_get_rate(clk); clk_put(clk); diff --git a/arch/loongarch/kernel/fpu.S b/arch/loongarch/kernel/fpu.S index 28caf416ae36e..f225dcc5b530c 100644 --- a/arch/loongarch/kernel/fpu.S +++ b/arch/loongarch/kernel/fpu.S @@ -96,6 +96,49 @@ EX fld.d $f31, \base, (31 * FPU_REG_WIDTH) .endm +#ifdef CONFIG_32BIT + .macro sc_save_fcc thread tmp0 tmp1 + movcf2gr \tmp0, $fcc0 + move \tmp1, \tmp0 + movcf2gr \tmp0, $fcc1 + bstrins.w \tmp1, \tmp0, 15, 8 + movcf2gr \tmp0, $fcc2 + bstrins.w \tmp1, \tmp0, 23, 16 + movcf2gr \tmp0, $fcc3 + bstrins.w \tmp1, \tmp0, 31, 24 + EX st.w \tmp1, \thread, THREAD_FCC + movcf2gr \tmp0, $fcc4 + move \tmp1, \tmp0 + movcf2gr \tmp0, $fcc5 + bstrins.w \tmp1, \tmp0, 15, 8 + movcf2gr \tmp0, $fcc6 + bstrins.w \tmp1, \tmp0, 23, 16 + movcf2gr \tmp0, $fcc7 + bstrins.w \tmp1, \tmp0, 31, 24 + EX st.w \tmp1, \thread, (THREAD_FCC + 4) + .endm + + .macro sc_restore_fcc thread tmp0 tmp1 + EX ld.w \tmp0, \thread, THREAD_FCC + bstrpick.w \tmp1, \tmp0, 7, 0 + movgr2cf $fcc0, \tmp1 + bstrpick.w \tmp1, \tmp0, 15, 8 + movgr2cf $fcc1, \tmp1 + bstrpick.w \tmp1, \tmp0, 23, 16 + movgr2cf $fcc2, \tmp1 + bstrpick.w \tmp1, \tmp0, 31, 24 + movgr2cf $fcc3, \tmp1 + EX ld.w \tmp0, \thread, (THREAD_FCC + 4) + bstrpick.w \tmp1, \tmp0, 7, 0 + movgr2cf $fcc4, \tmp1 + bstrpick.w \tmp1, \tmp0, 15, 8 + movgr2cf $fcc5, \tmp1 + bstrpick.w \tmp1, \tmp0, 23, 16 + movgr2cf $fcc6, \tmp1 + bstrpick.w \tmp1, \tmp0, 31, 24 + movgr2cf $fcc7, \tmp1 + .endm +#else .macro sc_save_fcc base, tmp0, tmp1 movcf2gr \tmp0, $fcc0 move \tmp1, \tmp0 @@ -135,6 +178,7 @@ bstrpick.d \tmp1, \tmp0, 63, 56 movgr2cf $fcc7, \tmp1 .endm +#endif .macro sc_save_fcsr base, tmp0 movfcsr2gr \tmp0, fcsr0 @@ -410,6 +454,72 @@ SYM_FUNC_START(_init_fpu) li.w t1, -1 # SNaN +#ifdef CONFIG_32BIT + movgr2fr.w $f0, t1 + movgr2frh.w $f0, t1 + movgr2fr.w $f1, t1 + movgr2frh.w $f1, t1 + movgr2fr.w $f2, t1 + movgr2frh.w $f2, t1 + movgr2fr.w $f3, t1 + movgr2frh.w $f3, t1 + movgr2fr.w $f4, t1 + movgr2frh.w $f4, t1 + movgr2fr.w $f5, t1 + movgr2frh.w $f5, t1 + movgr2fr.w $f6, t1 + movgr2frh.w $f6, t1 + movgr2fr.w $f7, t1 + movgr2frh.w $f7, t1 + movgr2fr.w $f8, t1 + movgr2frh.w $f8, t1 + movgr2fr.w $f9, t1 + movgr2frh.w $f9, t1 + movgr2fr.w $f10, t1 + movgr2frh.w $f10, t1 + movgr2fr.w $f11, t1 + movgr2frh.w $f11, t1 + movgr2fr.w $f12, t1 + movgr2frh.w $f12, t1 + movgr2fr.w $f13, t1 + movgr2frh.w $f13, t1 + movgr2fr.w $f14, t1 + movgr2frh.w $f14, t1 + movgr2fr.w $f15, t1 + movgr2frh.w $f15, t1 + movgr2fr.w $f16, t1 + movgr2frh.w $f16, t1 + movgr2fr.w $f17, t1 + movgr2frh.w $f17, t1 + movgr2fr.w $f18, t1 + movgr2frh.w $f18, t1 + movgr2fr.w $f19, t1 + movgr2frh.w $f19, t1 + movgr2fr.w $f20, t1 + movgr2frh.w $f20, t1 + movgr2fr.w $f21, t1 + movgr2frh.w $f21, t1 + movgr2fr.w $f22, t1 + movgr2frh.w $f22, t1 + movgr2fr.w $f23, t1 + movgr2frh.w $f23, t1 + movgr2fr.w $f24, t1 + movgr2frh.w $f24, t1 + movgr2fr.w $f25, t1 + movgr2frh.w $f25, t1 + movgr2fr.w $f26, t1 + movgr2frh.w $f26, t1 + movgr2fr.w $f27, t1 + movgr2frh.w $f27, t1 + movgr2fr.w $f28, t1 + movgr2frh.w $f28, t1 + movgr2fr.w $f29, t1 + movgr2frh.w $f29, t1 + movgr2fr.w $f30, t1 + movgr2frh.w $f30, t1 + movgr2fr.w $f31, t1 + movgr2frh.w $f31, t1 +#else movgr2fr.d $f0, t1 movgr2fr.d $f1, t1 movgr2fr.d $f2, t1 @@ -442,6 +552,7 @@ SYM_FUNC_START(_init_fpu) movgr2fr.d $f29, t1 movgr2fr.d $f30, t1 movgr2fr.d $f31, t1 +#endif jr ra SYM_FUNC_END(_init_fpu) diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S index e3865e92a917a..aba548db24460 100644 --- a/arch/loongarch/kernel/head.S +++ b/arch/loongarch/kernel/head.S @@ -43,36 +43,29 @@ SYM_DATA(kernel_fsize, .long _kernel_fsize); SYM_CODE_START(kernel_entry) # kernel entry point - /* Config direct window and set PG */ - SETUP_DMWINS t0 + SETUP_TWINS + SETUP_MODES t0 JUMP_VIRT_ADDR t0, t1 - - /* Enable PG */ - li.w t0, 0xb0 # PLV=0, IE=0, PG=1 - csrwr t0, LOONGARCH_CSR_CRMD - li.w t0, 0x04 # PLV=0, PIE=1, PWE=0 - csrwr t0, LOONGARCH_CSR_PRMD - li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0 - csrwr t0, LOONGARCH_CSR_EUEN + SETUP_DMWINS t0 la.pcrel t0, __bss_start # clear .bss - st.d zero, t0, 0 + LONG_S zero, t0, 0 la.pcrel t1, __bss_stop - LONGSIZE 1: - addi.d t0, t0, LONGSIZE - st.d zero, t0, 0 + PTR_ADDI t0, t0, LONGSIZE + LONG_S zero, t0, 0 bne t0, t1, 1b la.pcrel t0, fw_arg0 - st.d a0, t0, 0 # firmware arguments + PTR_S a0, t0, 0 # firmware arguments la.pcrel t0, fw_arg1 - st.d a1, t0, 0 + PTR_S a1, t0, 0 la.pcrel t0, fw_arg2 - st.d a2, t0, 0 + PTR_S a2, t0, 0 #ifdef CONFIG_PAGE_SIZE_4KB - li.d t0, 0 - li.d t1, CSR_STFILL + LONG_LI t0, 0 + LONG_LI t1, CSR_STFILL csrxchg t0, t1, LOONGARCH_CSR_IMPCTL1 #endif /* KSave3 used for percpu base, initialized as 0 */ @@ -98,7 +91,7 @@ SYM_CODE_START(kernel_entry) # kernel entry point /* Jump to the new kernel: new_pc = current_pc + random_offset */ pcaddi t0, 0 - add.d t0, t0, a0 + PTR_ADD t0, t0, a0 jirl zero, t0, 0xc #endif /* CONFIG_RANDOMIZE_BASE */ @@ -121,12 +114,14 @@ SYM_CODE_END(kernel_entry) */ SYM_CODE_START(smpboot_entry) - SETUP_DMWINS t0 + SETUP_TWINS + SETUP_MODES t0 JUMP_VIRT_ADDR t0, t1 + SETUP_DMWINS t0 #ifdef CONFIG_PAGE_SIZE_4KB - li.d t0, 0 - li.d t1, CSR_STFILL + LONG_LI t0, 0 + LONG_LI t1, CSR_STFILL csrxchg t0, t1, LOONGARCH_CSR_IMPCTL1 #endif /* Enable PG */ diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kernel/module-sections.c index a43ba7f9f9872..9fa1c9814fcc2 100644 --- a/arch/loongarch/kernel/module-sections.c +++ b/arch/loongarch/kernel/module-sections.c @@ -93,6 +93,7 @@ static void count_max_entries(Elf_Rela *relas, int num, (*plts)++; break; case R_LARCH_GOT_PC_HI20: + case R_LARCH_GOT_PCADD_HI20: (*gots)++; break; default: diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c index 36d6d9eeb7c72..7d4d571ee55e9 100644 --- a/arch/loongarch/kernel/module.c +++ b/arch/loongarch/kernel/module.c @@ -22,72 +22,89 @@ #include #include -static int rela_stack_push(s64 stack_value, s64 *rela_stack, size_t *rela_stack_top) +/* + * reloc_rela_handler() - Apply a particular relocation to a module + * @mod: the module to apply the reloc to + * @location: the address at which the reloc is to be applied + * @v: the value of the reloc, with addend for RELA-style + * @rela_stack: the stack used for store relocation info, LOCAL to THIS module + * @rela_stac_top: where the stack operation(pop/push) applies to + * + * Return: 0 upon success, else -ERRNO + */ +typedef int (*reloc_rela_handler)(struct module *mod, u32 *location, Elf_Addr v, + long *rela_stack, size_t *rela_stack_top, unsigned int type); + +static int rela_stack_push(long stack_value, long *rela_stack, size_t *rela_stack_top) { if (*rela_stack_top >= RELA_STACK_DEPTH) return -ENOEXEC; rela_stack[(*rela_stack_top)++] = stack_value; - pr_debug("%s stack_value = 0x%llx\n", __func__, stack_value); + pr_debug("%s stack_value = 0x%lx\n", __func__, stack_value); return 0; } -static int rela_stack_pop(s64 *stack_value, s64 *rela_stack, size_t *rela_stack_top) +static int rela_stack_pop(long *stack_value, long *rela_stack, size_t *rela_stack_top) { if (*rela_stack_top == 0) return -ENOEXEC; *stack_value = rela_stack[--(*rela_stack_top)]; - pr_debug("%s stack_value = 0x%llx\n", __func__, *stack_value); + pr_debug("%s stack_value = 0x%lx\n", __func__, *stack_value); return 0; } static int apply_r_larch_none(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { return 0; } static int apply_r_larch_error(struct module *me, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { pr_err("%s: Unsupport relocation type %u, please add its support.\n", me->name, type); return -EINVAL; } static int apply_r_larch_32(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { *location = v; return 0; } +#ifdef CONFIG_32BIT +#define apply_r_larch_64 apply_r_larch_error +#else static int apply_r_larch_64(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { *(Elf_Addr *)location = v; return 0; } +#endif static int apply_r_larch_sop_push_pcrel(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { - return rela_stack_push(v - (u64)location, rela_stack, rela_stack_top); + return rela_stack_push(v - (unsigned long)location, rela_stack, rela_stack_top); } static int apply_r_larch_sop_push_absolute(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { return rela_stack_push(v, rela_stack, rela_stack_top); } static int apply_r_larch_sop_push_dup(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { int err = 0; - s64 opr1; + long opr1; err = rela_stack_pop(&opr1, rela_stack, rela_stack_top); if (err) @@ -104,7 +121,7 @@ static int apply_r_larch_sop_push_dup(struct module *mod, u32 *location, Elf_Add static int apply_r_larch_sop_push_plt_pcrel(struct module *mod, Elf_Shdr *sechdrs, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { ptrdiff_t offset = (void *)v - (void *)location; @@ -118,10 +135,10 @@ static int apply_r_larch_sop_push_plt_pcrel(struct module *mod, } static int apply_r_larch_sop(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { int err = 0; - s64 opr1, opr2, opr3; + long opr1, opr2, opr3; if (type == R_LARCH_SOP_IF_ELSE) { err = rela_stack_pop(&opr3, rela_stack, rela_stack_top); @@ -164,10 +181,10 @@ static int apply_r_larch_sop(struct module *mod, u32 *location, Elf_Addr v, } static int apply_r_larch_sop_imm_field(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { int err = 0; - s64 opr1; + long opr1; union loongarch_instruction *insn = (union loongarch_instruction *)location; err = rela_stack_pop(&opr1, rela_stack, rela_stack_top); @@ -244,31 +261,33 @@ static int apply_r_larch_sop_imm_field(struct module *mod, u32 *location, Elf_Ad } overflow: - pr_err("module %s: opr1 = 0x%llx overflow! dangerous %s (%u) relocation\n", + pr_err("module %s: opr1 = 0x%lx overflow! dangerous %s (%u) relocation\n", mod->name, opr1, __func__, type); return -ENOEXEC; unaligned: - pr_err("module %s: opr1 = 0x%llx unaligned! dangerous %s (%u) relocation\n", + pr_err("module %s: opr1 = 0x%lx unaligned! dangerous %s (%u) relocation\n", mod->name, opr1, __func__, type); return -ENOEXEC; } static int apply_r_larch_add_sub(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { switch (type) { case R_LARCH_ADD32: *(s32 *)location += v; return 0; - case R_LARCH_ADD64: - *(s64 *)location += v; - return 0; case R_LARCH_SUB32: *(s32 *)location -= v; return 0; +#ifdef CONFIG_64BIT + case R_LARCH_ADD64: + *(s64 *)location += v; + return 0; case R_LARCH_SUB64: *(s64 *)location -= v; +#endif return 0; default: pr_err("%s: Unsupport relocation type %u\n", mod->name, type); @@ -278,7 +297,7 @@ static int apply_r_larch_add_sub(struct module *mod, u32 *location, Elf_Addr v, static int apply_r_larch_b26(struct module *mod, Elf_Shdr *sechdrs, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { ptrdiff_t offset = (void *)v - (void *)location; union loongarch_instruction *insn = (union loongarch_instruction *)location; @@ -310,15 +329,40 @@ static int apply_r_larch_b26(struct module *mod, return 0; } +static int apply_r_larch_pcadd(struct module *mod, u32 *location, Elf_Addr v, + long *rela_stack, size_t *rela_stack_top, unsigned int type) +{ + union loongarch_instruction *insn = (union loongarch_instruction *)location; + /* Use s32 for a sign-extension deliberately. */ + s32 offset_hi20 = (void *)((v + 0x800)) - (void *)((Elf_Addr)location); + + switch (type) { + case R_LARCH_PCADD_LO12: + insn->reg2i12_format.immediate = v & 0xfff; + break; + case R_LARCH_PCADD_HI20: + v = offset_hi20 >> 12; + insn->reg1i20_format.immediate = v & 0xfffff; + break; + default: + pr_err("%s: Unsupport relocation type %u\n", mod->name, type); + return -EINVAL; + } + + return 0; +} + static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { union loongarch_instruction *insn = (union loongarch_instruction *)location; /* Use s32 for a sign-extension deliberately. */ s32 offset_hi20 = (void *)((v + 0x800) & ~0xfff) - (void *)((Elf_Addr)location & ~0xfff); +#ifdef CONFIG_64BIT Elf_Addr anchor = (((Elf_Addr)location) & ~0xfff) + offset_hi20; ptrdiff_t offset_rem = (void *)v - (void *)anchor; +#endif switch (type) { case R_LARCH_PCALA_LO12: @@ -328,6 +372,7 @@ static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr v, v = offset_hi20 >> 12; insn->reg1i20_format.immediate = v & 0xfffff; break; +#ifdef CONFIG_64BIT case R_LARCH_PCALA64_LO20: v = offset_rem >> 32; insn->reg1i20_format.immediate = v & 0xfffff; @@ -336,6 +381,7 @@ static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr v, v = offset_rem >> 52; insn->reg2i12_format.immediate = v & 0xfff; break; +#endif default: pr_err("%s: Unsupport relocation type %u\n", mod->name, type); return -EINVAL; @@ -346,30 +392,43 @@ static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr v, static int apply_r_larch_got_pc(struct module *mod, Elf_Shdr *sechdrs, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { - Elf_Addr got = module_emit_got_entry(mod, sechdrs, v); + reloc_rela_handler got_handler; - if (!got) - return -EINVAL; + if (type != R_LARCH_GOT_PCADD_LO12) { + v = module_emit_got_entry(mod, sechdrs, v); + if (!v) + return -EINVAL; + } switch (type) { case R_LARCH_GOT_PC_LO12: type = R_LARCH_PCALA_LO12; + got_handler = apply_r_larch_pcala; break; case R_LARCH_GOT_PC_HI20: type = R_LARCH_PCALA_HI20; + got_handler = apply_r_larch_pcala; + break; + case R_LARCH_GOT_PCADD_LO12: + type = R_LARCH_PCADD_LO12; + got_handler = apply_r_larch_pcadd; + break; + case R_LARCH_GOT_PCADD_HI20: + type = R_LARCH_PCADD_HI20; + got_handler = apply_r_larch_pcadd; break; default: pr_err("%s: Unsupport relocation type %u\n", mod->name, type); return -EINVAL; } - return apply_r_larch_pcala(mod, location, got, rela_stack, rela_stack_top, type); + return got_handler(mod, location, v, rela_stack, rela_stack_top, type); } static int apply_r_larch_32_pcrel(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { ptrdiff_t offset = (void *)v - (void *)location; @@ -377,31 +436,22 @@ static int apply_r_larch_32_pcrel(struct module *mod, u32 *location, Elf_Addr v, return 0; } +#ifdef CONFIG_32BIT +#define apply_r_larch_64_pcrel apply_r_larch_error +#else static int apply_r_larch_64_pcrel(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { ptrdiff_t offset = (void *)v - (void *)location; *(u64 *)location = offset; return 0; } - -/* - * reloc_handlers_rela() - Apply a particular relocation to a module - * @mod: the module to apply the reloc to - * @location: the address at which the reloc is to be applied - * @v: the value of the reloc, with addend for RELA-style - * @rela_stack: the stack used for store relocation info, LOCAL to THIS module - * @rela_stac_top: where the stack operation(pop/push) applies to - * - * Return: 0 upon success, else -ERRNO - */ -typedef int (*reloc_rela_handler)(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type); +#endif /* The handlers for known reloc types */ static reloc_rela_handler reloc_rela_handlers[] = { - [R_LARCH_NONE ... R_LARCH_64_PCREL] = apply_r_larch_error, + [R_LARCH_NONE ... R_LARCH_TLS_DESC_PCADD_LO12] = apply_r_larch_error, [R_LARCH_NONE] = apply_r_larch_none, [R_LARCH_32] = apply_r_larch_32, @@ -414,7 +464,8 @@ static reloc_rela_handler reloc_rela_handlers[] = { [R_LARCH_SOP_SUB ... R_LARCH_SOP_IF_ELSE] = apply_r_larch_sop, [R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field, [R_LARCH_ADD32 ... R_LARCH_SUB64] = apply_r_larch_add_sub, - [R_LARCH_PCALA_HI20...R_LARCH_PCALA64_HI12] = apply_r_larch_pcala, + [R_LARCH_PCADD_HI20 ... R_LARCH_PCADD_LO12] = apply_r_larch_pcadd, + [R_LARCH_PCALA_HI20 ... R_LARCH_PCALA64_HI12] = apply_r_larch_pcala, [R_LARCH_32_PCREL] = apply_r_larch_32_pcrel, [R_LARCH_64_PCREL] = apply_r_larch_64_pcrel, }; @@ -423,9 +474,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex, unsigned int relsec, struct module *mod) { - int i, err; - unsigned int type; - s64 rela_stack[RELA_STACK_DEPTH]; + int err; + unsigned int i, idx, type; + unsigned int num_relocations; + long rela_stack[RELA_STACK_DEPTH]; size_t rela_stack_top = 0; reloc_rela_handler handler; void *location; @@ -436,8 +488,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, pr_debug("%s: Applying relocate section %u to %u\n", __func__, relsec, sechdrs[relsec].sh_info); + idx = 0; rela_stack_top = 0; - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { + num_relocations = sechdrs[relsec].sh_size / sizeof(*rel); + for (i = 0; i < num_relocations; i++) { /* This is where to make the change */ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset; /* This is the symbol it is referring to */ @@ -462,17 +516,59 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, return -EINVAL; } - pr_debug("type %d st_value %llx r_addend %llx loc %llx\n", + pr_debug("type %d st_value %lx r_addend %lx loc %lx\n", (int)ELF_R_TYPE(rel[i].r_info), - sym->st_value, rel[i].r_addend, (u64)location); + (unsigned long)sym->st_value, (unsigned long)rel[i].r_addend, (unsigned long)location); v = sym->st_value + rel[i].r_addend; + + if (type == R_LARCH_PCADD_LO12 || type == R_LARCH_GOT_PCADD_LO12) { + bool found = false; + unsigned int j = idx; + + do { + u32 hi20_type = ELF_R_TYPE(rel[j].r_info); + unsigned long hi20_location = + sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[j].r_offset; + + /* Find the corresponding HI20 relocation entry */ + if ((hi20_location == sym->st_value) && (hi20_type == type - 1)) { + s32 hi20, lo12; + Elf_Sym *hi20_sym = + (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_R_SYM(rel[j].r_info); + unsigned long hi20_sym_val = hi20_sym->st_value + rel[j].r_addend; + + /* Calculate LO12 offset */ + size_t offset = hi20_sym_val - hi20_location; + if (hi20_type == R_LARCH_GOT_PCADD_HI20) { + offset = module_emit_got_entry(mod, sechdrs, hi20_sym_val); + offset = offset - hi20_location; + } + hi20 = (offset + 0x800) & 0xfffff000; + v = lo12 = offset - hi20; + found = true; + break; + } + + j = (j + 1) % num_relocations; + + } while (idx != j); + + if (!found) { + pr_err("%s: Can not find HI20 relocation information\n", mod->name); + return -EINVAL; + } + + idx = j; /* Record the previous j-loop end index */ + } + switch (type) { case R_LARCH_B26: err = apply_r_larch_b26(mod, sechdrs, location, v, rela_stack, &rela_stack_top, type); break; case R_LARCH_GOT_PC_HI20...R_LARCH_GOT_PC_LO12: + case R_LARCH_GOT_PCADD_HI20...R_LARCH_GOT_PCADD_LO12: err = apply_r_larch_got_pc(mod, sechdrs, location, v, rela_stack, &rela_stack_top, type); break; diff --git a/arch/loongarch/kernel/proc.c b/arch/loongarch/kernel/proc.c index 63d2b7e7e844b..a8800d20e11bd 100644 --- a/arch/loongarch/kernel/proc.c +++ b/arch/loongarch/kernel/proc.c @@ -20,11 +20,14 @@ static int show_cpuinfo(struct seq_file *m, void *v) unsigned int prid = cpu_data[n].processor_id; unsigned int version = cpu_data[n].processor_id & 0xff; unsigned int fp_version = cpu_data[n].fpu_vers; + u64 freq = cpu_clock_freq, bogomips = lpj_fine * cpu_clock_freq; #ifdef CONFIG_SMP if (!cpu_online(n)) return 0; #endif + do_div(freq, 10000); + do_div(bogomips, const_clock_freq * (5000/HZ)); /* * For the first processor also print the system type @@ -41,11 +44,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "PRID\t\t\t: %s (%08x)\n", id_to_core_name(prid), prid); seq_printf(m, "CPU Revision\t\t: 0x%02x\n", version); seq_printf(m, "FPU Revision\t\t: 0x%02x\n", fp_version); - seq_printf(m, "CPU MHz\t\t\t: %llu.%02llu\n", - cpu_clock_freq / 1000000, (cpu_clock_freq / 10000) % 100); - seq_printf(m, "BogoMIPS\t\t: %llu.%02llu\n", - (lpj_fine * cpu_clock_freq / const_clock_freq) / (500000/HZ), - ((lpj_fine * cpu_clock_freq / const_clock_freq) / (5000/HZ)) % 100); + seq_printf(m, "CPU MHz\t\t\t: %u.%02u\n", (u32)freq / 100, (u32)freq % 100); + seq_printf(m, "BogoMIPS\t\t: %u.%02u\n", (u32)bogomips / 100, (u32)bogomips % 100); seq_printf(m, "TLB Entries\t\t: %d\n", cpu_data[n].tlbsize); seq_printf(m, "Address Sizes\t\t: %d bits physical, %d bits virtual\n", cpu_pabits + 1, cpu_vabits + 1); diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c index efd9edf65603c..4ac1c30861526 100644 --- a/arch/loongarch/kernel/process.c +++ b/arch/loongarch/kernel/process.c @@ -130,6 +130,11 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) preempt_enable(); + if (IS_ENABLED(CONFIG_RANDSTRUCT)) { + memcpy(dst, src, sizeof(struct task_struct)); + return 0; + } + if (!used_math()) memcpy(dst, src, offsetof(struct task_struct, thread.fpu.fpr)); else @@ -377,8 +382,11 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu) nmi_trigger_cpumask_backtrace(mask, exclude_cpu, raise_backtrace); } -#ifdef CONFIG_64BIT +#ifdef CONFIG_32BIT +void loongarch_dump_regs32(u32 *uregs, const struct pt_regs *regs) +#else void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs) +#endif { unsigned int i; @@ -395,4 +403,3 @@ void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs) uregs[LOONGARCH_EF_CSR_ECFG] = regs->csr_ecfg; uregs[LOONGARCH_EF_CSR_ESTAT] = regs->csr_estat; } -#endif /* CONFIG_64BIT */ diff --git a/arch/loongarch/kernel/ptrace.c b/arch/loongarch/kernel/ptrace.c index 8edd0954e55ab..be38430f7e280 100644 --- a/arch/loongarch/kernel/ptrace.c +++ b/arch/loongarch/kernel/ptrace.c @@ -650,8 +650,13 @@ static int ptrace_hbp_set_addr(unsigned int note_type, struct perf_event_attr attr; /* Kernel-space address cannot be monitored by user-space */ +#ifdef CONFIG_32BIT + if ((unsigned long)addr >= KPRANGE0) + return -EINVAL; +#else if ((unsigned long)addr >= XKPRANGE) return -EINVAL; +#endif bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx); if (IS_ERR(bp)) diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c index b5e2312a2fca5..82aa3f0359278 100644 --- a/arch/loongarch/kernel/relocate.c +++ b/arch/loongarch/kernel/relocate.c @@ -68,18 +68,25 @@ static inline void __init relocate_absolute(long random_offset) for (p = begin; (void *)p < end; p++) { long v = p->symvalue; - uint32_t lu12iw, ori, lu32id, lu52id; + uint32_t lu12iw, ori; +#ifdef CONFIG_64BIT + uint32_t lu32id, lu52id; +#endif union loongarch_instruction *insn = (void *)p->pc; lu12iw = (v >> 12) & 0xfffff; ori = v & 0xfff; +#ifdef CONFIG_64BIT lu32id = (v >> 32) & 0xfffff; lu52id = v >> 52; +#endif insn[0].reg1i20_format.immediate = lu12iw; insn[1].reg2i12_format.immediate = ori; +#ifdef CONFIG_64BIT insn[2].reg1i20_format.immediate = lu32id; insn[3].reg2i12_format.immediate = lu52id; +#endif } } @@ -183,7 +190,7 @@ static inline void __init *determine_relocation_address(void) if (kaslr_disabled()) return destination; - kernel_length = (long)_end - (long)_text; + kernel_length = (unsigned long)_end - (unsigned long)_text; random_offset = get_random_boot() << 16; random_offset &= (CONFIG_RANDOMIZE_BASE_MAX_OFFSET - 1); @@ -232,7 +239,7 @@ unsigned long __init relocate_kernel(void) early_memunmap(cmdline, COMMAND_LINE_SIZE); if (random_offset) { - kernel_length = (long)(_end) - (long)(_text); + kernel_length = (unsigned long)(_end) - (unsigned long)(_text); /* Copy the kernel to it's new location */ memcpy(location_new, _text, kernel_length); diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 25a87378e48e4..20cb6f3064568 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -56,6 +56,7 @@ #define SMBIOS_FREQLOW_MASK 0xFF #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 #define SMBIOS_THREAD_PACKAGE_OFFSET 0x25 +#define SMBIOS_THREAD_PACKAGE_2_OFFSET 0x2E #define LOONGSON_EFI_ENABLE (1 << 3) unsigned long fw_arg0, fw_arg1, fw_arg2; @@ -126,7 +127,12 @@ static void __init parse_cpu_table(const struct dmi_header *dm) cpu_clock_freq = freq_temp * 1000000; loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]); - loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_THREAD_PACKAGE_OFFSET); + loongson_sysconf.cores_per_package = *(u8 *)(dmi_data + SMBIOS_THREAD_PACKAGE_OFFSET); + if (dm->length >= 0x30 && loongson_sysconf.cores_per_package == 0xff) { + /* SMBIOS 3.0+ has ThreadCount2 for more than 255 threads */ + loongson_sysconf.cores_per_package = + *(u16 *)(dmi_data + SMBIOS_THREAD_PACKAGE_2_OFFSET); + } pr_info("CpuClock = %llu\n", cpu_clock_freq); } diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index 46036d98da75b..8b2fcb3fb874c 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -535,28 +535,32 @@ int hibernate_resume_nonboot_cpu_disable(void) */ #ifdef CONFIG_PM -static int loongson_ipi_suspend(void) +static int loongson_ipi_suspend(void *data) { return 0; } -static void loongson_ipi_resume(void) +static void loongson_ipi_resume(void *data) { iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN); } -static struct syscore_ops loongson_ipi_syscore_ops = { +static const struct syscore_ops loongson_ipi_syscore_ops = { .resume = loongson_ipi_resume, .suspend = loongson_ipi_suspend, }; +static struct syscore loongson_ipi_syscore = { + .ops = &loongson_ipi_syscore_ops, +}; + /* * Enable boot cpu ipi before enabling nonboot cpus * during syscore_resume. */ static int __init ipi_pm_init(void) { - register_syscore_ops(&loongson_ipi_syscore_ops); + register_syscore(&loongson_ipi_syscore); return 0; } diff --git a/arch/loongarch/kernel/switch.S b/arch/loongarch/kernel/switch.S index 9c23cb7e432f1..f377d8f5c51a6 100644 --- a/arch/loongarch/kernel/switch.S +++ b/arch/loongarch/kernel/switch.S @@ -16,18 +16,23 @@ */ .align 5 SYM_FUNC_START(__switch_to) - csrrd t1, LOONGARCH_CSR_PRMD - stptr.d t1, a0, THREAD_CSRPRMD +#ifdef CONFIG_32BIT + PTR_ADDI a0, a0, TASK_STRUCT_OFFSET + PTR_ADDI a1, a1, TASK_STRUCT_OFFSET +#endif + csrrd t1, LOONGARCH_CSR_PRMD + LONG_SPTR t1, a0, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET) cpu_save_nonscratch a0 - stptr.d ra, a0, THREAD_REG01 - stptr.d a3, a0, THREAD_SCHED_RA - stptr.d a4, a0, THREAD_SCHED_CFA + LONG_SPTR a3, a0, (THREAD_SCHED_RA - TASK_STRUCT_OFFSET) + LONG_SPTR a4, a0, (THREAD_SCHED_CFA - TASK_STRUCT_OFFSET) + #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) - la t7, __stack_chk_guard - LONG_L t8, a1, TASK_STACK_CANARY - LONG_S t8, t7, 0 + la t7, __stack_chk_guard + LONG_LPTR t8, a1, (TASK_STACK_CANARY - TASK_STRUCT_OFFSET) + LONG_SPTR t8, t7, 0 #endif + move tp, a2 cpu_restore_nonscratch a1 @@ -35,8 +40,11 @@ SYM_FUNC_START(__switch_to) PTR_ADD t0, t0, tp set_saved_sp t0, t1, t2 - ldptr.d t1, a1, THREAD_CSRPRMD - csrwr t1, LOONGARCH_CSR_PRMD + LONG_LPTR t1, a1, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET) + csrwr t1, LOONGARCH_CSR_PRMD +#ifdef CONFIG_32BIT + PTR_ADDI a0, a0, -TASK_STRUCT_OFFSET +#endif jr ra SYM_FUNC_END(__switch_to) diff --git a/arch/loongarch/kernel/syscall.c b/arch/loongarch/kernel/syscall.c index 168bd97540f8c..1249d82c1cd0a 100644 --- a/arch/loongarch/kernel/syscall.c +++ b/arch/loongarch/kernel/syscall.c @@ -34,9 +34,22 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long, return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); } +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, + prot, unsigned long, flags, unsigned long, fd, unsigned long, offset) +{ + if (offset & (~PAGE_MASK >> 12)) + return -EINVAL; + + return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> (PAGE_SHIFT - 12)); +} + void *sys_call_table[__NR_syscalls] = { [0 ... __NR_syscalls - 1] = sys_ni_syscall, +#ifdef CONFIG_32BIT +#include +#else #include +#endif }; typedef long (*sys_call_fn)(unsigned long, unsigned long, @@ -75,7 +88,7 @@ void noinstr __no_stack_protector do_syscall(struct pt_regs *regs) * * The resulting 6 bits of entropy is seen in SP[9:4]. */ - choose_random_kstack_offset(drdtime()); + choose_random_kstack_offset(get_cycles()); syscall_exit_to_user_mode(regs); } diff --git a/arch/loongarch/kernel/time.c b/arch/loongarch/kernel/time.c index 6fb92cc1a4c92..dbaaabcaf6f09 100644 --- a/arch/loongarch/kernel/time.c +++ b/arch/loongarch/kernel/time.c @@ -18,6 +18,7 @@ #include #include #include +#include u64 cpu_clock_freq; EXPORT_SYMBOL(cpu_clock_freq); @@ -50,10 +51,10 @@ static int constant_set_state_oneshot(struct clock_event_device *evt) raw_spin_lock(&state_lock); - timer_config = csr_read64(LOONGARCH_CSR_TCFG); + timer_config = csr_read(LOONGARCH_CSR_TCFG); timer_config |= CSR_TCFG_EN; timer_config &= ~CSR_TCFG_PERIOD; - csr_write64(timer_config, LOONGARCH_CSR_TCFG); + csr_write(timer_config, LOONGARCH_CSR_TCFG); raw_spin_unlock(&state_lock); @@ -62,15 +63,15 @@ static int constant_set_state_oneshot(struct clock_event_device *evt) static int constant_set_state_periodic(struct clock_event_device *evt) { - unsigned long period; unsigned long timer_config; + u64 period = const_clock_freq; raw_spin_lock(&state_lock); - period = const_clock_freq / HZ; + do_div(period, HZ); timer_config = period & CSR_TCFG_VAL; timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN); - csr_write64(timer_config, LOONGARCH_CSR_TCFG); + csr_write(timer_config, LOONGARCH_CSR_TCFG); raw_spin_unlock(&state_lock); @@ -83,9 +84,9 @@ static int constant_set_state_shutdown(struct clock_event_device *evt) raw_spin_lock(&state_lock); - timer_config = csr_read64(LOONGARCH_CSR_TCFG); + timer_config = csr_read(LOONGARCH_CSR_TCFG); timer_config &= ~CSR_TCFG_EN; - csr_write64(timer_config, LOONGARCH_CSR_TCFG); + csr_write(timer_config, LOONGARCH_CSR_TCFG); raw_spin_unlock(&state_lock); @@ -98,7 +99,7 @@ static int constant_timer_next_event(unsigned long delta, struct clock_event_dev delta &= CSR_TCFG_VAL; timer_config = delta | CSR_TCFG_EN; - csr_write64(timer_config, LOONGARCH_CSR_TCFG); + csr_write(timer_config, LOONGARCH_CSR_TCFG); return 0; } @@ -120,7 +121,7 @@ static int arch_timer_dying(unsigned int cpu) static unsigned long get_loops_per_jiffy(void) { - unsigned long lpj = (unsigned long)const_clock_freq; + u64 lpj = const_clock_freq; do_div(lpj, HZ); @@ -131,13 +132,13 @@ static long init_offset; void save_counter(void) { - init_offset = drdtime(); + init_offset = get_cycles(); } void sync_counter(void) { /* Ensure counter begin at 0 */ - csr_write64(init_offset, LOONGARCH_CSR_CNTC); + csr_write(init_offset, LOONGARCH_CSR_CNTC); } int constant_clockevent_init(void) @@ -197,12 +198,12 @@ int constant_clockevent_init(void) static u64 read_const_counter(struct clocksource *clk) { - return drdtime(); + return get_cycles64(); } static noinstr u64 sched_clock_read(void) { - return drdtime(); + return get_cycles64(); } static struct clocksource clocksource_const = { @@ -211,7 +212,9 @@ static struct clocksource clocksource_const = { .read = read_const_counter, .mask = CLOCKSOURCE_MASK(64), .flags = CLOCK_SOURCE_IS_CONTINUOUS, +#ifdef CONFIG_GENERIC_GETTIMEOFDAY .vdso_clock_mode = VDSO_CLOCKMODE_CPU, +#endif }; int __init constant_clocksource_init(void) @@ -235,7 +238,7 @@ void __init time_init(void) else const_clock_freq = calc_const_freq(); - init_offset = -(drdtime() - csr_read64(LOONGARCH_CSR_CNTC)); + init_offset = -(get_cycles() - csr_read(LOONGARCH_CSR_CNTC)); constant_clockevent_init(); constant_clocksource_init(); diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c index da5926fead4af..004b8ebf00512 100644 --- a/arch/loongarch/kernel/traps.c +++ b/arch/loongarch/kernel/traps.c @@ -625,7 +625,7 @@ asmlinkage void noinstr do_bce(struct pt_regs *regs) bool user = user_mode(regs); bool pie = regs_irqs_disabled(regs); unsigned long era = exception_era(regs); - u64 badv = 0, lower = 0, upper = ULONG_MAX; + unsigned long badv = 0, lower = 0, upper = ULONG_MAX; union loongarch_instruction insn; irqentry_state_t state = irqentry_enter(regs); @@ -1070,10 +1070,13 @@ asmlinkage void noinstr do_reserved(struct pt_regs *regs) asmlinkage void cache_parity_error(void) { + u32 merrctl = csr_read32(LOONGARCH_CSR_MERRCTL); + unsigned long merrera = csr_read(LOONGARCH_CSR_MERRERA); + /* For the moment, report the problem and hang. */ pr_err("Cache error exception:\n"); - pr_err("csr_merrctl == %08x\n", csr_read32(LOONGARCH_CSR_MERRCTL)); - pr_err("csr_merrera == %016lx\n", csr_read64(LOONGARCH_CSR_MERRERA)); + pr_err("csr_merrctl == %08x\n", merrctl); + pr_err("csr_merrera == %016lx\n", merrera); panic("Can't handle the cache error!"); } @@ -1130,9 +1133,9 @@ static void configure_exception_vector(void) eentry = (unsigned long)exception_handlers; tlbrentry = (unsigned long)exception_handlers + 80*VECSIZE; - csr_write64(eentry, LOONGARCH_CSR_EENTRY); - csr_write64(__pa(eentry), LOONGARCH_CSR_MERRENTRY); - csr_write64(__pa(tlbrentry), LOONGARCH_CSR_TLBRENTRY); + csr_write(eentry, LOONGARCH_CSR_EENTRY); + csr_write(__pa(eentry), LOONGARCH_CSR_MERRENTRY); + csr_write(__pa(tlbrentry), LOONGARCH_CSR_TLBRENTRY); } void per_cpu_trap_init(int cpu) diff --git a/arch/loongarch/kernel/unaligned.c b/arch/loongarch/kernel/unaligned.c index 487be604b96ae..cc929c9fe7e99 100644 --- a/arch/loongarch/kernel/unaligned.c +++ b/arch/loongarch/kernel/unaligned.c @@ -27,12 +27,21 @@ static u32 unaligned_instructions_user; static u32 unaligned_instructions_kernel; #endif -static inline unsigned long read_fpr(unsigned int idx) +static inline u64 read_fpr(unsigned int idx) { +#ifdef CONFIG_64BIT #define READ_FPR(idx, __value) \ __asm__ __volatile__("movfr2gr.d %0, $f"#idx"\n\t" : "=r"(__value)); - - unsigned long __value; +#else +#define READ_FPR(idx, __value) \ +{ \ + u32 __value_lo, __value_hi; \ + __asm__ __volatile__("movfr2gr.s %0, $f"#idx"\n\t" : "=r"(__value_lo)); \ + __asm__ __volatile__("movfrh2gr.s %0, $f"#idx"\n\t" : "=r"(__value_hi)); \ + __value = (__value_lo | ((u64)__value_hi << 32)); \ +} +#endif + u64 __value; switch (idx) { case 0: @@ -138,11 +147,20 @@ static inline unsigned long read_fpr(unsigned int idx) return __value; } -static inline void write_fpr(unsigned int idx, unsigned long value) +static inline void write_fpr(unsigned int idx, u64 value) { +#ifdef CONFIG_64BIT #define WRITE_FPR(idx, value) \ __asm__ __volatile__("movgr2fr.d $f"#idx", %0\n\t" :: "r"(value)); - +#else +#define WRITE_FPR(idx, value) \ +{ \ + u32 value_lo = value; \ + u32 value_hi = value >> 32; \ + __asm__ __volatile__("movgr2fr.w $f"#idx", %0\n\t" :: "r"(value_lo)); \ + __asm__ __volatile__("movgr2frh.w $f"#idx", %0\n\t" :: "r"(value_hi)); \ +} +#endif switch (idx) { case 0: WRITE_FPR(0, value); @@ -252,7 +270,7 @@ void emulate_load_store_insn(struct pt_regs *regs, void __user *addr, unsigned i bool sign, write; bool user = user_mode(regs); unsigned int res, size = 0; - unsigned long value = 0; + u64 value = 0; union loongarch_instruction insn; perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); diff --git a/arch/loongarch/kvm/Kconfig b/arch/loongarch/kvm/Kconfig index ae64bbdf83a7a..ed4f724db7741 100644 --- a/arch/loongarch/kvm/Kconfig +++ b/arch/loongarch/kvm/Kconfig @@ -25,7 +25,6 @@ config KVM select HAVE_KVM_IRQCHIP select HAVE_KVM_MSI select HAVE_KVM_READONLY_MEM - select HAVE_KVM_VCPU_ASYNC_IOCTL select KVM_COMMON select KVM_GENERIC_DIRTYLOG_READ_PROTECT select KVM_GENERIC_HARDWARE_ENABLING diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c index a1cc116b4dace..29886876143f1 100644 --- a/arch/loongarch/kvm/intc/eiointc.c +++ b/arch/loongarch/kvm/intc/eiointc.c @@ -13,19 +13,19 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s) struct kvm_vcpu *vcpu; for (irq = 0; irq < EIOINTC_IRQS; irq++) { - ipnum = s->ipmap.reg_u8[irq / 32]; + ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xff; if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) { ipnum = count_trailing_zeros(ipnum); ipnum = (ipnum >= 0 && ipnum < 4) ? ipnum : 0; } - cpuid = s->coremap.reg_u8[irq]; + cpuid = ((u8 *)s->coremap)[irq]; vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid); if (!vcpu) continue; cpu = vcpu->vcpu_id; - if (test_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu])) + if (test_bit(irq, (unsigned long *)s->coreisr[cpu])) __set_bit(irq, s->sw_coreisr[cpu][ipnum]); else __clear_bit(irq, s->sw_coreisr[cpu][ipnum]); @@ -38,7 +38,7 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level) struct kvm_vcpu *vcpu; struct kvm_interrupt vcpu_irq; - ipnum = s->ipmap.reg_u8[irq / 32]; + ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xff; if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) { ipnum = count_trailing_zeros(ipnum); ipnum = (ipnum >= 0 && ipnum < 4) ? ipnum : 0; @@ -53,13 +53,13 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level) if (level) { /* if not enable return false */ - if (!test_bit(irq, (unsigned long *)s->enable.reg_u32)) + if (!test_bit(irq, (unsigned long *)s->enable)) return; - __set_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu]); + __set_bit(irq, (unsigned long *)s->coreisr[cpu]); found = find_first_bit(s->sw_coreisr[cpu][ipnum], EIOINTC_IRQS); __set_bit(irq, s->sw_coreisr[cpu][ipnum]); } else { - __clear_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu]); + __clear_bit(irq, (unsigned long *)s->coreisr[cpu]); __clear_bit(irq, s->sw_coreisr[cpu][ipnum]); found = find_first_bit(s->sw_coreisr[cpu][ipnum], EIOINTC_IRQS); } @@ -94,7 +94,7 @@ static inline void eiointc_update_sw_coremap(struct loongarch_eiointc *s, if (s->sw_coremap[irq + i] == cpu) continue; - if (notify && test_bit(irq + i, (unsigned long *)s->isr.reg_u8)) { + if (notify && test_bit(irq + i, (unsigned long *)s->isr)) { /* lower irq at old cpu and raise irq at new cpu */ eiointc_update_irq(s, irq + i, 0); s->sw_coremap[irq + i] = cpu; @@ -108,7 +108,7 @@ static inline void eiointc_update_sw_coremap(struct loongarch_eiointc *s, void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level) { unsigned long flags; - unsigned long *isr = (unsigned long *)s->isr.reg_u8; + unsigned long *isr = (unsigned long *)s->isr; spin_lock_irqsave(&s->lock, flags); level ? __set_bit(irq, isr) : __clear_bit(irq, isr); @@ -127,27 +127,27 @@ static int loongarch_eiointc_read(struct kvm_vcpu *vcpu, struct loongarch_eioint switch (offset) { case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END: index = (offset - EIOINTC_NODETYPE_START) >> 3; - data = s->nodetype.reg_u64[index]; + data = s->nodetype[index]; break; case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END: index = (offset - EIOINTC_IPMAP_START) >> 3; - data = s->ipmap.reg_u64; + data = s->ipmap; break; case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END: index = (offset - EIOINTC_ENABLE_START) >> 3; - data = s->enable.reg_u64[index]; + data = s->enable[index]; break; case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END: index = (offset - EIOINTC_BOUNCE_START) >> 3; - data = s->bounce.reg_u64[index]; + data = s->bounce[index]; break; case EIOINTC_COREISR_START ... EIOINTC_COREISR_END: index = (offset - EIOINTC_COREISR_START) >> 3; - data = s->coreisr.reg_u64[vcpu->vcpu_id][index]; + data = s->coreisr[vcpu->vcpu_id][index]; break; case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END: index = (offset - EIOINTC_COREMAP_START) >> 3; - data = s->coremap.reg_u64[index]; + data = s->coremap[index]; break; default: ret = -EINVAL; @@ -223,26 +223,26 @@ static int loongarch_eiointc_write(struct kvm_vcpu *vcpu, switch (offset) { case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END: index = (offset - EIOINTC_NODETYPE_START) >> 3; - old = s->nodetype.reg_u64[index]; - s->nodetype.reg_u64[index] = (old & ~mask) | data; + old = s->nodetype[index]; + s->nodetype[index] = (old & ~mask) | data; break; case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END: /* * ipmap cannot be set at runtime, can be set only at the beginning * of irqchip driver, need not update upper irq level */ - old = s->ipmap.reg_u64; - s->ipmap.reg_u64 = (old & ~mask) | data; + old = s->ipmap; + s->ipmap = (old & ~mask) | data; break; case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END: index = (offset - EIOINTC_ENABLE_START) >> 3; - old = s->enable.reg_u64[index]; - s->enable.reg_u64[index] = (old & ~mask) | data; + old = s->enable[index]; + s->enable[index] = (old & ~mask) | data; /* * 1: enable irq. * update irq when isr is set. */ - data = s->enable.reg_u64[index] & ~old & s->isr.reg_u64[index]; + data = s->enable[index] & ~old & s->isr[index]; while (data) { irq = __ffs(data); eiointc_update_irq(s, irq + index * 64, 1); @@ -252,7 +252,7 @@ static int loongarch_eiointc_write(struct kvm_vcpu *vcpu, * 0: disable irq. * update irq when isr is set. */ - data = ~s->enable.reg_u64[index] & old & s->isr.reg_u64[index]; + data = ~s->enable[index] & old & s->isr[index]; while (data) { irq = __ffs(data); eiointc_update_irq(s, irq + index * 64, 0); @@ -262,16 +262,16 @@ static int loongarch_eiointc_write(struct kvm_vcpu *vcpu, case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END: /* do not emulate hw bounced irq routing */ index = (offset - EIOINTC_BOUNCE_START) >> 3; - old = s->bounce.reg_u64[index]; - s->bounce.reg_u64[index] = (old & ~mask) | data; + old = s->bounce[index]; + s->bounce[index] = (old & ~mask) | data; break; case EIOINTC_COREISR_START ... EIOINTC_COREISR_END: index = (offset - EIOINTC_COREISR_START) >> 3; /* use attrs to get current cpu index */ cpu = vcpu->vcpu_id; - old = s->coreisr.reg_u64[cpu][index]; + old = s->coreisr[cpu][index]; /* write 1 to clear interrupt */ - s->coreisr.reg_u64[cpu][index] = old & ~data; + s->coreisr[cpu][index] = old & ~data; data &= old; while (data) { irq = __ffs(data); @@ -281,9 +281,9 @@ static int loongarch_eiointc_write(struct kvm_vcpu *vcpu, break; case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END: index = (offset - EIOINTC_COREMAP_START) >> 3; - old = s->coremap.reg_u64[index]; - s->coremap.reg_u64[index] = (old & ~mask) | data; - data = s->coremap.reg_u64[index]; + old = s->coremap[index]; + s->coremap[index] = (old & ~mask) | data; + data = s->coremap[index]; eiointc_update_sw_coremap(s, index * 8, data, sizeof(data), true); break; default: @@ -451,10 +451,10 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev, break; case KVM_DEV_LOONGARCH_EXTIOI_CTRL_LOAD_FINISHED: eiointc_set_sw_coreisr(s); - for (i = 0; i < (EIOINTC_IRQS / 4); i++) { - start_irq = i * 4; + for (i = 0; i < (EIOINTC_IRQS / 8); i++) { + start_irq = i * 8; eiointc_update_sw_coremap(s, start_irq, - s->coremap.reg_u32[i], sizeof(u32), false); + s->coremap[i], sizeof(u64), false); } break; default: @@ -481,34 +481,34 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev, switch (addr) { case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END: offset = (addr - EIOINTC_NODETYPE_START) / 4; - p = &s->nodetype.reg_u32[offset]; + p = s->nodetype + offset * 4; break; case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END: offset = (addr - EIOINTC_IPMAP_START) / 4; - p = &s->ipmap.reg_u32[offset]; + p = &s->ipmap + offset * 4; break; case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END: offset = (addr - EIOINTC_ENABLE_START) / 4; - p = &s->enable.reg_u32[offset]; + p = s->enable + offset * 4; break; case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END: offset = (addr - EIOINTC_BOUNCE_START) / 4; - p = &s->bounce.reg_u32[offset]; + p = s->bounce + offset * 4; break; case EIOINTC_ISR_START ... EIOINTC_ISR_END: offset = (addr - EIOINTC_ISR_START) / 4; - p = &s->isr.reg_u32[offset]; + p = s->isr + offset * 4; break; case EIOINTC_COREISR_START ... EIOINTC_COREISR_END: if (cpu >= s->num_cpu) return -EINVAL; offset = (addr - EIOINTC_COREISR_START) / 4; - p = &s->coreisr.reg_u32[cpu][offset]; + p = s->coreisr[cpu] + offset * 4; break; case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END: offset = (addr - EIOINTC_COREMAP_START) / 4; - p = &s->coremap.reg_u32[offset]; + p = s->coremap + offset * 4; break; default: kvm_err("%s: unknown eiointc register, addr = %d\n", __func__, addr); diff --git a/arch/loongarch/kvm/interrupt.c b/arch/loongarch/kvm/interrupt.c index 8462083f03017..a6d42d399a597 100644 --- a/arch/loongarch/kvm/interrupt.c +++ b/arch/loongarch/kvm/interrupt.c @@ -21,6 +21,7 @@ static unsigned int priority_to_irq[EXCCODE_INT_NUM] = { [INT_HWI5] = CPU_IP5, [INT_HWI6] = CPU_IP6, [INT_HWI7] = CPU_IP7, + [INT_AVEC] = CPU_AVEC, }; static int kvm_irq_deliver(struct kvm_vcpu *vcpu, unsigned int priority) @@ -31,6 +32,11 @@ static int kvm_irq_deliver(struct kvm_vcpu *vcpu, unsigned int priority) if (priority < EXCCODE_INT_NUM) irq = priority_to_irq[priority]; + if (cpu_has_msgint && (priority == INT_AVEC)) { + set_gcsr_estat(irq); + return 1; + } + switch (priority) { case INT_TI: case INT_IPI: @@ -58,6 +64,11 @@ static int kvm_irq_clear(struct kvm_vcpu *vcpu, unsigned int priority) if (priority < EXCCODE_INT_NUM) irq = priority_to_irq[priority]; + if (cpu_has_msgint && (priority == INT_AVEC)) { + clear_gcsr_estat(irq); + return 1; + } + switch (priority) { case INT_TI: case INT_IPI: @@ -83,10 +94,10 @@ void kvm_deliver_intr(struct kvm_vcpu *vcpu) unsigned long *pending = &vcpu->arch.irq_pending; unsigned long *pending_clr = &vcpu->arch.irq_clear; - for_each_set_bit(priority, pending_clr, INT_IPI + 1) + for_each_set_bit(priority, pending_clr, EXCCODE_INT_NUM) kvm_irq_clear(vcpu, priority); - for_each_set_bit(priority, pending, INT_IPI + 1) + for_each_set_bit(priority, pending, EXCCODE_INT_NUM) kvm_irq_deliver(vcpu, priority); } diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 1245a6b358966..656b954c1134b 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -9,6 +9,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include "trace.h" @@ -659,8 +660,7 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v) *v = GENMASK(31, 0); return 0; case LOONGARCH_CPUCFG1: - /* CPUCFG1_MSGINT is not supported by KVM */ - *v = GENMASK(25, 0); + *v = GENMASK(26, 0); return 0; case LOONGARCH_CPUCFG2: /* CPUCFG2 features unconditionally supported by KVM */ @@ -728,6 +728,10 @@ static int kvm_check_cpucfg(int id, u64 val) return -EINVAL; switch (id) { + case LOONGARCH_CPUCFG1: + if ((val & CPUCFG1_MSGINT) && !cpu_has_msgint) + return -EINVAL; + return 0; case LOONGARCH_CPUCFG2: if (!(val & CPUCFG2_LLFTP)) /* Guests must have a constant timer */ @@ -811,7 +815,7 @@ static int kvm_get_one_reg(struct kvm_vcpu *vcpu, case KVM_REG_LOONGARCH_KVM: switch (reg->id) { case KVM_REG_LOONGARCH_COUNTER: - *v = drdtime() + vcpu->kvm->arch.time_offset; + *v = get_cycles() + vcpu->kvm->arch.time_offset; break; case KVM_REG_LOONGARCH_DEBUG_INST: *v = INSN_HVCL | KVM_HCALL_SWDBG; @@ -906,7 +910,7 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu, * only set for the first time for smp system */ if (vcpu->vcpu_id == 0) - vcpu->kvm->arch.time_offset = (signed long)(v - drdtime()); + vcpu->kvm->arch.time_offset = (signed long)(v - get_cycles()); break; case KVM_REG_LOONGARCH_VCPU_RESET: vcpu->arch.st.guest_addr = 0; @@ -1473,8 +1477,8 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) return 0; } -long kvm_arch_vcpu_async_ioctl(struct file *filp, - unsigned int ioctl, unsigned long arg) +long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) { void __user *argp = (void __user *)arg; struct kvm_vcpu *vcpu = filp->private_data; @@ -1657,6 +1661,12 @@ static int _kvm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_DMWIN2); kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_DMWIN3); kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_LLBCTL); + if (cpu_has_msgint) { + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR0); + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR1); + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR2); + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR3); + } /* Restore Root.GINTC from unused Guest.GINTC register */ write_csr_gintc(csr->csrs[LOONGARCH_CSR_GINTC]); @@ -1746,6 +1756,12 @@ static int _kvm_vcpu_put(struct kvm_vcpu *vcpu, int cpu) kvm_save_hw_gcsr(csr, LOONGARCH_CSR_DMWIN1); kvm_save_hw_gcsr(csr, LOONGARCH_CSR_DMWIN2); kvm_save_hw_gcsr(csr, LOONGARCH_CSR_DMWIN3); + if (cpu_has_msgint) { + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR0); + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR1); + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR2); + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR3); + } vcpu->arch.aux_inuse |= KVM_LARCH_SWCSR_LATEST; diff --git a/arch/loongarch/kvm/vm.c b/arch/loongarch/kvm/vm.c index a49b1c1a3dd1f..194ccbcdc3b38 100644 --- a/arch/loongarch/kvm/vm.c +++ b/arch/loongarch/kvm/vm.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,23 @@ const struct kvm_stats_header kvm_vm_stats_header = { sizeof(kvm_vm_stats_desc), }; +static void kvm_vm_init_features(struct kvm *kvm) +{ + unsigned long val; + + val = read_csr_gcfg(); + if (val & CSR_GCFG_GPMP) + kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PMU); + + /* Enable all PV features by default */ + kvm->arch.pv_features = BIT(KVM_FEATURE_IPI); + kvm->arch.kvm_features = BIT(KVM_LOONGARCH_VM_FEAT_PV_IPI); + if (kvm_pvtime_supported()) { + kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME); + kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PV_STEALTIME); + } +} + int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) { int i; @@ -42,11 +60,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) spin_lock_init(&kvm->arch.phyid_map_lock); kvm_init_vmcs(kvm); - - /* Enable all PV features by default */ - kvm->arch.pv_features = BIT(KVM_FEATURE_IPI); - if (kvm_pvtime_supported()) - kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME); + kvm_vm_init_features(kvm); /* * cpu_vabits means user address space only (a half of total). @@ -136,18 +150,18 @@ static int kvm_vm_feature_has_attr(struct kvm *kvm, struct kvm_device_attr *attr if (cpu_has_lbt_mips) return 0; return -ENXIO; - case KVM_LOONGARCH_VM_FEAT_PMU: - if (cpu_has_pmp) + case KVM_LOONGARCH_VM_FEAT_PTW: + if (cpu_has_ptw) return 0; return -ENXIO; - case KVM_LOONGARCH_VM_FEAT_PV_IPI: - return 0; - case KVM_LOONGARCH_VM_FEAT_PV_STEALTIME: - if (kvm_pvtime_supported()) + case KVM_LOONGARCH_VM_FEAT_MSGINT: + if (cpu_has_msgint) return 0; return -ENXIO; - case KVM_LOONGARCH_VM_FEAT_PTW: - if (cpu_has_ptw) + case KVM_LOONGARCH_VM_FEAT_PMU: + case KVM_LOONGARCH_VM_FEAT_PV_IPI: + case KVM_LOONGARCH_VM_FEAT_PV_STEALTIME: + if (kvm_vm_support(&kvm->arch, attr->attr)) return 0; return -ENXIO; default: diff --git a/arch/loongarch/lib/bswapdi.c b/arch/loongarch/lib/bswapdi.c new file mode 100644 index 0000000000000..88242dc7de176 --- /dev/null +++ b/arch/loongarch/lib/bswapdi.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +/* To silence -Wmissing-prototypes. */ +unsigned long long __bswapdi2(unsigned long long u); + +unsigned long long notrace __bswapdi2(unsigned long long u) +{ + return ___constant_swab64(u); +} +EXPORT_SYMBOL(__bswapdi2); diff --git a/arch/loongarch/lib/bswapsi.c b/arch/loongarch/lib/bswapsi.c new file mode 100644 index 0000000000000..2ed655497de5c --- /dev/null +++ b/arch/loongarch/lib/bswapsi.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +/* To silence -Wmissing-prototypes. */ +unsigned int __bswapsi2(unsigned int u); + +unsigned int notrace __bswapsi2(unsigned int u) +{ + return ___constant_swab32(u); +} +EXPORT_SYMBOL(__bswapsi2); diff --git a/arch/loongarch/lib/clear_user.S b/arch/loongarch/lib/clear_user.S index 7a0db643b2866..58c667dde8829 100644 --- a/arch/loongarch/lib/clear_user.S +++ b/arch/loongarch/lib/clear_user.S @@ -13,11 +13,15 @@ #include SYM_FUNC_START(__clear_user) +#ifdef CONFIG_32BIT + b __clear_user_generic +#else /* * Some CPUs support hardware unaligned access */ ALTERNATIVE "b __clear_user_generic", \ "b __clear_user_fast", CPU_FEATURE_UAL +#endif SYM_FUNC_END(__clear_user) EXPORT_SYMBOL(__clear_user) @@ -29,19 +33,20 @@ EXPORT_SYMBOL(__clear_user) * a1: size */ SYM_FUNC_START(__clear_user_generic) - beqz a1, 2f + beqz a1, 2f -1: st.b zero, a0, 0 - addi.d a0, a0, 1 - addi.d a1, a1, -1 - bgtz a1, 1b +1: st.b zero, a0, 0 + PTR_ADDI a0, a0, 1 + PTR_ADDI a1, a1, -1 + bgtz a1, 1b -2: move a0, a1 - jr ra +2: move a0, a1 + jr ra - _asm_extable 1b, 2b + _asm_extable 1b, 2b SYM_FUNC_END(__clear_user_generic) +#ifdef CONFIG_64BIT /* * unsigned long __clear_user_fast(void *addr, unsigned long size) * @@ -207,3 +212,4 @@ SYM_FUNC_START(__clear_user_fast) SYM_FUNC_END(__clear_user_fast) STACK_FRAME_NON_STANDARD __clear_user_fast +#endif diff --git a/arch/loongarch/lib/copy_user.S b/arch/loongarch/lib/copy_user.S index 095ce9181c6c0..c7264b779f6e4 100644 --- a/arch/loongarch/lib/copy_user.S +++ b/arch/loongarch/lib/copy_user.S @@ -13,11 +13,15 @@ #include SYM_FUNC_START(__copy_user) +#ifdef CONFIG_32BIT + b __copy_user_generic +#else /* * Some CPUs support hardware unaligned access */ ALTERNATIVE "b __copy_user_generic", \ "b __copy_user_fast", CPU_FEATURE_UAL +#endif SYM_FUNC_END(__copy_user) EXPORT_SYMBOL(__copy_user) @@ -30,22 +34,23 @@ EXPORT_SYMBOL(__copy_user) * a2: n */ SYM_FUNC_START(__copy_user_generic) - beqz a2, 3f + beqz a2, 3f -1: ld.b t0, a1, 0 -2: st.b t0, a0, 0 - addi.d a0, a0, 1 - addi.d a1, a1, 1 - addi.d a2, a2, -1 - bgtz a2, 1b +1: ld.b t0, a1, 0 +2: st.b t0, a0, 0 + PTR_ADDI a0, a0, 1 + PTR_ADDI a1, a1, 1 + PTR_ADDI a2, a2, -1 + bgtz a2, 1b -3: move a0, a2 - jr ra +3: move a0, a2 + jr ra - _asm_extable 1b, 3b - _asm_extable 2b, 3b + _asm_extable 1b, 3b + _asm_extable 2b, 3b SYM_FUNC_END(__copy_user_generic) +#ifdef CONFIG_64BIT /* * unsigned long __copy_user_fast(void *to, const void *from, unsigned long n) * @@ -281,3 +286,4 @@ SYM_FUNC_START(__copy_user_fast) SYM_FUNC_END(__copy_user_fast) STACK_FRAME_NON_STANDARD __copy_user_fast +#endif diff --git a/arch/loongarch/lib/dump_tlb.c b/arch/loongarch/lib/dump_tlb.c index 0b886a6e260fa..e1cdad7a676e1 100644 --- a/arch/loongarch/lib/dump_tlb.c +++ b/arch/loongarch/lib/dump_tlb.c @@ -20,9 +20,9 @@ void dump_tlb_regs(void) pr_info("Index : 0x%0x\n", read_csr_tlbidx()); pr_info("PageSize : 0x%0x\n", read_csr_pagesize()); - pr_info("EntryHi : 0x%0*lx\n", field, read_csr_entryhi()); - pr_info("EntryLo0 : 0x%0*lx\n", field, read_csr_entrylo0()); - pr_info("EntryLo1 : 0x%0*lx\n", field, read_csr_entrylo1()); + pr_info("EntryHi : 0x%0*lx\n", field, (unsigned long)read_csr_entryhi()); + pr_info("EntryLo0 : 0x%0*lx\n", field, (unsigned long)read_csr_entrylo0()); + pr_info("EntryLo1 : 0x%0*lx\n", field, (unsigned long)read_csr_entrylo1()); } static void dump_tlb(int first, int last) @@ -73,12 +73,16 @@ static void dump_tlb(int first, int last) vwidth, (entryhi & ~0x1fffUL), asidwidth, asid & asidmask); /* NR/NX are in awkward places, so mask them off separately */ +#ifdef CONFIG_64BIT pa = entrylo0 & ~(ENTRYLO_NR | ENTRYLO_NX); +#endif pa = pa & PAGE_MASK; pr_cont("\n\t["); +#ifdef CONFIG_64BIT pr_cont("nr=%d nx=%d ", (entrylo0 & ENTRYLO_NR) ? 1 : 0, (entrylo0 & ENTRYLO_NX) ? 1 : 0); +#endif pr_cont("pa=0x%0*llx c=%d d=%d v=%d g=%d plv=%lld] [", pwidth, pa, c0, (entrylo0 & ENTRYLO_D) ? 1 : 0, @@ -86,11 +90,15 @@ static void dump_tlb(int first, int last) (entrylo0 & ENTRYLO_G) ? 1 : 0, (entrylo0 & ENTRYLO_PLV) >> ENTRYLO_PLV_SHIFT); /* NR/NX are in awkward places, so mask them off separately */ +#ifdef CONFIG_64BIT pa = entrylo1 & ~(ENTRYLO_NR | ENTRYLO_NX); +#endif pa = pa & PAGE_MASK; +#ifdef CONFIG_64BIT pr_cont("nr=%d nx=%d ", (entrylo1 & ENTRYLO_NR) ? 1 : 0, (entrylo1 & ENTRYLO_NX) ? 1 : 0); +#endif pr_cont("pa=0x%0*llx c=%d d=%d v=%d g=%d plv=%lld]\n", pwidth, pa, c1, (entrylo1 & ENTRYLO_D) ? 1 : 0, diff --git a/arch/loongarch/lib/unaligned.S b/arch/loongarch/lib/unaligned.S index 185f82d85810a..470c0bfa3463b 100644 --- a/arch/loongarch/lib/unaligned.S +++ b/arch/loongarch/lib/unaligned.S @@ -24,35 +24,35 @@ * a3: sign */ SYM_FUNC_START(unaligned_read) - beqz a2, 5f + beqz a2, 5f - li.w t2, 0 - addi.d t0, a2, -1 - slli.d t1, t0, 3 - add.d a0, a0, t0 + li.w t2, 0 + LONG_ADDI t0, a2, -1 + PTR_SLLI t1, t0, LONGLOG + PTR_ADD a0, a0, t0 - beqz a3, 2f -1: ld.b t3, a0, 0 - b 3f + beqz a3, 2f +1: ld.b t3, a0, 0 + b 3f -2: ld.bu t3, a0, 0 -3: sll.d t3, t3, t1 - or t2, t2, t3 - addi.d t1, t1, -8 - addi.d a0, a0, -1 - addi.d a2, a2, -1 - bgtz a2, 2b -4: st.d t2, a1, 0 +2: ld.bu t3, a0, 0 +3: LONG_SLLV t3, t3, t1 + or t2, t2, t3 + LONG_ADDI t1, t1, -8 + PTR_ADDI a0, a0, -1 + PTR_ADDI a2, a2, -1 + bgtz a2, 2b +4: LONG_S t2, a1, 0 - move a0, a2 - jr ra + move a0, a2 + jr ra -5: li.w a0, -EFAULT - jr ra +5: li.w a0, -EFAULT + jr ra - _asm_extable 1b, .L_fixup_handle_unaligned - _asm_extable 2b, .L_fixup_handle_unaligned - _asm_extable 4b, .L_fixup_handle_unaligned + _asm_extable 1b, .L_fixup_handle_unaligned + _asm_extable 2b, .L_fixup_handle_unaligned + _asm_extable 4b, .L_fixup_handle_unaligned SYM_FUNC_END(unaligned_read) /* @@ -63,21 +63,21 @@ SYM_FUNC_END(unaligned_read) * a2: n */ SYM_FUNC_START(unaligned_write) - beqz a2, 3f + beqz a2, 3f - li.w t0, 0 -1: srl.d t1, a1, t0 -2: st.b t1, a0, 0 - addi.d t0, t0, 8 - addi.d a2, a2, -1 - addi.d a0, a0, 1 - bgtz a2, 1b + li.w t0, 0 +1: LONG_SRLV t1, a1, t0 +2: st.b t1, a0, 0 + LONG_ADDI t0, t0, 8 + PTR_ADDI a2, a2, -1 + PTR_ADDI a0, a0, 1 + bgtz a2, 1b - move a0, a2 - jr ra + move a0, a2 + jr ra -3: li.w a0, -EFAULT - jr ra +3: li.w a0, -EFAULT + jr ra - _asm_extable 2b, .L_fixup_handle_unaligned + _asm_extable 2b, .L_fixup_handle_unaligned SYM_FUNC_END(unaligned_write) diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c index 6bfd4b8dad1b6..0946662afdd64 100644 --- a/arch/loongarch/mm/init.c +++ b/arch/loongarch/mm/init.c @@ -224,7 +224,7 @@ EXPORT_SYMBOL(invalid_pmd_table); pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss; EXPORT_SYMBOL(invalid_pte_table); -#ifdef CONFIG_EXECMEM +#if defined(CONFIG_EXECMEM) && defined(MODULES_VADDR) static struct execmem_info execmem_info __ro_after_init; struct execmem_info __init *execmem_arch_setup(void) @@ -242,4 +242,4 @@ struct execmem_info __init *execmem_arch_setup(void) return &execmem_info; } -#endif /* CONFIG_EXECMEM */ +#endif /* CONFIG_EXECMEM && MODULES_VADDR */ diff --git a/arch/loongarch/mm/page.S b/arch/loongarch/mm/page.S index 7ad76551d3133..7286b804756da 100644 --- a/arch/loongarch/mm/page.S +++ b/arch/loongarch/mm/page.S @@ -10,75 +10,75 @@ .align 5 SYM_FUNC_START(clear_page) - lu12i.w t0, 1 << (PAGE_SHIFT - 12) - add.d t0, t0, a0 + lu12i.w t0, 1 << (PAGE_SHIFT - 12) + PTR_ADD t0, t0, a0 1: - st.d zero, a0, 0 - st.d zero, a0, 8 - st.d zero, a0, 16 - st.d zero, a0, 24 - st.d zero, a0, 32 - st.d zero, a0, 40 - st.d zero, a0, 48 - st.d zero, a0, 56 - addi.d a0, a0, 128 - st.d zero, a0, -64 - st.d zero, a0, -56 - st.d zero, a0, -48 - st.d zero, a0, -40 - st.d zero, a0, -32 - st.d zero, a0, -24 - st.d zero, a0, -16 - st.d zero, a0, -8 - bne t0, a0, 1b + LONG_S zero, a0, (LONGSIZE * 0) + LONG_S zero, a0, (LONGSIZE * 1) + LONG_S zero, a0, (LONGSIZE * 2) + LONG_S zero, a0, (LONGSIZE * 3) + LONG_S zero, a0, (LONGSIZE * 4) + LONG_S zero, a0, (LONGSIZE * 5) + LONG_S zero, a0, (LONGSIZE * 6) + LONG_S zero, a0, (LONGSIZE * 7) + PTR_ADDI a0, a0, (LONGSIZE * 16) + LONG_S zero, a0, -(LONGSIZE * 8) + LONG_S zero, a0, -(LONGSIZE * 7) + LONG_S zero, a0, -(LONGSIZE * 6) + LONG_S zero, a0, -(LONGSIZE * 5) + LONG_S zero, a0, -(LONGSIZE * 4) + LONG_S zero, a0, -(LONGSIZE * 3) + LONG_S zero, a0, -(LONGSIZE * 2) + LONG_S zero, a0, -(LONGSIZE * 1) + bne t0, a0, 1b - jr ra + jr ra SYM_FUNC_END(clear_page) EXPORT_SYMBOL(clear_page) .align 5 SYM_FUNC_START(copy_page) - lu12i.w t8, 1 << (PAGE_SHIFT - 12) - add.d t8, t8, a0 + lu12i.w t8, 1 << (PAGE_SHIFT - 12) + PTR_ADD t8, t8, a0 1: - ld.d t0, a1, 0 - ld.d t1, a1, 8 - ld.d t2, a1, 16 - ld.d t3, a1, 24 - ld.d t4, a1, 32 - ld.d t5, a1, 40 - ld.d t6, a1, 48 - ld.d t7, a1, 56 + LONG_L t0, a1, (LONGSIZE * 0) + LONG_L t1, a1, (LONGSIZE * 1) + LONG_L t2, a1, (LONGSIZE * 2) + LONG_L t3, a1, (LONGSIZE * 3) + LONG_L t4, a1, (LONGSIZE * 4) + LONG_L t5, a1, (LONGSIZE * 5) + LONG_L t6, a1, (LONGSIZE * 6) + LONG_L t7, a1, (LONGSIZE * 7) - st.d t0, a0, 0 - st.d t1, a0, 8 - ld.d t0, a1, 64 - ld.d t1, a1, 72 - st.d t2, a0, 16 - st.d t3, a0, 24 - ld.d t2, a1, 80 - ld.d t3, a1, 88 - st.d t4, a0, 32 - st.d t5, a0, 40 - ld.d t4, a1, 96 - ld.d t5, a1, 104 - st.d t6, a0, 48 - st.d t7, a0, 56 - ld.d t6, a1, 112 - ld.d t7, a1, 120 - addi.d a0, a0, 128 - addi.d a1, a1, 128 + LONG_S t0, a0, (LONGSIZE * 0) + LONG_S t1, a0, (LONGSIZE * 1) + LONG_L t0, a1, (LONGSIZE * 8) + LONG_L t1, a1, (LONGSIZE * 9) + LONG_S t2, a0, (LONGSIZE * 2) + LONG_S t3, a0, (LONGSIZE * 3) + LONG_L t2, a1, (LONGSIZE * 10) + LONG_L t3, a1, (LONGSIZE * 11) + LONG_S t4, a0, (LONGSIZE * 4) + LONG_S t5, a0, (LONGSIZE * 5) + LONG_L t4, a1, (LONGSIZE * 12) + LONG_L t5, a1, (LONGSIZE * 13) + LONG_S t6, a0, (LONGSIZE * 6) + LONG_S t7, a0, (LONGSIZE * 7) + LONG_L t6, a1, (LONGSIZE * 14) + LONG_L t7, a1, (LONGSIZE * 15) + PTR_ADDI a0, a0, (LONGSIZE * 16) + PTR_ADDI a1, a1, (LONGSIZE * 16) - st.d t0, a0, -64 - st.d t1, a0, -56 - st.d t2, a0, -48 - st.d t3, a0, -40 - st.d t4, a0, -32 - st.d t5, a0, -24 - st.d t6, a0, -16 - st.d t7, a0, -8 + LONG_S t0, a0, -(LONGSIZE * 8) + LONG_S t1, a0, -(LONGSIZE * 7) + LONG_S t2, a0, -(LONGSIZE * 6) + LONG_S t3, a0, -(LONGSIZE * 5) + LONG_S t4, a0, -(LONGSIZE * 4) + LONG_S t5, a0, -(LONGSIZE * 3) + LONG_S t6, a0, -(LONGSIZE * 2) + LONG_S t7, a0, -(LONGSIZE * 1) - bne t8, a0, 1b - jr ra + bne t8, a0, 1b + jr ra SYM_FUNC_END(copy_page) EXPORT_SYMBOL(copy_page) diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c index 3b427b319db21..6a3c91b9cacdc 100644 --- a/arch/loongarch/mm/tlb.c +++ b/arch/loongarch/mm/tlb.c @@ -229,11 +229,11 @@ static void setup_ptwalker(void) if (cpu_has_ptw) pwctl1 |= CSR_PWCTL1_PTW; - csr_write64(pwctl0, LOONGARCH_CSR_PWCTL0); - csr_write64(pwctl1, LOONGARCH_CSR_PWCTL1); - csr_write64((long)swapper_pg_dir, LOONGARCH_CSR_PGDH); - csr_write64((long)invalid_pg_dir, LOONGARCH_CSR_PGDL); - csr_write64((long)smp_processor_id(), LOONGARCH_CSR_TMID); + csr_write(pwctl0, LOONGARCH_CSR_PWCTL0); + csr_write(pwctl1, LOONGARCH_CSR_PWCTL1); + csr_write((long)swapper_pg_dir, LOONGARCH_CSR_PGDH); + csr_write((long)invalid_pg_dir, LOONGARCH_CSR_PGDL); + csr_write((long)smp_processor_id(), LOONGARCH_CSR_TMID); } static void output_pgtable_bits_defines(void) @@ -251,8 +251,10 @@ static void output_pgtable_bits_defines(void) pr_define("_PAGE_GLOBAL_SHIFT %d\n", _PAGE_GLOBAL_SHIFT); pr_define("_PAGE_PRESENT_SHIFT %d\n", _PAGE_PRESENT_SHIFT); pr_define("_PAGE_WRITE_SHIFT %d\n", _PAGE_WRITE_SHIFT); +#ifdef CONFIG_64BIT pr_define("_PAGE_NO_READ_SHIFT %d\n", _PAGE_NO_READ_SHIFT); pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT); +#endif pr_define("PFN_PTE_SHIFT %d\n", PFN_PTE_SHIFT); pr_debug("\n"); } diff --git a/arch/loongarch/mm/tlbex.S b/arch/loongarch/mm/tlbex.S index c08682a89c582..84a881a339a7c 100644 --- a/arch/loongarch/mm/tlbex.S +++ b/arch/loongarch/mm/tlbex.S @@ -11,10 +11,18 @@ #define INVTLB_ADDR_GFALSE_AND_ASID 5 -#define PTRS_PER_PGD_BITS (PAGE_SHIFT - 3) -#define PTRS_PER_PUD_BITS (PAGE_SHIFT - 3) -#define PTRS_PER_PMD_BITS (PAGE_SHIFT - 3) -#define PTRS_PER_PTE_BITS (PAGE_SHIFT - 3) +#define PTRS_PER_PGD_BITS (PAGE_SHIFT - PTRLOG) +#define PTRS_PER_PUD_BITS (PAGE_SHIFT - PTRLOG) +#define PTRS_PER_PMD_BITS (PAGE_SHIFT - PTRLOG) +#define PTRS_PER_PTE_BITS (PAGE_SHIFT - PTRLOG) + +#ifdef CONFIG_32BIT +#define PTE_LL ll.w +#define PTE_SC sc.w +#else +#define PTE_LL ll.d +#define PTE_SC sc.d +#endif .macro tlb_do_page_fault, write SYM_CODE_START(tlb_do_page_fault_\write) @@ -60,52 +68,61 @@ SYM_CODE_START(handle_tlb_load) vmalloc_done_load: /* Get PGD offset in bytes */ - bstrpick.d ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT - alsl.d t1, ra, t1, 3 +#ifdef CONFIG_32BIT + PTR_BSTRPICK ra, t0, 31, PGDIR_SHIFT +#else + PTR_BSTRPICK ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT +#endif + PTR_ALSL t1, ra, t1, _PGD_T_LOG2 + #if CONFIG_PGTABLE_LEVELS > 3 - ld.d t1, t1, 0 - bstrpick.d ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT - alsl.d t1, ra, t1, 3 + PTR_L t1, t1, 0 + PTR_BSTRPICK ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT + PTR_ALSL t1, ra, t1, _PMD_T_LOG2 + #endif #if CONFIG_PGTABLE_LEVELS > 2 - ld.d t1, t1, 0 - bstrpick.d ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT - alsl.d t1, ra, t1, 3 + PTR_L t1, t1, 0 + PTR_BSTRPICK ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT + PTR_ALSL t1, ra, t1, _PMD_T_LOG2 + #endif - ld.d ra, t1, 0 + PTR_L ra, t1, 0 /* * For huge tlb entries, pmde doesn't contain an address but * instead contains the tlb pte. Check the PAGE_HUGE bit and * see if we need to jump to huge tlb processing. */ - rotri.d ra, ra, _PAGE_HUGE_SHIFT + 1 + PTR_ROTRI ra, ra, _PAGE_HUGE_SHIFT + 1 bltz ra, tlb_huge_update_load - rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1) - bstrpick.d t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT - alsl.d t1, t0, ra, _PTE_T_LOG2 + PTR_ROTRI ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1) + PTR_BSTRPICK t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT + PTR_ALSL t1, t0, ra, _PTE_T_LOG2 #ifdef CONFIG_SMP smp_pgtable_change_load: - ll.d t0, t1, 0 + PTE_LL t0, t1, 0 #else - ld.d t0, t1, 0 + PTR_L t0, t1, 0 #endif andi ra, t0, _PAGE_PRESENT beqz ra, nopage_tlb_load ori t0, t0, _PAGE_VALID + #ifdef CONFIG_SMP - sc.d t0, t1, 0 + PTE_SC t0, t1, 0 beqz t0, smp_pgtable_change_load #else - st.d t0, t1, 0 + PTR_S t0, t1, 0 #endif + tlbsrch - bstrins.d t1, zero, 3, 3 - ld.d t0, t1, 0 - ld.d t1, t1, 8 + PTR_BSTRINS t1, zero, _PTE_T_LOG2, _PTE_T_LOG2 + PTR_L t0, t1, 0 + PTR_L t1, t1, _PTE_T_SIZE csrwr t0, LOONGARCH_CSR_TLBELO0 csrwr t1, LOONGARCH_CSR_TLBELO1 tlbwr @@ -115,30 +132,28 @@ smp_pgtable_change_load: csrrd ra, EXCEPTION_KS2 ertn -#ifdef CONFIG_64BIT vmalloc_load: la_abs t1, swapper_pg_dir b vmalloc_done_load -#endif /* This is the entry point of a huge page. */ tlb_huge_update_load: #ifdef CONFIG_SMP - ll.d ra, t1, 0 + PTE_LL ra, t1, 0 #else - rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1) + PTR_ROTRI ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1) #endif andi t0, ra, _PAGE_PRESENT beqz t0, nopage_tlb_load #ifdef CONFIG_SMP ori t0, ra, _PAGE_VALID - sc.d t0, t1, 0 + PTE_SC t0, t1, 0 beqz t0, tlb_huge_update_load ori t0, ra, _PAGE_VALID #else ori t0, ra, _PAGE_VALID - st.d t0, t1, 0 + PTR_S t0, t1, 0 #endif csrrd ra, LOONGARCH_CSR_ASID csrrd t1, LOONGARCH_CSR_BADV @@ -158,27 +173,27 @@ tlb_huge_update_load: xori t0, t0, _PAGE_HUGE lu12i.w t1, _PAGE_HGLOBAL >> 12 and t1, t0, t1 - srli.d t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT) + PTR_SRLI t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT) or t0, t0, t1 move ra, t0 csrwr ra, LOONGARCH_CSR_TLBELO0 /* Convert to entrylo1 */ - addi.d t1, zero, 1 - slli.d t1, t1, (HPAGE_SHIFT - 1) - add.d t0, t0, t1 + PTR_ADDI t1, zero, 1 + PTR_SLLI t1, t1, (HPAGE_SHIFT - 1) + PTR_ADD t0, t0, t1 csrwr t0, LOONGARCH_CSR_TLBELO1 /* Set huge page tlb entry size */ - addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16) - addu16i.d t1, zero, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16)) + PTR_LI t0, (CSR_TLBIDX_PS >> 16) << 16 + PTR_LI t1, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT)) csrxchg t1, t0, LOONGARCH_CSR_TLBIDX tlbfill - addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16) - addu16i.d t1, zero, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16)) + PTR_LI t0, (CSR_TLBIDX_PS >> 16) << 16 + PTR_LI t1, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT)) csrxchg t1, t0, LOONGARCH_CSR_TLBIDX csrrd t0, EXCEPTION_KS0 @@ -216,53 +231,71 @@ SYM_CODE_START(handle_tlb_store) vmalloc_done_store: /* Get PGD offset in bytes */ - bstrpick.d ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT - alsl.d t1, ra, t1, 3 +#ifdef CONFIG_32BIT + PTR_BSTRPICK ra, t0, 31, PGDIR_SHIFT +#else + PTR_BSTRPICK ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT +#endif + PTR_ALSL t1, ra, t1, _PGD_T_LOG2 + #if CONFIG_PGTABLE_LEVELS > 3 - ld.d t1, t1, 0 - bstrpick.d ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT - alsl.d t1, ra, t1, 3 + PTR_L t1, t1, 0 + PTR_BSTRPICK ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT + PTR_ALSL t1, ra, t1, _PMD_T_LOG2 #endif #if CONFIG_PGTABLE_LEVELS > 2 - ld.d t1, t1, 0 - bstrpick.d ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT - alsl.d t1, ra, t1, 3 + PTR_L t1, t1, 0 + PTR_BSTRPICK ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT + PTR_ALSL t1, ra, t1, _PMD_T_LOG2 #endif - ld.d ra, t1, 0 + PTR_L ra, t1, 0 /* * For huge tlb entries, pmde doesn't contain an address but * instead contains the tlb pte. Check the PAGE_HUGE bit and * see if we need to jump to huge tlb processing. */ - rotri.d ra, ra, _PAGE_HUGE_SHIFT + 1 + PTR_ROTRI ra, ra, _PAGE_HUGE_SHIFT + 1 bltz ra, tlb_huge_update_store - rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1) - bstrpick.d t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT - alsl.d t1, t0, ra, _PTE_T_LOG2 + PTR_ROTRI ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1) + PTR_BSTRPICK t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT + PTR_ALSL t1, t0, ra, _PTE_T_LOG2 #ifdef CONFIG_SMP smp_pgtable_change_store: - ll.d t0, t1, 0 + PTE_LL t0, t1, 0 #else - ld.d t0, t1, 0 + PTR_L t0, t1, 0 #endif + +#ifdef CONFIG_64BIT andi ra, t0, _PAGE_PRESENT | _PAGE_WRITE xori ra, ra, _PAGE_PRESENT | _PAGE_WRITE +#else + PTR_LI ra, _PAGE_PRESENT | _PAGE_WRITE + and ra, ra, t0 + nor ra, ra, zero +#endif bnez ra, nopage_tlb_store +#ifdef CONFIG_64BIT ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) +#else + PTR_LI ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) + or t0, ra, t0 +#endif + #ifdef CONFIG_SMP - sc.d t0, t1, 0 + PTE_SC t0, t1, 0 beqz t0, smp_pgtable_change_store #else - st.d t0, t1, 0 + PTR_S t0, t1, 0 #endif tlbsrch - bstrins.d t1, zero, 3, 3 - ld.d t0, t1, 0 - ld.d t1, t1, 8 + PTR_BSTRINS t1, zero, _PTE_T_LOG2, _PTE_T_LOG2 + PTR_L t0, t1, 0 + PTR_L t1, t1, _PTE_T_SIZE csrwr t0, LOONGARCH_CSR_TLBELO0 csrwr t1, LOONGARCH_CSR_TLBELO1 tlbwr @@ -272,31 +305,42 @@ smp_pgtable_change_store: csrrd ra, EXCEPTION_KS2 ertn -#ifdef CONFIG_64BIT vmalloc_store: la_abs t1, swapper_pg_dir b vmalloc_done_store -#endif /* This is the entry point of a huge page. */ tlb_huge_update_store: #ifdef CONFIG_SMP - ll.d ra, t1, 0 + PTE_LL ra, t1, 0 #else - rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1) + PTR_ROTRI ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1) #endif + +#ifdef CONFIG_64BIT andi t0, ra, _PAGE_PRESENT | _PAGE_WRITE xori t0, t0, _PAGE_PRESENT | _PAGE_WRITE +#else + PTR_LI t0, _PAGE_PRESENT | _PAGE_WRITE + and t0, t0, ra + nor t0, t0, zero +#endif + bnez t0, nopage_tlb_store #ifdef CONFIG_SMP ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) - sc.d t0, t1, 0 + PTE_SC t0, t1, 0 beqz t0, tlb_huge_update_store ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) #else +#ifdef CONFIG_64BIT ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) - st.d t0, t1, 0 +#else + PTR_LI t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) + or t0, ra, t0 +#endif + PTR_S t0, t1, 0 #endif csrrd ra, LOONGARCH_CSR_ASID csrrd t1, LOONGARCH_CSR_BADV @@ -316,28 +360,28 @@ tlb_huge_update_store: xori t0, t0, _PAGE_HUGE lu12i.w t1, _PAGE_HGLOBAL >> 12 and t1, t0, t1 - srli.d t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT) + PTR_SRLI t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT) or t0, t0, t1 move ra, t0 csrwr ra, LOONGARCH_CSR_TLBELO0 /* Convert to entrylo1 */ - addi.d t1, zero, 1 - slli.d t1, t1, (HPAGE_SHIFT - 1) - add.d t0, t0, t1 + PTR_ADDI t1, zero, 1 + PTR_SLLI t1, t1, (HPAGE_SHIFT - 1) + PTR_ADD t0, t0, t1 csrwr t0, LOONGARCH_CSR_TLBELO1 /* Set huge page tlb entry size */ - addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16) - addu16i.d t1, zero, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16)) + PTR_LI t0, (CSR_TLBIDX_PS >> 16) << 16 + PTR_LI t1, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT)) csrxchg t1, t0, LOONGARCH_CSR_TLBIDX tlbfill /* Reset default page size */ - addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16) - addu16i.d t1, zero, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16)) + PTR_LI t0, (CSR_TLBIDX_PS >> 16) << 16 + PTR_LI t1, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT)) csrxchg t1, t0, LOONGARCH_CSR_TLBIDX csrrd t0, EXCEPTION_KS0 @@ -375,52 +419,69 @@ SYM_CODE_START(handle_tlb_modify) vmalloc_done_modify: /* Get PGD offset in bytes */ - bstrpick.d ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT - alsl.d t1, ra, t1, 3 +#ifdef CONFIG_32BIT + PTR_BSTRPICK ra, t0, 31, PGDIR_SHIFT +#else + PTR_BSTRPICK ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT +#endif + PTR_ALSL t1, ra, t1, _PGD_T_LOG2 + #if CONFIG_PGTABLE_LEVELS > 3 - ld.d t1, t1, 0 - bstrpick.d ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT - alsl.d t1, ra, t1, 3 + PTR_L t1, t1, 0 + PTR_BSTRPICK ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT + PTR_ALSL t1, ra, t1, _PMD_T_LOG2 #endif #if CONFIG_PGTABLE_LEVELS > 2 - ld.d t1, t1, 0 - bstrpick.d ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT - alsl.d t1, ra, t1, 3 + PTR_L t1, t1, 0 + PTR_BSTRPICK ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT + PTR_ALSL t1, ra, t1, _PMD_T_LOG2 #endif - ld.d ra, t1, 0 + PTR_L ra, t1, 0 /* * For huge tlb entries, pmde doesn't contain an address but * instead contains the tlb pte. Check the PAGE_HUGE bit and * see if we need to jump to huge tlb processing. */ - rotri.d ra, ra, _PAGE_HUGE_SHIFT + 1 + PTR_ROTRI ra, ra, _PAGE_HUGE_SHIFT + 1 bltz ra, tlb_huge_update_modify - rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1) - bstrpick.d t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT - alsl.d t1, t0, ra, _PTE_T_LOG2 + PTR_ROTRI ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1) + PTR_BSTRPICK t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT + PTR_ALSL t1, t0, ra, _PTE_T_LOG2 #ifdef CONFIG_SMP smp_pgtable_change_modify: - ll.d t0, t1, 0 + PTE_LL t0, t1, 0 #else - ld.d t0, t1, 0 + PTR_L t0, t1, 0 #endif +#ifdef CONFIG_64BIT andi ra, t0, _PAGE_WRITE +#else + PTR_LI ra, _PAGE_WRITE + and ra, t0, ra +#endif + beqz ra, nopage_tlb_modify +#ifdef CONFIG_64BIT ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) +#else + PTR_LI ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) + or t0, ra, t0 +#endif + #ifdef CONFIG_SMP - sc.d t0, t1, 0 + PTE_SC t0, t1, 0 beqz t0, smp_pgtable_change_modify #else - st.d t0, t1, 0 + PTR_S t0, t1, 0 #endif tlbsrch - bstrins.d t1, zero, 3, 3 - ld.d t0, t1, 0 - ld.d t1, t1, 8 + PTR_BSTRINS t1, zero, _PTE_T_LOG2, _PTE_T_LOG2 + PTR_L t0, t1, 0 + PTR_L t1, t1, _PTE_T_SIZE csrwr t0, LOONGARCH_CSR_TLBELO0 csrwr t1, LOONGARCH_CSR_TLBELO1 tlbwr @@ -430,30 +491,40 @@ smp_pgtable_change_modify: csrrd ra, EXCEPTION_KS2 ertn -#ifdef CONFIG_64BIT vmalloc_modify: la_abs t1, swapper_pg_dir b vmalloc_done_modify -#endif /* This is the entry point of a huge page. */ tlb_huge_update_modify: #ifdef CONFIG_SMP - ll.d ra, t1, 0 + PTE_LL ra, t1, 0 #else - rotri.d ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1) + PTR_ROTRI ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1) #endif + +#ifdef CONFIG_64BIT andi t0, ra, _PAGE_WRITE +#else + PTR_LI t0, _PAGE_WRITE + and t0, ra, t0 +#endif + beqz t0, nopage_tlb_modify #ifdef CONFIG_SMP ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) - sc.d t0, t1, 0 + PTE_SC t0, t1, 0 beqz t0, tlb_huge_update_modify ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) #else +#ifdef CONFIG_64BIT ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) - st.d t0, t1, 0 +#else + PTR_LI t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED) + or t0, ra, t0 +#endif + PTR_S t0, t1, 0 #endif csrrd ra, LOONGARCH_CSR_ASID csrrd t1, LOONGARCH_CSR_BADV @@ -473,28 +544,28 @@ tlb_huge_update_modify: xori t0, t0, _PAGE_HUGE lu12i.w t1, _PAGE_HGLOBAL >> 12 and t1, t0, t1 - srli.d t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT) + PTR_SRLI t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT) or t0, t0, t1 move ra, t0 csrwr ra, LOONGARCH_CSR_TLBELO0 /* Convert to entrylo1 */ - addi.d t1, zero, 1 - slli.d t1, t1, (HPAGE_SHIFT - 1) - add.d t0, t0, t1 + PTR_ADDI t1, zero, 1 + PTR_SLLI t1, t1, (HPAGE_SHIFT - 1) + PTR_ADD t0, t0, t1 csrwr t0, LOONGARCH_CSR_TLBELO1 /* Set huge page tlb entry size */ - addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16) - addu16i.d t1, zero, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16)) + PTR_LI t0, (CSR_TLBIDX_PS >> 16) << 16 + PTR_LI t1, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT)) csrxchg t1, t0, LOONGARCH_CSR_TLBIDX tlbfill /* Reset default page size */ - addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16) - addu16i.d t1, zero, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16)) + PTR_LI t0, (CSR_TLBIDX_PS >> 16) << 16 + PTR_LI t1, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT)) csrxchg t1, t0, LOONGARCH_CSR_TLBIDX csrrd t0, EXCEPTION_KS0 @@ -517,6 +588,44 @@ SYM_CODE_START(handle_tlb_modify_ptw) jr t0 SYM_CODE_END(handle_tlb_modify_ptw) +#ifdef CONFIG_32BIT +SYM_CODE_START(handle_tlb_refill) + UNWIND_HINT_UNDEFINED + csrwr t0, EXCEPTION_KS0 + csrwr t1, EXCEPTION_KS1 + csrwr ra, EXCEPTION_KS2 + li.w ra, 0x1fffffff + + csrrd t0, LOONGARCH_CSR_PGD + csrrd t1, LOONGARCH_CSR_TLBRBADV + srli.w t1, t1, PGDIR_SHIFT + slli.w t1, t1, 0x2 + add.w t0, t0, t1 + and t0, t0, ra + + ld.w t0, t0, 0 + csrrd t1, LOONGARCH_CSR_TLBRBADV + slli.w t1, t1, (32 - PGDIR_SHIFT) + srli.w t1, t1, (32 - PGDIR_SHIFT + PAGE_SHIFT + 1) + slli.w t1, t1, (0x2 + 1) + add.w t0, t0, t1 + and t0, t0, ra + + ld.w t1, t0, 0x0 + csrwr t1, LOONGARCH_CSR_TLBRELO0 + + ld.w t1, t0, 0x4 + csrwr t1, LOONGARCH_CSR_TLBRELO1 + + tlbfill + csrrd t0, EXCEPTION_KS0 + csrrd t1, EXCEPTION_KS1 + csrrd ra, EXCEPTION_KS2 + ertn +SYM_CODE_END(handle_tlb_refill) +#endif + +#ifdef CONFIG_64BIT SYM_CODE_START(handle_tlb_refill) UNWIND_HINT_UNDEFINED csrwr t0, LOONGARCH_CSR_TLBRSAVE @@ -534,3 +643,4 @@ SYM_CODE_START(handle_tlb_refill) csrrd t0, LOONGARCH_CSR_TLBRSAVE ertn SYM_CODE_END(handle_tlb_refill) +#endif diff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index d9fc5d520b377..d923295ab8c66 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -14,6 +14,7 @@ #define PCI_DEVICE_ID_LOONGSON_HOST 0x7a00 #define PCI_DEVICE_ID_LOONGSON_DC1 0x7a06 #define PCI_DEVICE_ID_LOONGSON_DC2 0x7a36 +#define PCI_DEVICE_ID_LOONGSON_DC3 0x7a46 int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, int reg, int len, u32 *val) @@ -97,3 +98,4 @@ static void pci_fixup_vgadev(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC1, pci_fixup_vgadev); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC2, pci_fixup_vgadev); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC3, pci_fixup_vgadev); diff --git a/arch/loongarch/power/hibernate.c b/arch/loongarch/power/hibernate.c index e7b7346592cb2..817270410ef98 100644 --- a/arch/loongarch/power/hibernate.c +++ b/arch/loongarch/power/hibernate.c @@ -10,7 +10,7 @@ static u32 saved_crmd; static u32 saved_prmd; static u32 saved_euen; static u32 saved_ecfg; -static u64 saved_pcpu_base; +static unsigned long saved_pcpu_base; struct pt_regs saved_regs; void save_processor_state(void) @@ -20,7 +20,7 @@ void save_processor_state(void) saved_prmd = csr_read32(LOONGARCH_CSR_PRMD); saved_euen = csr_read32(LOONGARCH_CSR_EUEN); saved_ecfg = csr_read32(LOONGARCH_CSR_ECFG); - saved_pcpu_base = csr_read64(PERCPU_BASE_KS); + saved_pcpu_base = csr_read(PERCPU_BASE_KS); if (is_fpu_owner()) save_fp(current); @@ -33,7 +33,7 @@ void restore_processor_state(void) csr_write32(saved_prmd, LOONGARCH_CSR_PRMD); csr_write32(saved_euen, LOONGARCH_CSR_EUEN); csr_write32(saved_ecfg, LOONGARCH_CSR_ECFG); - csr_write64(saved_pcpu_base, PERCPU_BASE_KS); + csr_write(saved_pcpu_base, PERCPU_BASE_KS); if (is_fpu_owner()) restore_fp(current); diff --git a/arch/loongarch/power/platform.c b/arch/loongarch/power/platform.c index 5bbdb9fd76e5d..faa4fe4e7461c 100644 --- a/arch/loongarch/power/platform.c +++ b/arch/loongarch/power/platform.c @@ -72,10 +72,10 @@ static int __init loongson3_acpi_suspend_init(void) status = acpi_evaluate_integer(NULL, "\\SADR", NULL, &suspend_addr); if (ACPI_FAILURE(status) || !suspend_addr) { pr_info("ACPI S3 supported with hardware register default\n"); - loongson_sysconf.suspend_addr = (u64)default_suspend_addr; + loongson_sysconf.suspend_addr = (unsigned long)default_suspend_addr; } else { pr_info("ACPI S3 supported with Loongson ACPI SADR extension\n"); - loongson_sysconf.suspend_addr = (u64)phys_to_virt(PHYSADDR(suspend_addr)); + loongson_sysconf.suspend_addr = (unsigned long)phys_to_virt(PHYSADDR(suspend_addr)); } #endif return 0; diff --git a/arch/loongarch/power/suspend.c b/arch/loongarch/power/suspend.c index c9e594925c473..7e3d79f8bbd4e 100644 --- a/arch/loongarch/power/suspend.c +++ b/arch/loongarch/power/suspend.c @@ -20,24 +20,24 @@ u64 loongarch_suspend_addr; struct saved_registers { u32 ecfg; u32 euen; - u64 pgd; - u64 kpgd; u32 pwctl0; u32 pwctl1; - u64 pcpu_base; + unsigned long pgd; + unsigned long kpgd; + unsigned long pcpu_base; }; static struct saved_registers saved_regs; void loongarch_common_suspend(void) { save_counter(); - saved_regs.pgd = csr_read64(LOONGARCH_CSR_PGDL); - saved_regs.kpgd = csr_read64(LOONGARCH_CSR_PGDH); + saved_regs.pgd = csr_read(LOONGARCH_CSR_PGDL); + saved_regs.kpgd = csr_read(LOONGARCH_CSR_PGDH); saved_regs.pwctl0 = csr_read32(LOONGARCH_CSR_PWCTL0); saved_regs.pwctl1 = csr_read32(LOONGARCH_CSR_PWCTL1); saved_regs.ecfg = csr_read32(LOONGARCH_CSR_ECFG); saved_regs.euen = csr_read32(LOONGARCH_CSR_EUEN); - saved_regs.pcpu_base = csr_read64(PERCPU_BASE_KS); + saved_regs.pcpu_base = csr_read(PERCPU_BASE_KS); loongarch_suspend_addr = loongson_sysconf.suspend_addr; } @@ -46,17 +46,17 @@ void loongarch_common_resume(void) { sync_counter(); local_flush_tlb_all(); - csr_write64(eentry, LOONGARCH_CSR_EENTRY); - csr_write64(eentry, LOONGARCH_CSR_MERRENTRY); - csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY); + csr_write(eentry, LOONGARCH_CSR_EENTRY); + csr_write(eentry, LOONGARCH_CSR_MERRENTRY); + csr_write(tlbrentry, LOONGARCH_CSR_TLBRENTRY); - csr_write64(saved_regs.pgd, LOONGARCH_CSR_PGDL); - csr_write64(saved_regs.kpgd, LOONGARCH_CSR_PGDH); + csr_write(saved_regs.pgd, LOONGARCH_CSR_PGDL); + csr_write(saved_regs.kpgd, LOONGARCH_CSR_PGDH); csr_write32(saved_regs.pwctl0, LOONGARCH_CSR_PWCTL0); csr_write32(saved_regs.pwctl1, LOONGARCH_CSR_PWCTL1); csr_write32(saved_regs.ecfg, LOONGARCH_CSR_ECFG); csr_write32(saved_regs.euen, LOONGARCH_CSR_EUEN); - csr_write64(saved_regs.pcpu_base, PERCPU_BASE_KS); + csr_write(saved_regs.pcpu_base, PERCPU_BASE_KS); } int loongarch_acpi_suspend(void) diff --git a/arch/loongarch/power/suspend_asm.S b/arch/loongarch/power/suspend_asm.S index df0865df26fae..c8119ad5fb2c8 100644 --- a/arch/loongarch/power/suspend_asm.S +++ b/arch/loongarch/power/suspend_asm.S @@ -14,41 +14,41 @@ /* preparatory stuff */ .macro SETUP_SLEEP - addi.d sp, sp, -PT_SIZE - st.d $r1, sp, PT_R1 - st.d $r2, sp, PT_R2 - st.d $r3, sp, PT_R3 - st.d $r4, sp, PT_R4 - st.d $r21, sp, PT_R21 - st.d $r22, sp, PT_R22 - st.d $r23, sp, PT_R23 - st.d $r24, sp, PT_R24 - st.d $r25, sp, PT_R25 - st.d $r26, sp, PT_R26 - st.d $r27, sp, PT_R27 - st.d $r28, sp, PT_R28 - st.d $r29, sp, PT_R29 - st.d $r30, sp, PT_R30 - st.d $r31, sp, PT_R31 + PTR_ADDI sp, sp, -PT_SIZE + REG_S $r1, sp, PT_R1 + REG_S $r2, sp, PT_R2 + REG_S $r3, sp, PT_R3 + REG_S $r4, sp, PT_R4 + REG_S $r21, sp, PT_R21 + REG_S $r22, sp, PT_R22 + REG_S $r23, sp, PT_R23 + REG_S $r24, sp, PT_R24 + REG_S $r25, sp, PT_R25 + REG_S $r26, sp, PT_R26 + REG_S $r27, sp, PT_R27 + REG_S $r28, sp, PT_R28 + REG_S $r29, sp, PT_R29 + REG_S $r30, sp, PT_R30 + REG_S $r31, sp, PT_R31 .endm .macro SETUP_WAKEUP - ld.d $r1, sp, PT_R1 - ld.d $r2, sp, PT_R2 - ld.d $r3, sp, PT_R3 - ld.d $r4, sp, PT_R4 - ld.d $r21, sp, PT_R21 - ld.d $r22, sp, PT_R22 - ld.d $r23, sp, PT_R23 - ld.d $r24, sp, PT_R24 - ld.d $r25, sp, PT_R25 - ld.d $r26, sp, PT_R26 - ld.d $r27, sp, PT_R27 - ld.d $r28, sp, PT_R28 - ld.d $r29, sp, PT_R29 - ld.d $r30, sp, PT_R30 - ld.d $r31, sp, PT_R31 - addi.d sp, sp, PT_SIZE + REG_L $r1, sp, PT_R1 + REG_L $r2, sp, PT_R2 + REG_L $r3, sp, PT_R3 + REG_L $r4, sp, PT_R4 + REG_L $r21, sp, PT_R21 + REG_L $r22, sp, PT_R22 + REG_L $r23, sp, PT_R23 + REG_L $r24, sp, PT_R24 + REG_L $r25, sp, PT_R25 + REG_L $r26, sp, PT_R26 + REG_L $r27, sp, PT_R27 + REG_L $r28, sp, PT_R28 + REG_L $r29, sp, PT_R29 + REG_L $r30, sp, PT_R30 + REG_L $r31, sp, PT_R31 + PTR_ADDI sp, sp, PT_SIZE .endm .text @@ -59,15 +59,15 @@ SYM_FUNC_START(loongarch_suspend_enter) SETUP_SLEEP la.pcrel t0, acpi_saved_sp - st.d sp, t0, 0 + REG_S sp, t0, 0 bl __flush_cache_all /* Pass RA and SP to BIOS */ - addi.d a1, sp, 0 + PTR_ADDI a1, sp, 0 la.pcrel a0, loongarch_wakeup_start la.pcrel t0, loongarch_suspend_addr - ld.d t0, t0, 0 + REG_L t0, t0, 0 jirl ra, t0, 0 /* Call BIOS's STR sleep routine */ /* @@ -83,7 +83,7 @@ SYM_INNER_LABEL(loongarch_wakeup_start, SYM_L_GLOBAL) csrwr t0, LOONGARCH_CSR_CRMD la.pcrel t0, acpi_saved_sp - ld.d sp, t0, 0 + REG_L sp, t0, 0 SETUP_WAKEUP jr ra diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile index c0cc3ca5da9f4..520f1513f07dd 100644 --- a/arch/loongarch/vdso/Makefile +++ b/arch/loongarch/vdso/Makefile @@ -4,8 +4,9 @@ # Include the generic Makefile to check the built vdso. include $(srctree)/lib/vdso/Makefile.include -obj-vdso-y := elf.o vgetcpu.o vgettimeofday.o vgetrandom.o \ +obj-vdso-y := elf.o vgetcpu.o vgetrandom.o \ vgetrandom-chacha.o sigreturn.o +obj-vdso-$(CONFIG_GENERIC_GETTIMEOFDAY) += vgettimeofday.o # Common compiler flags between ABIs. ccflags-vdso := \ @@ -16,6 +17,10 @@ ccflags-vdso := \ $(CLANG_FLAGS) \ -D__VDSO__ +ifdef CONFIG_32BIT +ccflags-vdso += -DBUILD_VDSO32 +endif + cflags-vdso := $(ccflags-vdso) \ -isystem $(shell $(CC) -print-file-name=include) \ $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ diff --git a/arch/loongarch/vdso/vdso.lds.S b/arch/loongarch/vdso/vdso.lds.S index 8ff9864999475..ac537e02beb18 100644 --- a/arch/loongarch/vdso/vdso.lds.S +++ b/arch/loongarch/vdso/vdso.lds.S @@ -7,8 +7,6 @@ #include #include -OUTPUT_FORMAT("elf64-loongarch", "elf64-loongarch", "elf64-loongarch") - OUTPUT_ARCH(loongarch) SECTIONS @@ -63,9 +61,11 @@ VERSION LINUX_5.10 { global: __vdso_getcpu; +#ifdef CONFIG_GENERIC_GETTIMEOFDAY __vdso_clock_getres; __vdso_clock_gettime; __vdso_gettimeofday; +#endif __vdso_getrandom; __vdso_rt_sigreturn; local: *; diff --git a/arch/loongarch/vdso/vgetcpu.c b/arch/loongarch/vdso/vgetcpu.c index 5301cd9d0f839..73af49242ecdc 100644 --- a/arch/loongarch/vdso/vgetcpu.c +++ b/arch/loongarch/vdso/vgetcpu.c @@ -10,11 +10,19 @@ static __always_inline int read_cpu_id(void) { int cpu_id; +#ifdef CONFIG_64BIT __asm__ __volatile__( " rdtime.d $zero, %0\n" : "=r" (cpu_id) : : "memory"); +#else + __asm__ __volatile__( + " rdtimel.w $zero, %0\n" + : "=r" (cpu_id) + : + : "memory"); +#endif return cpu_id; } diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e8683f58fd3e2..b88b97139fa8e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -658,7 +658,7 @@ config EYEQ select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN select USE_OF - select HOTPLUG_PARALLEL if SMP + select HOTPLUG_PARALLEL if HOTPLUG_CPU help Select this to build a kernel supporting EyeQ SoC from Mobileye. diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c index 68ea575116290..cb6be58808a08 100644 --- a/arch/mips/alchemy/board-mtx1.c +++ b/arch/mips/alchemy/board-mtx1.c @@ -9,10 +9,8 @@ #include #include #include -#include -#include #include -#include +#include #include #include #include @@ -80,64 +78,134 @@ void __init board_setup(void) /******************************************************************************/ -static struct gpio_keys_button mtx1_gpio_button[] = { - { - .gpio = 207, - .code = BTN_0, - .desc = "System button", - } +static const struct software_node mtx1_gpiochip_node = { + .name = "alchemy-gpio2", }; -static struct gpio_keys_platform_data mtx1_buttons_data = { - .buttons = mtx1_gpio_button, - .nbuttons = ARRAY_SIZE(mtx1_gpio_button), +static const struct software_node mtx1_gpio_keys_node = { + .name = "mtx1-gpio-keys", }; -static struct platform_device mtx1_button = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &mtx1_buttons_data, - } +static const struct property_entry mtx1_button_props[] = { + PROPERTY_ENTRY_U32("linux,code", BTN_0), + PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 7, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_STRING("label", "System button"), + { } }; -static struct gpiod_lookup_table mtx1_wdt_gpio_table = { - .dev_id = "mtx1-wdt.0", - .table = { - /* Global number 215 is offset 15 on Alchemy GPIO 2 */ - GPIO_LOOKUP("alchemy-gpio2", 15, NULL, GPIO_ACTIVE_HIGH), - { }, - }, +static const struct software_node mtx1_button_node = { + .parent = &mtx1_gpio_keys_node, + .properties = mtx1_button_props, +}; + +static const struct software_node *mtx1_gpio_keys_swnodes[] __initconst = { + &mtx1_gpio_keys_node, + &mtx1_button_node, + NULL }; -static struct platform_device mtx1_wdt = { +static void __init mtx1_keys_init(void) +{ + struct platform_device_info keys_info = { + .name = "gpio-keys", + .id = PLATFORM_DEVID_NONE, + }; + struct platform_device *pd; + int err; + + err = software_node_register_node_group(mtx1_gpio_keys_swnodes); + if (err) { + pr_err("failed to register gpio-keys software nodes: %d\n", err); + return; + } + + keys_info.fwnode = software_node_fwnode(&mtx1_gpio_keys_node); + + pd = platform_device_register_full(&keys_info); + err = PTR_ERR_OR_ZERO(pd); + if (err) + pr_err("failed to create gpio-keys device: %d\n", err); +} + +/* Global number 215 is offset 15 on Alchemy GPIO 2 */ +static const struct property_entry mtx1_wdt_props[] = { + PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 15, GPIO_ACTIVE_HIGH), + { } +}; + +static struct platform_device_info mtx1_wdt_info __initconst = { .name = "mtx1-wdt", .id = 0, + .properties = mtx1_wdt_props, }; -static const struct gpio_led default_leds[] = { - { - .name = "mtx1:green", - .gpio = 211, - }, { - .name = "mtx1:red", - .gpio = 212, - }, +static void __init mtx1_wdt_init(void) +{ + struct platform_device *pd; + int err; + + pd = platform_device_register_full(&mtx1_wdt_info); + err = PTR_ERR_OR_ZERO(pd); + if (err) + pr_err("failed to create gpio-keys device: %d\n", err); +} + +static const struct software_node mtx1_gpio_leds_node = { + .name = "mtx1-leds", }; -static struct gpio_led_platform_data mtx1_led_data = { - .num_leds = ARRAY_SIZE(default_leds), - .leds = default_leds, +static const struct property_entry mtx1_green_led_props[] = { + PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 11, GPIO_ACTIVE_HIGH), + { } }; -static struct platform_device mtx1_gpio_leds = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &mtx1_led_data, - } +static const struct software_node mtx1_green_led_node = { + .name = "mtx1:green", + .parent = &mtx1_gpio_leds_node, + .properties = mtx1_green_led_props, }; +static const struct property_entry mtx1_red_led_props[] = { + PROPERTY_ENTRY_GPIO("gpios", &mtx1_gpiochip_node, 12, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node mtx1_red_led_node = { + .name = "mtx1:red", + .parent = &mtx1_gpio_leds_node, + .properties = mtx1_red_led_props, +}; + +static const struct software_node *mtx1_gpio_leds_swnodes[] = { + &mtx1_gpio_leds_node, + &mtx1_green_led_node, + &mtx1_red_led_node, + NULL +}; + +static void __init mtx1_leds_init(void) +{ + struct platform_device_info led_info = { + .name = "leds-gpio", + .id = PLATFORM_DEVID_NONE, + }; + struct platform_device *led_dev; + int err; + + err = software_node_register_node_group(mtx1_gpio_leds_swnodes); + if (err) { + pr_err("failed to register LED software nodes: %d\n", err); + return; + } + + led_info.fwnode = software_node_fwnode(&mtx1_gpio_leds_node); + + led_dev = platform_device_register_full(&led_info); + err = PTR_ERR_OR_ZERO(led_dev); + if (err) + pr_err("failed to create LED device: %d\n", err); +} + static struct mtd_partition mtx1_mtd_partitions[] = { { .name = "filesystem", @@ -247,9 +315,6 @@ static struct platform_device mtx1_pci_host = { static struct platform_device *mtx1_devs[] __initdata = { &mtx1_pci_host, - &mtx1_gpio_leds, - &mtx1_wdt, - &mtx1_button, &mtx1_mtd, }; @@ -270,16 +335,18 @@ static int __init mtx1_register_devices(void) au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata); - rc = gpio_request(mtx1_gpio_button[0].gpio, - mtx1_gpio_button[0].desc); - if (rc < 0) { - printk(KERN_INFO "mtx1: failed to request %d\n", - mtx1_gpio_button[0].gpio); - goto out; - } - gpio_direction_input(mtx1_gpio_button[0].gpio); -out: - gpiod_add_lookup_table(&mtx1_wdt_gpio_table); - return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs)); + rc = software_node_register(&mtx1_gpiochip_node); + if (rc) + return rc; + + rc = platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs)); + if (rc) + return rc; + + mtx1_leds_init(); + mtx1_wdt_init(); + mtx1_keys_init(); + + return 0; } arch_initcall(mtx1_register_devices); diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 6a3c890f7bbfe..6c2c2010bbaee 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c @@ -982,7 +982,7 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr) static unsigned long alchemy_dbdma_pm_data[NUM_DBDMA_CHANS + 1][6]; -static int alchemy_dbdma_suspend(void) +static int alchemy_dbdma_suspend(void *data) { int i; void __iomem *addr; @@ -1019,7 +1019,7 @@ static int alchemy_dbdma_suspend(void) return 0; } -static void alchemy_dbdma_resume(void) +static void alchemy_dbdma_resume(void *data) { int i; void __iomem *addr; @@ -1044,11 +1044,15 @@ static void alchemy_dbdma_resume(void) } } -static struct syscore_ops alchemy_dbdma_syscore_ops = { +static const struct syscore_ops alchemy_dbdma_syscore_ops = { .suspend = alchemy_dbdma_suspend, .resume = alchemy_dbdma_resume, }; +static struct syscore alchemy_dbdma_syscore = { + .ops = &alchemy_dbdma_syscore_ops, +}; + static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) { int ret; @@ -1071,7 +1075,7 @@ static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) printk(KERN_ERR "Cannot grab DBDMA interrupt!\n"); else { dbdma_initialized = 1; - register_syscore_ops(&alchemy_dbdma_syscore_ops); + register_syscore(&alchemy_dbdma_syscore); } return ret; diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index da9f9220048fc..2403afcd2fb95 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c @@ -758,7 +758,7 @@ static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d) wmb(); } -static int alchemy_ic_suspend(void) +static int alchemy_ic_suspend(void *data) { alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR), alchemy_gpic_pmdata); @@ -767,7 +767,7 @@ static int alchemy_ic_suspend(void) return 0; } -static void alchemy_ic_resume(void) +static void alchemy_ic_resume(void *data) { alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR), &alchemy_gpic_pmdata[7]); @@ -775,7 +775,7 @@ static void alchemy_ic_resume(void) alchemy_gpic_pmdata); } -static int alchemy_gpic_suspend(void) +static int alchemy_gpic_suspend(void *data) { void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR); int i; @@ -806,7 +806,7 @@ static int alchemy_gpic_suspend(void) return 0; } -static void alchemy_gpic_resume(void) +static void alchemy_gpic_resume(void *data) { void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR); int i; @@ -837,16 +837,24 @@ static void alchemy_gpic_resume(void) wmb(); } -static struct syscore_ops alchemy_ic_pmops = { +static const struct syscore_ops alchemy_ic_pmops = { .suspend = alchemy_ic_suspend, .resume = alchemy_ic_resume, }; -static struct syscore_ops alchemy_gpic_pmops = { +static struct syscore alchemy_ic_pm = { + .ops = &alchemy_ic_pmops, +}; + +static const struct syscore_ops alchemy_gpic_pmops = { .suspend = alchemy_gpic_suspend, .resume = alchemy_gpic_resume, }; +static struct syscore alchemy_gpic_pm = { + .ops = &alchemy_gpic_pmops, +}; + /******************************************************************************/ /* create chained handlers for the 4 IC requests to the MIPS IRQ ctrl */ @@ -880,7 +888,7 @@ static void __init au1000_init_irq(struct alchemy_irqmap *map) ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR)); ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR)); - register_syscore_ops(&alchemy_ic_pmops); + register_syscore(&alchemy_ic_pm); mips_cpu_irq_init(); /* register all 64 possible IC0+IC1 irq sources as type "none". @@ -925,7 +933,7 @@ static void __init alchemy_gpic_init_irq(const struct alchemy_irqmap *dints) int i; void __iomem *bank_base; - register_syscore_ops(&alchemy_gpic_pmops); + register_syscore(&alchemy_gpic_pm); mips_cpu_irq_init(); /* disable & ack all possible interrupt sources */ diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index a7a6d31a7a414..992134a8c23ae 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c @@ -94,12 +94,12 @@ phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) return phys_addr; } -int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long vaddr, - unsigned long pfn, unsigned long size, pgprot_t prot) +unsigned long io_remap_pfn_range_pfn(unsigned long pfn, unsigned long size) { phys_addr_t phys_addr = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); - return remap_pfn_range(vma, vaddr, phys_addr >> PAGE_SHIFT, size, prot); + return phys_addr >> PAGE_SHIFT; } -EXPORT_SYMBOL(io_remap_pfn_range); +EXPORT_SYMBOL(io_remap_pfn_range_pfn); + #endif /* CONFIG_MIPS_FIXUP_BIGPHYS_ADDR */ diff --git a/arch/mips/alchemy/common/usb.c b/arch/mips/alchemy/common/usb.c index 5d618547ebf01..a55f32bf517cd 100644 --- a/arch/mips/alchemy/common/usb.c +++ b/arch/mips/alchemy/common/usb.c @@ -580,22 +580,26 @@ static void alchemy_usb_pm(int susp) } } -static int alchemy_usb_suspend(void) +static int alchemy_usb_suspend(void *data) { alchemy_usb_pm(1); return 0; } -static void alchemy_usb_resume(void) +static void alchemy_usb_resume(void *data) { alchemy_usb_pm(0); } -static struct syscore_ops alchemy_usb_pm_ops = { +static const struct syscore_ops alchemy_usb_pm_syscore_ops = { .suspend = alchemy_usb_suspend, .resume = alchemy_usb_resume, }; +static struct syscore alchemy_usb_pm_syscore = { + .ops = &alchemy_usb_pm_syscore_ops, +}; + static int __init alchemy_usb_init(void) { int ret = 0; @@ -620,7 +624,7 @@ static int __init alchemy_usb_init(void) } if (!ret) - register_syscore_ops(&alchemy_usb_pm_ops); + register_syscore(&alchemy_usb_pm_syscore); return ret; } diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index 6d9dbe9455417..36c5e4c6e6406 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile @@ -1,20 +1,17 @@ # SPDX-License-Identifier: GPL-2.0 -subdir-$(CONFIG_BMIPS_GENERIC) += brcm -subdir-$(CONFIG_CAVIUM_OCTEON_SOC) += cavium-octeon -subdir-$(CONFIG_ECONET) += econet -subdir-$(CONFIG_EYEQ) += mobileye -subdir-$(CONFIG_FIT_IMAGE_FDT_MARDUK) += img -subdir-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += img -subdir-$(CONFIG_MACH_INGENIC) += ingenic -subdir-$(CONFIG_LANTIQ) += lantiq -subdir-$(CONFIG_MACH_LOONGSON64) += loongson -subdir-$(CONFIG_MACH_LOONGSON32) += loongson -subdir-$(CONFIG_SOC_VCOREIII) += mscc -subdir-$(CONFIG_MIPS_MALTA) += mti -subdir-$(CONFIG_LEGACY_BOARD_SEAD3) += mti -subdir-$(CONFIG_FIT_IMAGE_FDT_NI169445) += ni -subdir-$(CONFIG_MACH_PIC32) += pic32 -subdir-$(CONFIG_ATH79) += qca -subdir-$(CONFIG_RALINK) += ralink -subdir-$(CONFIG_MACH_REALTEK_RTL) += realtek -subdir-$(CONFIG_FIT_IMAGE_FDT_XILFPGA) += xilfpga +subdir-y += brcm +subdir-y += cavium-octeon +subdir-y += econet +subdir-y += mobileye +subdir-y += img +subdir-y += ingenic +subdir-y += lantiq +subdir-y += loongson +subdir-y += mscc +subdir-y += mti +subdir-y += ni +subdir-y += pic32 +subdir-y += qca +subdir-y += ralink +subdir-y += realtek +subdir-y += xilfpga diff --git a/arch/mips/boot/dts/realtek/Makefile b/arch/mips/boot/dts/realtek/Makefile index d2709798763ff..3ac795d852365 100644 --- a/arch/mips/boot/dts/realtek/Makefile +++ b/arch/mips/boot/dts/realtek/Makefile @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 -dtb-y += cisco_sg220-26.dtb -dtb-y += cameo-rtl9302c-2x-rtl8224-2xge.dtb +dtb-$(CONFIG_MACH_REALTEK_RTL) += cisco_sg220-26.dtb +dtb-$(CONFIG_MACH_REALTEK_RTL) += cameo-rtl9302c-2x-rtl8224-2xge.dtb diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index f56e8db5da951..d10b3d4adbd14 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig @@ -51,7 +51,6 @@ CONFIG_B43LEGACY=y CONFIG_BRCMSMAC=y CONFIG_ISDN=y CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_PCI is not set CONFIG_SERIAL_8250_NR_UARTS=2 diff --git a/arch/mips/configs/bmips_stb_defconfig b/arch/mips/configs/bmips_stb_defconfig index cd0dc37c3d844..ecfa7f777efac 100644 --- a/arch/mips/configs/bmips_stb_defconfig +++ b/arch/mips/configs/bmips_stb_defconfig @@ -119,7 +119,6 @@ CONFIG_INPUT_UINPUT=y CONFIG_VT=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set diff --git a/arch/mips/configs/gcw0_defconfig b/arch/mips/configs/gcw0_defconfig index 8b7ad877e07ae..adb9fd62ddb0d 100644 --- a/arch/mips/configs/gcw0_defconfig +++ b/arch/mips/configs/gcw0_defconfig @@ -52,7 +52,6 @@ CONFIG_INPUT_UINPUT=y CONFIG_INPUT_PWM_VIBRA=y # CONFIG_SERIO is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_INGENIC=y CONFIG_HW_RANDOM=y @@ -80,7 +79,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_SOUND=y CONFIG_SND=y -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_PROC_FS is not set # CONFIG_SND_DRIVERS is not set # CONFIG_SND_SPI is not set diff --git a/arch/mips/configs/loongson1_defconfig b/arch/mips/configs/loongson1_defconfig index 81acae6f61c8b..1d9781ff96986 100644 --- a/arch/mips/configs/loongson1_defconfig +++ b/arch/mips/configs/loongson1_defconfig @@ -13,6 +13,7 @@ CONFIG_EXPERT=y CONFIG_PERF_EVENTS=y CONFIG_MACH_LOONGSON32=y # CONFIG_SUSPEND is not set +CONFIG_JUMP_LABEL=y # CONFIG_SECCOMP is not set # CONFIG_GCC_PLUGINS is not set CONFIG_MODULES=y @@ -30,8 +31,8 @@ CONFIG_IP_PNP_DHCP=y CONFIG_SYN_COOKIES=y # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set +# CONFIG_BQL is not set # CONFIG_WIRELESS is not set -# CONFIG_ETHTOOL_NETLINK is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set @@ -39,7 +40,7 @@ CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_RAW_NAND=y -CONFIG_MTD_NAND_LOONGSON1=y +CONFIG_MTD_NAND_LOONGSON=y CONFIG_MTD_UBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_SCSI=m @@ -72,6 +73,7 @@ CONFIG_NETDEVICES=y # CONFIG_NET_VENDOR_MICROCHIP is not set # CONFIG_NET_VENDOR_MICROSEMI is not set # CONFIG_NET_VENDOR_MICROSOFT is not set +# CONFIG_NET_VENDOR_MUCSE is not set # CONFIG_NET_VENDOR_NI is not set # CONFIG_NET_VENDOR_NATSEMI is not set # CONFIG_NET_VENDOR_NETRONOME is not set @@ -117,7 +119,6 @@ CONFIG_WATCHDOG_SYSFS=y CONFIG_LOONGSON1_WDT=y CONFIG_SOUND=y CONFIG_SND=y -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_DRIVERS is not set # CONFIG_SND_MIPS is not set # CONFIG_SND_USB is not set @@ -166,15 +167,11 @@ CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=m CONFIG_NLS_ISO8859_1=m # CONFIG_CRYPTO_HW is not set -# CONFIG_XZ_DEC_X86 is not set -# CONFIG_XZ_DEC_POWERPC is not set -# CONFIG_XZ_DEC_ARM is not set -# CONFIG_XZ_DEC_ARMTHUMB is not set -# CONFIG_XZ_DEC_ARM64 is not set -# CONFIG_XZ_DEC_SPARC is not set -# CONFIG_XZ_DEC_RISCV is not set CONFIG_DYNAMIC_DEBUG=y # CONFIG_DEBUG_MISC is not set CONFIG_MAGIC_SYSRQ=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_RCU_TRACE is not set # CONFIG_FTRACE is not set # CONFIG_EARLY_PRINTK is not set +CONFIG_TEST_DHRY=m diff --git a/arch/mips/configs/qi_lb60_defconfig b/arch/mips/configs/qi_lb60_defconfig index 5f5b0254d75e7..a1bb0792f6eb1 100644 --- a/arch/mips/configs/qi_lb60_defconfig +++ b/arch/mips/configs/qi_lb60_defconfig @@ -81,7 +81,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_CLUT224 is not set CONFIG_SOUND=y CONFIG_SND=y -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_DRIVERS is not set # CONFIG_SND_SPI is not set diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig index 03a7bbe28a532..49c709d663beb 100644 --- a/arch/mips/configs/rbtx49xx_defconfig +++ b/arch/mips/configs/rbtx49xx_defconfig @@ -53,7 +53,6 @@ CONFIG_TXX9_WDT=m # CONFIG_VGA_ARB is not set CONFIG_SOUND=m CONFIG_SND=m -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_DRIVERS is not set # CONFIG_SND_PCI is not set diff --git a/arch/mips/configs/rs90_defconfig b/arch/mips/configs/rs90_defconfig index a53dd66e9b864..8382d535e6dc1 100644 --- a/arch/mips/configs/rs90_defconfig +++ b/arch/mips/configs/rs90_defconfig @@ -105,7 +105,6 @@ CONFIG_LOGO=y CONFIG_SOUND=y CONFIG_SND=y # CONFIG_SND_PCM_TIMER is not set -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_PROC_FS is not set # CONFIG_SND_DRIVERS is not set # CONFIG_SND_MIPS is not set diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h index 942af87f1cddb..7a04381efa0b5 100644 --- a/arch/mips/include/asm/pgalloc.h +++ b/arch/mips/include/asm/pgalloc.h @@ -81,8 +81,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) { pud_t *pud; - struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, - PUD_TABLE_ORDER); + struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, PUD_TABLE_ORDER); if (!ptdesc) return NULL; diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index ae73ecf4c41aa..9c06a612d33a7 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -604,9 +604,8 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, */ #ifdef CONFIG_MIPS_FIXUP_BIGPHYS_ADDR phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size); -int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long vaddr, - unsigned long pfn, unsigned long size, pgprot_t prot); -#define io_remap_pfn_range io_remap_pfn_range +unsigned long io_remap_pfn_range_pfn(unsigned long pfn, unsigned long size); +#define io_remap_pfn_range_pfn io_remap_pfn_range_pfn #else #define fixup_bigphys_addr(addr, size) (addr) #endif /* CONFIG_MIPS_FIXUP_BIGPHYS_ADDR */ diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c index c97b089b99029..eb9fb2f2a7201 100644 --- a/arch/mips/jazz/jazzdma.c +++ b/arch/mips/jazz/jazzdma.c @@ -521,18 +521,24 @@ static void jazz_dma_free(struct device *dev, size_t size, void *vaddr, __free_pages(virt_to_page(vaddr), get_order(size)); } -static dma_addr_t jazz_dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, enum dma_data_direction dir, - unsigned long attrs) +static dma_addr_t jazz_dma_map_phys(struct device *dev, phys_addr_t phys, + size_t size, enum dma_data_direction dir, unsigned long attrs) { - phys_addr_t phys = page_to_phys(page) + offset; + if (unlikely(attrs & DMA_ATTR_MMIO)) + /* + * This check is included because older versions of the code lacked + * MMIO path support, and my ability to test this path is limited. + * However, from a software technical standpoint, there is no restriction, + * as the following code operates solely on physical addresses. + */ + return DMA_MAPPING_ERROR; if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) arch_sync_dma_for_device(phys, size, dir); return vdma_alloc(phys, size); } -static void jazz_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, +static void jazz_dma_unmap_phys(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir, unsigned long attrs) { if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) @@ -607,8 +613,8 @@ static void jazz_dma_sync_sg_for_cpu(struct device *dev, const struct dma_map_ops jazz_dma_ops = { .alloc = jazz_dma_alloc, .free = jazz_dma_free, - .map_page = jazz_dma_map_page, - .unmap_page = jazz_dma_unmap_page, + .map_phys = jazz_dma_map_phys, + .unmap_phys = jazz_dma_unmap_phys, .map_sg = jazz_dma_map_sg, .unmap_sg = jazz_dma_unmap_sg, .sync_single_for_cpu = jazz_dma_sync_single_for_cpu, diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index f39e85fd58fa9..b15615b285690 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -54,10 +54,20 @@ static inline void ftrace_dyn_arch_init_insns(void) u32 *buf; unsigned int v1; - /* la v1, _mcount */ - v1 = 3; - buf = (u32 *)&insn_la_mcount[0]; - UASM_i_LA(&buf, v1, MCOUNT_ADDR); + /* If we are not in compat space, the number of generated + * instructions will exceed the maximum expected limit of 2. + * To prevent buffer overflow, we avoid generating them. + * insn_la_mcount will not be used later in ftrace_make_call. + */ + if (uasm_in_compat_space_p(MCOUNT_ADDR)) { + /* la v1, _mcount */ + v1 = 3; + buf = (u32 *)&insn_la_mcount[0]; + UASM_i_LA(&buf, v1, MCOUNT_ADDR); + } else { + pr_warn("ftrace: mcount address beyond 32 bits is not supported (%lX)\n", + MCOUNT_ADDR); + } /* jal (ftrace_caller + 8), jump over the first two instruction */ buf = (u32 *)&insn_jal_ftrace_caller; @@ -189,6 +199,13 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) unsigned int new; unsigned long ip = rec->ip; + /* When the code to patch does not belong to the kernel code + * space, we must use insn_la_mcount. However, if MCOUNT_ADDR + * is not in compat space, insn_la_mcount is not usable. + */ + if (!core_kernel_text(ip) && !uasm_in_compat_space_p(MCOUNT_ADDR)) + return -EFAULT; + new = core_kernel_text(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0]; #ifdef CONFIG_64BIT diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 08c0a01d9a298..be1b049d856fb 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -109,7 +109,7 @@ handle_vcei: .align 5 LEAF(r4k_wait) /* Keep the ISA bit clear for calculations on local labels here. */ -0: .fill 0 +0: .fill 0 /* Start of idle interrupt region. */ local_irq_enable /* @@ -121,7 +121,7 @@ LEAF(r4k_wait) */ 1: .fill 0 /* The R2 EI/EHB sequence takes 8 bytes, otherwise pad up. */ - .if 1b - 0b > 32 + .if 1b - 0b > 32 .error "overlong idle interrupt region" .elseif 1b - 0b > 8 .align 4 @@ -146,10 +146,10 @@ r4k_wait_exit: MFC0 k0, CP0_EPC /* Subtract/add 2 to let the ISA bit propagate through the mask. */ PTR_LA k1, r4k_wait_insn - 2 - ori k0, r4k_wait_idle_size - 2 + ori k0, r4k_wait_idle_size - 2 .set noreorder bne k0, k1, \handler - PTR_ADDIU k0, r4k_wait_exit - r4k_wait_insn + 2 + PTR_ADDIU k0, r4k_wait_exit - r4k_wait_insn + 2 .set reorder MTC0 k0, CP0_EPC .set pop diff --git a/arch/mips/kvm/Kconfig b/arch/mips/kvm/Kconfig index ab57221fa4dde..cc13cc35f2083 100644 --- a/arch/mips/kvm/Kconfig +++ b/arch/mips/kvm/Kconfig @@ -22,7 +22,6 @@ config KVM select EXPORT_UASM select KVM_COMMON select KVM_GENERIC_DIRTYLOG_READ_PROTECT - select HAVE_KVM_VCPU_ASYNC_IOCTL select KVM_MMIO select KVM_GENERIC_MMU_NOTIFIER select KVM_GENERIC_HARDWARE_ENABLING diff --git a/arch/mips/kvm/interrupt.c b/arch/mips/kvm/interrupt.c index 0277942279ea2..895a6f1781fd8 100644 --- a/arch/mips/kvm/interrupt.c +++ b/arch/mips/kvm/interrupt.c @@ -27,27 +27,11 @@ void kvm_mips_deliver_interrupts(struct kvm_vcpu *vcpu, u32 cause) unsigned long *pending_clr = &vcpu->arch.pending_exceptions_clr; unsigned int priority; - if (!(*pending) && !(*pending_clr)) - return; - - priority = __ffs(*pending_clr); - while (priority <= MIPS_EXC_MAX) { + for_each_set_bit(priority, pending_clr, MIPS_EXC_MAX + 1) kvm_mips_callbacks->irq_clear(vcpu, priority, cause); - priority = find_next_bit(pending_clr, - BITS_PER_BYTE * sizeof(*pending_clr), - priority + 1); - } - - priority = __ffs(*pending); - while (priority <= MIPS_EXC_MAX) { + for_each_set_bit(priority, pending, MIPS_EXC_MAX + 1) kvm_mips_callbacks->irq_deliver(vcpu, priority, cause); - - priority = find_next_bit(pending, - BITS_PER_BYTE * sizeof(*pending), - priority + 1); - } - } int kvm_mips_pending_timer(struct kvm_vcpu *vcpu) diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index a75587018f447..b0fb92fda4d42 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -895,8 +895,8 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, return r; } -long kvm_arch_vcpu_async_ioctl(struct file *filp, unsigned int ioctl, - unsigned long arg) +long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) { struct kvm_vcpu *vcpu = filp->private_data; void __user *argp = (void __user *)arg; diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index 58625d1b64658..6bfee0f71803e 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c @@ -304,7 +304,7 @@ static int alchemy_pci_def_idsel(unsigned int devsel, int assert) } /* save PCI controller register contents. */ -static int alchemy_pci_suspend(void) +static int alchemy_pci_suspend(void *data) { struct alchemy_pci_context *ctx = __alchemy_pci_ctx; if (!ctx) @@ -326,7 +326,7 @@ static int alchemy_pci_suspend(void) return 0; } -static void alchemy_pci_resume(void) +static void alchemy_pci_resume(void *data) { struct alchemy_pci_context *ctx = __alchemy_pci_ctx; if (!ctx) @@ -354,9 +354,13 @@ static void alchemy_pci_resume(void) alchemy_pci_wired_entry(ctx); /* install it */ } -static struct syscore_ops alchemy_pci_pmops = { - .suspend = alchemy_pci_suspend, - .resume = alchemy_pci_resume, +static const struct syscore_ops alchemy_pci_syscore_ops = { + .suspend = alchemy_pci_suspend, + .resume = alchemy_pci_resume, +}; + +static struct syscore alchemy_pci_syscore = { + .ops = &alchemy_pci_syscore_ops, }; static int alchemy_pci_probe(struct platform_device *pdev) @@ -478,7 +482,7 @@ static int alchemy_pci_probe(struct platform_device *pdev) __alchemy_pci_ctx = ctx; platform_set_drvdata(pdev, ctx); - register_syscore_ops(&alchemy_pci_pmops); + register_syscore(&alchemy_pci_syscore); register_pci_controller(&ctx->alchemy_pci_ctrl); dev_info(&pdev->dev, "PCI controller at %ld MHz\n", diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c index 5893ea4e382ca..19b70928d6dc3 100644 --- a/arch/mips/sgi-ip22/ip22-gio.c +++ b/arch/mips/sgi-ip22/ip22-gio.c @@ -372,7 +372,8 @@ static void ip22_check_gio(int slotno, unsigned long addr, int irq) gio_dev->resource.flags = IORESOURCE_MEM; gio_dev->irq = irq; dev_set_name(&gio_dev->dev, "%d", slotno); - gio_device_register(gio_dev); + if (gio_device_register(gio_dev)) + gio_dev_put(gio_dev); } else printk(KERN_INFO "GIO: slot %d : Empty\n", slotno); } diff --git a/arch/nios2/configs/10m50_defconfig b/arch/nios2/configs/10m50_defconfig index 048f74e0dc6da..b7224f44d3272 100644 --- a/arch/nios2/configs/10m50_defconfig +++ b/arch/nios2/configs/10m50_defconfig @@ -51,7 +51,6 @@ CONFIG_MARVELL_PHY=y # CONFIG_SERIO_SERPORT is not set # CONFIG_VT is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_ALTERA_JTAGUART=y diff --git a/arch/nios2/include/asm/uaccess.h b/arch/nios2/include/asm/uaccess.h index b8299082adbe3..6ccc9a232c239 100644 --- a/arch/nios2/include/asm/uaccess.h +++ b/arch/nios2/include/asm/uaccess.h @@ -172,15 +172,15 @@ do { \ #define __put_user(x, ptr) \ ({ \ - __auto_type __pu_ptr = (ptr); \ - typeof(*__pu_ptr) __pu_val = (typeof(*__pu_ptr))(x); \ + auto __pu_ptr = (ptr); \ + auto __pu_val = (typeof(*__pu_ptr))(x); \ __put_user_common(__pu_val, __pu_ptr); \ }) #define put_user(x, ptr) \ ({ \ - __auto_type __pu_ptr = (ptr); \ - typeof(*__pu_ptr) __pu_val = (typeof(*__pu_ptr))(x); \ + auto __pu_ptr = (ptr); \ + auto __pu_val = (typeof(*__pu_ptr))(x); \ access_ok(__pu_ptr, sizeof(*__pu_ptr)) ? \ __put_user_common(__pu_val, __pu_ptr) : \ -EFAULT; \ diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig index 52031bde9f17c..5444ce6405f3a 100644 --- a/arch/parisc/configs/generic-32bit_defconfig +++ b/arch/parisc/configs/generic-32bit_defconfig @@ -119,7 +119,6 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m CONFIG_LEGACY_PTY_COUNT=64 CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_EXTENDED=y diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig index 1aec04c09d0b4..ce91f9d1fdbfb 100644 --- a/arch/parisc/configs/generic-64bit_defconfig +++ b/arch/parisc/configs/generic-64bit_defconfig @@ -158,7 +158,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_RAW=m # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_RUNTIME_UARTS=8 diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h index 5aa1623e4f2f1..5cf35489ad80b 100644 --- a/arch/parisc/include/asm/bug.h +++ b/arch/parisc/include/asm/bug.h @@ -2,8 +2,6 @@ #ifndef _PARISC_BUG_H #define _PARISC_BUG_H -#include /* for BUGFLAG_TAINT */ - /* * Tell the user there is some problem. * The offending file and line are encoded in the __bug_table section. diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index 9abfe65492c65..3de4b5933b107 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c @@ -258,6 +258,8 @@ int main(void) BLANK(); DEFINE(TIF_BLOCKSTEP_PA_BIT, 31-TIF_BLOCKSTEP); DEFINE(TIF_SINGLESTEP_PA_BIT, 31-TIF_SINGLESTEP); + DEFINE(TIF_32BIT_PA_BIT, 31-TIF_32BIT); + BLANK(); DEFINE(ASM_PMD_SHIFT, PMD_SHIFT); DEFINE(ASM_PGDIR_SHIFT, PGDIR_SHIFT); diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 1f8936fc22928..8d23fe42b0cee 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -1043,11 +1043,7 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data) (unsigned char)mod_path.path.bc[3], (unsigned char)mod_path.path.bc[4], (unsigned char)mod_path.path.bc[5]); - pr_cont(".mod = 0x%x ", mod_path.path.mod); - pr_cont(" },\n"); - pr_cont("\t.layers = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }\n", - mod_path.layers[0], mod_path.layers[1], mod_path.layers[2], - mod_path.layers[3], mod_path.layers[4], mod_path.layers[5]); + pr_cont(".mod = 0x%x }\n", mod_path.path.mod); pr_cont("};\n"); pr_info("static struct pdc_iodc iodc_data_hpa_%08lx = {\n", hpa); @@ -1067,8 +1063,6 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data) DO(checksum); DO(length); #undef DO - pr_cont("\t/* pad: 0x%04x, 0x%04x */\n", - iodc_data.pad[0], iodc_data.pad[1]); pr_cont("};\n"); pr_info("#define HPA_%08lx_num_addr %d\n", hpa, dev->num_addrs); diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index f4bf61a34701e..e04c5d806c105 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -1059,8 +1059,6 @@ ENTRY_CFI(intr_save) /* for os_hpmc */ STREG %r17, PT_IOR(%r29) #if defined(CONFIG_64BIT) - b,n intr_save2 - skip_save_ior: /* We have a itlb miss, and when executing code above 4 Gb on ILP64, we * need to adjust iasq/iaoq here in the same way we adjusted isr/ior @@ -1069,10 +1067,17 @@ skip_save_ior: bb,COND(>=),n %r8,PSW_W_BIT,intr_save2 LDREG PT_IASQ0(%r29), %r16 LDREG PT_IAOQ0(%r29), %r17 - /* adjust iasq/iaoq */ + /* adjust iasq0/iaoq0 */ space_adjust %r16,%r17,%r1 STREG %r16, PT_IASQ0(%r29) STREG %r17, PT_IAOQ0(%r29) + + LDREG PT_IASQ1(%r29), %r16 + LDREG PT_IAOQ1(%r29), %r17 + /* adjust iasq1/iaoq1 */ + space_adjust %r16,%r17,%r1 + STREG %r16, PT_IASQ1(%r29) + STREG %r17, PT_IAOQ1(%r29) #else skip_save_ior: #endif @@ -1841,6 +1846,10 @@ syscall_restore_rfi: extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0 depi -1,7,1,%r20 /* T bit */ +#ifdef CONFIG_64BIT + extru,<> %r19,TIF_32BIT_PA_BIT,1,%r0 + depi -1,4,1,%r20 /* W bit */ +#endif STREG %r20,TASK_PT_PSW(%r1) /* Always store space registers, since sr3 can be changed (e.g. fork) */ @@ -1854,7 +1863,6 @@ syscall_restore_rfi: STREG %r25,TASK_PT_IASQ0(%r1) STREG %r25,TASK_PT_IASQ1(%r1) - /* XXX W bit??? */ /* Now if old D bit is clear, it means we didn't save all registers * on syscall entry, so do that now. This only happens on TRACEME * calls, or if someone attached to us while we were on a syscall. diff --git a/arch/parisc/kernel/perf_regs.c b/arch/parisc/kernel/perf_regs.c index 68458e2f6197e..10a1a5f06a185 100644 --- a/arch/parisc/kernel/perf_regs.c +++ b/arch/parisc/kernel/perf_regs.c @@ -27,7 +27,7 @@ u64 perf_reg_value(struct pt_regs *regs, int idx) return regs->ior; case PERF_REG_PARISC_IPSW: /* CR22 */ return regs->ipsw; - }; + } WARN_ON_ONCE((u32)idx >= PERF_REG_PARISC_MAX); return 0; } diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c index 53b3b2621457d..78704927453aa 100644 --- a/arch/powerpc/boot/addnote.c +++ b/arch/powerpc/boot/addnote.c @@ -68,8 +68,8 @@ static int e_class = ELFCLASS32; #define PUT_16BE(off, v)(buf[off] = ((v) >> 8) & 0xff, \ buf[(off) + 1] = (v) & 0xff) #define PUT_32BE(off, v)(PUT_16BE((off), (v) >> 16L), PUT_16BE((off) + 2, (v))) -#define PUT_64BE(off, v)((PUT_32BE((off), (v) >> 32L), \ - PUT_32BE((off) + 4, (v)))) +#define PUT_64BE(off, v)((PUT_32BE((off), (unsigned long long)(v) >> 32L), \ + PUT_32BE((off) + 4, (unsigned long long)(v)))) #define GET_16LE(off) ((buf[off]) + (buf[(off)+1] << 8)) #define GET_32LE(off) (GET_16LE(off) + (GET_16LE((off)+2U) << 16U)) @@ -78,7 +78,8 @@ static int e_class = ELFCLASS32; #define PUT_16LE(off, v) (buf[off] = (v) & 0xff, \ buf[(off) + 1] = ((v) >> 8) & 0xff) #define PUT_32LE(off, v) (PUT_16LE((off), (v)), PUT_16LE((off) + 2, (v) >> 16L)) -#define PUT_64LE(off, v) (PUT_32LE((off), (v)), PUT_32LE((off) + 4, (v) >> 32L)) +#define PUT_64LE(off, v) (PUT_32LE((off), (unsigned long long)(v)), \ + PUT_32LE((off) + 4, (unsigned long long)(v) >> 32L)) #define GET_16(off) (e_data == ELFDATA2MSB ? GET_16BE(off) : GET_16LE(off)) #define GET_32(off) (e_data == ELFDATA2MSB ? GET_32BE(off) : GET_32LE(off)) diff --git a/arch/powerpc/boot/dts/asp834x-redboot.dts b/arch/powerpc/boot/dts/asp834x-redboot.dts index 52a84561c4f07..33ddb17d18760 100644 --- a/arch/powerpc/boot/dts/asp834x-redboot.dts +++ b/arch/powerpc/boot/dts/asp834x-redboot.dts @@ -72,7 +72,7 @@ reg = <0xff000000 0x00000200>; bus-frequency = <0>; - wdt@200 { + watchdog@200 { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; diff --git a/arch/powerpc/boot/dts/fsl/ge_imp3a.dts b/arch/powerpc/boot/dts/fsl/ge_imp3a.dts index da3de8e2b7d2c..9e5c01cfac2f8 100644 --- a/arch/powerpc/boot/dts/fsl/ge_imp3a.dts +++ b/arch/powerpc/boot/dts/fsl/ge_imp3a.dts @@ -94,7 +94,7 @@ gpio-controller; }; - wdt@4,800 { + watchdog@4,800 { compatible = "ge,imp3a-fpga-wdt", "gef,fpga-wdt-1.00", "gef,fpga-wdt"; reg = <0x4 0x800 0x8>; @@ -103,7 +103,7 @@ }; /* Second watchdog available, driver currently supports one. - wdt@4,808 { + watchdog@4,808 { compatible = "gef,imp3a-fpga-wdt", "gef,fpga-wdt-1.00", "gef,fpga-wdt"; reg = <0x4 0x808 0x8>; diff --git a/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts b/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts index fc92bb032c517..48a81430a8a31 100644 --- a/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts +++ b/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts @@ -82,7 +82,7 @@ reg = <0x4 0x0 0x40>; }; - wdt@4,2000 { + watchdog@4,2000 { compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", "gef,fpga-wdt"; reg = <0x4 0x2000 0x8>; @@ -90,7 +90,7 @@ interrupt-parent = <&gef_pic>; }; /* Second watchdog available, driver currently supports one. - wdt@4,2010 { + watchdog@4,2010 { compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", "gef,fpga-wdt"; reg = <0x4 0x2010 0x8>; diff --git a/arch/powerpc/boot/dts/fsl/gef_sbc310.dts b/arch/powerpc/boot/dts/fsl/gef_sbc310.dts index 47ae85c34635b..8eb254b1738dd 100644 --- a/arch/powerpc/boot/dts/fsl/gef_sbc310.dts +++ b/arch/powerpc/boot/dts/fsl/gef_sbc310.dts @@ -79,7 +79,7 @@ reg = <0x4 0x0 0x40>; }; - wdt@4,2000 { + watchdog@4,2000 { compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00", "gef,fpga-wdt"; reg = <0x4 0x2000 0x8>; @@ -87,7 +87,7 @@ interrupt-parent = <&gef_pic>; }; /* - wdt@4,2010 { + watchdog@4,2010 { compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00", "gef,fpga-wdt"; reg = <0x4 0x2010 0x8>; diff --git a/arch/powerpc/boot/dts/fsl/gef_sbc610.dts b/arch/powerpc/boot/dts/fsl/gef_sbc610.dts index 5322be44b62e7..02edbb262b8f0 100644 --- a/arch/powerpc/boot/dts/fsl/gef_sbc610.dts +++ b/arch/powerpc/boot/dts/fsl/gef_sbc610.dts @@ -82,14 +82,14 @@ reg = <0x4 0x0 0x40>; }; - wdt@4,2000 { + watchdog@4,2000 { compatible = "gef,fpga-wdt"; reg = <0x4 0x2000 0x8>; interrupts = <0x1a 0x4>; interrupt-parent = <&gef_pic>; }; /* Second watchdog available, driver currently supports one. - wdt@4,2010 { + watchdog@4,2010 { compatible = "gef,fpga-wdt"; reg = <0x4 0x2010 0x8>; interrupts = <0x1b 0x4>; diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi index d3fc8062fbcd7..a278fb7b9e711 100644 --- a/arch/powerpc/boot/dts/mpc5121.dtsi +++ b/arch/powerpc/boot/dts/mpc5121.dtsi @@ -112,7 +112,7 @@ }; /* Watchdog timer */ - wdt@900 { + watchdog@900 { compatible = "fsl,mpc5121-wdt"; reg = <0x900 0x100>; }; diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts index a8315795b2c95..09508b4c8c730 100644 --- a/arch/powerpc/boot/dts/mpc8313erdb.dts +++ b/arch/powerpc/boot/dts/mpc8313erdb.dts @@ -99,7 +99,7 @@ reg = <0xe0000000 0x00000200>; bus-frequency = <0>; - wdt@200 { + watchdog@200 { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index a89cb3139ca8c..a8f68d6e50b0d 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -100,7 +100,7 @@ reg = <0xe0000000 0x00000200>; bus-frequency = <0>; - wdt@200 { + watchdog@200 { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts index ecebc27a28987..ba7caaf98fd58 100644 --- a/arch/powerpc/boot/dts/mpc832x_rdb.dts +++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts @@ -52,7 +52,7 @@ reg = <0xe0000000 0x00000200>; bus-frequency = <0>; - wdt@200 { + watchdog@200 { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index d4ebbb93de0b3..13f17232ba83d 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -53,7 +53,7 @@ reg = <0xe0000000 0x00000200>; bus-frequency = <0>; // from bootloader - wdt@200 { + watchdog@200 { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts index bcf68a0a7b557..eae0afd5abbc3 100644 --- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts +++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts @@ -51,7 +51,7 @@ reg = <0xe0000000 0x00000200>; bus-frequency = <0>; // from bootloader - wdt@200 { + watchdog@200 { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; diff --git a/arch/powerpc/boot/dts/mpc836x_rdk.dts b/arch/powerpc/boot/dts/mpc836x_rdk.dts index a0cc1953484d7..4ff38e1a2185f 100644 --- a/arch/powerpc/boot/dts/mpc836x_rdk.dts +++ b/arch/powerpc/boot/dts/mpc836x_rdk.dts @@ -62,7 +62,7 @@ /* filled by u-boot */ bus-frequency = <0>; - wdt@200 { + watchdog@200 { compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; }; diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index 7df452efa9579..f137ccb8cfded 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -99,7 +99,7 @@ reg = <0xe0000000 0x00000200>; bus-frequency = <0>; - wdt@200 { + watchdog@200 { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; diff --git a/arch/powerpc/boot/dts/mpc8377_wlan.dts b/arch/powerpc/boot/dts/mpc8377_wlan.dts index d8e7d40aeae44..ce254dd74dd06 100644 --- a/arch/powerpc/boot/dts/mpc8377_wlan.dts +++ b/arch/powerpc/boot/dts/mpc8377_wlan.dts @@ -89,7 +89,7 @@ reg = <0xe0000000 0x00000200>; bus-frequency = <0>; - wdt@200 { + watchdog@200 { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts index bdcfe83a561e1..19e5473d4161b 100644 --- a/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -99,7 +99,7 @@ reg = <0xe0000000 0x00000200>; bus-frequency = <0>; - wdt@200 { + watchdog@200 { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts index a5f702304a353..61519acca2280 100644 --- a/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -97,7 +97,7 @@ reg = <0xe0000000 0x00000200>; bus-frequency = <0>; - wdt@200 { + watchdog@200 { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = <0x200 0x100>; diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index a75baefd1cffb..1efd1206fcab0 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -21,7 +21,7 @@ # (default ./arch/powerpc/boot) # -W dir specify working directory for temporary files (default .) # -z use gzip (legacy) -# -Z zsuffix compression to use (gz, xz or none) +# -Z zsuffix compression to use (gz, xz, lzma, lzo or none) # Stop execution if any command fails set -e @@ -69,7 +69,7 @@ usage() { echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2 echo ' [-d devtree] [-s tree.dts] [-e esm_blob]' >&2 echo ' [-c] [-C cross-prefix] [-D datadir] [-W workingdir]' >&2 - echo ' [-Z (gz|xz|none)] [--no-compression] [vmlinux]' >&2 + echo ' [-Z (gz|xz|lzma|lzo|none)] [--no-compression] [vmlinux]' >&2 exit 1 } diff --git a/arch/powerpc/configs/44x/akebono_defconfig b/arch/powerpc/configs/44x/akebono_defconfig index 1882eb2da354a..02e88648a2e63 100644 --- a/arch/powerpc/configs/44x/akebono_defconfig +++ b/arch/powerpc/configs/44x/akebono_defconfig @@ -85,7 +85,6 @@ CONFIG_IBM_EMAC=y # CONFIG_SERIO is not set # CONFIG_VT is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/powerpc/configs/85xx-hw.config b/arch/powerpc/configs/85xx-hw.config index 8aff832173977..2b19c20a9a2c4 100644 --- a/arch/powerpc/configs/85xx-hw.config +++ b/arch/powerpc/configs/85xx-hw.config @@ -117,7 +117,6 @@ CONFIG_SND_INTEL8X0=y CONFIG_SND_POWERPC_SOC=y # CONFIG_SND_PPC is not set CONFIG_SND_SOC=y -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_USB is not set CONFIG_SND=y CONFIG_SOUND=y diff --git a/arch/powerpc/configs/86xx-hw.config b/arch/powerpc/configs/86xx-hw.config index e7bd265fae5a4..07f30ab881e59 100644 --- a/arch/powerpc/configs/86xx-hw.config +++ b/arch/powerpc/configs/86xx-hw.config @@ -80,7 +80,6 @@ CONFIG_SERIO_LIBPS2=y CONFIG_SND_INTEL8X0=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y -# CONFIG_SND_SUPPORT_OLD_API is not set CONFIG_SND=y CONFIG_SOUND=y CONFIG_ULI526X=y diff --git a/arch/powerpc/configs/microwatt_defconfig b/arch/powerpc/configs/microwatt_defconfig index a64fb1ef8c75b..d81989a6f59b5 100644 --- a/arch/powerpc/configs/microwatt_defconfig +++ b/arch/powerpc/configs/microwatt_defconfig @@ -62,7 +62,6 @@ CONFIG_LITEX_LITEETH=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_NONSTANDARD=y diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig index c0fe5e76604a0..617650cea56a9 100644 --- a/arch/powerpc/configs/mpc5200_defconfig +++ b/arch/powerpc/configs/mpc5200_defconfig @@ -75,7 +75,6 @@ CONFIG_FB_SM501=m CONFIG_LOGO=y CONFIG_SOUND=y CONFIG_SND=y -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_DRIVERS is not set # CONFIG_SND_PCI is not set # CONFIG_SND_PPC is not set diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index b082c1fae13c9..787d707f64a42 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -726,7 +726,6 @@ CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_DYNAMIC_MINORS=y -# CONFIG_SND_SUPPORT_OLD_API is not set CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_DEBUG=y CONFIG_SND_DEBUG_VERBOSE=y diff --git a/arch/powerpc/include/asm/book3s/32/tlbflush.h b/arch/powerpc/include/asm/book3s/32/tlbflush.h index e43534da5207a..4be2200a3c7e1 100644 --- a/arch/powerpc/include/asm/book3s/32/tlbflush.h +++ b/arch/powerpc/include/asm/book3s/32/tlbflush.h @@ -11,6 +11,7 @@ void hash__flush_tlb_mm(struct mm_struct *mm); void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); void hash__flush_range(struct mm_struct *mm, unsigned long start, unsigned long end); +void hash__flush_gather(struct mmu_gather *tlb); #ifdef CONFIG_SMP void _tlbie(unsigned long address); @@ -29,7 +30,9 @@ void _tlbia(void); static inline void tlb_flush(struct mmu_gather *tlb) { /* 603 needs to flush the whole TLB here since it doesn't use a hash table. */ - if (!mmu_has_feature(MMU_FTR_HPTE_TABLE)) + if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) + hash__flush_gather(tlb); + else _tlbia(); } diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index 3463514232071..af12e2ba8eb85 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -524,7 +524,6 @@ void slb_save_contents(struct slb_entry *slb_ptr); void slb_dump_contents(struct slb_entry *slb_ptr); extern void slb_vmalloc_update(void); -void preload_new_slb_context(unsigned long start, unsigned long sp); #ifdef CONFIG_PPC_64S_HASH_MMU void slb_set_size(u16 size); diff --git a/arch/powerpc/include/asm/crash_reserve.h b/arch/powerpc/include/asm/crash_reserve.h index 6467ce29b1fab..d1b570ddbf98b 100644 --- a/arch/powerpc/include/asm/crash_reserve.h +++ b/arch/powerpc/include/asm/crash_reserve.h @@ -5,4 +5,12 @@ /* crash kernel regions are Page size agliged */ #define CRASH_ALIGN PAGE_SIZE +#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION +static inline bool arch_add_crash_res_to_iomem(void) +{ + return false; +} +#define arch_add_crash_res_to_iomem arch_add_crash_res_to_iomem +#endif + #endif /* _ASM_POWERPC_CRASH_RESERVE_H */ diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index 1078ba88efaf4..9cd945f2acafa 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -90,7 +90,7 @@ static inline void __hard_EE_RI_disable(void) if (IS_ENABLED(CONFIG_BOOKE)) wrtee(0); else if (IS_ENABLED(CONFIG_PPC_8xx)) - wrtspr(SPRN_NRI); + wrtspr_sync(SPRN_NRI); else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) __mtmsrd(0, 1); else diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index b410021ad4c69..eafdd63cd6c4f 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -274,12 +274,12 @@ extern void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl, unsigned long mask, gfp_t flag, int node); extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, void *vaddr, dma_addr_t dma_handle); -extern dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl, - struct page *page, unsigned long offset, - size_t size, unsigned long mask, +extern dma_addr_t iommu_map_phys(struct device *dev, struct iommu_table *tbl, + phys_addr_t phys, size_t size, + unsigned long mask, enum dma_data_direction direction, unsigned long attrs); -extern void iommu_unmap_page(struct iommu_table *tbl, dma_addr_t dma_handle, +extern void iommu_unmap_phys(struct iommu_table *tbl, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction, unsigned long attrs); diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index 4bbf9f699aaaf..bd4a6c42a5f38 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h @@ -115,9 +115,11 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt, struct crash_mem #ifdef CONFIG_CRASH_RESERVE int __init overlaps_crashkernel(unsigned long start, unsigned long size); extern void arch_reserve_crashkernel(void); +extern void kdump_cma_reserve(void); #else static inline void arch_reserve_crashkernel(void) {} static inline int overlaps_crashkernel(unsigned long start, unsigned long size) { return 0; } +static inline void kdump_cma_reserve(void) { } #endif #if defined(CONFIG_CRASH_DUMP) diff --git a/arch/powerpc/include/asm/mem_encrypt.h b/arch/powerpc/include/asm/mem_encrypt.h index 2f26b8fc8d297..e355ca46fad93 100644 --- a/arch/powerpc/include/asm/mem_encrypt.h +++ b/arch/powerpc/include/asm/mem_encrypt.h @@ -9,6 +9,9 @@ #define _ASM_POWERPC_MEM_ENCRYPT_H #include +#include + +struct device; static inline bool force_dma_unencrypted(struct device *dev) { diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 3fe1866354323..3449dd2b577d4 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1400,6 +1400,7 @@ static inline void mtmsr_isync(unsigned long val) : "r" ((unsigned long)(v)) \ : "memory") #define wrtspr(rn) asm volatile("mtspr " __stringify(rn) ",2" : : : "memory") +#define wrtspr_sync(rn) asm volatile("mtspr " __stringify(rn) ",2; sync" : : : "memory") static inline void wrtee(unsigned long val) { diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index f19ca44512d1e..66ed5fe1b7184 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -132,15 +132,18 @@ static inline int cpu_to_coregroup_id(int cpu) #include struct cpumask *cpu_coregroup_mask(int cpu); +const struct cpumask *cpu_die_mask(int cpu); +int cpu_die_id(int cpu); #ifdef CONFIG_PPC64 #include #define topology_physical_package_id(cpu) (cpu_to_chip_id(cpu)) - -#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) -#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) -#define topology_core_id(cpu) (cpu_to_core_id(cpu)) +#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) +#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) +#define topology_core_id(cpu) (cpu_to_core_id(cpu)) +#define topology_die_id(cpu) (cpu_die_id(cpu)) +#define topology_die_cpumask(cpu) (cpu_die_mask(cpu)) #endif #endif diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 7f63f1cdc6c39..ca00c4824e313 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -20,6 +20,7 @@ #include #include #include +#include #define NO_SCROLL @@ -463,7 +464,7 @@ static noinline void draw_byte(unsigned char c, long locX, long locY) { unsigned char *base = calc_base(locX << 3, locY << 4); unsigned int font_index = c * 16; - const unsigned char *font = font_sun_8x16.data + font_index; + const unsigned char *font = PTRRELOC(font_sun_8x16.data) + font_index; int rb = dispDeviceRowBytes; rmci_maybe_on(); diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 0359ab72cd3ba..aa3689d619179 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -93,28 +93,26 @@ static void dma_iommu_free_coherent(struct device *dev, size_t size, /* Creates TCEs for a user provided buffer. The user buffer must be * contiguous real kernel storage (not vmalloc). The address passed here - * comprises a page address and offset into that page. The dma_addr_t - * returned will point to the same byte within the page as was passed in. + * is a physical address to that page. The dma_addr_t returned will point + * to the same byte within the page as was passed in. */ -static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, +static dma_addr_t dma_iommu_map_phys(struct device *dev, phys_addr_t phys, + size_t size, enum dma_data_direction direction, unsigned long attrs) { - return iommu_map_page(dev, get_iommu_table_base(dev), page, offset, - size, dma_get_mask(dev), direction, attrs); + return iommu_map_phys(dev, get_iommu_table_base(dev), phys, size, + dma_get_mask(dev), direction, attrs); } - -static void dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle, +static void dma_iommu_unmap_phys(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction, unsigned long attrs) { - iommu_unmap_page(get_iommu_table_base(dev), dma_handle, size, direction, + iommu_unmap_phys(get_iommu_table_base(dev), dma_handle, size, direction, attrs); } - static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, int nelems, enum dma_data_direction direction, unsigned long attrs) @@ -211,8 +209,8 @@ const struct dma_map_ops dma_iommu_ops = { .map_sg = dma_iommu_map_sg, .unmap_sg = dma_iommu_unmap_sg, .dma_supported = dma_iommu_dma_supported, - .map_page = dma_iommu_map_page, - .unmap_page = dma_iommu_unmap_page, + .map_phys = dma_iommu_map_phys, + .unmap_phys = dma_iommu_unmap_phys, .get_required_mask = dma_iommu_get_required_mask, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index f4a8c98772491..d8426251b1cda 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -168,6 +168,7 @@ syscall_exit_finish: REST_GPR(0, r1) REST_GPRS(3, 12, r1) b 1b +_ASM_NOKPROBE_SYMBOL(syscall_exit_finish) #ifdef CONFIG_44x .L44x_icache_flush: @@ -216,7 +217,7 @@ fast_exception_return: beq 3f /* if not, we've got problems */ #endif -2: lwz r10,_CCR(r11) + lwz r10,_CCR(r11) REST_GPRS(1, 6, r11) mtcr r10 lwz r10,_LINK(r11) @@ -224,13 +225,10 @@ fast_exception_return: /* Clear the exception marker on the stack to avoid confusing stacktrace */ li r10, 0 stw r10, 8(r11) - REST_GPR(10, r11) -#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS) - mtspr SPRN_NRI, r0 -#endif mtspr SPRN_SRR1,r9 mtspr SPRN_SRR0,r12 REST_GPR(9, r11) + REST_GPR(10, r11) REST_GPR(12, r11) REST_GPR(11, r11) rfi @@ -263,10 +261,9 @@ interrupt_return: mtspr SPRN_SRR1,r12 BEGIN_FTR_SECTION + lwarx r0,0,r1 +END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) stwcx. r0,0,r1 /* to clear the reservation */ -FTR_SECTION_ELSE - lwarx r0,0,r1 -ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) lwz r3,_CCR(r1) lwz r4,_LINK(r1) @@ -306,10 +303,9 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) mtspr SPRN_SRR1,r12 BEGIN_FTR_SECTION + lwarx r0,0,r1 +END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) stwcx. r0,0,r1 /* to clear the reservation */ -FTR_SECTION_ELSE - lwarx r0,0,r1 -ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) lwz r3,_LINK(r1) lwz r4,_CTR(r1) diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c index e0c681d0b0763..e63bfde13e031 100644 --- a/arch/powerpc/kernel/interrupt.c +++ b/arch/powerpc/kernel/interrupt.c @@ -443,6 +443,9 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs) if (unlikely(stack_store)) __hard_EE_RI_disable(); +#else + } else { + __hard_EE_RI_disable(); #endif /* CONFIG_PPC64 */ } diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 244eb4857e7f4..0ce71310b7d91 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -848,12 +848,12 @@ EXPORT_SYMBOL_GPL(iommu_tce_table_put); /* Creates TCEs for a user provided buffer. The user buffer must be * contiguous real kernel storage (not vmalloc). The address passed here - * comprises a page address and offset into that page. The dma_addr_t - * returned will point to the same byte within the page as was passed in. + * is physical address into that page. The dma_addr_t returned will point + * to the same byte within the page as was passed in. */ -dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl, - struct page *page, unsigned long offset, size_t size, - unsigned long mask, enum dma_data_direction direction, +dma_addr_t iommu_map_phys(struct device *dev, struct iommu_table *tbl, + phys_addr_t phys, size_t size, unsigned long mask, + enum dma_data_direction direction, unsigned long attrs) { dma_addr_t dma_handle = DMA_MAPPING_ERROR; @@ -863,7 +863,7 @@ dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl, BUG_ON(direction == DMA_NONE); - vaddr = page_address(page) + offset; + vaddr = phys_to_virt(phys); uaddr = (unsigned long)vaddr; if (tbl) { @@ -890,7 +890,7 @@ dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl, return dma_handle; } -void iommu_unmap_page(struct iommu_table *tbl, dma_addr_t dma_handle, +void iommu_unmap_phys(struct iommu_table *tbl, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction, unsigned long attrs) { @@ -1156,7 +1156,8 @@ EXPORT_SYMBOL_GPL(iommu_add_device); */ static int spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain, - struct device *dev) + struct device *dev, + struct iommu_domain *old) { struct iommu_domain *domain = iommu_get_domain_for_dev(dev); struct iommu_table_group *table_group; @@ -1189,7 +1190,7 @@ static struct iommu_domain spapr_tce_platform_domain = { static int spapr_tce_blocked_iommu_attach_dev(struct iommu_domain *platform_domain, - struct device *dev) + struct device *dev, struct iommu_domain *old) { struct iommu_group *grp = iommu_group_get(dev); struct iommu_table_group *table_group; diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index eb23966ac0a9f..a45fe147868bc 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1897,8 +1897,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) return 0; } -void preload_new_slb_context(unsigned long start, unsigned long sp); - /* * Set up a thread for executing a new program */ @@ -1906,9 +1904,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) { #ifdef CONFIG_PPC64 unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */ - - if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled()) - preload_new_slb_context(start, sp); #endif #ifdef CONFIG_PPC_TRANSACTIONAL_MEM diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 68d47c53876c6..c8c42b419742f 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -995,11 +996,12 @@ void __init setup_arch(char **cmdline_p) initmem_init(); /* - * Reserve large chunks of memory for use by CMA for fadump, KVM and + * Reserve large chunks of memory for use by CMA for kdump, fadump, KVM and * hugetlb. These must be called after initmem_init(), so that * pageblock_order is initialised. */ fadump_cma_init(); + kdump_cma_reserve(); kvm_cma_reserve(); gigantic_hugetlb_cma_reserve(); diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 68edb66c2964b..292fee8809bc8 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -1085,6 +1085,29 @@ static int __init init_big_cores(void) return 0; } +/* + * die_mask and die_id are only available on systems which support + * multiple coregroups within a same package. On all other systems, die_mask + * would be same as package mask and die_id would be set to -1. + */ +const struct cpumask *cpu_die_mask(int cpu) +{ + if (has_coregroup_support()) + return per_cpu(cpu_coregroup_map, cpu); + else + return cpu_node_mask(cpu); +} +EXPORT_SYMBOL_GPL(cpu_die_mask); + +int cpu_die_id(int cpu) +{ + if (has_coregroup_support()) + return cpu_to_coregroup_id(cpu); + else + return -1; +} +EXPORT_SYMBOL_GPL(cpu_die_id); + void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int cpu, num_threads; diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index de6ee7d35cff0..15850296c0a9c 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -330,7 +330,6 @@ SECTIONS } .hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) } .gnu.hash : AT(ADDR(.gnu.hash) - LOAD_OFFSET) { *(.gnu.hash) } - .interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) } .rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET) { __rela_dyn_start = .; diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c index d1a2d755381ca..104c05520bf05 100644 --- a/arch/powerpc/kexec/core.c +++ b/arch/powerpc/kexec/core.c @@ -22,6 +22,8 @@ #include #include +#define cpu_to_be_ulong __PASTE(cpu_to_be, BITS_PER_LONG) + #ifdef CONFIG_CRASH_DUMP void machine_crash_shutdown(struct pt_regs *regs) { @@ -59,6 +61,8 @@ void machine_kexec(struct kimage *image) #ifdef CONFIG_CRASH_RESERVE +static unsigned long long crashk_cma_size; + static unsigned long long __init get_crash_base(unsigned long long crash_base) { @@ -110,7 +114,7 @@ void __init arch_reserve_crashkernel(void) /* use common parsing */ ret = parse_crashkernel(boot_command_line, total_mem_sz, &crash_size, - &crash_base, NULL, NULL, NULL); + &crash_base, NULL, &crashk_cma_size, NULL); if (ret) return; @@ -130,23 +134,22 @@ void __init arch_reserve_crashkernel(void) reserve_crashkernel_generic(crash_size, crash_base, 0, false); } +void __init kdump_cma_reserve(void) +{ + if (crashk_cma_size) + reserve_crashkernel_cma(crashk_cma_size); +} + int __init overlaps_crashkernel(unsigned long start, unsigned long size) { return (start + size) > crashk_res.start && start <= crashk_res.end; } /* Values we need to export to the second kernel via the device tree. */ -static phys_addr_t kernel_end; static phys_addr_t crashk_base; static phys_addr_t crashk_size; static unsigned long long mem_limit; -static struct property kernel_end_prop = { - .name = "linux,kernel-end", - .length = sizeof(phys_addr_t), - .value = &kernel_end, -}; - static struct property crashk_base_prop = { .name = "linux,crashkernel-base", .length = sizeof(phys_addr_t), @@ -165,8 +168,6 @@ static struct property memory_limit_prop = { .value = &mem_limit, }; -#define cpu_to_be_ulong __PASTE(cpu_to_be, BITS_PER_LONG) - static void __init export_crashk_values(struct device_node *node) { /* There might be existing crash kernel properties, but we can't @@ -190,6 +191,15 @@ static void __init export_crashk_values(struct device_node *node) mem_limit = cpu_to_be_ulong(memory_limit); of_update_property(node, &memory_limit_prop); } +#endif /* CONFIG_CRASH_RESERVE */ + +static phys_addr_t kernel_end; + +static struct property kernel_end_prop = { + .name = "linux,kernel-end", + .length = sizeof(phys_addr_t), + .value = &kernel_end, +}; static int __init kexec_setup(void) { @@ -200,16 +210,17 @@ static int __init kexec_setup(void) return -ENOENT; /* remove any stale properties so ours can be found */ - of_remove_property(node, of_find_property(node, kernel_end_prop.name, NULL)); + of_remove_property(node, of_find_property(node, kernel_end_prop.name, + NULL)); /* information needed by userspace when using default_machine_kexec */ kernel_end = cpu_to_be_ulong(__pa(_end)); of_add_property(node, &kernel_end_prop); +#ifdef CONFIG_CRASH_RESERVE export_crashk_values(node); - +#endif of_node_put(node); return 0; } late_initcall(kexec_setup); -#endif /* CONFIG_CRASH_RESERVE */ diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c index 222aa326dacee..825ab8a88f18e 100644 --- a/arch/powerpc/kexec/core_64.c +++ b/arch/powerpc/kexec/core_64.c @@ -202,6 +202,23 @@ static void kexec_prepare_cpus_wait(int wait_state) mb(); } + +/* + * The add_cpu() call in wake_offline_cpus() can fail as cpu_bootable() + * returns false for CPUs that fail the cpu_smt_thread_allowed() check + * or non primary threads if SMT is disabled. Re-enable SMT and set the + * number of SMT threads to threads per core. + */ +static void kexec_smt_reenable(void) +{ +#if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT) + lock_device_hotplug(); + cpu_smt_num_threads = threads_per_core; + cpu_smt_control = CPU_SMT_ENABLED; + unlock_device_hotplug(); +#endif +} + /* * We need to make sure each present CPU is online. The next kernel will scan * the device tree and assume primary threads are online and query secondary @@ -216,6 +233,8 @@ static void wake_offline_cpus(void) { int cpu = 0; + kexec_smt_reenable(); + for_each_present_cpu(cpu) { if (!cpu_online(cpu)) { printk(KERN_INFO "kexec: Waking offline cpu %d.\n", diff --git a/arch/powerpc/kexec/ranges.c b/arch/powerpc/kexec/ranges.c index 3702b0bdab141..867135560e5c8 100644 --- a/arch/powerpc/kexec/ranges.c +++ b/arch/powerpc/kexec/ranges.c @@ -515,7 +515,7 @@ int get_exclude_memory_ranges(struct crash_mem **mem_ranges) */ int get_usable_memory_ranges(struct crash_mem **mem_ranges) { - int ret; + int ret, i; /* * Early boot failure observed on guests when low memory (first memory @@ -528,6 +528,13 @@ int get_usable_memory_ranges(struct crash_mem **mem_ranges) if (ret) goto out; + for (i = 0; i < crashk_cma_cnt; i++) { + ret = add_mem_range(mem_ranges, crashk_cma_ranges[i].start, + crashk_cma_ranges[i].end - crashk_cma_ranges[i].start + 1); + if (ret) + goto out; + } + ret = add_rtas_mem_range(mem_ranges); if (ret) goto out; @@ -546,6 +553,22 @@ int get_usable_memory_ranges(struct crash_mem **mem_ranges) #endif /* CONFIG_KEXEC_FILE */ #ifdef CONFIG_CRASH_DUMP +static int crash_exclude_mem_range_guarded(struct crash_mem **mem_ranges, + unsigned long long mstart, + unsigned long long mend) +{ + struct crash_mem *tmem = *mem_ranges; + + /* Reallocate memory ranges if there is no space to split ranges */ + if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) { + tmem = realloc_mem_ranges(mem_ranges); + if (!tmem) + return -ENOMEM; + } + + return crash_exclude_mem_range(tmem, mstart, mend); +} + /** * get_crash_memory_ranges - Get crash memory ranges. This list includes * first/crashing kernel's memory regions that @@ -557,7 +580,6 @@ int get_usable_memory_ranges(struct crash_mem **mem_ranges) int get_crash_memory_ranges(struct crash_mem **mem_ranges) { phys_addr_t base, end; - struct crash_mem *tmem; u64 i; int ret; @@ -582,19 +604,18 @@ int get_crash_memory_ranges(struct crash_mem **mem_ranges) sort_memory_ranges(*mem_ranges, true); } - /* Reallocate memory ranges if there is no space to split ranges */ - tmem = *mem_ranges; - if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) { - tmem = realloc_mem_ranges(mem_ranges); - if (!tmem) - goto out; - } - /* Exclude crashkernel region */ - ret = crash_exclude_mem_range(tmem, crashk_res.start, crashk_res.end); + ret = crash_exclude_mem_range_guarded(mem_ranges, crashk_res.start, crashk_res.end); if (ret) goto out; + for (i = 0; i < crashk_cma_cnt; ++i) { + ret = crash_exclude_mem_range_guarded(mem_ranges, crashk_cma_ranges[i].start, + crashk_cma_ranges[i].end); + if (ret) + goto out; + } + /* * FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL * regions are exported to save their context at the time of @@ -697,8 +718,8 @@ int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size) * two half. */ else { + size = mem_rngs->ranges[i].end - end + 1; mem_rngs->ranges[i].end = base - 1; - size = mem_rngs->ranges[i].end - end; ret = add_mem_range(mem_ranges, end + 1, size); } } diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 2f2702c867f76..c9a2d50ff1b0e 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -20,7 +20,6 @@ if VIRTUALIZATION config KVM bool select KVM_COMMON - select HAVE_KVM_VCPU_ASYNC_IOCTL select KVM_VFIO select HAVE_KVM_IRQ_BYPASS diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c index 03f8c34fa0a20..e5000bef90f2a 100644 --- a/arch/powerpc/kvm/book3s_hv_uvmem.c +++ b/arch/powerpc/kvm/book3s_hv_uvmem.c @@ -723,7 +723,7 @@ static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm) dpage = pfn_to_page(uvmem_pfn); dpage->zone_device_data = pvt; - zone_device_page_init(dpage); + zone_device_page_init(dpage, 0); return dpage; out_clear: spin_lock(&kvmppc_uvmem_bitmap_lock); @@ -1014,8 +1014,9 @@ static vm_fault_t kvmppc_uvmem_migrate_to_ram(struct vm_fault *vmf) * to a normal PFN during H_SVM_PAGE_OUT. * Gets called with kvm->arch.uvmem_lock held. */ -static void kvmppc_uvmem_page_free(struct page *page) +static void kvmppc_uvmem_folio_free(struct folio *folio) { + struct page *page = &folio->page; unsigned long pfn = page_to_pfn(page) - (kvmppc_uvmem_pgmap.range.start >> PAGE_SHIFT); struct kvmppc_uvmem_page_pvt *pvt; @@ -1034,7 +1035,7 @@ static void kvmppc_uvmem_page_free(struct page *page) } static const struct dev_pagemap_ops kvmppc_uvmem_ops = { - .page_free = kvmppc_uvmem_page_free, + .folio_free = kvmppc_uvmem_folio_free, .migrate_to_ram = kvmppc_uvmem_migrate_to_ram, }; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 2ba057171ebe0..9a89a6d98f97b 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -2028,8 +2028,8 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, return -EINVAL; } -long kvm_arch_vcpu_async_ioctl(struct file *filp, - unsigned int ioctl, unsigned long arg) +long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) { struct kvm_vcpu *vcpu = filp->private_data; void __user *argp = (void __user *)arg; diff --git a/arch/powerpc/mm/book3s32/tlb.c b/arch/powerpc/mm/book3s32/tlb.c index 9ad6b56bfec96..e54a7b0112322 100644 --- a/arch/powerpc/mm/book3s32/tlb.c +++ b/arch/powerpc/mm/book3s32/tlb.c @@ -105,3 +105,12 @@ void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); } EXPORT_SYMBOL(hash__flush_tlb_page); + +void hash__flush_gather(struct mmu_gather *tlb) +{ + if (tlb->fullmm || tlb->need_flush_all) + hash__flush_tlb_mm(tlb->mm); + else + hash__flush_range(tlb->mm, tlb->start, tlb->end); +} +EXPORT_SYMBOL(hash__flush_gather); diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index 3aee3af614af8..9dc5889d6ecb5 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -449,6 +450,7 @@ static __init void hash_kfence_map_pool(void) { unsigned long kfence_pool_start, kfence_pool_end; unsigned long prot = pgprot_val(PAGE_KERNEL); + unsigned int pshift = mmu_psize_defs[mmu_linear_psize].shift; if (!kfence_pool) return; @@ -459,6 +461,7 @@ static __init void hash_kfence_map_pool(void) BUG_ON(htab_bolt_mapping(kfence_pool_start, kfence_pool_end, kfence_pool, prot, mmu_linear_psize, mmu_kernel_ssize)); + update_page_count(mmu_linear_psize, KFENCE_POOL_SIZE >> pshift); memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE); } @@ -952,7 +955,7 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node, block_size = be64_to_cpu(addr_prop[1]); if (block_size != (16 * GB)) return 0; - printk(KERN_INFO "Huge page(16GB) memory: " + pr_info("Huge page(16GB) memory: " "addr = 0x%lX size = 0x%lX pages = %d\n", phys_addr, block_size, expected_pages); if (phys_addr + block_size * expected_pages <= memblock_end_of_DRAM()) { @@ -1135,7 +1138,7 @@ static void __init htab_init_page_sizes(void) mmu_vmemmap_psize = mmu_virtual_psize; #endif /* CONFIG_SPARSEMEM_VMEMMAP */ - printk(KERN_DEBUG "Page orders: linear mapping = %d, " + pr_info("Page orders: linear mapping = %d, " "virtual = %d, io = %d" #ifdef CONFIG_SPARSEMEM_VMEMMAP ", vmemmap = %d" @@ -1234,6 +1237,7 @@ int hash__create_section_mapping(unsigned long start, unsigned long end, int nid, pgprot_t prot) { int rc; + unsigned int pshift = mmu_psize_defs[mmu_linear_psize].shift; if (end >= H_VMALLOC_START) { pr_warn("Outside the supported range\n"); @@ -1251,17 +1255,22 @@ int hash__create_section_mapping(unsigned long start, unsigned long end, mmu_kernel_ssize); BUG_ON(rc2 && (rc2 != -ENOENT)); } + update_page_count(mmu_linear_psize, (end - start) >> pshift); return rc; } int hash__remove_section_mapping(unsigned long start, unsigned long end) { + unsigned int pshift = mmu_psize_defs[mmu_linear_psize].shift; + int rc = htab_remove_mapping(start, end, mmu_linear_psize, mmu_kernel_ssize); if (resize_hpt_for_hotplug(memblock_phys_mem_size()) == -ENOSPC) pr_warn("Hash collision while resizing HPT\n"); + if (!rc) + update_page_count(mmu_linear_psize, -((end - start) >> pshift)); return rc; } #endif /* CONFIG_MEMORY_HOTPLUG */ @@ -1302,27 +1311,34 @@ static void __init htab_initialize(void) unsigned long table; unsigned long pteg_count; unsigned long prot; - phys_addr_t base = 0, size = 0, end; + phys_addr_t base = 0, size = 0, end, limit = MEMBLOCK_ALLOC_ANYWHERE; u64 i; + unsigned int pshift = mmu_psize_defs[mmu_linear_psize].shift; DBG(" -> htab_initialize()\n"); + if (firmware_has_feature(FW_FEATURE_LPAR)) + limit = ppc64_rma_size; + if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) { mmu_kernel_ssize = MMU_SEGSIZE_1T; mmu_highuser_ssize = MMU_SEGSIZE_1T; - printk(KERN_INFO "Using 1TB segments\n"); + pr_info("Using 1TB segments\n"); } if (stress_slb_enabled) static_branch_enable(&stress_slb_key); + if (no_slb_preload) + static_branch_enable(&no_slb_preload_key); + if (stress_hpt_enabled) { unsigned long tmp; static_branch_enable(&stress_hpt_key); // Too early to use nr_cpu_ids, so use NR_CPUS tmp = memblock_phys_alloc_range(sizeof(struct stress_hpt_struct) * NR_CPUS, __alignof__(struct stress_hpt_struct), - 0, MEMBLOCK_ALLOC_ANYWHERE); + MEMBLOCK_LOW_LIMIT, limit); memset((void *)tmp, 0xff, sizeof(struct stress_hpt_struct) * NR_CPUS); stress_hpt_struct = __va(tmp); @@ -1356,11 +1372,10 @@ static void __init htab_initialize(void) mmu_hash_ops.hpte_clear_all(); #endif } else { - unsigned long limit = MEMBLOCK_ALLOC_ANYWHERE; table = memblock_phys_alloc_range(htab_size_bytes, htab_size_bytes, - 0, limit); + MEMBLOCK_LOW_LIMIT, limit); if (!table) panic("ERROR: Failed to allocate %pa bytes below %pa\n", &htab_size_bytes, &limit); @@ -1392,8 +1407,8 @@ static void __init htab_initialize(void) size = end - base; base = (unsigned long)__va(base); - DBG("creating mapping for region: %lx..%lx (prot: %lx)\n", - base, size, prot); + pr_debug("creating mapping for region: 0x%pa..0x%pa (prot: %lx)\n", + &base, &size, prot); if ((base + size) >= H_VMALLOC_START) { pr_warn("Outside the supported range\n"); @@ -1402,6 +1417,8 @@ static void __init htab_initialize(void) BUG_ON(htab_bolt_mapping(base, base + size, __pa(base), prot, mmu_linear_psize, mmu_kernel_ssize)); + + update_page_count(mmu_linear_psize, size >> pshift); } hash_kfence_map_pool(); memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE); @@ -1423,6 +1440,8 @@ static void __init htab_initialize(void) BUG_ON(htab_bolt_mapping(tce_alloc_start, tce_alloc_end, __pa(tce_alloc_start), prot, mmu_linear_psize, mmu_kernel_ssize)); + update_page_count(mmu_linear_psize, + (tce_alloc_end - tce_alloc_start) >> pshift); } @@ -1867,7 +1886,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, * in vmalloc space, so switch vmalloc * to 4k pages */ - printk(KERN_ALERT "Reducing vmalloc segment " + pr_alert("Reducing vmalloc segment " "to 4kB pages because of " "non-cacheable mapping\n"); psize = mmu_vmalloc_psize = MMU_PAGE_4K; @@ -2432,6 +2451,8 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_hpt_order, hpt_order_get, hpt_order_set, "%llu\n") static int __init hash64_debugfs(void) { + if (radix_enabled()) + return 0; debugfs_create_file("hpt_order", 0600, arch_debugfs_dir, NULL, &fops_hpt_order); return 0; diff --git a/arch/powerpc/mm/book3s64/internal.h b/arch/powerpc/mm/book3s64/internal.h index a57a25f06a215..cad08d83369cf 100644 --- a/arch/powerpc/mm/book3s64/internal.h +++ b/arch/powerpc/mm/book3s64/internal.h @@ -22,9 +22,14 @@ static inline bool stress_hpt(void) return static_branch_unlikely(&stress_hpt_key); } -void hpt_do_stress(unsigned long ea, unsigned long hpte_group); +extern bool no_slb_preload; +DECLARE_STATIC_KEY_FALSE(no_slb_preload_key); +static inline bool slb_preload_disabled(void) +{ + return static_branch_unlikely(&no_slb_preload_key); +} -void slb_setup_new_exec(void); +void hpt_do_stress(unsigned long ea, unsigned long hpte_group); void exit_lazy_flush_tlb(struct mm_struct *mm, bool always_flush); diff --git a/arch/powerpc/mm/book3s64/mmu_context.c b/arch/powerpc/mm/book3s64/mmu_context.c index 4e1e45420bd49..fb9dcf9ca5998 100644 --- a/arch/powerpc/mm/book3s64/mmu_context.c +++ b/arch/powerpc/mm/book3s64/mmu_context.c @@ -150,8 +150,6 @@ static int hash__init_new_context(struct mm_struct *mm) void hash__setup_new_exec(void) { slice_setup_new_exec(); - - slb_setup_new_exec(); } #else static inline int hash__init_new_context(struct mm_struct *mm) diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c index c9431ae7f78a0..e3485db7de027 100644 --- a/arch/powerpc/mm/book3s64/pgtable.c +++ b/arch/powerpc/mm/book3s64/pgtable.c @@ -510,20 +510,21 @@ atomic_long_t direct_pages_count[MMU_PAGE_COUNT]; void arch_report_meminfo(struct seq_file *m) { - /* - * Hash maps the memory with one size mmu_linear_psize. - * So don't bother to print these on hash - */ - if (!radix_enabled()) - return; seq_printf(m, "DirectMap4k: %8lu kB\n", atomic_long_read(&direct_pages_count[MMU_PAGE_4K]) << 2); - seq_printf(m, "DirectMap64k: %8lu kB\n", + seq_printf(m, "DirectMap64k: %8lu kB\n", atomic_long_read(&direct_pages_count[MMU_PAGE_64K]) << 6); - seq_printf(m, "DirectMap2M: %8lu kB\n", - atomic_long_read(&direct_pages_count[MMU_PAGE_2M]) << 11); - seq_printf(m, "DirectMap1G: %8lu kB\n", - atomic_long_read(&direct_pages_count[MMU_PAGE_1G]) << 20); + if (radix_enabled()) { + seq_printf(m, "DirectMap2M: %8lu kB\n", + atomic_long_read(&direct_pages_count[MMU_PAGE_2M]) << 11); + seq_printf(m, "DirectMap1G: %8lu kB\n", + atomic_long_read(&direct_pages_count[MMU_PAGE_1G]) << 20); + } else { + seq_printf(m, "DirectMap16M: %8lu kB\n", + atomic_long_read(&direct_pages_count[MMU_PAGE_16M]) << 14); + seq_printf(m, "DirectMap16G: %8lu kB\n", + atomic_long_read(&direct_pages_count[MMU_PAGE_16G]) << 24); + } } #endif /* CONFIG_PROC_FS */ diff --git a/arch/powerpc/mm/book3s64/slb.c b/arch/powerpc/mm/book3s64/slb.c index 6b783552403c6..15f73abd15069 100644 --- a/arch/powerpc/mm/book3s64/slb.c +++ b/arch/powerpc/mm/book3s64/slb.c @@ -42,6 +42,15 @@ early_param("stress_slb", parse_stress_slb); __ro_after_init DEFINE_STATIC_KEY_FALSE(stress_slb_key); +bool no_slb_preload __initdata; +static int __init parse_no_slb_preload(char *p) +{ + no_slb_preload = true; + return 0; +} +early_param("no_slb_preload", parse_no_slb_preload); +__ro_after_init DEFINE_STATIC_KEY_FALSE(no_slb_preload_key); + static void assert_slb_presence(bool present, unsigned long ea) { #ifdef CONFIG_DEBUG_VM @@ -294,11 +303,14 @@ static bool preload_hit(struct thread_info *ti, unsigned long esid) return false; } -static bool preload_add(struct thread_info *ti, unsigned long ea) +static void preload_add(struct thread_info *ti, unsigned long ea) { unsigned char idx; unsigned long esid; + if (slb_preload_disabled()) + return; + if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) { /* EAs are stored >> 28 so 256MB segments don't need clearing */ if (ea & ESID_MASK_1T) @@ -308,7 +320,7 @@ static bool preload_add(struct thread_info *ti, unsigned long ea) esid = ea >> SID_SHIFT; if (preload_hit(ti, esid)) - return false; + return; idx = (ti->slb_preload_tail + ti->slb_preload_nr) % SLB_PRELOAD_NR; ti->slb_preload_esid[idx] = esid; @@ -316,8 +328,6 @@ static bool preload_add(struct thread_info *ti, unsigned long ea) ti->slb_preload_tail = (ti->slb_preload_tail + 1) % SLB_PRELOAD_NR; else ti->slb_preload_nr++; - - return true; } static void preload_age(struct thread_info *ti) @@ -328,94 +338,6 @@ static void preload_age(struct thread_info *ti) ti->slb_preload_tail = (ti->slb_preload_tail + 1) % SLB_PRELOAD_NR; } -void slb_setup_new_exec(void) -{ - struct thread_info *ti = current_thread_info(); - struct mm_struct *mm = current->mm; - unsigned long exec = 0x10000000; - - WARN_ON(irqs_disabled()); - - /* - * preload cache can only be used to determine whether a SLB - * entry exists if it does not start to overflow. - */ - if (ti->slb_preload_nr + 2 > SLB_PRELOAD_NR) - return; - - hard_irq_disable(); - - /* - * We have no good place to clear the slb preload cache on exec, - * flush_thread is about the earliest arch hook but that happens - * after we switch to the mm and have already preloaded the SLBEs. - * - * For the most part that's probably okay to use entries from the - * previous exec, they will age out if unused. It may turn out to - * be an advantage to clear the cache before switching to it, - * however. - */ - - /* - * preload some userspace segments into the SLB. - * Almost all 32 and 64bit PowerPC executables are linked at - * 0x10000000 so it makes sense to preload this segment. - */ - if (!is_kernel_addr(exec)) { - if (preload_add(ti, exec)) - slb_allocate_user(mm, exec); - } - - /* Libraries and mmaps. */ - if (!is_kernel_addr(mm->mmap_base)) { - if (preload_add(ti, mm->mmap_base)) - slb_allocate_user(mm, mm->mmap_base); - } - - /* see switch_slb */ - asm volatile("isync" : : : "memory"); - - local_irq_enable(); -} - -void preload_new_slb_context(unsigned long start, unsigned long sp) -{ - struct thread_info *ti = current_thread_info(); - struct mm_struct *mm = current->mm; - unsigned long heap = mm->start_brk; - - WARN_ON(irqs_disabled()); - - /* see above */ - if (ti->slb_preload_nr + 3 > SLB_PRELOAD_NR) - return; - - hard_irq_disable(); - - /* Userspace entry address. */ - if (!is_kernel_addr(start)) { - if (preload_add(ti, start)) - slb_allocate_user(mm, start); - } - - /* Top of stack, grows down. */ - if (!is_kernel_addr(sp)) { - if (preload_add(ti, sp)) - slb_allocate_user(mm, sp); - } - - /* Bottom of heap, grows up. */ - if (heap && !is_kernel_addr(heap)) { - if (preload_add(ti, heap)) - slb_allocate_user(mm, heap); - } - - /* see switch_slb */ - asm volatile("isync" : : : "memory"); - - local_irq_enable(); -} - static void slb_cache_slbie_kernel(unsigned int index) { unsigned long slbie_data = get_paca()->slb_cache[index]; @@ -502,6 +424,9 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) copy_mm_to_paca(mm); + if (slb_preload_disabled()) + return; + /* * We gradually age out SLBs after a number of context switches to * reduce reload overhead of unused entries (like we do with FP/VEC diff --git a/arch/powerpc/mm/ptdump/8xx.c b/arch/powerpc/mm/ptdump/8xx.c index 4ca9cf7a90c9e..ff845f2517244 100644 --- a/arch/powerpc/mm/ptdump/8xx.c +++ b/arch/powerpc/mm/ptdump/8xx.c @@ -71,18 +71,23 @@ static const struct flag_info flag_array[] = { struct ptdump_pg_level pg_level[5] = { { /* pgd */ + .name = "PGD", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* p4d */ + .name = "P4D", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* pud */ + .name = "PUD", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* pmd */ + .name = "PMD", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* pte */ + .name = "PTE", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, diff --git a/arch/powerpc/mm/ptdump/book3s64.c b/arch/powerpc/mm/ptdump/book3s64.c index 6b2da9241d4c4..e8a21c6dc32e4 100644 --- a/arch/powerpc/mm/ptdump/book3s64.c +++ b/arch/powerpc/mm/ptdump/book3s64.c @@ -104,18 +104,23 @@ static const struct flag_info flag_array[] = { struct ptdump_pg_level pg_level[5] = { { /* pgd */ + .name = "PGD", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* p4d */ + .name = "P4D", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* pud */ + .name = "PUD", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* pmd */ + .name = "PMD", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* pte */ + .name = "PTE", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c index a6baa6166d940..671d0dc00c6d0 100644 --- a/arch/powerpc/mm/ptdump/hashpagetable.c +++ b/arch/powerpc/mm/ptdump/hashpagetable.c @@ -216,6 +216,8 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 vpn = hpt_vpn(ea, vsid, ssize); hash = hpt_hash(vpn, shift, ssize); want_v = hpte_encode_avpn(vpn, psize, ssize); + if (cpu_has_feature(CPU_FTR_ARCH_300)) + want_v = hpte_old_to_new_v(want_v); /* to check in the secondary hash table, we invert the hash */ if (!primary) @@ -229,6 +231,10 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 /* HPTE matches */ *v = be64_to_cpu(hptep->v); *r = be64_to_cpu(hptep->r); + if (cpu_has_feature(CPU_FTR_ARCH_300)) { + *v = hpte_new_to_old_v(*v, *r); + *r = hpte_new_to_old_r(*r); + } return 0; } ++hpte_group; diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c index b2358d794855c..0d499aebee72f 100644 --- a/arch/powerpc/mm/ptdump/ptdump.c +++ b/arch/powerpc/mm/ptdump/ptdump.c @@ -178,6 +178,7 @@ static void dump_addr(struct pg_state *st, unsigned long addr) pt_dump_seq_printf(st->seq, REG "-" REG " ", st->start_address, addr - 1); pt_dump_seq_printf(st->seq, " " REG " ", st->start_pa); pt_dump_size(st->seq, addr - st->start_address); + pt_dump_seq_printf(st->seq, "%s ", pg_level[st->level].name); } static void note_prot_wx(struct pg_state *st, unsigned long addr) diff --git a/arch/powerpc/mm/ptdump/ptdump.h b/arch/powerpc/mm/ptdump/ptdump.h index 4232aa4b57eae..12aa9eca8b0cc 100644 --- a/arch/powerpc/mm/ptdump/ptdump.h +++ b/arch/powerpc/mm/ptdump/ptdump.h @@ -13,6 +13,7 @@ struct flag_info { struct ptdump_pg_level { const struct flag_info *flag; + char name[4]; size_t num; u64 mask; }; diff --git a/arch/powerpc/mm/ptdump/shared.c b/arch/powerpc/mm/ptdump/shared.c index 58998960eb9a4..edc69da19b853 100644 --- a/arch/powerpc/mm/ptdump/shared.c +++ b/arch/powerpc/mm/ptdump/shared.c @@ -69,18 +69,23 @@ static const struct flag_info flag_array[] = { struct ptdump_pg_level pg_level[5] = { { /* pgd */ + .name = "PGD", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* p4d */ + .name = "P4D", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* pud */ + .name = "PUD", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* pmd */ + .name = "PMD", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, { /* pte */ + .name = "PTE", .flag = flag_array, .num = ARRAY_SIZE(flag_array), }, diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index cb7b9498f291f..80d944f292885 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -123,6 +123,8 @@ static int mcu_gpiochip_add(struct mcu *mcu) gc->owner = THIS_MODULE; gc->label = kasprintf(GFP_KERNEL, "%pfw", dev_fwnode(dev)); + if (!gc->label) + return -ENOMEM; gc->can_sleep = 1; gc->ngpio = MCU_NUM_GPIO; gc->base = -1; diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 2c07387201d0d..3c86248709674 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -464,7 +464,7 @@ void spu_init_channels(struct spu *spu) } EXPORT_SYMBOL_GPL(spu_init_channels); -static struct bus_type spu_subsys = { +static const struct bus_type spu_subsys = { .name = "spu", .dev_name = "spu", }; @@ -726,7 +726,7 @@ static inline void crash_register_spus(struct list_head *list) } #endif -static void spu_shutdown(void) +static void spu_shutdown(void *data) { struct spu *spu; @@ -738,10 +738,14 @@ static void spu_shutdown(void) mutex_unlock(&spu_full_list_mutex); } -static struct syscore_ops spu_syscore_ops = { +static const struct syscore_ops spu_syscore_ops = { .shutdown = spu_shutdown, }; +static struct syscore spu_syscore = { + .ops = &spu_syscore_ops, +}; + static int __init init_spu_base(void) { int i, ret = 0; @@ -774,7 +778,7 @@ static int __init init_spu_base(void) crash_register_spus(&spu_full_list); mutex_unlock(&spu_full_list_mutex); spu_add_dev_attr(&dev_attr_stat); - register_syscore_ops(&spu_syscore_ops); + register_syscore(&spu_syscore); spu_init_affinity(); diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 78c4b6ce5f136..577a00c25217a 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -127,7 +127,7 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry, inode->i_fop = fops; inode->i_size = size; inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); - d_add(dentry, inode); + d_make_persistent(dentry, inode); out: return ret; } @@ -163,10 +163,9 @@ static int spufs_fill_dir(struct dentry *dir, return -ENOMEM; ret = spufs_new_file(dir->d_sb, dentry, files->ops, files->mode & mode, files->size, ctx); - if (ret) { - dput(dentry); + dput(dentry); + if (ret) return ret; - } files++; } return 0; @@ -241,11 +240,10 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, inode_lock(inode); - dget(dentry); inc_nlink(dir); inc_nlink(inode); - d_instantiate(dentry, inode); + d_make_persistent(dentry, inode); if (flags & SPU_CREATE_NOSCHED) ret = spufs_fill_dir(dentry, spufs_dir_nosched_contents, @@ -468,10 +466,9 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, umode_t mode) inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; - d_instantiate(dentry, inode); - dget(dentry); inc_nlink(dir); - inc_nlink(d_inode(dentry)); + inc_nlink(inode); + d_make_persistent(dentry, inode); return ret; out_iput: @@ -758,7 +755,7 @@ static struct file_system_type spufs_type = { .name = "spufs", .init_fs_context = spufs_init_fs_context, .parameters = spufs_fs_parameters, - .kill_sb = kill_litter_super, + .kill_sb = kill_anon_super, }; MODULE_ALIAS_FS("spufs"); diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c index 79741370c40c6..1796327955c6d 100644 --- a/arch/powerpc/platforms/powermac/backlight.c +++ b/arch/powerpc/platforms/powermac/backlight.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index c37783a03d254..1959cc13438f5 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -600,7 +600,7 @@ static int pmacpic_find_viaint(void) return viaint; } -static int pmacpic_suspend(void) +static int pmacpic_suspend(void *data) { int viaint = pmacpic_find_viaint(); @@ -621,7 +621,7 @@ static int pmacpic_suspend(void) return 0; } -static void pmacpic_resume(void) +static void pmacpic_resume(void *data) { int i; @@ -634,15 +634,19 @@ static void pmacpic_resume(void) pmac_unmask_irq(irq_get_irq_data(i)); } -static struct syscore_ops pmacpic_syscore_ops = { +static const struct syscore_ops pmacpic_syscore_ops = { .suspend = pmacpic_suspend, .resume = pmacpic_resume, }; +static struct syscore pmacpic_syscore = { + .ops = &pmacpic_syscore_ops, +}; + static int __init init_pmacpic_syscore(void) { if (pmac_irq_hw[0]) - register_syscore_ops(&pmacpic_syscore_ops); + register_syscore(&pmacpic_syscore); return 0; } diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index d98b933e4984c..e4f4e907f6e36 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -1171,8 +1171,9 @@ static void __init pnv_arch300_idle_init(void) u64 max_residency_ns = 0; int i; - /* stop is not really architected, we only have p9,p10 drivers */ - if (!pvr_version_is(PVR_POWER10) && !pvr_version_is(PVR_POWER9)) + /* stop is not really architected, we only have p9,p10 and p11 drivers */ + if (!pvr_version_is(PVR_POWER9) && !pvr_version_is(PVR_POWER10) && + !pvr_version_is(PVR_POWER11)) return; /* @@ -1189,8 +1190,8 @@ static void __init pnv_arch300_idle_init(void) struct pnv_idle_states_t *state = &pnv_idle_states[i]; u64 psscr_rl = state->psscr_val & PSSCR_RL_MASK; - /* No deep loss driver implemented for POWER10 yet */ - if (pvr_version_is(PVR_POWER10) && + /* No deep loss driver implemented for POWER10 and POWER11 yet */ + if ((pvr_version_is(PVR_POWER10) || pvr_version_is(PVR_POWER11)) && state->flags & (OPAL_PM_TIMEBASE_STOP|OPAL_PM_LOSE_FULL_CONTEXT)) continue; diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index afbaabf182d01..0537a678a32f2 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -465,7 +465,7 @@ static struct attribute *ps3_system_bus_dev_attrs[] = { }; ATTRIBUTE_GROUPS(ps3_system_bus_dev); -static struct bus_type ps3_system_bus_type = { +static const struct bus_type ps3_system_bus_type = { .name = "ps3_system_bus", .match = ps3_system_bus_match, .uevent = ps3_system_bus_uevent, @@ -551,18 +551,20 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, /* Creates TCEs for a user provided buffer. The user buffer must be * contiguous real kernel storage (not vmalloc). The address passed here - * comprises a page address and offset into that page. The dma_addr_t - * returned will point to the same byte within the page as was passed in. + * is physical address to that hat page. The dma_addr_t returned will point + * to the same byte within the page as was passed in. */ -static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page, - unsigned long offset, size_t size, enum dma_data_direction direction, - unsigned long attrs) +static dma_addr_t ps3_sb_map_phys(struct device *_dev, phys_addr_t phys, + size_t size, enum dma_data_direction direction, unsigned long attrs) { struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); int result; dma_addr_t bus_addr; - void *ptr = page_address(page) + offset; + void *ptr = phys_to_virt(phys); + + if (unlikely(attrs & DMA_ATTR_MMIO)) + return DMA_MAPPING_ERROR; result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, &bus_addr, @@ -577,8 +579,8 @@ static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page, return bus_addr; } -static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page, - unsigned long offset, size_t size, +static dma_addr_t ps3_ioc0_map_phys(struct device *_dev, phys_addr_t phys, + size_t size, enum dma_data_direction direction, unsigned long attrs) { @@ -586,7 +588,10 @@ static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page, int result; dma_addr_t bus_addr; u64 iopte_flag; - void *ptr = page_address(page) + offset; + void *ptr = phys_to_virt(phys); + + if (unlikely(attrs & DMA_ATTR_MMIO)) + return DMA_MAPPING_ERROR; iopte_flag = CBE_IOPTE_M; switch (direction) { @@ -613,7 +618,7 @@ static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page, return bus_addr; } -static void ps3_unmap_page(struct device *_dev, dma_addr_t dma_addr, +static void ps3_unmap_phys(struct device *_dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction, unsigned long attrs) { struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); @@ -690,8 +695,8 @@ static const struct dma_map_ops ps3_sb_dma_ops = { .map_sg = ps3_sb_map_sg, .unmap_sg = ps3_sb_unmap_sg, .dma_supported = ps3_dma_supported, - .map_page = ps3_sb_map_page, - .unmap_page = ps3_unmap_page, + .map_phys = ps3_sb_map_phys, + .unmap_phys = ps3_unmap_phys, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, .alloc_pages_op = dma_common_alloc_pages, @@ -704,8 +709,8 @@ static const struct dma_map_ops ps3_ioc0_dma_ops = { .map_sg = ps3_ioc0_map_sg, .unmap_sg = ps3_ioc0_unmap_sg, .dma_supported = ps3_dma_supported, - .map_page = ps3_ioc0_map_page, - .unmap_page = ps3_unmap_page, + .map_phys = ps3_ioc0_map_phys, + .unmap_phys = ps3_unmap_phys, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, .alloc_pages_op = dma_common_alloc_pages, diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c index 0823fa2da1516..4cbbe2ee58aba 100644 --- a/arch/powerpc/platforms/pseries/cmm.c +++ b/arch/powerpc/platforms/pseries/cmm.c @@ -375,7 +375,7 @@ static struct device_attribute *cmm_attrs[] = { static DEVICE_ULONG_ATTR(simulate_loan_target_kb, 0644, simulate_loan_target_kb); -static struct bus_type cmm_subsys = { +static const struct bus_type cmm_subsys = { .name = "cmm", .dev_name = "cmm", }; @@ -532,6 +532,7 @@ static int cmm_migratepage(struct balloon_dev_info *b_dev_info, spin_lock_irqsave(&b_dev_info->pages_lock, flags); balloon_page_insert(b_dev_info, newpage); + __count_vm_event(BALLOON_MIGRATE); b_dev_info->isolated_pages--; spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); @@ -550,7 +551,6 @@ static int cmm_migratepage(struct balloon_dev_info *b_dev_info, static void cmm_balloon_compaction_init(void) { - balloon_devinfo_init(&b_dev_info); b_dev_info.migratepage = cmm_migratepage; } #else /* CONFIG_BALLOON_COMPACTION */ @@ -572,6 +572,7 @@ static int cmm_init(void) if (!firmware_has_feature(FW_FEATURE_CMO) && !simulate) return -EOPNOTSUPP; + balloon_devinfo_init(&b_dev_info); cmm_balloon_compaction_init(); rc = register_oom_notifier(&cmm_oom_nb); diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c index 3436b0af795e2..cad2deb7e70d9 100644 --- a/arch/powerpc/platforms/pseries/ibmebus.c +++ b/arch/powerpc/platforms/pseries/ibmebus.c @@ -86,17 +86,18 @@ static void ibmebus_free_coherent(struct device *dev, kfree(vaddr); } -static dma_addr_t ibmebus_map_page(struct device *dev, - struct page *page, - unsigned long offset, +static dma_addr_t ibmebus_map_phys(struct device *dev, phys_addr_t phys, size_t size, enum dma_data_direction direction, unsigned long attrs) { - return (dma_addr_t)(page_address(page) + offset); + if (attrs & DMA_ATTR_MMIO) + return DMA_MAPPING_ERROR; + + return (dma_addr_t)(phys_to_virt(phys)); } -static void ibmebus_unmap_page(struct device *dev, +static void ibmebus_unmap_phys(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction, @@ -146,8 +147,8 @@ static const struct dma_map_ops ibmebus_dma_ops = { .unmap_sg = ibmebus_unmap_sg, .dma_supported = ibmebus_dma_supported, .get_required_mask = ibmebus_dma_get_required_mask, - .map_page = ibmebus_map_page, - .unmap_page = ibmebus_unmap_page, + .map_phys = ibmebus_map_phys, + .unmap_phys = ibmebus_unmap_phys, }; static int ibmebus_match_path(struct device *dev, const void *data) diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c index cc22924f159f5..6554537984fb5 100644 --- a/arch/powerpc/platforms/pseries/lparcfg.c +++ b/arch/powerpc/platforms/pseries/lparcfg.c @@ -78,6 +78,8 @@ struct hvcall_ppp_data { u8 capped; u8 weight; u8 unallocated_weight; + u8 resource_group_index; + u16 active_procs_in_resource_group; u16 active_procs_in_pool; u16 active_system_procs; u16 phys_platform_procs; @@ -86,7 +88,7 @@ struct hvcall_ppp_data { }; /* - * H_GET_PPP hcall returns info in 4 parms. + * H_GET_PPP hcall returns info in 5 parms. * entitled_capacity,unallocated_capacity, * aggregation, resource_capability). * @@ -94,11 +96,11 @@ struct hvcall_ppp_data { * R5 = Unallocated Processor Capacity Percentage. * R6 (AABBCCDDEEFFGGHH). * XXXX - reserved (0) - * XXXX - reserved (0) + * XXXX - Active Cores in Resource Group * XXXX - Group Number * XXXX - Pool Number. * R7 (IIJJKKLLMMNNOOPP). - * XX - reserved. (0) + * XX - Resource group Number * XX - bit 0-6 reserved (0). bit 7 is Capped indicator. * XX - variable processor Capacity Weight * XX - Unallocated Variable Processor Capacity Weight. @@ -120,9 +122,11 @@ static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data) ppp_data->entitlement = retbuf[0]; ppp_data->unallocated_entitlement = retbuf[1]; + ppp_data->active_procs_in_resource_group = (retbuf[2] >> 4 * 8) & 0xffff; ppp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff; ppp_data->pool_num = retbuf[2] & 0xffff; + ppp_data->resource_group_index = (retbuf[3] >> 7 * 8) & 0xff; ppp_data->capped = (retbuf[3] >> 6 * 8) & 0x01; ppp_data->weight = (retbuf[3] >> 5 * 8) & 0xff; ppp_data->unallocated_weight = (retbuf[3] >> 4 * 8) & 0xff; @@ -236,6 +240,13 @@ static void parse_ppp_data(struct seq_file *m) seq_printf(m, "unallocated_capacity=%lld\n", ppp_data.unallocated_entitlement); + if (ppp_data.active_procs_in_resource_group) { + seq_printf(m, "resource_group_number=%d\n", + ppp_data.resource_group_index); + seq_printf(m, "resource_group_active_processors=%d\n", + ppp_data.active_procs_in_resource_group); + } + /* The last bits of information returned from h_get_ppp are only * valid if the ibm,partition-performance-parameters-level * property is >= 1. diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index aeb8633a3d00f..8c77ec7980de3 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -29,7 +29,7 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn) nid = of_node_to_nid(dn); if (likely((nid) >= 0)) { if (!node_online(nid)) { - if (register_one_node(nid)) { + if (register_node(nid)) { pr_err("PCI: Failed to register node %d\n", nid); } else { update_numa_distance(dn); diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c index 382003dfdb9ab..c51db63d3e88d 100644 --- a/arch/powerpc/platforms/pseries/suspend.c +++ b/arch/powerpc/platforms/pseries/suspend.c @@ -126,7 +126,7 @@ static ssize_t show_hibernate(struct device *dev, static DEVICE_ATTR(hibernate, 0644, show_hibernate, store_hibernate); -static struct bus_type suspend_subsys = { +static const struct bus_type suspend_subsys = { .name = "power", .dev_name = "power", }; diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index ac1d2d2c9a88a..18cffac5468f8 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -512,18 +512,21 @@ static void vio_dma_iommu_free_coherent(struct device *dev, size_t size, vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE)); } -static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction, - unsigned long attrs) +static dma_addr_t vio_dma_iommu_map_phys(struct device *dev, phys_addr_t phys, + size_t size, + enum dma_data_direction direction, + unsigned long attrs) { struct vio_dev *viodev = to_vio_dev(dev); struct iommu_table *tbl = get_iommu_table_base(dev); dma_addr_t ret = DMA_MAPPING_ERROR; + if (unlikely(attrs & DMA_ATTR_MMIO)) + return ret; + if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl)))) goto out_fail; - ret = iommu_map_page(dev, tbl, page, offset, size, dma_get_mask(dev), + ret = iommu_map_phys(dev, tbl, phys, size, dma_get_mask(dev), direction, attrs); if (unlikely(ret == DMA_MAPPING_ERROR)) goto out_deallocate; @@ -536,7 +539,7 @@ static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page, return DMA_MAPPING_ERROR; } -static void vio_dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle, +static void vio_dma_iommu_unmap_phys(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction, unsigned long attrs) @@ -544,7 +547,7 @@ static void vio_dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle, struct vio_dev *viodev = to_vio_dev(dev); struct iommu_table *tbl = get_iommu_table_base(dev); - iommu_unmap_page(tbl, dma_handle, size, direction, attrs); + iommu_unmap_phys(tbl, dma_handle, size, direction, attrs); vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl))); } @@ -605,8 +608,8 @@ static const struct dma_map_ops vio_dma_mapping_ops = { .free = vio_dma_iommu_free_coherent, .map_sg = vio_dma_iommu_map_sg, .unmap_sg = vio_dma_iommu_unmap_sg, - .map_page = vio_dma_iommu_map_page, - .unmap_page = vio_dma_iommu_unmap_page, + .map_phys = vio_dma_iommu_map_phys, + .unmap_phys = vio_dma_iommu_unmap_phys, .dma_supported = dma_iommu_dma_supported, .get_required_mask = dma_iommu_get_required_mask, .mmap = dma_common_mmap, diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c index 217cea150987d..7ed07232a69a4 100644 --- a/arch/powerpc/sysdev/fsl_lbc.c +++ b/arch/powerpc/sysdev/fsl_lbc.c @@ -350,7 +350,7 @@ static int fsl_lbc_ctrl_probe(struct platform_device *dev) #ifdef CONFIG_SUSPEND /* save lbc registers */ -static int fsl_lbc_syscore_suspend(void) +static int fsl_lbc_syscore_suspend(void *data) { struct fsl_lbc_ctrl *ctrl; struct fsl_lbc_regs __iomem *lbc; @@ -374,7 +374,7 @@ static int fsl_lbc_syscore_suspend(void) } /* restore lbc registers */ -static void fsl_lbc_syscore_resume(void) +static void fsl_lbc_syscore_resume(void *data) { struct fsl_lbc_ctrl *ctrl; struct fsl_lbc_regs __iomem *lbc; @@ -408,10 +408,14 @@ static const struct of_device_id fsl_lbc_match[] = { }; #ifdef CONFIG_SUSPEND -static struct syscore_ops lbc_syscore_pm_ops = { +static const struct syscore_ops lbc_syscore_pm_ops = { .suspend = fsl_lbc_syscore_suspend, .resume = fsl_lbc_syscore_resume, }; + +static struct syscore lbc_syscore_pm = { + .ops = &lbc_syscore_pm_ops, +}; #endif static struct platform_driver fsl_lbc_ctrl_driver = { @@ -425,7 +429,7 @@ static struct platform_driver fsl_lbc_ctrl_driver = { static int __init fsl_lbc_init(void) { #ifdef CONFIG_SUSPEND - register_syscore_ops(&lbc_syscore_pm_ops); + register_syscore(&lbc_syscore_pm); #endif return platform_driver_register(&fsl_lbc_ctrl_driver); } diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index ef7707ea0db7b..4e501654cb41b 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -1258,7 +1258,7 @@ static void fsl_pci_syscore_do_suspend(struct pci_controller *hose) send_pme_turnoff_message(hose); } -static int fsl_pci_syscore_suspend(void) +static int fsl_pci_syscore_suspend(void *data) { struct pci_controller *hose, *tmp; @@ -1291,7 +1291,7 @@ static void fsl_pci_syscore_do_resume(struct pci_controller *hose) setup_pci_atmu(hose); } -static void fsl_pci_syscore_resume(void) +static void fsl_pci_syscore_resume(void *data) { struct pci_controller *hose, *tmp; @@ -1299,10 +1299,14 @@ static void fsl_pci_syscore_resume(void) fsl_pci_syscore_do_resume(hose); } -static struct syscore_ops pci_syscore_pm_ops = { +static const struct syscore_ops pci_syscore_pm_ops = { .suspend = fsl_pci_syscore_suspend, .resume = fsl_pci_syscore_resume, }; + +static struct syscore pci_syscore_pm = { + .ops = &pci_syscore_pm_ops, +}; #endif void fsl_pcibios_fixup_phb(struct pci_controller *phb) @@ -1359,7 +1363,7 @@ static struct platform_driver fsl_pci_driver = { static int __init fsl_pci_init(void) { #ifdef CONFIG_PM_SLEEP - register_syscore_ops(&pci_syscore_pm_ops); + register_syscore(&pci_syscore_pm); #endif return platform_driver_register(&fsl_pci_driver); } diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index 70be2105865db..290ba8427239f 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -817,7 +817,7 @@ static struct { u32 sercr; } ipic_saved_state; -static int ipic_suspend(void) +static int ipic_suspend(void *data) { struct ipic *ipic = primary_ipic; @@ -848,7 +848,7 @@ static int ipic_suspend(void) return 0; } -static void ipic_resume(void) +static void ipic_resume(void *data) { struct ipic *ipic = primary_ipic; @@ -870,18 +870,22 @@ static void ipic_resume(void) #define ipic_resume NULL #endif -static struct syscore_ops ipic_syscore_ops = { +static const struct syscore_ops ipic_syscore_ops = { .suspend = ipic_suspend, .resume = ipic_resume, }; +static struct syscore ipic_syscore = { + .ops = &ipic_syscore_ops, +}; + static int __init init_ipic_syscore(void) { if (!primary_ipic || !primary_ipic->regs) return -ENODEV; printk(KERN_DEBUG "Registering ipic system core operations\n"); - register_syscore_ops(&ipic_syscore_ops); + register_syscore(&ipic_syscore); return 0; } diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index ad7310bba00bc..67e51998d1aea 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1944,7 +1944,7 @@ static void mpic_suspend_one(struct mpic *mpic) } } -static int mpic_suspend(void) +static int mpic_suspend(void *data) { struct mpic *mpic = mpics; @@ -1986,7 +1986,7 @@ static void mpic_resume_one(struct mpic *mpic) } /* end for loop */ } -static void mpic_resume(void) +static void mpic_resume(void *data) { struct mpic *mpic = mpics; @@ -1996,19 +1996,23 @@ static void mpic_resume(void) } } -static struct syscore_ops mpic_syscore_ops = { +static const struct syscore_ops mpic_syscore_ops = { .resume = mpic_resume, .suspend = mpic_suspend, }; +static struct syscore mpic_syscore = { + .ops = &mpic_syscore_ops, +}; + static int mpic_init_sys(void) { int rc; - register_syscore_ops(&mpic_syscore_ops); + register_syscore(&mpic_syscore); rc = subsys_system_register(&mpic_subsys, NULL); if (rc) { - unregister_syscore_ops(&mpic_syscore_ops); + unregister_syscore(&mpic_syscore); pr_err("mpic: Failed to register subsystem!\n"); return rc; } diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c index 7166e2e0baaf6..60f5b3934b511 100644 --- a/arch/powerpc/sysdev/mpic_timer.c +++ b/arch/powerpc/sysdev/mpic_timer.c @@ -519,7 +519,7 @@ static void __init timer_group_init(struct device_node *np) kfree(priv); } -static void mpic_timer_resume(void) +static void mpic_timer_resume(void *data) { struct timer_group_priv *priv; @@ -535,10 +535,14 @@ static const struct of_device_id mpic_timer_ids[] = { {}, }; -static struct syscore_ops mpic_timer_syscore_ops = { +static const struct syscore_ops mpic_timer_syscore_ops = { .resume = mpic_timer_resume, }; +static struct syscore mpic_timer_syscore = { + .ops = &mpic_timer_syscore_ops, +}; + static int __init mpic_timer_init(void) { struct device_node *np = NULL; @@ -546,7 +550,7 @@ static int __init mpic_timer_init(void) for_each_matching_node(np, mpic_timer_ids) timer_group_init(np); - register_syscore_ops(&mpic_timer_syscore_ops); + register_syscore(&mpic_timer_syscore); if (list_empty(&timer_group_list)) return -ENODEV; diff --git a/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh b/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh index 06706903503b6..baed467a016b3 100755 --- a/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh +++ b/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-2.0 set -e -set -o pipefail # To debug, uncomment the following line # set -x diff --git a/arch/powerpc/tools/gcc-check-mprofile-kernel.sh b/arch/powerpc/tools/gcc-check-mprofile-kernel.sh index 73e331e7660ef..6193b0ed0c775 100755 --- a/arch/powerpc/tools/gcc-check-mprofile-kernel.sh +++ b/arch/powerpc/tools/gcc-check-mprofile-kernel.sh @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-2.0 set -e -set -o pipefail # To debug, uncomment the following line # set -x diff --git a/arch/powerpc/tools/head_check.sh b/arch/powerpc/tools/head_check.sh index 689907cda9960..a9cd06958921b 100644 --- a/arch/powerpc/tools/head_check.sh +++ b/arch/powerpc/tools/head_check.sh @@ -1,3 +1,4 @@ +#!/bin/sh # Copyright © 2016 IBM Corporation # This program is free software; you can redistribute it and/or diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index fadec20b87a8e..6b39f37f769a2 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -142,11 +142,13 @@ config RISCV select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET select HAVE_ARCH_SECCOMP_FILTER + select HAVE_ARCH_SOFT_DIRTY if 64BIT && MMU && RISCV_ISA_SVRSW60T59B select HAVE_ARCH_THREAD_STRUCT_WHITELIST select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT && MMU select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if 64BIT && MMU select HAVE_ARCH_USERFAULTFD_MINOR if 64BIT && USERFAULTFD + select HAVE_ARCH_USERFAULTFD_WP if 64BIT && MMU && USERFAULTFD && RISCV_ISA_SVRSW60T59B select HAVE_ARCH_VMAP_STACK if MMU && 64BIT select HAVE_ASM_MODVERSIONS select HAVE_CONTEXT_TRACKING_USER @@ -198,7 +200,7 @@ config RISCV select HAVE_SAMPLE_FTRACE_DIRECT_MULTI select HAVE_STACKPROTECTOR select HAVE_SYSCALL_TRACEPOINTS - select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU + select HOTPLUG_PARALLEL if HOTPLUG_CPU select IRQ_DOMAIN select IRQ_FORCED_THREADING select KASAN_VMALLOC if KASAN @@ -849,6 +851,20 @@ config RISCV_ISA_ZICBOP If you don't know what to do here, say Y. +config RISCV_ISA_SVRSW60T59B + bool "Svrsw60t59b extension support for using PTE bits 60 and 59" + depends on MMU && 64BIT + depends on RISCV_ALTERNATIVE + default y + help + Adds support to dynamically detect the presence of the Svrsw60t59b + extension and enable its usage. + + The Svrsw60t59b extension allows to free the PTE reserved bits 60 + and 59 for software to use. + + If you don't know what to do here, say Y. + config TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI def_bool y # https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aed44286efa8ae8717a77d94b51ac3614e2ca6dc diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs index 848e7149e4435..d621b85dd63bd 100644 --- a/arch/riscv/Kconfig.socs +++ b/arch/riscv/Kconfig.socs @@ -7,6 +7,11 @@ config ARCH_ANDES help This enables support for Andes SoC platform hardware. +config ARCH_ANLOGIC + bool "Anlogic SoCs" + help + This enables support for Anlogic SoC platform hardware. + config ARCH_ESWIN bool "ESWIN SoCs" help @@ -63,6 +68,14 @@ config ARCH_SUNXI This enables support for Allwinner sun20i platform hardware, including boards based on the D1 and D1s SoCs. +config ARCH_TENSTORRENT + bool "Tenstorrent SoCs" + help + This enables support for Tenstorrent SoC platforms. + Current support is for Blackhole P100 and P150 PCIe cards. + The Blackhole SoC contains four RISC-V CPU tiles each + consisting of 4x SiFive X280 cores. + config ARCH_THEAD bool "T-HEAD RISC-V SoCs" depends on MMU && !XIP_KERNEL diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile index 3763d199c70ac..69d8751fb17c8 100644 --- a/arch/riscv/boot/dts/Makefile +++ b/arch/riscv/boot/dts/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 subdir-y += allwinner subdir-y += andes +subdir-y += anlogic subdir-y += canaan subdir-y += eswin subdir-y += microchip @@ -9,4 +10,5 @@ subdir-y += sifive subdir-y += sophgo subdir-y += spacemit subdir-y += starfive +subdir-y += tenstorrent subdir-y += thead diff --git a/arch/riscv/boot/dts/anlogic/Makefile b/arch/riscv/boot/dts/anlogic/Makefile new file mode 100644 index 0000000000000..87f3b2f418cfa --- /dev/null +++ b/arch/riscv/boot/dts/anlogic/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_ARCH_ANLOGIC) += dr1v90-mlkpai-fs01.dtb diff --git a/arch/riscv/boot/dts/anlogic/dr1v90-mlkpai-fs01.dts b/arch/riscv/boot/dts/anlogic/dr1v90-mlkpai-fs01.dts new file mode 100644 index 0000000000000..597407655efd2 --- /dev/null +++ b/arch/riscv/boot/dts/anlogic/dr1v90-mlkpai-fs01.dts @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2025 Junhui Liu + */ + +#include "dr1v90.dtsi" + +/ { + model = "Milianke MLKPAI-FS01"; + compatible = "milianke,mlkpai-fs01", "anlogic,dr1v90"; + + aliases { + serial0 = &uart1; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x20000000>; + }; +}; + +&uart1 { + status = "okay"; +}; diff --git a/arch/riscv/boot/dts/anlogic/dr1v90.dtsi b/arch/riscv/boot/dts/anlogic/dr1v90.dtsi new file mode 100644 index 0000000000000..a5d0765ade323 --- /dev/null +++ b/arch/riscv/boot/dts/anlogic/dr1v90.dtsi @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2025 Junhui Liu + */ + +/dts-v1/; +/ { + #address-cells = <2>; + #size-cells = <2>; + model = "Anlogic DR1V90"; + compatible = "anlogic,dr1v90"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <800000000>; + + cpu@0 { + compatible = "nuclei,ux900", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <256>; + d-cache-size = <32768>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <256>; + i-cache-size = <32768>; + mmu-type = "riscv,sv39"; + reg = <0>; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zba", "zbb", "zbc", + "zbkc", "zbs", "zicntr", "zicsr", "zifencei", + "zihintpause", "zihpm"; + + cpu0_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + }; + + soc { + compatible = "simple-bus"; + interrupt-parent = <&plic>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + aclint_mswi: interrupt-controller@68031000 { + compatible = "anlogic,dr1v90-aclint-mswi", "nuclei,ux900-aclint-mswi"; + reg = <0x0 0x68031000 0x0 0x4000>; + interrupts-extended = <&cpu0_intc 3>; + }; + + aclint_mtimer: timer@68035000 { + compatible = "anlogic,dr1v90-aclint-mtimer", "nuclei,ux900-aclint-mtimer"; + reg = <0x0 0x68035000 0x0 0x8000>; + reg-names = "mtimecmp"; + interrupts-extended = <&cpu0_intc 7>; + }; + + aclint_sswi: interrupt-controller@6803d000 { + compatible = "anlogic,dr1v90-aclint-sswi", "nuclei,ux900-aclint-sswi"; + reg = <0x0 0x6803d000 0x0 0x3000>; + #interrupt-cells = <0>; + interrupt-controller; + interrupts-extended = <&cpu0_intc 1>; + }; + + plic: interrupt-controller@6c000000 { + compatible = "anlogic,dr1v90-plic", "sifive,plic-1.0.0"; + reg = <0x0 0x6c000000 0x0 0x4000000>; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>; + riscv,ndev = <150>; + }; + + uart0: serial@f8400000 { + compatible = "anlogic,dr1v90-uart", "snps,dw-apb-uart"; + reg = <0x0 0xf8400000 0x0 0x1000>; + clock-frequency = <50000000>; + interrupts = <71>; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + + uart1: serial@f8401000 { + compatible = "anlogic,dr1v90-uart", "snps,dw-apb-uart"; + reg = <0x0 0xf8401000 0x0 0x1000>; + clock-frequency = <50000000>; + interrupts = <72>; + reg-io-width = <4>; + reg-shift = <2>; + status = "disabled"; + }; + }; +}; diff --git a/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts b/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts index 55e30f3636df2..f44ad8e6f4e49 100644 --- a/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts +++ b/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts @@ -79,6 +79,26 @@ }; +&gpio0 { + interrupts = <13>, <14>, <15>, <16>, + <17>, <18>, <19>, <20>, + <21>, <22>, <23>, <24>, + <25>, <26>; + ngpios = <14>; + status = "okay"; +}; + +&gpio1 { + interrupts = <27>, <28>, <29>, <30>, + <31>, <32>, <33>, <34>, + <35>, <36>, <37>, <38>, + <39>, <40>, <41>, <42>, + <43>, <44>, <45>, <46>, + <47>, <48>, <49>, <50>; + ngpios = <24>; + status = "okay"; +}; + &gpio2 { interrupts = <53>, <53>, <53>, <53>, <53>, <53>, <53>, <53>, @@ -199,6 +219,82 @@ status = "okay"; }; +&qspi { + status = "okay"; + cs-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>, <&gpio0 12 GPIO_ACTIVE_LOW>; + num-cs = <2>; + + adc@0 { + compatible = "microchip,mcp3464r"; + reg = <0>; /* CE0 */ + spi-cpol; + spi-cpha; + spi-max-frequency = <5000000>; + microchip,hw-device-address = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + channel@0 { + /* CH0 to AGND */ + reg = <0>; + label = "CH0"; + }; + + channel@1 { + /* CH1 to AGND */ + reg = <1>; + label = "CH1"; + }; + + channel@2 { + /* CH2 to AGND */ + reg = <2>; + label = "CH2"; + }; + + channel@3 { + /* CH3 to AGND */ + reg = <3>; + label = "CH3"; + }; + + channel@4 { + /* CH4 to AGND */ + reg = <4>; + label = "CH4"; + }; + + channel@5 { + /* CH5 to AGND */ + reg = <5>; + label = "CH5"; + }; + + channel@6 { + /* CH6 to AGND */ + reg = <6>; + label = "CH6"; + }; + + channel@7 { + /* CH7 is connected to AGND */ + reg = <7>; + label = "CH7"; + }; + }; + + mmc@1 { + compatible = "mmc-spi-slot"; + reg = <1>; + gpios = <&gpio2 31 1>; + voltage-ranges = <3300 3300>; + spi-max-frequency = <5000000>; + disable-wp; + }; +}; + + &syscontroller { microchip,bitstream-flash = <&sys_ctrl_flash>; status = "okay"; diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts index 03ce2cee4e976..850fa1d25be75 100644 --- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts +++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts @@ -47,6 +47,16 @@ gpios = <&gpio 2 GPIO_ACTIVE_LOW>; }; + fan1 { + compatible = "pwm-fan"; + pwms = <&pwm1 2 7812500 0>; + }; + + fan2 { + compatible = "pwm-fan"; + pwms = <&pwm1 3 7812500 0>; + }; + led-controller-1 { compatible = "pwm-leds"; diff --git a/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts b/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts index 9feb520eaec41..0e6d79e6e3a4a 100644 --- a/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts +++ b/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts @@ -100,3 +100,8 @@ pinctrl-names = "default"; status = "okay"; }; + +&usb { + dr_mode = "host"; + status = "okay"; +}; diff --git a/arch/riscv/boot/dts/sophgo/cv180x.dtsi b/arch/riscv/boot/dts/sophgo/cv180x.dtsi index ccdb454986535..1b2b1969a6484 100644 --- a/arch/riscv/boot/dts/sophgo/cv180x.dtsi +++ b/arch/riscv/boot/dts/sophgo/cv180x.dtsi @@ -25,6 +25,32 @@ #size-cells = <1>; ranges; + syscon: syscon@3000000 { + compatible = "sophgo,cv1800b-top-syscon", + "syscon", "simple-mfd"; + reg = <0x03000000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + usbphy: phy@48 { + compatible = "sophgo,cv1800b-usb2-phy"; + reg = <0x48 0x4>; + #phy-cells = <0>; + clocks = <&clk CLK_USB_125M>, + <&clk CLK_USB_33K>, + <&clk CLK_USB_12M>; + clock-names = "app", "stb", "lpm"; + resets = <&rst RST_COMBO_PHY0>; + }; + + dmamux: dma-router@154 { + compatible = "sophgo,cv1800b-dmamux"; + reg = <0x154 0x8>, <0x298 0x4>; + #dma-cells = <2>; + dma-masters = <&dmac>; + }; + }; + rst: reset-controller@3003000 { compatible = "sophgo,cv1800b-reset"; reg = <0x3003000 0x1000>; @@ -406,6 +432,22 @@ status = "disabled"; }; + usb: usb@4340000 { + compatible = "sophgo,cv1800b-usb"; + reg = <0x04340000 0x10000>; + clocks = <&clk CLK_AXI4_USB>, <&clk CLK_APB_USB>; + clock-names = "otg", "utmi"; + g-np-tx-fifo-size = <32>; + g-rx-fifo-size = <536>; + g-tx-fifo-size = <768 512 512 384 128 128>; + interrupts = ; + phys = <&usbphy>; + phy-names = "usb2-phy"; + resets = <&rst RST_USB>; + reset-names = "dwc2"; + status = "disabled"; + }; + rtc@5025000 { compatible = "sophgo,cv1800b-rtc", "syscon"; reg = <0x5025000 0x2000>; diff --git a/arch/riscv/boot/dts/sophgo/cv1812h-huashan-pi.dts b/arch/riscv/boot/dts/sophgo/cv1812h-huashan-pi.dts index 4a5835fa9e96f..aedf79f474071 100644 --- a/arch/riscv/boot/dts/sophgo/cv1812h-huashan-pi.dts +++ b/arch/riscv/boot/dts/sophgo/cv1812h-huashan-pi.dts @@ -86,3 +86,8 @@ &uart0 { status = "okay"; }; + +&usb { + dr_mode = "host"; + status = "okay"; +}; diff --git a/arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts b/arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts index 86a712b953a5a..b1853770d0178 100644 --- a/arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts +++ b/arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts @@ -93,3 +93,8 @@ pinctrl-names = "default"; status = "okay"; }; + +&usb { + dr_mode = "host"; + status = "okay"; +}; diff --git a/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts b/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts index 3320bc1dd2c66..b116dfa904cd9 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts +++ b/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts @@ -164,6 +164,18 @@ }; }; +&pcie_rc0 { + status = "okay"; +}; + +&pcie_rc1 { + status = "okay"; +}; + +&pcie_rc2 { + status = "okay"; +}; + &pinctrl { emmc_cfg: sdhci-emmc-cfg { sdhci-emmc-wp-pins { @@ -238,6 +250,30 @@ status = "okay"; }; +&spifmc0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <1>; + }; +}; + +&spifmc1 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <1>; + }; +}; + &uart0 { pinctrl-0 = <&uart0_cfg>; pinctrl-names = "default"; diff --git a/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts b/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts index 46980e41b886c..b2ceae2d8829e 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts +++ b/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts @@ -152,6 +152,18 @@ }; }; +&pcie_rc0 { + status = "okay"; +}; + +&pcie_rc1 { + status = "okay"; +}; + +&pcie_rc2 { + status = "okay"; +}; + &pinctrl { emmc_cfg: sdhci-emmc-cfg { sdhci-emmc-wp-pins { @@ -226,6 +238,18 @@ status = "okay"; }; +&spifmc1 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <1>; + }; +}; + &uart0 { pinctrl-0 = <&uart0_cfg>; pinctrl-names = "default"; diff --git a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts index ef3a602172b1e..54d8386bf9c0f 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts +++ b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts @@ -128,6 +128,18 @@ }; }; +&pcie_rc0 { + status = "okay"; +}; + +&pcie_rc2 { + status = "okay"; +}; + +&pcie_rc3 { + status = "okay"; +}; + &sd { pinctrl-0 = <&sd_cfg>; pinctrl-names = "default"; @@ -138,6 +150,30 @@ status = "okay"; }; +&spifmc0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <1>; + }; +}; + +&spifmc1 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <1>; + }; +}; + &uart0 { pinctrl-0 = <&uart0_cfg>; pinctrl-names = "default"; diff --git a/arch/riscv/boot/dts/sophgo/sg2042.dtsi b/arch/riscv/boot/dts/sophgo/sg2042.dtsi index c5e49709b3088..ec99da39150f7 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042.dtsi +++ b/arch/riscv/boot/dts/sophgo/sg2042.dtsi @@ -68,6 +68,30 @@ interrupt-parent = <&intc>; ranges; + spifmc0: spi@7000180000 { + compatible = "sophgo,sg2042-spifmc-nor"; + reg = <0x70 0x00180000 0x0 0x1000000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkgen GATE_CLK_AHB_SF>; + interrupt-parent = <&intc>; + interrupts = <108 IRQ_TYPE_LEVEL_HIGH>; + resets = <&rstgen RST_SF0>; + status = "disabled"; + }; + + spifmc1: spi@7002180000 { + compatible = "sophgo,sg2042-spifmc-nor"; + reg = <0x70 0x02180000 0x0 0x1000000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkgen GATE_CLK_AHB_SF>; + interrupt-parent = <&intc>; + interrupts = <109 IRQ_TYPE_LEVEL_HIGH>; + resets = <&rstgen RST_SF1>; + status = "disabled"; + }; + i2c0: i2c@7030005000 { compatible = "snps,designware-i2c"; reg = <0x70 0x30005000 0x0 0x1000>; @@ -240,6 +264,94 @@ #clock-cells = <1>; }; + pcie_rc0: pcie@7060000000 { + compatible = "sophgo,sg2042-pcie-host"; + device_type = "pci"; + reg = <0x70 0x60000000 0x0 0x00800000>, + <0x40 0x00000000 0x0 0x00001000>; + reg-names = "reg", "cfg"; + linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x40 0xc0000000 0x0 0x00400000>, + <0x42000000 0x0 0xd0000000 0x40 0xd0000000 0x0 0x10000000>, + <0x02000000 0x0 0xe0000000 0x40 0xe0000000 0x0 0x20000000>, + <0x43000000 0x42 0x00000000 0x42 0x00000000 0x2 0x00000000>, + <0x03000000 0x41 0x00000000 0x41 0x00000000 0x1 0x00000000>; + bus-range = <0x0 0xff>; + vendor-id = <0x1f1c>; + device-id = <0x2042>; + cdns,no-bar-match-nbits = <48>; + msi-parent = <&msi>; + status = "disabled"; + }; + + pcie_rc1: pcie@7060800000 { + compatible = "sophgo,sg2042-pcie-host"; + device_type = "pci"; + reg = <0x70 0x60800000 0x0 0x00800000>, + <0x44 0x00000000 0x0 0x00001000>; + reg-names = "reg", "cfg"; + linux,pci-domain = <1>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x44 0xc0400000 0x0 0x00400000>, + <0x42000000 0x0 0xd0000000 0x44 0xd0000000 0x0 0x10000000>, + <0x02000000 0x0 0xe0000000 0x44 0xe0000000 0x0 0x20000000>, + <0x43000000 0x46 0x00000000 0x46 0x00000000 0x2 0x00000000>, + <0x03000000 0x45 0x00000000 0x45 0x00000000 0x1 0x00000000>; + bus-range = <0x0 0xff>; + vendor-id = <0x1f1c>; + device-id = <0x2042>; + cdns,no-bar-match-nbits = <48>; + msi-parent = <&msi>; + status = "disabled"; + }; + + pcie_rc2: pcie@7062000000 { + compatible = "sophgo,sg2042-pcie-host"; + device_type = "pci"; + reg = <0x70 0x62000000 0x0 0x00800000>, + <0x48 0x00000000 0x0 0x00001000>; + reg-names = "reg", "cfg"; + linux,pci-domain = <2>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x48 0xc0800000 0x0 0x00400000>, + <0x42000000 0x0 0xd0000000 0x48 0xd0000000 0x0 0x10000000>, + <0x02000000 0x0 0xe0000000 0x48 0xe0000000 0x0 0x20000000>, + <0x03000000 0x49 0x00000000 0x49 0x00000000 0x1 0x00000000>, + <0x43000000 0x4a 0x00000000 0x4a 0x00000000 0x2 0x00000000>; + bus-range = <0x0 0xff>; + vendor-id = <0x1f1c>; + device-id = <0x2042>; + cdns,no-bar-match-nbits = <48>; + msi-parent = <&msi>; + status = "disabled"; + }; + + pcie_rc3: pcie@7062800000 { + compatible = "sophgo,sg2042-pcie-host"; + device_type = "pci"; + reg = <0x70 0x62800000 0x0 0x00800000>, + <0x4c 0x00000000 0x0 0x00001000>; + reg-names = "reg", "cfg"; + linux,pci-domain = <3>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x4c 0xc0c00000 0x0 0x00400000>, + <0x42000000 0x0 0xf8000000 0x4c 0xf8000000 0x0 0x04000000>, + <0x02000000 0x0 0xfc000000 0x4c 0xfc000000 0x0 0x04000000>, + <0x43000000 0x4e 0x00000000 0x4e 0x00000000 0x2 0x00000000>, + <0x03000000 0x4d 0x00000000 0x4d 0x00000000 0x1 0x00000000>; + bus-range = <0x0 0xff>; + vendor-id = <0x1f1c>; + device-id = <0x2042>; + cdns,no-bar-match-nbits = <48>; + msi-parent = <&msi>; + status = "disabled"; + }; + clint_mswi: interrupt-controller@7094000000 { compatible = "sophgo,sg2042-aclint-mswi", "thead,c900-aclint-mswi"; reg = <0x00000070 0x94000000 0x00000000 0x00004000>; diff --git a/arch/riscv/boot/dts/spacemit/Makefile b/arch/riscv/boot/dts/spacemit/Makefile index 1528326448706..95889e7269d1b 100644 --- a/arch/riscv/boot/dts/spacemit/Makefile +++ b/arch/riscv/boot/dts/spacemit/Makefile @@ -1,4 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_SPACEMIT) += k1-bananapi-f3.dtb dtb-$(CONFIG_ARCH_SPACEMIT) += k1-milkv-jupiter.dtb +dtb-$(CONFIG_ARCH_SPACEMIT) += k1-musepi-pro.dtb +dtb-$(CONFIG_ARCH_SPACEMIT) += k1-orangepi-r2s.dtb dtb-$(CONFIG_ARCH_SPACEMIT) += k1-orangepi-rv2.dtb diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts index 2aaaff77831e1..02f218a16318e 100644 --- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts @@ -14,6 +14,8 @@ ethernet0 = ð0; ethernet1 = ð1; serial0 = &uart0; + i2c2 = &i2c2; + i2c8 = &i2c8; }; chosen { @@ -30,6 +32,25 @@ default-state = "on"; }; }; + + reg_dc_in: dc-in-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_in_12v"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_vcc_4v: vcc-4v { + compatible = "regulator-fixed"; + regulator-name = "vcc_4v"; + regulator-min-microvolt = <4000000>; + regulator-max-microvolt = <4000000>; + regulator-boot-on; + regulator-always-on; + vin-supply = <®_dc_in>; + }; }; &emmc { @@ -92,6 +113,157 @@ status = "okay"; }; +&qspi { + pinctrl-names = "default"; + pinctrl-0 = <&qspi_cfg>; + status = "okay"; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_0_cfg>; + pinctrl-names = "default"; + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + vcc-supply = <&buck3_1v8>; /* EEPROM_VCC1V8 */ + pagesize = <16>; + read-only; + size = <256>; + + nvmem-layout { + compatible = "onie,tlv-layout"; + + mac-address { + #nvmem-cell-cells = <1>; + }; + + num-macs { + }; + + serial-number { + }; + }; + }; +}; + +&i2c8 { + pinctrl-0 = <&i2c8_cfg>; + pinctrl-names = "default"; + status = "okay"; + + pmic@41 { + compatible = "spacemit,p1"; + reg = <0x41>; + interrupts = <64>; + vin-supply = <®_vcc_4v>; + + regulators { + buck1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + buck2 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + buck3_1v8: buck3 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1800000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + buck4 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + buck5 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + buck6 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + aldo1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + }; + + aldo2 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + aldo3 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + aldo4 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + }; + + dldo2 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo3 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo4 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-always-on; + }; + + dldo5 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo6 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-always-on; + }; + + dldo7 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + }; + }; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_2_cfg>; diff --git a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts new file mode 100644 index 0000000000000..29e333b670cf0 --- /dev/null +++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2024 Yangyu Chen + * Copyright (C) 2025 SpacemiT, Inc + * Copyright (C) 2025 Troy Mitchell + */ + +/dts-v1/; + +#include "k1.dtsi" +#include "k1-pinctrl.dtsi" + +/ { + model = "SpacemiT MusePi Pro"; + compatible = "spacemit,musepi-pro", "spacemit,k1"; + + aliases { + ethernet0 = ð0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0"; + }; + + leds { + compatible = "gpio-leds"; + + led1 { + label = "sys-led"; + gpios = <&gpio K1_GPIO(96) GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + default-state = "on"; + }; + }; +}; + +&emmc { + bus-width = <8>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + non-removable; + no-sd; + no-sdio; + status = "okay"; +}; + +ð0 { + phy-handle = <&rgmii0>; + phy-mode = "rgmii-id"; + pinctrl-0 = <&gmac0_cfg>; + pinctrl-names = "default"; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; + status = "okay"; + + mdio-bus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + reset-gpios = <&gpio K1_GPIO(110) GPIO_ACTIVE_LOW>; + reset-delay-us = <10000>; + reset-post-delay-us = <100000>; + + rgmii0: phy@1 { + reg = <0x1>; + }; + }; +}; + +&pdma { + status = "okay"; +}; + +&uart0 { + pinctrl-0 = <&uart0_2_cfg>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts new file mode 100644 index 0000000000000..58098c4a2aabd --- /dev/null +++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2025 Michael Opdenacker + */ + +/dts-v1/; + +#include "k1.dtsi" +#include "k1-pinctrl.dtsi" + +/ { + model = "OrangePi R2S"; + compatible = "xunlong,orangepi-r2s", "spacemit,k1"; + + aliases { + serial0 = &uart0; + ethernet0 = ð0; + ethernet1 = ð1; + }; + + chosen { + stdout-path = "serial0"; + }; +}; + +&emmc { + bus-width = <8>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + non-removable; + no-sd; + no-sdio; + status = "okay"; +}; + +ð0 { + phy-handle = <&rgmii0>; + phy-mode = "rgmii-id"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_cfg>; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; + status = "okay"; + + mdio-bus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + reset-gpios = <&gpio K1_GPIO(110) GPIO_ACTIVE_LOW>; + reset-delay-us = <10000>; + reset-post-delay-us = <100000>; + + rgmii0: phy@1 { + reg = <0x1>; + }; + }; +}; + +ð1 { + phy-handle = <&rgmii1>; + phy-mode = "rgmii-id"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1_cfg>; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <250>; + status = "okay"; + + mdio-bus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + reset-gpios = <&gpio K1_GPIO(115) GPIO_ACTIVE_LOW>; + reset-delay-us = <10000>; + reset-post-delay-us = <100000>; + + rgmii1: phy@1 { + reg = <0x1>; + }; + }; +}; + +&pdma { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_2_cfg>; + status = "okay"; +}; diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts index 337240ebb7b79..41dc8e35e6ebe 100644 --- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts @@ -15,6 +15,8 @@ aliases { serial0 = &uart0; + ethernet0 = ð0; + ethernet1 = ð1; }; chosen { @@ -33,6 +35,56 @@ }; }; +ð0 { + phy-handle = <&rgmii0>; + phy-mode = "rgmii-id"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_cfg>; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; + status = "okay"; + + mdio-bus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + reset-gpios = <&gpio K1_GPIO(110) GPIO_ACTIVE_LOW>; + reset-delay-us = <10000>; + reset-post-delay-us = <100000>; + + rgmii0: phy@1 { + reg = <0x1>; + }; + }; +}; + +ð1 { + phy-handle = <&rgmii1>; + phy-mode = "rgmii-id"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1_cfg>; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <250>; + status = "okay"; + + mdio-bus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + reset-gpios = <&gpio K1_GPIO(115) GPIO_ACTIVE_LOW>; + reset-delay-us = <10000>; + reset-post-delay-us = <100000>; + + rgmii1: phy@1 { + reg = <0x1>; + }; + }; +}; + +&pdma { + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_2_cfg>; diff --git a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi index aff19c86d5ff3..e922e05ff856d 100644 --- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi +++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi @@ -59,11 +59,472 @@ }; }; + i2c2_0_cfg: i2c2-0-cfg { + i2c2-0-pins { + pinmux = , /* I2C2_SCL */ + ; /* I2C2_SDA */ + }; + }; + + i2c8_cfg: i2c8-cfg { + i2c8-0-pins { + pinmux = , /* PWR_SCL */ + ; /* PWR_SDA */ + }; + }; + + qspi_cfg: qspi-cfg { + qspi-pins { + pinmux = , /* QSPI_DATA3 */ + , /* QSPI_DATA2 */ + , /* QSPI_DATA1 */ + , /* QSPI_DATA0 */ + ; /* QSPI_CLK */ + + bias-disable; + drive-strength = <19>; + power-source = <3300>; + }; + + qspi-cs1-pins { + pinmux = ; /* QSPI_CS1 */ + bias-pull-up = <0>; + drive-strength = <19>; + power-source = <3300>; + }; + }; + + /omit-if-no-ref/ + uart0_0_cfg: uart0-0-cfg { + uart0-0-pins { + pinmux = , /* uart0_txd */ + ; /* uart0_rxd */ + power-source = <3300>; + bias-pull-up = <0>; + drive-strength = <19>; + }; + }; + + /omit-if-no-ref/ + uart0_1_cfg: uart0-1-cfg { + uart0-1-pins { + pinmux = , /* uart0_txd */ + ; /* uart0_rxd */ + power-source = <3300>; + bias-pull-up = <0>; + drive-strength = <19>; + }; + }; + + /omit-if-no-ref/ uart0_2_cfg: uart0-2-cfg { uart0-2-pins { - pinmux = , - ; + pinmux = , /* uart0_txd */ + ; /* uart0_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart2_0_cfg: uart2-0-cfg { + uart2-0-pins { + pinmux = , /* uart2_txd */ + ; /* uart2_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart2_0_cts_rts_cfg: uart2-0-cts-rts-cfg { + uart2-0-pins { + pinmux = , /* uart2_cts */ + ; /* uart2_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart3_0_cfg: uart3-0-cfg { + uart3-0-pins { + pinmux = , /* uart3_txd */ + ; /* uart3_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart3_0_cts_rts_cfg: uart3-0-cts-rts-cfg { + uart3-0-pins { + pinmux = , /* uart3_cts */ + ; /* uart3_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart3_1_cfg: uart3-1-cfg { + uart3-1-pins { + pinmux = , /* uart3_txd */ + ; /* uart3_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart3_1_cts_rts_cfg: uart3-1-cts-rts-cfg { + uart3-1-pins { + pinmux = , /* uart3_cts */ + ; /* uart3_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart3_2_cfg: uart3-2-cfg { + uart3-2-pins { + pinmux = , /* uart3_txd */ + ; /* uart3_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart3_2_cts_rts_cfg: uart3-2-cts-rts-cfg { + uart3-2-pins { + pinmux = , /* uart3_cts */ + ; /* uart3_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart4_0_cfg: uart4-0-cfg { + uart4-0-pins { + pinmux = , /* uart4_txd */ + ; /* uart4_rxd */ + power-source = <3300>; + bias-pull-up = <0>; + drive-strength = <19>; + }; + }; + + /omit-if-no-ref/ + uart4_1_cfg: uart4-1-cfg { + uart4-1-pins { + pinmux = , /* uart4_txd */ + ; /* uart4_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart4_1_cts_rts_cfg: uart4-1-cts-rts-cfg { + uart4-1-pins { + pinmux = , /* uart4_cts */ + ; /* uart4_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart4_2_cfg: uart4-2-cfg { + uart4-2-pins { + pinmux = , /* uart4_txd */ + ; /* uart4_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart4_3_cfg: uart4-3-cfg { + uart4-3-pins { + pinmux = , /* uart4_txd */ + ; /* uart4_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart4_3_cts_rts_cfg: uart4-3-cts-rts-cfg { + uart4-3-pins { + pinmux = , /* uart4_cts */ + ; /* uart4_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart4_4_cfg: uart4-4-cfg { + uart4-4-pins { + pinmux = , /* uart4_txd */ + ; /* uart4_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart4_4_cts_rts_cfg: uart4-4-cts-rts-cfg { + uart4-4-pins { + pinmux = , /* uart4_cts */ + ; /* uart4_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart5_0_cfg: uart5-0-cfg { + uart5-0-pins { + pinmux = , /* uart5_txd */ + ; /* uart5_rxd */ + power-source = <3300>; + bias-pull-up = <0>; + drive-strength = <19>; + }; + }; + + /omit-if-no-ref/ + uart5_1_cfg: uart5-1-cfg { + uart5-1-pins { + pinmux = , /* uart5_txd */ + ; /* uart5_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart5_1_cts_rts_cfg: uart5-1-cts-rts-cfg { + uart5-1-pins { + pinmux = , /* uart5_cts */ + ; /* uart5_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart5_2_cfg: uart5-2-cfg { + uart5-2-pins { + pinmux = , /* uart5_txd */ + ; /* uart5_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart5_2_cts_rts_cfg: uart5-2-cts-rts-cfg { + uart5-2-pins { + pinmux = , /* uart5_cts */ + ; /* uart5_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart5_3_cfg: uart5-3-cfg { + uart5-3-pins { + pinmux = , /* uart5_txd */ + ; /* uart5_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart5_3_cts_rts_cfg: uart5-3-cts-rts-cfg { + uart5-3-pins { + pinmux = , /* uart5_cts */ + ; /* uart5_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart6_0_cfg: uart6-0-cfg { + uart6-0-pins { + pinmux = , /* uart6_txd */ + ; /* uart6_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart6_0_cts_rts_cfg: uart6-0-cts-rts-cfg { + uart6-0-pins { + pinmux = , /* uart6_cts */ + ; /* uart6_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart6_1_cfg: uart6-1-cfg { + uart6-1-pins { + pinmux = , /* uart6_txd */ + ; /* uart6_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart6_1_cts_rts_cfg: uart6-1-cts-rts-cfg { + uart6-1-pins { + pinmux = , /* uart6_cts */ + ; /* uart6_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart6_2_cfg: uart6-2-cfg { + uart6-2-pins { + pinmux = , /* uart6_txd */ + ; /* uart6_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart7_0_cfg: uart7-0-cfg { + uart7-0-pins { + pinmux = , /* uart7_txd */ + ; /* uart7_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart7_1_cfg: uart7-1-cfg { + uart7-1-pins { + pinmux = , /* uart7_txd */ + ; /* uart7_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart7_1_cts_rts_cfg: uart7-1-cts-rts-cfg { + uart7-1-pins { + pinmux = , /* uart7_cts */ + ; /* uart7_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart8_0_cfg: uart8-0-cfg { + uart8-0-pins { + pinmux = , /* uart8_txd */ + ; /* uart8_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart8_1_cfg: uart8-1-cfg { + uart8-1-pins { + pinmux = , /* uart8_txd */ + ; /* uart8_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart8_1_cts_rts_cfg: uart8-1-cts-rts-cfg { + uart8-1-pins { + pinmux = , /* uart8_cts */ + ; /* uart8_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart8_2_cfg: uart8-2-cfg { + uart8-2-pins { + pinmux = , /* uart8_txd */ + ; /* uart8_rxd */ + power-source = <3300>; + bias-pull-up = <0>; + drive-strength = <19>; + }; + }; + + /omit-if-no-ref/ + uart8_2_cts_rts_cfg: uart8-2-cts-rts-cfg { + uart8-2-pins { + pinmux = , /* uart8_cts */ + ; /* uart8_rts */ + power-source = <3300>; + bias-pull-up = <0>; + drive-strength = <19>; + }; + }; + + /omit-if-no-ref/ + uart9_0_cfg: uart9-0-cfg { + uart9-0-pins { + pinmux = , /* uart9_txd */ + ; /* uart9_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart9_1_cfg: uart9-1-cfg { + uart9-1-pins { + pinmux = , /* uart9_txd */ + ; /* uart9_rxd */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + + /omit-if-no-ref/ + uart9_1_cts_rts_cfg: uart9-1-cts-rts-cfg { + uart9-1-pins { + pinmux = , /* uart9_cts */ + ; /* uart9_rts */ + bias-pull-up = <0>; + drive-strength = <32>; + }; + }; + /omit-if-no-ref/ + uart9_2_cfg: uart9-2-cfg { + uart9-2-pins { + pinmux = , /* uart9_txd */ + ; /* uart9_rxd */ bias-pull-up = <0>; drive-strength = <32>; }; diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi index 6cdcd80a7c83b..7818ca4979b6a 100644 --- a/arch/riscv/boot/dts/spacemit/k1.dtsi +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi @@ -358,6 +358,71 @@ #reset-cells = <1>; }; + i2c0: i2c@d4010800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4010800 0x0 0x38>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&syscon_apbc CLK_TWSI0>, + <&syscon_apbc CLK_TWSI0_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; + interrupts = <36>; + status = "disabled"; + }; + + i2c1: i2c@d4011000 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4011000 0x0 0x38>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&syscon_apbc CLK_TWSI1>, + <&syscon_apbc CLK_TWSI1_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; + interrupts = <37>; + status = "disabled"; + }; + + i2c2: i2c@d4012000 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4012000 0x0 0x38>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&syscon_apbc CLK_TWSI2>, + <&syscon_apbc CLK_TWSI2_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; + interrupts = <38>; + status = "disabled"; + }; + + i2c4: i2c@d4012800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4012800 0x0 0x38>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&syscon_apbc CLK_TWSI4>, + <&syscon_apbc CLK_TWSI4_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; + interrupts = <40>; + status = "disabled"; + }; + + i2c5: i2c@d4013800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4013800 0x0 0x38>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&syscon_apbc CLK_TWSI5>, + <&syscon_apbc CLK_TWSI5_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; + interrupts = <41>; + status = "disabled"; + }; + syscon_apbc: system-controller@d4015000 { compatible = "spacemit,k1-syscon-apbc"; reg = <0x0 0xd4015000 0x0 0x1000>; @@ -369,6 +434,19 @@ #reset-cells = <1>; }; + i2c6: i2c@d4018800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4018800 0x0 0x38>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&syscon_apbc CLK_TWSI6>, + <&syscon_apbc CLK_TWSI6_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; + interrupts = <70>; + status = "disabled"; + }; + gpio: gpio@d4019000 { compatible = "spacemit,k1-gpio"; reg = <0x0 0xd4019000 0x0 0x100>; @@ -459,6 +537,32 @@ status = "disabled"; }; + i2c7: i2c@d401d000 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd401d000 0x0 0x38>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&syscon_apbc CLK_TWSI7>, + <&syscon_apbc CLK_TWSI7_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; + interrupts = <18>; + status = "disabled"; + }; + + i2c8: i2c@d401d800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd401d800 0x0 0x38>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&syscon_apbc CLK_TWSI8>, + <&syscon_apbc CLK_TWSI8_BUS>; + clock-names = "func", "bus"; + clock-frequency = <400000>; + interrupts = <19>; + status = "disabled"; + }; + pinctrl: pinctrl@d401e000 { compatible = "spacemit,k1-pinctrl"; reg = <0x0 0xd401e000 0x0 0x400>; @@ -643,6 +747,8 @@ #reset-cells = <1>; }; + /* sec_i2c3: 0xf0614000, not available from Linux */ + camera-bus { compatible = "simple-bus"; ranges; @@ -797,6 +903,22 @@ status = "disabled"; }; + qspi: spi@d420c000 { + compatible = "spacemit,k1-qspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0xd420c000 0x0 0x1000>, + <0x0 0xb8000000 0x0 0xc00000>; + reg-names = "QuadSPI", "QuadSPI-memory"; + clocks = <&syscon_apmu CLK_QSPI_BUS>, + <&syscon_apmu CLK_QSPI>; + clock-names = "qspi_en", "qspi"; + resets = <&syscon_apmu RESET_QSPI>, + <&syscon_apmu RESET_QSPI_BUS>; + interrupts = <117>; + status = "disabled"; + }; + /* sec_uart1: 0xf0612000, not available from Linux */ }; diff --git a/arch/riscv/boot/dts/starfive/Makefile b/arch/riscv/boot/dts/starfive/Makefile index 62b659f89ba71..3dd1f05283f74 100644 --- a/arch/riscv/boot/dts/starfive/Makefile +++ b/arch/riscv/boot/dts/starfive/Makefile @@ -12,6 +12,9 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-deepcomputing-fml13v01.dtb dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-milkv-mars.dtb dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-milkv-marscm-emmc.dtb dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-milkv-marscm-lite.dtb +dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-orangepi-rv.dtb dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-pine64-star64.dtb +dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-lite.dtb +dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-lite-emmc.dtb dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb diff --git a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi index 5dc15e48b74b1..8cfe8033305d8 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi @@ -281,14 +281,8 @@ assigned-clock-rates = <50000000>; bus-width = <8>; bootph-pre-ram; - cap-mmc-highspeed; - mmc-ddr-1_8v; - mmc-hs200-1_8v; - cap-mmc-hw-reset; pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; - vmmc-supply = <&vcc_3v3>; - vqmmc-supply = <&emmc_vdd>; status = "okay"; }; @@ -298,8 +292,6 @@ assigned-clock-rates = <50000000>; bus-width = <4>; bootph-pre-ram; - cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>; - disable-wp; cap-sd-highspeed; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; @@ -444,17 +436,6 @@ }; mmc0_pins: mmc0-0 { - rst-pins { - pinmux = ; - bias-pull-up; - drive-strength = <12>; - input-disable; - input-schmitt-disable; - slew-rate = <0>; - }; - mmc-pins { pinmux = , , diff --git a/arch/riscv/boot/dts/starfive/jh7110-deepcomputing-fml13v01.dts b/arch/riscv/boot/dts/starfive/jh7110-deepcomputing-fml13v01.dts index f2857d021d681..d8db9ed4474dc 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-deepcomputing-fml13v01.dts +++ b/arch/riscv/boot/dts/starfive/jh7110-deepcomputing-fml13v01.dts @@ -11,6 +11,33 @@ compatible = "deepcomputing,fml13v01", "starfive,jh7110"; }; +&mmc0 { + cap-mmc-highspeed; + cap-mmc-hw-reset; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&emmc_vdd>; +}; + +&mmc0_pins { + rst-pins { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; +}; + +&mmc1 { + cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>; + disable-wp; +}; + &pcie1 { perst-gpios = <&sysgpio 21 GPIO_ACTIVE_LOW>; phys = <&pciephy1>; diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts index fdaf6b4557da9..21873612d9931 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts +++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts @@ -22,6 +22,33 @@ status = "okay"; }; +&mmc0 { + cap-mmc-highspeed; + cap-mmc-hw-reset; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&emmc_vdd>; +}; + +&mmc0_pins { + rst-pins { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; +}; + +&mmc1 { + cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>; + disable-wp; +}; + &pcie0 { status = "okay"; }; diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-emmc.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-emmc.dts index e568537af2c47..ce95496263afc 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-emmc.dts +++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-emmc.dts @@ -10,3 +10,12 @@ model = "Milk-V Mars CM"; compatible = "milkv,marscm-emmc", "starfive,jh7110"; }; + +&mmc0 { + cap-mmc-highspeed; + cap-mmc-hw-reset; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&emmc_vdd>; +}; diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-lite.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-lite.dts index 6c40d0ec40115..63aa94d65ab55 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-lite.dts +++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-lite.dts @@ -14,6 +14,7 @@ &mmc0 { bus-width = <4>; cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>; + disable-wp; }; &mmc0_pins { diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi index 25b70af564eea..025471061d439 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi @@ -40,6 +40,19 @@ status = "disabled"; }; +&mmc0_pins { + rst-pins { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; +}; + &mmc1 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/riscv/boot/dts/starfive/jh7110-orangepi-rv.dts b/arch/riscv/boot/dts/starfive/jh7110-orangepi-rv.dts new file mode 100644 index 0000000000000..053c35992ec39 --- /dev/null +++ b/arch/riscv/boot/dts/starfive/jh7110-orangepi-rv.dts @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2025 Icenowy Zheng + */ + +/dts-v1/; +#include "jh7110-common.dtsi" + +/ { + model = "Xunlong Orange Pi RV"; + compatible = "xunlong,orangepi-rv", "starfive,jh7110"; + + /* This regulator is always on by hardware */ + reg_vcc3v3_pcie: regulator-vcc3v3-pcie { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3-pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&sysgpio 62 GPIO_ACTIVE_LOW>; + }; +}; + +&gmac0 { + assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>; + assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>; + starfive,tx-use-rgmii-clk; + status = "okay"; +}; + +&mmc0 { + #address-cells = <1>; + #size-cells = <0>; + cap-sd-highspeed; + mmc-pwrseq = <&wifi_pwrseq>; + vmmc-supply = <®_vcc3v3_pcie>; + vqmmc-supply = <&vcc_3v3>; + status = "okay"; + + ap6256: wifi@1 { + compatible = "brcm,bcm43456-fmac", "brcm,bcm4329-fmac"; + reg = <1>; + /* TODO: out-of-band IRQ on GPIO21, lacking pinctrl support */ + }; +}; + +&mmc1 { + cd-gpios = <&sysgpio 41 GPIO_ACTIVE_HIGH>; +}; + +&pcie0 { + status = "okay"; +}; + +&pcie1 { + status = "okay"; +}; + +&phy0 { + rx-internal-delay-ps = <1500>; + tx-internal-delay-ps = <1500>; + motorcomm,rx-clk-drv-microamp = <3970>; + motorcomm,rx-data-drv-microamp = <2910>; + motorcomm,tx-clk-adj-enabled; + motorcomm,tx-clk-10-inverted; + motorcomm,tx-clk-100-inverted; + motorcomm,tx-clk-1000-inverted; +}; + +&pwmdac { + status = "okay"; +}; diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts index 31e825be2065a..aec7ae3d1f5b4 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts +++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts @@ -44,6 +44,33 @@ status = "okay"; }; +&mmc0 { + cap-mmc-highspeed; + cap-mmc-hw-reset; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&emmc_vdd>; +}; + +&mmc0_pins { + rst-pins { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; +}; + +&mmc1 { + cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>; + disable-wp; +}; + &pcie1 { status = "okay"; }; diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite-emmc.dts b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite-emmc.dts new file mode 100644 index 0000000000000..e27a662d40222 --- /dev/null +++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite-emmc.dts @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2025 StarFive Technology Co., Ltd. + * Copyright (C) 2025 Hal Feng + */ + +/dts-v1/; +#include "jh7110-starfive-visionfive-2-lite.dtsi" + +/ { + model = "StarFive VisionFive 2 Lite eMMC"; + compatible = "starfive,visionfive-2-lite-emmc", "starfive,jh7110s"; +}; + +&mmc0 { + cap-mmc-highspeed; + cap-mmc-hw-reset; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&emmc_vdd>; +}; diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dts b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dts new file mode 100644 index 0000000000000..b96eea4fa7d51 --- /dev/null +++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2025 StarFive Technology Co., Ltd. + * Copyright (C) 2025 Hal Feng + */ + +/dts-v1/; +#include "jh7110-starfive-visionfive-2-lite.dtsi" + +/ { + model = "StarFive VisionFive 2 Lite"; + compatible = "starfive,visionfive-2-lite", "starfive,jh7110s"; +}; + +&mmc0 { + bus-width = <4>; + cd-gpios = <&sysgpio 41 GPIO_ACTIVE_HIGH>; + disable-wp; + cap-sd-highspeed; +}; diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi new file mode 100644 index 0000000000000..f8797a666dbf5 --- /dev/null +++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2025 StarFive Technology Co., Ltd. + * Copyright (C) 2025 Hal Feng + */ + +/dts-v1/; +#include "jh7110-common.dtsi" + +/ { + vcc_3v3_pcie: regulator-vcc-3v3-pcie { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&sysgpio 27 GPIO_ACTIVE_HIGH>; + regulator-name = "vcc_3v3_pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; + +&cpu_opp { + /delete-node/ opp-375000000; + /delete-node/ opp-500000000; + /delete-node/ opp-750000000; + /delete-node/ opp-1500000000; + + opp-312500000 { + opp-hz = /bits/ 64 <312500000>; + opp-microvolt = <800000>; + }; + opp-417000000 { + opp-hz = /bits/ 64 <417000000>; + opp-microvolt = <800000>; + }; + opp-625000000 { + opp-hz = /bits/ 64 <625000000>; + opp-microvolt = <800000>; + }; + opp-1250000000 { + opp-hz = /bits/ 64 <1250000000>; + opp-microvolt = <1000000>; + }; +}; + +&gmac0 { + starfive,tx-use-rgmii-clk; + assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>; + assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&mmc1 { + max-frequency = <50000000>; + keep-power-in-suspend; + non-removable; +}; + +&pcie1 { + vpcie3v3-supply = <&vcc_3v3_pcie>; + status = "okay"; +}; + +&phy0 { + motorcomm,tx-clk-adj-enabled; + motorcomm,tx-clk-100-inverted; + motorcomm,tx-clk-1000-inverted; + motorcomm,rx-clk-drv-microamp = <3970>; + motorcomm,rx-data-drv-microamp = <2910>; + rx-internal-delay-ps = <1500>; + tx-internal-delay-ps = <1500>; +}; + +&pwm { + status = "okay"; +}; + +&spi0 { + status = "okay"; +}; + +&syscrg { + assigned-clock-rates = <0>, <0>, <0>, <0>, <500000000>, <1250000000>; +}; + +&sysgpio { + uart1_pins: uart1-0 { + tx-pins { + pinmux = ; + bias-disable; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + + rx-pins { + pinmux = ; + bias-pull-up; + drive-strength = <2>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + cts-pins { + pinmux = ; + input-enable; + }; + + rts-pins { + pinmux = ; + input-enable; + }; + }; + + usb0_pins: usb0-0 { + power-pins { + pinmux = ; + input-disable; + }; + + switch-pins { + pinmux = ; + input-disable; + }; + }; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; +}; + +&usb0 { + dr_mode = "host"; + pinctrl-names = "default"; + pinctrl-0 = <&usb0_pins>; + status = "okay"; +}; + +&usb_cdns3 { + phys = <&usbphy0>, <&pciephy0>; + phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy"; +}; diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi index 5f14afb2c24dc..edc8f45881336 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi @@ -38,9 +38,33 @@ }; &mmc0 { + cap-mmc-highspeed; + cap-mmc-hw-reset; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&emmc_vdd>; non-removable; }; +&mmc0_pins { + rst-pins { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; +}; + +&mmc1 { + cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>; + disable-wp; +}; + &pcie0 { status = "okay"; }; diff --git a/arch/riscv/boot/dts/tenstorrent/Makefile b/arch/riscv/boot/dts/tenstorrent/Makefile new file mode 100644 index 0000000000000..2c81faaba4623 --- /dev/null +++ b/arch/riscv/boot/dts/tenstorrent/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_ARCH_TENSTORRENT) += blackhole-card.dtb diff --git a/arch/riscv/boot/dts/tenstorrent/blackhole-card.dts b/arch/riscv/boot/dts/tenstorrent/blackhole-card.dts new file mode 100644 index 0000000000000..f53667ce73a94 --- /dev/null +++ b/arch/riscv/boot/dts/tenstorrent/blackhole-card.dts @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/dts-v1/; + +#include "blackhole.dtsi" + +/ { + model = "Tenstorrent Blackhole"; + compatible = "tenstorrent,blackhole-card", "tenstorrent,blackhole"; + + memory@400030000000 { + device_type = "memory"; + reg = <0x4000 0x30000000 0x1 0x00000000>; + }; +}; diff --git a/arch/riscv/boot/dts/tenstorrent/blackhole.dtsi b/arch/riscv/boot/dts/tenstorrent/blackhole.dtsi new file mode 100644 index 0000000000000..6408810d8d80d --- /dev/null +++ b/arch/riscv/boot/dts/tenstorrent/blackhole.dtsi @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +// Copyright 2025 Tenstorrent AI ULC +/dts-v1/; + +/ { + compatible = "tenstorrent,blackhole"; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <50000000>; + + cpu@0 { + compatible = "sifive,x280", "sifive,rocket0", "riscv"; + device_type = "cpu"; + reg = <0>; + mmu-type = "riscv,sv57"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicsr", + "zifencei", "zfh", "zba", "zbb", "sscofpmf"; + + cpu0_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + + cpu@1 { + compatible = "sifive,x280", "sifive,rocket0", "riscv"; + device_type = "cpu"; + reg = <1>; + mmu-type = "riscv,sv57"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicsr", + "zifencei", "zfh", "zba", "zbb", "sscofpmf"; + + cpu1_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + + cpu@2 { + compatible = "sifive,x280", "sifive,rocket0", "riscv"; + device_type = "cpu"; + reg = <2>; + mmu-type = "riscv,sv57"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicsr", + "zifencei", "zfh", "zba", "zbb", "sscofpmf"; + + cpu2_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + + cpu@3 { + compatible = "sifive,x280", "sifive,rocket0", "riscv"; + device_type = "cpu"; + reg = <3>; + mmu-type = "riscv,sv57"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicsr", + "zifencei", "zfh", "zba", "zbb", "sscofpmf"; + + cpu3_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + ranges; + + clint0: timer@2000000 { + compatible = "tenstorrent,blackhole-clint", "sifive,clint0"; + reg = <0x0 0x2000000 0x0 0x10000>; + interrupts-extended = <&cpu0_intc 0x3>, <&cpu0_intc 0x7>, + <&cpu1_intc 0x3>, <&cpu1_intc 0x7>, + <&cpu2_intc 0x3>, <&cpu2_intc 0x7>, + <&cpu3_intc 0x3>, <&cpu3_intc 0x7>; + }; + + plic0: interrupt-controller@c000000 { + compatible = "tenstorrent,blackhole-plic", "sifive,plic-1.0.0"; + reg = <0x0 0x0c000000 0x0 0x04000000>; + interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>, + <&cpu1_intc 11>, <&cpu1_intc 9>, + <&cpu2_intc 11>, <&cpu2_intc 9>, + <&cpu3_intc 11>, <&cpu3_intc 9>; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <0>; + riscv,ndev = <128>; + }; + }; +}; diff --git a/arch/riscv/boot/dts/thead/th1520-lichee-pi-4a.dts b/arch/riscv/boot/dts/thead/th1520-lichee-pi-4a.dts index 4020c727f09e8..c58c2085ca92a 100644 --- a/arch/riscv/boot/dts/thead/th1520-lichee-pi-4a.dts +++ b/arch/riscv/boot/dts/thead/th1520-lichee-pi-4a.dts @@ -28,9 +28,76 @@ chosen { stdout-path = "serial0:115200n8"; }; + + thermal-zones { + cpu-thermal { + polling-delay = <1000>; + polling-delay-passive = <1000>; + thermal-sensors = <&pvt 0>; + + trips { + fan_config0: fan-trip0 { + temperature = <39000>; + hysteresis = <5000>; + type = "active"; + }; + + fan_config1: fan-trip1 { + temperature = <50000>; + hysteresis = <5000>; + type = "active"; + }; + + fan_config2: fan-trip2 { + temperature = <60000>; + hysteresis = <5000>; + type = "active"; + }; + }; + + cooling-maps { + map-active-0 { + cooling-device = <&fan 1 1>; + trip = <&fan_config0>; + }; + + map-active-1 { + cooling-device = <&fan 2 2>; + trip = <&fan_config1>; + }; + + map-active-2 { + cooling-device = <&fan 3 3>; + trip = <&fan_config2>; + }; + }; + }; + }; + + fan: pwm-fan { + pinctrl-names = "default"; + pinctrl-0 = <&fan_pins>; + compatible = "pwm-fan"; + #cooling-cells = <2>; + pwms = <&pwm 1 10000000 0>; + cooling-levels = <0 66 196 255>; + }; + }; &padctrl0_apsys { + fan_pins: fan-0 { + pwm1-pins { + pins = "GPIO3_3"; /* PWM1 */ + function = "pwm"; + bias-disable; + drive-strength = <25>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + uart0_pins: uart0-0 { tx-pins { pins = "UART0_TXD"; diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi index e680d1a7c821f..bd5d33840884e 100644 --- a/arch/riscv/boot/dts/thead/th1520.dtsi +++ b/arch/riscv/boot/dts/thead/th1520.dtsi @@ -24,8 +24,11 @@ device_type = "cpu"; riscv,isa = "rv64imafdc"; riscv,isa-base = "rv64i"; - riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr", - "zifencei", "zihpm"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", + "ziccrse", "zicntr", "zicsr", + "zifencei", "zihpm", "zfh", + "xtheadvector"; + thead,vlenb = <16>; reg = <0>; i-cache-block-size = <64>; i-cache-size = <65536>; @@ -48,8 +51,11 @@ device_type = "cpu"; riscv,isa = "rv64imafdc"; riscv,isa-base = "rv64i"; - riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr", - "zifencei", "zihpm"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", + "ziccrse", "zicntr", "zicsr", + "zifencei", "zihpm", "zfh", + "xtheadvector"; + thead,vlenb = <16>; reg = <1>; i-cache-block-size = <64>; i-cache-size = <65536>; @@ -72,8 +78,11 @@ device_type = "cpu"; riscv,isa = "rv64imafdc"; riscv,isa-base = "rv64i"; - riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr", - "zifencei", "zihpm"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", + "ziccrse", "zicntr", "zicsr", + "zifencei", "zihpm", "zfh", + "xtheadvector"; + thead,vlenb = <16>; reg = <2>; i-cache-block-size = <64>; i-cache-size = <65536>; @@ -96,8 +105,11 @@ device_type = "cpu"; riscv,isa = "rv64imafdc"; riscv,isa-base = "rv64i"; - riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr", - "zifencei", "zihpm"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", + "ziccrse", "zicntr", "zicsr", + "zifencei", "zihpm", "zfh", + "xtheadvector"; + thead,vlenb = <16>; reg = <3>; i-cache-block-size = <64>; i-cache-size = <65536>; @@ -277,6 +289,12 @@ <&cpu3_intc 3>, <&cpu3_intc 7>; }; + rst_vi: reset-controller@ffe4040100 { + compatible = "thead,th1520-reset-vi"; + reg = <0xff 0xe4040100 0x0 0x8>; + #reset-cells = <1>; + }; + spi0: spi@ffe700c000 { compatible = "thead,th1520-spi", "snps,dw-apb-ssi"; reg = <0xff 0xe700c000 0x0 0x1000>; @@ -502,6 +520,25 @@ status = "disabled"; }; + pwm: pwm@ffec01c000 { + compatible = "thead,th1520-pwm"; + reg = <0xff 0xec01c000 0x0 0x4000>; + clocks = <&clk CLK_PWM>; + #pwm-cells = <3>; + }; + + rst_misc: reset-controller@ffec02c000 { + compatible = "thead,th1520-reset-misc"; + reg = <0xff 0xec02c000 0x0 0x18>; + #reset-cells = <1>; + }; + + rst_vp: reset-controller@ffecc30000 { + compatible = "thead,th1520-reset-vp"; + reg = <0xff 0xecc30000 0x0 0x14>; + #reset-cells = <1>; + }; + clk: clock-controller@ffef010000 { compatible = "thead,th1520-clk-ap"; reg = <0xff 0xef010000 0x0 0x1000>; @@ -509,6 +546,18 @@ #clock-cells = <1>; }; + rst_ap: reset-controller@ffef014000 { + compatible = "thead,th1520-reset-ap"; + reg = <0xff 0xef014000 0x0 0x1000>; + #reset-cells = <1>; + }; + + rst_dsp: reset-controller@ffef040028 { + compatible = "thead,th1520-reset-dsp"; + reg = <0xff 0xef040028 0x0 0x4>; + #reset-cells = <1>; + }; + gpu: gpu@ffef400000 { compatible = "thead,th1520-gpu", "img,img-bxm-4-64", "img,img-rogue"; @@ -681,6 +730,13 @@ }; }; + rst_ao: reset-controller@fffff44000 { + compatible = "thead,th1520-reset-ao"; + reg = <0xff 0xfff44000 0x0 0x2000>; + #reset-cells = <1>; + status = "reserved"; + }; + padctrl_aosys: pinctrl@fffff4a000 { compatible = "thead,th1520-pinctrl"; reg = <0xff 0xfff4a000 0x0 0x2000>; diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig index fc2725cbca187..cd736a1d657ec 100644 --- a/arch/riscv/configs/defconfig +++ b/arch/riscv/configs/defconfig @@ -23,12 +23,14 @@ CONFIG_CHECKPOINT_RESTORE=y CONFIG_BLK_DEV_INITRD=y CONFIG_PROFILING=y CONFIG_ARCH_ANDES=y +CONFIG_ARCH_ANLOGIC=y CONFIG_ARCH_MICROCHIP=y CONFIG_ARCH_SIFIVE=y CONFIG_ARCH_SOPHGO=y CONFIG_ARCH_SPACEMIT=y CONFIG_SOC_STARFIVE=y CONFIG_ARCH_SUNXI=y +CONFIG_ARCH_TENSTORRENT=y CONFIG_ARCH_THEAD=y CONFIG_ARCH_VIRT=y CONFIG_ARCH_CANAAN=y @@ -158,6 +160,7 @@ CONFIG_I2C_DESIGNWARE_CORE=y CONFIG_I2C_MV64XXX=m CONFIG_SPI=y CONFIG_SPI_CADENCE_QUADSPI=m +CONFIG_SPI_FSL_QUADSPI=m CONFIG_SPI_PL022=m CONFIG_SPI_SIFIVE=y CONFIG_SPI_SUN6I=y diff --git a/arch/riscv/configs/nommu_virt_defconfig b/arch/riscv/configs/nommu_virt_defconfig index d4b03dc3c2c04..0da5069bfbef2 100644 --- a/arch/riscv/configs/nommu_virt_defconfig +++ b/arch/riscv/configs/nommu_virt_defconfig @@ -48,7 +48,6 @@ CONFIG_VIRTIO_BLK=y # CONFIG_LEGACY_PTYS is not set # CONFIG_LDISC_AUTOLOAD is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=1 CONFIG_SERIAL_8250_RUNTIME_UARTS=1 diff --git a/arch/riscv/crypto/Kconfig b/arch/riscv/crypto/Kconfig index a75d6325607b4..14c5acb935e94 100644 --- a/arch/riscv/crypto/Kconfig +++ b/arch/riscv/crypto/Kconfig @@ -4,7 +4,8 @@ menu "Accelerated Cryptographic Algorithms for CPU (riscv)" config CRYPTO_AES_RISCV64 tristate "Ciphers: AES, modes: ECB, CBC, CTS, CTR, XTS" - depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO + depends on 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \ + RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS select CRYPTO_ALGAPI select CRYPTO_LIB_AES select CRYPTO_SKCIPHER @@ -20,7 +21,8 @@ config CRYPTO_AES_RISCV64 config CRYPTO_GHASH_RISCV64 tristate "Hash functions: GHASH" - depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO + depends on 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \ + RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS select CRYPTO_GCM help GCM GHASH function (NIST SP 800-38D) @@ -30,7 +32,8 @@ config CRYPTO_GHASH_RISCV64 config CRYPTO_SM3_RISCV64 tristate "Hash functions: SM3 (ShangMi 3)" - depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO + depends on 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \ + RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS select CRYPTO_HASH select CRYPTO_LIB_SM3 help @@ -42,7 +45,8 @@ config CRYPTO_SM3_RISCV64 config CRYPTO_SM4_RISCV64 tristate "Ciphers: SM4 (ShangMi 4)" - depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO + depends on 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \ + RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS select CRYPTO_ALGAPI select CRYPTO_SM4 help diff --git a/arch/riscv/include/asm/arch_hweight.h b/arch/riscv/include/asm/arch_hweight.h index 0e7cdbbec8efd..f3c0831beefc6 100644 --- a/arch/riscv/include/asm/arch_hweight.h +++ b/arch/riscv/include/asm/arch_hweight.h @@ -19,10 +19,10 @@ static __always_inline unsigned int __arch_hweight32(unsigned int w) { -#if defined(CONFIG_RISCV_ISA_ZBB) && defined(CONFIG_TOOLCHAIN_HAS_ZBB) - asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, - RISCV_ISA_EXT_ZBB, 1) - : : : : legacy); + if (!(IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && + IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) && + riscv_has_extension_likely(RISCV_ISA_EXT_ZBB))) + return __sw_hweight32(w); asm (".option push\n" ".option arch,+zbb\n" @@ -31,10 +31,6 @@ static __always_inline unsigned int __arch_hweight32(unsigned int w) : "=r" (w) : "r" (w) :); return w; - -legacy: -#endif - return __sw_hweight32(w); } static inline unsigned int __arch_hweight16(unsigned int w) @@ -50,10 +46,10 @@ static inline unsigned int __arch_hweight8(unsigned int w) #if BITS_PER_LONG == 64 static __always_inline unsigned long __arch_hweight64(__u64 w) { -#if defined(CONFIG_RISCV_ISA_ZBB) && defined(CONFIG_TOOLCHAIN_HAS_ZBB) - asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, - RISCV_ISA_EXT_ZBB, 1) - : : : : legacy); + if (!(IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && + IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) && + riscv_has_extension_likely(RISCV_ISA_EXT_ZBB))) + return __sw_hweight64(w); asm (".option push\n" ".option arch,+zbb\n" @@ -62,10 +58,6 @@ static __always_inline unsigned long __arch_hweight64(__u64 w) : "=r" (w) : "r" (w) :); return w; - -legacy: -#endif - return __sw_hweight64(w); } #else /* BITS_PER_LONG == 64 */ static inline unsigned long __arch_hweight64(__u64 w) diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h index 5b96c2f61adb5..3f33dc54f94b2 100644 --- a/arch/riscv/include/asm/atomic.h +++ b/arch/riscv/include/asm/atomic.h @@ -203,7 +203,7 @@ ATOMIC_OPS(xor, xor, i) " add %[rc], %[p], %[a]\n" \ " sc." sfx ".rl %[rc], %[rc], %[c]\n" \ " bnez %[rc], 0b\n" \ - " fence rw, rw\n" \ + RISCV_FULL_BARRIER \ "1:\n" \ : [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \ : [a]"r" (_a), [u]"r" (_u) \ @@ -242,7 +242,7 @@ static __always_inline s64 arch_atomic64_fetch_add_unless(atomic64_t *v, s64 a, " addi %[rc], %[p], 1\n" \ " sc." sfx ".rl %[rc], %[rc], %[c]\n" \ " bnez %[rc], 0b\n" \ - " fence rw, rw\n" \ + RISCV_FULL_BARRIER \ "1:\n" \ : [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \ : \ @@ -268,7 +268,7 @@ static __always_inline bool arch_atomic_inc_unless_negative(atomic_t *v) " addi %[rc], %[p], -1\n" \ " sc." sfx ".rl %[rc], %[rc], %[c]\n" \ " bnez %[rc], 0b\n" \ - " fence rw, rw\n" \ + RISCV_FULL_BARRIER \ "1:\n" \ : [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \ : \ @@ -294,7 +294,7 @@ static __always_inline bool arch_atomic_dec_unless_positive(atomic_t *v) " bltz %[rc], 1f\n" \ " sc." sfx ".rl %[rc], %[rc], %[c]\n" \ " bnez %[rc], 0b\n" \ - " fence rw, rw\n" \ + RISCV_FULL_BARRIER \ "1:\n" \ : [p]"=&r" (_prev), [rc]"=&r" (_rc), [c]"+A" (counter) \ : \ diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h index 77880677b06e0..238092125c118 100644 --- a/arch/riscv/include/asm/bitops.h +++ b/arch/riscv/include/asm/bitops.h @@ -47,9 +47,8 @@ static __always_inline __attribute_const__ unsigned long variable__ffs(unsigned long word) { - asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, - RISCV_ISA_EXT_ZBB, 1) - : : : : legacy); + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) + return generic___ffs(word); asm volatile (".option push\n" ".option arch,+zbb\n" @@ -58,9 +57,6 @@ static __always_inline __attribute_const__ unsigned long variable__ffs(unsigned : "=r" (word) : "r" (word) :); return word; - -legacy: - return generic___ffs(word); } /** @@ -76,9 +72,8 @@ static __always_inline __attribute_const__ unsigned long variable__ffs(unsigned static __always_inline __attribute_const__ unsigned long variable__fls(unsigned long word) { - asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, - RISCV_ISA_EXT_ZBB, 1) - : : : : legacy); + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) + return generic___fls(word); asm volatile (".option push\n" ".option arch,+zbb\n" @@ -87,9 +82,6 @@ static __always_inline __attribute_const__ unsigned long variable__fls(unsigned : "=r" (word) : "r" (word) :); return BITS_PER_LONG - 1 - word; - -legacy: - return generic___fls(word); } /** @@ -105,9 +97,8 @@ static __always_inline __attribute_const__ unsigned long variable__fls(unsigned static __always_inline __attribute_const__ int variable_ffs(int x) { - asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, - RISCV_ISA_EXT_ZBB, 1) - : : : : legacy); + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) + return generic_ffs(x); if (!x) return 0; @@ -119,9 +110,6 @@ static __always_inline __attribute_const__ int variable_ffs(int x) : "=r" (x) : "r" (x) :); return x + 1; - -legacy: - return generic_ffs(x); } /** @@ -137,9 +125,8 @@ static __always_inline __attribute_const__ int variable_ffs(int x) static __always_inline int variable_fls(unsigned int x) { - asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0, - RISCV_ISA_EXT_ZBB, 1) - : : : : legacy); + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) + return generic_fls(x); if (!x) return 0; @@ -151,9 +138,6 @@ static __always_inline int variable_fls(unsigned int x) : "=r" (x) : "r" (x) :); return 32 - x; - -legacy: - return generic_fls(x); } /** diff --git a/arch/riscv/include/asm/checksum.h b/arch/riscv/include/asm/checksum.h index da378856f1d59..945cce34be921 100644 --- a/arch/riscv/include/asm/checksum.h +++ b/arch/riscv/include/asm/checksum.h @@ -49,16 +49,11 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) * ZBB only saves three instructions on 32-bit and five on 64-bit so not * worth checking if supported without Alternatives. */ - if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB)) { + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && + IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) && + riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) { unsigned long fold_temp; - asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, - RISCV_ISA_EXT_ZBB, 1) - : - : - : - : no_zbb); - if (IS_ENABLED(CONFIG_32BIT)) { asm(".option push \n\ .option arch,+zbb \n\ @@ -81,7 +76,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) } return (__force __sum16)(csum >> 16); } -no_zbb: + #ifndef CONFIG_32BIT csum += ror64(csum, 32); csum >>= 32; diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h index 122e1485d39a0..8712cf9c69dcb 100644 --- a/arch/riscv/include/asm/cmpxchg.h +++ b/arch/riscv/include/asm/cmpxchg.h @@ -373,9 +373,10 @@ static __always_inline void __cmpwait(volatile void *ptr, u32 *__ptr32b; ulong __s, __val, __mask; - asm goto(ALTERNATIVE("j %l[no_zawrs]", "nop", - 0, RISCV_ISA_EXT_ZAWRS, 1) - : : : : no_zawrs); + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZAWRS)) { + ALT_RISCV_PAUSE(); + return; + } switch (size) { case 1: @@ -437,11 +438,6 @@ static __always_inline void __cmpwait(volatile void *ptr, default: BUILD_BUG(); } - - return; - -no_zawrs: - ALT_RISCV_PAUSE(); } #define __cmpwait_relaxed(ptr, val) \ diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h index affd63e11b0a3..4369a23385413 100644 --- a/arch/riscv/include/asm/hwcap.h +++ b/arch/riscv/include/asm/hwcap.h @@ -106,6 +106,10 @@ #define RISCV_ISA_EXT_ZAAMO 97 #define RISCV_ISA_EXT_ZALRSC 98 #define RISCV_ISA_EXT_ZICBOP 99 +#define RISCV_ISA_EXT_SVRSW60T59B 100 +#define RISCV_ISA_EXT_ZALASR 101 +#define RISCV_ISA_EXT_ZILSD 102 +#define RISCV_ISA_EXT_ZCLSD 103 #define RISCV_ISA_EXT_XLINUXENVCFG 127 diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h index 58f8dda73259a..8c572a4647190 100644 --- a/arch/riscv/include/asm/hwprobe.h +++ b/arch/riscv/include/asm/hwprobe.h @@ -8,7 +8,7 @@ #include -#define RISCV_HWPROBE_MAX_KEY 14 +#define RISCV_HWPROBE_MAX_KEY 15 static inline bool riscv_hwprobe_key_is_valid(__s64 key) { diff --git a/arch/riscv/include/asm/insn-def.h b/arch/riscv/include/asm/insn-def.h index d29da6ccd3dd8..7c6daf1167567 100644 --- a/arch/riscv/include/asm/insn-def.h +++ b/arch/riscv/include/asm/insn-def.h @@ -179,6 +179,7 @@ #define RV___RS1(v) __RV_REG(v) #define RV___RS2(v) __RV_REG(v) +#define RV_OPCODE_AMO RV_OPCODE(47) #define RV_OPCODE_MISC_MEM RV_OPCODE(15) #define RV_OPCODE_OP_IMM RV_OPCODE(19) #define RV_OPCODE_SYSTEM RV_OPCODE(115) @@ -208,6 +209,84 @@ __ASM_STR(.error "hlv.d requires 64-bit support") #endif +#define LB_AQ(dest, addr) \ + INSN_R(OPCODE_AMO, FUNC3(0), FUNC7(26), \ + RD(dest), RS1(addr), __RS2(0)) + +#define LB_AQRL(dest, addr) \ + INSN_R(OPCODE_AMO, FUNC3(0), FUNC7(27), \ + RD(dest), RS1(addr), __RS2(0)) + +#define LH_AQ(dest, addr) \ + INSN_R(OPCODE_AMO, FUNC3(1), FUNC7(26), \ + RD(dest), RS1(addr), __RS2(0)) + +#define LH_AQRL(dest, addr) \ + INSN_R(OPCODE_AMO, FUNC3(1), FUNC7(27), \ + RD(dest), RS1(addr), __RS2(0)) + +#define LW_AQ(dest, addr) \ + INSN_R(OPCODE_AMO, FUNC3(2), FUNC7(26), \ + RD(dest), RS1(addr), __RS2(0)) + +#define LW_AQRL(dest, addr) \ + INSN_R(OPCODE_AMO, FUNC3(2), FUNC7(27), \ + RD(dest), RS1(addr), __RS2(0)) + +#define SB_RL(src, addr) \ + INSN_R(OPCODE_AMO, FUNC3(0), FUNC7(29), \ + __RD(0), RS1(addr), RS2(src)) + +#define SB_AQRL(src, addr) \ + INSN_R(OPCODE_AMO, FUNC3(0), FUNC7(31), \ + __RD(0), RS1(addr), RS2(src)) + +#define SH_RL(src, addr) \ + INSN_R(OPCODE_AMO, FUNC3(1), FUNC7(29), \ + __RD(0), RS1(addr), RS2(src)) + +#define SH_AQRL(src, addr) \ + INSN_R(OPCODE_AMO, FUNC3(1), FUNC7(31), \ + __RD(0), RS1(addr), RS2(src)) + +#define SW_RL(src, addr) \ + INSN_R(OPCODE_AMO, FUNC3(2), FUNC7(29), \ + __RD(0), RS1(addr), RS2(src)) + +#define SW_AQRL(src, addr) \ + INSN_R(OPCODE_AMO, FUNC3(2), FUNC7(31), \ + __RD(0), RS1(addr), RS2(src)) + +#ifdef CONFIG_64BIT +#define LD_AQ(dest, addr) \ + INSN_R(OPCODE_AMO, FUNC3(3), FUNC7(26), \ + RD(dest), RS1(addr), __RS2(0)) + +#define LD_AQRL(dest, addr) \ + INSN_R(OPCODE_AMO, FUNC3(3), FUNC7(27), \ + RD(dest), RS1(addr), __RS2(0)) + +#define SD_RL(src, addr) \ + INSN_R(OPCODE_AMO, FUNC3(3), FUNC7(29), \ + __RD(0), RS1(addr), RS2(src)) + +#define SD_AQRL(src, addr) \ + INSN_R(OPCODE_AMO, FUNC3(3), FUNC7(31), \ + __RD(0), RS1(addr), RS2(src)) +#else +#define LD_AQ(dest, addr) \ + __ASM_STR(.error "ld.aq requires 64-bit support") + +#define LD_AQRL(dest, addr) \ + __ASM_STR(.error "ld.aqrl requires 64-bit support") + +#define SD_RL(dest, addr) \ + __ASM_STR(.error "sd.rl requires 64-bit support") + +#define SD_AQRL(dest, addr) \ + __ASM_STR(.error "sd.aqrl requires 64-bit support") +#endif + #define SINVAL_VMA(vaddr, asid) \ INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(11), \ __RD(0), RS1(vaddr), RS2(asid)) diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h index 4d794573e3dbe..24585304c02b1 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -59,6 +59,9 @@ BIT(IRQ_VS_TIMER) | \ BIT(IRQ_VS_EXT)) +#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ + KVM_DIRTY_LOG_INITIALLY_SET) + struct kvm_vm_stat { struct kvm_vm_stat_generic generic; }; @@ -327,4 +330,7 @@ bool kvm_riscv_vcpu_stopped(struct kvm_vcpu *vcpu); void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu); +/* Flags representing implementation specific details */ +DECLARE_STATIC_KEY_FALSE(kvm_riscv_vsstage_tlb_no_gpa); + #endif /* __RISCV_KVM_HOST_H__ */ diff --git a/arch/riscv/include/asm/kvm_tlb.h b/arch/riscv/include/asm/kvm_tlb.h index 38a2f933ad3ab..a0e7099bcb858 100644 --- a/arch/riscv/include/asm/kvm_tlb.h +++ b/arch/riscv/include/asm/kvm_tlb.h @@ -49,6 +49,7 @@ void kvm_riscv_local_hfence_vvma_gva(unsigned long vmid, unsigned long gva, unsigned long gvsz, unsigned long order); void kvm_riscv_local_hfence_vvma_all(unsigned long vmid); +void kvm_riscv_local_tlb_sanitize(struct kvm_vcpu *vcpu); void kvm_riscv_tlb_flush_process(struct kvm_vcpu *vcpu); diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index 3497489e04db4..c1a7e3b40d9ce 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -69,7 +69,9 @@ struct kvm_vcpu_sbi_extension { unsigned long reg_size, const void *reg_val); }; -void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run); +int kvm_riscv_vcpu_sbi_forward_handler(struct kvm_vcpu *vcpu, + struct kvm_run *run, + struct kvm_vcpu_sbi_return *retdata); void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, struct kvm_run *run, u32 type, u64 flags); @@ -105,6 +107,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_susp; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_sta; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_fwft; +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_mpxy; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor; diff --git a/arch/riscv/include/asm/kvm_vmid.h b/arch/riscv/include/asm/kvm_vmid.h index ab98e1434fb79..db61b0525a8d0 100644 --- a/arch/riscv/include/asm/kvm_vmid.h +++ b/arch/riscv/include/asm/kvm_vmid.h @@ -22,6 +22,5 @@ unsigned long kvm_riscv_gstage_vmid_bits(void); int kvm_riscv_gstage_vmid_init(struct kvm *kvm); bool kvm_riscv_gstage_vmid_ver_changed(struct kvm_vmid *vmid); void kvm_riscv_gstage_vmid_update(struct kvm_vcpu *vcpu); -void kvm_riscv_gstage_vmid_sanitize(struct kvm_vcpu *vcpu); #endif diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h index 179bd4afece46..b422d9691e60d 100644 --- a/arch/riscv/include/asm/pgtable-bits.h +++ b/arch/riscv/include/asm/pgtable-bits.h @@ -19,6 +19,43 @@ #define _PAGE_SOFT (3 << 8) /* Reserved for software */ #define _PAGE_SPECIAL (1 << 8) /* RSW: 0x1 */ + +#ifdef CONFIG_MEM_SOFT_DIRTY + +/* ext_svrsw60t59b: bit 59 for soft-dirty tracking */ +#define _PAGE_SOFT_DIRTY \ + ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \ + (1UL << 59) : 0) +/* + * Bit 3 is always zero for swap entry computation, so we + * can borrow it for swap page soft-dirty tracking. + */ +#define _PAGE_SWP_SOFT_DIRTY \ + ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \ + _PAGE_EXEC : 0) +#else +#define _PAGE_SOFT_DIRTY 0 +#define _PAGE_SWP_SOFT_DIRTY 0 +#endif /* CONFIG_MEM_SOFT_DIRTY */ + +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP + +/* ext_svrsw60t59b: Bit(60) for uffd-wp tracking */ +#define _PAGE_UFFD_WP \ + ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \ + (1UL << 60) : 0) +/* + * Bit 4 is not involved into swap entry computation, so we + * can borrow it for swap page uffd-wp tracking. + */ +#define _PAGE_SWP_UFFD_WP \ + ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \ + _PAGE_USER : 0) +#else +#define _PAGE_UFFD_WP 0 +#define _PAGE_SWP_UFFD_WP 0 +#endif + #define _PAGE_TABLE _PAGE_PRESENT /* diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 5a08eb5fe99fc..6bb1f5bdc5d26 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -417,6 +417,41 @@ static inline pte_t pte_wrprotect(pte_t pte) return __pte(pte_val(pte) & ~(_PAGE_WRITE)); } +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP +#define pgtable_supports_uffd_wp() \ + riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B) + +static inline bool pte_uffd_wp(pte_t pte) +{ + return !!(pte_val(pte) & _PAGE_UFFD_WP); +} + +static inline pte_t pte_mkuffd_wp(pte_t pte) +{ + return pte_wrprotect(__pte(pte_val(pte) | _PAGE_UFFD_WP)); +} + +static inline pte_t pte_clear_uffd_wp(pte_t pte) +{ + return __pte(pte_val(pte) & ~(_PAGE_UFFD_WP)); +} + +static inline bool pte_swp_uffd_wp(pte_t pte) +{ + return !!(pte_val(pte) & _PAGE_SWP_UFFD_WP); +} + +static inline pte_t pte_swp_mkuffd_wp(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_SWP_UFFD_WP); +} + +static inline pte_t pte_swp_clear_uffd_wp(pte_t pte) +{ + return __pte(pte_val(pte) & ~(_PAGE_SWP_UFFD_WP)); +} +#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */ + /* static inline pte_t pte_mkread(pte_t pte) */ static inline pte_t pte_mkwrite_novma(pte_t pte) @@ -428,7 +463,7 @@ static inline pte_t pte_mkwrite_novma(pte_t pte) static inline pte_t pte_mkdirty(pte_t pte) { - return __pte(pte_val(pte) | _PAGE_DIRTY); + return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY); } static inline pte_t pte_mkclean(pte_t pte) @@ -456,6 +491,42 @@ static inline pte_t pte_mkhuge(pte_t pte) return pte; } +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY +#define pgtable_supports_soft_dirty() \ + (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && \ + riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) + +static inline bool pte_soft_dirty(pte_t pte) +{ + return !!(pte_val(pte) & _PAGE_SOFT_DIRTY); +} + +static inline pte_t pte_mksoft_dirty(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY); +} + +static inline pte_t pte_clear_soft_dirty(pte_t pte) +{ + return __pte(pte_val(pte) & ~(_PAGE_SOFT_DIRTY)); +} + +static inline bool pte_swp_soft_dirty(pte_t pte) +{ + return !!(pte_val(pte) & _PAGE_SWP_SOFT_DIRTY); +} + +static inline pte_t pte_swp_mksoft_dirty(pte_t pte) +{ + return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY); +} + +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) +{ + return __pte(pte_val(pte) & ~(_PAGE_SWP_SOFT_DIRTY)); +} +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ + #ifdef CONFIG_RISCV_ISA_SVNAPOT #define pte_leaf_size(pte) (pte_napot(pte) ? \ napot_cont_size(napot_cont_order(pte)) :\ @@ -496,8 +567,13 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma, unsigned long address, pte_t *ptep, unsigned int nr) { - asm goto(ALTERNATIVE("nop", "j %l[svvptc]", 0, RISCV_ISA_EXT_SVVPTC, 1) - : : : : svvptc); + /* + * Svvptc guarantees that the new valid pte will be visible within + * a bounded timeframe, so when the uarch does not cache invalid + * entries, we don't have to do anything. + */ + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SVVPTC)) + return; /* * The kernel assumes that TLBs don't cache invalid entries, but @@ -509,12 +585,6 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf, while (nr--) local_flush_tlb_page(address + nr * PAGE_SIZE); -svvptc:; - /* - * Svvptc guarantees that the new valid pte will be visible within - * a bounded timeframe, so when the uarch does not cache invalid - * entries, we don't have to do anything. - */ } #define update_mmu_cache(vma, addr, ptep) \ update_mmu_cache_range(NULL, vma, addr, ptep, 1) @@ -590,7 +660,13 @@ extern int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long a static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long address, pte_t *ptep) { - pte_t pte = __pte(atomic_long_xchg((atomic_long_t *)ptep, 0)); +#ifdef CONFIG_SMP + pte_t pte = __pte(xchg(&ptep->pte, 0)); +#else + pte_t pte = *ptep; + + set_pte(ptep, __pte(0)); +#endif page_table_check_pte_clear(mm, pte); @@ -805,6 +881,72 @@ static inline pud_t pud_mkspecial(pud_t pud) } #endif +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP +static inline bool pmd_uffd_wp(pmd_t pmd) +{ + return pte_uffd_wp(pmd_pte(pmd)); +} + +static inline pmd_t pmd_mkuffd_wp(pmd_t pmd) +{ + return pte_pmd(pte_mkuffd_wp(pmd_pte(pmd))); +} + +static inline pmd_t pmd_clear_uffd_wp(pmd_t pmd) +{ + return pte_pmd(pte_clear_uffd_wp(pmd_pte(pmd))); +} + +static inline bool pmd_swp_uffd_wp(pmd_t pmd) +{ + return pte_swp_uffd_wp(pmd_pte(pmd)); +} + +static inline pmd_t pmd_swp_mkuffd_wp(pmd_t pmd) +{ + return pte_pmd(pte_swp_mkuffd_wp(pmd_pte(pmd))); +} + +static inline pmd_t pmd_swp_clear_uffd_wp(pmd_t pmd) +{ + return pte_pmd(pte_swp_clear_uffd_wp(pmd_pte(pmd))); +} +#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */ + +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY +static inline bool pmd_soft_dirty(pmd_t pmd) +{ + return pte_soft_dirty(pmd_pte(pmd)); +} + +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd) +{ + return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd))); +} + +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd) +{ + return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd))); +} + +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION +static inline bool pmd_swp_soft_dirty(pmd_t pmd) +{ + return pte_swp_soft_dirty(pmd_pte(pmd)); +} + +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd) +{ + return pte_pmd(pte_swp_mksoft_dirty(pmd_pte(pmd))); +} + +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd) +{ + return pte_pmd(pte_swp_clear_soft_dirty(pmd_pte(pmd))); +} +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */ +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ + static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, pmd_t pmd) { @@ -861,7 +1003,13 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long address, pmd_t *pmdp) { - pmd_t pmd = __pmd(atomic_long_xchg((atomic_long_t *)pmdp, 0)); +#ifdef CONFIG_SMP + pmd_t pmd = __pmd(xchg(&pmdp->pmd, 0)); +#else + pmd_t pmd = *pmdp; + + pmd_clear(pmdp); +#endif page_table_check_pmd_clear(mm, pmd); @@ -1003,7 +1151,9 @@ static inline pud_t pud_modify(pud_t pud, pgprot_t newprot) * * Format of swap PTE: * bit 0: _PAGE_PRESENT (zero) - * bit 1 to 3: _PAGE_LEAF (zero) + * bit 1 to 2: (zero) + * bit 3: _PAGE_SWP_SOFT_DIRTY + * bit 4: _PAGE_SWP_UFFD_WP * bit 5: _PAGE_PROT_NONE (zero) * bit 6: exclusive marker * bits 7 to 11: swap type diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index ccc77a89b1e22..5725e0ca4dda3 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -37,6 +37,7 @@ enum sbi_ext_id { SBI_EXT_NACL = 0x4E41434C, SBI_EXT_FWFT = 0x46574654, SBI_EXT_MPXY = 0x4D505859, + SBI_EXT_DBTR = 0x44425452, /* Experimentals extensions must lie within this range */ SBI_EXT_EXPERIMENTAL_START = 0x08000000, @@ -505,6 +506,34 @@ enum sbi_mpxy_rpmi_attribute_id { #define SBI_MPXY_CHAN_CAP_SEND_WITHOUT_RESP BIT(4) #define SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS BIT(5) +/* SBI debug triggers function IDs */ +enum sbi_ext_dbtr_fid { + SBI_EXT_DBTR_NUM_TRIGGERS = 0, + SBI_EXT_DBTR_SETUP_SHMEM, + SBI_EXT_DBTR_TRIG_READ, + SBI_EXT_DBTR_TRIG_INSTALL, + SBI_EXT_DBTR_TRIG_UPDATE, + SBI_EXT_DBTR_TRIG_UNINSTALL, + SBI_EXT_DBTR_TRIG_ENABLE, + SBI_EXT_DBTR_TRIG_DISABLE, +}; + +struct sbi_dbtr_data_msg { + unsigned long tstate; + unsigned long tdata1; + unsigned long tdata2; + unsigned long tdata3; +}; + +struct sbi_dbtr_id_msg { + unsigned long idx; +}; + +union sbi_dbtr_shmem_entry { + struct sbi_dbtr_data_msg data; + struct sbi_dbtr_id_msg id; +}; + /* SBI spec version fields */ #define SBI_SPEC_VERSION_DEFAULT 0x1 #define SBI_SPEC_VERSION_MAJOR_SHIFT 24 diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h index b61786d43c205..00cb9c0982b1a 100644 --- a/arch/riscv/include/asm/vector.h +++ b/arch/riscv/include/asm/vector.h @@ -51,6 +51,7 @@ void put_cpu_vector_context(void); void riscv_v_thread_free(struct task_struct *tsk); void __init riscv_v_setup_ctx_cache(void); void riscv_v_thread_alloc(struct task_struct *tsk); +void __init update_regset_vector_info(unsigned long size); static inline u32 riscv_v_flags(void) { @@ -423,6 +424,9 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; } #define riscv_v_thread_free(tsk) do {} while (0) #define riscv_v_setup_ctx_cache() do {} while (0) #define riscv_v_thread_alloc(tsk) do {} while (0) +#define get_cpu_vector_context() do {} while (0) +#define put_cpu_vector_context() do {} while (0) +#define riscv_v_vstate_set_restore(task, regs) do {} while (0) #endif /* CONFIG_RISCV_ISA_V */ diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h index 5d30a4fae37a8..cd3c126730c33 100644 --- a/arch/riscv/include/uapi/asm/hwprobe.h +++ b/arch/riscv/include/uapi/asm/hwprobe.h @@ -82,6 +82,11 @@ struct riscv_hwprobe { #define RISCV_HWPROBE_EXT_ZAAMO (1ULL << 56) #define RISCV_HWPROBE_EXT_ZALRSC (1ULL << 57) #define RISCV_HWPROBE_EXT_ZABHA (1ULL << 58) +#define RISCV_HWPROBE_EXT_ZALASR (1ULL << 59) +#define RISCV_HWPROBE_EXT_ZICBOP (1ULL << 60) +#define RISCV_HWPROBE_EXT_ZILSD (1ULL << 61) +#define RISCV_HWPROBE_EXT_ZCLSD (1ULL << 62) + #define RISCV_HWPROBE_KEY_CPUPERF_0 5 #define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0) #define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0) @@ -107,6 +112,7 @@ struct riscv_hwprobe { #define RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE 12 #define RISCV_HWPROBE_KEY_VENDOR_EXT_SIFIVE_0 13 #define RISCV_HWPROBE_KEY_VENDOR_EXT_MIPS_0 14 +#define RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE 15 /* Increase RISCV_HWPROBE_MAX_KEY when adding items. */ /* Flags */ diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h index 759a4852c09a5..54f3ad7ed2e4b 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h @@ -23,6 +23,8 @@ #define KVM_INTERRUPT_SET -1U #define KVM_INTERRUPT_UNSET -2U +#define KVM_EXIT_FAIL_ENTRY_NO_VSFILE (1ULL << 0) + /* for KVM_GET_REGS and KVM_SET_REGS */ struct kvm_regs { }; @@ -211,6 +213,7 @@ enum KVM_RISCV_SBI_EXT_ID { KVM_RISCV_SBI_EXT_STA, KVM_RISCV_SBI_EXT_SUSP, KVM_RISCV_SBI_EXT_FWFT, + KVM_RISCV_SBI_EXT_MPXY, KVM_RISCV_SBI_EXT_MAX, }; diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 72ca768f4e919..c05b11596c190 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -242,6 +242,28 @@ static int riscv_ext_zcf_validate(const struct riscv_isa_ext_data *data, return -EPROBE_DEFER; } +static int riscv_ext_zilsd_validate(const struct riscv_isa_ext_data *data, + const unsigned long *isa_bitmap) +{ + if (IS_ENABLED(CONFIG_64BIT)) + return -EINVAL; + + return 0; +} + +static int riscv_ext_zclsd_validate(const struct riscv_isa_ext_data *data, + const unsigned long *isa_bitmap) +{ + if (IS_ENABLED(CONFIG_64BIT)) + return -EINVAL; + + if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZILSD) && + __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZCA)) + return 0; + + return -EPROBE_DEFER; +} + static int riscv_vector_f_validate(const struct riscv_isa_ext_data *data, const unsigned long *isa_bitmap) { @@ -472,6 +494,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = { __RISCV_ISA_EXT_DATA(zaamo, RISCV_ISA_EXT_ZAAMO), __RISCV_ISA_EXT_DATA(zabha, RISCV_ISA_EXT_ZABHA), __RISCV_ISA_EXT_DATA(zacas, RISCV_ISA_EXT_ZACAS), + __RISCV_ISA_EXT_DATA(zalasr, RISCV_ISA_EXT_ZALASR), __RISCV_ISA_EXT_DATA(zalrsc, RISCV_ISA_EXT_ZALRSC), __RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS), __RISCV_ISA_EXT_DATA_VALIDATE(zfa, RISCV_ISA_EXT_ZFA, riscv_ext_f_depends), @@ -483,6 +506,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = { __RISCV_ISA_EXT_DATA_VALIDATE(zcd, RISCV_ISA_EXT_ZCD, riscv_ext_zcd_validate), __RISCV_ISA_EXT_DATA_VALIDATE(zcf, RISCV_ISA_EXT_ZCF, riscv_ext_zcf_validate), __RISCV_ISA_EXT_DATA_VALIDATE(zcmop, RISCV_ISA_EXT_ZCMOP, riscv_ext_zca_depends), + __RISCV_ISA_EXT_DATA_VALIDATE(zclsd, RISCV_ISA_EXT_ZCLSD, riscv_ext_zclsd_validate), + __RISCV_ISA_EXT_DATA_VALIDATE(zilsd, RISCV_ISA_EXT_ZILSD, riscv_ext_zilsd_validate), __RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA), __RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB), __RISCV_ISA_EXT_DATA(zbc, RISCV_ISA_EXT_ZBC), @@ -539,6 +564,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = { __RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL), __RISCV_ISA_EXT_DATA(svnapot, RISCV_ISA_EXT_SVNAPOT), __RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT), + __RISCV_ISA_EXT_DATA(svrsw60t59b, RISCV_ISA_EXT_SVRSW60T59B), __RISCV_ISA_EXT_DATA(svvptc, RISCV_ISA_EXT_SVVPTC), }; diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c index 8e86305831ea4..e6272d74572f9 100644 --- a/arch/riscv/kernel/ptrace.c +++ b/arch/riscv/kernel/ptrace.c @@ -153,6 +153,17 @@ static int riscv_vr_set(struct task_struct *target, 0, riscv_v_vsize); return ret; } + +static int riscv_vr_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!(has_vector() || has_xtheadvector())) + return -ENODEV; + + if (!riscv_v_vstate_query(task_pt_regs(target))) + return 0; + + return regset->n; +} #endif #ifdef CONFIG_RISCV_ISA_SUPM @@ -184,7 +195,7 @@ static int tagged_addr_ctrl_set(struct task_struct *target, } #endif -static const struct user_regset riscv_user_regset[] = { +static struct user_regset riscv_user_regset[] __ro_after_init = { [REGSET_X] = { USER_REGSET_NOTE_TYPE(PRSTATUS), .n = ELF_NGREG, @@ -207,11 +218,10 @@ static const struct user_regset riscv_user_regset[] = { [REGSET_V] = { USER_REGSET_NOTE_TYPE(RISCV_VECTOR), .align = 16, - .n = ((32 * RISCV_MAX_VLENB) + - sizeof(struct __riscv_v_regset_state)) / sizeof(__u32), .size = sizeof(__u32), .regset_get = riscv_vr_get, .set = riscv_vr_set, + .active = riscv_vr_active, }, #endif #ifdef CONFIG_RISCV_ISA_SUPM @@ -233,6 +243,14 @@ static const struct user_regset_view riscv_user_native_view = { .n = ARRAY_SIZE(riscv_user_regset), }; +#ifdef CONFIG_RISCV_ISA_V +void __init update_regset_vector_info(unsigned long size) +{ + riscv_user_regset[REGSET_V].n = (size + sizeof(struct __riscv_v_regset_state)) / + sizeof(__u32); +} +#endif + struct pt_regs_offset { const char *name; int offset; diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c index 08378fea3a111..5a956108b1eaf 100644 --- a/arch/riscv/kernel/signal.c +++ b/arch/riscv/kernel/signal.c @@ -68,18 +68,19 @@ static long save_fp_state(struct pt_regs *regs, #define restore_fp_state(task, regs) (0) #endif -#ifdef CONFIG_RISCV_ISA_V - -static long save_v_state(struct pt_regs *regs, void __user **sc_vec) +static long save_v_state(struct pt_regs *regs, void __user *sc_vec) { - struct __riscv_ctx_hdr __user *hdr; struct __sc_riscv_v_state __user *state; void __user *datap; long err; - hdr = *sc_vec; - /* Place state to the user's signal context space after the hdr */ - state = (struct __sc_riscv_v_state __user *)(hdr + 1); + if (!IS_ENABLED(CONFIG_RISCV_ISA_V) || + !((has_vector() || has_xtheadvector()) && + riscv_v_vstate_query(regs))) + return 0; + + /* Place state to the user's signal context space */ + state = (struct __sc_riscv_v_state __user *)sc_vec; /* Point datap right after the end of __sc_riscv_v_state */ datap = state + 1; @@ -97,15 +98,11 @@ static long save_v_state(struct pt_regs *regs, void __user **sc_vec) err |= __put_user((__force void *)datap, &state->v_state.datap); /* Copy the whole vector content to user space datap. */ err |= __copy_to_user(datap, current->thread.vstate.datap, riscv_v_vsize); - /* Copy magic to the user space after saving all vector conetext */ - err |= __put_user(RISCV_V_MAGIC, &hdr->magic); - err |= __put_user(riscv_v_sc_size, &hdr->size); if (unlikely(err)) - return err; + return -EFAULT; - /* Only progress the sv_vec if everything has done successfully */ - *sc_vec += riscv_v_sc_size; - return 0; + /* Only return the size if everything has done successfully */ + return riscv_v_sc_size; } /* @@ -142,10 +139,20 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec) */ return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize); } -#else -#define save_v_state(task, regs) (0) -#define __restore_v_state(task, regs) (0) -#endif + +struct arch_ext_priv { + __u32 magic; + long (*save)(struct pt_regs *regs, void __user *sc_vec); +}; + +struct arch_ext_priv arch_ext_list[] = { + { + .magic = RISCV_V_MAGIC, + .save = &save_v_state, + }, +}; + +const size_t nr_arch_exts = ARRAY_SIZE(arch_ext_list); static long restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) @@ -270,7 +277,8 @@ static long setup_sigcontext(struct rt_sigframe __user *frame, { struct sigcontext __user *sc = &frame->uc.uc_mcontext; struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr; - long err; + struct arch_ext_priv *arch_ext; + long err, i, ext_size; /* sc_regs is structured the same as the start of pt_regs */ err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs)); @@ -278,8 +286,20 @@ static long setup_sigcontext(struct rt_sigframe __user *frame, if (has_fpu()) err |= save_fp_state(regs, &sc->sc_fpregs); /* Save the vector state. */ - if ((has_vector() || has_xtheadvector()) && riscv_v_vstate_query(regs)) - err |= save_v_state(regs, (void __user **)&sc_ext_ptr); + for (i = 0; i < nr_arch_exts; i++) { + arch_ext = &arch_ext_list[i]; + if (!arch_ext->save) + continue; + + ext_size = arch_ext->save(regs, sc_ext_ptr + 1); + if (ext_size <= 0) { + err |= ext_size; + } else { + err |= __put_user(arch_ext->magic, &sc_ext_ptr->magic); + err |= __put_user(ext_size, &sc_ext_ptr->size); + sc_ext_ptr = (void *)sc_ext_ptr + ext_size; + } + } /* Write zero to fp-reserved space and check it on restore_sigcontext */ err |= __put_user(0, &sc->sc_extdesc.reserved); /* And put END __riscv_ctx_hdr at the end. */ diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 601a321e0f176..d85916a3660c3 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -39,7 +39,9 @@ #include "head.h" +#ifndef CONFIG_HOTPLUG_PARALLEL static DECLARE_COMPLETION(cpu_running); +#endif void __init smp_prepare_cpus(unsigned int max_cpus) { @@ -179,6 +181,12 @@ static int start_secondary_cpu(int cpu, struct task_struct *tidle) return -EOPNOTSUPP; } +#ifdef CONFIG_HOTPLUG_PARALLEL +int arch_cpuhp_kick_ap_alive(unsigned int cpu, struct task_struct *tidle) +{ + return start_secondary_cpu(cpu, tidle); +} +#else int __cpu_up(unsigned int cpu, struct task_struct *tidle) { int ret = 0; @@ -199,6 +207,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) return ret; } +#endif void __init smp_cpus_done(unsigned int max_cpus) { @@ -225,6 +234,10 @@ asmlinkage __visible void smp_callin(void) mmgrab(mm); current->active_mm = mm; +#ifdef CONFIG_HOTPLUG_PARALLEL + cpuhp_ap_sync_alive(); +#endif + store_cpu_topology(curr_cpuid); notify_cpu_starting(curr_cpuid); @@ -243,7 +256,9 @@ asmlinkage __visible void smp_callin(void) */ local_flush_icache_all(); local_flush_tlb_all(); +#ifndef CONFIG_HOTPLUG_PARALLEL complete(&cpu_running); +#endif /* * Disable preemption before enabling interrupts, so we don't try to * schedule a CPU that hasn't actually started yet. diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c index 199d13f86f313..e6787ba7f2fc4 100644 --- a/arch/riscv/kernel/sys_hwprobe.c +++ b/arch/riscv/kernel/sys_hwprobe.c @@ -109,6 +109,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair, EXT_KEY(ZAAMO); EXT_KEY(ZABHA); EXT_KEY(ZACAS); + EXT_KEY(ZALASR); EXT_KEY(ZALRSC); EXT_KEY(ZAWRS); EXT_KEY(ZBA); @@ -120,14 +121,17 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair, EXT_KEY(ZBS); EXT_KEY(ZCA); EXT_KEY(ZCB); + EXT_KEY(ZCLSD); EXT_KEY(ZCMOP); EXT_KEY(ZICBOM); + EXT_KEY(ZICBOP); EXT_KEY(ZICBOZ); EXT_KEY(ZICNTR); EXT_KEY(ZICOND); EXT_KEY(ZIHINTNTL); EXT_KEY(ZIHINTPAUSE); EXT_KEY(ZIHPM); + EXT_KEY(ZILSD); EXT_KEY(ZIMOP); EXT_KEY(ZKND); EXT_KEY(ZKNE); @@ -302,6 +306,11 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair, if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOM)) pair->value = riscv_cbom_block_size; break; + case RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE: + pair->value = 0; + if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOP)) + pair->value = riscv_cbop_block_size; + break; case RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS: pair->value = user_max_virt_addr(); break; diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c index 901e67adf5760..3ed071dab9d83 100644 --- a/arch/riscv/kernel/vector.c +++ b/arch/riscv/kernel/vector.c @@ -66,6 +66,8 @@ void __init riscv_v_setup_ctx_cache(void) if (!(has_vector() || has_xtheadvector())) return; + update_regset_vector_info(riscv_v_vsize); + riscv_v_user_cachep = kmem_cache_create_usercopy("riscv_vector_ctx", riscv_v_vsize, 16, SLAB_PANIC, 0, riscv_v_vsize, NULL); diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig index c50328212917e..77379f77840ae 100644 --- a/arch/riscv/kvm/Kconfig +++ b/arch/riscv/kvm/Kconfig @@ -23,7 +23,6 @@ config KVM select HAVE_KVM_IRQCHIP select HAVE_KVM_IRQ_ROUTING select HAVE_KVM_MSI - select HAVE_KVM_VCPU_ASYNC_IOCTL select HAVE_KVM_READONLY_MEM select HAVE_KVM_DIRTY_RING_ACQ_REL select KVM_COMMON diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile index 07197395750e3..3b8afb038b35c 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -27,6 +27,7 @@ kvm-y += vcpu_onereg.o kvm-$(CONFIG_RISCV_PMU_SBI) += vcpu_pmu.o kvm-y += vcpu_sbi.o kvm-y += vcpu_sbi_base.o +kvm-y += vcpu_sbi_forward.o kvm-y += vcpu_sbi_fwft.o kvm-y += vcpu_sbi_hsm.o kvm-$(CONFIG_RISCV_PMU_SBI) += vcpu_sbi_pmu.o diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c index 11422cb95a644..e597e86491c3b 100644 --- a/arch/riscv/kvm/aia_imsic.c +++ b/arch/riscv/kvm/aia_imsic.c @@ -814,7 +814,7 @@ int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu) /* For HW acceleration mode, we can't continue */ if (kvm->arch.aia.mode == KVM_DEV_RISCV_AIA_MODE_HWACCEL) { run->fail_entry.hardware_entry_failure_reason = - CSR_HSTATUS; + KVM_EXIT_FAIL_ENTRY_NO_VSFILE; run->fail_entry.cpu = vcpu->cpu; run->exit_reason = KVM_EXIT_FAIL_ENTRY; return 0; diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c index 77dc1655b4423..45536af521f05 100644 --- a/arch/riscv/kvm/main.c +++ b/arch/riscv/kvm/main.c @@ -15,6 +15,18 @@ #include #include +DEFINE_STATIC_KEY_FALSE(kvm_riscv_vsstage_tlb_no_gpa); + +static void kvm_riscv_setup_vendor_features(void) +{ + /* Andes AX66: split two-stage TLBs */ + if (riscv_cached_mvendorid(0) == ANDES_VENDOR_ID && + (riscv_cached_marchid(0) & 0xFFFF) == 0x8A66) { + static_branch_enable(&kvm_riscv_vsstage_tlb_no_gpa); + kvm_info("VS-stage TLB does not cache guest physical address and VMID\n"); + } +} + long kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -160,6 +172,8 @@ static int __init riscv_kvm_init(void) kvm_info("AIA available with %d guest external interrupts\n", kvm_riscv_aia_nr_hgei); + kvm_riscv_setup_vendor_features(); + kvm_register_perf_callbacks(NULL); rc = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE); diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c index 58f5f3536ffdf..4ab06697bfc08 100644 --- a/arch/riscv/kvm/mmu.c +++ b/arch/riscv/kvm/mmu.c @@ -161,8 +161,11 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, * allocated dirty_bitmap[], dirty pages will be tracked while * the memory slot is write protected. */ - if (change != KVM_MR_DELETE && new->flags & KVM_MEM_LOG_DIRTY_PAGES) + if (change != KVM_MR_DELETE && new->flags & KVM_MEM_LOG_DIRTY_PAGES) { + if (kvm_dirty_log_manual_protect_and_init_set(kvm)) + return; mmu_wp_memory_region(kvm, new->id); + } } int kvm_arch_prepare_memory_region(struct kvm *kvm, diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c index 3c5a70a2b9271..ff1aeac4eb8eb 100644 --- a/arch/riscv/kvm/tlb.c +++ b/arch/riscv/kvm/tlb.c @@ -158,6 +158,36 @@ void kvm_riscv_local_hfence_vvma_all(unsigned long vmid) csr_write(CSR_HGATP, hgatp); } +void kvm_riscv_local_tlb_sanitize(struct kvm_vcpu *vcpu) +{ + unsigned long vmid; + + if (!kvm_riscv_gstage_vmid_bits() || + vcpu->arch.last_exit_cpu == vcpu->cpu) + return; + + /* + * On RISC-V platforms with hardware VMID support, we share same + * VMID for all VCPUs of a particular Guest/VM. This means we might + * have stale G-stage TLB entries on the current Host CPU due to + * some other VCPU of the same Guest which ran previously on the + * current Host CPU. + * + * To cleanup stale TLB entries, we simply flush all G-stage TLB + * entries by VMID whenever underlying Host CPU changes for a VCPU. + */ + + vmid = READ_ONCE(vcpu->kvm->arch.vmid.vmid); + kvm_riscv_local_hfence_gvma_vmid_all(vmid); + + /* + * Flush VS-stage TLB entries for implementation where VS-stage + * TLB does not cahce guest physical address and VMID. + */ + if (static_branch_unlikely(&kvm_riscv_vsstage_tlb_no_gpa)) + kvm_riscv_local_hfence_vvma_all(vmid); +} + void kvm_riscv_fence_i_process(struct kvm_vcpu *vcpu) { kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_FENCE_I_RCVD); diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index 5ce35aba60696..a55a95da54d0f 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -238,8 +238,8 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) return VM_FAULT_SIGBUS; } -long kvm_arch_vcpu_async_ioctl(struct file *filp, - unsigned int ioctl, unsigned long arg) +long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) { struct kvm_vcpu *vcpu = filp->private_data; void __user *argp = (void __user *)arg; @@ -968,7 +968,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) * Note: This should be done after G-stage VMID has been * updated using kvm_riscv_gstage_vmid_ver_changed() */ - kvm_riscv_gstage_vmid_sanitize(vcpu); + kvm_riscv_local_tlb_sanitize(vcpu); trace_kvm_entry(vcpu); diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c index de1f96ea62251..4d89b94128aea 100644 --- a/arch/riscv/kvm/vcpu_insn.c +++ b/arch/riscv/kvm/vcpu_insn.c @@ -298,6 +298,22 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, return (rc <= 0) ? rc : 1; } +static bool is_load_guest_page_fault(unsigned long scause) +{ + /** + * If a g-stage page fault occurs, the direct approach + * is to let the g-stage page fault handler handle it + * naturally, however, calling the g-stage page fault + * handler here seems rather strange. + * Considering this is a corner case, we can directly + * return to the guest and re-execute the same PC, this + * will trigger a g-stage page fault again and then the + * regular g-stage page fault handler will populate + * g-stage page table. + */ + return (scause == EXC_LOAD_GUEST_PAGE_FAULT); +} + /** * kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap * @@ -323,6 +339,8 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ct->sepc, &utrap); if (utrap.scause) { + if (is_load_guest_page_fault(utrap.scause)) + return 1; utrap.sepc = ct->sepc; kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); return 1; @@ -378,6 +396,8 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, &utrap); if (utrap.scause) { + if (is_load_guest_page_fault(utrap.scause)) + return 1; /* Redirect trap if we failed to read instruction */ utrap.sepc = ct->sepc; kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); @@ -504,6 +524,8 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, &utrap); if (utrap.scause) { + if (is_load_guest_page_fault(utrap.scause)) + return 1; /* Redirect trap if we failed to read instruction */ utrap.sepc = ct->sepc; kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 1b13623380e15..46ab7b989432b 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -82,6 +82,10 @@ static const struct kvm_riscv_sbi_extension_entry sbi_ext[] = { .ext_idx = KVM_RISCV_SBI_EXT_FWFT, .ext_ptr = &vcpu_sbi_ext_fwft, }, + { + .ext_idx = KVM_RISCV_SBI_EXT_MPXY, + .ext_ptr = &vcpu_sbi_ext_mpxy, + }, { .ext_idx = KVM_RISCV_SBI_EXT_EXPERIMENTAL, .ext_ptr = &vcpu_sbi_ext_experimental, @@ -120,7 +124,9 @@ static bool riscv_vcpu_supports_sbi_ext(struct kvm_vcpu *vcpu, int idx) return sext && scontext->ext_status[sext->ext_idx] != KVM_RISCV_SBI_EXT_STATUS_UNAVAILABLE; } -void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) +int kvm_riscv_vcpu_sbi_forward_handler(struct kvm_vcpu *vcpu, + struct kvm_run *run, + struct kvm_vcpu_sbi_return *retdata) { struct kvm_cpu_context *cp = &vcpu->arch.guest_context; @@ -137,6 +143,8 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) run->riscv_sbi.args[5] = cp->a5; run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED; run->riscv_sbi.ret[1] = 0; + retdata->uexit = true; + return 0; } void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, diff --git a/arch/riscv/kvm/vcpu_sbi_base.c b/arch/riscv/kvm/vcpu_sbi_base.c index 5bc570b984f42..06fdd5f693649 100644 --- a/arch/riscv/kvm/vcpu_sbi_base.c +++ b/arch/riscv/kvm/vcpu_sbi_base.c @@ -41,8 +41,7 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, * For experimental/vendor extensions * forward it to the userspace */ - kvm_riscv_vcpu_sbi_forward(vcpu, run); - retdata->uexit = true; + return kvm_riscv_vcpu_sbi_forward_handler(vcpu, run, retdata); } else { sbi_ext = kvm_vcpu_sbi_find_ext(vcpu, cp->a0); *out_val = sbi_ext && sbi_ext->probe ? @@ -71,28 +70,3 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base = { .extid_end = SBI_EXT_BASE, .handler = kvm_sbi_ext_base_handler, }; - -static int kvm_sbi_ext_forward_handler(struct kvm_vcpu *vcpu, - struct kvm_run *run, - struct kvm_vcpu_sbi_return *retdata) -{ - /* - * Both SBI experimental and vendor extensions are - * unconditionally forwarded to userspace. - */ - kvm_riscv_vcpu_sbi_forward(vcpu, run); - retdata->uexit = true; - return 0; -} - -const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental = { - .extid_start = SBI_EXT_EXPERIMENTAL_START, - .extid_end = SBI_EXT_EXPERIMENTAL_END, - .handler = kvm_sbi_ext_forward_handler, -}; - -const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor = { - .extid_start = SBI_EXT_VENDOR_START, - .extid_end = SBI_EXT_VENDOR_END, - .handler = kvm_sbi_ext_forward_handler, -}; diff --git a/arch/riscv/kvm/vcpu_sbi_forward.c b/arch/riscv/kvm/vcpu_sbi_forward.c new file mode 100644 index 0000000000000..5a3c75eb23c5a --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_forward.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Ventana Micro Systems Inc. + */ + +#include +#include +#include + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental = { + .extid_start = SBI_EXT_EXPERIMENTAL_START, + .extid_end = SBI_EXT_EXPERIMENTAL_END, + .handler = kvm_riscv_vcpu_sbi_forward_handler, +}; + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor = { + .extid_start = SBI_EXT_VENDOR_START, + .extid_end = SBI_EXT_VENDOR_END, + .handler = kvm_riscv_vcpu_sbi_forward_handler, +}; + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn = { + .extid_start = SBI_EXT_DBCN, + .extid_end = SBI_EXT_DBCN, + .default_disabled = true, + .handler = kvm_riscv_vcpu_sbi_forward_handler, +}; + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_mpxy = { + .extid_start = SBI_EXT_MPXY, + .extid_end = SBI_EXT_MPXY, + .default_disabled = true, + .handler = kvm_riscv_vcpu_sbi_forward_handler, +}; diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c index b490ed1428a68..506a510b6bff3 100644 --- a/arch/riscv/kvm/vcpu_sbi_replace.c +++ b/arch/riscv/kvm/vcpu_sbi_replace.c @@ -185,35 +185,3 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = { .extid_end = SBI_EXT_SRST, .handler = kvm_sbi_ext_srst_handler, }; - -static int kvm_sbi_ext_dbcn_handler(struct kvm_vcpu *vcpu, - struct kvm_run *run, - struct kvm_vcpu_sbi_return *retdata) -{ - struct kvm_cpu_context *cp = &vcpu->arch.guest_context; - unsigned long funcid = cp->a6; - - switch (funcid) { - case SBI_EXT_DBCN_CONSOLE_WRITE: - case SBI_EXT_DBCN_CONSOLE_READ: - case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: - /* - * The SBI debug console functions are unconditionally - * forwarded to the userspace. - */ - kvm_riscv_vcpu_sbi_forward(vcpu, run); - retdata->uexit = true; - break; - default: - retdata->err_val = SBI_ERR_NOT_SUPPORTED; - } - - return 0; -} - -const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn = { - .extid_start = SBI_EXT_DBCN, - .extid_end = SBI_EXT_DBCN, - .default_disabled = true, - .handler = kvm_sbi_ext_dbcn_handler, -}; diff --git a/arch/riscv/kvm/vcpu_sbi_system.c b/arch/riscv/kvm/vcpu_sbi_system.c index 359be90b0fc58..c6f7e609ac794 100644 --- a/arch/riscv/kvm/vcpu_sbi_system.c +++ b/arch/riscv/kvm/vcpu_sbi_system.c @@ -47,9 +47,7 @@ static int kvm_sbi_ext_susp_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, kvm_riscv_vcpu_sbi_request_reset(vcpu, cp->a1, cp->a2); /* userspace provides the suspend implementation */ - kvm_riscv_vcpu_sbi_forward(vcpu, run); - retdata->uexit = true; - break; + return kvm_riscv_vcpu_sbi_forward_handler(vcpu, run, retdata); default: retdata->err_val = SBI_ERR_NOT_SUPPORTED; break; diff --git a/arch/riscv/kvm/vcpu_sbi_v01.c b/arch/riscv/kvm/vcpu_sbi_v01.c index 368dfddd23d96..188d5ea5b3b85 100644 --- a/arch/riscv/kvm/vcpu_sbi_v01.c +++ b/arch/riscv/kvm/vcpu_sbi_v01.c @@ -32,8 +32,7 @@ static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, * The CONSOLE_GETCHAR/CONSOLE_PUTCHAR SBI calls cannot be * handled in kernel so we forward these to user-space */ - kvm_riscv_vcpu_sbi_forward(vcpu, run); - retdata->uexit = true; + ret = kvm_riscv_vcpu_sbi_forward_handler(vcpu, run, retdata); break; case SBI_EXT_0_1_SET_TIMER: #if __riscv_xlen == 32 diff --git a/arch/riscv/kvm/vmid.c b/arch/riscv/kvm/vmid.c index abb1c2bf25423..cf34d448289d7 100644 --- a/arch/riscv/kvm/vmid.c +++ b/arch/riscv/kvm/vmid.c @@ -122,26 +122,3 @@ void kvm_riscv_gstage_vmid_update(struct kvm_vcpu *vcpu) kvm_for_each_vcpu(i, v, vcpu->kvm) kvm_make_request(KVM_REQ_UPDATE_HGATP, v); } - -void kvm_riscv_gstage_vmid_sanitize(struct kvm_vcpu *vcpu) -{ - unsigned long vmid; - - if (!kvm_riscv_gstage_vmid_bits() || - vcpu->arch.last_exit_cpu == vcpu->cpu) - return; - - /* - * On RISC-V platforms with hardware VMID support, we share same - * VMID for all VCPUs of a particular Guest/VM. This means we might - * have stale G-stage TLB entries on the current Host CPU due to - * some other VCPU of the same Guest which ran previously on the - * current Host CPU. - * - * To cleanup stale TLB entries, we simply flush all G-stage TLB - * entries by VMID whenever underlying Host CPU changes for a VCPU. - */ - - vmid = READ_ONCE(vcpu->kvm->arch.vmid.vmid); - kvm_riscv_local_hfence_gvma_vmid_all(vmid); -} diff --git a/arch/riscv/lib/csum.c b/arch/riscv/lib/csum.c index 9408f50ca59a8..75bd0abffd631 100644 --- a/arch/riscv/lib/csum.c +++ b/arch/riscv/lib/csum.c @@ -40,20 +40,11 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, uproto = (__force unsigned int)htonl(proto); sum += uproto; - if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB)) { + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && + IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) && + riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) { unsigned long fold_temp; - /* - * Zbb is likely available when the kernel is compiled with Zbb - * support, so nop when Zbb is available and jump when Zbb is - * not available. - */ - asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, - RISCV_ISA_EXT_ZBB, 1) - : - : - : - : no_zbb); asm(".option push \n\ .option arch,+zbb \n\ rori %[fold_temp], %[sum], 32 \n\ @@ -66,7 +57,7 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, : [sum] "+r" (sum), [fold_temp] "=&r" (fold_temp)); return (__force __sum16)(sum >> 16); } -no_zbb: + sum += ror64(sum, 32); sum >>= 32; return csum_fold((__force __wsum)sum); @@ -152,21 +143,11 @@ do_csum_with_alignment(const unsigned char *buff, int len) csum = do_csum_common(ptr, end, data); #ifdef CC_HAS_ASM_GOTO_TIED_OUTPUT - if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB)) { + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && + IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) && + riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) { unsigned long fold_temp; - /* - * Zbb is likely available when the kernel is compiled with Zbb - * support, so nop when Zbb is available and jump when Zbb is - * not available. - */ - asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, - RISCV_ISA_EXT_ZBB, 1) - : - : - : - : no_zbb); - #ifdef CONFIG_32BIT asm_goto_output(".option push \n\ .option arch,+zbb \n\ @@ -204,7 +185,7 @@ do_csum_with_alignment(const unsigned char *buff, int len) end: return csum >> 16; } -no_zbb: + #endif /* CC_HAS_ASM_GOTO_TIED_OUTPUT */ #ifndef CONFIG_32BIT csum += ror64(csum, 32); @@ -234,21 +215,11 @@ do_csum_no_alignment(const unsigned char *buff, int len) end = (const unsigned long *)(buff + len); csum = do_csum_common(ptr, end, data); - if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB)) { + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && + IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) && + riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) { unsigned long fold_temp; - /* - * Zbb is likely available when the kernel is compiled with Zbb - * support, so nop when Zbb is available and jump when Zbb is - * not available. - */ - asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, - RISCV_ISA_EXT_ZBB, 1) - : - : - : - : no_zbb); - #ifdef CONFIG_32BIT asm (".option push \n\ .option arch,+zbb \n\ @@ -274,7 +245,7 @@ do_csum_no_alignment(const unsigned char *buff, int len) #endif /* !CONFIG_32BIT */ return csum >> 16; } -no_zbb: + #ifndef CONFIG_32BIT csum += ror64(csum, 32); csum >>= 32; diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index d85efe74a4b69..addb8a9305bee 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -441,7 +441,7 @@ static inline phys_addr_t __init alloc_pte_fixmap(uintptr_t va) static phys_addr_t __meminit alloc_pte_late(uintptr_t va) { - struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, 0); + struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0); /* * We do not know which mm the PTE page is associated to at this point. @@ -526,7 +526,7 @@ static phys_addr_t __init alloc_pmd_fixmap(uintptr_t va) static phys_addr_t __meminit alloc_pmd_late(uintptr_t va) { - struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, 0); + struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0); /* See comment in alloc_pte_late() regarding NULL passed the ctor */ BUG_ON(!ptdesc || !pagetable_pmd_ctor(NULL, ptdesc)); diff --git a/arch/riscv/mm/pgtable.c b/arch/riscv/mm/pgtable.c index 8b6c0a112a8db..807c0a0de1827 100644 --- a/arch/riscv/mm/pgtable.c +++ b/arch/riscv/mm/pgtable.c @@ -9,8 +9,16 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, pte_t *ptep, pte_t entry, int dirty) { - asm goto(ALTERNATIVE("nop", "j %l[svvptc]", 0, RISCV_ISA_EXT_SVVPTC, 1) - : : : : svvptc); + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SVVPTC)) { + if (!pte_same(ptep_get(ptep), entry)) { + __set_pte_at(vma->vm_mm, ptep, entry); + /* Here only not svadu is impacted */ + flush_tlb_page(vma, address); + return true; + } + + return false; + } if (!pte_same(ptep_get(ptep), entry)) __set_pte_at(vma->vm_mm, ptep, entry); @@ -19,16 +27,6 @@ int ptep_set_access_flags(struct vm_area_struct *vma, * the case that the PTE changed and the spurious fault case. */ return true; - -svvptc: - if (!pte_same(ptep_get(ptep), entry)) { - __set_pte_at(vma->vm_mm, ptep, entry); - /* Here only not svadu is impacted */ - flush_tlb_page(vma, address); - return true; - } - - return false; } int ptep_test_and_clear_young(struct vm_area_struct *vma, diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 938e5df75b2df..0e5fad5f06ca1 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -238,6 +238,7 @@ config S390 select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_POSIX_CPU_TIMERS_TASK_WORK select HAVE_PREEMPT_DYNAMIC_KEY select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_RELIABLE_STACKTRACE @@ -254,6 +255,7 @@ config S390 select HOTPLUG_SMT select IOMMU_HELPER if PCI select IOMMU_SUPPORT if PCI + select IRQ_MSI_LIB if PCI select KASAN_VMALLOC if KASAN select LOCK_MM_AND_FIND_VMA select MMU_GATHER_MERGE_VMAS diff --git a/arch/s390/boot/vmem.c b/arch/s390/boot/vmem.c index cea3de4dce8c3..7d6cc4c85af05 100644 --- a/arch/s390/boot/vmem.c +++ b/arch/s390/boot/vmem.c @@ -16,7 +16,6 @@ #include "decompressor.h" #include "boot.h" -#define INVALID_PHYS_ADDR (~(phys_addr_t)0) struct ctlreg __bootdata_preserved(s390_invalid_asce); #ifdef CONFIG_PROC_FS @@ -245,22 +244,10 @@ static void *boot_crst_alloc(unsigned long val) static pte_t *boot_pte_alloc(void) { - static void *pte_leftover; pte_t *pte; - /* - * handling pte_leftovers this way helps to avoid memory fragmentation - * during POPULATE_KASAN_MAP_SHADOW when EDAT is off - */ - if (!pte_leftover) { - pte_leftover = (void *)physmem_alloc_or_die(RR_VMEM, PAGE_SIZE, PAGE_SIZE); - pte = pte_leftover + _PAGE_TABLE_SIZE; - __arch_set_page_dat(pte, 1); - } else { - pte = pte_leftover; - pte_leftover = NULL; - } - + pte = (void *)physmem_alloc_or_die(RR_VMEM, PAGE_SIZE, PAGE_SIZE); + __arch_set_page_dat(pte, 1); memset64((u64 *)pte, _PAGE_INVALID, PTRS_PER_PTE); return pte; } diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h index 4dc2e068e0ff5..2bb7104124cac 100644 --- a/arch/s390/hypfs/hypfs.h +++ b/arch/s390/hypfs/hypfs.h @@ -22,11 +22,9 @@ extern struct dentry *hypfs_mkdir(struct dentry *parent, const char *name); -extern struct dentry *hypfs_create_u64(struct dentry *dir, const char *name, - __u64 value); +extern int hypfs_create_u64(struct dentry *dir, const char *name, __u64 value); -extern struct dentry *hypfs_create_str(struct dentry *dir, const char *name, - char *string); +extern int hypfs_create_str(struct dentry *dir, const char *name, char *string); /* LPAR Hypervisor */ extern int hypfs_diag_init(void); diff --git a/arch/s390/hypfs/hypfs_diag_fs.c b/arch/s390/hypfs/hypfs_diag_fs.c index 013da4ff9802e..39621c3260103 100644 --- a/arch/s390/hypfs/hypfs_diag_fs.c +++ b/arch/s390/hypfs/hypfs_diag_fs.c @@ -203,7 +203,7 @@ static int hypfs_create_cpu_files(struct dentry *cpus_dir, void *cpu_info) { struct dentry *cpu_dir; char buffer[TMP_SIZE]; - void *rc; + int rc; snprintf(buffer, TMP_SIZE, "%d", cpu_info__cpu_addr(diag204_get_info_type(), cpu_info)); @@ -213,22 +213,21 @@ static int hypfs_create_cpu_files(struct dentry *cpus_dir, void *cpu_info) rc = hypfs_create_u64(cpu_dir, "mgmtime", cpu_info__acc_time(diag204_get_info_type(), cpu_info) - cpu_info__lp_time(diag204_get_info_type(), cpu_info)); - if (IS_ERR(rc)) - return PTR_ERR(rc); + if (rc) + return rc; rc = hypfs_create_u64(cpu_dir, "cputime", cpu_info__lp_time(diag204_get_info_type(), cpu_info)); - if (IS_ERR(rc)) - return PTR_ERR(rc); + if (rc) + return rc; if (diag204_get_info_type() == DIAG204_INFO_EXT) { rc = hypfs_create_u64(cpu_dir, "onlinetime", cpu_info__online_time(diag204_get_info_type(), cpu_info)); - if (IS_ERR(rc)) - return PTR_ERR(rc); + if (rc) + return rc; } diag224_idx2name(cpu_info__ctidx(diag204_get_info_type(), cpu_info), buffer); - rc = hypfs_create_str(cpu_dir, "type", buffer); - return PTR_ERR_OR_ZERO(rc); + return hypfs_create_str(cpu_dir, "type", buffer); } static void *hypfs_create_lpar_files(struct dentry *systems_dir, void *part_hdr) @@ -263,7 +262,7 @@ static int hypfs_create_phys_cpu_files(struct dentry *cpus_dir, void *cpu_info) { struct dentry *cpu_dir; char buffer[TMP_SIZE]; - void *rc; + int rc; snprintf(buffer, TMP_SIZE, "%i", phys_cpu__cpu_addr(diag204_get_info_type(), cpu_info)); @@ -272,11 +271,10 @@ static int hypfs_create_phys_cpu_files(struct dentry *cpus_dir, void *cpu_info) return PTR_ERR(cpu_dir); rc = hypfs_create_u64(cpu_dir, "mgmtime", phys_cpu__mgm_time(diag204_get_info_type(), cpu_info)); - if (IS_ERR(rc)) - return PTR_ERR(rc); + if (rc) + return rc; diag224_idx2name(phys_cpu__ctidx(diag204_get_info_type(), cpu_info), buffer); - rc = hypfs_create_str(cpu_dir, "type", buffer); - return PTR_ERR_OR_ZERO(rc); + return hypfs_create_str(cpu_dir, "type", buffer); } static void *hypfs_create_phys_files(struct dentry *parent_dir, void *phys_hdr) @@ -315,41 +313,25 @@ int hypfs_diag_create_files(struct dentry *root) return rc; systems_dir = hypfs_mkdir(root, "systems"); - if (IS_ERR(systems_dir)) { - rc = PTR_ERR(systems_dir); - goto err_out; - } + if (IS_ERR(systems_dir)) + return PTR_ERR(systems_dir); time_hdr = (struct x_info_blk_hdr *)buffer; part_hdr = time_hdr + info_blk_hdr__size(diag204_get_info_type()); for (i = 0; i < info_blk_hdr__npar(diag204_get_info_type(), time_hdr); i++) { part_hdr = hypfs_create_lpar_files(systems_dir, part_hdr); - if (IS_ERR(part_hdr)) { - rc = PTR_ERR(part_hdr); - goto err_out; - } + if (IS_ERR(part_hdr)) + return PTR_ERR(part_hdr); } if (info_blk_hdr__flags(diag204_get_info_type(), time_hdr) & DIAG204_LPAR_PHYS_FLG) { ptr = hypfs_create_phys_files(root, part_hdr); - if (IS_ERR(ptr)) { - rc = PTR_ERR(ptr); - goto err_out; - } + if (IS_ERR(ptr)) + return PTR_ERR(ptr); } hyp_dir = hypfs_mkdir(root, "hyp"); - if (IS_ERR(hyp_dir)) { - rc = PTR_ERR(hyp_dir); - goto err_out; - } - ptr = hypfs_create_str(hyp_dir, "type", "LPAR Hypervisor"); - if (IS_ERR(ptr)) { - rc = PTR_ERR(ptr); - goto err_out; - } - rc = 0; - -err_out: - return rc; + if (IS_ERR(hyp_dir)) + return PTR_ERR(hyp_dir); + return hypfs_create_str(hyp_dir, "type", "LPAR Hypervisor"); } /* Diagnose 224 functions */ diff --git a/arch/s390/hypfs/hypfs_vm_fs.c b/arch/s390/hypfs/hypfs_vm_fs.c index 6011289afa8c8..a149a9f92e40a 100644 --- a/arch/s390/hypfs/hypfs_vm_fs.c +++ b/arch/s390/hypfs/hypfs_vm_fs.c @@ -19,10 +19,9 @@ #define ATTRIBUTE(dir, name, member) \ do { \ - void *rc; \ - rc = hypfs_create_u64(dir, name, member); \ - if (IS_ERR(rc)) \ - return PTR_ERR(rc); \ + int rc = hypfs_create_u64(dir, name, member); \ + if (rc) \ + return rc; \ } while (0) static int hypfs_vm_create_guest(struct dentry *systems_dir, @@ -85,7 +84,7 @@ static int hypfs_vm_create_guest(struct dentry *systems_dir, int hypfs_vm_create_files(struct dentry *root) { - struct dentry *dir, *file; + struct dentry *dir; struct diag2fc_data *data; unsigned int count = 0; int rc, i; @@ -100,11 +99,9 @@ int hypfs_vm_create_files(struct dentry *root) rc = PTR_ERR(dir); goto failed; } - file = hypfs_create_str(dir, "type", "z/VM Hypervisor"); - if (IS_ERR(file)) { - rc = PTR_ERR(file); + rc = hypfs_create_str(dir, "type", "z/VM Hypervisor"); + if (rc) goto failed; - } /* physical cpus */ dir = hypfs_mkdir(root, "cpus"); @@ -112,11 +109,9 @@ int hypfs_vm_create_files(struct dentry *root) rc = PTR_ERR(dir); goto failed; } - file = hypfs_create_u64(dir, "count", data->lcpus); - if (IS_ERR(file)) { - rc = PTR_ERR(file); + rc = hypfs_create_u64(dir, "count", data->lcpus); + if (rc) goto failed; - } /* guests */ dir = hypfs_mkdir(root, "systems"); diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index ee5cfa8f71a0e..3a47c2e24b6eb 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -60,33 +60,17 @@ static void hypfs_update_update(struct super_block *sb) static void hypfs_add_dentry(struct dentry *dentry) { - dentry->d_fsdata = hypfs_last_dentry; - hypfs_last_dentry = dentry; -} - -static void hypfs_remove(struct dentry *dentry) -{ - struct dentry *parent; - - parent = dentry->d_parent; - inode_lock(d_inode(parent)); - if (simple_positive(dentry)) { - if (d_is_dir(dentry)) - simple_rmdir(d_inode(parent), dentry); - else - simple_unlink(d_inode(parent), dentry); + if (IS_ROOT(dentry->d_parent)) { + dentry->d_fsdata = hypfs_last_dentry; + hypfs_last_dentry = dentry; } - d_drop(dentry); - dput(dentry); - inode_unlock(d_inode(parent)); } -static void hypfs_delete_tree(struct dentry *root) +static void hypfs_delete_tree(void) { while (hypfs_last_dentry) { - struct dentry *next_dentry; - next_dentry = hypfs_last_dentry->d_fsdata; - hypfs_remove(hypfs_last_dentry); + struct dentry *next_dentry = hypfs_last_dentry->d_fsdata; + simple_recursive_removal(hypfs_last_dentry, NULL); hypfs_last_dentry = next_dentry; } } @@ -183,14 +167,14 @@ static ssize_t hypfs_write_iter(struct kiocb *iocb, struct iov_iter *from) rc = -EBUSY; goto out; } - hypfs_delete_tree(sb->s_root); + hypfs_delete_tree(); if (machine_is_vm()) rc = hypfs_vm_create_files(sb->s_root); else rc = hypfs_diag_create_files(sb->s_root); if (rc) { pr_err("Updating the hypfs tree failed\n"); - hypfs_delete_tree(sb->s_root); + hypfs_delete_tree(); goto out; } hypfs_update_update(sb); @@ -325,13 +309,9 @@ static void hypfs_kill_super(struct super_block *sb) { struct hypfs_sb_info *sb_info = sb->s_fs_info; - if (sb->s_root) - hypfs_delete_tree(sb->s_root); - if (sb_info && sb_info->update_file) - hypfs_remove(sb_info->update_file); - kfree(sb->s_fs_info); - sb->s_fs_info = NULL; - kill_litter_super(sb); + hypfs_last_dentry = NULL; + kill_anon_super(sb); + kfree(sb_info); } static struct dentry *hypfs_create_file(struct dentry *parent, const char *name, @@ -340,17 +320,13 @@ static struct dentry *hypfs_create_file(struct dentry *parent, const char *name, struct dentry *dentry; struct inode *inode; - inode_lock(d_inode(parent)); - dentry = lookup_noperm(&QSTR(name), parent); - if (IS_ERR(dentry)) { - dentry = ERR_PTR(-ENOMEM); - goto fail; - } + dentry = simple_start_creating(parent, name); + if (IS_ERR(dentry)) + return ERR_PTR(-ENOMEM); inode = hypfs_make_inode(parent->d_sb, mode); if (!inode) { - dput(dentry); - dentry = ERR_PTR(-ENOMEM); - goto fail; + simple_done_creating(dentry); + return ERR_PTR(-ENOMEM); } if (S_ISREG(mode)) { inode->i_fop = &hypfs_file_ops; @@ -365,11 +341,9 @@ static struct dentry *hypfs_create_file(struct dentry *parent, const char *name, } else BUG(); inode->i_private = data; - d_instantiate(dentry, inode); - dget(dentry); -fail: - inode_unlock(d_inode(parent)); - return dentry; + d_make_persistent(dentry, inode); + simple_done_creating(dentry); + return dentry; // borrowed } struct dentry *hypfs_mkdir(struct dentry *parent, const char *name) @@ -397,8 +371,7 @@ static struct dentry *hypfs_create_update_file(struct dentry *dir) return dentry; } -struct dentry *hypfs_create_u64(struct dentry *dir, - const char *name, __u64 value) +int hypfs_create_u64(struct dentry *dir, const char *name, __u64 value) { char *buffer; char tmp[TMP_SIZE]; @@ -407,35 +380,34 @@ struct dentry *hypfs_create_u64(struct dentry *dir, snprintf(tmp, TMP_SIZE, "%llu\n", (unsigned long long int)value); buffer = kstrdup(tmp, GFP_KERNEL); if (!buffer) - return ERR_PTR(-ENOMEM); + return -ENOMEM; dentry = hypfs_create_file(dir, name, buffer, S_IFREG | REG_FILE_MODE); if (IS_ERR(dentry)) { kfree(buffer); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } hypfs_add_dentry(dentry); - return dentry; + return 0; } -struct dentry *hypfs_create_str(struct dentry *dir, - const char *name, char *string) +int hypfs_create_str(struct dentry *dir, const char *name, char *string) { char *buffer; struct dentry *dentry; buffer = kmalloc(strlen(string) + 2, GFP_KERNEL); if (!buffer) - return ERR_PTR(-ENOMEM); + return -ENOMEM; sprintf(buffer, "%s\n", string); dentry = hypfs_create_file(dir, name, buffer, S_IFREG | REG_FILE_MODE); if (IS_ERR(dentry)) { kfree(buffer); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } hypfs_add_dentry(dentry); - return dentry; + return 0; } static const struct file_operations hypfs_file_ops = { diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h index acb4b13d98c5e..ee9221bb5d180 100644 --- a/arch/s390/include/asm/bug.h +++ b/arch/s390/include/asm/bug.h @@ -4,11 +4,14 @@ #include +#ifdef CONFIG_BUG + #ifndef CONFIG_DEBUG_BUGVERBOSE #define _BUGVERBOSE_LOCATION(file, line) #else #define __BUGVERBOSE_LOCATION(file, line) \ .pushsection .rodata.str, "aMS", @progbits, 1; \ + .align 2; \ 10002: .ascii file "\0"; \ .popsection; \ \ @@ -52,6 +55,8 @@ do { \ #define HAVE_ARCH_BUG +#endif /* CONFIG_BUG */ + #include #endif /* _ASM_S390_BUG_H */ diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index c2ba3d4398c53..ae1223264d3cd 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -146,6 +146,7 @@ struct kvm_vcpu_stat { u64 instruction_diagnose_500; u64 instruction_diagnose_other; u64 pfault_sync; + u64 signal_exits; }; #define PGM_OPERATION 0x01 @@ -631,10 +632,8 @@ struct kvm_s390_pv { struct mmu_notifier mmu_notifier; }; -struct kvm_arch{ - void *sca; - int use_esca; - rwlock_t sca_lock; +struct kvm_arch { + struct esca_block *sca; debug_info_t *dbf; struct kvm_s390_float_interrupt float_int; struct kvm_device *flic; @@ -650,6 +649,7 @@ struct kvm_arch{ int user_sigp; int user_stsi; int user_instr0; + int user_operexec; struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; wait_queue_head_t ipte_wq; int ipte_lock_count; diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 9240a363c8935..c1d63b613bf9b 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -166,6 +166,8 @@ static inline int page_reset_referenced(unsigned long addr) return CC_TRANSFORM(cc); } +int split_pud_page(pud_t *pudp, unsigned long addr); + /* Bits int the storage key */ #define _PAGE_CHANGED 0x02 /* HW changed bit */ #define _PAGE_REFERENCED 0x04 /* HW referenced bit */ diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index a32f465ecf73a..c0ff19dab5807 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -109,6 +110,7 @@ struct zpci_bus { struct list_head resources; struct list_head bus_next; struct resource bus_resource; + struct irq_domain *msi_parent_domain; int topo; /* TID if topo_is_tid, PCHID otherwise */ int domain_nr; u8 multifunction : 1; @@ -310,6 +312,9 @@ int zpci_dma_exit_device(struct zpci_dev *zdev); /* IRQ */ int __init zpci_irq_init(void); void __init zpci_irq_exit(void); +int zpci_set_irq(struct zpci_dev *zdev); +int zpci_create_parent_msi_domain(struct zpci_bus *zbus); +void zpci_remove_parent_msi_domain(struct zpci_bus *zbus); /* FMB */ int zpci_fmb_enable_device(struct zpci_dev *); diff --git a/arch/s390/include/asm/stacktrace.h b/arch/s390/include/asm/stacktrace.h index 810a6b9d96280..c9ae680a28af9 100644 --- a/arch/s390/include/asm/stacktrace.h +++ b/arch/s390/include/asm/stacktrace.h @@ -66,6 +66,7 @@ struct stack_frame { unsigned long sie_flags; unsigned long sie_control_block_phys; unsigned long sie_guest_asce; + unsigned long sie_irq; }; }; unsigned long gprs[10]; diff --git a/arch/s390/include/uapi/asm/ipl.h b/arch/s390/include/uapi/asm/ipl.h index 2cd28af50dd43..3d64a22516994 100644 --- a/arch/s390/include/uapi/asm/ipl.h +++ b/arch/s390/include/uapi/asm/ipl.h @@ -15,6 +15,7 @@ struct ipl_pl_hdr { #define IPL_PL_FLAG_IPLPS 0x80 #define IPL_PL_FLAG_SIPL 0x40 #define IPL_PL_FLAG_IPLSR 0x20 +#define IPL_PL_FLAG_SBP 0x10 /* IPL Parameter Block header */ struct ipl_pb_hdr { diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index cfe27f6579e33..e1a5b5b54e4f8 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -67,6 +67,7 @@ int main(void) OFFSET(__SF_SIE_FLAGS, stack_frame, sie_flags); OFFSET(__SF_SIE_CONTROL_PHYS, stack_frame, sie_control_block_phys); OFFSET(__SF_SIE_GUEST_ASCE, stack_frame, sie_guest_asce); + OFFSET(__SF_SIE_IRQ, stack_frame, sie_irq); DEFINE(STACK_FRAME_OVERHEAD, sizeof(struct stack_frame)); BLANK(); OFFSET(__SFUSER_BACKCHAIN, stack_frame_user, back_chain); diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index c360087807d8a..b7f1553d9ee5b 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -193,6 +193,7 @@ SYM_FUNC_START(__sie64a) mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r14) # copy thread flags lmg %r0,%r13,0(%r4) # load guest gprs 0-13 mvi __TI_sie(%r14),1 + stosm __SF_SIE_IRQ(%r15),0x03 # enable interrupts lctlg %c1,%c1,__SF_SIE_GUEST_ASCE(%r15) # load primary asce lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now @@ -216,6 +217,7 @@ SYM_FUNC_START(__sie64a) lg %r14,__LC_CURRENT(%r14) mvi __TI_sie(%r14),0 SYM_INNER_LABEL(sie_exit, SYM_L_GLOBAL) + stnsm __SF_SIE_IRQ(%r15),0xfc # disable interrupts lg %r14,__SF_SIE_SAVEAREA(%r15) # load guest register save area stmg %r0,%r13,0(%r14) # save guest gprs 0-13 xgr %r0,%r0 # clear guest registers to diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 961a3d60a4ddd..dcdc7e2748486 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -262,6 +262,24 @@ static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ sys_##_prefix##_##_name##_show, \ sys_##_prefix##_##_name##_store) +#define DEFINE_IPL_ATTR_BOOTPROG_RW(_prefix, _name, _fmt_out, _fmt_in, _hdr, _value) \ + IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, (unsigned long long) _value) \ +static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \ + struct kobj_attribute *attr, \ + const char *buf, size_t len) \ +{ \ + unsigned long long value; \ + if (sscanf(buf, _fmt_in, &value) != 1) \ + return -EINVAL; \ + (_value) = value; \ + (_hdr).flags &= ~IPL_PL_FLAG_SBP; \ + return len; \ +} \ +static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ + __ATTR(_name, 0644, \ + sys_##_prefix##_##_name##_show, \ + sys_##_prefix##_##_name##_store) + #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\ IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, _value) \ static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \ @@ -818,12 +836,13 @@ DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%llx\n", reipl_block_fcp->fcp.wwpn); DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n", reipl_block_fcp->fcp.lun); -DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n", - reipl_block_fcp->fcp.bootprog); DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n", reipl_block_fcp->fcp.br_lba); DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", reipl_block_fcp->fcp.devno); +DEFINE_IPL_ATTR_BOOTPROG_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n", + reipl_block_fcp->hdr, + reipl_block_fcp->fcp.bootprog); static void reipl_get_ascii_loadparm(char *loadparm, struct ipl_parameter_block *ibp) @@ -942,10 +961,11 @@ DEFINE_IPL_ATTR_RW(reipl_nvme, fid, "0x%08llx\n", "%llx\n", reipl_block_nvme->nvme.fid); DEFINE_IPL_ATTR_RW(reipl_nvme, nsid, "0x%08llx\n", "%llx\n", reipl_block_nvme->nvme.nsid); -DEFINE_IPL_ATTR_RW(reipl_nvme, bootprog, "%lld\n", "%lld\n", - reipl_block_nvme->nvme.bootprog); DEFINE_IPL_ATTR_RW(reipl_nvme, br_lba, "%lld\n", "%lld\n", reipl_block_nvme->nvme.br_lba); +DEFINE_IPL_ATTR_BOOTPROG_RW(reipl_nvme, bootprog, "%lld\n", "%lld\n", + reipl_block_nvme->hdr, + reipl_block_nvme->nvme.bootprog); static struct attribute *reipl_nvme_attrs[] = { &sys_reipl_nvme_fid_attr.attr, @@ -1038,8 +1058,9 @@ static const struct bin_attribute *const reipl_eckd_bin_attrs[] = { }; DEFINE_IPL_CCW_ATTR_RW(reipl_eckd, device, reipl_block_eckd->eckd); -DEFINE_IPL_ATTR_RW(reipl_eckd, bootprog, "%lld\n", "%lld\n", - reipl_block_eckd->eckd.bootprog); +DEFINE_IPL_ATTR_BOOTPROG_RW(reipl_eckd, bootprog, "%lld\n", "%lld\n", + reipl_block_eckd->hdr, + reipl_block_eckd->eckd.bootprog); static struct attribute *reipl_eckd_attrs[] = { &sys_reipl_eckd_device_attr.attr, @@ -1567,12 +1588,13 @@ DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%llx\n", dump_block_fcp->fcp.wwpn); DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n", dump_block_fcp->fcp.lun); -DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", - dump_block_fcp->fcp.bootprog); DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n", dump_block_fcp->fcp.br_lba); DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", dump_block_fcp->fcp.devno); +DEFINE_IPL_ATTR_BOOTPROG_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", + dump_block_fcp->hdr, + dump_block_fcp->fcp.bootprog); DEFINE_IPL_ATTR_SCP_DATA_RW(dump_fcp, dump_block_fcp->hdr, dump_block_fcp->fcp, @@ -1604,10 +1626,11 @@ DEFINE_IPL_ATTR_RW(dump_nvme, fid, "0x%08llx\n", "%llx\n", dump_block_nvme->nvme.fid); DEFINE_IPL_ATTR_RW(dump_nvme, nsid, "0x%08llx\n", "%llx\n", dump_block_nvme->nvme.nsid); -DEFINE_IPL_ATTR_RW(dump_nvme, bootprog, "%lld\n", "%llx\n", - dump_block_nvme->nvme.bootprog); DEFINE_IPL_ATTR_RW(dump_nvme, br_lba, "%lld\n", "%llx\n", dump_block_nvme->nvme.br_lba); +DEFINE_IPL_ATTR_BOOTPROG_RW(dump_nvme, bootprog, "%lld\n", "%llx\n", + dump_block_nvme->hdr, + dump_block_nvme->nvme.bootprog); DEFINE_IPL_ATTR_SCP_DATA_RW(dump_nvme, dump_block_nvme->hdr, dump_block_nvme->nvme, @@ -1635,8 +1658,9 @@ static const struct attribute_group dump_nvme_attr_group = { /* ECKD dump device attributes */ DEFINE_IPL_CCW_ATTR_RW(dump_eckd, device, dump_block_eckd->eckd); -DEFINE_IPL_ATTR_RW(dump_eckd, bootprog, "%lld\n", "%llx\n", - dump_block_eckd->eckd.bootprog); +DEFINE_IPL_ATTR_BOOTPROG_RW(dump_eckd, bootprog, "%lld\n", "%llx\n", + dump_block_eckd->hdr, + dump_block_eckd->eckd.bootprog); IPL_ATTR_BR_CHR_SHOW_FN(dump, dump_block_eckd->eckd); IPL_ATTR_BR_CHR_STORE_FN(dump, dump_block_eckd->eckd); diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index 3aae7f70e6ab1..18520d3330581 100644 --- a/arch/s390/kernel/stacktrace.c +++ b/arch/s390/kernel/stacktrace.c @@ -104,7 +104,6 @@ void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *coo struct stack_frame_vdso_wrapper __user *sf_vdso; struct stack_frame_user __user *sf; unsigned long ip, sp; - bool first = true; if (!current->mm) return; @@ -133,24 +132,11 @@ void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *coo if (__get_user(ip, &sf->gprs[8])) break; } - /* Sanity check: ABI requires SP to be 8 byte aligned. */ - if (sp & 0x7) + /* Validate SP and RA (ABI requires SP to be 8 byte aligned). */ + if (sp & 0x7 || ip_invalid(ip)) break; - 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) - break; - ip = regs->gprs[14]; - if (ip_invalid(ip)) - break; - } if (!store_ip(consume_entry, cookie, entry, perf, ip)) break; - first = false; } pagefault_enable(); } diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index cae908d645501..f4ec8c1ce2149 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig @@ -20,7 +20,6 @@ config KVM def_tristate y prompt "Kernel-based Virtual Machine (KVM) support" select HAVE_KVM_CPU_RELAX_INTERCEPT - select HAVE_KVM_VCPU_ASYNC_IOCTL select KVM_ASYNC_PF select KVM_ASYNC_PF_SYNC select KVM_COMMON @@ -30,6 +29,7 @@ config KVM select HAVE_KVM_NO_POLL select KVM_VFIO select MMU_NOTIFIER + select VIRT_XFER_TO_GUEST_WORK help Support hosting paravirtualized guest machines using the SIE virtualization capability on the mainframe. This should work diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 21c2e61fece43..41ca6b0ee7a92 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -109,14 +109,9 @@ struct aste { int ipte_lock_held(struct kvm *kvm) { - if (sclp.has_siif) { - int rc; + if (sclp.has_siif) + return kvm->arch.sca->ipte_control.kh != 0; - read_lock(&kvm->arch.sca_lock); - rc = kvm_s390_get_ipte_control(kvm)->kh != 0; - read_unlock(&kvm->arch.sca_lock); - return rc; - } return kvm->arch.ipte_lock_count != 0; } @@ -129,19 +124,16 @@ static void ipte_lock_simple(struct kvm *kvm) if (kvm->arch.ipte_lock_count > 1) goto out; retry: - read_lock(&kvm->arch.sca_lock); - ic = kvm_s390_get_ipte_control(kvm); + ic = &kvm->arch.sca->ipte_control; old = READ_ONCE(*ic); do { if (old.k) { - read_unlock(&kvm->arch.sca_lock); cond_resched(); goto retry; } new = old; new.k = 1; } while (!try_cmpxchg(&ic->val, &old.val, new.val)); - read_unlock(&kvm->arch.sca_lock); out: mutex_unlock(&kvm->arch.ipte_mutex); } @@ -154,14 +146,12 @@ static void ipte_unlock_simple(struct kvm *kvm) kvm->arch.ipte_lock_count--; if (kvm->arch.ipte_lock_count) goto out; - read_lock(&kvm->arch.sca_lock); - ic = kvm_s390_get_ipte_control(kvm); + ic = &kvm->arch.sca->ipte_control; old = READ_ONCE(*ic); do { new = old; new.k = 0; } while (!try_cmpxchg(&ic->val, &old.val, new.val)); - read_unlock(&kvm->arch.sca_lock); wake_up(&kvm->arch.ipte_wq); out: mutex_unlock(&kvm->arch.ipte_mutex); @@ -172,12 +162,10 @@ static void ipte_lock_siif(struct kvm *kvm) union ipte_control old, new, *ic; retry: - read_lock(&kvm->arch.sca_lock); - ic = kvm_s390_get_ipte_control(kvm); + ic = &kvm->arch.sca->ipte_control; old = READ_ONCE(*ic); do { if (old.kg) { - read_unlock(&kvm->arch.sca_lock); cond_resched(); goto retry; } @@ -185,15 +173,13 @@ static void ipte_lock_siif(struct kvm *kvm) new.k = 1; new.kh++; } while (!try_cmpxchg(&ic->val, &old.val, new.val)); - read_unlock(&kvm->arch.sca_lock); } static void ipte_unlock_siif(struct kvm *kvm) { union ipte_control old, new, *ic; - read_lock(&kvm->arch.sca_lock); - ic = kvm_s390_get_ipte_control(kvm); + ic = &kvm->arch.sca->ipte_control; old = READ_ONCE(*ic); do { new = old; @@ -201,7 +187,6 @@ static void ipte_unlock_siif(struct kvm *kvm) if (!new.kh) new.k = 0; } while (!try_cmpxchg(&ic->val, &old.val, new.val)); - read_unlock(&kvm->arch.sca_lock); if (!new.kh) wake_up(&kvm->arch.ipte_wq); } diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index c7908950c1f44..420ae62977e2e 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c @@ -471,6 +471,9 @@ static int handle_operexc(struct kvm_vcpu *vcpu) if (vcpu->arch.sie_block->ipa == 0xb256) return handle_sthyi(vcpu); + if (vcpu->kvm->arch.user_operexec) + return -EOPNOTSUPP; + if (vcpu->arch.sie_block->ipa == 0 && vcpu->kvm->arch.user_instr0) return -EOPNOTSUPP; rc = read_guest_lc(vcpu, __LC_PGM_NEW_PSW, &newpsw, sizeof(psw_t)); diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index f55574af98cc7..249cdc822ec52 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -44,70 +44,34 @@ static struct kvm_s390_gib *gib; /* handle external calls via sigp interpretation facility */ static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id) { - int c, scn; + struct esca_block *sca = vcpu->kvm->arch.sca; + union esca_sigp_ctrl sigp_ctrl = sca->cpu[vcpu->vcpu_id].sigp_ctrl; if (!kvm_s390_test_cpuflags(vcpu, CPUSTAT_ECALL_PEND)) return 0; BUG_ON(!kvm_s390_use_sca_entries()); - read_lock(&vcpu->kvm->arch.sca_lock); - if (vcpu->kvm->arch.use_esca) { - struct esca_block *sca = vcpu->kvm->arch.sca; - union esca_sigp_ctrl sigp_ctrl = - sca->cpu[vcpu->vcpu_id].sigp_ctrl; - - c = sigp_ctrl.c; - scn = sigp_ctrl.scn; - } else { - struct bsca_block *sca = vcpu->kvm->arch.sca; - union bsca_sigp_ctrl sigp_ctrl = - sca->cpu[vcpu->vcpu_id].sigp_ctrl; - - c = sigp_ctrl.c; - scn = sigp_ctrl.scn; - } - read_unlock(&vcpu->kvm->arch.sca_lock); if (src_id) - *src_id = scn; + *src_id = sigp_ctrl.scn; - return c; + return sigp_ctrl.c; } static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id) { + struct esca_block *sca = vcpu->kvm->arch.sca; + union esca_sigp_ctrl *sigp_ctrl = &sca->cpu[vcpu->vcpu_id].sigp_ctrl; + union esca_sigp_ctrl old_val, new_val = {.scn = src_id, .c = 1}; int expect, rc; BUG_ON(!kvm_s390_use_sca_entries()); - read_lock(&vcpu->kvm->arch.sca_lock); - if (vcpu->kvm->arch.use_esca) { - struct esca_block *sca = vcpu->kvm->arch.sca; - union esca_sigp_ctrl *sigp_ctrl = - &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); - union esca_sigp_ctrl new_val = {0}, old_val; - - old_val = READ_ONCE(*sigp_ctrl); - new_val.scn = src_id; - new_val.c = 1; - old_val.c = 0; - - expect = old_val.value; - rc = cmpxchg(&sigp_ctrl->value, old_val.value, new_val.value); - } else { - struct bsca_block *sca = vcpu->kvm->arch.sca; - union bsca_sigp_ctrl *sigp_ctrl = - &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); - union bsca_sigp_ctrl new_val = {0}, old_val; - old_val = READ_ONCE(*sigp_ctrl); - new_val.scn = src_id; - new_val.c = 1; - old_val.c = 0; + old_val = READ_ONCE(*sigp_ctrl); + old_val.c = 0; - expect = old_val.value; - rc = cmpxchg(&sigp_ctrl->value, old_val.value, new_val.value); - } - read_unlock(&vcpu->kvm->arch.sca_lock); + expect = old_val.value; + rc = cmpxchg(&sigp_ctrl->value, old_val.value, new_val.value); if (rc != expect) { /* another external call is pending */ @@ -119,24 +83,14 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id) static void sca_clear_ext_call(struct kvm_vcpu *vcpu) { + struct esca_block *sca = vcpu->kvm->arch.sca; + union esca_sigp_ctrl *sigp_ctrl = &sca->cpu[vcpu->vcpu_id].sigp_ctrl; + if (!kvm_s390_use_sca_entries()) return; kvm_s390_clear_cpuflags(vcpu, CPUSTAT_ECALL_PEND); - read_lock(&vcpu->kvm->arch.sca_lock); - if (vcpu->kvm->arch.use_esca) { - struct esca_block *sca = vcpu->kvm->arch.sca; - union esca_sigp_ctrl *sigp_ctrl = - &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); - - WRITE_ONCE(sigp_ctrl->value, 0); - } else { - struct bsca_block *sca = vcpu->kvm->arch.sca; - union bsca_sigp_ctrl *sigp_ctrl = - &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); - WRITE_ONCE(sigp_ctrl->value, 0); - } - read_unlock(&vcpu->kvm->arch.sca_lock); + WRITE_ONCE(sigp_ctrl->value, 0); } int psw_extint_disabled(struct kvm_vcpu *vcpu) @@ -1223,7 +1177,7 @@ int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu) { struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; - if (!sclp.has_sigpif) + if (!kvm_s390_use_sca_entries()) return test_bit(IRQ_PEND_EXT_EXTERNAL, &li->pending_irqs); return sca_ext_call_pending(vcpu, NULL); @@ -1548,7 +1502,7 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) if (kvm_get_vcpu_by_id(vcpu->kvm, src_id) == NULL) return -EINVAL; - if (sclp.has_sigpif && !kvm_s390_pv_cpu_get_handle(vcpu)) + if (kvm_s390_use_sca_entries() && !kvm_s390_pv_cpu_get_handle(vcpu)) return sca_inject_ext_call(vcpu, src_id); if (test_and_set_bit(IRQ_PEND_EXT_EXTERNAL, &li->pending_irqs)) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ff3a185f156c9..56a50524b3eee 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -13,6 +13,7 @@ #define pr_fmt(fmt) "kvm-s390: " fmt #include +#include #include #include #include @@ -184,7 +185,8 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { STATS_DESC_COUNTER(VCPU, instruction_diagnose_308), STATS_DESC_COUNTER(VCPU, instruction_diagnose_500), STATS_DESC_COUNTER(VCPU, instruction_diagnose_other), - STATS_DESC_COUNTER(VCPU, pfault_sync) + STATS_DESC_COUNTER(VCPU, pfault_sync), + STATS_DESC_COUNTER(VCPU, signal_exits) }; const struct kvm_stats_header kvm_vcpu_stats_header = { @@ -271,7 +273,6 @@ debug_info_t *kvm_s390_dbf_uv; /* forward declarations */ static void kvm_gmap_notifier(struct gmap *gmap, unsigned long start, unsigned long end); -static int sca_switch_to_extended(struct kvm *kvm); static void kvm_clock_sync_scb(struct kvm_s390_sie_block *scb, u64 delta) { @@ -606,6 +607,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_SET_GUEST_DEBUG: case KVM_CAP_S390_DIAG318: case KVM_CAP_IRQFD_RESAMPLE: + case KVM_CAP_S390_USER_OPEREXEC: r = 1; break; case KVM_CAP_SET_GUEST_DEBUG2: @@ -631,11 +633,13 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_NR_VCPUS: case KVM_CAP_MAX_VCPUS: case KVM_CAP_MAX_VCPU_ID: - r = KVM_S390_BSCA_CPU_SLOTS; + /* + * Return the same value for KVM_CAP_MAX_VCPUS and + * KVM_CAP_MAX_VCPU_ID to conform with the KVM API. + */ + r = KVM_S390_ESCA_CPU_SLOTS; if (!kvm_s390_use_sca_entries()) r = KVM_MAX_VCPUS; - else if (sclp.has_esca && sclp.has_64bscao) - r = KVM_S390_ESCA_CPU_SLOTS; if (ext == KVM_CAP_NR_VCPUS) r = min_t(unsigned int, num_online_cpus(), r); break; @@ -919,6 +923,12 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) VM_EVENT(kvm, 3, "ENABLE: CAP_S390_CPU_TOPOLOGY %s", r ? "(not available)" : "(success)"); break; + case KVM_CAP_S390_USER_OPEREXEC: + VM_EVENT(kvm, 3, "%s", "ENABLE: CAP_S390_USER_OPEREXEC"); + kvm->arch.user_operexec = 1; + icpt_operexc_on_all_vcpus(kvm); + r = 0; + break; default: r = -EINVAL; break; @@ -1930,22 +1940,18 @@ static int kvm_s390_get_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) * Updates the Multiprocessor Topology-Change-Report bit to signal * the guest with a topology change. * This is only relevant if the topology facility is present. - * - * The SCA version, bsca or esca, doesn't matter as offset is the same. */ static void kvm_s390_update_topology_change_report(struct kvm *kvm, bool val) { union sca_utility new, old; - struct bsca_block *sca; + struct esca_block *sca; - read_lock(&kvm->arch.sca_lock); sca = kvm->arch.sca; old = READ_ONCE(sca->utility); do { new = old; new.mtcr = val; } while (!try_cmpxchg(&sca->utility.val, &old.val, new.val)); - read_unlock(&kvm->arch.sca_lock); } static int kvm_s390_set_topo_change_indication(struct kvm *kvm, @@ -1966,9 +1972,7 @@ static int kvm_s390_get_topo_change_indication(struct kvm *kvm, if (!test_kvm_facility(kvm, 11)) return -ENXIO; - read_lock(&kvm->arch.sca_lock); - topo = ((struct bsca_block *)kvm->arch.sca)->utility.mtcr; - read_unlock(&kvm->arch.sca_lock); + topo = kvm->arch.sca->utility.mtcr; return put_user(topo, (u8 __user *)attr->addr); } @@ -2666,14 +2670,6 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd) if (kvm_s390_pv_is_protected(kvm)) break; - /* - * FMT 4 SIE needs esca. As we never switch back to bsca from - * esca, we need no cleanup in the error cases below - */ - r = sca_switch_to_extended(kvm); - if (r) - break; - mmap_write_lock(kvm->mm); r = gmap_helper_disable_cow_sharing(); mmap_write_unlock(kvm->mm); @@ -3316,10 +3312,7 @@ static void kvm_s390_crypto_init(struct kvm *kvm) static void sca_dispose(struct kvm *kvm) { - if (kvm->arch.use_esca) - free_pages_exact(kvm->arch.sca, sizeof(struct esca_block)); - else - free_page((unsigned long)(kvm->arch.sca)); + free_pages_exact(kvm->arch.sca, sizeof(*kvm->arch.sca)); kvm->arch.sca = NULL; } @@ -3333,10 +3326,9 @@ void kvm_arch_free_vm(struct kvm *kvm) int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) { - gfp_t alloc_flags = GFP_KERNEL_ACCOUNT; - int i, rc; + gfp_t alloc_flags = GFP_KERNEL_ACCOUNT | __GFP_ZERO; char debug_name[16]; - static unsigned long sca_offset; + int i, rc; rc = -EINVAL; #ifdef CONFIG_KVM_S390_UCONTROL @@ -3357,20 +3349,14 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (!sclp.has_64bscao) alloc_flags |= GFP_DMA; - rwlock_init(&kvm->arch.sca_lock); - /* start with basic SCA */ - kvm->arch.sca = (struct bsca_block *) get_zeroed_page(alloc_flags); - if (!kvm->arch.sca) - goto out_err; mutex_lock(&kvm_lock); - sca_offset += 16; - if (sca_offset + sizeof(struct bsca_block) > PAGE_SIZE) - sca_offset = 0; - kvm->arch.sca = (struct bsca_block *) - ((char *) kvm->arch.sca + sca_offset); + + kvm->arch.sca = alloc_pages_exact(sizeof(*kvm->arch.sca), alloc_flags); mutex_unlock(&kvm_lock); + if (!kvm->arch.sca) + goto out_err; - sprintf(debug_name, "kvm-%u", current->pid); + snprintf(debug_name, sizeof(debug_name), "kvm-%u", current->pid); kvm->arch.dbf = debug_register(debug_name, 32, 1, 7 * sizeof(long)); if (!kvm->arch.dbf) @@ -3547,133 +3533,38 @@ static int __kvm_ucontrol_vcpu_init(struct kvm_vcpu *vcpu) static void sca_del_vcpu(struct kvm_vcpu *vcpu) { + struct esca_block *sca = vcpu->kvm->arch.sca; + if (!kvm_s390_use_sca_entries()) return; - read_lock(&vcpu->kvm->arch.sca_lock); - if (vcpu->kvm->arch.use_esca) { - struct esca_block *sca = vcpu->kvm->arch.sca; - clear_bit_inv(vcpu->vcpu_id, (unsigned long *) sca->mcn); - sca->cpu[vcpu->vcpu_id].sda = 0; - } else { - struct bsca_block *sca = vcpu->kvm->arch.sca; - - clear_bit_inv(vcpu->vcpu_id, (unsigned long *) &sca->mcn); - sca->cpu[vcpu->vcpu_id].sda = 0; - } - read_unlock(&vcpu->kvm->arch.sca_lock); + clear_bit_inv(vcpu->vcpu_id, (unsigned long *)sca->mcn); + sca->cpu[vcpu->vcpu_id].sda = 0; } static void sca_add_vcpu(struct kvm_vcpu *vcpu) { - if (!kvm_s390_use_sca_entries()) { - phys_addr_t sca_phys = virt_to_phys(vcpu->kvm->arch.sca); - - /* we still need the basic sca for the ipte control */ - vcpu->arch.sie_block->scaoh = sca_phys >> 32; - vcpu->arch.sie_block->scaol = sca_phys; - return; - } - read_lock(&vcpu->kvm->arch.sca_lock); - if (vcpu->kvm->arch.use_esca) { - struct esca_block *sca = vcpu->kvm->arch.sca; - phys_addr_t sca_phys = virt_to_phys(sca); - - sca->cpu[vcpu->vcpu_id].sda = virt_to_phys(vcpu->arch.sie_block); - vcpu->arch.sie_block->scaoh = sca_phys >> 32; - vcpu->arch.sie_block->scaol = sca_phys & ESCA_SCAOL_MASK; - vcpu->arch.sie_block->ecb2 |= ECB2_ESCA; - set_bit_inv(vcpu->vcpu_id, (unsigned long *) sca->mcn); - } else { - struct bsca_block *sca = vcpu->kvm->arch.sca; - phys_addr_t sca_phys = virt_to_phys(sca); - - sca->cpu[vcpu->vcpu_id].sda = virt_to_phys(vcpu->arch.sie_block); - vcpu->arch.sie_block->scaoh = sca_phys >> 32; - vcpu->arch.sie_block->scaol = sca_phys; - set_bit_inv(vcpu->vcpu_id, (unsigned long *) &sca->mcn); - } - read_unlock(&vcpu->kvm->arch.sca_lock); -} - -/* Basic SCA to Extended SCA data copy routines */ -static inline void sca_copy_entry(struct esca_entry *d, struct bsca_entry *s) -{ - d->sda = s->sda; - d->sigp_ctrl.c = s->sigp_ctrl.c; - d->sigp_ctrl.scn = s->sigp_ctrl.scn; -} - -static void sca_copy_b_to_e(struct esca_block *d, struct bsca_block *s) -{ - int i; + struct esca_block *sca = vcpu->kvm->arch.sca; + phys_addr_t sca_phys = virt_to_phys(sca); - d->ipte_control = s->ipte_control; - d->mcn[0] = s->mcn; - for (i = 0; i < KVM_S390_BSCA_CPU_SLOTS; i++) - sca_copy_entry(&d->cpu[i], &s->cpu[i]); -} + /* we still need the sca header for the ipte control */ + vcpu->arch.sie_block->scaoh = sca_phys >> 32; + vcpu->arch.sie_block->scaol = sca_phys & ESCA_SCAOL_MASK; + vcpu->arch.sie_block->ecb2 |= ECB2_ESCA; -static int sca_switch_to_extended(struct kvm *kvm) -{ - struct bsca_block *old_sca = kvm->arch.sca; - struct esca_block *new_sca; - struct kvm_vcpu *vcpu; - unsigned long vcpu_idx; - u32 scaol, scaoh; - phys_addr_t new_sca_phys; - - if (kvm->arch.use_esca) - return 0; - - new_sca = alloc_pages_exact(sizeof(*new_sca), GFP_KERNEL_ACCOUNT | __GFP_ZERO); - if (!new_sca) - return -ENOMEM; - - new_sca_phys = virt_to_phys(new_sca); - scaoh = new_sca_phys >> 32; - scaol = new_sca_phys & ESCA_SCAOL_MASK; - - kvm_s390_vcpu_block_all(kvm); - write_lock(&kvm->arch.sca_lock); - - sca_copy_b_to_e(new_sca, old_sca); - - kvm_for_each_vcpu(vcpu_idx, vcpu, kvm) { - vcpu->arch.sie_block->scaoh = scaoh; - vcpu->arch.sie_block->scaol = scaol; - vcpu->arch.sie_block->ecb2 |= ECB2_ESCA; - } - kvm->arch.sca = new_sca; - kvm->arch.use_esca = 1; - - write_unlock(&kvm->arch.sca_lock); - kvm_s390_vcpu_unblock_all(kvm); - - free_page((unsigned long)old_sca); + if (!kvm_s390_use_sca_entries()) + return; - VM_EVENT(kvm, 2, "Switched to ESCA (0x%p -> 0x%p)", - old_sca, kvm->arch.sca); - return 0; + set_bit_inv(vcpu->vcpu_id, (unsigned long *)sca->mcn); + sca->cpu[vcpu->vcpu_id].sda = virt_to_phys(vcpu->arch.sie_block); } static int sca_can_add_vcpu(struct kvm *kvm, unsigned int id) { - int rc; - - if (!kvm_s390_use_sca_entries()) { - if (id < KVM_MAX_VCPUS) - return true; - return false; - } - if (id < KVM_S390_BSCA_CPU_SLOTS) - return true; - if (!sclp.has_esca || !sclp.has_64bscao) - return false; - - rc = kvm->arch.use_esca ? 0 : sca_switch_to_extended(kvm); + if (!kvm_s390_use_sca_entries()) + return id < KVM_MAX_VCPUS; - return rc == 0 && id < KVM_S390_ESCA_CPU_SLOTS; + return id < KVM_S390_ESCA_CPU_SLOTS; } /* needs disabled preemption to protect from TOD sync and vcpu_load/put */ @@ -3919,7 +3810,7 @@ static int kvm_s390_vcpu_setup(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->eca |= ECA_IB; if (sclp.has_siif) vcpu->arch.sie_block->eca |= ECA_SII; - if (sclp.has_sigpif) + if (kvm_s390_use_sca_entries()) vcpu->arch.sie_block->eca |= ECA_SIGPI; if (test_kvm_facility(vcpu->kvm, 129)) { vcpu->arch.sie_block->eca |= ECA_VX; @@ -4366,8 +4257,6 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { - int ret = 0; - vcpu_load(vcpu); vcpu->run->s.regs.fpc = fpu->fpc; @@ -4378,7 +4267,7 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) memcpy(vcpu->run->s.regs.fprs, &fpu->fprs, sizeof(fpu->fprs)); vcpu_put(vcpu); - return ret; + return 0; } int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) @@ -4786,9 +4675,6 @@ static int vcpu_pre_run(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->gg14 = vcpu->run->s.regs.gprs[14]; vcpu->arch.sie_block->gg15 = vcpu->run->s.regs.gprs[15]; - if (need_resched()) - schedule(); - if (!kvm_is_ucontrol(vcpu->kvm)) { rc = kvm_s390_deliver_pending_interrupts(vcpu); if (rc || guestdbg_exit_pending(vcpu)) @@ -5073,13 +4959,8 @@ int noinstr kvm_s390_enter_exit_sie(struct kvm_s390_sie_block *scb, * The guest_state_{enter,exit}_irqoff() functions inform lockdep and * tracing that entry to the guest will enable host IRQs, and exit from * the guest will disable host IRQs. - * - * We must not use lockdep/tracing/RCU in this critical section, so we - * use the low-level arch_local_irq_*() helpers to enable/disable IRQs. */ - arch_local_irq_enable(); ret = sie64a(scb, gprs, gasce); - arch_local_irq_disable(); guest_state_exit_irqoff(); @@ -5098,12 +4979,12 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) */ kvm_vcpu_srcu_read_lock(vcpu); - do { + while (true) { rc = vcpu_pre_run(vcpu); + kvm_vcpu_srcu_read_unlock(vcpu); if (rc || guestdbg_exit_pending(vcpu)) break; - kvm_vcpu_srcu_read_unlock(vcpu); /* * As PF_VCPU will be used in fault handler, between * guest_timing_enter_irqoff and guest_timing_exit_irqoff @@ -5115,7 +4996,17 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) sizeof(sie_page->pv_grregs)); } +xfer_to_guest_mode_check: local_irq_disable(); + xfer_to_guest_mode_prepare(); + if (xfer_to_guest_mode_work_pending()) { + local_irq_enable(); + rc = kvm_xfer_to_guest_mode_handle_work(vcpu); + if (rc) + break; + goto xfer_to_guest_mode_check; + } + guest_timing_enter_irqoff(); __disable_cpu_timer_accounting(vcpu); @@ -5145,9 +5036,12 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) kvm_vcpu_srcu_read_lock(vcpu); rc = vcpu_post_run(vcpu, exit_reason); - } while (!signal_pending(current) && !guestdbg_exit_pending(vcpu) && !rc); + if (rc || guestdbg_exit_pending(vcpu)) { + kvm_vcpu_srcu_read_unlock(vcpu); + break; + } + } - kvm_vcpu_srcu_read_unlock(vcpu); return rc; } @@ -5363,6 +5257,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) if (signal_pending(current) && !rc) { kvm_run->exit_reason = KVM_EXIT_INTR; + vcpu->stat.signal_exits++; rc = -EINTR; } @@ -5729,8 +5624,8 @@ static long kvm_s390_vcpu_memsida_op(struct kvm_vcpu *vcpu, return r; } -long kvm_arch_vcpu_async_ioctl(struct file *filp, - unsigned int ioctl, unsigned long arg) +long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) { struct kvm_vcpu *vcpu = filp->private_data; void __user *argp = (void __user *)arg; diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index c44fe0c3a097c..65c9507609934 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -570,13 +570,6 @@ void kvm_s390_prepare_debug_exit(struct kvm_vcpu *vcpu); int kvm_s390_handle_per_ifetch_icpt(struct kvm_vcpu *vcpu); int kvm_s390_handle_per_event(struct kvm_vcpu *vcpu); -/* support for Basic/Extended SCA handling */ -static inline union ipte_control *kvm_s390_get_ipte_control(struct kvm *kvm) -{ - struct bsca_block *sca = kvm->arch.sca; /* SCA version doesn't matter */ - - return &sca->ipte_control; -} static inline int kvm_s390_use_sca_entries(void) { /* @@ -584,7 +577,7 @@ static inline int kvm_s390_use_sca_entries(void) * might use the entries. By not setting the entries and keeping them * invalid, hardware will not access them but intercept. */ - return sclp.has_sigpif; + return sclp.has_sigpif && sclp.has_esca; } void kvm_s390_reinject_machine_check(struct kvm_vcpu *vcpu, struct mcck_volatile_info *mcck_info); diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index 347268f89f2f1..b526621d2a1b0 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -782,7 +782,7 @@ static int pin_blocks(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) else if ((gpa & ~0x1fffUL) == kvm_s390_get_prefix(vcpu)) rc = set_validity_icpt(scb_s, 0x0011U); else if ((gpa & PAGE_MASK) != - ((gpa + sizeof(struct bsca_block) - 1) & PAGE_MASK)) + ((gpa + offsetof(struct bsca_block, cpu[0]) - 1) & PAGE_MASK)) rc = set_validity_icpt(scb_s, 0x003bU); if (!rc) { rc = pin_guest_page(vcpu->kvm, gpa, &hpa); @@ -1180,12 +1180,23 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) current->thread.gmap_int_code = 0; barrier(); if (!kvm_s390_vcpu_sie_inhibited(vcpu)) { +xfer_to_guest_mode_check: local_irq_disable(); + xfer_to_guest_mode_prepare(); + if (xfer_to_guest_mode_work_pending()) { + local_irq_enable(); + rc = kvm_xfer_to_guest_mode_handle_work(vcpu); + if (rc) + goto skip_sie; + goto xfer_to_guest_mode_check; + } guest_timing_enter_irqoff(); rc = kvm_s390_enter_exit_sie(scb_s, vcpu->run->s.regs.gprs, vsie_page->gmap->asce); guest_timing_exit_irqoff(); local_irq_enable(); } + +skip_sie: barrier(); vcpu->arch.sie_block->prog0c &= ~PROG_IN_SIE; @@ -1345,13 +1356,11 @@ static int vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) * but rewind the PSW to re-enter SIE once that's completed * instead of passing a "no action" intercept to the guest. */ - if (signal_pending(current) || - kvm_s390_vcpu_has_irq(vcpu, 0) || + if (kvm_s390_vcpu_has_irq(vcpu, 0) || kvm_s390_vcpu_sie_inhibited(vcpu)) { kvm_s390_rewind_psw(vcpu, 4); break; } - cond_resched(); } if (rc == -EFAULT) { @@ -1483,8 +1492,7 @@ int kvm_s390_handle_vsie(struct kvm_vcpu *vcpu) if (unlikely(scb_addr & 0x1ffUL)) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - if (signal_pending(current) || kvm_s390_vcpu_has_irq(vcpu, 0) || - kvm_s390_vcpu_sie_inhibited(vcpu)) { + if (kvm_s390_vcpu_has_irq(vcpu, 0) || kvm_s390_vcpu_sie_inhibited(vcpu)) { kvm_s390_rewind_psw(vcpu, 4); return 0; } diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 603d9e5febb56..dd85bcca817de 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -596,8 +596,9 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr) | _SEGMENT_ENTRY_GMAP_UC | _SEGMENT_ENTRY; } else - *table = pmd_val(*pmd) & - _SEGMENT_ENTRY_HARDWARE_BITS; + *table = (pmd_val(*pmd) & + _SEGMENT_ENTRY_HARDWARE_BITS) + | _SEGMENT_ENTRY; } } else if (*table & _SEGMENT_ENTRY_PROTECT && !(pmd_val(*pmd) & _SEGMENT_ENTRY_PROTECT)) { diff --git a/arch/s390/mm/gmap_helpers.c b/arch/s390/mm/gmap_helpers.c index d4c3c36855e26..d41b19925a5ad 100644 --- a/arch/s390/mm/gmap_helpers.c +++ b/arch/s390/mm/gmap_helpers.c @@ -11,27 +11,27 @@ #include #include #include -#include +#include #include #include #include #include /** - * ptep_zap_swap_entry() - discard a swap entry. + * ptep_zap_softleaf_entry() - discard a software leaf entry. * @mm: the mm - * @entry: the swap entry that needs to be zapped + * @entry: the software leaf entry that needs to be zapped * - * Discards the given swap entry. If the swap entry was an actual swap - * entry (and not a migration entry, for example), the actual swapped + * Discards the given software leaf entry. If the leaf entry was an actual + * swap entry (and not a migration entry, for example), the actual swapped * page is also discarded from swap. */ -static void ptep_zap_swap_entry(struct mm_struct *mm, swp_entry_t entry) +static void ptep_zap_softleaf_entry(struct mm_struct *mm, softleaf_t entry) { - if (!non_swap_entry(entry)) + if (softleaf_is_swap(entry)) dec_mm_counter(mm, MM_SWAPENTS); - else if (is_migration_entry(entry)) - dec_mm_counter(mm, mm_counter(pfn_swap_entry_folio(entry))); + else if (softleaf_is_migration(entry)) + dec_mm_counter(mm, mm_counter(softleaf_to_folio(entry))); free_swap_and_cache(entry); } @@ -47,6 +47,7 @@ static void ptep_zap_swap_entry(struct mm_struct *mm, swp_entry_t entry) void gmap_helper_zap_one_page(struct mm_struct *mm, unsigned long vmaddr) { struct vm_area_struct *vma; + unsigned long pgstev; spinlock_t *ptl; pgste_t pgste; pte_t *ptep; @@ -65,9 +66,13 @@ void gmap_helper_zap_one_page(struct mm_struct *mm, unsigned long vmaddr) if (pte_swap(*ptep)) { preempt_disable(); pgste = pgste_get_lock(ptep); + pgstev = pgste_val(pgste); - ptep_zap_swap_entry(mm, pte_to_swp_entry(*ptep)); - pte_clear(mm, vmaddr, ptep); + if ((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED || + (pgstev & _PGSTE_GPS_ZERO)) { + ptep_zap_softleaf_entry(mm, softleaf_from_pte(*ptep)); + pte_clear(mm, vmaddr, ptep); + } pgste_set_unlock(ptep, pgste); preempt_enable(); diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index 3042647c9dbf4..d3ce04a4b2486 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c @@ -204,7 +204,7 @@ static int walk_pmd_level(pud_t *pudp, unsigned long addr, unsigned long end, return rc; } -static int split_pud_page(pud_t *pudp, unsigned long addr) +int split_pud_page(pud_t *pudp, unsigned long addr) { unsigned long pmd_addr, prot; pmd_t *pm_dir, *pmdp; diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 7ae77df276b5a..666adcd681aba 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -673,12 +673,12 @@ void ptep_unshadow_pte(struct mm_struct *mm, unsigned long saddr, pte_t *ptep) pgste_set_unlock(ptep, pgste); } -static void ptep_zap_swap_entry(struct mm_struct *mm, swp_entry_t entry) +static void ptep_zap_softleaf_entry(struct mm_struct *mm, softleaf_t entry) { - if (!non_swap_entry(entry)) + if (softleaf_is_swap(entry)) dec_mm_counter(mm, MM_SWAPENTS); - else if (is_migration_entry(entry)) { - struct folio *folio = pfn_swap_entry_folio(entry); + else if (softleaf_is_migration(entry)) { + struct folio *folio = softleaf_to_folio(entry); dec_mm_counter(mm, mm_counter(folio)); } @@ -700,7 +700,7 @@ void ptep_zap_unused(struct mm_struct *mm, unsigned long addr, if (!reset && pte_swap(pte) && ((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED || (pgstev & _PGSTE_GPS_ZERO))) { - ptep_zap_swap_entry(mm, pte_to_swp_entry(pte)); + ptep_zap_softleaf_entry(mm, softleaf_from_pte(pte)); pte_clear(mm, addr, ptep); } if (reset) diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index d96587b84e81f..eeadff45e0e10 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -330,10 +330,14 @@ static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end, if (pud_leaf(*pud)) { if (IS_ALIGNED(addr, PUD_SIZE) && IS_ALIGNED(next, PUD_SIZE)) { + if (!direct) + vmem_free_pages(pud_deref(*pud), get_order(PUD_SIZE), altmap); pud_clear(pud); pages++; + continue; + } else { + split_pud_page(pud, addr & PUD_MASK); } - continue; } } else if (pud_none(*pud)) { if (IS_ALIGNED(addr, PUD_SIZE) && @@ -433,9 +437,15 @@ static int modify_pagetable(unsigned long start, unsigned long end, bool add, if (WARN_ON_ONCE(!PAGE_ALIGNED(start | end))) return -EINVAL; - /* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */ + /* Don't mess with any tables not fully in 1:1 mapping, vmemmap & kasan area */ +#ifdef CONFIG_KASAN + if (WARN_ON_ONCE(!(start >= KASAN_SHADOW_START && end <= KASAN_SHADOW_END) && + end > __abs_lowcore)) + return -EINVAL; +#else if (WARN_ON_ONCE(end > __abs_lowcore)) return -EINVAL; +#endif for (addr = start; addr < end; addr = next) { next = pgd_addr_end(addr, end); pgd = pgd_offset_k(addr); diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 93d2c9c780fce..57f3980b98a92 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -708,6 +708,12 @@ int zpci_reenable_device(struct zpci_dev *zdev) if (rc) return rc; + if (zdev->msi_nr_irqs > 0) { + rc = zpci_set_irq(zdev); + if (rc) + return rc; + } + rc = zpci_iommu_register_ioat(zdev, &status); if (rc) zpci_disable_device(zdev); @@ -955,6 +961,7 @@ void zpci_device_reserved(struct zpci_dev *zdev) } void zpci_release_device(struct kref *kref) + __releases(&zpci_list_lock) { struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref); @@ -1142,6 +1149,7 @@ static void zpci_add_devices(struct list_head *scan_list) int zpci_scan_devices(void) { + struct zpci_bus *zbus; LIST_HEAD(scan_list); int rc; @@ -1150,7 +1158,10 @@ int zpci_scan_devices(void) return rc; zpci_add_devices(&scan_list); - zpci_bus_scan_busses(); + zpci_bus_for_each(zbus) { + zpci_bus_scan_bus(zbus); + cond_resched(); + } return 0; } diff --git a/arch/s390/pci/pci_bus.c b/arch/s390/pci/pci_bus.c index 72adc8f6e94f7..42a13e451f649 100644 --- a/arch/s390/pci/pci_bus.c +++ b/arch/s390/pci/pci_bus.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -152,23 +153,6 @@ int zpci_bus_scan_bus(struct zpci_bus *zbus) return ret; } -/* zpci_bus_scan_busses - Scan all registered busses - * - * Scan all available zbusses - * - */ -void zpci_bus_scan_busses(void) -{ - struct zpci_bus *zbus = NULL; - - mutex_lock(&zbus_list_lock); - list_for_each_entry(zbus, &zbus_list, bus_next) { - zpci_bus_scan_bus(zbus); - cond_resched(); - } - mutex_unlock(&zbus_list_lock); -} - static bool zpci_bus_is_multifunction_root(struct zpci_dev *zdev) { return !s390_pci_no_rid && zdev->rid_available && @@ -198,25 +182,52 @@ static int zpci_bus_create_pci_bus(struct zpci_bus *zbus, struct zpci_dev *fr, s zbus->multifunction = zpci_bus_is_multifunction_root(fr); zbus->max_bus_speed = fr->max_bus_speed; + if (zpci_create_parent_msi_domain(zbus)) + goto out_free_domain; + /* * Note that the zbus->resources are taken over and zbus->resources * is empty after a successful call */ bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, ops, zbus, &zbus->resources); - if (!bus) { - zpci_free_domain(zbus->domain_nr); - return -EFAULT; - } + if (!bus) + goto out_remove_msi_domain; zbus->bus = bus; + dev_set_msi_domain(&zbus->bus->dev, zbus->msi_parent_domain); return 0; + +out_remove_msi_domain: + zpci_remove_parent_msi_domain(zbus); +out_free_domain: + zpci_free_domain(zbus->domain_nr); + return -ENOMEM; } -static void zpci_bus_release(struct kref *kref) +/** + * zpci_bus_release - Un-initialize resources associated with the zbus and + * free memory + * @kref: refcount * that is part of struct zpci_bus + * + * MUST be called with `zbus_list_lock` held, but the lock is released during + * run of the function. + */ +static inline void zpci_bus_release(struct kref *kref) + __releases(&zbus_list_lock) { struct zpci_bus *zbus = container_of(kref, struct zpci_bus, kref); + lockdep_assert_held(&zbus_list_lock); + + list_del(&zbus->bus_next); + mutex_unlock(&zbus_list_lock); + + /* + * At this point no-one should see this object, or be able to get a new + * reference to it. + */ + if (zbus->bus) { pci_lock_rescan_remove(); pci_stop_root_bus(zbus->bus); @@ -228,15 +239,19 @@ static void zpci_bus_release(struct kref *kref) pci_unlock_rescan_remove(); } - mutex_lock(&zbus_list_lock); - list_del(&zbus->bus_next); - mutex_unlock(&zbus_list_lock); + zpci_remove_parent_msi_domain(zbus); kfree(zbus); } -static void zpci_bus_put(struct zpci_bus *zbus) +static inline void __zpci_bus_get(struct zpci_bus *zbus) +{ + lockdep_assert_held(&zbus_list_lock); + kref_get(&zbus->kref); +} + +static inline void zpci_bus_put(struct zpci_bus *zbus) { - kref_put(&zbus->kref, zpci_bus_release); + kref_put_mutex(&zbus->kref, zpci_bus_release, &zbus_list_lock); } static struct zpci_bus *zpci_bus_get(int topo, bool topo_is_tid) @@ -248,7 +263,7 @@ static struct zpci_bus *zpci_bus_get(int topo, bool topo_is_tid) if (!zbus->multifunction) continue; if (topo_is_tid == zbus->topo_is_tid && topo == zbus->topo) { - kref_get(&zbus->kref); + __zpci_bus_get(zbus); goto out_unlock; } } @@ -258,6 +273,44 @@ static struct zpci_bus *zpci_bus_get(int topo, bool topo_is_tid) return zbus; } +/** + * zpci_bus_get_next - get the next zbus object from given position in the list + * @pos: current position/cursor in the global zbus list + * + * Acquires and releases references as the cursor iterates (might also free/ + * release the cursor). Is tolerant of concurrent operations on the list. + * + * To begin the iteration, set *@pos to %NULL before calling the function. + * + * *@pos is set to %NULL in cases where either the list is empty, or *@pos is + * the last element in the list. + * + * Context: Process context. May sleep. + */ +void zpci_bus_get_next(struct zpci_bus **pos) +{ + struct zpci_bus *curp = *pos, *next = NULL; + + mutex_lock(&zbus_list_lock); + if (curp) + next = list_next_entry(curp, bus_next); + else + next = list_first_entry(&zbus_list, typeof(*curp), bus_next); + + if (list_entry_is_head(next, &zbus_list, bus_next)) + next = NULL; + + if (next) + __zpci_bus_get(next); + + *pos = next; + mutex_unlock(&zbus_list_lock); + + /* zpci_bus_put() might drop refcount to 0 and locks zbus_list_lock */ + if (curp) + zpci_bus_put(curp); +} + static struct zpci_bus *zpci_bus_alloc(int topo, bool topo_is_tid) { struct zpci_bus *zbus; @@ -269,9 +322,6 @@ static struct zpci_bus *zpci_bus_alloc(int topo, bool topo_is_tid) zbus->topo = topo; zbus->topo_is_tid = topo_is_tid; INIT_LIST_HEAD(&zbus->bus_next); - mutex_lock(&zbus_list_lock); - list_add_tail(&zbus->bus_next, &zbus_list); - mutex_unlock(&zbus_list_lock); kref_init(&zbus->kref); INIT_LIST_HEAD(&zbus->resources); @@ -281,6 +331,10 @@ static struct zpci_bus *zpci_bus_alloc(int topo, bool topo_is_tid) zbus->bus_resource.flags = IORESOURCE_BUS; pci_add_resource(&zbus->resources, &zbus->bus_resource); + mutex_lock(&zbus_list_lock); + list_add_tail(&zbus->bus_next, &zbus_list); + mutex_unlock(&zbus_list_lock); + return zbus; } diff --git a/arch/s390/pci/pci_bus.h b/arch/s390/pci/pci_bus.h index ae3d7a9159bde..e440742e3145f 100644 --- a/arch/s390/pci/pci_bus.h +++ b/arch/s390/pci/pci_bus.h @@ -15,7 +15,20 @@ int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops); void zpci_bus_device_unregister(struct zpci_dev *zdev); int zpci_bus_scan_bus(struct zpci_bus *zbus); -void zpci_bus_scan_busses(void); +void zpci_bus_get_next(struct zpci_bus **pos); + +/** + * zpci_bus_for_each - iterate over all the registered zbus objects + * @pos: a struct zpci_bus * as cursor + * + * Acquires and releases references as the cursor iterates over the registered + * objects. Is tolerant against concurrent removals of objects. + * + * Context: Process context. May sleep. + */ +#define zpci_bus_for_each(pos) \ + for ((pos) = NULL, zpci_bus_get_next(&(pos)); (pos) != NULL; \ + zpci_bus_get_next(&(pos))) int zpci_bus_scan_device(struct zpci_dev *zdev); void zpci_bus_remove_device(struct zpci_dev *zdev, bool set_error); diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c index 2a06df8c24980..e9dd45f3c09de 100644 --- a/arch/s390/pci/pci_irq.c +++ b/arch/s390/pci/pci_irq.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -97,7 +98,7 @@ static int zpci_clear_directed_irq(struct zpci_dev *zdev) } /* Register adapter interruptions */ -static int zpci_set_irq(struct zpci_dev *zdev) +int zpci_set_irq(struct zpci_dev *zdev) { int rc; @@ -125,27 +126,53 @@ static int zpci_clear_irq(struct zpci_dev *zdev) static int zpci_set_irq_affinity(struct irq_data *data, const struct cpumask *dest, bool force) { - struct msi_desc *entry = irq_data_get_msi_desc(data); - struct msi_msg msg = entry->msg; - int cpu_addr = smp_cpu_get_cpu_address(cpumask_first(dest)); + irq_data_update_affinity(data, dest); + return IRQ_SET_MASK_OK; +} - msg.address_lo &= 0xff0000ff; - msg.address_lo |= (cpu_addr << 8); - pci_write_msi_msg(data->irq, &msg); +/* + * Encode the hwirq number for the parent domain. The encoding must be unique + * for each IRQ of each device in the parent domain, so it uses the devfn to + * identify the device and the msi_index to identify the IRQ within that device. + */ +static inline u32 zpci_encode_hwirq(u8 devfn, u16 msi_index) +{ + return (devfn << 16) | msi_index; +} - return IRQ_SET_MASK_OK; +static inline u16 zpci_decode_hwirq_msi_index(irq_hw_number_t hwirq) +{ + return hwirq & 0xffff; +} + +static void zpci_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) +{ + struct msi_desc *desc = irq_data_get_msi_desc(data); + struct zpci_dev *zdev = to_zpci_dev(desc->dev); + + if (irq_delivery == DIRECTED) { + int cpu = cpumask_first(irq_data_get_affinity_mask(data)); + + msg->address_lo = zdev->msi_addr & 0xff0000ff; + msg->address_lo |= (smp_cpu_get_cpu_address(cpu) << 8); + } else { + msg->address_lo = zdev->msi_addr & 0xffffffff; + } + msg->address_hi = zdev->msi_addr >> 32; + msg->data = zpci_decode_hwirq_msi_index(data->hwirq); } static struct irq_chip zpci_irq_chip = { .name = "PCI-MSI", - .irq_unmask = pci_msi_unmask_irq, - .irq_mask = pci_msi_mask_irq, + .irq_compose_msi_msg = zpci_compose_msi_msg, }; static void zpci_handle_cpu_local_irq(bool rescan) { struct airq_iv *dibv = zpci_ibv[smp_processor_id()]; union zpci_sic_iib iib = {{0}}; + struct irq_domain *msi_domain; + irq_hw_number_t hwirq; unsigned long bit; int irqs_on = 0; @@ -163,7 +190,9 @@ static void zpci_handle_cpu_local_irq(bool rescan) continue; } inc_irq_stat(IRQIO_MSI); - generic_handle_irq(airq_iv_get_data(dibv, bit)); + hwirq = airq_iv_get_data(dibv, bit); + msi_domain = (struct irq_domain *)airq_iv_get_ptr(dibv, bit); + generic_handle_domain_irq(msi_domain, hwirq); } } @@ -228,6 +257,8 @@ static void zpci_floating_irq_handler(struct airq_struct *airq, struct tpi_info *tpi_info) { union zpci_sic_iib iib = {{0}}; + struct irq_domain *msi_domain; + irq_hw_number_t hwirq; unsigned long si, ai; struct airq_iv *aibv; int irqs_on = 0; @@ -255,7 +286,9 @@ static void zpci_floating_irq_handler(struct airq_struct *airq, break; inc_irq_stat(IRQIO_MSI); airq_iv_lock(aibv, ai); - generic_handle_irq(airq_iv_get_data(aibv, ai)); + hwirq = airq_iv_get_data(aibv, ai); + msi_domain = (struct irq_domain *)airq_iv_get_ptr(aibv, ai); + generic_handle_domain_irq(msi_domain, hwirq); airq_iv_unlock(aibv, ai); } } @@ -277,7 +310,9 @@ static int __alloc_airq(struct zpci_dev *zdev, int msi_vecs, zdev->aisb = *bit; /* Create adapter interrupt vector */ - zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK, NULL); + zdev->aibv = airq_iv_create(msi_vecs, + AIRQ_IV_PTR | AIRQ_IV_DATA | AIRQ_IV_BITLOCK, + NULL); if (!zdev->aibv) return -ENOMEM; @@ -289,146 +324,220 @@ static int __alloc_airq(struct zpci_dev *zdev, int msi_vecs, return 0; } -int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) +bool arch_restore_msi_irqs(struct pci_dev *pdev) { - unsigned int hwirq, msi_vecs, irqs_per_msi, i, cpu; struct zpci_dev *zdev = to_zpci(pdev); - struct msi_desc *msi; - struct msi_msg msg; - unsigned long bit; - int cpu_addr; - int rc, irq; + zpci_set_irq(zdev); + return true; +} + +static struct airq_struct zpci_airq = { + .handler = zpci_floating_irq_handler, + .isc = PCI_ISC, +}; + +static void zpci_msi_teardown_directed(struct zpci_dev *zdev) +{ + airq_iv_free(zpci_ibv[0], zdev->msi_first_bit, zdev->max_msi); + zdev->msi_first_bit = -1U; + zdev->msi_nr_irqs = 0; +} + +static void zpci_msi_teardown_floating(struct zpci_dev *zdev) +{ + airq_iv_release(zdev->aibv); + zdev->aibv = NULL; + airq_iv_free_bit(zpci_sbv, zdev->aisb); zdev->aisb = -1UL; zdev->msi_first_bit = -1U; + zdev->msi_nr_irqs = 0; +} + +static void zpci_msi_teardown(struct irq_domain *domain, msi_alloc_info_t *arg) +{ + struct zpci_dev *zdev = to_zpci_dev(domain->dev); + + zpci_clear_irq(zdev); + if (irq_delivery == DIRECTED) + zpci_msi_teardown_directed(zdev); + else + zpci_msi_teardown_floating(zdev); +} + +static int zpci_msi_prepare(struct irq_domain *domain, + struct device *dev, int nvec, + msi_alloc_info_t *info) +{ + struct zpci_dev *zdev = to_zpci_dev(dev); + struct pci_dev *pdev = to_pci_dev(dev); + unsigned long bit; + int msi_vecs, rc; msi_vecs = min_t(unsigned int, nvec, zdev->max_msi); if (msi_vecs < nvec) { - pr_info("%s requested %d irqs, allocate system limit of %d", + pr_info("%s requested %d IRQs, allocate system limit of %d\n", pci_name(pdev), nvec, zdev->max_msi); } rc = __alloc_airq(zdev, msi_vecs, &bit); - if (rc < 0) + if (rc) { + pr_err("Allocating adapter IRQs for %s failed\n", pci_name(pdev)); return rc; + } - /* - * Request MSI interrupts: - * When using MSI, nvec_used interrupt sources and their irq - * descriptors are controlled through one msi descriptor. - * Thus the outer loop over msi descriptors shall run only once, - * while two inner loops iterate over the interrupt vectors. - * When using MSI-X, each interrupt vector/irq descriptor - * is bound to exactly one msi descriptor (nvec_used is one). - * So the inner loops are executed once, while the outer iterates - * over the MSI-X descriptors. - */ - hwirq = bit; - msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) { - if (hwirq - bit >= msi_vecs) - break; - irqs_per_msi = min_t(unsigned int, msi_vecs, msi->nvec_used); - irq = __irq_alloc_descs(-1, 0, irqs_per_msi, 0, THIS_MODULE, - (irq_delivery == DIRECTED) ? - msi->affinity : NULL); - if (irq < 0) - return -ENOMEM; + zdev->msi_first_bit = bit; + zdev->msi_nr_irqs = msi_vecs; + rc = zpci_set_irq(zdev); + if (rc) { + pr_err("Registering adapter IRQs for %s failed\n", + pci_name(pdev)); + + if (irq_delivery == DIRECTED) + zpci_msi_teardown_directed(zdev); + else + zpci_msi_teardown_floating(zdev); + return rc; + } + return 0; +} - for (i = 0; i < irqs_per_msi; i++) { - rc = irq_set_msi_desc_off(irq, i, msi); - if (rc) - return rc; - irq_set_chip_and_handler(irq + i, &zpci_irq_chip, - handle_percpu_irq); - } +static int zpci_msi_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *args) +{ + struct msi_desc *desc = ((msi_alloc_info_t *)args)->desc; + struct zpci_dev *zdev = to_zpci_dev(desc->dev); + struct zpci_bus *zbus = zdev->zbus; + unsigned int cpu, hwirq; + unsigned long bit; + int i; - msg.data = hwirq - bit; - if (irq_delivery == DIRECTED) { - if (msi->affinity) - cpu = cpumask_first(&msi->affinity->mask); - else - cpu = 0; - cpu_addr = smp_cpu_get_cpu_address(cpu); + bit = zdev->msi_first_bit + desc->msi_index; + hwirq = zpci_encode_hwirq(zdev->devfn, desc->msi_index); - msg.address_lo = zdev->msi_addr & 0xff0000ff; - msg.address_lo |= (cpu_addr << 8); + if (desc->msi_index + nr_irqs > zdev->max_msi) + return -EINVAL; + for (i = 0; i < nr_irqs; i++) { + irq_domain_set_info(domain, virq + i, hwirq + i, + &zpci_irq_chip, zdev, + handle_percpu_irq, NULL, NULL); + + if (irq_delivery == DIRECTED) { for_each_possible_cpu(cpu) { - for (i = 0; i < irqs_per_msi; i++) - airq_iv_set_data(zpci_ibv[cpu], - hwirq + i, irq + i); + airq_iv_set_ptr(zpci_ibv[cpu], bit + i, + (unsigned long)zbus->msi_parent_domain); + airq_iv_set_data(zpci_ibv[cpu], bit + i, hwirq + i); } } else { - msg.address_lo = zdev->msi_addr & 0xffffffff; - for (i = 0; i < irqs_per_msi; i++) - airq_iv_set_data(zdev->aibv, hwirq + i, irq + i); + airq_iv_set_ptr(zdev->aibv, bit + i, + (unsigned long)zbus->msi_parent_domain); + airq_iv_set_data(zdev->aibv, bit + i, hwirq + i); } - msg.address_hi = zdev->msi_addr >> 32; - pci_write_msi_msg(irq, &msg); - hwirq += irqs_per_msi; } - zdev->msi_first_bit = bit; - zdev->msi_nr_irqs = hwirq - bit; - - rc = zpci_set_irq(zdev); - if (rc) - return rc; - - return (zdev->msi_nr_irqs == nvec) ? 0 : zdev->msi_nr_irqs; + return 0; } -void arch_teardown_msi_irqs(struct pci_dev *pdev) +static void zpci_msi_clear_airq(struct irq_data *d, int i) { - struct zpci_dev *zdev = to_zpci(pdev); - struct msi_desc *msi; - unsigned int i; - int rc; + struct msi_desc *desc = irq_data_get_msi_desc(d); + struct zpci_dev *zdev = to_zpci_dev(desc->dev); + unsigned long bit; + unsigned int cpu; + u16 msi_index; - /* Disable interrupts */ - rc = zpci_clear_irq(zdev); - if (rc) - return; + msi_index = zpci_decode_hwirq_msi_index(d->hwirq); + bit = zdev->msi_first_bit + msi_index; - /* Release MSI interrupts */ - msi_for_each_desc(msi, &pdev->dev, MSI_DESC_ASSOCIATED) { - for (i = 0; i < msi->nvec_used; i++) { - irq_set_msi_desc(msi->irq + i, NULL); - irq_free_desc(msi->irq + i); + if (irq_delivery == DIRECTED) { + for_each_possible_cpu(cpu) { + airq_iv_set_ptr(zpci_ibv[cpu], bit + i, 0); + airq_iv_set_data(zpci_ibv[cpu], bit + i, 0); } - msi->msg.address_lo = 0; - msi->msg.address_hi = 0; - msi->msg.data = 0; - msi->irq = 0; + } else { + airq_iv_set_ptr(zdev->aibv, bit + i, 0); + airq_iv_set_data(zdev->aibv, bit + i, 0); } +} - if (zdev->aisb != -1UL) { - zpci_ibv[zdev->aisb] = NULL; - airq_iv_free_bit(zpci_sbv, zdev->aisb); - zdev->aisb = -1UL; - } - if (zdev->aibv) { - airq_iv_release(zdev->aibv); - zdev->aibv = NULL; - } +static void zpci_msi_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + struct irq_data *d; + int i; - if ((irq_delivery == DIRECTED) && zdev->msi_first_bit != -1U) - airq_iv_free(zpci_ibv[0], zdev->msi_first_bit, zdev->msi_nr_irqs); + for (i = 0; i < nr_irqs; i++) { + d = irq_domain_get_irq_data(domain, virq + i); + zpci_msi_clear_airq(d, i); + irq_domain_reset_irq_data(d); + } } -bool arch_restore_msi_irqs(struct pci_dev *pdev) +static const struct irq_domain_ops zpci_msi_domain_ops = { + .alloc = zpci_msi_domain_alloc, + .free = zpci_msi_domain_free, +}; + +static bool zpci_init_dev_msi_info(struct device *dev, struct irq_domain *domain, + struct irq_domain *real_parent, + struct msi_domain_info *info) { - struct zpci_dev *zdev = to_zpci(pdev); + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info)) + return false; + + info->ops->msi_prepare = zpci_msi_prepare; + info->ops->msi_teardown = zpci_msi_teardown; - zpci_set_irq(zdev); return true; } -static struct airq_struct zpci_airq = { - .handler = zpci_floating_irq_handler, - .isc = PCI_ISC, +static struct msi_parent_ops zpci_msi_parent_ops = { + .supported_flags = MSI_GENERIC_FLAGS_MASK | + MSI_FLAG_PCI_MSIX | + MSI_FLAG_MULTI_PCI_MSI, + .required_flags = MSI_FLAG_USE_DEF_DOM_OPS | + MSI_FLAG_USE_DEF_CHIP_OPS, + .init_dev_msi_info = zpci_init_dev_msi_info, }; +int zpci_create_parent_msi_domain(struct zpci_bus *zbus) +{ + char fwnode_name[18]; + + snprintf(fwnode_name, sizeof(fwnode_name), "ZPCI_MSI_DOM_%04x", zbus->domain_nr); + struct irq_domain_info info = { + .fwnode = irq_domain_alloc_named_fwnode(fwnode_name), + .ops = &zpci_msi_domain_ops, + }; + + if (!info.fwnode) { + pr_err("Failed to allocate fwnode for MSI IRQ domain\n"); + return -ENOMEM; + } + + if (irq_delivery == FLOATING) + zpci_msi_parent_ops.required_flags |= MSI_FLAG_NO_AFFINITY; + + zbus->msi_parent_domain = msi_create_parent_irq_domain(&info, &zpci_msi_parent_ops); + if (!zbus->msi_parent_domain) { + irq_domain_free_fwnode(info.fwnode); + pr_err("Failed to create MSI IRQ domain\n"); + return -ENOMEM; + } + + return 0; +} + +void zpci_remove_parent_msi_domain(struct zpci_bus *zbus) +{ + struct fwnode_handle *fn; + + fn = zbus->msi_parent_domain->fwnode; + irq_domain_remove(zbus->msi_parent_domain); + irq_domain_free_fwnode(fn); +} + static void __init cpu_enable_directed_irq(void *unused) { union zpci_sic_iib iib = {{0}}; @@ -465,6 +574,7 @@ static int __init zpci_directed_irq_init(void) * is only done on the first vector. */ zpci_ibv[cpu] = airq_iv_create(cache_line_size() * BITS_PER_BYTE, + AIRQ_IV_PTR | AIRQ_IV_DATA | AIRQ_IV_CACHELINE | (!cpu ? AIRQ_IV_ALLOC : 0), NULL); diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig index abeae220606a3..905fac1072845 100644 --- a/arch/sh/configs/edosk7760_defconfig +++ b/arch/sh/configs/edosk7760_defconfig @@ -79,7 +79,6 @@ CONFIG_FB_TILEBLITTING=y CONFIG_FB_SH_MOBILE_LCDC=m CONFIG_SOUND=y CONFIG_SND=y -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_VERBOSE_PROCFS is not set CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_SOC=y diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig index 9e3a54936f76f..8ca46d704c8ba 100644 --- a/arch/sh/configs/se7724_defconfig +++ b/arch/sh/configs/se7724_defconfig @@ -83,7 +83,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_SUPERH_VGA16 is not set CONFIG_SOUND=y CONFIG_SND=m -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_DRIVERS is not set # CONFIG_SND_SPI is not set # CONFIG_SND_SUPERH is not set diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig index eb63aa61b0465..5468cc53cddb4 100644 --- a/arch/sh/configs/sh7785lcr_32bit_defconfig +++ b/arch/sh/configs/sh7785lcr_32bit_defconfig @@ -93,7 +93,6 @@ CONFIG_SND_PCM_OSS=y CONFIG_SND_SEQUENCER_OSS=y CONFIG_SND_HRTIMER=y CONFIG_SND_DYNAMIC_MINORS=y -# CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_VERBOSE_PROCFS is not set CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_DEBUG=y diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 68eb7cc6e5643..482eec50f404e 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -857,7 +857,7 @@ static int __init pmb_debugfs_init(void) subsys_initcall(pmb_debugfs_init); #ifdef CONFIG_PM -static void pmb_syscore_resume(void) +static void pmb_syscore_resume(void *data) { struct pmb_entry *pmbe; int i; @@ -874,13 +874,17 @@ static void pmb_syscore_resume(void) read_unlock(&pmb_rwlock); } -static struct syscore_ops pmb_syscore_ops = { +static const struct syscore_ops pmb_syscore_ops = { .resume = pmb_syscore_resume, }; +static struct syscore pmb_syscore = { + .ops = &pmb_syscore_ops, +}; + static int __init pmb_sysdev_init(void) { - register_syscore_ops(&pmb_syscore_ops); + register_syscore(&pmb_syscore); return 0; } subsys_initcall(pmb_sysdev_init); diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h index f1538a48484ac..a9f802d1dd64f 100644 --- a/arch/sparc/include/asm/pgtable_32.h +++ b/arch/sparc/include/asm/pgtable_32.h @@ -395,12 +395,8 @@ __get_iospace (unsigned long addr) #define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4)) #define GET_PFN(pfn) (pfn & 0x0fffffffUL) -int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long, - unsigned long, pgprot_t); - -static inline int io_remap_pfn_range(struct vm_area_struct *vma, - unsigned long from, unsigned long pfn, - unsigned long size, pgprot_t prot) +static inline unsigned long io_remap_pfn_range_pfn(unsigned long pfn, + unsigned long size) { unsigned long long offset, space, phys_base; @@ -408,9 +404,9 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, space = GET_IOSPACE(pfn); phys_base = offset | (space << 32ULL); - return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot); + return phys_base >> PAGE_SHIFT; } -#define io_remap_pfn_range io_remap_pfn_range +#define io_remap_pfn_range_pfn io_remap_pfn_range_pfn #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \ diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 64b85ff9c7662..615f460c50af4 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -1048,9 +1048,6 @@ int page_in_phys_avail(unsigned long paddr); #define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4)) #define GET_PFN(pfn) (pfn & 0x0fffffffffffffffUL) -int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long, - unsigned long, pgprot_t); - void adi_restore_tags(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, pte_t pte); @@ -1084,9 +1081,8 @@ static inline int arch_unmap_one(struct mm_struct *mm, return 0; } -static inline int io_remap_pfn_range(struct vm_area_struct *vma, - unsigned long from, unsigned long pfn, - unsigned long size, pgprot_t prot) +static inline unsigned long io_remap_pfn_range_pfn(unsigned long pfn, + unsigned long size) { unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT; int space = GET_IOSPACE(pfn); @@ -1094,9 +1090,9 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, phys_base = offset | (((unsigned long) space) << 32UL); - return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot); + return phys_base >> PAGE_SHIFT; } -#define io_remap_pfn_range io_remap_pfn_range +#define io_remap_pfn_range_pfn io_remap_pfn_range_pfn static inline unsigned long __untagged_addr(unsigned long start) { diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index da03636925283..46ef88bc9c26e 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -260,26 +260,35 @@ static void dma_4u_free_coherent(struct device *dev, size_t size, free_pages((unsigned long)cpu, order); } -static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t sz, - enum dma_data_direction direction, +static dma_addr_t dma_4u_map_phys(struct device *dev, phys_addr_t phys, + size_t sz, enum dma_data_direction direction, unsigned long attrs) { struct iommu *iommu; struct strbuf *strbuf; iopte_t *base; unsigned long flags, npages, oaddr; - unsigned long i, base_paddr, ctx; + unsigned long i, ctx; u32 bus_addr, ret; unsigned long iopte_protection; + if (unlikely(attrs & DMA_ATTR_MMIO)) + /* + * This check is included because older versions of the code + * lacked MMIO path support, and my ability to test this path + * is limited. However, from a software technical standpoint, + * there is no restriction, as the following code operates + * solely on physical addresses. + */ + goto bad_no_ctx; + iommu = dev->archdata.iommu; strbuf = dev->archdata.stc; if (unlikely(direction == DMA_NONE)) goto bad_no_ctx; - oaddr = (unsigned long)(page_address(page) + offset); + oaddr = (unsigned long)(phys_to_virt(phys)); npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); npages >>= IO_PAGE_SHIFT; @@ -296,7 +305,6 @@ static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page, bus_addr = (iommu->tbl.table_map_base + ((base - iommu->page_table) << IO_PAGE_SHIFT)); ret = bus_addr | (oaddr & ~IO_PAGE_MASK); - base_paddr = __pa(oaddr & IO_PAGE_MASK); if (strbuf->strbuf_enabled) iopte_protection = IOPTE_STREAMING(ctx); else @@ -304,8 +312,8 @@ static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page, if (direction != DMA_TO_DEVICE) iopte_protection |= IOPTE_WRITE; - for (i = 0; i < npages; i++, base++, base_paddr += IO_PAGE_SIZE) - iopte_val(*base) = iopte_protection | base_paddr; + for (i = 0; i < npages; i++, base++, phys += IO_PAGE_SIZE) + iopte_val(*base) = iopte_protection | phys; return ret; @@ -383,7 +391,7 @@ static void strbuf_flush(struct strbuf *strbuf, struct iommu *iommu, vaddr, ctx, npages); } -static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr, +static void dma_4u_unmap_phys(struct device *dev, dma_addr_t bus_addr, size_t sz, enum dma_data_direction direction, unsigned long attrs) { @@ -753,8 +761,8 @@ static int dma_4u_supported(struct device *dev, u64 device_mask) static const struct dma_map_ops sun4u_dma_ops = { .alloc = dma_4u_alloc_coherent, .free = dma_4u_free_coherent, - .map_page = dma_4u_map_page, - .unmap_page = dma_4u_unmap_page, + .map_phys = dma_4u_map_phys, + .unmap_phys = dma_4u_unmap_phys, .map_sg = dma_4u_map_sg, .unmap_sg = dma_4u_unmap_sg, .sync_single_for_cpu = dma_4u_sync_single_for_cpu, diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index b720b21ccfbd8..791f0a76665f6 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -352,9 +352,8 @@ static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu, free_pages((unsigned long)cpu, order); } -static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t sz, - enum dma_data_direction direction, +static dma_addr_t dma_4v_map_phys(struct device *dev, phys_addr_t phys, + size_t sz, enum dma_data_direction direction, unsigned long attrs) { struct iommu *iommu; @@ -362,18 +361,27 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, struct iommu_map_table *tbl; u64 mask; unsigned long flags, npages, oaddr; - unsigned long i, base_paddr; - unsigned long prot; + unsigned long i, prot; dma_addr_t bus_addr, ret; long entry; + if (unlikely(attrs & DMA_ATTR_MMIO)) + /* + * This check is included because older versions of the code + * lacked MMIO path support, and my ability to test this path + * is limited. However, from a software technical standpoint, + * there is no restriction, as the following code operates + * solely on physical addresses. + */ + goto bad; + iommu = dev->archdata.iommu; atu = iommu->atu; if (unlikely(direction == DMA_NONE)) goto bad; - oaddr = (unsigned long)(page_address(page) + offset); + oaddr = (unsigned long)(phys_to_virt(phys)); npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); npages >>= IO_PAGE_SHIFT; @@ -391,7 +399,6 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, bus_addr = (tbl->table_map_base + (entry << IO_PAGE_SHIFT)); ret = bus_addr | (oaddr & ~IO_PAGE_MASK); - base_paddr = __pa(oaddr & IO_PAGE_MASK); prot = HV_PCI_MAP_ATTR_READ; if (direction != DMA_TO_DEVICE) prot |= HV_PCI_MAP_ATTR_WRITE; @@ -403,8 +410,8 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, iommu_batch_start(dev, prot, entry); - for (i = 0; i < npages; i++, base_paddr += IO_PAGE_SIZE) { - long err = iommu_batch_add(base_paddr, mask); + for (i = 0; i < npages; i++, phys += IO_PAGE_SIZE) { + long err = iommu_batch_add(phys, mask); if (unlikely(err < 0L)) goto iommu_map_fail; } @@ -426,7 +433,7 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, return DMA_MAPPING_ERROR; } -static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr, +static void dma_4v_unmap_phys(struct device *dev, dma_addr_t bus_addr, size_t sz, enum dma_data_direction direction, unsigned long attrs) { @@ -686,8 +693,8 @@ static int dma_4v_supported(struct device *dev, u64 device_mask) static const struct dma_map_ops sun4v_dma_ops = { .alloc = dma_4v_alloc_coherent, .free = dma_4v_free_coherent, - .map_page = dma_4v_map_page, - .unmap_page = dma_4v_unmap_page, + .map_phys = dma_4v_map_phys, + .unmap_phys = dma_4v_unmap_phys, .map_sg = dma_4v_map_sg, .unmap_sg = dma_4v_unmap_sg, .dma_supported = dma_4v_supported, diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 55faf2effa46c..dbf118b406011 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -241,7 +241,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u if (flags & MAP_FIXED) { /* Ok, don't mess with it. */ - return mm_get_unmapped_area(current->mm, NULL, orig_addr, len, pgoff, flags); + return mm_get_unmapped_area(NULL, orig_addr, len, pgoff, flags); } flags &= ~MAP_SHARED; @@ -254,7 +254,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u align_goal = (64UL * 1024); do { - addr = mm_get_unmapped_area(current->mm, NULL, orig_addr, + addr = mm_get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); if (!(addr & ~PAGE_MASK)) { addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); @@ -273,7 +273,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u * be obtained. */ if (addr & ~PAGE_MASK) - addr = mm_get_unmapped_area(current->mm, NULL, orig_addr, len, pgoff, flags); + addr = mm_get_unmapped_area(NULL, orig_addr, len, pgoff, flags); return addr; } diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index d8376f61b4d08..d409cb450de48 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -94,13 +94,14 @@ static int __init iounit_init(void) subsys_initcall(iounit_init); /* One has to hold iounit->lock to call this */ -static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size) +static dma_addr_t iounit_get_area(struct iounit_struct *iounit, + phys_addr_t phys, int size) { int i, j, k, npages; unsigned long rotor, scan, limit; iopte_t iopte; - npages = ((vaddr & ~PAGE_MASK) + size + (PAGE_SIZE-1)) >> PAGE_SHIFT; + npages = (offset_in_page(phys) + size + (PAGE_SIZE - 1)) >> PAGE_SHIFT; /* A tiny bit of magic ingredience :) */ switch (npages) { @@ -109,7 +110,7 @@ static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long default: i = 0x0213; break; } - IOD(("iounit_get_area(%08lx,%d[%d])=", vaddr, size, npages)); + IOD(("%s(%pa,%d[%d])=", __func__, &phys, size, npages)); next: j = (i & 15); rotor = iounit->rotor[j - 1]; @@ -124,7 +125,8 @@ nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan); } i >>= 4; if (!(i & 15)) - panic("iounit_get_area: Couldn't find free iopte slots for (%08lx,%d)\n", vaddr, size); + panic("iounit_get_area: Couldn't find free iopte slots for (%pa,%d)\n", + &phys, size); goto next; } for (k = 1, scan++; k < npages; k++) @@ -132,30 +134,29 @@ nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan); goto nexti; iounit->rotor[j - 1] = (scan < limit) ? scan : iounit->limit[j - 1]; scan -= npages; - iopte = MKIOPTE(__pa(vaddr & PAGE_MASK)); - vaddr = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT) + (vaddr & ~PAGE_MASK); + iopte = MKIOPTE(phys & PAGE_MASK); + phys = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT) + offset_in_page(phys); for (k = 0; k < npages; k++, iopte = __iopte(iopte_val(iopte) + 0x100), scan++) { set_bit(scan, iounit->bmap); sbus_writel(iopte_val(iopte), &iounit->page_table[scan]); } - IOD(("%08lx\n", vaddr)); - return vaddr; + IOD(("%pa\n", &phys)); + return phys; } -static dma_addr_t iounit_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t len, enum dma_data_direction dir, - unsigned long attrs) +static dma_addr_t iounit_map_phys(struct device *dev, phys_addr_t phys, + size_t len, enum dma_data_direction dir, unsigned long attrs) { - void *vaddr = page_address(page) + offset; struct iounit_struct *iounit = dev->archdata.iommu; - unsigned long ret, flags; + unsigned long flags; + dma_addr_t ret; /* XXX So what is maxphys for us and how do drivers know it? */ if (!len || len > 256 * 1024) return DMA_MAPPING_ERROR; spin_lock_irqsave(&iounit->lock, flags); - ret = iounit_get_area(iounit, (unsigned long)vaddr, len); + ret = iounit_get_area(iounit, phys, len); spin_unlock_irqrestore(&iounit->lock, flags); return ret; } @@ -171,14 +172,15 @@ static int iounit_map_sg(struct device *dev, struct scatterlist *sgl, int nents, /* FIXME: Cache some resolved pages - often several sg entries are to the same page */ spin_lock_irqsave(&iounit->lock, flags); for_each_sg(sgl, sg, nents, i) { - sg->dma_address = iounit_get_area(iounit, (unsigned long) sg_virt(sg), sg->length); + sg->dma_address = + iounit_get_area(iounit, sg_phys(sg), sg->length); sg->dma_length = sg->length; } spin_unlock_irqrestore(&iounit->lock, flags); return nents; } -static void iounit_unmap_page(struct device *dev, dma_addr_t vaddr, size_t len, +static void iounit_unmap_phys(struct device *dev, dma_addr_t vaddr, size_t len, enum dma_data_direction dir, unsigned long attrs) { struct iounit_struct *iounit = dev->archdata.iommu; @@ -279,8 +281,8 @@ static const struct dma_map_ops iounit_dma_ops = { .alloc = iounit_alloc, .free = iounit_free, #endif - .map_page = iounit_map_page, - .unmap_page = iounit_unmap_page, + .map_phys = iounit_map_phys, + .unmap_phys = iounit_unmap_phys, .map_sg = iounit_map_sg, .unmap_sg = iounit_unmap_sg, }; diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 5a5080db800f5..f48adf62724ab 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -181,18 +181,20 @@ static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte) } } -static dma_addr_t __sbus_iommu_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t len, bool per_page_flush) +static dma_addr_t __sbus_iommu_map_phys(struct device *dev, phys_addr_t paddr, + size_t len, bool per_page_flush, unsigned long attrs) { struct iommu_struct *iommu = dev->archdata.iommu; - phys_addr_t paddr = page_to_phys(page) + offset; - unsigned long off = paddr & ~PAGE_MASK; + unsigned long off = offset_in_page(paddr); unsigned long npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; unsigned long pfn = __phys_to_pfn(paddr); unsigned int busa, busa0; iopte_t *iopte, *iopte0; int ioptex, i; + if (unlikely(attrs & DMA_ATTR_MMIO)) + return DMA_MAPPING_ERROR; + /* XXX So what is maxphys for us and how do drivers know it? */ if (!len || len > 256 * 1024) return DMA_MAPPING_ERROR; @@ -202,10 +204,10 @@ static dma_addr_t __sbus_iommu_map_page(struct device *dev, struct page *page, * XXX Is this a good assumption? * XXX What if someone else unmaps it here and races us? */ - if (per_page_flush && !PageHighMem(page)) { + if (per_page_flush && !PhysHighMem(paddr)) { unsigned long vaddr, p; - vaddr = (unsigned long)page_address(page) + offset; + vaddr = (unsigned long)phys_to_virt(paddr); for (p = vaddr & PAGE_MASK; p < vaddr + len; p += PAGE_SIZE) flush_page_for_dma(p); } @@ -231,19 +233,19 @@ static dma_addr_t __sbus_iommu_map_page(struct device *dev, struct page *page, return busa0 + off; } -static dma_addr_t sbus_iommu_map_page_gflush(struct device *dev, - struct page *page, unsigned long offset, size_t len, - enum dma_data_direction dir, unsigned long attrs) +static dma_addr_t sbus_iommu_map_phys_gflush(struct device *dev, + phys_addr_t phys, size_t len, enum dma_data_direction dir, + unsigned long attrs) { flush_page_for_dma(0); - return __sbus_iommu_map_page(dev, page, offset, len, false); + return __sbus_iommu_map_phys(dev, phys, len, false, attrs); } -static dma_addr_t sbus_iommu_map_page_pflush(struct device *dev, - struct page *page, unsigned long offset, size_t len, - enum dma_data_direction dir, unsigned long attrs) +static dma_addr_t sbus_iommu_map_phys_pflush(struct device *dev, + phys_addr_t phys, size_t len, enum dma_data_direction dir, + unsigned long attrs) { - return __sbus_iommu_map_page(dev, page, offset, len, true); + return __sbus_iommu_map_phys(dev, phys, len, true, attrs); } static int __sbus_iommu_map_sg(struct device *dev, struct scatterlist *sgl, @@ -254,8 +256,8 @@ static int __sbus_iommu_map_sg(struct device *dev, struct scatterlist *sgl, int j; for_each_sg(sgl, sg, nents, j) { - sg->dma_address =__sbus_iommu_map_page(dev, sg_page(sg), - sg->offset, sg->length, per_page_flush); + sg->dma_address = __sbus_iommu_map_phys(dev, sg_phys(sg), + sg->length, per_page_flush, attrs); if (sg->dma_address == DMA_MAPPING_ERROR) return -EIO; sg->dma_length = sg->length; @@ -277,7 +279,7 @@ static int sbus_iommu_map_sg_pflush(struct device *dev, struct scatterlist *sgl, return __sbus_iommu_map_sg(dev, sgl, nents, dir, attrs, true); } -static void sbus_iommu_unmap_page(struct device *dev, dma_addr_t dma_addr, +static void sbus_iommu_unmap_phys(struct device *dev, dma_addr_t dma_addr, size_t len, enum dma_data_direction dir, unsigned long attrs) { struct iommu_struct *iommu = dev->archdata.iommu; @@ -303,7 +305,7 @@ static void sbus_iommu_unmap_sg(struct device *dev, struct scatterlist *sgl, int i; for_each_sg(sgl, sg, nents, i) { - sbus_iommu_unmap_page(dev, sg->dma_address, sg->length, dir, + sbus_iommu_unmap_phys(dev, sg->dma_address, sg->length, dir, attrs); sg->dma_address = 0x21212121; } @@ -426,8 +428,8 @@ static const struct dma_map_ops sbus_iommu_dma_gflush_ops = { .alloc = sbus_iommu_alloc, .free = sbus_iommu_free, #endif - .map_page = sbus_iommu_map_page_gflush, - .unmap_page = sbus_iommu_unmap_page, + .map_phys = sbus_iommu_map_phys_gflush, + .unmap_phys = sbus_iommu_unmap_phys, .map_sg = sbus_iommu_map_sg_gflush, .unmap_sg = sbus_iommu_unmap_sg, }; @@ -437,8 +439,8 @@ static const struct dma_map_ops sbus_iommu_dma_pflush_ops = { .alloc = sbus_iommu_alloc, .free = sbus_iommu_free, #endif - .map_page = sbus_iommu_map_page_pflush, - .unmap_page = sbus_iommu_unmap_page, + .map_phys = sbus_iommu_map_phys_pflush, + .unmap_phys = sbus_iommu_unmap_phys, .map_sg = sbus_iommu_map_sg_pflush, .unmap_sg = sbus_iommu_unmap_sg, }; diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 49781bee79058..8415d39b0d430 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -5,6 +5,7 @@ menu "UML-specific options" config UML bool default y + select ARCH_DISABLE_KASAN_INLINE if STATIC_LINK select ARCH_NEEDS_DEFER_KASAN if STATIC_LINK select ARCH_WANTS_DYNAMIC_TASK_STRUCT select ARCH_HAS_CACHE_LINE_SIZE @@ -28,6 +29,7 @@ config UML select OF_EARLY_FLATTREE if OF select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES + select GENERIC_SMP_IDLE_THREAD select HAVE_GCC_PLUGINS select ARCH_SUPPORTS_LTO_CLANG select ARCH_SUPPORTS_LTO_CLANG_THIN @@ -81,10 +83,48 @@ config HZ int default 100 -config NR_CPUS +config UML_SUBARCH_SUPPORTS_SMP + bool + +config SMP + bool "Symmetric multi-processing support" + default n + depends on UML_SUBARCH_SUPPORTS_SMP + help + This option enables UML SMP support. + + With this enabled, users can tell UML to start multiple virtual + processors. Each virtual processor is represented as a separate + host thread. + + In UML, kthreads and normal threads (when running in kernel mode) + can be scheduled and executed simultaneously on different virtual + processors. However, the userspace code of normal threads still + runs within their respective single-threaded stubs. + + That is, SMP support is available both within the kernel and + across different processes, but remains limited within threads + of the same process in userspace. + +config NR_CPUS_RANGE_BEGIN int - range 1 1 - default 1 + default 1 if !SMP + default 2 + +config NR_CPUS_RANGE_END + int + default 1 if !SMP + default 64 + +config NR_CPUS_DEFAULT + int + default 1 if !SMP + default 2 + +config NR_CPUS + int "Maximum number of CPUs" if SMP + range NR_CPUS_RANGE_BEGIN NR_CPUS_RANGE_END + default NR_CPUS_DEFAULT source "arch/$(HEADER_ARCH)/um/Kconfig" @@ -200,12 +240,6 @@ config KERNEL_STACK_ORDER increase in the size of the state which needs to be saved when handling signals. -config MMAPPER - tristate "iomem emulation driver" - help - This driver allows a host file to be used as emulated IO memory inside - UML. - config PGTABLE_LEVELS int default 4 if 64BIT @@ -260,6 +294,7 @@ source "arch/um/drivers/Kconfig" config ARCH_SUSPEND_POSSIBLE def_bool y + depends on !SMP menu "Power management options" diff --git a/arch/um/Makefile b/arch/um/Makefile index 7be0143b5ba35..721b652ffb658 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -46,19 +46,17 @@ ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) ARCH_INCLUDE += -I$(srctree)/$(HOST_DIR)/um/shared KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um -# -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so -# named - it's a common symbol in libpcap, so we get a binary which crashes. -# -# Same things for in6addr_loopback and mktime - found in libc. For these two we -# only get link-time error, luckily. +# -Dstrrchr=kernel_strrchr (as well as the various in6addr symbols) prevents +# anything from referencing +# libc symbols with the same name, which can cause a linker error. # # -Dlongjmp=kernel_longjmp prevents anything from referencing the libpthread.a # embedded copy of longjmp, same thing for setjmp. # -# These apply to USER_CFLAGS to. +# These apply to USER_CFLAGS too. KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \ - $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ + $(ARCH_INCLUDE) $(MODE_INCLUDE) \ -Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \ -Din6addr_loopback=kernel_in6addr_loopback \ -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr \ diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile index 6bf8cbf71d3ca..36dc578400844 100644 --- a/arch/um/drivers/Makefile +++ b/arch/um/drivers/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o obj-$(CONFIG_UML_NET_VECTOR) += vector.o obj-$(CONFIG_MCONSOLE) += mconsole.o -obj-$(CONFIG_MMAPPER) += mmapper_kern.o obj-$(CONFIG_BLK_DEV_UBD) += ubd.o obj-$(CONFIG_UML_SOUND) += hostaudio.o obj-$(CONFIG_NULL_CHAN) += null.o diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c deleted file mode 100644 index 807cd33587405..0000000000000 --- a/arch/um/drivers/mmapper_kern.c +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * arch/um/drivers/mmapper_kern.c - * - * BRIEF MODULE DESCRIPTION - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* These are set in mmapper_init, which is called at boot time */ -static unsigned long mmapper_size; -static unsigned long p_buf; -static char *v_buf; - -static ssize_t mmapper_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - return simple_read_from_buffer(buf, count, ppos, v_buf, mmapper_size); -} - -static ssize_t mmapper_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - if (*ppos > mmapper_size) - return -EINVAL; - - return simple_write_to_buffer(v_buf, mmapper_size, ppos, buf, count); -} - -static long mmapper_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} - -static int mmapper_mmap(struct file *file, struct vm_area_struct *vma) -{ - int ret = -EINVAL; - int size; - - if (vma->vm_pgoff != 0) - goto out; - - size = vma->vm_end - vma->vm_start; - if (size > mmapper_size) - return -EFAULT; - - /* - * XXX A comment above remap_pfn_range says it should only be - * called when the mm semaphore is held - */ - if (remap_pfn_range(vma, vma->vm_start, p_buf >> PAGE_SHIFT, size, - vma->vm_page_prot)) - goto out; - ret = 0; -out: - return ret; -} - -static int mmapper_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static int mmapper_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations mmapper_fops = { - .owner = THIS_MODULE, - .read = mmapper_read, - .write = mmapper_write, - .unlocked_ioctl = mmapper_ioctl, - .mmap = mmapper_mmap, - .open = mmapper_open, - .release = mmapper_release, - .llseek = default_llseek, -}; - -/* - * No locking needed - only used (and modified) by below initcall and exitcall. - */ -static struct miscdevice mmapper_dev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "mmapper", - .fops = &mmapper_fops -}; - -static int __init mmapper_init(void) -{ - int err; - - printk(KERN_INFO "Mapper v0.1\n"); - - v_buf = (char *) find_iomem("mmapper", &mmapper_size); - if (mmapper_size == 0) { - printk(KERN_ERR "mmapper_init - find_iomem failed\n"); - return -ENODEV; - } - p_buf = __pa(v_buf); - - err = misc_register(&mmapper_dev); - if (err) { - printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", - err); - return err; - } - return 0; -} - -static void __exit mmapper_exit(void) -{ - misc_deregister(&mmapper_dev); -} - -module_init(mmapper_init); -module_exit(mmapper_exit); - -MODULE_AUTHOR("Greg Lonnon "); -MODULE_DESCRIPTION("DSPLinux simulator mmapper driver"); -MODULE_LICENSE("GPL"); diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index de7867ae220d0..6cf1152a1a4e6 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1151,8 +1152,7 @@ void virtio_uml_set_no_vq_suspend(struct virtio_device *vdev, return; vu_dev->no_vq_suspend = no_vq_suspend; - dev_info(&vdev->dev, "%sabled VQ suspend\n", - no_vq_suspend ? "dis" : "en"); + dev_info(&vdev->dev, "%s VQ suspend\n", str_disabled_enabled(no_vq_suspend)); } static void vu_of_conn_broken(struct work_struct *wk) diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index b6810db24ca4d..1b9b82bbe3220 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -5,7 +5,6 @@ generic-y += device.h generic-y += dma-mapping.h generic-y += emergency-restart.h generic-y += exec.h -generic-y += extable.h generic-y += ftrace.h generic-y += hw_irq.h generic-y += irq_regs.h diff --git a/arch/um/include/asm/current.h b/arch/um/include/asm/current.h index 8accc6d6f5026..159a29b3d4cc5 100644 --- a/arch/um/include/asm/current.h +++ b/arch/um/include/asm/current.h @@ -7,15 +7,16 @@ #ifndef __ASSEMBLER__ +#include + struct task_struct; extern struct task_struct *cpu_tasks[NR_CPUS]; static __always_inline struct task_struct *get_current(void) { - return cpu_tasks[0]; + return cpu_tasks[uml_curr_cpu()]; } - #define current get_current() #endif /* __ASSEMBLER__ */ diff --git a/arch/um/include/asm/hardirq.h b/arch/um/include/asm/hardirq.h index 52e2c36267a93..8de71752a9b8d 100644 --- a/arch/um/include/asm/hardirq.h +++ b/arch/um/include/asm/hardirq.h @@ -2,8 +2,30 @@ #ifndef __ASM_UM_HARDIRQ_H #define __ASM_UM_HARDIRQ_H -#include +#include +#include #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 +typedef struct { + unsigned int __softirq_pending; +#if IS_ENABLED(CONFIG_SMP) + unsigned int irq_resched_count; + unsigned int irq_call_count; +#endif +} ____cacheline_aligned irq_cpustat_t; + +DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); + +#define __ARCH_IRQ_STAT + +#define inc_irq_stat(member) this_cpu_inc(irq_stat.member) + +#include + +static inline void ack_bad_irq(unsigned int irq) +{ + pr_crit("unexpected IRQ trap at vector %02x\n", irq); +} + #endif /* __ASM_UM_HARDIRQ_H */ diff --git a/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h index 1e69ef5bc35e0..31e49e0894c5e 100644 --- a/arch/um/include/asm/irqflags.h +++ b/arch/um/include/asm/irqflags.h @@ -2,7 +2,7 @@ #ifndef __UM_IRQFLAGS_H #define __UM_IRQFLAGS_H -extern int signals_enabled; +int um_get_signals(void); int um_set_signals(int enable); void block_signals(void); void unblock_signals(void); @@ -10,7 +10,7 @@ void unblock_signals(void); #define arch_local_save_flags arch_local_save_flags static inline unsigned long arch_local_save_flags(void) { - return signals_enabled; + return um_get_signals(); } #define arch_local_irq_restore arch_local_irq_restore diff --git a/arch/um/include/asm/kasan.h b/arch/um/include/asm/kasan.h index b54a4e937fd12..81bcdc0f962e6 100644 --- a/arch/um/include/asm/kasan.h +++ b/arch/um/include/asm/kasan.h @@ -24,10 +24,6 @@ #ifdef CONFIG_KASAN void kasan_init(void); - -#if defined(CONFIG_STATIC_LINK) && defined(CONFIG_KASAN_INLINE) -#error UML does not work in KASAN_INLINE mode with STATIC_LINK enabled! -#endif #else static inline void kasan_init(void) { } #endif /* CONFIG_KASAN */ diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h index 4d0e4239f3ccc..07d48738b402b 100644 --- a/arch/um/include/asm/mmu.h +++ b/arch/um/include/asm/mmu.h @@ -7,16 +7,26 @@ #define __ARCH_UM_MMU_H #include "linux/types.h" +#include +#include #include typedef struct mm_context { struct mm_id id; + struct mutex turnstile; struct list_head list; /* Address range in need of a TLB sync */ + spinlock_t sync_tlb_lock; unsigned long sync_tlb_range_from; unsigned long sync_tlb_range_to; } mm_context_t; +#define INIT_MM_CONTEXT(mm) \ + .context = { \ + .turnstile = __MUTEX_INITIALIZER(mm.context.turnstile), \ + .sync_tlb_lock = __SPIN_LOCK_INITIALIZER(mm.context.sync_tlb_lock), \ + } + #endif diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h index 6f54254aaf443..2d363460d8960 100644 --- a/arch/um/include/asm/page.h +++ b/arch/um/include/asm/page.h @@ -96,8 +96,4 @@ extern unsigned long uml_physmem; #endif /* __ASSEMBLER__ */ -#ifdef CONFIG_X86_32 -#define __HAVE_ARCH_GATE_AREA 1 -#endif - #endif /* __UM_PAGE_H */ diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index 24fdea6f88c37..3b42b0f45bf6c 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -45,10 +45,12 @@ extern unsigned long *empty_zero_page; * area for the same reason. ;) */ -extern unsigned long end_iomem; +#ifndef COMPILE_OFFSETS +#include /* for high_physmem */ +#endif #define VMALLOC_OFFSET (__va_space) -#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_START ((high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) #define VMALLOC_END (TASK_SIZE-2*PAGE_SIZE) #define MODULES_VADDR VMALLOC_START #define MODULES_END VMALLOC_END @@ -225,6 +227,8 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval) static inline void um_tlb_mark_sync(struct mm_struct *mm, unsigned long start, unsigned long end) { + guard(spinlock_irqsave)(&mm->context.sync_tlb_lock); + if (!mm->context.sync_tlb_range_to) { mm->context.sync_tlb_range_from = start; mm->context.sync_tlb_range_to = end; diff --git a/arch/um/include/asm/smp.h b/arch/um/include/asm/smp.h index a8cc1d46ddcbd..be1743a6ff3c9 100644 --- a/arch/um/include/asm/smp.h +++ b/arch/um/include/asm/smp.h @@ -2,6 +2,19 @@ #ifndef __UM_SMP_H #define __UM_SMP_H -#define hard_smp_processor_id() 0 +#if IS_ENABLED(CONFIG_SMP) + +#include +#include + +#define raw_smp_processor_id() uml_curr_cpu() + +void arch_smp_send_reschedule(int cpu); + +void arch_send_call_function_single_ipi(int cpu); + +void arch_send_call_function_ipi_mask(const struct cpumask *mask); + +#endif /* CONFIG_SMP */ #endif diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h index 1c6e0ae41b0c5..0df9ea4abda83 100644 --- a/arch/um/include/asm/uaccess.h +++ b/arch/um/include/asm/uaccess.h @@ -15,11 +15,6 @@ (((unsigned long) (addr) < TASK_SIZE) && \ (((unsigned long) (addr) + (size)) < TASK_SIZE)) -#define __access_ok_vsyscall(addr, size) \ - (((unsigned long) (addr) >= FIXADDR_USER_START) && \ - ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ - ((unsigned long) (addr) + (size) >= (unsigned long)(addr))) - #define __addr_range_nowrap(addr, size) \ ((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) @@ -40,9 +35,7 @@ static inline int __access_ok(const void __user *ptr, unsigned long size); static inline int __access_ok(const void __user *ptr, unsigned long size) { unsigned long addr = (unsigned long)ptr; - return __addr_range_nowrap(addr, size) && - (__under_task_size(addr, size) || - __access_ok_vsyscall(addr, size)); + return __addr_range_nowrap(addr, size) && __under_task_size(addr, size); } #define __get_kernel_nofault(dst, src, type, err_label) \ diff --git a/arch/um/include/linux/smp-internal.h b/arch/um/include/linux/smp-internal.h new file mode 100644 index 0000000000000..1dbcbc23f9c90 --- /dev/null +++ b/arch/um/include/linux/smp-internal.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __UM_SMP_INTERNAL_H +#define __UM_SMP_INTERNAL_H + +#if IS_ENABLED(CONFIG_SMP) + +void prefill_possible_map(void); + +#else /* !CONFIG_SMP */ + +static inline void prefill_possible_map(void) { } + +#endif /* CONFIG_SMP */ + +extern char cpu_irqstacks[NR_CPUS][THREAD_SIZE] __aligned(THREAD_SIZE); + +#endif /* __UM_SMP_INTERNAL_H */ diff --git a/arch/um/include/linux/time-internal.h b/arch/um/include/linux/time-internal.h index 138908b999d76..c274eb5ad55e6 100644 --- a/arch/um/include/linux/time-internal.h +++ b/arch/um/include/linux/time-internal.h @@ -90,4 +90,7 @@ extern unsigned long tt_extra_sched_jiffies; * which is intentional since we really shouldn't link it in that case. */ void time_travel_ndelay(unsigned long nsec); + +int um_setup_timer(void); + #endif /* __TIMER_INTERNAL_H__ */ diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index 7c7e17bce403d..02ef258e3395e 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h @@ -44,7 +44,6 @@ extern unsigned long start_vm; extern unsigned long brk_start; -extern unsigned long host_task_size; extern unsigned long stub_start; extern int linux_main(int argc, char **argv, char **envp); diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h deleted file mode 100644 index 8ca66a1918c3a..0000000000000 --- a/arch/um/include/shared/common-offsets.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* for use by sys-$SUBARCH/kernel-offsets.c */ - -DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); - -DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); -DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK); -DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT); - -DEFINE(UM_GFP_KERNEL, GFP_KERNEL); -DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC); - -DEFINE(UM_THREAD_SIZE, THREAD_SIZE); - -DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); -DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC); - -DEFINE(UM_KERN_GDT_ENTRY_TLS_ENTRIES, GDT_ENTRY_TLS_ENTRIES); - -DEFINE(UM_SECCOMP_ARCH_NATIVE, SECCOMP_ARCH_NATIVE); diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index 00ca3e12fd9ae..38321188c04c4 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -15,9 +15,6 @@ extern int uml_exitcode; extern int kmalloc_ok; -#define UML_ROUND_UP(addr) \ - ((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK) - extern unsigned long alloc_stack(int order, int atomic); extern void free_stack(unsigned long stack, int order); @@ -42,7 +39,6 @@ extern void uml_pm_wake(void); extern int start_uml(void); extern void paging_init(void); -extern int parse_iomem(char *str, int *add); extern void uml_cleanup(void); extern void do_uml_exitcalls(void); @@ -55,6 +51,7 @@ extern int __uml_cant_sleep(void); extern int get_current_pid(void); extern int copy_from_user_proc(void *to, void *from, int size); extern char *uml_strdup(const char *string); +int uml_need_resched(void); extern unsigned long to_irq_stack(unsigned long *mask_out); extern unsigned long from_irq_stack(int nested); diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h index 8863319039f3d..c53e43d980c85 100644 --- a/arch/um/include/shared/longjmp.h +++ b/arch/um/include/shared/longjmp.h @@ -5,7 +5,6 @@ #include #include -extern int signals_enabled; extern int setjmp(jmp_buf); extern void longjmp(jmp_buf, int); @@ -15,7 +14,7 @@ extern void longjmp(jmp_buf, int); #define UML_SETJMP(buf) ({ \ int n, enable; \ - enable = *(volatile int *)&signals_enabled; \ + enable = um_get_signals(); \ n = setjmp(*buf); \ if(n != 0) \ um_set_signals_trace(enable); \ diff --git a/arch/um/include/shared/mem_user.h b/arch/um/include/shared/mem_user.h index d4727efcf23d0..8a5b72872ff8e 100644 --- a/arch/um/include/shared/mem_user.h +++ b/arch/um/include/shared/mem_user.h @@ -32,21 +32,8 @@ #ifndef _MEM_USER_H #define _MEM_USER_H -struct iomem_region { - struct iomem_region *next; - char *driver; - int fd; - int size; - unsigned long phys; - unsigned long virt; -}; - -extern struct iomem_region *iomem_regions; -extern int iomem_size; - #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1)) -extern unsigned long find_iomem(char *driver, unsigned long *len_out); extern void setup_physmem(unsigned long start, unsigned long usable, unsigned long len); extern void map_memory(unsigned long virt, unsigned long phys, diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index b35cc8ce333bb..b26e94292fc14 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -216,6 +216,9 @@ extern int can_drop_memory(void); void os_set_pdeathsig(void); +int os_futex_wait(void *uaddr, unsigned int val); +int os_futex_wake(void *uaddr); + /* execvp.c */ extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); /* helper.c */ @@ -243,6 +246,7 @@ extern void send_sigio_to_self(void); extern int change_sig(int signal, int on); extern void block_signals(void); extern void unblock_signals(void); +extern int um_get_signals(void); extern int um_set_signals(int enable); extern int um_set_signals_trace(int enable); extern void deliver_alarm(void); @@ -266,11 +270,12 @@ extern void os_warn(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); /* time.c */ +void os_idle_prepare(void); extern void os_idle_sleep(void); extern int os_timer_create(void); -extern int os_timer_set_interval(unsigned long long nsecs); -extern int os_timer_one_shot(unsigned long long nsecs); -extern void os_timer_disable(void); +extern int os_timer_set_interval(int cpu, unsigned long long nsecs); +extern int os_timer_one_shot(int cpu, unsigned long long nsecs); +extern void os_timer_disable(int cpu); extern long long os_persistent_clock_emulation(void); extern long long os_nsecs(void); @@ -338,4 +343,17 @@ extern void um_trace_signals_off(void); /* time-travel */ extern void deliver_time_travel_irqs(void); +/* smp.c */ +#if IS_ENABLED(CONFIG_SMP) +void os_init_smp(void); +int os_start_cpu_thread(int cpu); +void os_start_secondary(void *arg, jmp_buf *switch_buf); +int os_send_ipi(int cpu, int vector); +void os_local_ipi_enable(void); +void os_local_ipi_disable(void); +#else /* !CONFIG_SMP */ +static inline void os_local_ipi_enable(void) { } +static inline void os_local_ipi_disable(void) { } +#endif /* CONFIG_SMP */ + #endif diff --git a/arch/um/include/shared/skas/mm_id.h b/arch/um/include/shared/skas/mm_id.h index 4f977ef5dda55..fb96c0bd82228 100644 --- a/arch/um/include/shared/skas/mm_id.h +++ b/arch/um/include/shared/skas/mm_id.h @@ -6,6 +6,8 @@ #ifndef __MM_ID_H #define __MM_ID_H +#include + #define STUB_MAX_FDS 4 struct mm_id { @@ -19,6 +21,9 @@ struct mm_id { int syscall_fd_map[STUB_MAX_FDS]; }; +void enter_turnstile(struct mm_id *mm_id) __acquires(turnstile); +void exit_turnstile(struct mm_id *mm_id) __releases(turnstile); + void notify_mm_kill(int pid); #endif diff --git a/arch/um/include/shared/skas/skas.h b/arch/um/include/shared/skas/skas.h index 807514e105382..2237ffedec75b 100644 --- a/arch/um/include/shared/skas/skas.h +++ b/arch/um/include/shared/skas/skas.h @@ -15,5 +15,7 @@ extern void handle_syscall(struct uml_pt_regs *regs); extern unsigned long current_stub_stack(void); extern struct mm_id *current_mm_id(void); extern void current_mm_sync(void); +void initial_jmpbuf_lock(void); +void initial_jmpbuf_unlock(void); #endif diff --git a/arch/um/include/shared/smp.h b/arch/um/include/shared/smp.h new file mode 100644 index 0000000000000..06e3faa950913 --- /dev/null +++ b/arch/um/include/shared/smp.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __UM_SHARED_SMP_H +#define __UM_SHARED_SMP_H + +#if IS_ENABLED(CONFIG_SMP) + +extern int uml_ncpus; + +int uml_curr_cpu(void); +void uml_start_secondary(void *opaque); +void uml_ipi_handler(int vector); + +#else /* !CONFIG_SMP */ + +#define uml_ncpus 1 +#define uml_curr_cpu() 0 + +#endif /* CONFIG_SMP */ + +#endif /* __UM_SHARED_SMP_H */ diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index b8f4e92815992..be60bc451b3f9 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_GPROF) += gprof_syms.o obj-$(CONFIG_OF) += dtb.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_STACKTRACE) += stacktrace.o +obj-$(CONFIG_SMP) += smp.o USER_OBJS := config.o diff --git a/arch/um/kernel/asm-offsets.c b/arch/um/kernel/asm-offsets.c index a69873aa697f4..d620b6f6de9bb 100644 --- a/arch/um/kernel/asm-offsets.c +++ b/arch/um/kernel/asm-offsets.c @@ -1,3 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define COMPILE_OFFSETS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include +/* workaround for a warning with -Wmissing-prototypes */ +void foo(void); + +void foo(void) +{ + DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); + + DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); + DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK); + DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT); + + DEFINE(UM_GFP_KERNEL, GFP_KERNEL); + DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC); + + DEFINE(UM_THREAD_SIZE, THREAD_SIZE); + + DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); + DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC); + + DEFINE(UM_KERN_GDT_ENTRY_TLS_ENTRIES, GDT_ENTRY_TLS_ENTRIES); + + DEFINE(UM_SECCOMP_ARCH_NATIVE, SECCOMP_ARCH_NATIVE); + + DEFINE(HOSTFS_ATTR_MODE, ATTR_MODE); + DEFINE(HOSTFS_ATTR_UID, ATTR_UID); + DEFINE(HOSTFS_ATTR_GID, ATTR_GID); + DEFINE(HOSTFS_ATTR_SIZE, ATTR_SIZE); + DEFINE(HOSTFS_ATTR_ATIME, ATTR_ATIME); + DEFINE(HOSTFS_ATTR_MTIME, ATTR_MTIME); + DEFINE(HOSTFS_ATTR_CTIME, ATTR_CTIME); + DEFINE(HOSTFS_ATTR_ATIME_SET, ATTR_ATIME_SET); + DEFINE(HOSTFS_ATTR_MTIME_SET, ATTR_MTIME_SET); + + DEFINE(ALT_INSTR_SIZE, sizeof(struct alt_instr)); + DEFINE(EXTABLE_SIZE, sizeof(struct exception_table_entry)); +} diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index d69d137a0334a..f4b13f15a9c1e 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -22,6 +22,9 @@ #include #include +DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); + +#define irq_stats(x) (&per_cpu(irq_stat, x)) /* When epoll triggers we do not know why it did so * we can also have different IRQs for read and write. @@ -683,7 +686,7 @@ void __init init_IRQ(void) { int i; - irq_set_chip_and_handler(TIMER_IRQ, &alarm_irq_type, handle_edge_irq); + irq_set_chip_and_handler(TIMER_IRQ, &alarm_irq_type, handle_percpu_irq); for (i = 1; i < UM_LAST_SIGNAL_IRQ; i++) irq_set_chip_and_handler(i, &normal_irq_type, handle_edge_irq); @@ -701,3 +704,25 @@ void sigchld_handler(int sig, struct siginfo *unused_si, { do_IRQ(SIGCHLD_IRQ, regs); } + +/* + * /proc/interrupts printing for arch specific interrupts + */ +int arch_show_interrupts(struct seq_file *p, int prec) +{ +#if IS_ENABLED(CONFIG_SMP) + int cpu; + + seq_printf(p, "%*s: ", prec, "RES"); + for_each_online_cpu(cpu) + seq_printf(p, "%10u ", irq_stats(cpu)->irq_resched_count); + seq_puts(p, " Rescheduling interrupts\n"); + + seq_printf(p, "%*s: ", prec, "CAL"); + for_each_online_cpu(cpu) + seq_printf(p, "%10u ", irq_stats(cpu)->irq_call_count); + seq_puts(p, " Function call interrupts\n"); +#endif + + return 0; +} diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index f2fb77da08cff..96314c31e61c1 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -6,8 +6,8 @@ #include #include +EXPORT_SYMBOL(um_get_signals); EXPORT_SYMBOL(um_set_signals); -EXPORT_SYMBOL(signals_enabled); EXPORT_SYMBOL(os_stat_fd); EXPORT_SYMBOL(os_stat_file); diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 32e3b1972dc12..39c4a7e21c6fc 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -71,7 +71,7 @@ void __init arch_mm_preinit(void) /* Map in the area just after the brk now that kmalloc is about * to be turned on. */ - brk_end = (unsigned long) UML_ROUND_UP(sbrk(0)); + brk_end = PAGE_ALIGN((unsigned long) sbrk(0)); map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0); memblock_free((void *)brk_end, uml_reserved - brk_end); uml_reserved = brk_end; @@ -84,109 +84,6 @@ void __init mem_init(void) kmalloc_ok = 1; } -#if IS_ENABLED(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) -/* - * Create a page table and place a pointer to it in a middle page - * directory entry. - */ -static void __init one_page_table_init(pmd_t *pmd) -{ - if (pmd_none(*pmd)) { - pte_t *pte = (pte_t *) memblock_alloc_low(PAGE_SIZE, - PAGE_SIZE); - if (!pte) - panic("%s: Failed to allocate %lu bytes align=%lx\n", - __func__, PAGE_SIZE, PAGE_SIZE); - - set_pmd(pmd, __pmd(_KERNPG_TABLE + - (unsigned long) __pa(pte))); - BUG_ON(pte != pte_offset_kernel(pmd, 0)); - } -} - -static void __init one_md_table_init(pud_t *pud) -{ -#if CONFIG_PGTABLE_LEVELS > 2 - pmd_t *pmd_table = (pmd_t *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE); - if (!pmd_table) - panic("%s: Failed to allocate %lu bytes align=%lx\n", - __func__, PAGE_SIZE, PAGE_SIZE); - - set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table))); - BUG_ON(pmd_table != pmd_offset(pud, 0)); -#endif -} - -static void __init one_ud_table_init(p4d_t *p4d) -{ -#if CONFIG_PGTABLE_LEVELS > 3 - pud_t *pud_table = (pud_t *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE); - if (!pud_table) - panic("%s: Failed to allocate %lu bytes align=%lx\n", - __func__, PAGE_SIZE, PAGE_SIZE); - - set_p4d(p4d, __p4d(_KERNPG_TABLE + (unsigned long) __pa(pud_table))); - BUG_ON(pud_table != pud_offset(p4d, 0)); -#endif -} - -static void __init fixrange_init(unsigned long start, unsigned long end, - pgd_t *pgd_base) -{ - pgd_t *pgd; - p4d_t *p4d; - pud_t *pud; - pmd_t *pmd; - int i, j; - unsigned long vaddr; - - vaddr = start; - i = pgd_index(vaddr); - j = pmd_index(vaddr); - pgd = pgd_base + i; - - for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { - p4d = p4d_offset(pgd, vaddr); - if (p4d_none(*p4d)) - one_ud_table_init(p4d); - pud = pud_offset(p4d, vaddr); - if (pud_none(*pud)) - one_md_table_init(pud); - pmd = pmd_offset(pud, vaddr); - for (; (j < PTRS_PER_PMD) && (vaddr < end); pmd++, j++) { - one_page_table_init(pmd); - vaddr += PMD_SIZE; - } - j = 0; - } -} - -static void __init fixaddr_user_init( void) -{ - long size = FIXADDR_USER_END - FIXADDR_USER_START; - pte_t *pte; - phys_t p; - unsigned long v, vaddr = FIXADDR_USER_START; - - if (!size) - return; - - fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir); - v = (unsigned long) memblock_alloc_low(size, PAGE_SIZE); - if (!v) - panic("%s: Failed to allocate %lu bytes align=%lx\n", - __func__, size, PAGE_SIZE); - - memcpy((void *) v , (void *) FIXADDR_USER_START, size); - p = __pa(v); - for ( ; size > 0; size -= PAGE_SIZE, vaddr += PAGE_SIZE, - p += PAGE_SIZE) { - pte = virt_to_kpte(vaddr); - pte_set_val(*pte, p, PAGE_READONLY); - } -} -#endif - void __init paging_init(void) { unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; @@ -197,12 +94,8 @@ void __init paging_init(void) panic("%s: Failed to allocate %lu bytes align=%lx\n", __func__, PAGE_SIZE, PAGE_SIZE); - max_zone_pfn[ZONE_NORMAL] = end_iomem >> PAGE_SHIFT; + max_zone_pfn[ZONE_NORMAL] = high_physmem >> PAGE_SHIFT; free_area_init(max_zone_pfn); - -#if IS_ENABLED(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) - fixaddr_user_init(); -#endif } /* diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index af02b5f9911d3..ae6ca373c2610 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -105,19 +105,6 @@ int phys_mapping(unsigned long phys, unsigned long long *offset_out) fd = physmem_fd; *offset_out = phys; } - else if (phys < __pa(end_iomem)) { - struct iomem_region *region = iomem_regions; - - while (region != NULL) { - if ((phys >= region->phys) && - (phys < region->phys + region->size)) { - fd = region->fd; - *offset_out = phys - region->phys; - break; - } - region = region->next; - } - } return fd; } @@ -140,61 +127,3 @@ __uml_setup("mem=", uml_mem_setup, " be more, and the excess, if it's ever used, will just be swapped out.\n" " Example: mem=64M\n\n" ); - -__uml_setup("iomem=", parse_iomem, -"iomem=,\n" -" Configure as an IO memory region named .\n\n" -); - -/* - * This list is constructed in parse_iomem and addresses filled in - * setup_iomem, both of which run during early boot. Afterwards, it's - * unchanged. - */ -struct iomem_region *iomem_regions; - -/* Initialized in parse_iomem and unchanged thereafter */ -int iomem_size; - -unsigned long find_iomem(char *driver, unsigned long *len_out) -{ - struct iomem_region *region = iomem_regions; - - while (region != NULL) { - if (!strcmp(region->driver, driver)) { - *len_out = region->size; - return region->virt; - } - - region = region->next; - } - - return 0; -} -EXPORT_SYMBOL(find_iomem); - -static int setup_iomem(void) -{ - struct iomem_region *region = iomem_regions; - unsigned long iomem_start = high_physmem + PAGE_SIZE; - int err; - - while (region != NULL) { - err = os_map_memory((void *) iomem_start, region->fd, 0, - region->size, 1, 1, 0); - if (err) - printk(KERN_ERR "Mapping iomem region for driver '%s' " - "failed, errno = %d\n", region->driver, -err); - else { - region->virt = iomem_start; - region->phys = __pa(region->virt); - } - - iomem_start += region->size + PAGE_SIZE; - region = region->next; - } - - return 0; -} - -__initcall(setup_iomem); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 9c9c66dc45f05..63b38a3f73f78 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -43,7 +43,9 @@ * cares about its entry, so it's OK if another processor is modifying its * entry. */ -struct task_struct *cpu_tasks[NR_CPUS]; +struct task_struct *cpu_tasks[NR_CPUS] = { + [0 ... NR_CPUS - 1] = &init_task, +}; EXPORT_SYMBOL(cpu_tasks); void free_stack(unsigned long stack, int order) @@ -185,11 +187,7 @@ int copy_thread(struct task_struct * p, const struct kernel_clone_args *args) void initial_thread_cb(void (*proc)(void *), void *arg) { - int save_kmalloc_ok = kmalloc_ok; - - kmalloc_ok = 0; initial_thread_cb_skas(proc, arg); - kmalloc_ok = save_kmalloc_ok; } int arch_dup_task_struct(struct task_struct *dst, @@ -220,11 +218,21 @@ void arch_cpu_idle(void) um_idle_sleep(); } +void arch_cpu_idle_prepare(void) +{ + os_idle_prepare(); +} + int __uml_cant_sleep(void) { return in_atomic() || irqs_disabled() || in_interrupt(); /* Is in_interrupt() really needed? */ } +int uml_need_resched(void) +{ + return need_resched(); +} + extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; void do_uml_exitcalls(void) diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index afe9a2f251efd..00957788591b3 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -23,17 +23,36 @@ static_assert(sizeof(struct stub_data) == STUB_DATA_PAGES * UM_KERN_PAGE_SIZE); static spinlock_t mm_list_lock; static struct list_head mm_list; +void enter_turnstile(struct mm_id *mm_id) __acquires(turnstile) +{ + struct mm_context *ctx = container_of(mm_id, struct mm_context, id); + + mutex_lock(&ctx->turnstile); +} + +void exit_turnstile(struct mm_id *mm_id) __releases(turnstile) +{ + struct mm_context *ctx = container_of(mm_id, struct mm_context, id); + + mutex_unlock(&ctx->turnstile); +} + int init_new_context(struct task_struct *task, struct mm_struct *mm) { struct mm_id *new_id = &mm->context.id; unsigned long stack = 0; int ret = -ENOMEM; + mutex_init(&mm->context.turnstile); + spin_lock_init(&mm->context.sync_tlb_lock); + stack = __get_free_pages(GFP_KERNEL | __GFP_ZERO, ilog2(STUB_DATA_PAGES)); if (stack == 0) goto out; new_id->stack = stack; + new_id->syscall_data_len = 0; + new_id->syscall_fd_num = 0; scoped_guard(spinlock_irqsave, &mm_list_lock) { /* Insert into list, used for lookups when the child dies */ @@ -73,6 +92,9 @@ void destroy_context(struct mm_struct *mm) return; } + scoped_guard(spinlock_irqsave, &mm_list_lock) + list_del(&mm->context.list); + if (mmu->id.pid > 0) { os_kill_ptraced_process(mmu->id.pid, 1); mmu->id.pid = -1; @@ -82,10 +104,6 @@ void destroy_context(struct mm_struct *mm) os_close_file(mmu->id.sock); free_pages(mmu->id.stack, ilog2(STUB_DATA_PAGES)); - - guard(spinlock_irqsave)(&mm_list_lock); - - list_del(&mm->context.list); } static irqreturn_t mm_sigchld_irq(int irq, void* dev) @@ -110,12 +128,11 @@ static irqreturn_t mm_sigchld_irq(int irq, void* dev) /* Marks the MM as dead */ mm_context->id.pid = -1; - /* - * NOTE: If SMP is implemented, a futex_wake - * needs to be added here. - */ stub_data = (void *)mm_context->id.stack; stub_data->futex = FUTEX_IN_KERN; +#if IS_ENABLED(CONFIG_SMP) + os_futex_wake(&stub_data->futex); +#endif /* * NOTE: Currently executing syscalls by diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 5881b17eb9874..4a7673b0261a8 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -26,12 +27,12 @@ static int __init start_kernel_proc(void *unused) return 0; } -static char cpu0_irqstack[THREAD_SIZE] __aligned(THREAD_SIZE); +char cpu_irqstacks[NR_CPUS][THREAD_SIZE] __aligned(THREAD_SIZE); int __init start_uml(void) { - stack_protections((unsigned long) &cpu0_irqstack); - set_sigstack(cpu0_irqstack, THREAD_SIZE); + stack_protections((unsigned long) &cpu_irqstacks[0]); + set_sigstack(cpu_irqstacks[0], THREAD_SIZE); init_new_thread_signals(); @@ -64,3 +65,15 @@ void current_mm_sync(void) um_tlb_sync(current->mm); } + +static DEFINE_SPINLOCK(initial_jmpbuf_spinlock); + +void initial_jmpbuf_lock(void) +{ + spin_lock_irq(&initial_jmpbuf_spinlock); +} + +void initial_jmpbuf_unlock(void) +{ + spin_unlock_irq(&initial_jmpbuf_spinlock); +} diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c new file mode 100644 index 0000000000000..f1e52b7348fb8 --- /dev/null +++ b/arch/um/kernel/smp.c @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Ant Group + * Author: Tiwei Bie + * + * Based on the previous implementation in TT mode + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + UML_IPI_RES = 0, + UML_IPI_CALL_SINGLE, + UML_IPI_CALL, + UML_IPI_STOP, +}; + +void arch_smp_send_reschedule(int cpu) +{ + os_send_ipi(cpu, UML_IPI_RES); +} + +void arch_send_call_function_single_ipi(int cpu) +{ + os_send_ipi(cpu, UML_IPI_CALL_SINGLE); +} + +void arch_send_call_function_ipi_mask(const struct cpumask *mask) +{ + int cpu; + + for_each_cpu(cpu, mask) + os_send_ipi(cpu, UML_IPI_CALL); +} + +void smp_send_stop(void) +{ + int cpu, me = smp_processor_id(); + + for_each_online_cpu(cpu) { + if (cpu == me) + continue; + os_send_ipi(cpu, UML_IPI_STOP); + } +} + +static void ipi_handler(int vector, struct uml_pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs); + int cpu = raw_smp_processor_id(); + + irq_enter(); + + if (current->mm) + os_alarm_process(current->mm->context.id.pid); + + switch (vector) { + case UML_IPI_RES: + inc_irq_stat(irq_resched_count); + scheduler_ipi(); + break; + + case UML_IPI_CALL_SINGLE: + inc_irq_stat(irq_call_count); + generic_smp_call_function_single_interrupt(); + break; + + case UML_IPI_CALL: + inc_irq_stat(irq_call_count); + generic_smp_call_function_interrupt(); + break; + + case UML_IPI_STOP: + set_cpu_online(cpu, false); + while (1) + pause(); + break; + + default: + pr_err("CPU#%d received unknown IPI (vector=%d)!\n", cpu, vector); + break; + } + + irq_exit(); + set_irq_regs(old_regs); +} + +void uml_ipi_handler(int vector) +{ + struct uml_pt_regs r = { .is_user = 0 }; + + preempt_disable(); + ipi_handler(vector, &r); + preempt_enable(); +} + +/* AP states used only during CPU startup */ +enum { + UML_CPU_PAUSED = 0, + UML_CPU_RUNNING, +}; + +static int cpu_states[NR_CPUS]; + +static int start_secondary(void *unused) +{ + int err, cpu = raw_smp_processor_id(); + + notify_cpu_starting(cpu); + set_cpu_online(cpu, true); + + err = um_setup_timer(); + if (err) + panic("CPU#%d failed to setup timer, err = %d", cpu, err); + + local_irq_enable(); + + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); + + return 0; +} + +void uml_start_secondary(void *opaque) +{ + int cpu = raw_smp_processor_id(); + struct mm_struct *mm = &init_mm; + struct task_struct *idle; + + stack_protections((unsigned long) &cpu_irqstacks[cpu]); + set_sigstack(&cpu_irqstacks[cpu], THREAD_SIZE); + + set_cpu_present(cpu, true); + os_futex_wait(&cpu_states[cpu], UML_CPU_PAUSED); + + smp_rmb(); /* paired with smp_wmb() in __cpu_up() */ + + idle = cpu_tasks[cpu]; + idle->thread_info.cpu = cpu; + + mmgrab(mm); + idle->active_mm = mm; + + idle->thread.request.thread.proc = start_secondary; + idle->thread.request.thread.arg = NULL; + + new_thread(task_stack_page(idle), &idle->thread.switch_buf, + new_thread_handler); + os_start_secondary(opaque, &idle->thread.switch_buf); +} + +void __init smp_prepare_cpus(unsigned int max_cpus) +{ + int err, cpu, me = smp_processor_id(); + unsigned long deadline; + + os_init_smp(); + + for_each_possible_cpu(cpu) { + if (cpu == me) + continue; + + pr_debug("Booting processor %d...\n", cpu); + err = os_start_cpu_thread(cpu); + if (err) { + pr_crit("CPU#%d failed to start cpu thread, err = %d", + cpu, err); + continue; + } + + deadline = jiffies + msecs_to_jiffies(1000); + spin_until_cond(cpu_present(cpu) || + time_is_before_jiffies(deadline)); + + if (!cpu_present(cpu)) + pr_crit("CPU#%d failed to boot\n", cpu); + } +} + +int __cpu_up(unsigned int cpu, struct task_struct *tidle) +{ + cpu_tasks[cpu] = tidle; + smp_wmb(); /* paired with smp_rmb() in uml_start_secondary() */ + cpu_states[cpu] = UML_CPU_RUNNING; + os_futex_wake(&cpu_states[cpu]); + spin_until_cond(cpu_online(cpu)); + + return 0; +} + +void __init smp_cpus_done(unsigned int max_cpus) +{ +} + +/* Set in uml_ncpus_setup */ +int uml_ncpus = 1; + +void __init prefill_possible_map(void) +{ + int cpu; + + for (cpu = 0; cpu < uml_ncpus; cpu++) + set_cpu_possible(cpu, true); + for (; cpu < NR_CPUS; cpu++) + set_cpu_possible(cpu, false); +} + +static int __init uml_ncpus_setup(char *line, int *add) +{ + *add = 0; + + if (kstrtoint(line, 10, ¨_ncpus)) { + os_warn("%s: Couldn't parse '%s'\n", __func__, line); + return -1; + } + + uml_ncpus = clamp(uml_ncpus, 1, NR_CPUS); + + return 0; +} + +__uml_setup("ncpus=", uml_ncpus_setup, +"ncpus=<# of desired CPUs>\n" +" This tells UML how many virtual processors to start. The maximum\n" +" number of supported virtual processors can be obtained by querying\n" +" the CONFIG_NR_CPUS option using --showconfig.\n\n" +); + +EXPORT_SYMBOL(uml_curr_cpu); diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 17da0a870650a..b344a36b44eb1 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -625,9 +625,10 @@ void time_travel_sleep(void) * controller application. */ unsigned long long next = S64_MAX; + int cpu = raw_smp_processor_id(); if (time_travel_mode == TT_MODE_BASIC) - os_timer_disable(); + os_timer_disable(cpu); time_travel_update_time(next, true); @@ -638,9 +639,9 @@ void time_travel_sleep(void) * This is somewhat wrong - we should get the first * one sooner like the os_timer_one_shot() below... */ - os_timer_set_interval(time_travel_timer_interval); + os_timer_set_interval(cpu, time_travel_timer_interval); } else { - os_timer_one_shot(time_travel_timer_event.time - next); + os_timer_one_shot(cpu, time_travel_timer_event.time - next); } } } @@ -758,6 +759,8 @@ extern u64 time_travel_ext_req(u32 op, u64 time); #define time_travel_del_event(e) do { } while (0) #endif +static struct clock_event_device timer_clockevent[NR_CPUS]; + void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) { unsigned long flags; @@ -780,12 +783,14 @@ void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) static int itimer_shutdown(struct clock_event_device *evt) { + int cpu = evt - &timer_clockevent[0]; + if (time_travel_mode != TT_MODE_OFF) time_travel_del_event(&time_travel_timer_event); if (time_travel_mode != TT_MODE_INFCPU && time_travel_mode != TT_MODE_EXTERNAL) - os_timer_disable(); + os_timer_disable(cpu); return 0; } @@ -793,6 +798,7 @@ static int itimer_shutdown(struct clock_event_device *evt) static int itimer_set_periodic(struct clock_event_device *evt) { unsigned long long interval = NSEC_PER_SEC / HZ; + int cpu = evt - &timer_clockevent[0]; if (time_travel_mode != TT_MODE_OFF) { time_travel_del_event(&time_travel_timer_event); @@ -805,7 +811,7 @@ static int itimer_set_periodic(struct clock_event_device *evt) if (time_travel_mode != TT_MODE_INFCPU && time_travel_mode != TT_MODE_EXTERNAL) - os_timer_set_interval(interval); + os_timer_set_interval(cpu, interval); return 0; } @@ -825,7 +831,7 @@ static int itimer_next_event(unsigned long delta, if (time_travel_mode != TT_MODE_INFCPU && time_travel_mode != TT_MODE_EXTERNAL) - return os_timer_one_shot(delta); + return os_timer_one_shot(raw_smp_processor_id(), delta); return 0; } @@ -835,10 +841,9 @@ static int itimer_one_shot(struct clock_event_device *evt) return itimer_next_event(0, evt); } -static struct clock_event_device timer_clockevent = { +static struct clock_event_device _timer_clockevent = { .name = "posix-timer", .rating = 250, - .cpumask = cpu_possible_mask, .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .set_state_shutdown = itimer_shutdown, @@ -856,6 +861,9 @@ static struct clock_event_device timer_clockevent = { static irqreturn_t um_timer(int irq, void *dev) { + int cpu = raw_smp_processor_id(); + struct clock_event_device *evt = &timer_clockevent[cpu]; + /* * Interrupt the (possibly) running userspace process, technically this * should only happen if userspace is currently executing. @@ -867,7 +875,7 @@ static irqreturn_t um_timer(int irq, void *dev) get_current()->mm) os_alarm_process(get_current()->mm->context.id.pid); - (*timer_clockevent.event_handler)(&timer_clockevent); + evt->event_handler(evt); return IRQ_HANDLED; } @@ -904,7 +912,24 @@ static struct clocksource timer_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init um_timer_setup(void) +int um_setup_timer(void) +{ + int cpu = raw_smp_processor_id(); + struct clock_event_device *evt = &timer_clockevent[cpu]; + int err; + + err = os_timer_create(); + if (err) + return err; + + memcpy(evt, &_timer_clockevent, sizeof(*evt)); + evt->cpumask = cpumask_of(cpu); + clockevents_register_device(evt); + + return 0; +} + +static void __init um_timer_init(void) { int err; @@ -913,8 +938,8 @@ static void __init um_timer_setup(void) printk(KERN_ERR "register_timer : request_irq failed - " "errno = %d\n", -err); - err = os_timer_create(); - if (err != 0) { + err = um_setup_timer(); + if (err) { printk(KERN_ERR "creation of timer failed - errno = %d\n", -err); return; } @@ -924,7 +949,6 @@ static void __init um_timer_setup(void) printk(KERN_ERR "clocksource_register_hz returned %d\n", err); return; } - clockevents_register_device(&timer_clockevent); } void read_persistent_clock64(struct timespec64 *ts) @@ -945,7 +969,7 @@ void read_persistent_clock64(struct timespec64 *ts) void __init time_init(void) { timer_set_signal_handler(); - late_time_init = um_timer_setup; + late_time_init = um_timer_init; } #ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT @@ -961,21 +985,21 @@ static int setup_time_travel(char *str) { if (strcmp(str, "=inf-cpu") == 0) { time_travel_mode = TT_MODE_INFCPU; - timer_clockevent.name = "time-travel-timer-infcpu"; + _timer_clockevent.name = "time-travel-timer-infcpu"; timer_clocksource.name = "time-travel-clock"; return 1; } if (strncmp(str, "=ext:", 5) == 0) { time_travel_mode = TT_MODE_EXTERNAL; - timer_clockevent.name = "time-travel-timer-external"; + _timer_clockevent.name = "time-travel-timer-external"; timer_clocksource.name = "time-travel-clock-external"; return time_travel_connect_external(str + 5); } if (!*str) { time_travel_mode = TT_MODE_BASIC; - timer_clockevent.name = "time-travel-timer"; + _timer_clockevent.name = "time-travel-timer"; timer_clocksource.name = "time-travel-clock"; return 1; } diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index cf7e0d4407f2c..39608cccf2c69 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -162,9 +162,11 @@ int um_tlb_sync(struct mm_struct *mm) { pgd_t *pgd; struct vm_ops ops; - unsigned long addr = mm->context.sync_tlb_range_from, next; + unsigned long addr, next; int ret = 0; + guard(spinlock_irqsave)(&mm->context.sync_tlb_lock); + if (mm->context.sync_tlb_range_to == 0) return 0; @@ -177,6 +179,7 @@ int um_tlb_sync(struct mm_struct *mm) ops.unmap = unmap; } + addr = mm->context.sync_tlb_range_from; pgd = pgd_offset(mm, addr); do { next = pgd_addr_end(addr, mm->context.sync_tlb_range_to); diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 5b80a3a89c201..177615820a4cc 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -316,7 +316,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, if (!is_user && regs) current->thread.segv_regs = container_of(regs, struct pt_regs, regs); - if (!is_user && init_mm.context.sync_tlb_range_to) { + if (!is_user && address >= start_vm && address < end_vm) { /* * Kernel has pending updates from set_ptes that were not * flushed yet. Syncing them should fix the pagefault (if not diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index cfbbbf8500c34..e2b24e1ecfa64 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -71,6 +72,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) { int i = 0; +#if IS_ENABLED(CONFIG_SMP) + i = (uintptr_t) v - 1; + if (!cpu_online(i)) + return 0; +#endif + seq_printf(m, "processor\t: %d\n", i); seq_printf(m, "vendor_id\t: User Mode Linux\n"); seq_printf(m, "model name\t: UML\n"); @@ -87,13 +94,14 @@ static int show_cpuinfo(struct seq_file *m, void *v) loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ)) % 100); - return 0; } static void *c_start(struct seq_file *m, loff_t *pos) { - return *pos < nr_cpu_ids ? &boot_cpu_data + *pos : NULL; + if (*pos < nr_cpu_ids) + return (void *)(uintptr_t)(*pos + 1); + return NULL; } static void *c_next(struct seq_file *m, void *v, loff_t *pos) @@ -239,8 +247,6 @@ static struct notifier_block panic_exit_notifier = { void uml_finishsetup(void) { - cpu_tasks[0] = &init_task; - atomic_notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); @@ -254,11 +260,7 @@ unsigned long stub_start; unsigned long task_size; EXPORT_SYMBOL(task_size); -unsigned long host_task_size; - unsigned long brk_start; -unsigned long end_iomem; -EXPORT_SYMBOL(end_iomem); #define MIN_VMALLOC (32 * 1024 * 1024) @@ -298,16 +300,14 @@ static unsigned long __init get_top_address(char **envp) top_addr = (unsigned long) envp[i]; } - top_addr &= ~(UM_KERN_PAGE_SIZE - 1); - top_addr += UM_KERN_PAGE_SIZE; - - return top_addr; + return PAGE_ALIGN(top_addr + 1); } int __init linux_main(int argc, char **argv, char **envp) { unsigned long avail, diff; unsigned long virtmem_size, max_physmem; + unsigned long host_task_size; unsigned long stack; unsigned int i; int add; @@ -354,12 +354,11 @@ int __init linux_main(int argc, char **argv, char **envp) * so they actually get what they asked for. This should * add zero for non-exec shield users */ - - diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); + diff = PAGE_ALIGN(brk_start) - PAGE_ALIGN((unsigned long) &_end); if (diff > 1024 * 1024) { os_info("Adding %ld bytes to physical memory to account for " "exec-shield gap\n", diff); - physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); + physmem_size += diff; } uml_physmem = (unsigned long) __binary_start & PAGE_MASK; @@ -369,10 +368,8 @@ int __init linux_main(int argc, char **argv, char **envp) setup_machinename(init_utsname()->machine); - physmem_size = (physmem_size + PAGE_SIZE - 1) & PAGE_MASK; - iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; - - max_physmem = TASK_SIZE - uml_physmem - iomem_size - MIN_VMALLOC; + physmem_size = PAGE_ALIGN(physmem_size); + max_physmem = TASK_SIZE - uml_physmem - MIN_VMALLOC; if (physmem_size > max_physmem) { physmem_size = max_physmem; os_info("Physical memory size shrunk to %llu bytes\n", @@ -380,7 +377,6 @@ int __init linux_main(int argc, char **argv, char **envp) } high_physmem = uml_physmem + physmem_size; - end_iomem = high_physmem + iomem_size; start_vm = VMALLOC_START; @@ -421,6 +417,7 @@ void __init setup_arch(char **cmdline_p) strscpy(boot_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; setup_hostinfo(host_info, sizeof host_info); + prefill_possible_map(); if (os_getrandom(rng_seed, sizeof(rng_seed), 0) == sizeof(rng_seed)) { add_bootloader_randomness(rng_seed, sizeof(rng_seed)); @@ -455,6 +452,18 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) { } +#if IS_ENABLED(CONFIG_SMP) +void alternatives_smp_module_add(struct module *mod, char *name, + void *locks, void *locks_end, + void *text, void *text_end) +{ +} + +void alternatives_smp_module_del(struct module *mod) +{ +} +#endif + void *text_poke(void *addr, const void *opcode, size_t len) { /* diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index fae836713487b..f8d672d570d9b 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -6,7 +6,7 @@ # Don't instrument UML-specific code KCOV_INSTRUMENT := n -obj-y = execvp.o file.o helper.o irq.o main.o mem.o process.o \ +obj-y = elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ registers.o sigio.o signal.o start_up.o time.o tty.o \ umid.o user_syms.o util.o skas/ @@ -14,10 +14,10 @@ CFLAGS_signal.o += -Wframe-larger-than=4096 CFLAGS_main.o += -Wno-frame-larger-than -obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o +obj-$(CONFIG_SMP) += smp.o USER_OBJS := $(user-objs-y) elf_aux.o execvp.o file.o helper.o irq.o \ main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ - tty.o umid.o util.o + tty.o umid.o util.o smp.o include $(srctree)/arch/um/scripts/Makefile.rules diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 0a0f91cf4d6d5..72f416edf2524 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -14,37 +14,26 @@ #include #include #include "internal.h" +#include +#if __BITS_PER_LONG == 64 +typedef Elf64_auxv_t elf_auxv_t; +#else typedef Elf32_auxv_t elf_auxv_t; +#endif /* These are initialized very early in boot and never changed */ char * elf_aux_platform; -extern long elf_aux_hwcap; -unsigned long vsyscall_ehdr; -unsigned long vsyscall_end; -unsigned long __kernel_vsyscall; +long elf_aux_hwcap; __init void scan_elf_aux( char **envp) { - long page_size = 0; elf_auxv_t * auxv; while ( *envp++ != NULL) ; for ( auxv = (elf_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) { switch ( auxv->a_type ) { - case AT_SYSINFO: - __kernel_vsyscall = auxv->a_un.a_val; - /* See if the page is under TASK_SIZE */ - if (__kernel_vsyscall < (unsigned long) envp) - __kernel_vsyscall = 0; - break; - case AT_SYSINFO_EHDR: - vsyscall_ehdr = auxv->a_un.a_val; - /* See if the page is under TASK_SIZE */ - if (vsyscall_ehdr < (unsigned long) envp) - vsyscall_ehdr = 0; - break; case AT_HWCAP: elf_aux_hwcap = auxv->a_un.a_val; break; @@ -56,20 +45,6 @@ __init void scan_elf_aux( char **envp) elf_aux_platform = (char *) (long) auxv->a_un.a_val; break; - case AT_PAGESZ: - page_size = auxv->a_un.a_val; - break; } } - if ( ! __kernel_vsyscall || ! vsyscall_ehdr || - ! elf_aux_hwcap || ! elf_aux_platform || - ! page_size || (vsyscall_ehdr % page_size) ) { - __kernel_vsyscall = 0; - vsyscall_ehdr = 0; - elf_aux_hwcap = 0; - elf_aux_platform = "i586"; - } - else { - vsyscall_end = vsyscall_ehdr + page_size; - } } diff --git a/arch/um/os-Linux/internal.h b/arch/um/os-Linux/internal.h index 5d8d3b0817a95..bac9fcc8c14c5 100644 --- a/arch/um/os-Linux/internal.h +++ b/arch/um/os-Linux/internal.h @@ -4,6 +4,7 @@ #include #include +#include /* * elf_aux.c @@ -15,9 +16,21 @@ void scan_elf_aux(char **envp); */ void check_tmpexec(void); +/* + * signal.c + */ +extern __thread int signals_enabled; +int timer_alarm_pending(void); + /* * skas/process.c */ void wait_stub_done(int pid); void wait_stub_done_seccomp(struct mm_id *mm_idp, int running, int wait_sigsys); + +/* + * smp.c + */ +#define IPI_SIGNAL SIGRTMIN + #endif /* __UM_OS_LINUX_INTERNAL_H */ diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 3c63ce19e3bf5..7e114862a7235 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -21,8 +21,6 @@ #define STACKSIZE (8 * 1024 * 1024) -long elf_aux_hwcap; - static void __init set_stklim(void) { struct rlimit lim; @@ -149,9 +147,7 @@ int __init main(int argc, char **argv, char **envp) install_fatal_handler(SIGINT); install_fatal_handler(SIGTERM); -#ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA scan_elf_aux(envp); -#endif change_sig(SIGPIPE, 0); ret = linux_main(argc, argv, envp); @@ -171,7 +167,7 @@ int __init main(int argc, char **argv, char **envp) */ /* stop timers and set timer signal to be ignored */ - os_timer_disable(); + os_timer_disable(0); /* disable SIGIO for the fds and set SIGIO to be ignored */ err = deactivate_all_fds(); diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 00b49e90d05fe..3a2a84ab93257 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -189,3 +191,21 @@ void os_set_pdeathsig(void) { prctl(PR_SET_PDEATHSIG, SIGKILL); } + +int os_futex_wait(void *uaddr, unsigned int val) +{ + int r; + + CATCH_EINTR(r = syscall(__NR_futex, uaddr, FUTEX_WAIT, val, + NULL, NULL, 0)); + return r < 0 ? -errno : r; +} + +int os_futex_wake(void *uaddr) +{ + int r; + + CATCH_EINTR(r = syscall(__NR_futex, uaddr, FUTEX_WAKE, INT_MAX, + NULL, NULL, 0)); + return r < 0 ? -errno : r; +} diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 11f07f4982700..327fb3c52fc79 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -20,6 +20,7 @@ #include #include #include +#include "internal.h" void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *, void *mc) = { [SIGTRAP] = relay_signal, @@ -68,12 +69,12 @@ static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc) #define SIGCHLD_BIT 2 #define SIGCHLD_MASK (1 << SIGCHLD_BIT) -int signals_enabled; +__thread int signals_enabled; #if IS_ENABLED(CONFIG_UML_TIME_TRAVEL_SUPPORT) static int signals_blocked, signals_blocked_pending; #endif -static unsigned int signals_pending; -static unsigned int signals_active = 0; +static __thread unsigned int signals_pending; +static __thread unsigned int signals_active; static void sig_handler(int sig, struct siginfo *si, mcontext_t *mc) { @@ -159,6 +160,11 @@ void timer_set_signal_handler(void) set_handler(SIGALRM); } +int timer_alarm_pending(void) +{ + return !!(signals_pending & SIGALRM_MASK); +} + void set_sigstack(void *sig_stack, int size) { stack_t stack = { @@ -253,9 +259,29 @@ int change_sig(int signal, int on) return 0; } -void block_signals(void) +static inline void __block_signals(void) { + if (!signals_enabled) + return; + + os_local_ipi_disable(); + barrier(); signals_enabled = 0; +} + +static inline void __unblock_signals(void) +{ + if (signals_enabled) + return; + + signals_enabled = 1; + barrier(); + os_local_ipi_enable(); +} + +void block_signals(void) +{ + __block_signals(); /* * This must return with signals disabled, so this barrier * ensures that writes are flushed out before the return. @@ -272,7 +298,8 @@ void unblock_signals(void) if (signals_enabled == 1) return; - signals_enabled = 1; + __unblock_signals(); + #if IS_ENABLED(CONFIG_UML_TIME_TRAVEL_SUPPORT) deliver_time_travel_irqs(); #endif @@ -306,7 +333,7 @@ void unblock_signals(void) * tracing that happens inside the handlers we call for the * pending signals will mess up the tracing state. */ - signals_enabled = 0; + __block_signals(); um_trace_signals_off(); /* @@ -338,10 +365,15 @@ void unblock_signals(void) /* Re-enable signals and trace that we're doing so. */ um_trace_signals_on(); - signals_enabled = 1; + __unblock_signals(); } } +int um_get_signals(void) +{ + return signals_enabled; +} + int um_set_signals(int enable) { int ret; diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 0bc10cd4cbed4..d6c22f8aa06d1 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -298,7 +298,6 @@ static int userspace_tramp(void *data) .seccomp = using_seccomp, .stub_start = STUB_START, }; - struct iomem_region *iomem; int ret; if (using_seccomp) { @@ -332,12 +331,6 @@ static int userspace_tramp(void *data) fcntl(init_data.stub_data_fd, F_SETFD, 0); - /* In SECCOMP mode, these FDs are passed when needed */ - if (!using_seccomp) { - for (iomem = iomem_regions; iomem; iomem = iomem->next) - fcntl(iomem->fd, F_SETFD, 0); - } - /* dup2 signaling FD/socket to STDIN */ if (dup2(tramp_data->sockpair[0], 0) < 0) exit(3); @@ -553,7 +546,7 @@ extern unsigned long tt_extra_sched_jiffies; void userspace(struct uml_pt_regs *regs) { int err, status, op; - siginfo_t si_ptrace; + siginfo_t si_local; siginfo_t *si; int sig; @@ -563,6 +556,13 @@ void userspace(struct uml_pt_regs *regs) while (1) { struct mm_id *mm_id = current_mm_id(); + /* + * At any given time, only one CPU thread can enter the + * turnstile to operate on the same stub process, including + * executing stub system calls (mmap and munmap). + */ + enter_turnstile(mm_id); + /* * When we are in time-travel mode, userspace can theoretically * do a *lot* of work without being scheduled. The problem with @@ -630,9 +630,10 @@ void userspace(struct uml_pt_regs *regs) } if (proc_data->si_offset > sizeof(proc_data->sigstack) - sizeof(*si)) - panic("%s - Invalid siginfo offset from child", - __func__); - si = (void *)&proc_data->sigstack[proc_data->si_offset]; + panic("%s - Invalid siginfo offset from child", __func__); + + si = &si_local; + memcpy(si, &proc_data->sigstack[proc_data->si_offset], sizeof(*si)); regs->is_user = 1; @@ -728,8 +729,8 @@ void userspace(struct uml_pt_regs *regs) case SIGFPE: case SIGWINCH: ptrace(PTRACE_GETSIGINFO, pid, 0, - (struct siginfo *)&si_ptrace); - si = &si_ptrace; + (struct siginfo *)&si_local); + si = &si_local; break; default: si = NULL; @@ -740,6 +741,8 @@ void userspace(struct uml_pt_regs *regs) } } + exit_turnstile(mm_id); + UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ if (sig) { @@ -809,10 +812,9 @@ void switch_threads(jmp_buf *me, jmp_buf *you) static jmp_buf initial_jmpbuf; -/* XXX Make these percpu */ -static void (*cb_proc)(void *arg); -static void *cb_arg; -static jmp_buf *cb_back; +static __thread void (*cb_proc)(void *arg); +static __thread void *cb_arg; +static __thread jmp_buf *cb_back; int start_idle_thread(void *stack, jmp_buf *switch_buf) { @@ -866,10 +868,10 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) cb_arg = arg; cb_back = &here; - block_signals_trace(); + initial_jmpbuf_lock(); if (UML_SETJMP(&here) == 0) UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); - unblock_signals_trace(); + initial_jmpbuf_unlock(); cb_proc = NULL; cb_arg = NULL; @@ -878,8 +880,9 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) void halt_skas(void) { - block_signals_trace(); + initial_jmpbuf_lock(); UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT); + /* unreachable */ } static bool noreboot; @@ -899,6 +902,7 @@ __uml_setup("noreboot", noreboot_cmd_param, void reboot_skas(void) { - block_signals_trace(); + initial_jmpbuf_lock(); UML_LONGJMP(&initial_jmpbuf, noreboot ? INIT_JMP_HALT : INIT_JMP_REBOOT); + /* unreachable */ } diff --git a/arch/um/os-Linux/smp.c b/arch/um/os-Linux/smp.c new file mode 100644 index 0000000000000..18d3858a7cd29 --- /dev/null +++ b/arch/um/os-Linux/smp.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Ant Group + * Author: Tiwei Bie + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" + +struct cpu_thread_data { + int cpu; + sigset_t sigset; +}; + +static __thread int __curr_cpu; + +int uml_curr_cpu(void) +{ + return __curr_cpu; +} + +static pthread_t cpu_threads[CONFIG_NR_CPUS]; + +static void *cpu_thread(void *arg) +{ + struct cpu_thread_data *data = arg; + + __curr_cpu = data->cpu; + + uml_start_secondary(data); + + return NULL; +} + +int os_start_cpu_thread(int cpu) +{ + struct cpu_thread_data *data; + sigset_t sigset, oset; + int err; + + data = uml_kmalloc(sizeof(*data), UM_GFP_ATOMIC); + if (!data) + return -ENOMEM; + + sigfillset(&sigset); + if (sigprocmask(SIG_SETMASK, &sigset, &oset) < 0) { + err = errno; + goto err; + } + + data->cpu = cpu; + data->sigset = oset; + + err = pthread_create(&cpu_threads[cpu], NULL, cpu_thread, data); + if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0) + panic("Failed to restore the signal mask, errno = %d", errno); + if (err != 0) + goto err; + + return 0; + +err: + kfree(data); + return -err; +} + +void os_start_secondary(void *arg, jmp_buf *switch_buf) +{ + struct cpu_thread_data *data = arg; + + sigaddset(&data->sigset, IPI_SIGNAL); + sigaddset(&data->sigset, SIGIO); + + if (sigprocmask(SIG_SETMASK, &data->sigset, NULL) < 0) + panic("Failed to restore the signal mask, errno = %d", errno); + + kfree(data); + longjmp(*switch_buf, 1); + + /* unreachable */ + printk(UM_KERN_ERR "impossible long jump!"); + fatal_sigsegv(); +} + +int os_send_ipi(int cpu, int vector) +{ + union sigval value = { .sival_int = vector }; + + return pthread_sigqueue(cpu_threads[cpu], IPI_SIGNAL, value); +} + +static void __local_ipi_set(int enable) +{ + sigset_t sigset; + + sigemptyset(&sigset); + sigaddset(&sigset, IPI_SIGNAL); + + if (sigprocmask(enable ? SIG_UNBLOCK : SIG_BLOCK, &sigset, NULL) < 0) + panic("%s: sigprocmask failed, errno = %d", __func__, errno); +} + +void os_local_ipi_enable(void) +{ + __local_ipi_set(1); +} + +void os_local_ipi_disable(void) +{ + __local_ipi_set(0); +} + +static void ipi_sig_handler(int sig, siginfo_t *si, void *uc) +{ + int save_errno = errno; + + signals_enabled = 0; + um_trace_signals_off(); + + uml_ipi_handler(si->si_value.sival_int); + + um_trace_signals_on(); + signals_enabled = 1; + + errno = save_errno; +} + +void __init os_init_smp(void) +{ + struct sigaction action = { + .sa_sigaction = ipi_sig_handler, + .sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART, + }; + + sigfillset(&action.sa_mask); + + if (sigaction(IPI_SIGNAL, &action, NULL) < 0) + panic("%s: sigaction failed, errno = %d", __func__, errno); + + cpu_threads[0] = pthread_self(); +} diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index a827c2e01aa53..054ac03bbf5ee 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -481,6 +482,9 @@ void __init os_early_checks(void) fatal("SECCOMP userspace requested but not functional!\n"); } + if (uml_ncpus > 1) + fatal("SMP is not supported with PTRACE userspace.\n"); + using_seccomp = 0; check_ptrace(); @@ -489,53 +493,3 @@ void __init os_early_checks(void) fatal("Failed to initialize default registers"); stop_ptraced_child(pid, 1); } - -int __init parse_iomem(char *str, int *add) -{ - struct iomem_region *new; - struct stat64 buf; - char *file, *driver; - int fd, size; - - driver = str; - file = strchr(str,','); - if (file == NULL) { - os_warn("parse_iomem : failed to parse iomem\n"); - goto out; - } - *file = '\0'; - file++; - fd = open(file, O_RDWR, 0); - if (fd < 0) { - perror("parse_iomem - Couldn't open io file"); - goto out; - } - - if (fstat64(fd, &buf) < 0) { - perror("parse_iomem - cannot stat_fd file"); - goto out_close; - } - - new = malloc(sizeof(*new)); - if (new == NULL) { - perror("Couldn't allocate iomem_region struct"); - goto out_close; - } - - size = (buf.st_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1); - - *new = ((struct iomem_region) { .next = iomem_regions, - .driver = driver, - .fd = fd, - .size = size, - .phys = 0, - .virt = 0 }); - iomem_regions = new; - iomem_size += new->size + UM_KERN_PAGE_SIZE; - - return 0; - out_close: - close(fd); - out: - return 1; -} diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 4d5591d96d8c3..13ebc86918d44 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -11,12 +11,15 @@ #include #include #include +#include #include #include #include +#include #include +#include "internal.h" -static timer_t event_high_res_timer = 0; +static timer_t event_high_res_timer[CONFIG_NR_CPUS] = { 0 }; static inline long long timespec_to_ns(const struct timespec *ts) { @@ -31,20 +34,31 @@ long long os_persistent_clock_emulation(void) return timespec_to_ns(&realtime_tp); } +#ifndef sigev_notify_thread_id +#define sigev_notify_thread_id _sigev_un._tid +#endif + /** * os_timer_create() - create an new posix (interval) timer */ int os_timer_create(void) { - timer_t *t = &event_high_res_timer; + int cpu = uml_curr_cpu(); + timer_t *t = &event_high_res_timer[cpu]; + struct sigevent sev = { + .sigev_notify = SIGEV_THREAD_ID, + .sigev_signo = SIGALRM, + .sigev_value.sival_ptr = t, + .sigev_notify_thread_id = gettid(), + }; - if (timer_create(CLOCK_MONOTONIC, NULL, t) == -1) + if (timer_create(CLOCK_MONOTONIC, &sev, t) == -1) return -1; return 0; } -int os_timer_set_interval(unsigned long long nsecs) +int os_timer_set_interval(int cpu, unsigned long long nsecs) { struct itimerspec its; @@ -54,13 +68,13 @@ int os_timer_set_interval(unsigned long long nsecs) its.it_interval.tv_sec = nsecs / UM_NSEC_PER_SEC; its.it_interval.tv_nsec = nsecs % UM_NSEC_PER_SEC; - if (timer_settime(event_high_res_timer, 0, &its, NULL) == -1) + if (timer_settime(event_high_res_timer[cpu], 0, &its, NULL) == -1) return -errno; return 0; } -int os_timer_one_shot(unsigned long long nsecs) +int os_timer_one_shot(int cpu, unsigned long long nsecs) { struct itimerspec its = { .it_value.tv_sec = nsecs / UM_NSEC_PER_SEC, @@ -70,19 +84,20 @@ int os_timer_one_shot(unsigned long long nsecs) .it_interval.tv_nsec = 0, // we cheat here }; - timer_settime(event_high_res_timer, 0, &its, NULL); + timer_settime(event_high_res_timer[cpu], 0, &its, NULL); return 0; } /** * os_timer_disable() - disable the posix (interval) timer + * @cpu: the CPU for which the timer is to be disabled */ -void os_timer_disable(void) +void os_timer_disable(int cpu) { struct itimerspec its; memset(&its, 0, sizeof(struct itimerspec)); - timer_settime(event_high_res_timer, 0, &its, NULL); + timer_settime(event_high_res_timer[cpu], 0, &its, NULL); } long long os_nsecs(void) @@ -93,23 +108,50 @@ long long os_nsecs(void) return timespec_to_ns(&ts); } +static __thread int wake_signals; + +void os_idle_prepare(void) +{ + sigset_t set; + + sigemptyset(&set); + sigaddset(&set, SIGALRM); + sigaddset(&set, IPI_SIGNAL); + + /* + * We need to use signalfd rather than sigsuspend in idle sleep + * because the IPI signal is a real-time signal that carries data, + * and unlike handling SIGALRM, we cannot simply flag it in + * signals_pending. + */ + wake_signals = signalfd(-1, &set, SFD_CLOEXEC); + if (wake_signals < 0) + panic("Failed to create signal FD, errno = %d", errno); +} + /** * os_idle_sleep() - sleep until interrupted */ void os_idle_sleep(void) { - struct itimerspec its; - sigset_t set, old; + sigset_t set; - /* block SIGALRM while we analyze the timer state */ + /* + * Block SIGALRM while performing the need_resched check. + * Note that, because IRQs are disabled, the IPI signal is + * already blocked. + */ sigemptyset(&set); sigaddset(&set, SIGALRM); - sigprocmask(SIG_BLOCK, &set, &old); + sigprocmask(SIG_BLOCK, &set, NULL); + + /* + * Because disabling IRQs does not block SIGALRM, it is also + * necessary to check for any pending timer alarms. + */ + if (!uml_need_resched() && !timer_alarm_pending()) + os_poll(1, &wake_signals); - /* check the timer, and if it'll fire then wait for it */ - timer_gettime(event_high_res_timer, &its); - if (its.it_value.tv_sec || its.it_value.tv_nsec) - sigsuspend(&old); - /* either way, restore the signal mask */ + /* Restore the signal mask. */ sigprocmask(SIG_UNBLOCK, &set, NULL); } diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index a310ae27b479a..67f6112318b64 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c @@ -31,12 +31,6 @@ extern void *memset(void *, int, size_t); EXPORT_SYMBOL(memset); #endif -#ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA -/* needed for __access_ok() */ -EXPORT_SYMBOL(vsyscall_ehdr); -EXPORT_SYMBOL(vsyscall_end); -#endif - #ifdef _FORTIFY_SOURCE extern int __sprintf_chk(char *str, int flag, size_t len, const char *format); EXPORT_SYMBOL(__sprintf_chk); diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 17a107cc5244b..80527299f859a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -281,6 +281,7 @@ config X86 select HAVE_PCI select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select ASYNC_KERNEL_PGTABLE_FREE if IOMMU_SVA select MMU_GATHER_RCU_TABLE_FREE select MMU_GATHER_MERGE_VMAS select HAVE_POSIX_CPU_TIMERS_TASK_WORK diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 112f43b23ebf8..aca89f23d2e00 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -1718,26 +1718,30 @@ static int x86_pmu_amd_ibs_starting_cpu(unsigned int cpu) #ifdef CONFIG_PM -static int perf_ibs_suspend(void) +static int perf_ibs_suspend(void *data) { clear_APIC_ibs(); return 0; } -static void perf_ibs_resume(void) +static void perf_ibs_resume(void *data) { ibs_eilvt_setup(); setup_APIC_ibs(); } -static struct syscore_ops perf_ibs_syscore_ops = { +static const struct syscore_ops perf_ibs_syscore_ops = { .resume = perf_ibs_resume, .suspend = perf_ibs_suspend, }; +static struct syscore perf_ibs_syscore = { + .ops = &perf_ibs_syscore_ops, +}; + static void perf_ibs_pm_init(void) { - register_syscore_ops(&perf_ibs_syscore_ops); + register_syscore(&perf_ibs_syscore); } #else diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c index e8b6af199c738..9293ce50574da 100644 --- a/arch/x86/events/amd/uncore.c +++ b/arch/x86/events/amd/uncore.c @@ -656,14 +656,11 @@ static int amd_uncore_df_event_init(struct perf_event *event) struct hw_perf_event *hwc = &event->hw; int ret = amd_uncore_event_init(event); - if (ret || pmu_version < 2) - return ret; - hwc->config = event->attr.config & (pmu_version >= 2 ? AMD64_PERFMON_V2_RAW_EVENT_MASK_NB : AMD64_RAW_EVENT_MASK_NB); - return 0; + return ret; } static int amd_uncore_df_add(struct perf_event *event, int flags) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 853fe073bab30..bdf3f0d0fe216 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3378,6 +3378,9 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) if (!test_bit(bit, cpuc->active_mask)) continue; + /* Event may have already been cleared: */ + if (!event) + continue; /* * There may be unprocessed PEBS records in the PEBS buffer, diff --git a/arch/x86/hyperv/.gitignore b/arch/x86/hyperv/.gitignore new file mode 100644 index 0000000000000..333615d993b56 --- /dev/null +++ b/arch/x86/hyperv/.gitignore @@ -0,0 +1 @@ +mshv-asm-offsets.h diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile index d55f494f471d4..56292102af623 100644 --- a/arch/x86/hyperv/Makefile +++ b/arch/x86/hyperv/Makefile @@ -1,8 +1,22 @@ # SPDX-License-Identifier: GPL-2.0-only obj-y := hv_init.o mmu.o nested.o irqdomain.o ivm.o obj-$(CONFIG_X86_64) += hv_apic.o -obj-$(CONFIG_HYPERV_VTL_MODE) += hv_vtl.o +obj-$(CONFIG_HYPERV_VTL_MODE) += hv_vtl.o mshv_vtl_asm.o + +$(obj)/mshv_vtl_asm.o: $(obj)/mshv-asm-offsets.h + +$(obj)/mshv-asm-offsets.h: $(obj)/mshv-asm-offsets.s FORCE + $(call filechk,offsets,__MSHV_ASM_OFFSETS_H__) ifdef CONFIG_X86_64 obj-$(CONFIG_PARAVIRT_SPINLOCKS) += hv_spinlock.o + + ifdef CONFIG_MSHV_ROOT + CFLAGS_REMOVE_hv_trampoline.o += -pg + CFLAGS_hv_trampoline.o += -fno-stack-protector + obj-$(CONFIG_CRASH_DUMP) += hv_crash.o hv_trampoline.o + endif endif + +targets += mshv-asm-offsets.s +clean-files += mshv-asm-offsets.h diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c index bfde0a3498b90..a8de503def370 100644 --- a/arch/x86/hyperv/hv_apic.c +++ b/arch/x86/hyperv/hv_apic.c @@ -53,6 +53,11 @@ static void hv_apic_icr_write(u32 low, u32 id) wrmsrq(HV_X64_MSR_ICR, reg_val); } +void hv_enable_coco_interrupt(unsigned int cpu, unsigned int vector, bool set) +{ + apic_update_vector(cpu, vector, set); +} + static u32 hv_apic_read(u32 reg) { u32 reg_val, hi; @@ -293,6 +298,9 @@ static void hv_send_ipi_self(int vector) void __init hv_apic_init(void) { + if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC)) + return; + if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) { pr_info("Hyper-V: Using IPI hypercalls\n"); /* diff --git a/arch/x86/hyperv/hv_crash.c b/arch/x86/hyperv/hv_crash.c new file mode 100644 index 0000000000000..c0e22921ace1a --- /dev/null +++ b/arch/x86/hyperv/hv_crash.c @@ -0,0 +1,642 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * X86 specific Hyper-V root partition kdump/crash support module + * + * Copyright (C) 2025, Microsoft, Inc. + * + * This module implements hypervisor RAM collection into vmcore for both + * cases of the hypervisor crash and Linux root crash. Hyper-V implements + * a disable hypercall with a 32bit protected mode ABI callback. This + * mechanism must be used to unlock hypervisor RAM. Since the hypervisor RAM + * is already mapped in Linux, it is automatically collected into Linux vmcore, + * and can be examined by the crash command (raw RAM dump) or windbg. + * + * At a high level: + * + * Hypervisor Crash: + * Upon crash, hypervisor goes into an emergency minimal dispatch loop, a + * restrictive mode with very limited hypercall and MSR support. Each cpu + * then injects NMIs into root vcpus. A shared page is used to check + * by Linux in the NMI handler if the hypervisor has crashed. This shared + * page is setup in hv_root_crash_init during boot. + * + * Linux Crash: + * In case of Linux crash, the callback hv_crash_stop_other_cpus will send + * NMIs to all cpus, then proceed to the crash_nmi_callback where it waits + * for all cpus to be in NMI. + * + * NMI Handler (upon quorum): + * Eventually, in both cases, all cpus will end up in the NMI handler. + * Hyper-V requires the disable hypervisor must be done from the BSP. So + * the BSP NMI handler saves current context, does some fixups and makes + * the hypercall to disable the hypervisor, ie, devirtualize. Hypervisor + * at that point will suspend all vcpus (except the BSP), unlock all its + * RAM, and return to Linux at the 32bit mode entry RIP. + * + * Linux 32bit entry trampoline will then restore long mode and call C + * function here to restore context and continue execution to crash kexec. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool hv_crash_enabled; +EXPORT_SYMBOL_GPL(hv_crash_enabled); + +struct hv_crash_ctxt { + ulong rsp; + ulong cr0; + ulong cr2; + ulong cr4; + ulong cr8; + + u16 cs; + u16 ss; + u16 ds; + u16 es; + u16 fs; + u16 gs; + + u16 gdt_fill; + struct desc_ptr gdtr; + char idt_fill[6]; + struct desc_ptr idtr; + + u64 gsbase; + u64 efer; + u64 pat; +}; +static struct hv_crash_ctxt hv_crash_ctxt; + +/* Shared hypervisor page that contains crash dump area we peek into. + * NB: windbg looks for "hv_cda" symbol so don't change it. + */ +static struct hv_crashdump_area *hv_cda; + +static u32 trampoline_pa, devirt_arg; +static atomic_t crash_cpus_wait; +static void *hv_crash_ptpgs[4]; +static bool hv_has_crashed, lx_has_crashed; + +static void __noreturn hv_panic_timeout_reboot(void) +{ + #define PANIC_TIMER_STEP 100 + + if (panic_timeout > 0) { + int i; + + for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP) + mdelay(PANIC_TIMER_STEP); + } + + if (panic_timeout) + native_wrmsrq(HV_X64_MSR_RESET, 1); /* get hyp to reboot */ + + for (;;) + cpu_relax(); +} + +/* This cannot be inlined as it needs stack */ +static noinline __noclone void hv_crash_restore_tss(void) +{ + load_TR_desc(); +} + +/* This cannot be inlined as it needs stack */ +static noinline void hv_crash_clear_kernpt(void) +{ + pgd_t *pgd; + p4d_t *p4d; + + /* Clear entry so it's not confusing to someone looking at the core */ + pgd = pgd_offset_k(trampoline_pa); + p4d = p4d_offset(pgd, trampoline_pa); + native_p4d_clear(p4d); +} + +/* + * This is the C entry point from the asm glue code after the disable hypercall. + * We enter here in IA32-e long mode, ie, full 64bit mode running on kernel + * page tables with our below 4G page identity mapped, but using a temporary + * GDT. ds/fs/gs/es are null. ss is not usable. bp is null. stack is not + * available. We restore kernel GDT, and rest of the context, and continue + * to kexec. + */ +static asmlinkage void __noreturn hv_crash_c_entry(void) +{ + struct hv_crash_ctxt *ctxt = &hv_crash_ctxt; + + /* first thing, restore kernel gdt */ + native_load_gdt(&ctxt->gdtr); + + asm volatile("movw %%ax, %%ss" : : "a"(ctxt->ss)); + asm volatile("movq %0, %%rsp" : : "m"(ctxt->rsp)); + + asm volatile("movw %%ax, %%ds" : : "a"(ctxt->ds)); + asm volatile("movw %%ax, %%es" : : "a"(ctxt->es)); + asm volatile("movw %%ax, %%fs" : : "a"(ctxt->fs)); + asm volatile("movw %%ax, %%gs" : : "a"(ctxt->gs)); + + native_wrmsrq(MSR_IA32_CR_PAT, ctxt->pat); + asm volatile("movq %0, %%cr0" : : "r"(ctxt->cr0)); + + asm volatile("movq %0, %%cr8" : : "r"(ctxt->cr8)); + asm volatile("movq %0, %%cr4" : : "r"(ctxt->cr4)); + asm volatile("movq %0, %%cr2" : : "r"(ctxt->cr4)); + + native_load_idt(&ctxt->idtr); + native_wrmsrq(MSR_GS_BASE, ctxt->gsbase); + native_wrmsrq(MSR_EFER, ctxt->efer); + + /* restore the original kernel CS now via far return */ + asm volatile("movzwq %0, %%rax\n\t" + "pushq %%rax\n\t" + "pushq $1f\n\t" + "lretq\n\t" + "1:nop\n\t" : : "m"(ctxt->cs) : "rax"); + + /* We are in asmlinkage without stack frame, hence make C function + * calls which will buy stack frames. + */ + hv_crash_restore_tss(); + hv_crash_clear_kernpt(); + + /* we are now fully in devirtualized normal kernel mode */ + __crash_kexec(NULL); + + hv_panic_timeout_reboot(); +} +/* Tell gcc we are using lretq long jump in the above function intentionally */ +STACK_FRAME_NON_STANDARD(hv_crash_c_entry); + +static void hv_mark_tss_not_busy(void) +{ + struct desc_struct *desc = get_current_gdt_rw(); + tss_desc tss; + + memcpy(&tss, &desc[GDT_ENTRY_TSS], sizeof(tss_desc)); + tss.type = 0x9; /* available 64-bit TSS. 0xB is busy TSS */ + write_gdt_entry(desc, GDT_ENTRY_TSS, &tss, DESC_TSS); +} + +/* Save essential context */ +static void hv_hvcrash_ctxt_save(void) +{ + struct hv_crash_ctxt *ctxt = &hv_crash_ctxt; + + asm volatile("movq %%rsp,%0" : "=m"(ctxt->rsp)); + + ctxt->cr0 = native_read_cr0(); + ctxt->cr4 = native_read_cr4(); + + asm volatile("movq %%cr2, %0" : "=a"(ctxt->cr2)); + asm volatile("movq %%cr8, %0" : "=a"(ctxt->cr8)); + + asm volatile("movl %%cs, %%eax" : "=a"(ctxt->cs)); + asm volatile("movl %%ss, %%eax" : "=a"(ctxt->ss)); + asm volatile("movl %%ds, %%eax" : "=a"(ctxt->ds)); + asm volatile("movl %%es, %%eax" : "=a"(ctxt->es)); + asm volatile("movl %%fs, %%eax" : "=a"(ctxt->fs)); + asm volatile("movl %%gs, %%eax" : "=a"(ctxt->gs)); + + native_store_gdt(&ctxt->gdtr); + store_idt(&ctxt->idtr); + + ctxt->gsbase = __rdmsr(MSR_GS_BASE); + ctxt->efer = __rdmsr(MSR_EFER); + ctxt->pat = __rdmsr(MSR_IA32_CR_PAT); +} + +/* Add trampoline page to the kernel pagetable for transition to kernel PT */ +static void hv_crash_fixup_kernpt(void) +{ + pgd_t *pgd; + p4d_t *p4d; + + pgd = pgd_offset_k(trampoline_pa); + p4d = p4d_offset(pgd, trampoline_pa); + + /* trampoline_pa is below 4G, so no pre-existing entry to clobber */ + p4d_populate(&init_mm, p4d, (pud_t *)hv_crash_ptpgs[1]); + p4d->p4d = p4d->p4d & ~(_PAGE_NX); /* enable execute */ +} + +/* + * Notify the hyp that Linux has crashed. This will cause the hyp to quiesce + * and suspend all guest VPs. + */ +static void hv_notify_prepare_hyp(void) +{ + u64 status; + struct hv_input_notify_partition_event *input; + struct hv_partition_event_root_crashdump_input *cda; + + input = *this_cpu_ptr(hyperv_pcpu_input_arg); + cda = &input->input.crashdump_input; + memset(input, 0, sizeof(*input)); + input->event = HV_PARTITION_EVENT_ROOT_CRASHDUMP; + + cda->crashdump_action = HV_CRASHDUMP_ENTRY; + status = hv_do_hypercall(HVCALL_NOTIFY_PARTITION_EVENT, input, NULL); + if (!hv_result_success(status)) + return; + + cda->crashdump_action = HV_CRASHDUMP_SUSPEND_ALL_VPS; + hv_do_hypercall(HVCALL_NOTIFY_PARTITION_EVENT, input, NULL); +} + +/* + * Common function for all cpus before devirtualization. + * + * Hypervisor crash: all cpus get here in NMI context. + * Linux crash: the panicing cpu gets here at base level, all others in NMI + * context. Note, panicing cpu may not be the BSP. + * + * The function is not inlined so it will show on the stack. It is named so + * because the crash cmd looks for certain well known function names on the + * stack before looking into the cpu saved note in the elf section, and + * that work is currently incomplete. + * + * Notes: + * Hypervisor crash: + * - the hypervisor is in a very restrictive mode at this point and any + * vmexit it cannot handle would result in reboot. So, no mumbo jumbo, + * just get to kexec as quickly as possible. + * + * Devirtualization is supported from the BSP only at present. + */ +static noinline __noclone void crash_nmi_callback(struct pt_regs *regs) +{ + struct hv_input_disable_hyp_ex *input; + u64 status; + int msecs = 1000, ccpu = smp_processor_id(); + + if (ccpu == 0) { + /* crash_save_cpu() will be done in the kexec path */ + cpu_emergency_stop_pt(); /* disable performance trace */ + atomic_inc(&crash_cpus_wait); + } else { + crash_save_cpu(regs, ccpu); + cpu_emergency_stop_pt(); /* disable performance trace */ + atomic_inc(&crash_cpus_wait); + for (;;) + cpu_relax(); + } + + while (atomic_read(&crash_cpus_wait) < num_online_cpus() && msecs--) + mdelay(1); + + stop_nmi(); + if (!hv_has_crashed) + hv_notify_prepare_hyp(); + + if (crashing_cpu == -1) + crashing_cpu = ccpu; /* crash cmd uses this */ + + hv_hvcrash_ctxt_save(); + hv_mark_tss_not_busy(); + hv_crash_fixup_kernpt(); + + input = *this_cpu_ptr(hyperv_pcpu_input_arg); + memset(input, 0, sizeof(*input)); + input->rip = trampoline_pa; + input->arg = devirt_arg; + + status = hv_do_hypercall(HVCALL_DISABLE_HYP_EX, input, NULL); + + hv_panic_timeout_reboot(); +} + + +static DEFINE_SPINLOCK(hv_crash_reboot_lk); + +/* + * Generic NMI callback handler: could be called without any crash also. + * hv crash: hypervisor injects NMI's into all cpus + * lx crash: panicing cpu sends NMI to all but self via crash_stop_other_cpus + */ +static int hv_crash_nmi_local(unsigned int cmd, struct pt_regs *regs) +{ + if (!hv_has_crashed && hv_cda && hv_cda->cda_valid) + hv_has_crashed = true; + + if (!hv_has_crashed && !lx_has_crashed) + return NMI_DONE; /* ignore the NMI */ + + if (hv_has_crashed && !kexec_crash_loaded()) { + if (spin_trylock(&hv_crash_reboot_lk)) + hv_panic_timeout_reboot(); + else + for (;;) + cpu_relax(); + } + + crash_nmi_callback(regs); + + return NMI_DONE; +} + +/* + * hv_crash_stop_other_cpus() == smp_ops.crash_stop_other_cpus + * + * On normal Linux panic, this is called twice: first from panic and then again + * from native_machine_crash_shutdown. + * + * In case of hyperv, 3 ways to get here: + * 1. hv crash (only BSP will get here): + * BSP : NMI callback -> DisableHv -> hv_crash_asm32 -> hv_crash_c_entry + * -> __crash_kexec -> native_machine_crash_shutdown + * -> crash_smp_send_stop -> smp_ops.crash_stop_other_cpus + * Linux panic: + * 2. panic cpu x: panic() -> crash_smp_send_stop + * -> smp_ops.crash_stop_other_cpus + * 3. BSP: native_machine_crash_shutdown -> crash_smp_send_stop + * + * NB: noclone and non standard stack because of call to crash_setup_regs(). + */ +static void __noclone hv_crash_stop_other_cpus(void) +{ + static bool crash_stop_done; + struct pt_regs lregs; + int ccpu = smp_processor_id(); + + if (hv_has_crashed) + return; /* all cpus already in NMI handler path */ + + if (!kexec_crash_loaded()) { + hv_notify_prepare_hyp(); + hv_panic_timeout_reboot(); /* no return */ + } + + /* If the hv crashes also, we could come here again before cpus_stopped + * is set in crash_smp_send_stop(). So use our own check. + */ + if (crash_stop_done) + return; + crash_stop_done = true; + + /* Linux has crashed: hv is healthy, we can IPI safely */ + lx_has_crashed = true; + wmb(); /* NMI handlers look at lx_has_crashed */ + + apic->send_IPI_allbutself(NMI_VECTOR); + + if (crashing_cpu == -1) + crashing_cpu = ccpu; /* crash cmd uses this */ + + /* crash_setup_regs() happens in kexec also, but for the kexec cpu which + * is the BSP. We could be here on non-BSP cpu, collect regs if so. + */ + if (ccpu) + crash_setup_regs(&lregs, NULL); + + crash_nmi_callback(&lregs); +} +STACK_FRAME_NON_STANDARD(hv_crash_stop_other_cpus); + +/* This GDT is accessed in IA32-e compat mode which uses 32bits addresses */ +struct hv_gdtreg_32 { + u16 fill; + u16 limit; + u32 address; +} __packed; + +/* We need a CS with L bit to goto IA32-e long mode from 32bit compat mode */ +struct hv_crash_tramp_gdt { + u64 null; /* index 0, selector 0, null selector */ + u64 cs64; /* index 1, selector 8, cs64 selector */ +} __packed; + +/* No stack, so jump via far ptr in memory to load the 64bit CS */ +struct hv_cs_jmptgt { + u32 address; + u16 csval; + u16 fill; +} __packed; + +/* Linux use only, hypervisor doesn't look at this struct */ +struct hv_crash_tramp_data { + u64 tramp32_cr3; + u64 kernel_cr3; + struct hv_gdtreg_32 gdtr32; + struct hv_crash_tramp_gdt tramp_gdt; + struct hv_cs_jmptgt cs_jmptgt; + u64 c_entry_addr; +} __packed; + +/* + * Setup a temporary gdt to allow the asm code to switch to the long mode. + * Since the asm code is relocated/copied to a below 4G page, it cannot use rip + * relative addressing, hence we must use trampoline_pa here. Also, save other + * info like jmp and C entry targets for same reasons. + * + * Returns: 0 on success, -1 on error + */ +static int hv_crash_setup_trampdata(u64 trampoline_va) +{ + int size, offs; + void *dest; + struct hv_crash_tramp_data *tramp; + + /* These must match exactly the ones in the corresponding asm file */ + BUILD_BUG_ON(offsetof(struct hv_crash_tramp_data, tramp32_cr3) != 0); + BUILD_BUG_ON(offsetof(struct hv_crash_tramp_data, kernel_cr3) != 8); + BUILD_BUG_ON(offsetof(struct hv_crash_tramp_data, gdtr32.limit) != 18); + BUILD_BUG_ON(offsetof(struct hv_crash_tramp_data, + cs_jmptgt.address) != 40); + BUILD_BUG_ON(offsetof(struct hv_crash_tramp_data, c_entry_addr) != 48); + + /* hv_crash_asm_end is beyond last byte by 1 */ + size = &hv_crash_asm_end - &hv_crash_asm32; + if (size + sizeof(struct hv_crash_tramp_data) > PAGE_SIZE) { + pr_err("%s: trampoline page overflow\n", __func__); + return -1; + } + + dest = (void *)trampoline_va; + memcpy(dest, &hv_crash_asm32, size); + + dest += size; + dest = (void *)round_up((ulong)dest, 16); + tramp = (struct hv_crash_tramp_data *)dest; + + /* see MAX_ASID_AVAILABLE in tlb.c: "PCID 0 is reserved for use by + * non-PCID-aware users". Build cr3 with pcid 0 + */ + tramp->tramp32_cr3 = __sme_pa(hv_crash_ptpgs[0]); + + /* Note, when restoring X86_CR4_PCIDE, cr3[11:0] must be zero */ + tramp->kernel_cr3 = __sme_pa(init_mm.pgd); + + tramp->gdtr32.limit = sizeof(struct hv_crash_tramp_gdt); + tramp->gdtr32.address = trampoline_pa + + (ulong)&tramp->tramp_gdt - trampoline_va; + + /* base:0 limit:0xfffff type:b dpl:0 P:1 L:1 D:0 avl:0 G:1 */ + tramp->tramp_gdt.cs64 = 0x00af9a000000ffff; + + tramp->cs_jmptgt.csval = 0x8; + offs = (ulong)&hv_crash_asm64 - (ulong)&hv_crash_asm32; + tramp->cs_jmptgt.address = trampoline_pa + offs; + + tramp->c_entry_addr = (u64)&hv_crash_c_entry; + + devirt_arg = trampoline_pa + (ulong)dest - trampoline_va; + + return 0; +} + +/* + * Build 32bit trampoline page table for transition from protected mode + * non-paging to long-mode paging. This transition needs pagetables below 4G. + */ +static void hv_crash_build_tramp_pt(void) +{ + p4d_t *p4d; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + u64 pa, addr = trampoline_pa; + + p4d = hv_crash_ptpgs[0] + pgd_index(addr) * sizeof(p4d); + pa = virt_to_phys(hv_crash_ptpgs[1]); + set_p4d(p4d, __p4d(_PAGE_TABLE | pa)); + p4d->p4d &= ~(_PAGE_NX); /* enable execute */ + + pud = hv_crash_ptpgs[1] + pud_index(addr) * sizeof(pud); + pa = virt_to_phys(hv_crash_ptpgs[2]); + set_pud(pud, __pud(_PAGE_TABLE | pa)); + + pmd = hv_crash_ptpgs[2] + pmd_index(addr) * sizeof(pmd); + pa = virt_to_phys(hv_crash_ptpgs[3]); + set_pmd(pmd, __pmd(_PAGE_TABLE | pa)); + + pte = hv_crash_ptpgs[3] + pte_index(addr) * sizeof(pte); + set_pte(pte, pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL_EXEC)); +} + +/* + * Setup trampoline for devirtualization: + * - a page below 4G, ie 32bit addr containing asm glue code that hyp jmps to + * in protected mode. + * - 4 pages for a temporary page table that asm code uses to turn paging on + * - a temporary gdt to use in the compat mode. + * + * Returns: 0 on success + */ +static int hv_crash_trampoline_setup(void) +{ + int i, rc, order; + struct page *page; + u64 trampoline_va; + gfp_t flags32 = GFP_KERNEL | GFP_DMA32 | __GFP_ZERO; + + /* page for 32bit trampoline assembly code + hv_crash_tramp_data */ + page = alloc_page(flags32); + if (page == NULL) { + pr_err("%s: failed to alloc asm stub page\n", __func__); + return -1; + } + + trampoline_va = (u64)page_to_virt(page); + trampoline_pa = (u32)page_to_phys(page); + + order = 2; /* alloc 2^2 pages */ + page = alloc_pages(flags32, order); + if (page == NULL) { + pr_err("%s: failed to alloc pt pages\n", __func__); + free_page(trampoline_va); + return -1; + } + + for (i = 0; i < 4; i++, page++) + hv_crash_ptpgs[i] = page_to_virt(page); + + hv_crash_build_tramp_pt(); + + rc = hv_crash_setup_trampdata(trampoline_va); + if (rc) + goto errout; + + return 0; + +errout: + free_page(trampoline_va); + free_pages((ulong)hv_crash_ptpgs[0], order); + + return rc; +} + +/* Setup for kdump kexec to collect hypervisor RAM when running as root */ +void hv_root_crash_init(void) +{ + int rc; + struct hv_input_get_system_property *input; + struct hv_output_get_system_property *output; + unsigned long flags; + u64 status; + union hv_pfn_range cda_info; + + if (pgtable_l5_enabled()) { + pr_err("Hyper-V: crash dump not yet supported on 5level PTs\n"); + return; + } + + rc = register_nmi_handler(NMI_LOCAL, hv_crash_nmi_local, NMI_FLAG_FIRST, + "hv_crash_nmi"); + if (rc) { + pr_err("Hyper-V: failed to register crash nmi handler\n"); + return; + } + + local_irq_save(flags); + input = *this_cpu_ptr(hyperv_pcpu_input_arg); + output = *this_cpu_ptr(hyperv_pcpu_output_arg); + + memset(input, 0, sizeof(*input)); + input->property_id = HV_SYSTEM_PROPERTY_CRASHDUMPAREA; + + status = hv_do_hypercall(HVCALL_GET_SYSTEM_PROPERTY, input, output); + cda_info.as_uint64 = output->hv_cda_info.as_uint64; + local_irq_restore(flags); + + if (!hv_result_success(status)) { + pr_err("Hyper-V: %s: property:%d %s\n", __func__, + input->property_id, hv_result_to_string(status)); + goto err_out; + } + + if (cda_info.base_pfn == 0) { + pr_err("Hyper-V: hypervisor crash dump area pfn is 0\n"); + goto err_out; + } + + hv_cda = phys_to_virt(cda_info.base_pfn << HV_HYP_PAGE_SHIFT); + + rc = hv_crash_trampoline_setup(); + if (rc) + goto err_out; + + smp_ops.crash_stop_other_cpus = hv_crash_stop_other_cpus; + + crash_kexec_post_notifiers = true; + hv_crash_enabled = true; + pr_info("Hyper-V: both linux and hypervisor kdump support enabled\n"); + + return; + +err_out: + unregister_nmi_handler(NMI_LOCAL, "hv_crash_nmi"); + pr_err("Hyper-V: only linux root kdump support enabled\n"); +} diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index e890fd37e9c2d..14de43f4bc6c1 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -170,6 +170,10 @@ static int hv_cpu_init(unsigned int cpu) wrmsrq(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); } + /* Allow Hyper-V stimer vector to be injected from Hypervisor. */ + if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) + apic_update_vector(cpu, HYPERV_STIMER0_VECTOR, true); + return hyperv_init_ghcb(); } @@ -277,6 +281,9 @@ static int hv_cpu_die(unsigned int cpu) *ghcb_va = NULL; } + if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) + apic_update_vector(cpu, HYPERV_STIMER0_VECTOR, false); + hv_common_cpu_die(cpu); if (hv_vp_assist_page && hv_vp_assist_page[cpu]) { @@ -351,7 +358,7 @@ static int __init hv_pci_init(void) return 1; } -static int hv_suspend(void) +static int hv_suspend(void *data) { union hv_x64_msr_hypercall_contents hypercall_msr; int ret; @@ -378,7 +385,7 @@ static int hv_suspend(void) return ret; } -static void hv_resume(void) +static void hv_resume(void *data) { union hv_x64_msr_hypercall_contents hypercall_msr; int ret; @@ -405,11 +412,15 @@ static void hv_resume(void) } /* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */ -static struct syscore_ops hv_syscore_ops = { +static const struct syscore_ops hv_syscore_ops = { .suspend = hv_suspend, .resume = hv_resume, }; +static struct syscore hv_syscore = { + .ops = &hv_syscore_ops, +}; + static void (* __initdata old_setup_percpu_clockev)(void); static void __init hv_stimer_setup_percpu_clockev(void) @@ -547,6 +558,8 @@ void __init hyperv_init(void) memunmap(src); hv_remap_tsc_clocksource(); + hv_root_crash_init(); + hv_sleep_notifiers_register(); } else { hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg); wrmsrq(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); @@ -569,7 +582,7 @@ void __init hyperv_init(void) x86_init.pci.arch_init = hv_pci_init; - register_syscore_ops(&hv_syscore_ops); + register_syscore(&hv_syscore); if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID) hv_get_partition_id(); diff --git a/arch/x86/hyperv/hv_trampoline.S b/arch/x86/hyperv/hv_trampoline.S new file mode 100644 index 0000000000000..25f02ff122862 --- /dev/null +++ b/arch/x86/hyperv/hv_trampoline.S @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * X86 specific Hyper-V kdump/crash related code. + * + * Copyright (C) 2025, Microsoft, Inc. + * + */ +#include +#include +#include +#include +#include + +/* + * void noreturn hv_crash_asm32(arg1) + * arg1 == edi == 32bit PA of struct hv_crash_tramp_data + * + * The hypervisor jumps here upon devirtualization in protected mode. This + * code gets copied to a page in the low 4G ie, 32bit space so it can run + * in the protected mode. Hence we cannot use any compile/link time offsets or + * addresses. It restores long mode via temporary gdt and page tables and + * eventually jumps to kernel code entry at HV_CRASHDATA_OFFS_C_entry. + * + * PreCondition (ie, Hypervisor call back ABI): + * o CR0 is set to 0x0021: PE(prot mode) and NE are set, paging is disabled + * o CR4 is set to 0x0 + * o IA32_EFER is set to 0x901 (SCE and NXE are set) + * o EDI is set to the Arg passed to HVCALL_DISABLE_HYP_EX. + * o CS, DS, ES, FS, GS are all initialized with a base of 0 and limit 0xFFFF + * o IDTR, TR and GDTR are initialized with a base of 0 and limit of 0xFFFF + * o LDTR is initialized as invalid (limit of 0) + * o MSR PAT is power on default. + * o Other state/registers are cleared. All TLBs flushed. + */ + +#define HV_CRASHDATA_OFFS_TRAMPCR3 0x0 /* 0 */ +#define HV_CRASHDATA_OFFS_KERNCR3 0x8 /* 8 */ +#define HV_CRASHDATA_OFFS_GDTRLIMIT 0x12 /* 18 */ +#define HV_CRASHDATA_OFFS_CS_JMPTGT 0x28 /* 40 */ +#define HV_CRASHDATA_OFFS_C_entry 0x30 /* 48 */ + + .text + .code32 + +SYM_CODE_START(hv_crash_asm32) + UNWIND_HINT_UNDEFINED + ENDBR + movl $X86_CR4_PAE, %ecx + movl %ecx, %cr4 + + movl %edi, %ebx + add $HV_CRASHDATA_OFFS_TRAMPCR3, %ebx + movl %cs:(%ebx), %eax + movl %eax, %cr3 + + /* Setup EFER for long mode now */ + movl $MSR_EFER, %ecx + rdmsr + btsl $_EFER_LME, %eax + wrmsr + + /* Turn paging on using the temp 32bit trampoline page table */ + movl %cr0, %eax + orl $(X86_CR0_PG), %eax + movl %eax, %cr0 + + /* since kernel cr3 could be above 4G, we need to be in the long mode + * before we can load 64bits of the kernel cr3. We use a temp gdt for + * that with CS.L=1 and CS.D=0 */ + mov %edi, %eax + add $HV_CRASHDATA_OFFS_GDTRLIMIT, %eax + lgdtl %cs:(%eax) + + /* not done yet, restore CS now to switch to CS.L=1 */ + mov %edi, %eax + add $HV_CRASHDATA_OFFS_CS_JMPTGT, %eax + ljmp %cs:*(%eax) +SYM_CODE_END(hv_crash_asm32) + + /* we now run in full 64bit IA32-e long mode, CS.L=1 and CS.D=0 */ + .code64 + .balign 8 +SYM_CODE_START(hv_crash_asm64) + UNWIND_HINT_UNDEFINED + ENDBR + /* restore kernel page tables so we can jump to kernel code */ + mov %edi, %eax + add $HV_CRASHDATA_OFFS_KERNCR3, %eax + movq %cs:(%eax), %rbx + movq %rbx, %cr3 + + mov %edi, %eax + add $HV_CRASHDATA_OFFS_C_entry, %eax + movq %cs:(%eax), %rbx + ANNOTATE_RETPOLINE_SAFE + jmp *%rbx + + int $3 + +SYM_INNER_LABEL(hv_crash_asm_end, SYM_L_GLOBAL) +SYM_CODE_END(hv_crash_asm64) diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c index 042e8712d8dea..c0edaed0efb30 100644 --- a/arch/x86/hyperv/hv_vtl.c +++ b/arch/x86/hyperv/hv_vtl.c @@ -9,12 +9,17 @@ #include #include #include +#include +#include #include #include #include #include #include +#include +#include #include <../kernel/smpboot.h> +#include "../../kernel/fpu/legacy.h" extern struct boot_params boot_params; static struct real_mode_header hv_vtl_real_mode_header; @@ -249,3 +254,28 @@ int __init hv_vtl_early_init(void) return 0; } + +DEFINE_STATIC_CALL_NULL(__mshv_vtl_return_hypercall, void (*)(void)); + +void mshv_vtl_return_call_init(u64 vtl_return_offset) +{ + static_call_update(__mshv_vtl_return_hypercall, + (void *)((u8 *)hv_hypercall_pg + vtl_return_offset)); +} +EXPORT_SYMBOL(mshv_vtl_return_call_init); + +void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0) +{ + struct hv_vp_assist_page *hvp; + + hvp = hv_vp_assist_page[smp_processor_id()]; + hvp->vtl_ret_x64rax = vtl0->rax; + hvp->vtl_ret_x64rcx = vtl0->rcx; + + kernel_fpu_begin_mask(0); + fxrstor(&vtl0->fx_state); + __mshv_vtl_return_call(vtl0); + fxsave(&vtl0->fx_state); + kernel_fpu_end(); +} +EXPORT_SYMBOL(mshv_vtl_return_call); diff --git a/arch/x86/hyperv/mshv-asm-offsets.c b/arch/x86/hyperv/mshv-asm-offsets.c new file mode 100644 index 0000000000000..882c1db6df16c --- /dev/null +++ b/arch/x86/hyperv/mshv-asm-offsets.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Generate definitions needed by assembly language modules. + * This code generates raw asm output which is post-processed to extract + * and format the required data. + * + * Copyright (c) 2025, Microsoft Corporation. + * + * Author: + * Naman Jain + */ +#define COMPILE_OFFSETS + +#include +#include + +static void __used common(void) +{ + if (IS_ENABLED(CONFIG_HYPERV_VTL_MODE)) { + OFFSET(MSHV_VTL_CPU_CONTEXT_rax, mshv_vtl_cpu_context, rax); + OFFSET(MSHV_VTL_CPU_CONTEXT_rcx, mshv_vtl_cpu_context, rcx); + OFFSET(MSHV_VTL_CPU_CONTEXT_rdx, mshv_vtl_cpu_context, rdx); + OFFSET(MSHV_VTL_CPU_CONTEXT_rbx, mshv_vtl_cpu_context, rbx); + OFFSET(MSHV_VTL_CPU_CONTEXT_rbp, mshv_vtl_cpu_context, rbp); + OFFSET(MSHV_VTL_CPU_CONTEXT_rsi, mshv_vtl_cpu_context, rsi); + OFFSET(MSHV_VTL_CPU_CONTEXT_rdi, mshv_vtl_cpu_context, rdi); + OFFSET(MSHV_VTL_CPU_CONTEXT_r8, mshv_vtl_cpu_context, r8); + OFFSET(MSHV_VTL_CPU_CONTEXT_r9, mshv_vtl_cpu_context, r9); + OFFSET(MSHV_VTL_CPU_CONTEXT_r10, mshv_vtl_cpu_context, r10); + OFFSET(MSHV_VTL_CPU_CONTEXT_r11, mshv_vtl_cpu_context, r11); + OFFSET(MSHV_VTL_CPU_CONTEXT_r12, mshv_vtl_cpu_context, r12); + OFFSET(MSHV_VTL_CPU_CONTEXT_r13, mshv_vtl_cpu_context, r13); + OFFSET(MSHV_VTL_CPU_CONTEXT_r14, mshv_vtl_cpu_context, r14); + OFFSET(MSHV_VTL_CPU_CONTEXT_r15, mshv_vtl_cpu_context, r15); + OFFSET(MSHV_VTL_CPU_CONTEXT_cr2, mshv_vtl_cpu_context, cr2); + } +} diff --git a/arch/x86/hyperv/mshv_vtl_asm.S b/arch/x86/hyperv/mshv_vtl_asm.S new file mode 100644 index 0000000000000..f595eefad9abf --- /dev/null +++ b/arch/x86/hyperv/mshv_vtl_asm.S @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Assembly level code for mshv_vtl VTL transition + * + * Copyright (c) 2025, Microsoft Corporation. + * + * Author: + * Naman Jain + */ + +#include +#include +#include +#include +#include +#include "mshv-asm-offsets.h" + + .text + .section .noinstr.text, "ax" +/* + * void __mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0) + * + * This function is used to context switch between different Virtual Trust Levels. + * It is marked as 'noinstr' to prevent against instrumentation and debugging facilities. + * NMIs aren't a problem because the NMI handler saves/restores CR2 specifically to guard + * against #PFs in NMI context clobbering the guest state. + */ +SYM_FUNC_START(__mshv_vtl_return_call) + /* Push callee save registers */ + pushq %rbp + mov %rsp, %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushq %rbx + + /* register switch to VTL0 clobbers all registers except rax/rcx */ + mov %_ASM_ARG1, %rax + + /* grab rbx/rbp/rsi/rdi/r8-r15 */ + mov MSHV_VTL_CPU_CONTEXT_rbx(%rax), %rbx + mov MSHV_VTL_CPU_CONTEXT_rbp(%rax), %rbp + mov MSHV_VTL_CPU_CONTEXT_rsi(%rax), %rsi + mov MSHV_VTL_CPU_CONTEXT_rdi(%rax), %rdi + mov MSHV_VTL_CPU_CONTEXT_r8(%rax), %r8 + mov MSHV_VTL_CPU_CONTEXT_r9(%rax), %r9 + mov MSHV_VTL_CPU_CONTEXT_r10(%rax), %r10 + mov MSHV_VTL_CPU_CONTEXT_r11(%rax), %r11 + mov MSHV_VTL_CPU_CONTEXT_r12(%rax), %r12 + mov MSHV_VTL_CPU_CONTEXT_r13(%rax), %r13 + mov MSHV_VTL_CPU_CONTEXT_r14(%rax), %r14 + mov MSHV_VTL_CPU_CONTEXT_r15(%rax), %r15 + + mov MSHV_VTL_CPU_CONTEXT_cr2(%rax), %rdx + mov %rdx, %cr2 + mov MSHV_VTL_CPU_CONTEXT_rdx(%rax), %rdx + + /* stash host registers on stack */ + pushq %rax + pushq %rcx + + xor %ecx, %ecx + + /* make a hypercall to switch VTL */ + call STATIC_CALL_TRAMP_STR(__mshv_vtl_return_hypercall) + + /* stash guest registers on stack, restore saved host copies */ + pushq %rax + pushq %rcx + mov 16(%rsp), %rcx + mov 24(%rsp), %rax + + mov %rdx, MSHV_VTL_CPU_CONTEXT_rdx(%rax) + mov %cr2, %rdx + mov %rdx, MSHV_VTL_CPU_CONTEXT_cr2(%rax) + pop MSHV_VTL_CPU_CONTEXT_rcx(%rax) + pop MSHV_VTL_CPU_CONTEXT_rax(%rax) + add $16, %rsp + + /* save rbx/rbp/rsi/rdi/r8-r15 */ + mov %rbx, MSHV_VTL_CPU_CONTEXT_rbx(%rax) + mov %rbp, MSHV_VTL_CPU_CONTEXT_rbp(%rax) + mov %rsi, MSHV_VTL_CPU_CONTEXT_rsi(%rax) + mov %rdi, MSHV_VTL_CPU_CONTEXT_rdi(%rax) + mov %r8, MSHV_VTL_CPU_CONTEXT_r8(%rax) + mov %r9, MSHV_VTL_CPU_CONTEXT_r9(%rax) + mov %r10, MSHV_VTL_CPU_CONTEXT_r10(%rax) + mov %r11, MSHV_VTL_CPU_CONTEXT_r11(%rax) + mov %r12, MSHV_VTL_CPU_CONTEXT_r12(%rax) + mov %r13, MSHV_VTL_CPU_CONTEXT_r13(%rax) + mov %r14, MSHV_VTL_CPU_CONTEXT_r14(%rax) + mov %r15, MSHV_VTL_CPU_CONTEXT_r15(%rax) + + /* pop callee-save registers r12-r15, rbx */ + pop %rbx + pop %r15 + pop %r14 + pop %r13 + pop %r12 + + pop %rbp + RET +SYM_FUNC_END(__mshv_vtl_return_call) +/* + * Make sure that static_call_key symbol: __SCK____mshv_vtl_return_hypercall is accessible here. + * Below code is inspired from __ADDRESSABLE(sym) macro. Symbol name is kept simple, to avoid + * naming it something like "__UNIQUE_ID_addressable___SCK____mshv_vtl_return_hypercall_662.0" + * which would otherwise have been generated by the macro. + */ + .section .discard.addressable,"aw" + .align 8 + .type mshv_vtl_return_sym, @object + .size mshv_vtl_return_sym, 8 +mshv_vtl_return_sym: + .quad __SCK____mshv_vtl_return_hypercall diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index b14c045679e16..03364510d5fe2 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -197,8 +197,8 @@ static inline int alternatives_text_reserved(void *start, void *end) "773:\n" #define ALTINSTR_ENTRY(ft_flags) \ - ".pushsection .altinstructions,\"a\"\n" \ - ANNOTATE_DATA_SPECIAL \ + ".pushsection .altinstructions, \"aM\", @progbits, " \ + __stringify(ALT_INSTR_SIZE) "\n" \ " .long 771b - .\n" /* label */ \ " .long 774f - .\n" /* new instruction */ \ " .4byte " __stringify(ft_flags) "\n" /* feature + flags */ \ @@ -208,7 +208,7 @@ static inline int alternatives_text_reserved(void *start, void *end) #define ALTINSTR_REPLACEMENT(newinstr) /* replacement */ \ ".pushsection .altinstr_replacement, \"ax\"\n" \ - ANNOTATE_DATA_SPECIAL \ + ANNOTATE_DATA_SPECIAL "\n" \ "# ALT: replacement\n" \ "774:\n\t" newinstr "\n775:\n" \ ".popsection\n" @@ -339,7 +339,6 @@ void nop_func(void); * instruction. See apply_alternatives(). */ .macro altinstr_entry orig alt ft_flags orig_len alt_len - ANNOTATE_DATA_SPECIAL .long \orig - . .long \alt - . .4byte \ft_flags @@ -363,7 +362,7 @@ void nop_func(void); 741: \ .skip -(((744f-743f)-(741b-740b)) > 0) * ((744f-743f)-(741b-740b)),0x90 ;\ 742: \ - .pushsection .altinstructions,"a" ; \ + .pushsection .altinstructions, "aM", @progbits, ALT_INSTR_SIZE ;\ altinstr_entry 740b,743f,flag,742b-740b,744f-743f ; \ .popsection ; \ .pushsection .altinstr_replacement,"ax" ; \ diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index bd62bd87a841e..0e8c611bc9e2a 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h @@ -126,18 +126,21 @@ static __always_inline __pure void *rip_rel_ptr(void *p) #ifdef __KERNEL__ +#ifndef COMPILE_OFFSETS +#include +#endif + # include /* Exception table entry */ #ifdef __ASSEMBLER__ -# define _ASM_EXTABLE_TYPE(from, to, type) \ - .pushsection "__ex_table","a" ; \ - .balign 4 ; \ - ANNOTATE_DATA_SPECIAL ; \ - .long (from) - . ; \ - .long (to) - . ; \ - .long type ; \ +# define _ASM_EXTABLE_TYPE(from, to, type) \ + .pushsection "__ex_table", "aM", @progbits, EXTABLE_SIZE ; \ + .balign 4 ; \ + .long (from) - . ; \ + .long (to) - . ; \ + .long type ; \ .popsection # ifdef CONFIG_KPROBES @@ -180,18 +183,18 @@ static __always_inline __pure void *rip_rel_ptr(void *p) ".purgem extable_type_reg\n" # define _ASM_EXTABLE_TYPE(from, to, type) \ - " .pushsection \"__ex_table\",\"a\"\n" \ + " .pushsection __ex_table, \"aM\", @progbits, " \ + __stringify(EXTABLE_SIZE) "\n" \ " .balign 4\n" \ - ANNOTATE_DATA_SPECIAL \ " .long (" #from ") - .\n" \ " .long (" #to ") - .\n" \ " .long " __stringify(type) " \n" \ " .popsection\n" # define _ASM_EXTABLE_TYPE_REG(from, to, type, reg) \ - " .pushsection \"__ex_table\",\"a\"\n" \ + " .pushsection __ex_table, \"aM\", @progbits, " \ + __stringify(EXTABLE_SIZE) "\n" \ " .balign 4\n" \ - ANNOTATE_DATA_SPECIAL \ " .long (" #from ") - .\n" \ " .long (" #to ") - .\n" \ DEFINE_EXTABLE_TYPE_REG \ diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h index ab5bba6cf7f52..9b4e04690e1a2 100644 --- a/arch/x86/include/asm/bug.h +++ b/arch/x86/include/asm/bug.h @@ -15,7 +15,7 @@ extern void __WARN_trap(struct bug_entry *bug, ...); /* * Despite that some emulators terminate on UD2, we use it for WARN(). */ -#define ASM_UD2 _ASM_BYTES(0x0f, 0x0b) +#define ASM_UD2 __ASM_FORM(ud2) #define INSN_UD2 0x0b0f #define LEN_UD2 2 @@ -70,7 +70,7 @@ extern void __WARN_trap(struct bug_entry *bug, ...); #define _BUG_FLAGS_ASM(format, file, line, flags, size, extra) \ ".pushsection __bug_table,\"aw\"\n\t" \ - ANNOTATE_DATA_SPECIAL \ + ANNOTATE_DATA_SPECIAL "\n\t" \ "2:\n\t" \ __BUG_ENTRY(format, file, line, flags) \ "\t.org 2b + " size "\n" \ @@ -129,7 +129,7 @@ do { \ #define __WARN_FLAGS(cond_str, flags) \ do { \ - __auto_type __flags = BUGFLAG_WARNING|(flags); \ + auto __flags = BUGFLAG_WARNING|(flags); \ instrumentation_begin(); \ _BUG_FLAGS(cond_str, ASM_UD2, __flags, ARCH_WARN_REACHABLE); \ instrumentation_end(); \ diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 4b1a6ade17003..3ddc1d33399be 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -101,7 +101,7 @@ static __always_inline bool _static_cpu_has(u16 bit) asm goto(ALTERNATIVE_TERNARY("jmp 6f", %c[feature], "", "jmp %l[t_no]") ".pushsection .altinstr_aux,\"ax\"\n" "6:\n" - ANNOTATE_DATA_SPECIAL + ANNOTATE_DATA_SPECIAL "\n" " testb %[bitnum], %a[cap_byte]\n" " jnz %l[t_yes]\n" " jmp %l[t_no]\n" diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index d90ce601917ce..c3b53beb13007 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -339,6 +339,7 @@ #define X86_FEATURE_AMD_STIBP (13*32+15) /* Single Thread Indirect Branch Predictors */ #define X86_FEATURE_AMD_STIBP_ALWAYS_ON (13*32+17) /* Single Thread Indirect Branch Predictors always-on preferred */ #define X86_FEATURE_AMD_IBRS_SAME_MODE (13*32+19) /* Indirect Branch Restricted Speculation same mode protection*/ +#define X86_FEATURE_EFER_LMSLE_MBZ (13*32+20) /* EFER.LMSLE must be zero */ #define X86_FEATURE_AMD_PPIN (13*32+23) /* "amd_ppin" Protected Processor Inventory Number */ #define X86_FEATURE_AMD_SSBD (13*32+24) /* Speculative Store Bypass Disable */ #define X86_FEATURE_VIRT_SSBD (13*32+25) /* "virt_ssbd" Virtualized Speculative Store Bypass Disable */ @@ -506,6 +507,12 @@ #define X86_FEATURE_SGX_EUPDATESVN (21*32+17) /* Support for ENCLS[EUPDATESVN] instruction */ #define X86_FEATURE_SDCIAE (21*32+18) /* L3 Smart Data Cache Injection Allocation Enforcement */ +#define X86_FEATURE_CLEAR_CPU_BUF_VM_MMIO (21*32+19) /* + * Clear CPU buffers before VM-Enter if the vCPU + * can access host MMIO (ignored for all intents + * and purposes if CLEAR_CPU_BUF_VM is set). + */ +#define X86_FEATURE_X2AVIC_EXT (21*32+20) /* AMD SVM x2AVIC support for 4k vCPUs */ /* * BUG word(s) diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h index 70f6b60ad67b9..9df9e9cde670b 100644 --- a/arch/x86/include/asm/cpumask.h +++ b/arch/x86/include/asm/cpumask.h @@ -2,6 +2,8 @@ #ifndef _ASM_X86_CPUMASK_H #define _ASM_X86_CPUMASK_H #ifndef __ASSEMBLER__ + +#include #include extern void setup_cpu_local_masks(void); diff --git a/arch/x86/include/asm/div64.h b/arch/x86/include/asm/div64.h index 9931e4c7d73f3..30fd06ede751c 100644 --- a/arch/x86/include/asm/div64.h +++ b/arch/x86/include/asm/div64.h @@ -60,6 +60,12 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) } #define div_u64_rem div_u64_rem +/* + * gcc tends to zero extend 32bit values and do full 64bit maths. + * Define asm functions that avoid this. + * (clang generates better code for the C versions.) + */ +#ifndef __clang__ static inline u64 mul_u32_u32(u32 a, u32 b) { u32 high, low; @@ -71,6 +77,19 @@ static inline u64 mul_u32_u32(u32 a, u32 b) } #define mul_u32_u32 mul_u32_u32 +static inline u64 add_u64_u32(u64 a, u32 b) +{ + u32 high = a >> 32, low = a; + + asm ("addl %[b], %[low]; adcl $0, %[high]" + : [low] "+r" (low), [high] "+r" (high) + : [b] "rm" (b) ); + + return low | (u64)high << 32; +} +#define add_u64_u32 add_u64_u32 +#endif + /* * __div64_32() is never called on x86, so prevent the * generic definition from getting built. @@ -84,21 +103,25 @@ static inline u64 mul_u32_u32(u32 a, u32 b) * Will generate an #DE when the result doesn't fit u64, could fix with an * __ex_table[] entry when it becomes an issue. */ -static inline u64 mul_u64_u64_div_u64(u64 a, u64 mul, u64 div) +static inline u64 mul_u64_add_u64_div_u64(u64 rax, u64 mul, u64 add, u64 div) { - u64 q; + u64 rdx; + + asm ("mulq %[mul]" : "+a" (rax), "=d" (rdx) : [mul] "rm" (mul)); + + if (!statically_true(!add)) + asm ("addq %[add], %[lo]; adcq $0, %[hi]" : + [lo] "+r" (rax), [hi] "+r" (rdx) : [add] "irm" (add)); - asm ("mulq %2; divq %3" : "=a" (q) - : "a" (a), "rm" (mul), "rm" (div) - : "rdx"); + asm ("divq %[div]" : "+a" (rax), "+d" (rdx) : [div] "rm" (div)); - return q; + return rax; } -#define mul_u64_u64_div_u64 mul_u64_u64_div_u64 +#define mul_u64_add_u64_div_u64 mul_u64_add_u64_div_u64 static inline u64 mul_u64_u32_div(u64 a, u32 mul, u32 div) { - return mul_u64_u64_div_u64(a, mul, div); + return mul_u64_add_u64_div_u64(a, mul, 0, div); } #define mul_u64_u32_div mul_u64_u32_div diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h index f00c09ffe6a95..6b6d472baa0bb 100644 --- a/arch/x86/include/asm/hardirq.h +++ b/arch/x86/include/asm/hardirq.h @@ -5,7 +5,7 @@ #include typedef struct { -#if IS_ENABLED(CONFIG_KVM_INTEL) +#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL) u8 kvm_cpu_l1tf_flush_l1d; #endif unsigned int __nmi_count; /* arch dependent */ @@ -68,7 +68,7 @@ extern u64 arch_irq_stat(void); DECLARE_PER_CPU_CACHE_HOT(u16, __softirq_pending); #define local_softirq_pending_ref __softirq_pending -#if IS_ENABLED(CONFIG_KVM_INTEL) +#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL) /* * This function is called from noinstr interrupt contexts * and must be inlined to not get instrumentation. diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h index 5a0d42464d442..4e55d17558465 100644 --- a/arch/x86/include/asm/irq_remapping.h +++ b/arch/x86/include/asm/irq_remapping.h @@ -87,4 +87,11 @@ static inline void panic_if_irq_remap(const char *msg) } #endif /* CONFIG_IRQ_REMAP */ + +#ifdef CONFIG_X86_POSTED_MSI +void intel_ack_posted_msi_irq(struct irq_data *irqd); +#else +#define intel_ack_posted_msi_irq NULL +#endif + #endif /* __X86_IRQ_REMAPPING_H */ diff --git a/arch/x86/include/asm/irq_stack.h b/arch/x86/include/asm/irq_stack.h index 735c3a491f604..8325b79f2ac6a 100644 --- a/arch/x86/include/asm/irq_stack.h +++ b/arch/x86/include/asm/irq_stack.h @@ -101,7 +101,7 @@ #define ASM_CALL_ARG0 \ "1: call %c[__func] \n" \ - ANNOTATE_REACHABLE(1b) + ANNOTATE_REACHABLE(1b) " \n" #define ASM_CALL_ARG1 \ "movq %[arg1], %%rdi \n" \ diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h index b30e5474c18e1..a1193e9d65f20 100644 --- a/arch/x86/include/asm/irqflags.h +++ b/arch/x86/include/asm/irqflags.h @@ -25,7 +25,7 @@ extern __always_inline unsigned long native_save_fl(void) */ asm volatile("# __raw_save_flags\n\t" "pushf ; pop %0" - : "=rm" (flags) + : ASM_OUTPUT_RM (flags) : /* no input */ : "memory"); diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h index e0a6930a4029a..05b16299588d5 100644 --- a/arch/x86/include/asm/jump_label.h +++ b/arch/x86/include/asm/jump_label.h @@ -15,7 +15,7 @@ #define JUMP_TABLE_ENTRY(key, label) \ ".pushsection __jump_table, \"aw\" \n\t" \ _ASM_ALIGN "\n\t" \ - ANNOTATE_DATA_SPECIAL \ + ANNOTATE_DATA_SPECIAL "\n" \ ".long 1b - . \n\t" \ ".long " label " - . \n\t" \ _ASM_PTR " " key " - . \n\t" \ diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h index fdf178443f850..de709fb5bd76a 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -128,6 +128,7 @@ KVM_X86_OP(enable_smi_window) KVM_X86_OP_OPTIONAL(dev_get_attr) KVM_X86_OP_OPTIONAL(mem_enc_ioctl) KVM_X86_OP_OPTIONAL(vcpu_mem_enc_ioctl) +KVM_X86_OP_OPTIONAL(vcpu_mem_enc_unlocked_ioctl) KVM_X86_OP_OPTIONAL(mem_enc_register_region) KVM_X86_OP_OPTIONAL(mem_enc_unregister_region) KVM_X86_OP_OPTIONAL(vm_copy_enc_context_from) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 48598d017d6f3..5a3bfa293e8b1 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1055,9 +1055,6 @@ struct kvm_vcpu_arch { /* be preempted when it's in kernel-mode(cpl=0) */ bool preempted_in_kernel; - /* Flush the L1 Data cache for L1TF mitigation on VMENTER */ - bool l1tf_flush_l1d; - /* Host CPU on which VM-entry was most recently attempted */ int last_vmentry_cpu; @@ -1456,8 +1453,6 @@ struct kvm_arch { bool use_master_clock; u64 master_kernel_ns; u64 master_cycle_now; - struct delayed_work kvmclock_update_work; - struct delayed_work kvmclock_sync_work; #ifdef CONFIG_KVM_HYPERV struct kvm_hv hyperv; @@ -1848,15 +1843,15 @@ struct kvm_x86_ops { void *external_spt); /* Update the external page table from spte getting set. */ int (*set_external_spte)(struct kvm *kvm, gfn_t gfn, enum pg_level level, - kvm_pfn_t pfn_for_gfn); + u64 mirror_spte); /* Update external page tables for page table about to be freed. */ int (*free_external_spt)(struct kvm *kvm, gfn_t gfn, enum pg_level level, void *external_spt); /* Update external page table from spte getting removed, and flush TLB. */ - int (*remove_external_spte)(struct kvm *kvm, gfn_t gfn, enum pg_level level, - kvm_pfn_t pfn_for_gfn); + void (*remove_external_spte)(struct kvm *kvm, gfn_t gfn, enum pg_level level, + u64 mirror_spte); bool (*has_wbinvd_exit)(void); @@ -1914,6 +1909,7 @@ struct kvm_x86_ops { int (*dev_get_attr)(u32 group, u64 attr, u64 *val); int (*mem_enc_ioctl)(struct kvm *kvm, void __user *argp); int (*vcpu_mem_enc_ioctl)(struct kvm_vcpu *vcpu, void __user *argp); + int (*vcpu_mem_enc_unlocked_ioctl)(struct kvm_vcpu *vcpu, void __user *argp); int (*mem_enc_register_region)(struct kvm *kvm, struct kvm_enc_region *argp); int (*mem_enc_unregister_region)(struct kvm *kvm, struct kvm_enc_region *argp); int (*vm_copy_enc_context_from)(struct kvm *kvm, unsigned int source_fd); @@ -2143,6 +2139,11 @@ u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu); * the gfn, i.e. retrying the instruction will hit a * !PRESENT fault, which results in a new shadow page * and sends KVM back to square one. + * + * EMULTYPE_SKIP_SOFT_INT - Set in combination with EMULTYPE_SKIP to only skip + * an instruction if it could generate a given software + * interrupt, which must be encoded via + * EMULTYPE_SET_SOFT_INT_VECTOR(). */ #define EMULTYPE_NO_DECODE (1 << 0) #define EMULTYPE_TRAP_UD (1 << 1) @@ -2153,6 +2154,10 @@ u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu); #define EMULTYPE_PF (1 << 6) #define EMULTYPE_COMPLETE_USER_EXIT (1 << 7) #define EMULTYPE_WRITE_PF_TO_SP (1 << 8) +#define EMULTYPE_SKIP_SOFT_INT (1 << 9) + +#define EMULTYPE_SET_SOFT_INT_VECTOR(v) ((u32)((v) & 0xff) << 16) +#define EMULTYPE_GET_SOFT_INT_VECTOR(e) (((e) >> 16) & 0xff) static inline bool kvm_can_emulate_event_vectoring(int emul_type) { @@ -2167,6 +2172,7 @@ void __kvm_prepare_emulation_failure_exit(struct kvm_vcpu *vcpu, void kvm_prepare_emulation_failure_exit(struct kvm_vcpu *vcpu); void kvm_prepare_event_vectoring_exit(struct kvm_vcpu *vcpu, gpa_t gpa); +void kvm_prepare_unexpected_reason_exit(struct kvm_vcpu *vcpu, u64 exit_reason); void kvm_enable_efer_bits(u64); bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer); @@ -2378,7 +2384,6 @@ int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, int kvm_add_user_return_msr(u32 msr); int kvm_find_user_return_msr(u32 msr); int kvm_set_user_return_msr(unsigned index, u64 val, u64 mask); -void kvm_user_return_msr_update_cache(unsigned int index, u64 val); u64 kvm_get_user_return_msr(unsigned int slot); static inline bool kvm_is_supported_user_return_msr(u32 msr) diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 605abd02158dd..eef4c3a5ba28e 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -11,6 +11,7 @@ #include #include #include +#include /* * Hyper-V always provides a single IO-APIC at this MMIO address. @@ -176,6 +177,8 @@ int hyperv_flush_guest_mapping_range(u64 as, int hyperv_fill_flush_guest_mapping_list( struct hv_guest_mapping_flush_list *flush, u64 start_gfn, u64 end_gfn); +void hv_sleep_notifiers_register(void); +void hv_machine_power_off(void); #ifdef CONFIG_X86_64 void hv_apic_init(void); @@ -237,6 +240,15 @@ static __always_inline u64 hv_raw_get_msr(unsigned int reg) } int hv_apicid_to_vp_index(u32 apic_id); +#if IS_ENABLED(CONFIG_MSHV_ROOT) && IS_ENABLED(CONFIG_CRASH_DUMP) +void hv_root_crash_init(void); +void hv_crash_asm32(void); +void hv_crash_asm64(void); +void hv_crash_asm_end(void); +#else /* CONFIG_MSHV_ROOT && CONFIG_CRASH_DUMP */ +static inline void hv_root_crash_init(void) {} +#endif /* CONFIG_MSHV_ROOT && CONFIG_CRASH_DUMP */ + #else /* CONFIG_HYPERV */ static inline void hyperv_init(void) {} static inline void hyperv_setup_mmu_ops(void) {} @@ -260,13 +272,46 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg) { return 0; } static inline int hv_apicid_to_vp_index(u32 apic_id) { return -EINVAL; } #endif /* CONFIG_HYPERV */ +struct mshv_vtl_cpu_context { + union { + struct { + u64 rax; + u64 rcx; + u64 rdx; + u64 rbx; + u64 cr2; + u64 rbp; + u64 rsi; + u64 rdi; + u64 r8; + u64 r9; + u64 r10; + u64 r11; + u64 r12; + u64 r13; + u64 r14; + u64 r15; + }; + u64 gp_regs[16]; + }; + + struct fxregs_state fx_state; +}; #ifdef CONFIG_HYPERV_VTL_MODE void __init hv_vtl_init_platform(void); int __init hv_vtl_early_init(void); +void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0); +void mshv_vtl_return_call_init(u64 vtl_return_offset); +void mshv_vtl_return_hypercall(void); +void __mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0); #else static inline void __init hv_vtl_init_platform(void) {} static inline int __init hv_vtl_early_init(void) { return 0; } +static inline void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0) {} +static inline void mshv_vtl_return_call_init(u64 vtl_return_offset) {} +static inline void mshv_vtl_return_hypercall(void) {} +static inline void __mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0) {} #endif #include diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index 08ed5a2e46a5f..4f4b5e8a15743 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -308,24 +308,26 @@ * CFLAGS.ZF. * Note: Only the memory operand variant of VERW clears the CPU buffers. */ -.macro __CLEAR_CPU_BUFFERS feature #ifdef CONFIG_X86_64 - ALTERNATIVE "", "verw x86_verw_sel(%rip)", \feature +#define VERW verw x86_verw_sel(%rip) #else - /* - * In 32bit mode, the memory operand must be a %cs reference. The data - * segments may not be usable (vm86 mode), and the stack segment may not - * be flat (ESPFIX32). - */ - ALTERNATIVE "", "verw %cs:x86_verw_sel", \feature +/* + * In 32bit mode, the memory operand must be a %cs reference. The data segments + * may not be usable (vm86 mode), and the stack segment may not be flat (ESPFIX32). + */ +#define VERW verw %cs:x86_verw_sel #endif -.endm -#define CLEAR_CPU_BUFFERS \ - __CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF +/* + * Provide a stringified VERW macro for simple usage, and a non-stringified + * VERW macro for use in more elaborate sequences, e.g. to encode a conditional + * VERW within an ALTERNATIVE. + */ +#define __CLEAR_CPU_BUFFERS __stringify(VERW) -#define VM_CLEAR_CPU_BUFFERS \ - __CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF_VM +/* If necessary, emit VERW on exit-to-userspace to clear CPU buffers. */ +#define CLEAR_CPU_BUFFERS \ + ALTERNATIVE "", __CLEAR_CPU_BUFFERS, X86_FEATURE_CLEAR_CPU_BUF #ifdef CONFIG_X86_64 .macro CLEAR_BRANCH_HISTORY @@ -464,7 +466,7 @@ static inline void call_depth_return_thunk(void) {} */ # define CALL_NOSPEC \ ALTERNATIVE_2( \ - ANNOTATE_RETPOLINE_SAFE \ + ANNOTATE_RETPOLINE_SAFE "\n" \ "call *%[thunk_target]\n", \ " jmp 904f;\n" \ " .align 16\n" \ @@ -480,7 +482,7 @@ static inline void call_depth_return_thunk(void) {} "904: call 901b;\n", \ X86_FEATURE_RETPOLINE, \ "lfence;\n" \ - ANNOTATE_RETPOLINE_SAFE \ + ANNOTATE_RETPOLINE_SAFE "\n" \ "call *%[thunk_target]\n", \ X86_FEATURE_RETPOLINE_LFENCE) @@ -580,8 +582,6 @@ DECLARE_STATIC_KEY_FALSE(cpu_buf_idle_clear); DECLARE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); -DECLARE_STATIC_KEY_FALSE(cpu_buf_vm_clear); - extern u16 x86_verw_sel; #include diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 37a8627d8277f..3502939415ad0 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -249,7 +249,7 @@ extern struct paravirt_patch_template pv_ops; * don't need to bother with CFI prefixes. */ #define PARAVIRT_CALL \ - ANNOTATE_RETPOLINE_SAFE \ + ANNOTATE_RETPOLINE_SAFE "\n\t" \ "call *%[paravirt_opptr];" /* diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h index 20a3baae9568d..977bef14a0abf 100644 --- a/arch/x86/include/asm/smap.h +++ b/arch/x86/include/asm/smap.h @@ -77,7 +77,7 @@ static __always_inline unsigned long smap_save(void) unsigned long flags; asm volatile ("# smap_save\n\t" - ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE + ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "\n\t" "", "pushf; pop %0; clac", X86_FEATURE_SMAP) : "=rm" (flags) : : "memory", "cc"); @@ -88,7 +88,7 @@ static __always_inline unsigned long smap_save(void) static __always_inline void smap_restore(unsigned long flags) { asm volatile ("# smap_restore\n\t" - ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE + ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "\n\t" "", "push %0; popf", X86_FEATURE_SMAP) : : "g" (flags) : "memory", "cc"); @@ -101,9 +101,9 @@ static __always_inline void smap_restore(unsigned long flags) ALTERNATIVE("", "stac", X86_FEATURE_SMAP) #define ASM_CLAC_UNSAFE \ - ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "clac", X86_FEATURE_SMAP) + ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "\n\t" "clac", X86_FEATURE_SMAP) #define ASM_STAC_UNSAFE \ - ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "stac", X86_FEATURE_SMAP) + ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "\n\t" "stac", X86_FEATURE_SMAP) #endif /* __ASSEMBLER__ */ diff --git a/arch/x86/include/asm/static_call.h b/arch/x86/include/asm/static_call.h index 41502bd2afd64..4cd725a8fe91f 100644 --- a/arch/x86/include/asm/static_call.h +++ b/arch/x86/include/asm/static_call.h @@ -36,7 +36,7 @@ ".align 4 \n" \ ".globl " STATIC_CALL_TRAMP_STR(name) " \n" \ STATIC_CALL_TRAMP_STR(name) ": \n" \ - ANNOTATE_NOENDBR \ + ANNOTATE_NOENDBR " \n" \ insns " \n" \ ".byte 0x0f, 0xb9, 0xcc \n" \ ".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \ diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h index 79e9695dc13e4..4635616863f53 100644 --- a/arch/x86/include/asm/string_64.h +++ b/arch/x86/include/asm/string_64.h @@ -31,7 +31,7 @@ KCFI_REFERENCE(__memset); #define __HAVE_ARCH_MEMSET16 static inline void *memset16(uint16_t *s, uint16_t v, size_t n) { - const __auto_type s0 = s; + const auto s0 = s; asm volatile ( "rep stosw" : "+D" (s), "+c" (n) @@ -44,7 +44,7 @@ static inline void *memset16(uint16_t *s, uint16_t v, size_t n) #define __HAVE_ARCH_MEMSET32 static inline void *memset32(uint32_t *s, uint32_t v, size_t n) { - const __auto_type s0 = s; + const auto s0 = s; asm volatile ( "rep stosl" : "+D" (s), "+c" (n) @@ -57,7 +57,7 @@ static inline void *memset32(uint32_t *s, uint32_t v, size_t n) #define __HAVE_ARCH_MEMSET64 static inline void *memset64(uint64_t *s, uint64_t v, size_t n) { - const __auto_type s0 = s; + const auto s0 = s; asm volatile ( "rep stosq" : "+D" (s), "+c" (n) diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 0581c477d466e..56aa99503dc4f 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -279,7 +279,7 @@ enum avic_ipi_failure_cause { AVIC_IPI_FAILURE_INVALID_IPI_VECTOR, }; -#define AVIC_PHYSICAL_MAX_INDEX_MASK GENMASK_ULL(8, 0) +#define AVIC_PHYSICAL_MAX_INDEX_MASK GENMASK_ULL(11, 0) /* * For AVIC, the max index allowed for physical APIC ID table is 0xfe (254), as @@ -289,11 +289,14 @@ enum avic_ipi_failure_cause { /* * For x2AVIC, the max index allowed for physical APIC ID table is 0x1ff (511). + * With X86_FEATURE_X2AVIC_EXT, the max index is increased to 0xfff (4095). */ #define X2AVIC_MAX_PHYSICAL_ID 0x1FFUL +#define X2AVIC_4K_MAX_PHYSICAL_ID 0xFFFUL static_assert((AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == AVIC_MAX_PHYSICAL_ID); static_assert((X2AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_MAX_PHYSICAL_ID); +static_assert((X2AVIC_4K_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_4K_MAX_PHYSICAL_ID); #define SVM_SEV_FEAT_SNP_ACTIVE BIT(0) #define SVM_SEV_FEAT_RESTRICTED_INJECTION BIT(3) diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 641f45c22f9da..915124011c276 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -72,7 +72,7 @@ static inline void __user *mask_user_address(const void __user *ptr) return ret; } #define masked_user_access_begin(x) ({ \ - __auto_type __masked_ptr = (x); \ + auto __masked_ptr = (x); \ __masked_ptr = mask_user_address(__masked_ptr); \ __uaccess_begin(); __masked_ptr; }) diff --git a/arch/x86/include/asm/uv/bios.h b/arch/x86/include/asm/uv/bios.h index 6989b824fd321..d0b62e2552902 100644 --- a/arch/x86/include/asm/uv/bios.h +++ b/arch/x86/include/asm/uv/bios.h @@ -122,7 +122,7 @@ struct uv_systab { struct { u32 type:8; /* type of entry */ u32 offset:24; /* byte offset from struct start to entry */ - } entry[1]; /* additional entries follow */ + } entry[]; /* additional entries follow */ }; extern struct uv_systab *uv_systab; diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index 36698cc9fb44b..6c8a6ead84f6e 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -79,7 +79,7 @@ struct x86_init_paging { /** * struct x86_init_timers - platform specific timer setup - * @setup_perpcu_clockev: set up the per cpu clock event device for the + * @setup_percpu_clockev: set up the per cpu clock event device for the * boot cpu * @timer_init: initialize the platform timer (default PIT/HPET) * @wallclock_init: init the wallclock device @@ -132,7 +132,7 @@ struct x86_hyper_init { /** * struct x86_init_acpi - x86 ACPI init functions - * @set_root_poitner: set RSDP address + * @set_root_pointer: set RSDP address * @get_root_pointer: get RSDP address * @reduced_hw_early_init: hardware reduced platform early init */ @@ -145,14 +145,14 @@ struct x86_init_acpi { /** * struct x86_guest - Functions used by misc guest incarnations like SEV, TDX, etc. * - * @enc_status_change_prepare Notify HV before the encryption status of a range is changed - * @enc_status_change_finish Notify HV after the encryption status of a range is changed - * @enc_tlb_flush_required Returns true if a TLB flush is needed before changing page encryption status - * @enc_cache_flush_required Returns true if a cache flush is needed before changing page encryption status - * @enc_kexec_begin Begin the two-step process of converting shared memory back + * @enc_status_change_prepare: Notify HV before the encryption status of a range is changed + * @enc_status_change_finish: Notify HV after the encryption status of a range is changed + * @enc_tlb_flush_required: Returns true if a TLB flush is needed before changing page encryption status + * @enc_cache_flush_required: Returns true if a cache flush is needed before changing page encryption status + * @enc_kexec_begin: Begin the two-step process of converting shared memory back * to private. It stops the new conversions from being started * and waits in-flight conversions to finish, if possible. - * @enc_kexec_finish Finish the two-step process of converting shared memory to + * @enc_kexec_finish: Finish the two-step process of converting shared memory to * private. All memory is private after the call when * the function returns. * It is called on only one CPU while the others are shut down @@ -229,7 +229,7 @@ struct x86_legacy_devices { * given platform/subarch. * @X86_LEGACY_I8042_FIRMWARE_ABSENT: firmware reports that the controller * is absent. - * @X86_LEGACY_i8042_EXPECTED_PRESENT: the controller is likely to be + * @X86_LEGACY_I8042_EXPECTED_PRESENT: the controller is likely to be * present, the i8042 driver should probe for controller existence. */ enum x86_legacy_i8042_state { @@ -244,6 +244,8 @@ enum x86_legacy_i8042_state { * @i8042: indicated if we expect the device to have i8042 controller * present. * @rtc: this device has a CMOS real-time clock present + * @warm_reset: 1 if platform allows warm reset, else 0 + * @no_vga: 1 if (FADT.boot_flags & ACPI_FADT_NO_VGA) is set, else 0 * @reserve_bios_regions: boot code will search for the EBDA address and the * start of the 640k - 1M BIOS region. If false, the platform must * ensure that its memory map correctly reserves sub-1MB regions as needed. @@ -290,9 +292,10 @@ struct x86_hyper_runtime { * @calibrate_tsc: calibrate TSC, if different from CPU * @get_wallclock: get time from HW clock like RTC etc. * @set_wallclock: set time back to HW clock - * @is_untracked_pat_range exclude from PAT logic - * @nmi_init enable NMI on cpus - * @get_nmi_reason get the reason an NMI was received + * @iommu_shutdown: set by an IOMMU driver for shutdown if necessary + * @is_untracked_pat_range: exclude from PAT logic + * @nmi_init: enable NMI on cpus + * @get_nmi_reason: get the reason an NMI was received * @save_sched_clock_state: save state for sched_clock() on suspend * @restore_sched_clock_state: restore state for sched_clock() on resume * @apic_post_init: adjust apic if needed @@ -307,6 +310,7 @@ struct x86_hyper_runtime { * @realmode_reserve: reserve memory for realmode trampoline * @realmode_init: initialize realmode trampoline * @hyper: x86 hypervisor specific runtime callbacks + * @guest: guest incarnations callbacks */ struct x86_platform_ops { unsigned long (*calibrate_cpu)(void); diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index d420c9c066d48..7ceff65836525 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -502,6 +502,7 @@ struct kvm_sync_regs { /* vendor-specific groups and attributes for system fd */ #define KVM_X86_GRP_SEV 1 # define KVM_X86_SEV_VMSA_FEATURES 0 +# define KVM_X86_SNP_POLICY_BITS 1 struct kvm_vmx_nested_state_data { __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 74f4c659f9c9f..28518371d8bf3 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -2229,7 +2229,7 @@ asm ( " .pushsection .init.text, \"ax\", @progbits\n" " .type int3_selftest_asm, @function\n" "int3_selftest_asm:\n" - ANNOTATE_NOENDBR + ANNOTATE_NOENDBR "\n" /* * INT3 padded with NOP to CALL_INSN_SIZE. The INT3 triggers an * exception, then the int3_exception_nb notifier emulates a call to @@ -2247,7 +2247,7 @@ asm ( " .pushsection .init.text, \"ax\", @progbits\n" " .type int3_selftest_callee, @function\n" "int3_selftest_callee:\n" - ANNOTATE_NOENDBR + ANNOTATE_NOENDBR "\n" " movl $0x1234, (%" _ASM_ARG1 ")\n" ASM_RET " .size int3_selftest_callee, . - int3_selftest_callee\n" diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c index 3485d419c2f5e..e8000a56732e4 100644 --- a/arch/x86/kernel/amd_gart_64.c +++ b/arch/x86/kernel/amd_gart_64.c @@ -222,13 +222,14 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, } /* Map a single area into the IOMMU */ -static dma_addr_t gart_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, +static dma_addr_t gart_map_phys(struct device *dev, phys_addr_t paddr, + size_t size, enum dma_data_direction dir, unsigned long attrs) { unsigned long bus; - phys_addr_t paddr = page_to_phys(page) + offset; + + if (unlikely(attrs & DMA_ATTR_MMIO)) + return DMA_MAPPING_ERROR; if (!need_iommu(dev, paddr, size)) return paddr; @@ -242,7 +243,7 @@ static dma_addr_t gart_map_page(struct device *dev, struct page *page, /* * Free a DMA mapping. */ -static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr, +static void gart_unmap_phys(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir, unsigned long attrs) { @@ -282,7 +283,7 @@ static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, for_each_sg(sg, s, nents, i) { if (!s->dma_length || !s->length) break; - gart_unmap_page(dev, s->dma_address, s->dma_length, dir, 0); + gart_unmap_phys(dev, s->dma_address, s->dma_length, dir, 0); } } @@ -487,7 +488,7 @@ static void gart_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_addr, unsigned long attrs) { - gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, 0); + gart_unmap_phys(dev, dma_addr, size, DMA_BIDIRECTIONAL, 0); dma_direct_free(dev, size, vaddr, dma_addr, attrs); } @@ -591,7 +592,7 @@ static void gart_fixup_northbridges(void) } } -static void gart_resume(void) +static void gart_resume(void *data) { pr_info("PCI-DMA: Resuming GART IOMMU\n"); @@ -600,11 +601,15 @@ static void gart_resume(void) enable_gart_translations(); } -static struct syscore_ops gart_syscore_ops = { +static const struct syscore_ops gart_syscore_ops = { .resume = gart_resume, }; +static struct syscore gart_syscore = { + .ops = &gart_syscore_ops, +}; + /* * Private Northbridge GATT initialization in case we cannot use the * AGP driver for some reason. @@ -650,7 +655,7 @@ static __init int init_amd_gatt(struct agp_kern_info *info) agp_gatt_table = gatt; - register_syscore_ops(&gart_syscore_ops); + register_syscore(&gart_syscore); flush_gart(); @@ -668,8 +673,8 @@ static __init int init_amd_gatt(struct agp_kern_info *info) static const struct dma_map_ops gart_dma_ops = { .map_sg = gart_map_sg, .unmap_sg = gart_unmap_sg, - .map_page = gart_map_page, - .unmap_page = gart_unmap_page, + .map_phys = gart_map_phys, + .unmap_phys = gart_unmap_phys, .alloc = gart_alloc_coherent, .free = gart_free_coherent, .mmap = dma_common_mmap, diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 9c29e12b84e5d..d93f87f29d03b 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -2385,7 +2385,7 @@ static struct { unsigned int apic_cmci; } apic_pm_state; -static int lapic_suspend(void) +static int lapic_suspend(void *data) { unsigned long flags; int maxlvt; @@ -2433,7 +2433,7 @@ static int lapic_suspend(void) return 0; } -static void lapic_resume(void) +static void lapic_resume(void *data) { unsigned int l, h; unsigned long flags; @@ -2508,11 +2508,15 @@ static void lapic_resume(void) * are needed on every CPU up until machine_halt/restart/poweroff. */ -static struct syscore_ops lapic_syscore_ops = { +static const struct syscore_ops lapic_syscore_ops = { .resume = lapic_resume, .suspend = lapic_suspend, }; +static struct syscore lapic_syscore = { + .ops = &lapic_syscore_ops, +}; + static void apic_pm_activate(void) { apic_pm_state.active = 1; @@ -2522,7 +2526,7 @@ static int __init init_lapic_sysfs(void) { /* XXX: remove suspend/resume procs if !apic_pm_state.active? */ if (boot_cpu_has(X86_FEATURE_APIC)) - register_syscore_ops(&lapic_syscore_ops); + register_syscore(&lapic_syscore); return 0; } diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 1e0442e867b1c..28f934f05a850 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2308,7 +2308,12 @@ static void resume_ioapic_id(int ioapic_idx) } } -static void ioapic_resume(void) +static int ioapic_suspend(void *data) +{ + return save_ioapic_entries(); +} + +static void ioapic_resume(void *data) { int ioapic_idx; @@ -2318,14 +2323,18 @@ static void ioapic_resume(void) restore_ioapic_entries(); } -static struct syscore_ops ioapic_syscore_ops = { - .suspend = save_ioapic_entries, +static const struct syscore_ops ioapic_syscore_ops = { + .suspend = ioapic_suspend, .resume = ioapic_resume, }; +static struct syscore ioapic_syscore = { + .ops = &ioapic_syscore_ops, +}; + static int __init ioapic_init_ops(void) { - register_syscore_ops(&ioapic_syscore_ops); + register_syscore(&ioapic_syscore); return 0; } diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c index 32ba599a51f88..25fcde525c68c 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c @@ -124,4 +124,7 @@ static void __used common(void) OFFSET(ARIA_CTX_rounds, aria_ctx, rounds); #endif + BLANK(); + DEFINE(ALT_INSTR_SIZE, sizeof(struct alt_instr)); + DEFINE(EXTABLE_SIZE, sizeof(struct exception_table_entry)); } diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c index a315b0627dfb1..7ffc78d5ebf21 100644 --- a/arch/x86/kernel/cpu/aperfmperf.c +++ b/arch/x86/kernel/cpu/aperfmperf.c @@ -37,7 +37,7 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(struct aperfmperf, cpu_samples) = { .seq = SEQCNT_ZERO(cpu_samples.seq) }; -static void init_counter_refs(void) +static void init_counter_refs(void *data) { u64 aperf, mperf; @@ -289,16 +289,20 @@ static bool __init intel_set_max_freq_ratio(void) } #ifdef CONFIG_PM_SLEEP -static struct syscore_ops freq_invariance_syscore_ops = { +static const struct syscore_ops freq_invariance_syscore_ops = { .resume = init_counter_refs, }; -static void register_freq_invariance_syscore_ops(void) +static struct syscore freq_invariance_syscore = { + .ops = &freq_invariance_syscore_ops, +}; + +static void register_freq_invariance_syscore(void) { - register_syscore_ops(&freq_invariance_syscore_ops); + register_syscore(&freq_invariance_syscore); } #else -static inline void register_freq_invariance_syscore_ops(void) {} +static inline void register_freq_invariance_syscore(void) {} #endif static void freq_invariance_enable(void) @@ -308,7 +312,7 @@ static void freq_invariance_enable(void) return; } static_branch_enable_cpuslocked(&arch_scale_freq_key); - register_freq_invariance_syscore_ops(); + register_freq_invariance_syscore(); pr_info("Estimated ratio of average max frequency by base frequency (times 1024): %llu\n", arch_max_freq_ratio); } @@ -535,7 +539,7 @@ static int __init bp_init_aperfmperf(void) if (!cpu_feature_enabled(X86_FEATURE_APERFMPERF)) return 0; - init_counter_refs(); + init_counter_refs(NULL); bp_init_freq_invariance(); return 0; } @@ -544,5 +548,5 @@ early_initcall(bp_init_aperfmperf); void ap_init_aperfmperf(void) { if (cpu_feature_enabled(X86_FEATURE_APERFMPERF)) - init_counter_refs(); + init_counter_refs(NULL); } diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index d8660770dc6ac..d0a2847a4bb05 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -145,14 +145,6 @@ EXPORT_SYMBOL_GPL(cpu_buf_idle_clear); */ DEFINE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); -/* - * Controls CPU Fill buffer clear before VMenter. This is a subset of - * X86_FEATURE_CLEAR_CPU_BUF, and should only be enabled when KVM-only - * mitigation is required. - */ -DEFINE_STATIC_KEY_FALSE(cpu_buf_vm_clear); -EXPORT_SYMBOL_FOR_KVM(cpu_buf_vm_clear); - #undef pr_fmt #define pr_fmt(fmt) "mitigations: " fmt @@ -349,8 +341,8 @@ static enum rfds_mitigations rfds_mitigation __ro_after_init = IS_ENABLED(CONFIG_MITIGATION_RFDS) ? RFDS_MITIGATION_AUTO : RFDS_MITIGATION_OFF; /* - * Set if any of MDS/TAA/MMIO/RFDS are going to enable VERW clearing - * through X86_FEATURE_CLEAR_CPU_BUF on kernel and guest entry. + * Set if any of MDS/TAA/MMIO/RFDS are going to enable VERW clearing on exit to + * userspace *and* on entry to KVM guests. */ static bool verw_clear_cpu_buf_mitigation_selected __ro_after_init; @@ -396,6 +388,7 @@ static void __init mds_apply_mitigation(void) if (mds_mitigation == MDS_MITIGATION_FULL || mds_mitigation == MDS_MITIGATION_VMWERV) { setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM); if (!boot_cpu_has(X86_BUG_MSBDS_ONLY) && (mds_nosmt || smt_mitigations == SMT_MITIGATIONS_ON)) cpu_smt_disable(false); @@ -507,6 +500,7 @@ static void __init taa_apply_mitigation(void) * present on host, enable the mitigation for UCODE_NEEDED as well. */ setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM); if (taa_nosmt || smt_mitigations == SMT_MITIGATIONS_ON) cpu_smt_disable(false); @@ -608,9 +602,9 @@ static void __init mmio_apply_mitigation(void) */ if (verw_clear_cpu_buf_mitigation_selected) { setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); - static_branch_disable(&cpu_buf_vm_clear); + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM); } else { - static_branch_enable(&cpu_buf_vm_clear); + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM_MMIO); } /* @@ -699,8 +693,10 @@ static void __init rfds_update_mitigation(void) static void __init rfds_apply_mitigation(void) { - if (rfds_mitigation == RFDS_MITIGATION_VERW) + if (rfds_mitigation == RFDS_MITIGATION_VERW) { setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM); + } } static __init int rfds_parse_cmdline(char *str) diff --git a/arch/x86/kernel/cpu/intel_epb.c b/arch/x86/kernel/cpu/intel_epb.c index bc7671f920a7e..2c56f8730f596 100644 --- a/arch/x86/kernel/cpu/intel_epb.c +++ b/arch/x86/kernel/cpu/intel_epb.c @@ -75,7 +75,7 @@ static u8 energ_perf_values[] = { [EPB_INDEX_POWERSAVE] = ENERGY_PERF_BIAS_POWERSAVE, }; -static int intel_epb_save(void) +static int intel_epb_save(void *data) { u64 epb; @@ -89,7 +89,7 @@ static int intel_epb_save(void) return 0; } -static void intel_epb_restore(void) +static void intel_epb_restore(void *data) { u64 val = this_cpu_read(saved_epb); u64 epb; @@ -114,11 +114,15 @@ static void intel_epb_restore(void) wrmsrq(MSR_IA32_ENERGY_PERF_BIAS, (epb & ~EPB_MASK) | val); } -static struct syscore_ops intel_epb_syscore_ops = { +static const struct syscore_ops intel_epb_syscore_ops = { .suspend = intel_epb_save, .resume = intel_epb_restore, }; +static struct syscore intel_epb_syscore = { + .ops = &intel_epb_syscore_ops, +}; + static const char * const energy_perf_strings[] = { [EPB_INDEX_PERFORMANCE] = "performance", [EPB_INDEX_BALANCE_PERFORMANCE] = "balance-performance", @@ -185,7 +189,7 @@ static int intel_epb_online(unsigned int cpu) { struct device *cpu_dev = get_cpu_device(cpu); - intel_epb_restore(); + intel_epb_restore(NULL); if (!cpuhp_tasks_frozen) sysfs_merge_group(&cpu_dev->kobj, &intel_epb_attr_group); @@ -199,7 +203,7 @@ static int intel_epb_offline(unsigned int cpu) if (!cpuhp_tasks_frozen) sysfs_unmerge_group(&cpu_dev->kobj, &intel_epb_attr_group); - intel_epb_save(); + intel_epb_save(NULL); return 0; } @@ -230,7 +234,7 @@ static __init int intel_epb_init(void) if (ret < 0) goto err_out_online; - register_syscore_ops(&intel_epb_syscore_ops); + register_syscore(&intel_epb_syscore); return 0; err_out_online: diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index 4aff14e042873..34440021e8cfa 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -1729,6 +1730,9 @@ noinstr void do_machine_check(struct pt_regs *regs) } out: + /* Given it didn't panic, mark it as recoverable */ + hwerr_log_error_type(HWERR_RECOV_OTHERS); + instrumentation_end(); clear: @@ -2439,13 +2443,13 @@ static void vendor_disable_error_reporting(void) mce_disable_error_reporting(); } -static int mce_syscore_suspend(void) +static int mce_syscore_suspend(void *data) { vendor_disable_error_reporting(); return 0; } -static void mce_syscore_shutdown(void) +static void mce_syscore_shutdown(void *data) { vendor_disable_error_reporting(); } @@ -2455,7 +2459,7 @@ static void mce_syscore_shutdown(void) * Only one CPU is active at this time, the others get re-added later using * CPU hotplug: */ -static void mce_syscore_resume(void) +static void mce_syscore_resume(void *data) { __mcheck_cpu_init_generic(); __mcheck_cpu_init_vendor(raw_cpu_ptr(&cpu_info)); @@ -2463,12 +2467,16 @@ static void mce_syscore_resume(void) cr4_set_bits(X86_CR4_MCE); } -static struct syscore_ops mce_syscore_ops = { +static const struct syscore_ops mce_syscore_ops = { .suspend = mce_syscore_suspend, .shutdown = mce_syscore_shutdown, .resume = mce_syscore_resume, }; +static struct syscore mce_syscore = { + .ops = &mce_syscore_ops, +}; + /* * mce_device: Sysfs support */ @@ -2869,7 +2877,7 @@ static __init int mcheck_init_device(void) if (err < 0) goto err_out_online; - register_syscore_ops(&mce_syscore_ops); + register_syscore(&mce_syscore); return 0; diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index ccc83b0bf63c8..68049f171860e 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -823,8 +823,17 @@ void microcode_bsp_resume(void) reload_early_microcode(cpu); } -static struct syscore_ops mc_syscore_ops = { - .resume = microcode_bsp_resume, +static void microcode_bsp_syscore_resume(void *data) +{ + microcode_bsp_resume(); +} + +static const struct syscore_ops mc_syscore_ops = { + .resume = microcode_bsp_syscore_resume, +}; + +static struct syscore mc_syscore = { + .ops = &mc_syscore_ops, }; static int mc_cpu_online(unsigned int cpu) @@ -903,7 +912,7 @@ static int __init microcode_init(void) } } - register_syscore_ops(&mc_syscore_ops); + register_syscore(&mc_syscore); cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/microcode:online", mc_cpu_online, mc_cpu_down_prep); diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index c4febdbcfe4d8..579fb2c64cfd4 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -28,9 +28,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -39,6 +39,12 @@ bool hv_nested; struct ms_hyperv_info ms_hyperv; #if IS_ENABLED(CONFIG_HYPERV) +/* + * When running with the paravisor, controls proxying the synthetic interrupts + * from the host + */ +static bool hv_para_sint_proxy; + static inline unsigned int hv_get_nested_msr(unsigned int reg) { if (hv_is_sint_msr(reg)) @@ -75,17 +81,51 @@ EXPORT_SYMBOL_GPL(hv_get_non_nested_msr); void hv_set_non_nested_msr(unsigned int reg, u64 value) { if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present) { + /* The hypervisor will get the intercept. */ hv_ivm_msr_write(reg, value); - /* Write proxy bit via wrmsl instruction */ - if (hv_is_sint_msr(reg)) - wrmsrq(reg, value | 1 << 20); + /* Using wrmsrq so the following goes to the paravisor. */ + if (hv_is_sint_msr(reg)) { + union hv_synic_sint sint = { .as_uint64 = value }; + + sint.proxy = hv_para_sint_proxy; + native_wrmsrq(reg, sint.as_uint64); + } } else { - wrmsrq(reg, value); + native_wrmsrq(reg, value); } } EXPORT_SYMBOL_GPL(hv_set_non_nested_msr); +/* + * Enable or disable proxying synthetic interrupts + * to the paravisor. + */ +void hv_para_set_sint_proxy(bool enable) +{ + hv_para_sint_proxy = enable; +} + +/* + * Get the SynIC register value from the paravisor. + */ +u64 hv_para_get_synic_register(unsigned int reg) +{ + if (WARN_ON(!ms_hyperv.paravisor_present || !hv_is_synic_msr(reg))) + return ~0ULL; + return native_read_msr(reg); +} + +/* + * Set the SynIC register value with the paravisor. + */ +void hv_para_set_synic_register(unsigned int reg, u64 val) +{ + if (WARN_ON(!ms_hyperv.paravisor_present || !hv_is_synic_msr(reg))) + return; + native_write_msr(reg, val); +} + u64 hv_get_msr(unsigned int reg) { if (hv_nested) @@ -215,7 +255,7 @@ static void hv_machine_shutdown(void) #endif /* CONFIG_KEXEC_CORE */ #ifdef CONFIG_CRASH_DUMP -static void hv_machine_crash_shutdown(struct pt_regs *regs) +static void hv_guest_crash_shutdown(struct pt_regs *regs) { if (hv_crash_handler) hv_crash_handler(regs); @@ -440,7 +480,7 @@ EXPORT_SYMBOL_GPL(hv_get_hypervisor_version); static void __init ms_hyperv_init_platform(void) { - int hv_max_functions_eax; + int hv_max_functions_eax, eax; #ifdef CONFIG_PARAVIRT pv_info.name = "Hyper-V"; @@ -470,11 +510,27 @@ static void __init ms_hyperv_init_platform(void) hv_identify_partition_type(); + if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC)) + ms_hyperv.hints |= HV_DEPRECATING_AEOI_RECOMMENDED; + if (ms_hyperv.hints & HV_X64_HYPERV_NESTED) { hv_nested = true; pr_info("Hyper-V: running on a nested hypervisor\n"); } + /* + * There is no check against the max function for HYPERV_CPUID_VIRT_STACK_* CPUID + * leaves as the hypervisor doesn't handle them. Even a nested root partition (L2 + * root) will not get them because the nested (L1) hypervisor filters them out. + * These are handled through intercept processing by the Windows Hyper-V stack + * or the paravisor. + */ + eax = cpuid_eax(HYPERV_CPUID_VIRT_STACK_PROPERTIES); + ms_hyperv.confidential_vmbus_available = + eax & HYPERV_VS_PROPERTIES_EAX_CONFIDENTIAL_VMBUS_AVAILABLE; + ms_hyperv.msi_ext_dest_id = + eax & HYPERV_VS_PROPERTIES_EAX_EXTENDED_IOAPIC_RTE; + if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS && ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { x86_platform.calibrate_tsc = hv_get_tsc_khz; @@ -565,11 +621,14 @@ static void __init ms_hyperv_init_platform(void) #endif #if IS_ENABLED(CONFIG_HYPERV) + if (hv_root_partition()) + machine_ops.power_off = hv_machine_power_off; #if defined(CONFIG_KEXEC_CORE) machine_ops.shutdown = hv_machine_shutdown; #endif #if defined(CONFIG_CRASH_DUMP) - machine_ops.crash_shutdown = hv_machine_crash_shutdown; + if (!hv_root_partition()) + machine_ops.crash_shutdown = hv_guest_crash_shutdown; #endif #endif /* @@ -675,21 +734,10 @@ static bool __init ms_hyperv_x2apic_available(void) * pci-hyperv host bridge. * * Note: for a Hyper-V root partition, this will always return false. - * The hypervisor doesn't expose these HYPERV_CPUID_VIRT_STACK_* cpuids by - * default, they are implemented as intercepts by the Windows Hyper-V stack. - * Even a nested root partition (L2 root) will not get them because the - * nested (L1) hypervisor filters them out. */ static bool __init ms_hyperv_msi_ext_dest_id(void) { - u32 eax; - - eax = cpuid_eax(HYPERV_CPUID_VIRT_STACK_INTERFACE); - if (eax != HYPERV_VS_INTERFACE_EAX_SIGNATURE) - return false; - - eax = cpuid_eax(HYPERV_CPUID_VIRT_STACK_PROPERTIES); - return eax & HYPERV_VS_PROPERTIES_EAX_EXTENDED_IOAPIC_RTE; + return ms_hyperv.msi_ext_dest_id; } #ifdef CONFIG_AMD_MEM_ENCRYPT diff --git a/arch/x86/kernel/cpu/mtrr/legacy.c b/arch/x86/kernel/cpu/mtrr/legacy.c index d25882fcf181d..2415ffaaf02c0 100644 --- a/arch/x86/kernel/cpu/mtrr/legacy.c +++ b/arch/x86/kernel/cpu/mtrr/legacy.c @@ -41,7 +41,7 @@ struct mtrr_value { static struct mtrr_value *mtrr_value; -static int mtrr_save(void) +static int mtrr_save(void *data) { int i; @@ -56,7 +56,7 @@ static int mtrr_save(void) return 0; } -static void mtrr_restore(void) +static void mtrr_restore(void *data) { int i; @@ -69,11 +69,15 @@ static void mtrr_restore(void) } } -static struct syscore_ops mtrr_syscore_ops = { +static const struct syscore_ops mtrr_syscore_ops = { .suspend = mtrr_save, .resume = mtrr_restore, }; +static struct syscore mtrr_syscore = { + .ops = &mtrr_syscore_ops, +}; + void mtrr_register_syscore(void) { mtrr_value = kcalloc(num_var_ranges, sizeof(*mtrr_value), GFP_KERNEL); @@ -86,5 +90,5 @@ void mtrr_register_syscore(void) * TBD: is there any system with such CPU which supports * suspend/resume? If no, we should remove the code. */ - register_syscore_ops(&mtrr_syscore_ops); + register_syscore(&mtrr_syscore); } diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index cde4b6cd34718..42c7eac0c387b 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -53,6 +53,7 @@ static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 }, { X86_FEATURE_AMD_FAST_CPPC, CPUID_EDX, 15, 0x80000007, 0 }, { X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 }, + { X86_FEATURE_X2AVIC_EXT, CPUID_ECX, 6, 0x8000000a, 0 }, { X86_FEATURE_COHERENCY_SFW_NO, CPUID_EBX, 31, 0x8000001f, 0 }, { X86_FEATURE_SMBA, CPUID_EBX, 2, 0x80000020, 0 }, { X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 }, diff --git a/arch/x86/kernel/cpu/sgx/driver.c b/arch/x86/kernel/cpu/sgx/driver.c index 79d6020dfe9c8..a42c7180900b4 100644 --- a/arch/x86/kernel/cpu/sgx/driver.c +++ b/arch/x86/kernel/cpu/sgx/driver.c @@ -130,7 +130,7 @@ static unsigned long sgx_get_unmapped_area(struct file *file, if (flags & MAP_FIXED) return addr; - return mm_get_unmapped_area(current->mm, file, addr, len, pgoff, flags); + return mm_get_unmapped_area(file, addr, len, pgoff, flags); } #ifdef CONFIG_COMPAT diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index 66f1efa16fbb7..9322a9287dc7f 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -242,7 +242,7 @@ static int __sgx_encl_add_page(struct sgx_encl *encl, /* * If the caller requires measurement of the page as a proof for the content, * use EEXTEND to add a measurement for 256 bytes of the page. Repeat this - * operation until the entire page is measured." + * operation until the entire page is measured. */ static int __sgx_encl_extend(struct sgx_encl *encl, struct sgx_epc_page *epc_page) diff --git a/arch/x86/kernel/cpu/umwait.c b/arch/x86/kernel/cpu/umwait.c index 933fcd7ff2502..e4a31c5366427 100644 --- a/arch/x86/kernel/cpu/umwait.c +++ b/arch/x86/kernel/cpu/umwait.c @@ -86,15 +86,19 @@ static int umwait_cpu_offline(unsigned int cpu) * trust the firmware nor does it matter if the same value is written * again. */ -static void umwait_syscore_resume(void) +static void umwait_syscore_resume(void *data) { umwait_update_control_msr(NULL); } -static struct syscore_ops umwait_syscore_ops = { +static const struct syscore_ops umwait_syscore_ops = { .resume = umwait_syscore_resume, }; +static struct syscore umwait_syscore = { + .ops = &umwait_syscore_ops, +}; + /* sysfs interface */ /* @@ -226,7 +230,7 @@ static int __init umwait_init(void) return ret; } - register_syscore_ops(&umwait_syscore_ops); + register_syscore(&umwait_syscore); /* * Add umwait control interface. Ignore failure, so at least the diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index 48113c5193aa3..76153dfb58c9d 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -1946,7 +1946,7 @@ static int dump_xsave_layout_desc(struct coredump_params *cprm) }; if (!dump_emit(cprm, &xc, sizeof(xc))) - return 0; + return -1; num_records++; } @@ -1984,7 +1984,7 @@ int elf_coredump_extra_notes_write(struct coredump_params *cprm) return 1; num_records = dump_xsave_layout_desc(cprm); - if (!num_records) + if (num_records < 0) return 1; /* Total size should be equal to the number of records */ diff --git a/arch/x86/kernel/i8237.c b/arch/x86/kernel/i8237.c index 2cd124ad9380c..896d46b442848 100644 --- a/arch/x86/kernel/i8237.c +++ b/arch/x86/kernel/i8237.c @@ -19,7 +19,7 @@ * in asm/dma.h. */ -static void i8237A_resume(void) +static void i8237A_resume(void *data) { unsigned long flags; int i; @@ -41,10 +41,14 @@ static void i8237A_resume(void) release_dma_lock(flags); } -static struct syscore_ops i8237_syscore_ops = { +static const struct syscore_ops i8237_syscore_ops = { .resume = i8237A_resume, }; +static struct syscore i8237_syscore = { + .ops = &i8237_syscore_ops, +}; + static int __init i8237A_init_ops(void) { /* @@ -70,7 +74,7 @@ static int __init i8237A_init_ops(void) if (x86_pnpbios_disabled() && dmi_get_bios_year() >= 2017) return -ENODEV; - register_syscore_ops(&i8237_syscore_ops); + register_syscore(&i8237_syscore); return 0; } device_initcall(i8237A_init_ops); diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index 2bade73f49e33..f67063df67235 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -247,19 +247,19 @@ static void save_ELCR(char *trigger) trigger[1] = inb(PIC_ELCR2) & 0xDE; } -static void i8259A_resume(void) +static void i8259A_resume(void *data) { init_8259A(i8259A_auto_eoi); restore_ELCR(irq_trigger); } -static int i8259A_suspend(void) +static int i8259A_suspend(void *data) { save_ELCR(irq_trigger); return 0; } -static void i8259A_shutdown(void) +static void i8259A_shutdown(void *data) { /* Put the i8259A into a quiescent state that * the kernel initialization code can get it @@ -269,12 +269,16 @@ static void i8259A_shutdown(void) outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ } -static struct syscore_ops i8259_syscore_ops = { +static const struct syscore_ops i8259_syscore_ops = { .suspend = i8259A_suspend, .resume = i8259A_resume, .shutdown = i8259A_shutdown, }; +static struct syscore i8259_syscore = { + .ops = &i8259_syscore_ops, +}; + static void mask_8259A(void) { unsigned long flags; @@ -444,7 +448,7 @@ EXPORT_SYMBOL(legacy_pic); static int __init i8259A_init_ops(void) { if (legacy_pic == &default_legacy_pic) - register_syscore_ops(&i8259_syscore_ops); + register_syscore(&i8259_syscore); return 0; } diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 86f4e574de026..b2fe6181960c3 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -397,6 +397,7 @@ DEFINE_IDTENTRY_SYSVEC_SIMPLE(sysvec_kvm_posted_intr_nested_ipi) /* Posted Interrupt Descriptors for coalesced MSIs to be posted */ DEFINE_PER_CPU_ALIGNED(struct pi_desc, posted_msi_pi_desc); +static DEFINE_PER_CPU_CACHE_HOT(bool, posted_msi_handler_active); void intel_posted_msi_init(void) { @@ -414,6 +415,25 @@ void intel_posted_msi_init(void) this_cpu_write(posted_msi_pi_desc.ndst, destination); } +void intel_ack_posted_msi_irq(struct irq_data *irqd) +{ + irq_move_irq(irqd); + + /* + * Handle the rare case that irq_retrigger() raised the actual + * assigned vector on the target CPU, which means that it was not + * invoked via the posted MSI handler below. In that case APIC EOI + * is required as otherwise the ISR entry becomes stale and lower + * priority interrupts are never going to be delivered after that. + * + * If the posted handler invoked the device interrupt handler then + * the EOI would be premature because it would acknowledge the + * posted vector. + */ + if (unlikely(!__this_cpu_read(posted_msi_handler_active))) + apic_eoi(); +} + static __always_inline bool handle_pending_pir(unsigned long *pir, struct pt_regs *regs) { unsigned long pir_copy[NR_PIR_WORDS]; @@ -446,6 +466,8 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_posted_msi_notification) pid = this_cpu_ptr(&posted_msi_pi_desc); + /* Mark the handler active for intel_ack_posted_msi_irq() */ + __this_cpu_write(posted_msi_handler_active, true); inc_irq_stat(posted_msi_notification_count); irq_enter(); @@ -474,6 +496,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_posted_msi_notification) apic_eoi(); irq_exit(); + __this_cpu_write(posted_msi_handler_active, false); set_irq_regs(old_regs); } #endif /* X86_POSTED_MSI */ diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 204765004c729..df78ddee0abbb 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -721,7 +721,7 @@ static int kvm_cpu_down_prepare(unsigned int cpu) #endif -static int kvm_suspend(void) +static int kvm_suspend(void *data) { u64 val = 0; @@ -735,7 +735,7 @@ static int kvm_suspend(void) return 0; } -static void kvm_resume(void) +static void kvm_resume(void *data) { kvm_cpu_online(raw_smp_processor_id()); @@ -745,11 +745,15 @@ static void kvm_resume(void) #endif } -static struct syscore_ops kvm_syscore_ops = { +static const struct syscore_ops kvm_syscore_ops = { .suspend = kvm_suspend, .resume = kvm_resume, }; +static struct syscore kvm_syscore = { + .ops = &kvm_syscore_ops, +}; + static void kvm_pv_guest_cpu_reboot(void *unused) { kvm_guest_cpu_offline(true); @@ -859,7 +863,7 @@ static void __init kvm_guest_init(void) machine_ops.crash_shutdown = kvm_crash_shutdown; #endif - register_syscore_ops(&kvm_syscore_ops); + register_syscore(&kvm_syscore); /* * Hard lockup detection is enabled by default. Disable it, as guests diff --git a/arch/x86/kernel/rethook.c b/arch/x86/kernel/rethook.c index 8a1c0111ae792..85e2f2d16a904 100644 --- a/arch/x86/kernel/rethook.c +++ b/arch/x86/kernel/rethook.c @@ -25,7 +25,7 @@ asm( ".type arch_rethook_trampoline, @function\n" "arch_rethook_trampoline:\n" #ifdef CONFIG_X86_64 - ANNOTATE_NOENDBR /* This is only jumped from ret instruction */ + ANNOTATE_NOENDBR "\n" /* This is only jumped from ret instruction */ /* Push a fake return address to tell the unwinder it's a rethook. */ " pushq $arch_rethook_trampoline\n" UNWIND_HINT_FUNC diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c index 2892cdb145638..61592e41a6b15 100644 --- a/arch/x86/kernel/static_call.c +++ b/arch/x86/kernel/static_call.c @@ -50,8 +50,8 @@ asm (".global __static_call_return\n\t" ".type __static_call_return, @function\n\t" ASM_FUNC_ALIGN "\n\t" "__static_call_return:\n\t" - ANNOTATE_NOENDBR - ANNOTATE_RETPOLINE_SAFE + ANNOTATE_NOENDBR "\n\t" + ANNOTATE_RETPOLINE_SAFE "\n\t" "ret; int3\n\t" ".size __static_call_return, . - __static_call_return \n\t"); diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c index 977ee75e047c8..f610fde2d5c4b 100644 --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -172,6 +173,25 @@ static struct orc_entry *orc_ftrace_find(unsigned long ip) } #endif +/* Fake frame pointer entry -- used as a fallback for generated code */ +static struct orc_entry orc_fp_entry = { + .type = ORC_TYPE_CALL, + .sp_reg = ORC_REG_BP, + .sp_offset = 16, + .bp_reg = ORC_REG_PREV_SP, + .bp_offset = -16, +}; + +static struct orc_entry *orc_bpf_find(unsigned long ip) +{ +#ifdef CONFIG_BPF_JIT + if (bpf_has_frame_pointer(ip)) + return &orc_fp_entry; +#endif + + return NULL; +} + /* * If we crash with IP==0, the last successfully executed instruction * was probably an indirect function call with a NULL function pointer, @@ -186,15 +206,6 @@ static struct orc_entry null_orc_entry = { .type = ORC_TYPE_CALL }; -/* Fake frame pointer entry -- used as a fallback for generated code */ -static struct orc_entry orc_fp_entry = { - .type = ORC_TYPE_CALL, - .sp_reg = ORC_REG_BP, - .sp_offset = 16, - .bp_reg = ORC_REG_PREV_SP, - .bp_offset = -16, -}; - static struct orc_entry *orc_find(unsigned long ip) { static struct orc_entry *orc; @@ -238,6 +249,11 @@ static struct orc_entry *orc_find(unsigned long ip) if (orc) return orc; + /* BPF lookup: */ + orc = orc_bpf_find(ip); + if (orc) + return orc; + return orc_ftrace_find(ip); } @@ -495,9 +511,8 @@ bool unwind_next_frame(struct unwind_state *state) if (!orc) { /* * As a fallback, try to assume this code uses a frame pointer. - * This is useful for generated code, like BPF, which ORC - * doesn't know about. This is just a guess, so the rest of - * the unwind is no longer considered reliable. + * This is just a guess, so the rest of the unwind is no longer + * considered reliable. */ orc = &orc_fp_entry; state->error = true; diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 52524e0ca97f7..88a5426674a10 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -509,11 +509,18 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2, u32 vcpu_caps[NR_KVM_CPU_CAPS]; int r; + /* + * Apply pending runtime CPUID updates to the current CPUID entries to + * avoid false positives due to mismatches on KVM-owned feature flags. + */ + if (vcpu->arch.cpuid_dynamic_bits_dirty) + kvm_update_cpuid_runtime(vcpu); + /* * Swap the existing (old) entries with the incoming (new) entries in * order to massage the new entries, e.g. to account for dynamic bits - * that KVM controls, without clobbering the current guest CPUID, which - * KVM needs to preserve in order to unwind on failure. + * that KVM controls, without losing the current guest CPUID, which KVM + * needs to preserve in order to unwind on failure. * * Similarly, save the vCPU's current cpu_caps so that the capabilities * can be updated alongside the CPUID entries when performing runtime @@ -1135,6 +1142,7 @@ void kvm_set_cpu_caps(void) F(AMD_STIBP), F(AMD_STIBP_ALWAYS_ON), F(AMD_IBRS_SAME_MODE), + PASSTHROUGH_F(EFER_LMSLE_MBZ), F(AMD_PSFD), F(AMD_IBPB_RET), ); diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 4e3da5b497b85..c8e292e9a24df 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -81,9 +81,8 @@ */ /* Operand sizes: 8-bit operands or specified/overridden size. */ -#define ByteOp (1<<0) /* 8-bit operands. */ -/* Destination operand type. */ -#define DstShift 1 +#define ByteOp (1<<0) /* 8-bit operands. */ +#define DstShift 1 /* Destination operand type at bits 1-5 */ #define ImplicitOps (OpImplicit << DstShift) #define DstReg (OpReg << DstShift) #define DstMem (OpMem << DstShift) @@ -95,8 +94,7 @@ #define DstDX (OpDX << DstShift) #define DstAccLo (OpAccLo << DstShift) #define DstMask (OpMask << DstShift) -/* Source operand type. */ -#define SrcShift 6 +#define SrcShift 6 /* Source operand type at bits 6-10 */ #define SrcNone (OpNone << SrcShift) #define SrcReg (OpReg << SrcShift) #define SrcMem (OpMem << SrcShift) @@ -119,10 +117,10 @@ #define SrcAccHi (OpAccHi << SrcShift) #define SrcMask (OpMask << SrcShift) #define BitOp (1<<11) -#define MemAbs (1<<12) /* Memory operand is absolute displacement */ +#define MemAbs (1<<12) /* Memory operand is absolute displacement */ #define String (1<<13) /* String instruction (rep capable) */ #define Stack (1<<14) /* Stack instruction (push/pop) */ -#define GroupMask (7<<15) /* Opcode uses one of the group mechanisms */ +#define GroupMask (7<<15) /* Group mechanisms, at bits 15-17 */ #define Group (1<<15) /* Bits 3:5 of modrm byte extend opcode */ #define GroupDual (2<<15) /* Alternate decoding of mod == 3 */ #define Prefix (3<<15) /* Instruction varies with 66/f2/f3 prefix */ @@ -131,11 +129,8 @@ #define InstrDual (6<<15) /* Alternate instruction decoding of mod == 3 */ #define ModeDual (7<<15) /* Different instruction for 32/64 bit */ #define Sse (1<<18) /* SSE Vector instruction */ -/* Generic ModRM decode. */ -#define ModRM (1<<19) -/* Destination is only written; never read. */ -#define Mov (1<<20) -/* Misc flags */ +#define ModRM (1<<19) /* Generic ModRM decode. */ +#define Mov (1<<20) /* Destination is only written; never read. */ #define Prot (1<<21) /* instruction generates #UD if not in prot-mode */ #define EmulateOnUD (1<<22) /* Emulate if unsupported by the host */ #define NoAccess (1<<23) /* Don't access memory (lea/invlpg/verr etc) */ @@ -143,11 +138,11 @@ #define Undefined (1<<25) /* No Such Instruction */ #define Lock (1<<26) /* lock prefix is allowed for the instruction */ #define Priv (1<<27) /* instruction generates #GP if current CPL != 0 */ -#define No64 (1<<28) +#define No64 (1<<28) /* Instruction generates #UD in 64-bit mode */ #define PageTable (1 << 29) /* instruction used to write page table */ #define NotImpl (1 << 30) /* instruction is not implemented */ -/* Source 2 operand type */ -#define Src2Shift (31) +#define Avx ((u64)1 << 31) /* Instruction uses VEX prefix */ +#define Src2Shift (32) /* Source 2 operand type at bits 32-36 */ #define Src2None (OpNone << Src2Shift) #define Src2Mem (OpMem << Src2Shift) #define Src2CL (OpCL << Src2Shift) @@ -161,12 +156,13 @@ #define Src2FS (OpFS << Src2Shift) #define Src2GS (OpGS << Src2Shift) #define Src2Mask (OpMask << Src2Shift) +/* free: 37-39 */ #define Mmx ((u64)1 << 40) /* MMX Vector instruction */ -#define AlignMask ((u64)7 << 41) +#define AlignMask ((u64)3 << 41) /* Memory alignment requirement at bits 41-42 */ #define Aligned ((u64)1 << 41) /* Explicitly aligned (e.g. MOVDQA) */ #define Unaligned ((u64)2 << 41) /* Explicitly unaligned (e.g. MOVDQU) */ -#define Avx ((u64)3 << 41) /* Advanced Vector Extensions */ -#define Aligned16 ((u64)4 << 41) /* Aligned to 16 byte boundary (e.g. FXSAVE) */ +#define Aligned16 ((u64)3 << 41) /* Aligned to 16 byte boundary (e.g. FXSAVE) */ +/* free: 43-44 */ #define NoWrite ((u64)1 << 45) /* No writeback */ #define SrcWrite ((u64)1 << 46) /* Write back src operand */ #define NoMod ((u64)1 << 47) /* Mod field is ignored */ @@ -243,6 +239,13 @@ enum x86_transfer_type { X86_TRANSFER_TASK_SWITCH, }; +enum rex_bits { + REX_B = 1, + REX_X = 2, + REX_R = 4, + REX_W = 8, +}; + static void writeback_registers(struct x86_emulate_ctxt *ctxt) { unsigned long dirty = ctxt->regs_dirty; @@ -622,7 +625,6 @@ static unsigned insn_alignment(struct x86_emulate_ctxt *ctxt, unsigned size) switch (alignment) { case Unaligned: - case Avx: return 1; case Aligned16: return 16; @@ -924,7 +926,7 @@ static void *decode_register(struct x86_emulate_ctxt *ctxt, u8 modrm_reg, int byteop) { void *p; - int highbyte_regs = (ctxt->rex_prefix == 0) && byteop; + int highbyte_regs = (ctxt->rex_prefix == REX_NONE) && byteop; if (highbyte_regs && modrm_reg >= 4 && modrm_reg < 8) p = (unsigned char *)reg_rmw(ctxt, modrm_reg & 3) + 1; @@ -1030,6 +1032,7 @@ static void fetch_register_operand(struct operand *op) op->val = *(u64 *)op->addr.reg; break; } + op->orig_val = op->val; } static int em_fninit(struct x86_emulate_ctxt *ctxt) @@ -1075,17 +1078,17 @@ static int em_fnstsw(struct x86_emulate_ctxt *ctxt) return X86EMUL_CONTINUE; } -static void decode_register_operand(struct x86_emulate_ctxt *ctxt, - struct operand *op) +static void __decode_register_operand(struct x86_emulate_ctxt *ctxt, + struct operand *op, int reg) { - unsigned int reg; - - if (ctxt->d & ModRM) - reg = ctxt->modrm_reg; - else - reg = (ctxt->b & 7) | ((ctxt->rex_prefix & 1) << 3); - - if (ctxt->d & Sse) { + if ((ctxt->d & Avx) && ctxt->op_bytes == 32) { + op->type = OP_YMM; + op->bytes = 32; + op->addr.xmm = reg; + kvm_read_avx_reg(reg, &op->vec_val2); + return; + } + if (ctxt->d & (Avx|Sse)) { op->type = OP_XMM; op->bytes = 16; op->addr.xmm = reg; @@ -1103,9 +1106,20 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt, op->type = OP_REG; op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; op->addr.reg = decode_register(ctxt, reg, ctxt->d & ByteOp); - fetch_register_operand(op); - op->orig_val = op->val; +} + +static void decode_register_operand(struct x86_emulate_ctxt *ctxt, + struct operand *op) +{ + unsigned int reg; + + if (ctxt->d & ModRM) + reg = ctxt->modrm_reg; + else + reg = (ctxt->b & 7) | (ctxt->rex_bits & REX_B ? 8 : 0); + + __decode_register_operand(ctxt, op, reg); } static void adjust_modrm_seg(struct x86_emulate_ctxt *ctxt, int base_reg) @@ -1122,9 +1136,9 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, int rc = X86EMUL_CONTINUE; ulong modrm_ea = 0; - ctxt->modrm_reg = ((ctxt->rex_prefix << 1) & 8); /* REX.R */ - index_reg = (ctxt->rex_prefix << 2) & 8; /* REX.X */ - base_reg = (ctxt->rex_prefix << 3) & 8; /* REX.B */ + ctxt->modrm_reg = (ctxt->rex_bits & REX_R ? 8 : 0); + index_reg = (ctxt->rex_bits & REX_X ? 8 : 0); + base_reg = (ctxt->rex_bits & REX_B ? 8 : 0); ctxt->modrm_mod = (ctxt->modrm & 0xc0) >> 6; ctxt->modrm_reg |= (ctxt->modrm & 0x38) >> 3; @@ -1132,24 +1146,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, ctxt->modrm_seg = VCPU_SREG_DS; if (ctxt->modrm_mod == 3 || (ctxt->d & NoMod)) { - op->type = OP_REG; - op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; - op->addr.reg = decode_register(ctxt, ctxt->modrm_rm, - ctxt->d & ByteOp); - if (ctxt->d & Sse) { - op->type = OP_XMM; - op->bytes = 16; - op->addr.xmm = ctxt->modrm_rm; - kvm_read_sse_reg(ctxt->modrm_rm, &op->vec_val); - return rc; - } - if (ctxt->d & Mmx) { - op->type = OP_MM; - op->bytes = 8; - op->addr.mm = ctxt->modrm_rm & 7; - return rc; - } - fetch_register_operand(op); + __decode_register_operand(ctxt, op, ctxt->modrm_rm); return rc; } @@ -1783,7 +1780,15 @@ static int writeback(struct x86_emulate_ctxt *ctxt, struct operand *op) op->data, op->bytes * op->count); case OP_XMM: - kvm_write_sse_reg(op->addr.xmm, &op->vec_val); + if (!(ctxt->d & Avx)) { + kvm_write_sse_reg(op->addr.xmm, &op->vec_val); + break; + } + /* full YMM write but with high bytes cleared */ + memset(op->valptr + 16, 0, 16); + fallthrough; + case OP_YMM: + kvm_write_avx_reg(op->addr.xmm, &op->vec_val2); break; case OP_MM: kvm_write_mmx_reg(op->addr.mm, &op->mm_val); @@ -2466,7 +2471,7 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt) setup_syscalls_segments(&cs, &ss); - if ((ctxt->rex_prefix & 0x8) != 0x0) + if (ctxt->rex_bits & REX_W) usermode = X86EMUL_MODE_PROT64; else usermode = X86EMUL_MODE_PROT32; @@ -3958,6 +3963,8 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt) I2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock, _e), \ I2bv(((_f) & ~Lock) | DstAcc | SrcImm, _e) +static const struct opcode ud = I(SrcNone, emulate_ud); + static const struct opcode group7_rm0[] = { N, I(SrcNone | Priv | EmulateOnUD, em_hypercall), @@ -4114,7 +4121,7 @@ static const struct group_dual group15 = { { } }; static const struct gprefix pfx_0f_6f_0f_7f = { - I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov), + I(Mmx, em_mov), I(Sse | Avx | Aligned, em_mov), N, I(Sse | Avx | Unaligned, em_mov), }; static const struct instr_dual instr_dual_0f_2b = { @@ -4133,8 +4140,8 @@ static const struct gprefix pfx_0f_28_0f_29 = { I(Aligned, em_mov), I(Aligned, em_mov), N, N, }; -static const struct gprefix pfx_0f_e7 = { - N, I(Sse, em_mov), N, N, +static const struct gprefix pfx_0f_e7_0f_38_2a = { + N, I(Sse | Avx, em_mov), N, N, }; static const struct escape escape_d9 = { { @@ -4347,8 +4354,8 @@ static const struct opcode twobyte_table[256] = { DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N, N, D(ImplicitOps | ModRM | SrcMem | NoAccess), N, N, /* 0x10 - 0x1F */ - GP(ModRM | DstReg | SrcMem | Mov | Sse, &pfx_0f_10_0f_11), - GP(ModRM | DstMem | SrcReg | Mov | Sse, &pfx_0f_10_0f_11), + GP(ModRM | DstReg | SrcMem | Mov | Sse | Avx, &pfx_0f_10_0f_11), + GP(ModRM | DstMem | SrcReg | Mov | Sse | Avx, &pfx_0f_10_0f_11), N, N, N, N, N, N, D(ImplicitOps | ModRM | SrcMem | NoAccess), /* 4 * prefetch + 4 * reserved NOP */ D(ImplicitOps | ModRM | SrcMem | NoAccess), N, N, @@ -4364,9 +4371,9 @@ static const struct opcode twobyte_table[256] = { IIP(ModRM | SrcMem | Priv | Op3264 | NoMod, em_dr_write, dr_write, check_dr_write), N, N, N, N, - GP(ModRM | DstReg | SrcMem | Mov | Sse, &pfx_0f_28_0f_29), - GP(ModRM | DstMem | SrcReg | Mov | Sse, &pfx_0f_28_0f_29), - N, GP(ModRM | DstMem | SrcReg | Mov | Sse, &pfx_0f_2b), + GP(ModRM | DstReg | SrcMem | Mov | Sse | Avx, &pfx_0f_28_0f_29), + GP(ModRM | DstMem | SrcReg | Mov | Sse | Avx, &pfx_0f_28_0f_29), + N, GP(ModRM | DstMem | SrcReg | Mov | Sse | Avx, &pfx_0f_2b), N, N, N, N, /* 0x30 - 0x3F */ II(ImplicitOps | Priv, em_wrmsr, wrmsr), @@ -4431,7 +4438,7 @@ static const struct opcode twobyte_table[256] = { /* 0xD0 - 0xDF */ N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, /* 0xE0 - 0xEF */ - N, N, N, N, N, N, N, GP(SrcReg | DstMem | ModRM | Mov, &pfx_0f_e7), + N, N, N, N, N, N, N, GP(SrcReg | DstMem | ModRM | Mov, &pfx_0f_e7_0f_38_2a), N, N, N, N, N, N, N, N, /* 0xF0 - 0xFF */ N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N @@ -4458,8 +4465,13 @@ static const struct gprefix three_byte_0f_38_f1 = { * byte. */ static const struct opcode opcode_map_0f_38[256] = { - /* 0x00 - 0x7f */ - X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), + /* 0x00 - 0x1f */ + X16(N), X16(N), + /* 0x20 - 0x2f */ + X8(N), + X2(N), GP(SrcReg | DstMem | ModRM | Mov | Aligned, &pfx_0f_e7_0f_38_2a), N, N, N, N, N, + /* 0x30 - 0x7f */ + X16(N), X16(N), X16(N), X16(N), X16(N), /* 0x80 - 0xef */ X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), /* 0xf0 - 0xf1 */ @@ -4618,14 +4630,12 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX); fetch_register_operand(op); - op->orig_val = op->val; break; case OpAccLo: op->type = OP_REG; op->bytes = (ctxt->d & ByteOp) ? 2 : ctxt->op_bytes; op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX); fetch_register_operand(op); - op->orig_val = op->val; break; case OpAccHi: if (ctxt->d & ByteOp) { @@ -4636,7 +4646,6 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, op->bytes = ctxt->op_bytes; op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RDX); fetch_register_operand(op); - op->orig_val = op->val; break; case OpDI: op->type = OP_MEM; @@ -4755,12 +4764,87 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, return rc; } +static int x86_decode_avx(struct x86_emulate_ctxt *ctxt, + u8 vex_1st, u8 vex_2nd, struct opcode *opcode) +{ + u8 vex_3rd, map, pp, l, v; + int rc = X86EMUL_CONTINUE; + + if (ctxt->rep_prefix || ctxt->op_prefix || ctxt->rex_prefix) + goto ud; + + if (vex_1st == 0xc5) { + /* Expand RVVVVlpp to VEX3 format */ + vex_3rd = vex_2nd & ~0x80; /* VVVVlpp from VEX2, w=0 */ + vex_2nd = (vex_2nd & 0x80) | 0x61; /* R from VEX2, X=1 B=1 mmmmm=00001 */ + } else { + vex_3rd = insn_fetch(u8, ctxt); + } + + /* vex_2nd = RXBmmmmm, vex_3rd = wVVVVlpp. Fix polarity */ + vex_2nd ^= 0xE0; /* binary 11100000 */ + vex_3rd ^= 0x78; /* binary 01111000 */ + + ctxt->rex_prefix = REX_PREFIX; + ctxt->rex_bits = (vex_2nd & 0xE0) >> 5; /* RXB */ + ctxt->rex_bits |= (vex_3rd & 0x80) >> 4; /* w */ + if (ctxt->rex_bits && ctxt->mode != X86EMUL_MODE_PROT64) + goto ud; + + map = vex_2nd & 0x1f; + v = (vex_3rd >> 3) & 0xf; + l = vex_3rd & 0x4; + pp = vex_3rd & 0x3; + + ctxt->b = insn_fetch(u8, ctxt); + switch (map) { + case 1: + ctxt->opcode_len = 2; + *opcode = twobyte_table[ctxt->b]; + break; + case 2: + ctxt->opcode_len = 3; + *opcode = opcode_map_0f_38[ctxt->b]; + break; + case 3: + /* no 0f 3a instructions are supported yet */ + return X86EMUL_UNHANDLEABLE; + default: + goto ud; + } + + /* + * No three operand instructions are supported yet; those that + * *are* marked with the Avx flag reserve the VVVV flag. + */ + if (v) + goto ud; + + if (l) + ctxt->op_bytes = 32; + else + ctxt->op_bytes = 16; + + switch (pp) { + case 0: break; + case 1: ctxt->op_prefix = true; break; + case 2: ctxt->rep_prefix = 0xf3; break; + case 3: ctxt->rep_prefix = 0xf2; break; + } + +done: + return rc; +ud: + *opcode = ud; + return rc; +} + int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int emulation_type) { int rc = X86EMUL_CONTINUE; int mode = ctxt->mode; int def_op_bytes, def_ad_bytes, goffset, simd_prefix; - bool op_prefix = false; + bool vex_prefix = false; bool has_seg_override = false; struct opcode opcode; u16 dummy; @@ -4812,7 +4896,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int for (;;) { switch (ctxt->b = insn_fetch(u8, ctxt)) { case 0x66: /* operand-size override */ - op_prefix = true; + ctxt->op_prefix = true; /* switch between 2/4 bytes */ ctxt->op_bytes = def_op_bytes ^ 6; break; @@ -4851,7 +4935,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int case 0x40 ... 0x4f: /* REX */ if (mode != X86EMUL_MODE_PROT64) goto done_prefixes; - ctxt->rex_prefix = ctxt->b; + ctxt->rex_prefix = REX_PREFIX; + ctxt->rex_bits = ctxt->b & 0xf; continue; case 0xf0: /* LOCK */ ctxt->lock_prefix = 1; @@ -4865,20 +4950,33 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int } /* Any legacy prefix after a REX prefix nullifies its effect. */ - - ctxt->rex_prefix = 0; + ctxt->rex_prefix = REX_NONE; + ctxt->rex_bits = 0; } done_prefixes: /* REX prefix. */ - if (ctxt->rex_prefix & 8) - ctxt->op_bytes = 8; /* REX.W */ + if (ctxt->rex_bits & REX_W) + ctxt->op_bytes = 8; /* Opcode byte(s). */ - opcode = opcode_table[ctxt->b]; - /* Two-byte opcode? */ - if (ctxt->b == 0x0f) { + if (ctxt->b == 0xc4 || ctxt->b == 0xc5) { + /* VEX or LDS/LES */ + u8 vex_2nd = insn_fetch(u8, ctxt); + if (mode != X86EMUL_MODE_PROT64 && (vex_2nd & 0xc0) != 0xc0) { + opcode = opcode_table[ctxt->b]; + ctxt->modrm = vex_2nd; + /* the Mod/RM byte has been fetched already! */ + goto done_modrm; + } + + vex_prefix = true; + rc = x86_decode_avx(ctxt, ctxt->b, vex_2nd, &opcode); + if (rc != X86EMUL_CONTINUE) + goto done; + } else if (ctxt->b == 0x0f) { + /* Two- or three-byte opcode */ ctxt->opcode_len = 2; ctxt->b = insn_fetch(u8, ctxt); opcode = twobyte_table[ctxt->b]; @@ -4889,18 +4987,16 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int ctxt->b = insn_fetch(u8, ctxt); opcode = opcode_map_0f_38[ctxt->b]; } + } else { + /* Opcode byte(s). */ + opcode = opcode_table[ctxt->b]; } - ctxt->d = opcode.flags; - if (ctxt->d & ModRM) + if (opcode.flags & ModRM) ctxt->modrm = insn_fetch(u8, ctxt); - /* vex-prefix instructions are not implemented */ - if (ctxt->opcode_len == 1 && (ctxt->b == 0xc5 || ctxt->b == 0xc4) && - (mode == X86EMUL_MODE_PROT64 || (ctxt->modrm & 0xc0) == 0xc0)) { - ctxt->d = NotImpl; - } - +done_modrm: + ctxt->d = opcode.flags; while (ctxt->d & GroupMask) { switch (ctxt->d & GroupMask) { case Group: @@ -4919,9 +5015,9 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int opcode = opcode.u.group[goffset]; break; case Prefix: - if (ctxt->rep_prefix && op_prefix) + if (ctxt->rep_prefix && ctxt->op_prefix) return EMULATION_FAILED; - simd_prefix = op_prefix ? 0x66 : ctxt->rep_prefix; + simd_prefix = ctxt->op_prefix ? 0x66 : ctxt->rep_prefix; switch (simd_prefix) { case 0x00: opcode = opcode.u.gprefix->pfx_no; break; case 0x66: opcode = opcode.u.gprefix->pfx_66; break; @@ -4966,6 +5062,19 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int if (ctxt->d == 0) return EMULATION_FAILED; + if (unlikely(vex_prefix)) { + /* + * Only specifically marked instructions support VEX. Since many + * instructions support it but are not annotated, return not implemented + * rather than #UD. + */ + if (!(ctxt->d & Avx)) + return EMULATION_FAILED; + + if (!(ctxt->d & AlignMask)) + ctxt->d |= Unaligned; + } + ctxt->execute = opcode.u.execute; /* @@ -5036,8 +5145,10 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int if ((ctxt->d & No16) && ctxt->op_bytes == 2) ctxt->op_bytes = 4; - if (ctxt->d & Sse) - ctxt->op_bytes = 16; + if (vex_prefix) + ; + else if (ctxt->d & Sse) + ctxt->op_bytes = 16, ctxt->d &= ~Avx; else if (ctxt->d & Mmx) ctxt->op_bytes = 8; } @@ -5137,8 +5248,10 @@ void init_decode_cache(struct x86_emulate_ctxt *ctxt) { /* Clear fields that are set conditionally but read without a guard. */ ctxt->rip_relative = false; - ctxt->rex_prefix = 0; + ctxt->rex_prefix = REX_NONE; + ctxt->rex_bits = 0; ctxt->lock_prefix = 0; + ctxt->op_prefix = false; ctxt->rep_prefix = 0; ctxt->regs_valid = 0; ctxt->regs_dirty = 0; @@ -5168,20 +5281,34 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, bool check_intercepts) } if (unlikely(ctxt->d & - (No64|Undefined|Sse|Mmx|Intercept|CheckPerm|Priv|Prot|String))) { + (No64|Undefined|Avx|Sse|Mmx|Intercept|CheckPerm|Priv|Prot|String))) { if ((ctxt->mode == X86EMUL_MODE_PROT64 && (ctxt->d & No64)) || (ctxt->d & Undefined)) { rc = emulate_ud(ctxt); goto done; } - if (((ctxt->d & (Sse|Mmx)) && ((ops->get_cr(ctxt, 0) & X86_CR0_EM))) - || ((ctxt->d & Sse) && !(ops->get_cr(ctxt, 4) & X86_CR4_OSFXSR))) { + if ((ctxt->d & (Avx|Sse|Mmx)) && ((ops->get_cr(ctxt, 0) & X86_CR0_EM))) { rc = emulate_ud(ctxt); goto done; } - if ((ctxt->d & (Sse|Mmx)) && (ops->get_cr(ctxt, 0) & X86_CR0_TS)) { + if (ctxt->d & Avx) { + u64 xcr = 0; + if (!(ops->get_cr(ctxt, 4) & X86_CR4_OSXSAVE) + || ops->get_xcr(ctxt, 0, &xcr) + || !(xcr & XFEATURE_MASK_YMM)) { + rc = emulate_ud(ctxt); + goto done; + } + } else if (ctxt->d & Sse) { + if (!(ops->get_cr(ctxt, 4) & X86_CR4_OSFXSR)) { + rc = emulate_ud(ctxt); + goto done; + } + } + + if ((ctxt->d & (Avx|Sse|Mmx)) && (ops->get_cr(ctxt, 0) & X86_CR0_TS)) { rc = emulate_nm(ctxt); goto done; } diff --git a/arch/x86/kvm/fpu.h b/arch/x86/kvm/fpu.h index 3ba12888bf66a..f898781b6a068 100644 --- a/arch/x86/kvm/fpu.h +++ b/arch/x86/kvm/fpu.h @@ -15,6 +15,58 @@ typedef u32 __attribute__((vector_size(16))) sse128_t; #define sse128_l3(x) ({ __sse128_u t; t.vec = x; t.as_u32[3]; }) #define sse128(lo, hi) ({ __sse128_u t; t.as_u64[0] = lo; t.as_u64[1] = hi; t.vec; }) +typedef u32 __attribute__((vector_size(32))) avx256_t; + +static inline void _kvm_read_avx_reg(int reg, avx256_t *data) +{ + switch (reg) { + case 0: asm("vmovdqa %%ymm0, %0" : "=m"(*data)); break; + case 1: asm("vmovdqa %%ymm1, %0" : "=m"(*data)); break; + case 2: asm("vmovdqa %%ymm2, %0" : "=m"(*data)); break; + case 3: asm("vmovdqa %%ymm3, %0" : "=m"(*data)); break; + case 4: asm("vmovdqa %%ymm4, %0" : "=m"(*data)); break; + case 5: asm("vmovdqa %%ymm5, %0" : "=m"(*data)); break; + case 6: asm("vmovdqa %%ymm6, %0" : "=m"(*data)); break; + case 7: asm("vmovdqa %%ymm7, %0" : "=m"(*data)); break; +#ifdef CONFIG_X86_64 + case 8: asm("vmovdqa %%ymm8, %0" : "=m"(*data)); break; + case 9: asm("vmovdqa %%ymm9, %0" : "=m"(*data)); break; + case 10: asm("vmovdqa %%ymm10, %0" : "=m"(*data)); break; + case 11: asm("vmovdqa %%ymm11, %0" : "=m"(*data)); break; + case 12: asm("vmovdqa %%ymm12, %0" : "=m"(*data)); break; + case 13: asm("vmovdqa %%ymm13, %0" : "=m"(*data)); break; + case 14: asm("vmovdqa %%ymm14, %0" : "=m"(*data)); break; + case 15: asm("vmovdqa %%ymm15, %0" : "=m"(*data)); break; +#endif + default: BUG(); + } +} + +static inline void _kvm_write_avx_reg(int reg, const avx256_t *data) +{ + switch (reg) { + case 0: asm("vmovdqa %0, %%ymm0" : : "m"(*data)); break; + case 1: asm("vmovdqa %0, %%ymm1" : : "m"(*data)); break; + case 2: asm("vmovdqa %0, %%ymm2" : : "m"(*data)); break; + case 3: asm("vmovdqa %0, %%ymm3" : : "m"(*data)); break; + case 4: asm("vmovdqa %0, %%ymm4" : : "m"(*data)); break; + case 5: asm("vmovdqa %0, %%ymm5" : : "m"(*data)); break; + case 6: asm("vmovdqa %0, %%ymm6" : : "m"(*data)); break; + case 7: asm("vmovdqa %0, %%ymm7" : : "m"(*data)); break; +#ifdef CONFIG_X86_64 + case 8: asm("vmovdqa %0, %%ymm8" : : "m"(*data)); break; + case 9: asm("vmovdqa %0, %%ymm9" : : "m"(*data)); break; + case 10: asm("vmovdqa %0, %%ymm10" : : "m"(*data)); break; + case 11: asm("vmovdqa %0, %%ymm11" : : "m"(*data)); break; + case 12: asm("vmovdqa %0, %%ymm12" : : "m"(*data)); break; + case 13: asm("vmovdqa %0, %%ymm13" : : "m"(*data)); break; + case 14: asm("vmovdqa %0, %%ymm14" : : "m"(*data)); break; + case 15: asm("vmovdqa %0, %%ymm15" : : "m"(*data)); break; +#endif + default: BUG(); + } +} + static inline void _kvm_read_sse_reg(int reg, sse128_t *data) { switch (reg) { @@ -109,6 +161,20 @@ static inline void kvm_fpu_put(void) fpregs_unlock(); } +static inline void kvm_read_avx_reg(int reg, avx256_t *data) +{ + kvm_fpu_get(); + _kvm_read_avx_reg(reg, data); + kvm_fpu_put(); +} + +static inline void kvm_write_avx_reg(int reg, const avx256_t *data) +{ + kvm_fpu_get(); + _kvm_write_avx_reg(reg, data); + kvm_fpu_put(); +} + static inline void kvm_read_sse_reg(int reg, sse128_t *data) { kvm_fpu_get(); diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 38595ecb990d4..de92292eb1f58 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1568,7 +1568,7 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host) * only, there can be valuable data in the rest which needs * to be preserved e.g. on migration. */ - if (__put_user(0, (u32 __user *)addr)) + if (put_user(0, (u32 __user *)addr)) return 1; hv_vcpu->hv_vapic = data; kvm_vcpu_mark_page_dirty(vcpu, gfn); diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index 7b5ddb787a251..fb3dab4b5a53e 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -237,6 +237,7 @@ struct x86_emulate_ops { bool (*is_smm)(struct x86_emulate_ctxt *ctxt); int (*leave_smm)(struct x86_emulate_ctxt *ctxt); void (*triple_fault)(struct x86_emulate_ctxt *ctxt); + int (*get_xcr)(struct x86_emulate_ctxt *ctxt, u32 index, u64 *xcr); int (*set_xcr)(struct x86_emulate_ctxt *ctxt, u32 index, u64 xcr); gva_t (*get_untagged_addr)(struct x86_emulate_ctxt *ctxt, gva_t addr, @@ -248,7 +249,7 @@ struct x86_emulate_ops { /* Type, address-of, and value of an instruction's operand. */ struct operand { - enum { OP_REG, OP_MEM, OP_MEM_STR, OP_IMM, OP_XMM, OP_MM, OP_NONE } type; + enum { OP_REG, OP_MEM, OP_MEM_STR, OP_IMM, OP_XMM, OP_YMM, OP_MM, OP_NONE } type; unsigned int bytes; unsigned int count; union { @@ -267,11 +268,12 @@ struct operand { union { unsigned long val; u64 val64; - char valptr[sizeof(sse128_t)]; + char valptr[sizeof(avx256_t)]; sse128_t vec_val; + avx256_t vec_val2; u64 mm_val; void *data; - }; + } __aligned(32); }; #define X86_MAX_INSTRUCTION_LENGTH 15 @@ -317,6 +319,14 @@ typedef void (*fastop_t)(struct fastop *); #define NR_EMULATOR_GPRS 8 #endif +/* + * Distinguish between no prefix, REX, or in the future REX2. + */ +enum rex_type { + REX_NONE, + REX_PREFIX, +}; + struct x86_emulate_ctxt { void *vcpu; const struct x86_emulate_ops *ops; @@ -348,6 +358,7 @@ struct x86_emulate_ctxt { u8 opcode_len; u8 b; u8 intercept; + bool op_prefix; u8 op_bytes; u8 ad_bytes; union { @@ -357,7 +368,8 @@ struct x86_emulate_ctxt { int (*check_perm)(struct x86_emulate_ctxt *ctxt); bool rip_relative; - u8 rex_prefix; + enum rex_type rex_prefix; + u8 rex_bits; u8 lock_prefix; u8 rep_prefix; /* bitmaps of registers in _regs[] that can be read */ diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 0ae7f913d7826..1597dd0b0cc66 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2126,23 +2126,41 @@ static bool set_target_expiration(struct kvm_lapic *apic, u32 count_reg) static void advance_periodic_target_expiration(struct kvm_lapic *apic) { + struct kvm_timer *ktimer = &apic->lapic_timer; ktime_t now = ktime_get(); u64 tscl = rdtsc(); ktime_t delta; /* - * Synchronize both deadlines to the same time source or - * differences in the periods (caused by differences in the - * underlying clocks or numerical approximation errors) will - * cause the two to drift apart over time as the errors - * accumulate. + * Use kernel time as the time source for both the hrtimer deadline and + * TSC-based deadline so that they stay synchronized. Computing each + * deadline independently will cause the two deadlines to drift apart + * over time as differences in the periods accumulate, e.g. due to + * differences in the underlying clocks or numerical approximation errors. */ - apic->lapic_timer.target_expiration = - ktime_add_ns(apic->lapic_timer.target_expiration, - apic->lapic_timer.period); - delta = ktime_sub(apic->lapic_timer.target_expiration, now); - apic->lapic_timer.tscdeadline = kvm_read_l1_tsc(apic->vcpu, tscl) + - nsec_to_cycles(apic->vcpu, delta); + ktimer->target_expiration = ktime_add_ns(ktimer->target_expiration, + ktimer->period); + + /* + * If the new expiration is in the past, e.g. because userspace stopped + * running the VM for an extended duration, then force the expiration + * to "now" and don't try to play catch-up with the missed events. KVM + * will only deliver a single interrupt regardless of how many events + * are pending, i.e. restarting the timer with an expiration in the + * past will do nothing more than waste host cycles, and can even lead + * to a hard lockup in extreme cases. + */ + if (ktime_before(ktimer->target_expiration, now)) + ktimer->target_expiration = now; + + /* + * Note, ensuring the expiration isn't in the past also prevents delta + * from going negative, which could cause the TSC deadline to become + * excessively large due to it an unsigned value. + */ + delta = ktime_sub(ktimer->target_expiration, now); + ktimer->tscdeadline = kvm_read_l1_tsc(apic->vcpu, tscl) + + nsec_to_cycles(apic->vcpu, delta); } static void start_sw_period(struct kvm_lapic *apic) @@ -2970,9 +2988,9 @@ static enum hrtimer_restart apic_timer_fn(struct hrtimer *data) apic_timer_expired(apic, true); - if (lapic_is_periodic(apic)) { + if (lapic_is_periodic(apic) && !WARN_ON_ONCE(!apic->lapic_timer.period)) { advance_periodic_target_expiration(apic); - hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); + hrtimer_set_expires(&ktimer->timer, ktimer->target_expiration); return HRTIMER_RESTART; } else return HRTIMER_NORESTART; diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index f63074048ec61..830f46145692a 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -235,8 +235,6 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, return -(u32)fault & errcode; } -bool kvm_mmu_may_ignore_guest_pat(struct kvm *kvm); - int kvm_mmu_post_init_vm(struct kvm *kvm); void kvm_mmu_pre_destroy_vm(struct kvm *kvm); @@ -257,8 +255,7 @@ extern bool tdp_mmu_enabled; #define tdp_mmu_enabled false #endif -bool kvm_tdp_mmu_gpa_is_mapped(struct kvm_vcpu *vcpu, u64 gpa); -int kvm_tdp_map_page(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code, u8 *level); +int kvm_tdp_mmu_map_private_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, kvm_pfn_t pfn); static inline bool kvm_memslots_have_rmaps(struct kvm *kvm) { diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 667d66cf76d5e..02c450686b4a8 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -4859,7 +4859,7 @@ int kvm_handle_page_fault(struct kvm_vcpu *vcpu, u64 error_code, */ BUILD_BUG_ON(lower_32_bits(PFERR_SYNTHETIC_MASK)); - vcpu->arch.l1tf_flush_l1d = true; + kvm_request_l1tf_flush_l1d(); if (!flags) { trace_kvm_page_fault(vcpu, fault_address, error_code); @@ -4924,7 +4924,8 @@ int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) return direct_page_fault(vcpu, fault); } -int kvm_tdp_map_page(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code, u8 *level) +static int kvm_tdp_page_prefault(struct kvm_vcpu *vcpu, gpa_t gpa, + u64 error_code, u8 *level) { int r; @@ -4966,7 +4967,6 @@ int kvm_tdp_map_page(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code, u8 *level return -EIO; } } -EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_tdp_map_page); long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, struct kvm_pre_fault_memory *range) @@ -5002,7 +5002,7 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, * Shadow paging uses GVA for kvm page fault, so restrict to * two-dimensional paging. */ - r = kvm_tdp_map_page(vcpu, range->gpa | direct_bits, error_code, &level); + r = kvm_tdp_page_prefault(vcpu, range->gpa | direct_bits, error_code, &level); if (r < 0) return r; @@ -5014,6 +5014,86 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, return min(range->size, end - range->gpa); } +#ifdef CONFIG_KVM_GUEST_MEMFD +static void kvm_assert_gmem_invalidate_lock_held(struct kvm_memory_slot *slot) +{ +#ifdef CONFIG_PROVE_LOCKING + if (WARN_ON_ONCE(!kvm_slot_has_gmem(slot)) || + WARN_ON_ONCE(!slot->gmem.file) || + WARN_ON_ONCE(!file_count(slot->gmem.file))) + return; + + lockdep_assert_held(&file_inode(slot->gmem.file)->i_mapping->invalidate_lock); +#endif +} + +int kvm_tdp_mmu_map_private_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, kvm_pfn_t pfn) +{ + struct kvm_page_fault fault = { + .addr = gfn_to_gpa(gfn), + .error_code = PFERR_GUEST_FINAL_MASK | PFERR_PRIVATE_ACCESS, + .prefetch = true, + .is_tdp = true, + .nx_huge_page_workaround_enabled = is_nx_huge_page_enabled(vcpu->kvm), + + .max_level = PG_LEVEL_4K, + .req_level = PG_LEVEL_4K, + .goal_level = PG_LEVEL_4K, + .is_private = true, + + .gfn = gfn, + .slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn), + .pfn = pfn, + .map_writable = true, + }; + struct kvm *kvm = vcpu->kvm; + int r; + + lockdep_assert_held(&kvm->slots_lock); + + /* + * Mapping a pre-determined private pfn is intended only for use when + * populating a guest_memfd instance. Assert that the slot is backed + * by guest_memfd and that the gmem instance's invalidate_lock is held. + */ + kvm_assert_gmem_invalidate_lock_held(fault.slot); + + if (KVM_BUG_ON(!tdp_mmu_enabled, kvm)) + return -EIO; + + if (kvm_gfn_is_write_tracked(kvm, fault.slot, fault.gfn)) + return -EPERM; + + r = kvm_mmu_reload(vcpu); + if (r) + return r; + + r = mmu_topup_memory_caches(vcpu, false); + if (r) + return r; + + do { + if (signal_pending(current)) + return -EINTR; + + if (kvm_test_request(KVM_REQ_VM_DEAD, vcpu)) + return -EIO; + + cond_resched(); + + guard(read_lock)(&kvm->mmu_lock); + + r = kvm_tdp_mmu_map(vcpu, &fault); + } while (r == RET_PF_RETRY); + + if (r != RET_PF_FIXED) + return -EIO; + + return 0; +} +EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_tdp_mmu_map_private_pfn); +#endif + static void nonpaging_init_context(struct kvm_mmu *context) { context->page_fault = nonpaging_page_fault; @@ -5997,7 +6077,6 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu) out: return r; } -EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_mmu_load); void kvm_mmu_unload(struct kvm_vcpu *vcpu) { @@ -6863,6 +6942,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) write_unlock(&kvm->mmu_lock); } +EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_zap_gfn_range); static bool slot_rmap_write_protect(struct kvm *kvm, struct kvm_rmap_head *rmap_head, @@ -7204,7 +7284,6 @@ static bool kvm_mmu_zap_collapsible_spte(struct kvm *kvm, return need_tlb_flush; } -EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_zap_gfn_range); static void kvm_rmap_zap_collapsible_sptes(struct kvm *kvm, const struct kvm_memory_slot *slot) @@ -7364,6 +7443,9 @@ void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen) { WARN_ON_ONCE(gen & KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS); + if (!enable_mmio_caching) + return; + gen &= MMIO_SPTE_GEN_MASK; /* diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h index ed5c01df21ba2..73cdcbccc89e8 100644 --- a/arch/x86/kvm/mmu/mmu_internal.h +++ b/arch/x86/kvm/mmu/mmu_internal.h @@ -39,16 +39,6 @@ #define INVALID_PAE_ROOT 0 #define IS_VALID_PAE_ROOT(x) (!!(x)) -static inline hpa_t kvm_mmu_get_dummy_root(void) -{ - return my_zero_pfn(0) << PAGE_SHIFT; -} - -static inline bool kvm_mmu_is_dummy_root(hpa_t shadow_page) -{ - return is_zero_pfn(shadow_page >> PAGE_SHIFT); -} - typedef u64 __rcu *tdp_ptep_t; struct kvm_mmu_page { diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index ed762bb4b007b..901cd2bd40b84 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -402,7 +402,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, goto error; ptep_user = (pt_element_t __user *)((void *)host_addr + offset); - if (unlikely(__get_user(pte, ptep_user))) + if (unlikely(get_user(pte, ptep_user))) goto error; walker->ptep_user[walker->level - 1] = ptep_user; diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c index 37647afde7d3a..85a0473809b0e 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -292,7 +292,7 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, mark_page_dirty_in_slot(vcpu->kvm, slot, gfn); } - if (static_branch_unlikely(&cpu_buf_vm_clear) && + if (cpu_feature_enabled(X86_FEATURE_CLEAR_CPU_BUF_VM_MMIO) && !kvm_vcpu_can_access_host_mmio(vcpu) && kvm_is_mmio_pfn(pfn, &is_host_mmio)) kvm_track_host_mmio_mapping(vcpu); diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 3133f066927e1..91ce29fd6f1b2 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -246,6 +246,16 @@ static inline int spte_index(u64 *sptep) */ extern u64 __read_mostly shadow_nonpresent_or_rsvd_lower_gfn_mask; +static inline hpa_t kvm_mmu_get_dummy_root(void) +{ + return my_zero_pfn(0) << PAGE_SHIFT; +} + +static inline bool kvm_mmu_is_dummy_root(hpa_t shadow_page) +{ + return is_zero_pfn(shadow_page >> PAGE_SHIFT); +} + static inline struct kvm_mmu_page *to_shadow_page(hpa_t shadow_page) { struct page *page = pfn_to_page((shadow_page) >> PAGE_SHIFT); diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index c5734ca5c17dd..9c26038f6b77e 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -362,9 +362,6 @@ static void tdp_mmu_unlink_sp(struct kvm *kvm, struct kvm_mmu_page *sp) static void remove_external_spte(struct kvm *kvm, gfn_t gfn, u64 old_spte, int level) { - kvm_pfn_t old_pfn = spte_to_pfn(old_spte); - int ret; - /* * External (TDX) SPTEs are limited to PG_LEVEL_4K, and external * PTs are removed in a special order, involving free_external_spt(). @@ -377,9 +374,8 @@ static void remove_external_spte(struct kvm *kvm, gfn_t gfn, u64 old_spte, /* Zapping leaf spte is allowed only when write lock is held. */ lockdep_assert_held_write(&kvm->mmu_lock); - /* Because write lock is held, operation should success. */ - ret = kvm_x86_call(remove_external_spte)(kvm, gfn, level, old_pfn); - KVM_BUG_ON(ret, kvm); + + kvm_x86_call(remove_external_spte)(kvm, gfn, level, old_spte); } /** @@ -519,7 +515,6 @@ static int __must_check set_external_spte_present(struct kvm *kvm, tdp_ptep_t sp bool was_present = is_shadow_present_pte(old_spte); bool is_present = is_shadow_present_pte(new_spte); bool is_leaf = is_present && is_last_spte(new_spte, level); - kvm_pfn_t new_pfn = spte_to_pfn(new_spte); int ret = 0; KVM_BUG_ON(was_present, kvm); @@ -538,7 +533,7 @@ static int __must_check set_external_spte_present(struct kvm *kvm, tdp_ptep_t sp * external page table, or leaf. */ if (is_leaf) { - ret = kvm_x86_call(set_external_spte)(kvm, gfn, level, new_pfn); + ret = kvm_x86_call(set_external_spte)(kvm, gfn, level, new_spte); } else { void *external_spt = get_external_spt(gfn, new_spte, level); @@ -1273,6 +1268,8 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) struct kvm_mmu_page *sp; int ret = RET_PF_RETRY; + KVM_MMU_WARN_ON(!root || root->role.invalid); + kvm_mmu_hugepage_adjust(vcpu, fault); trace_kvm_mmu_spte_requested(fault); @@ -1939,13 +1936,16 @@ bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, * * Must be called between kvm_tdp_mmu_walk_lockless_{begin,end}. */ -static int __kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, - struct kvm_mmu_page *root) +int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, + int *root_level) { + struct kvm_mmu_page *root = root_to_sp(vcpu->arch.mmu->root.hpa); struct tdp_iter iter; gfn_t gfn = addr >> PAGE_SHIFT; int leaf = -1; + *root_level = vcpu->arch.mmu->root_role.level; + for_each_tdp_pte(iter, vcpu->kvm, root, gfn, gfn + 1) { leaf = iter.level; sptes[leaf] = iter.old_spte; @@ -1954,36 +1954,6 @@ static int __kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, return leaf; } -int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, - int *root_level) -{ - struct kvm_mmu_page *root = root_to_sp(vcpu->arch.mmu->root.hpa); - *root_level = vcpu->arch.mmu->root_role.level; - - return __kvm_tdp_mmu_get_walk(vcpu, addr, sptes, root); -} - -bool kvm_tdp_mmu_gpa_is_mapped(struct kvm_vcpu *vcpu, u64 gpa) -{ - struct kvm *kvm = vcpu->kvm; - bool is_direct = kvm_is_addr_direct(kvm, gpa); - hpa_t root = is_direct ? vcpu->arch.mmu->root.hpa : - vcpu->arch.mmu->mirror_root_hpa; - u64 sptes[PT64_ROOT_MAX_LEVEL + 1], spte; - int leaf; - - lockdep_assert_held(&kvm->mmu_lock); - rcu_read_lock(); - leaf = __kvm_tdp_mmu_get_walk(vcpu, gpa, sptes, root_to_sp(root)); - rcu_read_unlock(); - if (leaf < 0) - return false; - - spte = sptes[leaf]; - return is_shadow_present_pte(spte) && is_last_spte(spte, leaf); -} -EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_tdp_mmu_gpa_is_mapped); - /* * Returns the last level spte pointer of the shadow page walk for the given * gpa, and sets *spte to the spte value. This spte may be non-preset. If no diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c index fef00546c8856..6b77b2033208f 100644 --- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -106,7 +106,7 @@ static u32 next_vm_id = 0; static bool next_vm_id_wrapped = 0; static DEFINE_SPINLOCK(svm_vm_data_hash_lock); static bool x2avic_enabled; - +static u32 x2avic_max_physical_id; static void avic_set_x2apic_msr_interception(struct vcpu_svm *svm, bool intercept) @@ -158,12 +158,40 @@ static void avic_set_x2apic_msr_interception(struct vcpu_svm *svm, svm->x2avic_msrs_intercepted = intercept; } +static u32 __avic_get_max_physical_id(struct kvm *kvm, struct kvm_vcpu *vcpu) +{ + u32 arch_max; + + /* + * Return the largest size (x2APIC) when querying without a vCPU, e.g. + * to allocate the per-VM table.. + */ + if (x2avic_enabled && (!vcpu || apic_x2apic_mode(vcpu->arch.apic))) + arch_max = x2avic_max_physical_id; + else + arch_max = AVIC_MAX_PHYSICAL_ID; + + /* + * Despite its name, KVM_CAP_MAX_VCPU_ID represents the maximum APIC ID + * plus one, so the max possible APIC ID is one less than that. + */ + return min(kvm->arch.max_vcpu_ids - 1, arch_max); +} + +static u32 avic_get_max_physical_id(struct kvm_vcpu *vcpu) +{ + return __avic_get_max_physical_id(vcpu->kvm, vcpu); +} + static void avic_activate_vmcb(struct vcpu_svm *svm) { struct vmcb *vmcb = svm->vmcb01.ptr; + struct kvm_vcpu *vcpu = &svm->vcpu; vmcb->control.int_ctl &= ~(AVIC_ENABLE_MASK | X2APIC_MODE_MASK); + vmcb->control.avic_physical_id &= ~AVIC_PHYSICAL_MAX_INDEX_MASK; + vmcb->control.avic_physical_id |= avic_get_max_physical_id(vcpu); vmcb->control.int_ctl |= AVIC_ENABLE_MASK; @@ -176,7 +204,7 @@ static void avic_activate_vmcb(struct vcpu_svm *svm) */ if (x2avic_enabled && apic_x2apic_mode(svm->vcpu.arch.apic)) { vmcb->control.int_ctl |= X2APIC_MODE_MASK; - vmcb->control.avic_physical_id |= X2AVIC_MAX_PHYSICAL_ID; + /* Disabling MSR intercept for x2APIC registers */ avic_set_x2apic_msr_interception(svm, false); } else { @@ -186,8 +214,6 @@ static void avic_activate_vmcb(struct vcpu_svm *svm) */ kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, &svm->vcpu); - /* For xAVIC and hybrid-xAVIC modes */ - vmcb->control.avic_physical_id |= AVIC_MAX_PHYSICAL_ID; /* Enabling MSR intercept for x2APIC registers */ avic_set_x2apic_msr_interception(svm, true); } @@ -247,6 +273,30 @@ static int avic_ga_log_notifier(u32 ga_tag) return 0; } +static int avic_get_physical_id_table_order(struct kvm *kvm) +{ + /* Provision for the maximum physical ID supported in x2avic mode */ + return get_order((__avic_get_max_physical_id(kvm, NULL) + 1) * sizeof(u64)); +} + +int avic_alloc_physical_id_table(struct kvm *kvm) +{ + struct kvm_svm *kvm_svm = to_kvm_svm(kvm); + + if (!irqchip_in_kernel(kvm) || !enable_apicv) + return 0; + + if (kvm_svm->avic_physical_id_table) + return 0; + + kvm_svm->avic_physical_id_table = (void *)__get_free_pages(GFP_KERNEL_ACCOUNT | __GFP_ZERO, + avic_get_physical_id_table_order(kvm)); + if (!kvm_svm->avic_physical_id_table) + return -ENOMEM; + + return 0; +} + void avic_vm_destroy(struct kvm *kvm) { unsigned long flags; @@ -256,7 +306,8 @@ void avic_vm_destroy(struct kvm *kvm) return; free_page((unsigned long)kvm_svm->avic_logical_id_table); - free_page((unsigned long)kvm_svm->avic_physical_id_table); + free_pages((unsigned long)kvm_svm->avic_physical_id_table, + avic_get_physical_id_table_order(kvm)); spin_lock_irqsave(&svm_vm_data_hash_lock, flags); hash_del(&kvm_svm->hnode); @@ -274,10 +325,6 @@ int avic_vm_init(struct kvm *kvm) if (!enable_apicv) return 0; - kvm_svm->avic_physical_id_table = (void *)get_zeroed_page(GFP_KERNEL_ACCOUNT); - if (!kvm_svm->avic_physical_id_table) - goto free_avic; - kvm_svm->avic_logical_id_table = (void *)get_zeroed_page(GFP_KERNEL_ACCOUNT); if (!kvm_svm->avic_logical_id_table) goto free_avic; @@ -342,7 +389,7 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu) * fully initialized AVIC. */ if ((!x2avic_enabled && id > AVIC_MAX_PHYSICAL_ID) || - (id > X2AVIC_MAX_PHYSICAL_ID)) { + (id > x2avic_max_physical_id)) { kvm_set_apicv_inhibit(vcpu->kvm, APICV_INHIBIT_REASON_PHYSICAL_ID_TOO_BIG); vcpu->arch.apic->apicv_active = false; return 0; @@ -562,7 +609,7 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu) u32 icrh = svm->vmcb->control.exit_info_1 >> 32; u32 icrl = svm->vmcb->control.exit_info_1; u32 id = svm->vmcb->control.exit_info_2 >> 32; - u32 index = svm->vmcb->control.exit_info_2 & 0x1FF; + u32 index = svm->vmcb->control.exit_info_2 & AVIC_PHYSICAL_MAX_INDEX_MASK; struct kvm_lapic *apic = vcpu->arch.apic; trace_kvm_avic_incomplete_ipi(vcpu->vcpu_id, icrh, icrl, id, index); @@ -962,7 +1009,8 @@ static void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu, if (WARN_ON(h_physical_id & ~AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK)) return; - if (WARN_ON_ONCE(vcpu->vcpu_id * sizeof(entry) >= PAGE_SIZE)) + if (WARN_ON_ONCE(vcpu->vcpu_id * sizeof(entry) >= + PAGE_SIZE << avic_get_physical_id_table_order(vcpu->kvm))) return; /* @@ -1024,7 +1072,8 @@ static void __avic_vcpu_put(struct kvm_vcpu *vcpu, enum avic_vcpu_action action) lockdep_assert_preemption_disabled(); - if (WARN_ON_ONCE(vcpu->vcpu_id * sizeof(entry) >= PAGE_SIZE)) + if (WARN_ON_ONCE(vcpu->vcpu_id * sizeof(entry) >= + PAGE_SIZE << avic_get_physical_id_table_order(vcpu->kvm))) return; /* @@ -1226,10 +1275,15 @@ bool __init avic_hardware_setup(void) /* AVIC is a prerequisite for x2AVIC. */ x2avic_enabled = boot_cpu_has(X86_FEATURE_X2AVIC); - if (x2avic_enabled) - pr_info("x2AVIC enabled\n"); - else + if (x2avic_enabled) { + if (cpu_feature_enabled(X86_FEATURE_X2AVIC_EXT)) + x2avic_max_physical_id = X2AVIC_4K_MAX_PHYSICAL_ID; + else + x2avic_max_physical_id = X2AVIC_MAX_PHYSICAL_ID; + pr_info("x2AVIC enabled (max %u vCPUs)\n", x2avic_max_physical_id + 1); + } else { svm_x86_ops.allow_apicv_in_x2apic_without_x2apic_virtualization = true; + } /* * Disable IPI virtualization for AMD Family 17h CPUs (Zen1 and Zen2) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index da6e80b3ac353..ba0f11c68372b 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -613,6 +613,7 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm *svm, struct vmcb *vmcb12 struct kvm_vcpu *vcpu = &svm->vcpu; nested_vmcb02_compute_g_pat(svm); + vmcb_mark_dirty(vmcb02, VMCB_NPT); /* Load the nested guest state */ if (svm->nested.vmcb12_gpa != svm->nested.last_vmcb12_gpa) { @@ -751,6 +752,7 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, vmcb02->control.nested_ctl = vmcb01->control.nested_ctl; vmcb02->control.iopm_base_pa = vmcb01->control.iopm_base_pa; vmcb02->control.msrpm_base_pa = vmcb01->control.msrpm_base_pa; + vmcb_mark_dirty(vmcb02, VMCB_PERM_MAP); /* * Stash vmcb02's counter if the guest hasn't moved past the guilty @@ -983,7 +985,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu) if (!nested_vmcb_check_save(vcpu) || !nested_vmcb_check_controls(vcpu)) { vmcb12->control.exit_code = SVM_EXIT_ERR; - vmcb12->control.exit_code_hi = 0; + vmcb12->control.exit_code_hi = -1u; vmcb12->control.exit_info_1 = 0; vmcb12->control.exit_info_2 = 0; goto out; @@ -1016,7 +1018,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu) svm->soft_int_injected = false; svm->vmcb->control.exit_code = SVM_EXIT_ERR; - svm->vmcb->control.exit_code_hi = 0; + svm->vmcb->control.exit_code_hi = -1u; svm->vmcb->control.exit_info_1 = 0; svm->vmcb->control.exit_info_2 = 0; @@ -1430,16 +1432,6 @@ static int nested_svm_intercept(struct vcpu_svm *svm) case SVM_EXIT_IOIO: vmexit = nested_svm_intercept_ioio(svm); break; - case SVM_EXIT_READ_CR0 ... SVM_EXIT_WRITE_CR8: { - if (vmcb12_is_intercept(&svm->nested.ctl, exit_code)) - vmexit = NESTED_EXIT_DONE; - break; - } - case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: { - if (vmcb12_is_intercept(&svm->nested.ctl, exit_code)) - vmexit = NESTED_EXIT_DONE; - break; - } case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: { /* * Host-intercepted exceptions have been checked already in diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 0835c664fbfdb..f59c65abe3cfa 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -65,20 +65,24 @@ module_param_named(ciphertext_hiding_asids, nr_ciphertext_hiding_asids, uint, 04 #define AP_RESET_HOLD_NAE_EVENT 1 #define AP_RESET_HOLD_MSR_PROTO 2 -/* As defined by SEV-SNP Firmware ABI, under "Guest Policy". */ -#define SNP_POLICY_MASK_API_MINOR GENMASK_ULL(7, 0) -#define SNP_POLICY_MASK_API_MAJOR GENMASK_ULL(15, 8) -#define SNP_POLICY_MASK_SMT BIT_ULL(16) -#define SNP_POLICY_MASK_RSVD_MBO BIT_ULL(17) -#define SNP_POLICY_MASK_DEBUG BIT_ULL(19) -#define SNP_POLICY_MASK_SINGLE_SOCKET BIT_ULL(20) - -#define SNP_POLICY_MASK_VALID (SNP_POLICY_MASK_API_MINOR | \ - SNP_POLICY_MASK_API_MAJOR | \ - SNP_POLICY_MASK_SMT | \ - SNP_POLICY_MASK_RSVD_MBO | \ - SNP_POLICY_MASK_DEBUG | \ - SNP_POLICY_MASK_SINGLE_SOCKET) +/* + * SEV-SNP policy bits that can be supported by KVM. These include policy bits + * that have implementation support within KVM or policy bits that do not + * require implementation support within KVM to enforce the policy. + */ +#define KVM_SNP_POLICY_MASK_VALID (SNP_POLICY_MASK_API_MINOR | \ + SNP_POLICY_MASK_API_MAJOR | \ + SNP_POLICY_MASK_SMT | \ + SNP_POLICY_MASK_RSVD_MBO | \ + SNP_POLICY_MASK_DEBUG | \ + SNP_POLICY_MASK_SINGLE_SOCKET | \ + SNP_POLICY_MASK_CXL_ALLOW | \ + SNP_POLICY_MASK_MEM_AES_256_XTS | \ + SNP_POLICY_MASK_RAPL_DIS | \ + SNP_POLICY_MASK_CIPHERTEXT_HIDING_DRAM | \ + SNP_POLICY_MASK_PAGE_SWAP_DISABLE) + +static u64 snp_supported_policy_bits __ro_after_init; #define INITIAL_VMSA_GPA 0xFFFFFFFFF000 @@ -2143,6 +2147,10 @@ int sev_dev_get_attr(u32 group, u64 attr, u64 *val) *val = sev_supported_vmsa_features; return 0; + case KVM_X86_SNP_POLICY_BITS: + *val = snp_supported_policy_bits; + return 0; + default: return -ENXIO; } @@ -2207,7 +2215,7 @@ static int snp_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) if (params.flags) return -EINVAL; - if (params.policy & ~SNP_POLICY_MASK_VALID) + if (params.policy & ~snp_supported_policy_bits) return -EINVAL; /* Check for policy bits that must be set */ @@ -3100,8 +3108,11 @@ void __init sev_hardware_setup(void) else if (sev_snp_supported) sev_snp_supported = is_sev_snp_initialized(); - if (sev_snp_supported) + if (sev_snp_supported) { + snp_supported_policy_bits = sev_get_snp_policy_bits() & + KVM_SNP_POLICY_MASK_VALID; nr_ciphertext_hiding_asids = init_args.max_snp_asid; + } /* * If ciphertext hiding is enabled, the joint SEV-ES/SEV-SNP @@ -5085,10 +5096,10 @@ struct vmcb_save_area *sev_decrypt_vmsa(struct kvm_vcpu *vcpu) /* Check if the SEV policy allows debugging */ if (sev_snp_guest(vcpu->kvm)) { - if (!(sev->policy & SNP_POLICY_DEBUG)) + if (!(sev->policy & SNP_POLICY_MASK_DEBUG)) return NULL; } else { - if (sev->policy & SEV_POLICY_NODBG) + if (sev->policy & SEV_POLICY_MASK_NODBG) return NULL; } diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 9d29b2e7e855d..24d59ccfa40d9 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -272,6 +272,7 @@ static void svm_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) } static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, + int emul_type, bool commit_side_effects) { struct vcpu_svm *svm = to_svm(vcpu); @@ -293,7 +294,7 @@ static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, if (unlikely(!commit_side_effects)) old_rflags = svm->vmcb->save.rflags; - if (!kvm_emulate_instruction(vcpu, EMULTYPE_SKIP)) + if (!kvm_emulate_instruction(vcpu, emul_type)) return 0; if (unlikely(!commit_side_effects)) @@ -311,11 +312,13 @@ static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, static int svm_skip_emulated_instruction(struct kvm_vcpu *vcpu) { - return __svm_skip_emulated_instruction(vcpu, true); + return __svm_skip_emulated_instruction(vcpu, EMULTYPE_SKIP, true); } -static int svm_update_soft_interrupt_rip(struct kvm_vcpu *vcpu) +static int svm_update_soft_interrupt_rip(struct kvm_vcpu *vcpu, u8 vector) { + const int emul_type = EMULTYPE_SKIP | EMULTYPE_SKIP_SOFT_INT | + EMULTYPE_SET_SOFT_INT_VECTOR(vector); unsigned long rip, old_rip = kvm_rip_read(vcpu); struct vcpu_svm *svm = to_svm(vcpu); @@ -331,7 +334,7 @@ static int svm_update_soft_interrupt_rip(struct kvm_vcpu *vcpu) * in use, the skip must not commit any side effects such as clearing * the interrupt shadow or RFLAGS.RF. */ - if (!__svm_skip_emulated_instruction(vcpu, !nrips)) + if (!__svm_skip_emulated_instruction(vcpu, emul_type, !nrips)) return -EIO; rip = kvm_rip_read(vcpu); @@ -367,7 +370,7 @@ static void svm_inject_exception(struct kvm_vcpu *vcpu) kvm_deliver_exception_payload(vcpu, ex); if (kvm_exception_is_soft(ex->vector) && - svm_update_soft_interrupt_rip(vcpu)) + svm_update_soft_interrupt_rip(vcpu, ex->vector)) return; svm->vmcb->control.event_inj = ex->vector @@ -1198,6 +1201,11 @@ void svm_switch_vmcb(struct vcpu_svm *svm, struct kvm_vmcb_info *target_vmcb) svm->vmcb = target_vmcb->ptr; } +static int svm_vcpu_precreate(struct kvm *kvm) +{ + return avic_alloc_physical_id_table(kvm); +} + static int svm_vcpu_create(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm; @@ -2435,6 +2443,7 @@ static bool check_selective_cr0_intercepted(struct kvm_vcpu *vcpu, if (cr0 ^ val) { svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE; + svm->vmcb->control.exit_code_hi = 0; ret = (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE); } @@ -3442,13 +3451,8 @@ static bool svm_check_exit_valid(u64 exit_code) static int svm_handle_invalid_exit(struct kvm_vcpu *vcpu, u64 exit_code) { - vcpu_unimpl(vcpu, "svm: unexpected exit reason 0x%llx\n", exit_code); dump_vmcb(vcpu); - vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; - vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON; - vcpu->run->internal.ndata = 2; - vcpu->run->internal.data[0] = exit_code; - vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu; + kvm_prepare_unexpected_reason_exit(vcpu, exit_code); return 0; } @@ -3633,11 +3637,12 @@ static bool svm_set_vnmi_pending(struct kvm_vcpu *vcpu) static void svm_inject_irq(struct kvm_vcpu *vcpu, bool reinjected) { + struct kvm_queued_interrupt *intr = &vcpu->arch.interrupt; struct vcpu_svm *svm = to_svm(vcpu); u32 type; - if (vcpu->arch.interrupt.soft) { - if (svm_update_soft_interrupt_rip(vcpu)) + if (intr->soft) { + if (svm_update_soft_interrupt_rip(vcpu, intr->nr)) return; type = SVM_EVTINJ_TYPE_SOFT; @@ -3645,12 +3650,10 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu, bool reinjected) type = SVM_EVTINJ_TYPE_INTR; } - trace_kvm_inj_virq(vcpu->arch.interrupt.nr, - vcpu->arch.interrupt.soft, reinjected); + trace_kvm_inj_virq(intr->nr, intr->soft, reinjected); ++vcpu->stat.irq_injections; - svm->vmcb->control.event_inj = vcpu->arch.interrupt.nr | - SVM_EVTINJ_VALID | type; + svm->vmcb->control.event_inj = intr->nr | SVM_EVTINJ_VALID | type; } void svm_complete_interrupt_delivery(struct kvm_vcpu *vcpu, int delivery_mode, @@ -4251,7 +4254,6 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) svm_set_dr6(vcpu, DR6_ACTIVE_LOW); clgi(); - kvm_load_guest_xsave_state(vcpu); /* * Hardware only context switches DEBUGCTL if LBR virtualization is @@ -4294,7 +4296,6 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) vcpu->arch.host_debugctl != svm->vmcb->save.dbgctl) update_debugctlmsr(vcpu->arch.host_debugctl); - kvm_load_host_xsave_state(vcpu); stgi(); /* Any pending NMI will happen here */ @@ -4326,14 +4327,6 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) vcpu->arch.regs_avail &= ~SVM_REGS_LAZY_LOAD_SET; - /* - * We need to handle MC intercepts here before the vcpu has a chance to - * change the physical cpu - */ - if (unlikely(svm->vmcb->control.exit_code == - SVM_EXIT_EXCP_BASE + MC_VECTOR)) - svm_handle_mce(vcpu); - trace_kvm_exit(vcpu, KVM_ISA_SVM); svm_complete_interrupts(vcpu); @@ -4526,31 +4519,45 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, case SVM_EXIT_WRITE_CR0: { unsigned long cr0, val; - if (info->intercept == x86_intercept_cr_write) + /* + * Adjust the exit code accordingly if a CR other than CR0 is + * being written, and skip straight to the common handling as + * only CR0 has an additional selective intercept. + */ + if (info->intercept == x86_intercept_cr_write && info->modrm_reg) { icpt_info.exit_code += info->modrm_reg; - - if (icpt_info.exit_code != SVM_EXIT_WRITE_CR0 || - info->intercept == x86_intercept_clts) break; + } - if (!(vmcb12_is_intercept(&svm->nested.ctl, - INTERCEPT_SELECTIVE_CR0))) + /* + * Convert the exit_code to SVM_EXIT_CR0_SEL_WRITE if a + * selective CR0 intercept is triggered (the common logic will + * treat the selective intercept as being enabled). Note, the + * unconditional intercept has higher priority, i.e. this is + * only relevant if *only* the selective intercept is enabled. + */ + if (vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_CR0_WRITE) || + !(vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_SELECTIVE_CR0))) break; - cr0 = vcpu->arch.cr0 & ~SVM_CR0_SELECTIVE_MASK; - val = info->src_val & ~SVM_CR0_SELECTIVE_MASK; + /* CLTS never triggers INTERCEPT_SELECTIVE_CR0 */ + if (info->intercept == x86_intercept_clts) + break; + /* LMSW always triggers INTERCEPT_SELECTIVE_CR0 */ if (info->intercept == x86_intercept_lmsw) { - cr0 &= 0xfUL; - val &= 0xfUL; - /* lmsw can't clear PE - catch this here */ - if (cr0 & X86_CR0_PE) - val |= X86_CR0_PE; + icpt_info.exit_code = SVM_EXIT_CR0_SEL_WRITE; + break; } + /* + * MOV-to-CR0 only triggers INTERCEPT_SELECTIVE_CR0 if any bit + * other than SVM_CR0_SELECTIVE_MASK is changed. + */ + cr0 = vcpu->arch.cr0 & ~SVM_CR0_SELECTIVE_MASK; + val = info->src_val & ~SVM_CR0_SELECTIVE_MASK; if (cr0 ^ val) icpt_info.exit_code = SVM_EXIT_CR0_SEL_WRITE; - break; } case SVM_EXIT_READ_DR0: @@ -4611,6 +4618,7 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, if (static_cpu_has(X86_FEATURE_NRIPS)) vmcb->control.next_rip = info->next_rip; vmcb->control.exit_code = icpt_info.exit_code; + vmcb->control.exit_code_hi = 0; vmexit = nested_svm_exit_handled(svm); ret = (vmexit == NESTED_EXIT_DONE) ? X86EMUL_INTERCEPTED @@ -4622,8 +4630,16 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu) { - if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_INTR) + switch (to_svm(vcpu)->vmcb->control.exit_code) { + case SVM_EXIT_EXCP_BASE + MC_VECTOR: + svm_handle_mce(vcpu); + break; + case SVM_EXIT_INTR: vcpu->arch.at_instruction_boundary = true; + break; + default: + break; + } } static void svm_setup_mce(struct kvm_vcpu *vcpu) @@ -5012,6 +5028,7 @@ struct kvm_x86_ops svm_x86_ops __initdata = { .emergency_disable_virtualization_cpu = svm_emergency_disable_virtualization_cpu, .has_emulated_msr = svm_has_emulated_msr, + .vcpu_precreate = svm_vcpu_precreate, .vcpu_create = svm_vcpu_create, .vcpu_free = svm_vcpu_free, .vcpu_reset = svm_vcpu_reset, @@ -5316,7 +5333,9 @@ static __init int svm_hardware_setup(void) if (nested) { pr_info("Nested Virtualization enabled\n"); - kvm_enable_efer_bits(EFER_SVME | EFER_LMSLE); + kvm_enable_efer_bits(EFER_SVME); + if (!boot_cpu_has(X86_FEATURE_EFER_LMSLE_MBZ)) + kvm_enable_efer_bits(EFER_LMSLE); r = nested_svm_init_msrpm_merge_offsets(); if (r) diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index dd78e64023450..01be93a53d077 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -117,9 +117,6 @@ struct kvm_sev_info { cpumask_var_t have_run_cpus; /* CPUs that have done VMRUN for this VM. */ }; -#define SEV_POLICY_NODBG BIT_ULL(0) -#define SNP_POLICY_DEBUG BIT_ULL(19) - struct kvm_svm { struct kvm kvm; @@ -764,9 +761,10 @@ int nested_svm_vmexit(struct vcpu_svm *svm); static inline int nested_svm_simple_vmexit(struct vcpu_svm *svm, u32 exit_code) { - svm->vmcb->control.exit_code = exit_code; - svm->vmcb->control.exit_info_1 = 0; - svm->vmcb->control.exit_info_2 = 0; + svm->vmcb->control.exit_code = exit_code; + svm->vmcb->control.exit_code_hi = 0; + svm->vmcb->control.exit_info_1 = 0; + svm->vmcb->control.exit_info_2 = 0; return nested_svm_vmexit(svm); } @@ -807,6 +805,7 @@ extern struct kvm_x86_nested_ops svm_nested_ops; bool __init avic_hardware_setup(void); void avic_hardware_unsetup(void); +int avic_alloc_physical_id_table(struct kvm *kvm); void avic_vm_destroy(struct kvm *kvm); int avic_vm_init(struct kvm *kvm); void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb); diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S index 235c4af6b692a..3392bcadfb896 100644 --- a/arch/x86/kvm/svm/vmenter.S +++ b/arch/x86/kvm/svm/vmenter.S @@ -52,11 +52,23 @@ * there must not be any returns or indirect branches between this code * and vmentry. */ - movl SVM_spec_ctrl(%_ASM_DI), %eax - cmp PER_CPU_VAR(x86_spec_ctrl_current), %eax +#ifdef CONFIG_X86_64 + mov SVM_spec_ctrl(%rdi), %rdx + cmp PER_CPU_VAR(x86_spec_ctrl_current), %rdx + je 801b + movl %edx, %eax + shr $32, %rdx +#else + mov SVM_spec_ctrl(%edi), %eax + mov PER_CPU_VAR(x86_spec_ctrl_current), %ecx + xor %eax, %ecx + mov SVM_spec_ctrl + 4(%edi), %edx + mov PER_CPU_VAR(x86_spec_ctrl_current + 4), %esi + xor %edx, %esi + or %esi, %ecx je 801b +#endif mov $MSR_IA32_SPEC_CTRL, %ecx - xor %edx, %edx wrmsr jmp 801b .endm @@ -81,17 +93,31 @@ jnz 998f rdmsr movl %eax, SVM_spec_ctrl(%_ASM_DI) + movl %edx, SVM_spec_ctrl + 4(%_ASM_DI) 998: - /* Now restore the host value of the MSR if different from the guest's. */ - movl PER_CPU_VAR(x86_spec_ctrl_current), %eax - cmp SVM_spec_ctrl(%_ASM_DI), %eax +#ifdef CONFIG_X86_64 + mov PER_CPU_VAR(x86_spec_ctrl_current), %rdx + cmp SVM_spec_ctrl(%rdi), %rdx je 901b - xor %edx, %edx + movl %edx, %eax + shr $32, %rdx +#else + mov PER_CPU_VAR(x86_spec_ctrl_current), %eax + mov SVM_spec_ctrl(%edi), %esi + xor %eax, %esi + mov PER_CPU_VAR(x86_spec_ctrl_current + 4), %edx + mov SVM_spec_ctrl + 4(%edi), %edi + xor %edx, %edi + or %edi, %esi + je 901b +#endif wrmsr jmp 901b .endm +#define SVM_CLEAR_CPU_BUFFERS \ + ALTERNATIVE "", __CLEAR_CPU_BUFFERS, X86_FEATURE_CLEAR_CPU_BUF_VM /** * __svm_vcpu_run - Run a vCPU via a transition to SVM guest mode @@ -134,7 +160,7 @@ SYM_FUNC_START(__svm_vcpu_run) mov %_ASM_ARG1, %_ASM_DI .endif - /* Clobbers RAX, RCX, RDX. */ + /* Clobbers RAX, RCX, RDX (and ESI on 32-bit), consumes RDI (@svm). */ RESTORE_GUEST_SPEC_CTRL /* @@ -170,7 +196,7 @@ SYM_FUNC_START(__svm_vcpu_run) mov VCPU_RDI(%_ASM_DI), %_ASM_DI /* Clobbers EFLAGS.ZF */ - VM_CLEAR_CPU_BUFFERS + SVM_CLEAR_CPU_BUFFERS /* Enter guest mode */ 3: vmrun %_ASM_AX @@ -211,7 +237,10 @@ SYM_FUNC_START(__svm_vcpu_run) /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT - /* Clobbers RAX, RCX, RDX. */ + /* + * Clobbers RAX, RCX, RDX (and ESI, EDI on 32-bit), consumes RDI (@svm) + * and RSP (pointer to @spec_ctrl_intercepted). + */ RESTORE_HOST_SPEC_CTRL /* @@ -331,7 +360,7 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run) mov %rdi, SEV_ES_RDI (%rdx) mov %rsi, SEV_ES_RSI (%rdx) - /* Clobbers RAX, RCX, RDX (@hostsa). */ + /* Clobbers RAX, RCX, and RDX (@hostsa), consumes RDI (@svm). */ RESTORE_GUEST_SPEC_CTRL /* Get svm->current_vmcb->pa into RAX. */ @@ -339,7 +368,7 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run) mov KVM_VMCB_pa(%rax), %rax /* Clobbers EFLAGS.ZF */ - VM_CLEAR_CPU_BUFFERS + SVM_CLEAR_CPU_BUFFERS /* Enter guest mode */ 1: vmrun %rax diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index 0eb2773b2ae23..a46ccd6707859 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -831,6 +831,14 @@ static int vt_vcpu_mem_enc_ioctl(struct kvm_vcpu *vcpu, void __user *argp) return tdx_vcpu_ioctl(vcpu, argp); } +static int vt_vcpu_mem_enc_unlocked_ioctl(struct kvm_vcpu *vcpu, void __user *argp) +{ + if (!is_td_vcpu(vcpu)) + return -EINVAL; + + return tdx_vcpu_unlocked_ioctl(vcpu, argp); +} + static int vt_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, bool is_private) { @@ -1005,6 +1013,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = { .mem_enc_ioctl = vt_op_tdx_only(mem_enc_ioctl), .vcpu_mem_enc_ioctl = vt_op_tdx_only(vcpu_mem_enc_ioctl), + .vcpu_mem_enc_unlocked_ioctl = vt_op_tdx_only(vcpu_mem_enc_unlocked_ioctl), .gmem_max_mapping_level = vt_op_tdx_only(gmem_max_mapping_level) }; diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index bcea087b642fd..6137e5307d0f6 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -19,12 +19,13 @@ #include "trace.h" #include "vmx.h" #include "smm.h" +#include "x86_ops.h" static bool __read_mostly enable_shadow_vmcs = 1; module_param_named(enable_shadow_vmcs, enable_shadow_vmcs, bool, S_IRUGO); -static bool __read_mostly nested_early_check = 0; -module_param(nested_early_check, bool, S_IRUGO); +static bool __ro_after_init warn_on_missed_cc; +module_param(warn_on_missed_cc, bool, 0444); #define CC KVM_NESTED_VMENTER_CONSISTENCY_CHECK @@ -555,6 +556,9 @@ static int nested_vmx_check_tpr_shadow_controls(struct kvm_vcpu *vcpu, if (CC(!page_address_valid(vcpu, vmcs12->virtual_apic_page_addr))) return -EINVAL; + if (CC(!nested_cpu_has_vid(vmcs12) && vmcs12->tpr_threshold >> 4)) + return -EINVAL; + return 0; } @@ -761,7 +765,7 @@ static void nested_cache_shadow_vmcs12(struct kvm_vcpu *vcpu, vmcs12->vmcs_link_pointer, VMCS12_SIZE)) return; - kvm_read_guest_cached(vmx->vcpu.kvm, ghc, get_shadow_vmcs12(vcpu), + kvm_read_guest_cached(vcpu->kvm, ghc, get_shadow_vmcs12(vcpu), VMCS12_SIZE); } @@ -780,7 +784,7 @@ static void nested_flush_cached_shadow_vmcs12(struct kvm_vcpu *vcpu, vmcs12->vmcs_link_pointer, VMCS12_SIZE)) return; - kvm_write_guest_cached(vmx->vcpu.kvm, ghc, get_shadow_vmcs12(vcpu), + kvm_write_guest_cached(vcpu->kvm, ghc, get_shadow_vmcs12(vcpu), VMCS12_SIZE); } @@ -2296,15 +2300,6 @@ static void prepare_vmcs02_constant_state(struct vcpu_vmx *vmx) return; vmx->nested.vmcs02_initialized = true; - /* - * We don't care what the EPTP value is we just need to guarantee - * it's valid so we don't get a false positive when doing early - * consistency checks. - */ - if (enable_ept && nested_early_check) - vmcs_write64(EPT_POINTER, - construct_eptp(&vmx->vcpu, 0, PT64_ROOT_4LEVEL)); - if (vmx->ve_info) vmcs_write64(VE_INFORMATION_ADDRESS, __pa(vmx->ve_info)); @@ -2749,7 +2744,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, vmcs_write64(GUEST_IA32_PAT, vmcs12->guest_ia32_pat); vcpu->arch.pat = vmcs12->guest_ia32_pat; } else if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { - vmcs_write64(GUEST_IA32_PAT, vmx->vcpu.arch.pat); + vmcs_write64(GUEST_IA32_PAT, vcpu->arch.pat); } vcpu->arch.tsc_offset = kvm_calc_nested_tsc_offset( @@ -2961,6 +2956,10 @@ static int nested_check_vm_execution_controls(struct kvm_vcpu *vcpu, } } + if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_TSC_SCALING) && + CC(!vmcs12->tsc_multiplier)) + return -EINVAL; + return 0; } @@ -3078,6 +3077,38 @@ static int nested_vmx_check_controls(struct kvm_vcpu *vcpu, return 0; } +static int nested_vmx_check_controls_late(struct kvm_vcpu *vcpu, + struct vmcs12 *vmcs12) +{ + void *vapic = to_vmx(vcpu)->nested.virtual_apic_map.hva; + u32 vtpr = vapic ? (*(u32 *)(vapic + APIC_TASKPRI)) >> 4 : 0; + + /* + * Don't bother with the consistency checks if KVM isn't configured to + * WARN on missed consistency checks, as KVM needs to rely on hardware + * to fully detect an illegal vTPR vs. TRP Threshold combination due to + * the vTPR being writable by L1 at all times (it's an in-memory value, + * not a VMCS field). I.e. even if the check passes now, it might fail + * at the actual VM-Enter. + * + * Keying off the module param also allows treating an invalid vAPIC + * mapping as a consistency check failure without increasing the risk + * of breaking a "real" VM. + */ + if (!warn_on_missed_cc) + return 0; + + if ((exec_controls_get(to_vmx(vcpu)) & CPU_BASED_TPR_SHADOW) && + nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW) && + !nested_cpu_has_vid(vmcs12) && + !nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) && + (CC(!vapic) || + CC((vmcs12->tpr_threshold & GENMASK(3, 0)) > (vtpr & GENMASK(3, 0))))) + return -EINVAL; + + return 0; +} + static int nested_vmx_check_address_space_size(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) { @@ -3333,84 +3364,6 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu, return 0; } -static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu) -{ - struct vcpu_vmx *vmx = to_vmx(vcpu); - unsigned long cr3, cr4; - bool vm_fail; - - if (!nested_early_check) - return 0; - - if (vmx->msr_autoload.host.nr) - vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0); - if (vmx->msr_autoload.guest.nr) - vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0); - - preempt_disable(); - - vmx_prepare_switch_to_guest(vcpu); - - /* - * Induce a consistency check VMExit by clearing bit 1 in GUEST_RFLAGS, - * which is reserved to '1' by hardware. GUEST_RFLAGS is guaranteed to - * be written (by prepare_vmcs02()) before the "real" VMEnter, i.e. - * there is no need to preserve other bits or save/restore the field. - */ - vmcs_writel(GUEST_RFLAGS, 0); - - cr3 = __get_current_cr3_fast(); - if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) { - vmcs_writel(HOST_CR3, cr3); - vmx->loaded_vmcs->host_state.cr3 = cr3; - } - - cr4 = cr4_read_shadow(); - if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) { - vmcs_writel(HOST_CR4, cr4); - vmx->loaded_vmcs->host_state.cr4 = cr4; - } - - vm_fail = __vmx_vcpu_run(vmx, (unsigned long *)&vcpu->arch.regs, - __vmx_vcpu_run_flags(vmx)); - - if (vmx->msr_autoload.host.nr) - vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, vmx->msr_autoload.host.nr); - if (vmx->msr_autoload.guest.nr) - vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, vmx->msr_autoload.guest.nr); - - if (vm_fail) { - u32 error = vmcs_read32(VM_INSTRUCTION_ERROR); - - preempt_enable(); - - trace_kvm_nested_vmenter_failed( - "early hardware check VM-instruction error: ", error); - WARN_ON_ONCE(error != VMXERR_ENTRY_INVALID_CONTROL_FIELD); - return 1; - } - - /* - * VMExit clears RFLAGS.IF and DR7, even on a consistency check. - */ - if (hw_breakpoint_active()) - set_debugreg(__this_cpu_read(cpu_dr7), 7); - local_irq_enable(); - preempt_enable(); - - /* - * A non-failing VMEntry means we somehow entered guest mode with - * an illegal RIP, and that's just the tip of the iceberg. There - * is no telling what memory has been modified or what state has - * been exposed to unknown code. Hitting this all but guarantees - * a (very critical) hardware issue. - */ - WARN_ON(!(vmcs_read32(VM_EXIT_REASON) & - VMX_EXIT_REASONS_FAILED_VMENTRY)); - - return 0; -} - #ifdef CONFIG_KVM_HYPERV static bool nested_get_evmcs_page(struct kvm_vcpu *vcpu) { @@ -3667,22 +3620,18 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, &vmx->nested.pre_vmenter_ssp_tbl); /* - * Overwrite vmcs01.GUEST_CR3 with L1's CR3 if EPT is disabled *and* - * nested early checks are disabled. In the event of a "late" VM-Fail, - * i.e. a VM-Fail detected by hardware but not KVM, KVM must unwind its - * software model to the pre-VMEntry host state. When EPT is disabled, - * GUEST_CR3 holds KVM's shadow CR3, not L1's "real" CR3, which causes - * nested_vmx_restore_host_state() to corrupt vcpu->arch.cr3. Stuffing - * vmcs01.GUEST_CR3 results in the unwind naturally setting arch.cr3 to - * the correct value. Smashing vmcs01.GUEST_CR3 is safe because nested - * VM-Exits, and the unwind, reset KVM's MMU, i.e. vmcs01.GUEST_CR3 is - * guaranteed to be overwritten with a shadow CR3 prior to re-entering - * L1. Don't stuff vmcs01.GUEST_CR3 when using nested early checks as - * KVM modifies vcpu->arch.cr3 if and only if the early hardware checks - * pass, and early VM-Fails do not reset KVM's MMU, i.e. the VM-Fail - * path would need to manually save/restore vmcs01.GUEST_CR3. + * Overwrite vmcs01.GUEST_CR3 with L1's CR3 if EPT is disabled. In the + * event of a "late" VM-Fail, i.e. a VM-Fail detected by hardware but + * not KVM, KVM must unwind its software model to the pre-VM-Entry host + * state. When EPT is disabled, GUEST_CR3 holds KVM's shadow CR3, not + * L1's "real" CR3, which causes nested_vmx_restore_host_state() to + * corrupt vcpu->arch.cr3. Stuffing vmcs01.GUEST_CR3 results in the + * unwind naturally setting arch.cr3 to the correct value. Smashing + * vmcs01.GUEST_CR3 is safe because nested VM-Exits, and the unwind, + * reset KVM's MMU, i.e. vmcs01.GUEST_CR3 is guaranteed to be + * overwritten with a shadow CR3 prior to re-entering L1. */ - if (!enable_ept && !nested_early_check) + if (!enable_ept) vmcs_writel(GUEST_CR3, vcpu->arch.cr3); vmx_switch_vmcs(vcpu, &vmx->nested.vmcs02); @@ -3695,7 +3644,7 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, return NVMX_VMENTRY_KVM_INTERNAL_ERROR; } - if (nested_vmx_check_vmentry_hw(vcpu)) { + if (nested_vmx_check_controls_late(vcpu, vmcs12)) { vmx_switch_vmcs(vcpu, &vmx->vmcs01); return NVMX_VMENTRY_VMFAIL; } @@ -3880,7 +3829,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) goto vmentry_failed; /* Hide L1D cache contents from the nested guest. */ - vmx->vcpu.arch.l1tf_flush_l1d = true; + kvm_request_l1tf_flush_l1d(); /* * Must happen outside of nested_vmx_enter_non_root_mode() as it will @@ -5164,12 +5113,13 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, /* * The only expected VM-instruction error is "VM entry with * invalid control field(s)." Anything else indicates a - * problem with L0. And we should never get here with a - * VMFail of any type if early consistency checks are enabled. + * problem with L0. */ WARN_ON_ONCE(vmcs_read32(VM_INSTRUCTION_ERROR) != VMXERR_ENTRY_INVALID_CONTROL_FIELD); - WARN_ON_ONCE(nested_early_check); + + /* VM-Fail at VM-Entry means KVM missed a consistency check. */ + WARN_ON_ONCE(warn_on_missed_cc); } /* @@ -5216,7 +5166,7 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, if (vmx->nested.update_vmcs01_apicv_status) { vmx->nested.update_vmcs01_apicv_status = false; - kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu); + vmx_refresh_apicv_exec_ctrl(vcpu); } if (vmx->nested.update_vmcs01_hwapic_isr) { diff --git a/arch/x86/kvm/vmx/run_flags.h b/arch/x86/kvm/vmx/run_flags.h index 2f20fb170def8..6a87a12135fb5 100644 --- a/arch/x86/kvm/vmx/run_flags.h +++ b/arch/x86/kvm/vmx/run_flags.h @@ -2,12 +2,8 @@ #ifndef __KVM_X86_VMX_RUN_FLAGS_H #define __KVM_X86_VMX_RUN_FLAGS_H -#define VMX_RUN_VMRESUME_SHIFT 0 -#define VMX_RUN_SAVE_SPEC_CTRL_SHIFT 1 -#define VMX_RUN_CLEAR_CPU_BUFFERS_FOR_MMIO_SHIFT 2 - -#define VMX_RUN_VMRESUME BIT(VMX_RUN_VMRESUME_SHIFT) -#define VMX_RUN_SAVE_SPEC_CTRL BIT(VMX_RUN_SAVE_SPEC_CTRL_SHIFT) -#define VMX_RUN_CLEAR_CPU_BUFFERS_FOR_MMIO BIT(VMX_RUN_CLEAR_CPU_BUFFERS_FOR_MMIO_SHIFT) +#define VMX_RUN_VMRESUME BIT(0) +#define VMX_RUN_SAVE_SPEC_CTRL BIT(1) +#define VMX_RUN_CLEAR_CPU_BUFFERS_FOR_MMIO BIT(2) #endif /* __KVM_X86_VMX_RUN_FLAGS_H */ diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 0a49c863c811b..2d7a4d52ccfb4 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -24,20 +24,33 @@ #undef pr_fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#define pr_tdx_error(__fn, __err) \ - pr_err_ratelimited("SEAMCALL %s failed: 0x%llx\n", #__fn, __err) +#define __TDX_BUG_ON(__err, __f, __kvm, __fmt, __args...) \ +({ \ + struct kvm *_kvm = (__kvm); \ + bool __ret = !!(__err); \ + \ + if (WARN_ON_ONCE(__ret && (!_kvm || !_kvm->vm_bugged))) { \ + if (_kvm) \ + kvm_vm_bugged(_kvm); \ + pr_err_ratelimited("SEAMCALL " __f " failed: 0x%llx" __fmt "\n",\ + __err, __args); \ + } \ + unlikely(__ret); \ +}) + +#define TDX_BUG_ON(__err, __fn, __kvm) \ + __TDX_BUG_ON(__err, #__fn, __kvm, "%s", "") + +#define TDX_BUG_ON_1(__err, __fn, a1, __kvm) \ + __TDX_BUG_ON(__err, #__fn, __kvm, ", " #a1 " 0x%llx", a1) + +#define TDX_BUG_ON_2(__err, __fn, a1, a2, __kvm) \ + __TDX_BUG_ON(__err, #__fn, __kvm, ", " #a1 " 0x%llx, " #a2 " 0x%llx", a1, a2) + +#define TDX_BUG_ON_3(__err, __fn, a1, a2, a3, __kvm) \ + __TDX_BUG_ON(__err, #__fn, __kvm, ", " #a1 " 0x%llx, " #a2 ", 0x%llx, " #a3 " 0x%llx", \ + a1, a2, a3) -#define __pr_tdx_error_N(__fn_str, __err, __fmt, ...) \ - pr_err_ratelimited("SEAMCALL " __fn_str " failed: 0x%llx, " __fmt, __err, __VA_ARGS__) - -#define pr_tdx_error_1(__fn, __err, __rcx) \ - __pr_tdx_error_N(#__fn, __err, "rcx 0x%llx\n", __rcx) - -#define pr_tdx_error_2(__fn, __err, __rcx, __rdx) \ - __pr_tdx_error_N(#__fn, __err, "rcx 0x%llx, rdx 0x%llx\n", __rcx, __rdx) - -#define pr_tdx_error_3(__fn, __err, __rcx, __rdx, __r8) \ - __pr_tdx_error_N(#__fn, __err, "rcx 0x%llx, rdx 0x%llx, r8 0x%llx\n", __rcx, __rdx, __r8) bool enable_tdx __ro_after_init; module_param_named(tdx, enable_tdx, bool, 0444); @@ -281,25 +294,34 @@ static inline void tdx_disassociate_vp(struct kvm_vcpu *vcpu) vcpu->cpu = -1; } -static void tdx_no_vcpus_enter_start(struct kvm *kvm) -{ - struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); - - lockdep_assert_held_write(&kvm->mmu_lock); - - WRITE_ONCE(kvm_tdx->wait_for_sept_zap, true); - - kvm_make_all_cpus_request(kvm, KVM_REQ_OUTSIDE_GUEST_MODE); -} - -static void tdx_no_vcpus_enter_stop(struct kvm *kvm) -{ - struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); - - lockdep_assert_held_write(&kvm->mmu_lock); - - WRITE_ONCE(kvm_tdx->wait_for_sept_zap, false); -} +/* + * Execute a SEAMCALL related to removing/blocking S-EPT entries, with a single + * retry (if necessary) after forcing vCPUs to exit and wait for the operation + * to complete. All flows that remove/block S-EPT entries run with mmu_lock + * held for write, i.e. are mutually exclusive with each other, but they aren't + * mutually exclusive with running vCPUs, and so can fail with "operand busy" + * if a vCPU acquires a relevant lock in the TDX-Module, e.g. when doing TDCALL. + * + * Note, the retry is guaranteed to succeed, absent KVM and/or TDX-Module bugs. + */ +#define tdh_do_no_vcpus(tdh_func, kvm, args...) \ +({ \ + struct kvm_tdx *__kvm_tdx = to_kvm_tdx(kvm); \ + u64 __err; \ + \ + lockdep_assert_held_write(&kvm->mmu_lock); \ + \ + __err = tdh_func(args); \ + if (unlikely(tdx_operand_busy(__err))) { \ + WRITE_ONCE(__kvm_tdx->wait_for_sept_zap, true); \ + kvm_make_all_cpus_request(kvm, KVM_REQ_OUTSIDE_GUEST_MODE); \ + \ + __err = tdh_func(args); \ + \ + WRITE_ONCE(__kvm_tdx->wait_for_sept_zap, false); \ + } \ + __err; \ +}) /* TDH.PHYMEM.PAGE.RECLAIM is allowed only when destroying the TD. */ static int __tdx_reclaim_page(struct page *page) @@ -313,10 +335,9 @@ static int __tdx_reclaim_page(struct page *page) * before the HKID is released and control pages have also been * released at this point, so there is no possibility of contention. */ - if (WARN_ON_ONCE(err)) { - pr_tdx_error_3(TDH_PHYMEM_PAGE_RECLAIM, err, rcx, rdx, r8); + if (TDX_BUG_ON_3(err, TDH_PHYMEM_PAGE_RECLAIM, rcx, rdx, r8, NULL)) return -EIO; - } + return 0; } @@ -404,8 +425,8 @@ static void tdx_flush_vp_on_cpu(struct kvm_vcpu *vcpu) return; smp_call_function_single(cpu, tdx_flush_vp, &arg, 1); - if (KVM_BUG_ON(arg.err, vcpu->kvm)) - pr_tdx_error(TDH_VP_FLUSH, arg.err); + + TDX_BUG_ON(arg.err, TDH_VP_FLUSH, vcpu->kvm); } void tdx_disable_virtualization_cpu(void) @@ -464,8 +485,7 @@ static void smp_func_do_phymem_cache_wb(void *unused) } out: - if (WARN_ON_ONCE(err)) - pr_tdx_error(TDH_PHYMEM_CACHE_WB, err); + TDX_BUG_ON(err, TDH_PHYMEM_CACHE_WB, NULL); } void tdx_mmu_release_hkid(struct kvm *kvm) @@ -504,8 +524,7 @@ void tdx_mmu_release_hkid(struct kvm *kvm) err = tdh_mng_vpflushdone(&kvm_tdx->td); if (err == TDX_FLUSHVP_NOT_DONE) goto out; - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error(TDH_MNG_VPFLUSHDONE, err); + if (TDX_BUG_ON(err, TDH_MNG_VPFLUSHDONE, kvm)) { pr_err("tdh_mng_vpflushdone() failed. HKID %d is leaked.\n", kvm_tdx->hkid); goto out; @@ -528,8 +547,7 @@ void tdx_mmu_release_hkid(struct kvm *kvm) * tdh_mng_key_freeid() will fail. */ err = tdh_mng_key_freeid(&kvm_tdx->td); - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error(TDH_MNG_KEY_FREEID, err); + if (TDX_BUG_ON(err, TDH_MNG_KEY_FREEID, kvm)) { pr_err("tdh_mng_key_freeid() failed. HKID %d is leaked.\n", kvm_tdx->hkid); } else { @@ -580,10 +598,9 @@ static void tdx_reclaim_td_control_pages(struct kvm *kvm) * when it is reclaiming TDCS). */ err = tdh_phymem_page_wbinvd_tdr(&kvm_tdx->td); - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error(TDH_PHYMEM_PAGE_WBINVD, err); + if (TDX_BUG_ON(err, TDH_PHYMEM_PAGE_WBINVD, kvm)) return; - } + tdx_quirk_reset_page(kvm_tdx->td.tdr_page); __free_page(kvm_tdx->td.tdr_page); @@ -606,11 +623,8 @@ static int tdx_do_tdh_mng_key_config(void *param) /* TDX_RND_NO_ENTROPY related retries are handled by sc_retry() */ err = tdh_mng_key_config(&kvm_tdx->td); - - if (KVM_BUG_ON(err, &kvm_tdx->kvm)) { - pr_tdx_error(TDH_MNG_KEY_CONFIG, err); + if (TDX_BUG_ON(err, TDH_MNG_KEY_CONFIG, &kvm_tdx->kvm)) return -EIO; - } return 0; } @@ -763,25 +777,6 @@ static bool tdx_protected_apic_has_interrupt(struct kvm_vcpu *vcpu) return tdx_vcpu_state_details_intr_pending(vcpu_state_details); } -/* - * Compared to vmx_prepare_switch_to_guest(), there is not much to do - * as SEAMCALL/SEAMRET calls take care of most of save and restore. - */ -void tdx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) -{ - struct vcpu_vt *vt = to_vt(vcpu); - - if (vt->guest_state_loaded) - return; - - if (likely(is_64bit_mm(current->mm))) - vt->msr_host_kernel_gs_base = current->thread.gsbase; - else - vt->msr_host_kernel_gs_base = read_msr(MSR_KERNEL_GS_BASE); - - vt->guest_state_loaded = true; -} - struct tdx_uret_msr { u32 msr; unsigned int slot; @@ -795,19 +790,38 @@ static struct tdx_uret_msr tdx_uret_msrs[] = { {.msr = MSR_TSC_AUX,}, }; -static void tdx_user_return_msr_update_cache(void) +void tdx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) { + struct vcpu_vt *vt = to_vt(vcpu); int i; + if (vt->guest_state_loaded) + return; + + if (likely(is_64bit_mm(current->mm))) + vt->msr_host_kernel_gs_base = current->thread.gsbase; + else + vt->msr_host_kernel_gs_base = read_msr(MSR_KERNEL_GS_BASE); + + vt->guest_state_loaded = true; + + /* + * Explicitly set user-return MSRs that are clobbered by the TDX-Module + * if VP.ENTER succeeds, i.e. on TD-Exit, with the values that would be + * written by the TDX-Module. Don't rely on the TDX-Module to actually + * clobber the MSRs, as the contract is poorly defined and not upheld. + * E.g. the TDX-Module will synthesize an EPT Violation without doing + * VM-Enter if it suspects a zero-step attack, and never "restore" VMM + * state. + */ for (i = 0; i < ARRAY_SIZE(tdx_uret_msrs); i++) - kvm_user_return_msr_update_cache(tdx_uret_msrs[i].slot, - tdx_uret_msrs[i].defval); + kvm_set_user_return_msr(tdx_uret_msrs[i].slot, + tdx_uret_msrs[i].defval, -1ull); } static void tdx_prepare_switch_to_host(struct kvm_vcpu *vcpu) { struct vcpu_vt *vt = to_vt(vcpu); - struct vcpu_tdx *tdx = to_tdx(vcpu); if (!vt->guest_state_loaded) return; @@ -815,11 +829,6 @@ static void tdx_prepare_switch_to_host(struct kvm_vcpu *vcpu) ++vcpu->stat.host_state_reload; wrmsrl(MSR_KERNEL_GS_BASE, vt->msr_host_kernel_gs_base); - if (tdx->guest_entered) { - tdx_user_return_msr_update_cache(); - tdx->guest_entered = false; - } - vt->guest_state_loaded = false; } @@ -829,19 +838,52 @@ void tdx_vcpu_put(struct kvm_vcpu *vcpu) tdx_prepare_switch_to_host(vcpu); } +/* + * Life cycles for a TD and a vCPU: + * 1. KVM_CREATE_VM ioctl. + * TD state is TD_STATE_UNINITIALIZED. + * hkid is not assigned at this stage. + * 2. KVM_TDX_INIT_VM ioctl. + * TD transitions to TD_STATE_INITIALIZED. + * hkid is assigned after this stage. + * 3. KVM_CREATE_VCPU ioctl. (only when TD is TD_STATE_INITIALIZED). + * 3.1 tdx_vcpu_create() transitions vCPU state to VCPU_TD_STATE_UNINITIALIZED. + * 3.2 vcpu_load() and vcpu_put() in kvm_arch_vcpu_create(). + * 3.3 (conditional) if any error encountered after kvm_arch_vcpu_create() + * kvm_arch_vcpu_destroy() --> tdx_vcpu_free(). + * 4. KVM_TDX_INIT_VCPU ioctl. + * tdx_vcpu_init() transitions vCPU state to VCPU_TD_STATE_INITIALIZED. + * vCPU control structures are allocated at this stage. + * 5. kvm_destroy_vm(). + * 5.1 tdx_mmu_release_hkid(): (1) tdh_vp_flush(), disassociates all vCPUs. + * (2) puts hkid to !assigned state. + * 5.2 kvm_destroy_vcpus() --> tdx_vcpu_free(): + * transitions vCPU to VCPU_TD_STATE_UNINITIALIZED state. + * 5.3 tdx_vm_destroy() + * transitions TD to TD_STATE_UNINITIALIZED state. + * + * tdx_vcpu_free() can be invoked only at 3.3 or 5.2. + * - If at 3.3, hkid is still assigned, but the vCPU must be in + * VCPU_TD_STATE_UNINITIALIZED state. + * - if at 5.2, hkid must be !assigned and all vCPUs must be in + * VCPU_TD_STATE_INITIALIZED state and have been dissociated. + */ void tdx_vcpu_free(struct kvm_vcpu *vcpu) { struct kvm_tdx *kvm_tdx = to_kvm_tdx(vcpu->kvm); struct vcpu_tdx *tdx = to_tdx(vcpu); int i; + if (vcpu->cpu != -1) { + KVM_BUG_ON(tdx->state == VCPU_TD_STATE_INITIALIZED, vcpu->kvm); + tdx_flush_vp_on_cpu(vcpu); + return; + } + /* * It is not possible to reclaim pages while hkid is assigned. It might - * be assigned if: - * 1. the TD VM is being destroyed but freeing hkid failed, in which - * case the pages are leaked - * 2. TD VCPU creation failed and this on the error path, in which case - * there is nothing to do anyway + * be assigned if the TD VM is being destroyed but freeing hkid failed, + * in which case the pages are leaked. */ if (is_hkid_assigned(kvm_tdx)) return; @@ -856,7 +898,7 @@ void tdx_vcpu_free(struct kvm_vcpu *vcpu) } if (tdx->vp.tdvpr_page) { tdx_reclaim_control_page(tdx->vp.tdvpr_page); - tdx->vp.tdvpr_page = 0; + tdx->vp.tdvpr_page = NULL; tdx->vp.tdvpr_pa = 0; } @@ -1059,7 +1101,6 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) update_debugctlmsr(vcpu->arch.host_debugctl); tdx_load_host_xsave_state(vcpu); - tdx->guest_entered = true; vcpu->arch.regs_avail &= TDX_REGS_AVAIL_SET; @@ -1069,9 +1110,6 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) if (unlikely((tdx->vp_enter_ret & TDX_SW_ERROR) == TDX_SW_ERROR)) return EXIT_FASTPATH_NONE; - if (unlikely(vmx_get_exit_reason(vcpu).basic == EXIT_REASON_MCE_DURING_VMENTRY)) - kvm_machine_check(); - trace_kvm_exit(vcpu, KVM_ISA_VMX); if (unlikely(tdx_failed_vmentry(vcpu))) @@ -1583,137 +1621,79 @@ void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int pgd_level) td_vmcs_write64(to_tdx(vcpu), SHARED_EPT_POINTER, root_hpa); } -static void tdx_unpin(struct kvm *kvm, struct page *page) +static int tdx_mem_page_add(struct kvm *kvm, gfn_t gfn, enum pg_level level, + kvm_pfn_t pfn) { - put_page(page); + struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); + u64 err, entry, level_state; + gpa_t gpa = gfn_to_gpa(gfn); + + lockdep_assert_held(&kvm->slots_lock); + + if (KVM_BUG_ON(kvm->arch.pre_fault_allowed, kvm) || + KVM_BUG_ON(!kvm_tdx->page_add_src, kvm)) + return -EIO; + + err = tdh_mem_page_add(&kvm_tdx->td, gpa, pfn_to_page(pfn), + kvm_tdx->page_add_src, &entry, &level_state); + if (unlikely(tdx_operand_busy(err))) + return -EBUSY; + + if (TDX_BUG_ON_2(err, TDH_MEM_PAGE_ADD, entry, level_state, kvm)) + return -EIO; + + return 0; } static int tdx_mem_page_aug(struct kvm *kvm, gfn_t gfn, - enum pg_level level, struct page *page) + enum pg_level level, kvm_pfn_t pfn) { int tdx_level = pg_level_to_tdx_sept_level(level); struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); + struct page *page = pfn_to_page(pfn); gpa_t gpa = gfn_to_gpa(gfn); u64 entry, level_state; u64 err; err = tdh_mem_page_aug(&kvm_tdx->td, gpa, tdx_level, page, &entry, &level_state); - if (unlikely(tdx_operand_busy(err))) { - tdx_unpin(kvm, page); + if (unlikely(tdx_operand_busy(err))) return -EBUSY; - } - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error_2(TDH_MEM_PAGE_AUG, err, entry, level_state); - tdx_unpin(kvm, page); + if (TDX_BUG_ON_2(err, TDH_MEM_PAGE_AUG, entry, level_state, kvm)) return -EIO; - } - - return 0; -} - -/* - * KVM_TDX_INIT_MEM_REGION calls kvm_gmem_populate() to map guest pages; the - * callback tdx_gmem_post_populate() then maps pages into private memory. - * through the a seamcall TDH.MEM.PAGE.ADD(). The SEAMCALL also requires the - * private EPT structures for the page to have been built before, which is - * done via kvm_tdp_map_page(). nr_premapped counts the number of pages that - * were added to the EPT structures but not added with TDH.MEM.PAGE.ADD(). - * The counter has to be zero on KVM_TDX_FINALIZE_VM, to ensure that there - * are no half-initialized shared EPT pages. - */ -static int tdx_mem_page_record_premap_cnt(struct kvm *kvm, gfn_t gfn, - enum pg_level level, kvm_pfn_t pfn) -{ - struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); - - if (KVM_BUG_ON(kvm->arch.pre_fault_allowed, kvm)) - return -EINVAL; - /* nr_premapped will be decreased when tdh_mem_page_add() is called. */ - atomic64_inc(&kvm_tdx->nr_premapped); return 0; } static int tdx_sept_set_private_spte(struct kvm *kvm, gfn_t gfn, - enum pg_level level, kvm_pfn_t pfn) + enum pg_level level, u64 mirror_spte) { struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); - struct page *page = pfn_to_page(pfn); + kvm_pfn_t pfn = spte_to_pfn(mirror_spte); /* TODO: handle large pages. */ if (KVM_BUG_ON(level != PG_LEVEL_4K, kvm)) - return -EINVAL; + return -EIO; - /* - * Because guest_memfd doesn't support page migration with - * a_ops->migrate_folio (yet), no callback is triggered for KVM on page - * migration. Until guest_memfd supports page migration, prevent page - * migration. - * TODO: Once guest_memfd introduces callback on page migration, - * implement it and remove get_page/put_page(). - */ - get_page(page); + WARN_ON_ONCE(!is_shadow_present_pte(mirror_spte) || + (mirror_spte & VMX_EPT_RWX_MASK) != VMX_EPT_RWX_MASK); /* - * Read 'pre_fault_allowed' before 'kvm_tdx->state'; see matching - * barrier in tdx_td_finalize(). + * Ensure pre_fault_allowed is read by kvm_arch_vcpu_pre_fault_memory() + * before kvm_tdx->state. Userspace must not be allowed to pre-fault + * arbitrary memory until the initial memory image is finalized. Pairs + * with the smp_wmb() in tdx_td_finalize(). */ smp_rmb(); - if (likely(kvm_tdx->state == TD_STATE_RUNNABLE)) - return tdx_mem_page_aug(kvm, gfn, level, page); - - return tdx_mem_page_record_premap_cnt(kvm, gfn, level, pfn); -} - -static int tdx_sept_drop_private_spte(struct kvm *kvm, gfn_t gfn, - enum pg_level level, struct page *page) -{ - int tdx_level = pg_level_to_tdx_sept_level(level); - struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); - gpa_t gpa = gfn_to_gpa(gfn); - u64 err, entry, level_state; - - /* TODO: handle large pages. */ - if (KVM_BUG_ON(level != PG_LEVEL_4K, kvm)) - return -EINVAL; - - if (KVM_BUG_ON(!is_hkid_assigned(kvm_tdx), kvm)) - return -EINVAL; /* - * When zapping private page, write lock is held. So no race condition - * with other vcpu sept operation. - * Race with TDH.VP.ENTER due to (0-step mitigation) and Guest TDCALLs. + * If the TD isn't finalized/runnable, then userspace is initializing + * the VM image via KVM_TDX_INIT_MEM_REGION; ADD the page to the TD. */ - err = tdh_mem_page_remove(&kvm_tdx->td, gpa, tdx_level, &entry, - &level_state); - - if (unlikely(tdx_operand_busy(err))) { - /* - * The second retry is expected to succeed after kicking off all - * other vCPUs and prevent them from invoking TDH.VP.ENTER. - */ - tdx_no_vcpus_enter_start(kvm); - err = tdh_mem_page_remove(&kvm_tdx->td, gpa, tdx_level, &entry, - &level_state); - tdx_no_vcpus_enter_stop(kvm); - } - - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error_2(TDH_MEM_PAGE_REMOVE, err, entry, level_state); - return -EIO; - } - - err = tdh_phymem_page_wbinvd_hkid((u16)kvm_tdx->hkid, page); + if (unlikely(kvm_tdx->state != TD_STATE_RUNNABLE)) + return tdx_mem_page_add(kvm, gfn, level, pfn); - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error(TDH_PHYMEM_PAGE_WBINVD, err); - return -EIO; - } - tdx_quirk_reset_page(page); - tdx_unpin(kvm, page); - return 0; + return tdx_mem_page_aug(kvm, gfn, level, pfn); } static int tdx_sept_link_private_spt(struct kvm *kvm, gfn_t gfn, @@ -1729,80 +1709,12 @@ static int tdx_sept_link_private_spt(struct kvm *kvm, gfn_t gfn, if (unlikely(tdx_operand_busy(err))) return -EBUSY; - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error_2(TDH_MEM_SEPT_ADD, err, entry, level_state); + if (TDX_BUG_ON_2(err, TDH_MEM_SEPT_ADD, entry, level_state, kvm)) return -EIO; - } return 0; } -/* - * Check if the error returned from a SEPT zap SEAMCALL is due to that a page is - * mapped by KVM_TDX_INIT_MEM_REGION without tdh_mem_page_add() being called - * successfully. - * - * Since tdh_mem_sept_add() must have been invoked successfully before a - * non-leaf entry present in the mirrored page table, the SEPT ZAP related - * SEAMCALLs should not encounter err TDX_EPT_WALK_FAILED. They should instead - * find TDX_EPT_ENTRY_STATE_INCORRECT due to an empty leaf entry found in the - * SEPT. - * - * Further check if the returned entry from SEPT walking is with RWX permissions - * to filter out anything unexpected. - * - * Note: @level is pg_level, not the tdx_level. The tdx_level extracted from - * level_state returned from a SEAMCALL error is the same as that passed into - * the SEAMCALL. - */ -static int tdx_is_sept_zap_err_due_to_premap(struct kvm_tdx *kvm_tdx, u64 err, - u64 entry, int level) -{ - if (!err || kvm_tdx->state == TD_STATE_RUNNABLE) - return false; - - if (err != (TDX_EPT_ENTRY_STATE_INCORRECT | TDX_OPERAND_ID_RCX)) - return false; - - if ((is_last_spte(entry, level) && (entry & VMX_EPT_RWX_MASK))) - return false; - - return true; -} - -static int tdx_sept_zap_private_spte(struct kvm *kvm, gfn_t gfn, - enum pg_level level, struct page *page) -{ - int tdx_level = pg_level_to_tdx_sept_level(level); - struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); - gpa_t gpa = gfn_to_gpa(gfn) & KVM_HPAGE_MASK(level); - u64 err, entry, level_state; - - /* For now large page isn't supported yet. */ - WARN_ON_ONCE(level != PG_LEVEL_4K); - - err = tdh_mem_range_block(&kvm_tdx->td, gpa, tdx_level, &entry, &level_state); - - if (unlikely(tdx_operand_busy(err))) { - /* After no vCPUs enter, the second retry is expected to succeed */ - tdx_no_vcpus_enter_start(kvm); - err = tdh_mem_range_block(&kvm_tdx->td, gpa, tdx_level, &entry, &level_state); - tdx_no_vcpus_enter_stop(kvm); - } - if (tdx_is_sept_zap_err_due_to_premap(kvm_tdx, err, entry, level) && - !KVM_BUG_ON(!atomic64_read(&kvm_tdx->nr_premapped), kvm)) { - atomic64_dec(&kvm_tdx->nr_premapped); - tdx_unpin(kvm, page); - return 0; - } - - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error_2(TDH_MEM_RANGE_BLOCK, err, entry, level_state); - return -EIO; - } - return 1; -} - /* * Ensure shared and private EPTs to be flushed on all vCPUs. * tdh_mem_track() is the only caller that increases TD epoch. An increase in @@ -1836,18 +1748,15 @@ static void tdx_track(struct kvm *kvm) if (unlikely(kvm_tdx->state != TD_STATE_RUNNABLE)) return; + /* + * The full sequence of TDH.MEM.TRACK and forcing vCPUs out of guest + * mode must be serialized, as TDH.MEM.TRACK will fail if the previous + * tracking epoch hasn't completed. + */ lockdep_assert_held_write(&kvm->mmu_lock); - err = tdh_mem_track(&kvm_tdx->td); - if (unlikely(tdx_operand_busy(err))) { - /* After no vCPUs enter, the second retry is expected to succeed */ - tdx_no_vcpus_enter_start(kvm); - err = tdh_mem_track(&kvm_tdx->td); - tdx_no_vcpus_enter_stop(kvm); - } - - if (KVM_BUG_ON(err, kvm)) - pr_tdx_error(TDH_MEM_TRACK, err); + err = tdh_do_no_vcpus(tdh_mem_track, kvm, &kvm_tdx->td); + TDX_BUG_ON(err, TDH_MEM_TRACK, kvm); kvm_make_all_cpus_request(kvm, KVM_REQ_OUTSIDE_GUEST_MODE); } @@ -1866,7 +1775,7 @@ static int tdx_sept_free_private_spt(struct kvm *kvm, gfn_t gfn, * and slot move/deletion. */ if (KVM_BUG_ON(is_hkid_assigned(kvm_tdx), kvm)) - return -EINVAL; + return -EIO; /* * The HKID assigned to this TD was already freed and cache was @@ -1875,11 +1784,16 @@ static int tdx_sept_free_private_spt(struct kvm *kvm, gfn_t gfn, return tdx_reclaim_page(virt_to_page(private_spt)); } -static int tdx_sept_remove_private_spte(struct kvm *kvm, gfn_t gfn, - enum pg_level level, kvm_pfn_t pfn) +static void tdx_sept_remove_private_spte(struct kvm *kvm, gfn_t gfn, + enum pg_level level, u64 mirror_spte) { - struct page *page = pfn_to_page(pfn); - int ret; + struct page *page = pfn_to_page(spte_to_pfn(mirror_spte)); + int tdx_level = pg_level_to_tdx_sept_level(level); + struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); + gpa_t gpa = gfn_to_gpa(gfn); + u64 err, entry, level_state; + + lockdep_assert_held_write(&kvm->mmu_lock); /* * HKID is released after all private pages have been removed, and set @@ -1887,11 +1801,16 @@ static int tdx_sept_remove_private_spte(struct kvm *kvm, gfn_t gfn, * there can't be anything populated in the private EPT. */ if (KVM_BUG_ON(!is_hkid_assigned(to_kvm_tdx(kvm)), kvm)) - return -EINVAL; + return; - ret = tdx_sept_zap_private_spte(kvm, gfn, level, page); - if (ret <= 0) - return ret; + /* TODO: handle large pages. */ + if (KVM_BUG_ON(level != PG_LEVEL_4K, kvm)) + return; + + err = tdh_do_no_vcpus(tdh_mem_range_block, kvm, &kvm_tdx->td, gpa, + tdx_level, &entry, &level_state); + if (TDX_BUG_ON_2(err, TDH_MEM_RANGE_BLOCK, entry, level_state, kvm)) + return; /* * TDX requires TLB tracking before dropping private page. Do @@ -1899,7 +1818,21 @@ static int tdx_sept_remove_private_spte(struct kvm *kvm, gfn_t gfn, */ tdx_track(kvm); - return tdx_sept_drop_private_spte(kvm, gfn, level, page); + /* + * When zapping private page, write lock is held. So no race condition + * with other vcpu sept operation. + * Race with TDH.VP.ENTER due to (0-step mitigation) and Guest TDCALLs. + */ + err = tdh_do_no_vcpus(tdh_mem_page_remove, kvm, &kvm_tdx->td, gpa, + tdx_level, &entry, &level_state); + if (TDX_BUG_ON_2(err, TDH_MEM_PAGE_REMOVE, entry, level_state, kvm)) + return; + + err = tdh_phymem_page_wbinvd_hkid((u16)kvm_tdx->hkid, page); + if (TDX_BUG_ON(err, TDH_PHYMEM_PAGE_WBINVD, kvm)) + return; + + tdx_quirk_reset_page(page); } void tdx_deliver_interrupt(struct kvm_lapic *apic, int delivery_mode, @@ -2145,11 +2078,7 @@ int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath) } unhandled_exit: - vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; - vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON; - vcpu->run->internal.ndata = 2; - vcpu->run->internal.data[0] = vp_enter_ret; - vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu; + kvm_prepare_unexpected_reason_exit(vcpu, vp_enter_ret); return 0; } @@ -2282,37 +2211,28 @@ static int tdx_get_capabilities(struct kvm_tdx_cmd *cmd) if (cmd->flags) return -EINVAL; - caps = kzalloc(sizeof(*caps) + - sizeof(struct kvm_cpuid_entry2) * td_conf->num_cpuid_config, - GFP_KERNEL); - if (!caps) - return -ENOMEM; - user_caps = u64_to_user_ptr(cmd->data); - if (get_user(nr_user_entries, &user_caps->cpuid.nent)) { - ret = -EFAULT; - goto out; - } + if (get_user(nr_user_entries, &user_caps->cpuid.nent)) + return -EFAULT; - if (nr_user_entries < td_conf->num_cpuid_config) { - ret = -E2BIG; - goto out; - } + if (nr_user_entries < td_conf->num_cpuid_config) + return -E2BIG; + + caps = kzalloc(struct_size(caps, cpuid.entries, + td_conf->num_cpuid_config), GFP_KERNEL); + if (!caps) + return -ENOMEM; ret = init_kvm_tdx_caps(td_conf, caps); if (ret) goto out; - if (copy_to_user(user_caps, caps, sizeof(*caps))) { + if (copy_to_user(user_caps, caps, struct_size(caps, cpuid.entries, + caps->cpuid.nent))) { ret = -EFAULT; goto out; } - if (copy_to_user(user_caps->cpuid.entries, caps->cpuid.entries, - caps->cpuid.nent * - sizeof(caps->cpuid.entries[0]))) - ret = -EFAULT; - out: /* kfree() accepts NULL. */ kfree(caps); @@ -2537,8 +2457,7 @@ static int __tdx_td_init(struct kvm *kvm, struct td_params *td_params, goto free_packages; } - if (WARN_ON_ONCE(err)) { - pr_tdx_error(TDH_MNG_CREATE, err); + if (TDX_BUG_ON(err, TDH_MNG_CREATE, kvm)) { ret = -EIO; goto free_packages; } @@ -2579,8 +2498,7 @@ static int __tdx_td_init(struct kvm *kvm, struct td_params *td_params, ret = -EAGAIN; goto teardown; } - if (WARN_ON_ONCE(err)) { - pr_tdx_error(TDH_MNG_ADDCX, err); + if (TDX_BUG_ON(err, TDH_MNG_ADDCX, kvm)) { ret = -EIO; goto teardown; } @@ -2597,8 +2515,7 @@ static int __tdx_td_init(struct kvm *kvm, struct td_params *td_params, *seamcall_err = err; ret = -EINVAL; goto teardown; - } else if (WARN_ON_ONCE(err)) { - pr_tdx_error_1(TDH_MNG_INIT, err, rcx); + } else if (TDX_BUG_ON_1(err, TDH_MNG_INIT, rcx, kvm)) { ret = -EIO; goto teardown; } @@ -2642,7 +2559,7 @@ static int __tdx_td_init(struct kvm *kvm, struct td_params *td_params, free_tdr: if (tdr_page) __free_page(tdr_page); - kvm_tdx->td.tdr_page = 0; + kvm_tdx->td.tdr_page = NULL; free_hkid: tdx_hkid_free(kvm_tdx); @@ -2747,11 +2664,53 @@ static int tdx_read_cpuid(struct kvm_vcpu *vcpu, u32 leaf, u32 sub_leaf, return -EIO; } +typedef void *tdx_vm_state_guard_t; + +static tdx_vm_state_guard_t tdx_acquire_vm_state_locks(struct kvm *kvm) +{ + int r; + + mutex_lock(&kvm->lock); + + if (kvm->created_vcpus != atomic_read(&kvm->online_vcpus)) { + r = -EBUSY; + goto out_err; + } + + r = kvm_lock_all_vcpus(kvm); + if (r) + goto out_err; + + /* + * Note the unintuitive ordering! vcpu->mutex must be taken outside + * kvm->slots_lock! + */ + mutex_lock(&kvm->slots_lock); + return kvm; + +out_err: + mutex_unlock(&kvm->lock); + return ERR_PTR(r); +} + +static void tdx_release_vm_state_locks(struct kvm *kvm) +{ + mutex_unlock(&kvm->slots_lock); + kvm_unlock_all_vcpus(kvm); + mutex_unlock(&kvm->lock); +} + +DEFINE_CLASS(tdx_vm_state_guard, tdx_vm_state_guard_t, + if (!IS_ERR(_T)) tdx_release_vm_state_locks(_T), + tdx_acquire_vm_state_locks(kvm), struct kvm *kvm); + static int tdx_td_init(struct kvm *kvm, struct kvm_tdx_cmd *cmd) { + struct kvm_tdx_init_vm __user *user_data = u64_to_user_ptr(cmd->data); struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); struct kvm_tdx_init_vm *init_vm; struct td_params *td_params = NULL; + u32 nr_user_entries; int ret; BUILD_BUG_ON(sizeof(*init_vm) != 256 + sizeof_field(struct kvm_tdx_init_vm, cpuid)); @@ -2763,28 +2722,16 @@ static int tdx_td_init(struct kvm *kvm, struct kvm_tdx_cmd *cmd) if (cmd->flags) return -EINVAL; - init_vm = kmalloc(sizeof(*init_vm) + - sizeof(init_vm->cpuid.entries[0]) * KVM_MAX_CPUID_ENTRIES, - GFP_KERNEL); - if (!init_vm) - return -ENOMEM; - - if (copy_from_user(init_vm, u64_to_user_ptr(cmd->data), sizeof(*init_vm))) { - ret = -EFAULT; - goto out; - } + if (get_user(nr_user_entries, &user_data->cpuid.nent)) + return -EFAULT; - if (init_vm->cpuid.nent > KVM_MAX_CPUID_ENTRIES) { - ret = -E2BIG; - goto out; - } + if (nr_user_entries > KVM_MAX_CPUID_ENTRIES) + return -E2BIG; - if (copy_from_user(init_vm->cpuid.entries, - u64_to_user_ptr(cmd->data) + sizeof(*init_vm), - flex_array_size(init_vm, cpuid.entries, init_vm->cpuid.nent))) { - ret = -EFAULT; - goto out; - } + init_vm = memdup_user(user_data, + struct_size(user_data, cpuid.entries, nr_user_entries)); + if (IS_ERR(init_vm)) + return PTR_ERR(init_vm); if (memchr_inv(init_vm->reserved, 0, sizeof(init_vm->reserved))) { ret = -EINVAL; @@ -2868,24 +2815,14 @@ static int tdx_td_finalize(struct kvm *kvm, struct kvm_tdx_cmd *cmd) { struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); - guard(mutex)(&kvm->slots_lock); - if (!is_hkid_assigned(kvm_tdx) || kvm_tdx->state == TD_STATE_RUNNABLE) return -EINVAL; - /* - * Pages are pending for KVM_TDX_INIT_MEM_REGION to issue - * TDH.MEM.PAGE.ADD(). - */ - if (atomic64_read(&kvm_tdx->nr_premapped)) - return -EINVAL; cmd->hw_error = tdh_mr_finalize(&kvm_tdx->td); if (tdx_operand_busy(cmd->hw_error)) return -EBUSY; - if (KVM_BUG_ON(cmd->hw_error, kvm)) { - pr_tdx_error(TDH_MR_FINALIZE, cmd->hw_error); + if (TDX_BUG_ON(cmd->hw_error, TDH_MR_FINALIZE, kvm)) return -EIO; - } kvm_tdx->state = TD_STATE_RUNNABLE; /* TD_STATE_RUNNABLE must be set before 'pre_fault_allowed' */ @@ -2894,27 +2831,38 @@ static int tdx_td_finalize(struct kvm *kvm, struct kvm_tdx_cmd *cmd) return 0; } -int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) +static int tdx_get_cmd(void __user *argp, struct kvm_tdx_cmd *cmd) { - struct kvm_tdx_cmd tdx_cmd; - int r; - - if (copy_from_user(&tdx_cmd, argp, sizeof(struct kvm_tdx_cmd))) + if (copy_from_user(cmd, argp, sizeof(*cmd))) return -EFAULT; /* - * Userspace should never set hw_error. It is used to fill - * hardware-defined error by the kernel. + * Userspace should never set hw_error. KVM writes hw_error to report + * hardware-defined error back to userspace. */ - if (tdx_cmd.hw_error) + if (cmd->hw_error) return -EINVAL; - mutex_lock(&kvm->lock); + return 0; +} + +int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) +{ + struct kvm_tdx_cmd tdx_cmd; + int r; + + r = tdx_get_cmd(argp, &tdx_cmd); + if (r) + return r; + + if (tdx_cmd.id == KVM_TDX_CAPABILITIES) + return tdx_get_capabilities(&tdx_cmd); + + CLASS(tdx_vm_state_guard, guard)(kvm); + if (IS_ERR(guard)) + return PTR_ERR(guard); switch (tdx_cmd.id) { - case KVM_TDX_CAPABILITIES: - r = tdx_get_capabilities(&tdx_cmd); - break; case KVM_TDX_INIT_VM: r = tdx_td_init(kvm, &tdx_cmd); break; @@ -2922,15 +2870,12 @@ int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) r = tdx_td_finalize(kvm, &tdx_cmd); break; default: - r = -EINVAL; - goto out; + return -EINVAL; } if (copy_to_user(argp, &tdx_cmd, sizeof(struct kvm_tdx_cmd))) - r = -EFAULT; + return -EFAULT; -out: - mutex_unlock(&kvm->lock); return r; } @@ -2972,16 +2917,14 @@ static int tdx_td_vcpu_init(struct kvm_vcpu *vcpu, u64 vcpu_rcx) } err = tdh_vp_create(&kvm_tdx->td, &tdx->vp); - if (KVM_BUG_ON(err, vcpu->kvm)) { + if (TDX_BUG_ON(err, TDH_VP_CREATE, vcpu->kvm)) { ret = -EIO; - pr_tdx_error(TDH_VP_CREATE, err); goto free_tdcx; } for (i = 0; i < kvm_tdx->td.tdcx_nr_pages; i++) { err = tdh_vp_addcx(&tdx->vp, tdx->vp.tdcx_pages[i]); - if (KVM_BUG_ON(err, vcpu->kvm)) { - pr_tdx_error(TDH_VP_ADDCX, err); + if (TDX_BUG_ON(err, TDH_VP_ADDCX, vcpu->kvm)) { /* * Pages already added are reclaimed by the vcpu_free * method, but the rest are freed here. @@ -2994,10 +2937,19 @@ static int tdx_td_vcpu_init(struct kvm_vcpu *vcpu, u64 vcpu_rcx) } } - err = tdh_vp_init(&tdx->vp, vcpu_rcx, vcpu->vcpu_id); - if (KVM_BUG_ON(err, vcpu->kvm)) { - pr_tdx_error(TDH_VP_INIT, err); - return -EIO; + /* + * tdh_vp_init() can take an exclusive lock of the TDR resource inside + * the TDX-Module. The TDR resource is also taken as shared in several + * no-fail MMU paths, which could return TDX_OPERAND_BUSY on contention + * (TDX-Module locks are try-lock implementations with no slow path). + * Take mmu_lock for write to reflect the nature of the lock taken by + * the TDX-Module, and to ensure the no-fail MMU paths succeed, e.g. if + * a concurrent PUNCH_HOLE on guest_memfd triggers removal of SPTEs. + */ + scoped_guard(write_lock, &vcpu->kvm->mmu_lock) { + err = tdh_vp_init(&tdx->vp, vcpu_rcx, vcpu->vcpu_id); + if (TDX_BUG_ON(err, TDH_VP_INIT, vcpu->kvm)) + return -EIO; } vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; @@ -3016,7 +2968,7 @@ static int tdx_td_vcpu_init(struct kvm_vcpu *vcpu, u64 vcpu_rcx) free_tdvpr: if (tdx->vp.tdvpr_page) __free_page(tdx->vp.tdvpr_page); - tdx->vp.tdvpr_page = 0; + tdx->vp.tdvpr_page = NULL; tdx->vp.tdvpr_pa = 0; return ret; @@ -3054,7 +3006,8 @@ static int tdx_vcpu_get_cpuid_leaf(struct kvm_vcpu *vcpu, u32 leaf, int *entry_i static int tdx_vcpu_get_cpuid(struct kvm_vcpu *vcpu, struct kvm_tdx_cmd *cmd) { - struct kvm_cpuid2 __user *output, *td_cpuid; + struct kvm_cpuid2 __user *output; + struct kvm_cpuid2 *td_cpuid; int r = 0, i = 0, leaf; u32 level; @@ -3167,15 +3120,15 @@ struct tdx_gmem_post_populate_arg { static int tdx_gmem_post_populate(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, void __user *src, int order, void *_arg) { - u64 error_code = PFERR_GUEST_FINAL_MASK | PFERR_PRIVATE_ACCESS; - struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); struct tdx_gmem_post_populate_arg *arg = _arg; - struct kvm_vcpu *vcpu = arg->vcpu; + struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); + u64 err, entry, level_state; gpa_t gpa = gfn_to_gpa(gfn); - u8 level = PG_LEVEL_4K; struct page *src_page; int ret, i; - u64 err, entry, level_state; + + if (KVM_BUG_ON(kvm_tdx->page_add_src, kvm)) + return -EIO; /* * Get the source page if it has been faulted in. Return failure if the @@ -3187,49 +3140,29 @@ static int tdx_gmem_post_populate(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, if (ret != 1) return -ENOMEM; - ret = kvm_tdp_map_page(vcpu, gpa, error_code, &level); - if (ret < 0) - goto out; - - /* - * The private mem cannot be zapped after kvm_tdp_map_page() - * because all paths are covered by slots_lock and the - * filemap invalidate lock. Check that they are indeed enough. - */ - if (IS_ENABLED(CONFIG_KVM_PROVE_MMU)) { - scoped_guard(read_lock, &kvm->mmu_lock) { - if (KVM_BUG_ON(!kvm_tdp_mmu_gpa_is_mapped(vcpu, gpa), kvm)) { - ret = -EIO; - goto out; - } - } - } + kvm_tdx->page_add_src = src_page; + ret = kvm_tdp_mmu_map_private_pfn(arg->vcpu, gfn, pfn); + kvm_tdx->page_add_src = NULL; - ret = 0; - err = tdh_mem_page_add(&kvm_tdx->td, gpa, pfn_to_page(pfn), - src_page, &entry, &level_state); - if (err) { - ret = unlikely(tdx_operand_busy(err)) ? -EBUSY : -EIO; - goto out; - } + put_page(src_page); - if (!KVM_BUG_ON(!atomic64_read(&kvm_tdx->nr_premapped), kvm)) - atomic64_dec(&kvm_tdx->nr_premapped); + if (ret || !(arg->flags & KVM_TDX_MEASURE_MEMORY_REGION)) + return ret; - if (arg->flags & KVM_TDX_MEASURE_MEMORY_REGION) { - for (i = 0; i < PAGE_SIZE; i += TDX_EXTENDMR_CHUNKSIZE) { - err = tdh_mr_extend(&kvm_tdx->td, gpa + i, &entry, - &level_state); - if (err) { - ret = -EIO; - break; - } - } + /* + * Note, MR.EXTEND can fail if the S-EPT mapping is somehow removed + * between mapping the pfn and now, but slots_lock prevents memslot + * updates, filemap_invalidate_lock() prevents guest_memfd updates, + * mmu_notifier events can't reach S-EPT entries, and KVM's internal + * zapping flows are mutually exclusive with S-EPT mappings. + */ + for (i = 0; i < PAGE_SIZE; i += TDX_EXTENDMR_CHUNKSIZE) { + err = tdh_mr_extend(&kvm_tdx->td, gpa + i, &entry, &level_state); + if (TDX_BUG_ON_2(err, TDH_MR_EXTEND, entry, level_state, kvm)) + return -EIO; } -out: - put_page(src_page); - return ret; + return 0; } static int tdx_vcpu_init_mem_region(struct kvm_vcpu *vcpu, struct kvm_tdx_cmd *cmd) @@ -3245,8 +3178,6 @@ static int tdx_vcpu_init_mem_region(struct kvm_vcpu *vcpu, struct kvm_tdx_cmd *c if (tdx->state != VCPU_TD_STATE_INITIALIZED) return -EINVAL; - guard(mutex)(&kvm->slots_lock); - /* Once TD is finalized, the initial guest memory is fixed. */ if (kvm_tdx->state == TD_STATE_RUNNABLE) return -EINVAL; @@ -3264,7 +3195,6 @@ static int tdx_vcpu_init_mem_region(struct kvm_vcpu *vcpu, struct kvm_tdx_cmd *c !vt_is_tdx_private_gpa(kvm, region.gpa + (region.nr_pages << PAGE_SHIFT) - 1)) return -EINVAL; - kvm_mmu_reload(vcpu); ret = 0; while (region.nr_pages) { if (signal_pending(current)) { @@ -3301,28 +3231,57 @@ static int tdx_vcpu_init_mem_region(struct kvm_vcpu *vcpu, struct kvm_tdx_cmd *c return ret; } -int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) +int tdx_vcpu_unlocked_ioctl(struct kvm_vcpu *vcpu, void __user *argp) { - struct kvm_tdx *kvm_tdx = to_kvm_tdx(vcpu->kvm); + struct kvm *kvm = vcpu->kvm; + struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); struct kvm_tdx_cmd cmd; - int ret; + int r; - if (!is_hkid_assigned(kvm_tdx) || kvm_tdx->state == TD_STATE_RUNNABLE) - return -EINVAL; + r = tdx_get_cmd(argp, &cmd); + if (r) + return r; - if (copy_from_user(&cmd, argp, sizeof(cmd))) - return -EFAULT; + CLASS(tdx_vm_state_guard, guard)(kvm); + if (IS_ERR(guard)) + return PTR_ERR(guard); - if (cmd.hw_error) + if (!is_hkid_assigned(kvm_tdx) || kvm_tdx->state == TD_STATE_RUNNABLE) return -EINVAL; + vcpu_load(vcpu); + switch (cmd.id) { + case KVM_TDX_INIT_MEM_REGION: + r = tdx_vcpu_init_mem_region(vcpu, &cmd); + break; case KVM_TDX_INIT_VCPU: - ret = tdx_vcpu_init(vcpu, &cmd); + r = tdx_vcpu_init(vcpu, &cmd); break; - case KVM_TDX_INIT_MEM_REGION: - ret = tdx_vcpu_init_mem_region(vcpu, &cmd); + default: + r = -ENOIOCTLCMD; break; + } + + vcpu_put(vcpu); + + return r; +} + +int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) +{ + struct kvm_tdx *kvm_tdx = to_kvm_tdx(vcpu->kvm); + struct kvm_tdx_cmd cmd; + int ret; + + if (!is_hkid_assigned(kvm_tdx) || kvm_tdx->state == TD_STATE_RUNNABLE) + return -EINVAL; + + ret = tdx_get_cmd(argp, &cmd); + if (ret) + return ret; + + switch (cmd.id) { case KVM_TDX_GET_CPUID: ret = tdx_vcpu_get_cpuid(vcpu, &cmd); break; @@ -3447,10 +3406,6 @@ static int __init __tdx_bringup(void) /* * Check if MSRs (tdx_uret_msrs) can be saved/restored * before returning to user space. - * - * this_cpu_ptr(user_return_msrs)->registered isn't checked - * because the registration is done at vcpu runtime by - * tdx_user_return_msr_update_cache(). */ tdx_uret_msrs[i].slot = kvm_find_user_return_msr(tdx_uret_msrs[i].msr); if (tdx_uret_msrs[i].slot == -1) { diff --git a/arch/x86/kvm/vmx/tdx.h b/arch/x86/kvm/vmx/tdx.h index ca39a9391db1e..45b5183ccb36c 100644 --- a/arch/x86/kvm/vmx/tdx.h +++ b/arch/x86/kvm/vmx/tdx.h @@ -36,8 +36,12 @@ struct kvm_tdx { struct tdx_td td; - /* For KVM_TDX_INIT_MEM_REGION. */ - atomic64_t nr_premapped; + /* + * Scratch pointer used to pass the source page to tdx_mem_page_add(). + * Protected by slots_lock, and non-NULL only when mapping a private + * pfn via tdx_gmem_post_populate(). + */ + struct page *page_add_src; /* * Prevent vCPUs from TD entry to ensure SEPT zap related SEAMCALLs do @@ -67,7 +71,6 @@ struct vcpu_tdx { u64 vp_enter_ret; enum vcpu_tdx_state state; - bool guest_entered; u64 map_gpa_next; u64 map_gpa_end; diff --git a/arch/x86/kvm/vmx/vmenter.S b/arch/x86/kvm/vmx/vmenter.S index bc255d709d8a1..4426d34811fce 100644 --- a/arch/x86/kvm/vmx/vmenter.S +++ b/arch/x86/kvm/vmx/vmenter.S @@ -71,6 +71,7 @@ * @regs: unsigned long * (to guest registers) * @flags: VMX_RUN_VMRESUME: use VMRESUME instead of VMLAUNCH * VMX_RUN_SAVE_SPEC_CTRL: save guest SPEC_CTRL into vmx->spec_ctrl + * VMX_RUN_CLEAR_CPU_BUFFERS_FOR_MMIO: vCPU can access host MMIO * * Returns: * 0 on VM-Exit, 1 on VM-Fail @@ -92,7 +93,7 @@ SYM_FUNC_START(__vmx_vcpu_run) /* Save @vmx for SPEC_CTRL handling */ push %_ASM_ARG1 - /* Save @flags for SPEC_CTRL handling */ + /* Save @flags (used for VMLAUNCH vs. VMRESUME and mitigations). */ push %_ASM_ARG3 /* @@ -101,9 +102,6 @@ SYM_FUNC_START(__vmx_vcpu_run) */ push %_ASM_ARG2 - /* Copy @flags to EBX, _ASM_ARG3 is volatile. */ - mov %_ASM_ARG3L, %ebx - lea (%_ASM_SP), %_ASM_ARG2 call vmx_update_host_rsp @@ -118,13 +116,23 @@ SYM_FUNC_START(__vmx_vcpu_run) * and vmentry. */ mov 2*WORD_SIZE(%_ASM_SP), %_ASM_DI - movl VMX_spec_ctrl(%_ASM_DI), %edi - movl PER_CPU_VAR(x86_spec_ctrl_current), %esi - cmp %edi, %esi +#ifdef CONFIG_X86_64 + mov VMX_spec_ctrl(%rdi), %rdx + cmp PER_CPU_VAR(x86_spec_ctrl_current), %rdx je .Lspec_ctrl_done + movl %edx, %eax + shr $32, %rdx +#else + mov VMX_spec_ctrl(%edi), %eax + mov PER_CPU_VAR(x86_spec_ctrl_current), %ecx + xor %eax, %ecx + mov VMX_spec_ctrl + 4(%edi), %edx + mov PER_CPU_VAR(x86_spec_ctrl_current + 4), %edi + xor %edx, %edi + or %edi, %ecx + je .Lspec_ctrl_done +#endif mov $MSR_IA32_SPEC_CTRL, %ecx - xor %edx, %edx - mov %edi, %eax wrmsr .Lspec_ctrl_done: @@ -137,9 +145,6 @@ SYM_FUNC_START(__vmx_vcpu_run) /* Load @regs to RAX. */ mov (%_ASM_SP), %_ASM_AX - /* Check if vmlaunch or vmresume is needed */ - bt $VMX_RUN_VMRESUME_SHIFT, %ebx - /* Load guest registers. Don't clobber flags. */ mov VCPU_RCX(%_ASM_AX), %_ASM_CX mov VCPU_RDX(%_ASM_AX), %_ASM_DX @@ -160,11 +165,23 @@ SYM_FUNC_START(__vmx_vcpu_run) /* Load guest RAX. This kills the @regs pointer! */ mov VCPU_RAX(%_ASM_AX), %_ASM_AX - /* Clobbers EFLAGS.ZF */ - CLEAR_CPU_BUFFERS - - /* Check EFLAGS.CF from the VMX_RUN_VMRESUME bit test above. */ - jnc .Lvmlaunch + /* + * Note, ALTERNATIVE_2 works in reverse order. If CLEAR_CPU_BUF_VM is + * enabled, do VERW unconditionally. If CPU_BUF_VM_MMIO is enabled, + * check @flags to see if the vCPU has access to host MMIO, and if so, + * do VERW. Else, do nothing (no mitigations needed/enabled). + */ + ALTERNATIVE_2 "", \ + __stringify(testl $VMX_RUN_CLEAR_CPU_BUFFERS_FOR_MMIO, WORD_SIZE(%_ASM_SP); \ + jz .Lskip_mmio_verw; \ + VERW; \ + .Lskip_mmio_verw:), \ + X86_FEATURE_CLEAR_CPU_BUF_VM_MMIO, \ + __stringify(VERW), X86_FEATURE_CLEAR_CPU_BUF_VM + + /* Check @flags to see if VMLAUNCH or VMRESUME is needed. */ + testl $VMX_RUN_VMRESUME, WORD_SIZE(%_ASM_SP) + jz .Lvmlaunch /* * After a successful VMRESUME/VMLAUNCH, control flow "magically" diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 91b6f2f3edc2a..6b96f7aea20bd 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -203,6 +203,7 @@ module_param(pt_mode, int, S_IRUGO); struct x86_pmu_lbr __ro_after_init vmx_lbr_caps; +#ifdef CONFIG_CPU_MITIGATIONS static DEFINE_STATIC_KEY_FALSE(vmx_l1d_should_flush); static DEFINE_STATIC_KEY_FALSE(vmx_l1d_flush_cond); static DEFINE_MUTEX(vmx_l1d_flush_mutex); @@ -225,7 +226,7 @@ static const struct { #define L1D_CACHE_ORDER 4 static void *vmx_l1d_flush_pages; -static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf) +static int __vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf) { struct page *page; unsigned int i; @@ -302,6 +303,26 @@ static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf) return 0; } +static int vmx_setup_l1d_flush(void) +{ + /* + * Hand the parameter mitigation value in which was stored in the pre + * module init parser. If no parameter was given, it will contain + * 'auto' which will be turned into the default 'cond' mitigation mode. + */ + return __vmx_setup_l1d_flush(vmentry_l1d_flush_param); +} + +static void vmx_cleanup_l1d_flush(void) +{ + if (vmx_l1d_flush_pages) { + free_pages((unsigned long)vmx_l1d_flush_pages, L1D_CACHE_ORDER); + vmx_l1d_flush_pages = NULL; + } + /* Restore state so sysfs ignores VMX */ + l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO; +} + static int vmentry_l1d_flush_parse(const char *s) { unsigned int i; @@ -339,7 +360,7 @@ static int vmentry_l1d_flush_set(const char *s, const struct kernel_param *kp) } mutex_lock(&vmx_l1d_flush_mutex); - ret = vmx_setup_l1d_flush(l1tf); + ret = __vmx_setup_l1d_flush(l1tf); mutex_unlock(&vmx_l1d_flush_mutex); return ret; } @@ -352,6 +373,101 @@ static int vmentry_l1d_flush_get(char *s, const struct kernel_param *kp) return sysfs_emit(s, "%s\n", vmentry_l1d_param[l1tf_vmx_mitigation].option); } +/* + * Software based L1D cache flush which is used when microcode providing + * the cache control MSR is not loaded. + * + * The L1D cache is 32 KiB on Nehalem and later microarchitectures, but to + * flush it is required to read in 64 KiB because the replacement algorithm + * is not exactly LRU. This could be sized at runtime via topology + * information but as all relevant affected CPUs have 32KiB L1D cache size + * there is no point in doing so. + */ +static noinstr void vmx_l1d_flush(struct kvm_vcpu *vcpu) +{ + int size = PAGE_SIZE << L1D_CACHE_ORDER; + + if (!static_branch_unlikely(&vmx_l1d_should_flush)) + return; + + /* + * This code is only executed when the flush mode is 'cond' or + * 'always' + */ + if (static_branch_likely(&vmx_l1d_flush_cond)) { + /* + * Clear the per-cpu flush bit, it gets set again if the vCPU + * is reloaded, i.e. if the vCPU is scheduled out or if KVM + * exits to userspace, or if KVM reaches one of the unsafe + * VMEXIT handlers, e.g. if KVM calls into the emulator, + * or from the interrupt handlers. + */ + if (!kvm_get_cpu_l1tf_flush_l1d()) + return; + kvm_clear_cpu_l1tf_flush_l1d(); + } + + vcpu->stat.l1d_flush++; + + if (static_cpu_has(X86_FEATURE_FLUSH_L1D)) { + native_wrmsrq(MSR_IA32_FLUSH_CMD, L1D_FLUSH); + return; + } + + asm volatile( + /* First ensure the pages are in the TLB */ + "xorl %%eax, %%eax\n" + ".Lpopulate_tlb:\n\t" + "movzbl (%[flush_pages], %%" _ASM_AX "), %%ecx\n\t" + "addl $4096, %%eax\n\t" + "cmpl %%eax, %[size]\n\t" + "jne .Lpopulate_tlb\n\t" + "xorl %%eax, %%eax\n\t" + "cpuid\n\t" + /* Now fill the cache */ + "xorl %%eax, %%eax\n" + ".Lfill_cache:\n" + "movzbl (%[flush_pages], %%" _ASM_AX "), %%ecx\n\t" + "addl $64, %%eax\n\t" + "cmpl %%eax, %[size]\n\t" + "jne .Lfill_cache\n\t" + "lfence\n" + :: [flush_pages] "r" (vmx_l1d_flush_pages), + [size] "r" (size) + : "eax", "ebx", "ecx", "edx"); +} + +#else /* CONFIG_CPU_MITIGATIONS*/ +static int vmx_setup_l1d_flush(void) +{ + l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_NEVER; + return 0; +} +static void vmx_cleanup_l1d_flush(void) +{ + l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO; +} +static __always_inline void vmx_l1d_flush(struct kvm_vcpu *vcpu) +{ + +} +static int vmentry_l1d_flush_set(const char *s, const struct kernel_param *kp) +{ + pr_warn_once("Kernel compiled without mitigations, ignoring vmentry_l1d_flush\n"); + return 0; +} +static int vmentry_l1d_flush_get(char *s, const struct kernel_param *kp) +{ + return sysfs_emit(s, "never\n"); +} +#endif + +static const struct kernel_param_ops vmentry_l1d_flush_ops = { + .set = vmentry_l1d_flush_set, + .get = vmentry_l1d_flush_get, +}; +module_param_cb(vmentry_l1d_flush, &vmentry_l1d_flush_ops, NULL, 0644); + static __always_inline void vmx_disable_fb_clear(struct vcpu_vmx *vmx) { u64 msr; @@ -404,12 +520,6 @@ static void vmx_update_fb_clear_dis(struct kvm_vcpu *vcpu, struct vcpu_vmx *vmx) vmx->disable_fb_clear = false; } -static const struct kernel_param_ops vmentry_l1d_flush_ops = { - .set = vmentry_l1d_flush_set, - .get = vmentry_l1d_flush_get, -}; -module_param_cb(vmentry_l1d_flush, &vmentry_l1d_flush_ops, NULL, 0644); - static u32 vmx_segment_access_rights(struct kvm_segment *var); void vmx_vmexit(void); @@ -752,7 +862,7 @@ static void __loaded_vmcs_clear(void *arg) loaded_vmcs->launched = 0; } -void loaded_vmcs_clear(struct loaded_vmcs *loaded_vmcs) +static void loaded_vmcs_clear(struct loaded_vmcs *loaded_vmcs) { int cpu = loaded_vmcs->cpu; @@ -903,7 +1013,7 @@ unsigned int __vmx_vcpu_run_flags(struct vcpu_vmx *vmx) if (!msr_write_intercepted(vmx, MSR_IA32_SPEC_CTRL)) flags |= VMX_RUN_SAVE_SPEC_CTRL; - if (static_branch_unlikely(&cpu_buf_vm_clear) && + if (cpu_feature_enabled(X86_FEATURE_CLEAR_CPU_BUF_VM_MMIO) && kvm_vcpu_can_access_host_mmio(&vmx->vcpu)) flags |= VMX_RUN_CLEAR_CPU_BUFFERS_FOR_MMIO; @@ -3219,6 +3329,40 @@ static inline int vmx_get_current_vpid(struct kvm_vcpu *vcpu) return to_vmx(vcpu)->vpid; } +static u64 construct_eptp(hpa_t root_hpa) +{ + u64 eptp = root_hpa | VMX_EPTP_MT_WB; + struct kvm_mmu_page *root; + + if (kvm_mmu_is_dummy_root(root_hpa)) + return eptp | VMX_EPTP_PWL_4; + + /* + * EPT roots should always have an associated MMU page. Return a "bad" + * EPTP to induce VM-Fail instead of continuing on in a unknown state. + */ + root = root_to_sp(root_hpa); + if (WARN_ON_ONCE(!root)) + return INVALID_PAGE; + + eptp |= (root->role.level == 5) ? VMX_EPTP_PWL_5 : VMX_EPTP_PWL_4; + + if (enable_ept_ad_bits && !root->role.ad_disabled) + eptp |= VMX_EPTP_AD_ENABLE_BIT; + + return eptp; +} + +static void vmx_flush_tlb_ept_root(hpa_t root_hpa) +{ + u64 eptp = construct_eptp(root_hpa); + + if (VALID_PAGE(eptp)) + ept_sync_context(eptp); + else + ept_sync_global(); +} + void vmx_flush_tlb_current(struct kvm_vcpu *vcpu) { struct kvm_mmu *mmu = vcpu->arch.mmu; @@ -3229,8 +3373,7 @@ void vmx_flush_tlb_current(struct kvm_vcpu *vcpu) return; if (enable_ept) - ept_sync_context(construct_eptp(vcpu, root_hpa, - mmu->root_role.level)); + vmx_flush_tlb_ept_root(root_hpa); else vpid_sync_context(vmx_get_current_vpid(vcpu)); } @@ -3396,30 +3539,16 @@ static int vmx_get_max_ept_level(void) return 4; } -u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level) -{ - u64 eptp = VMX_EPTP_MT_WB; - - eptp |= (root_level == 5) ? VMX_EPTP_PWL_5 : VMX_EPTP_PWL_4; - - if (enable_ept_ad_bits && - (!is_guest_mode(vcpu) || nested_ept_ad_enabled(vcpu))) - eptp |= VMX_EPTP_AD_ENABLE_BIT; - eptp |= root_hpa; - - return eptp; -} - void vmx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level) { struct kvm *kvm = vcpu->kvm; bool update_guest_cr3 = true; unsigned long guest_cr3; - u64 eptp; if (enable_ept) { - eptp = construct_eptp(vcpu, root_hpa, root_level); - vmcs_write64(EPT_POINTER, eptp); + KVM_MMU_WARN_ON(root_to_sp(root_hpa) && + root_level != root_to_sp(root_hpa)->role.level); + vmcs_write64(EPT_POINTER, construct_eptp(root_hpa)); hv_track_root_tdp(vcpu, root_hpa); @@ -6631,15 +6760,8 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) return kvm_vmx_exit_handlers[exit_handler_index](vcpu); unexpected_vmexit: - vcpu_unimpl(vcpu, "vmx: unexpected exit reason 0x%x\n", - exit_reason.full); dump_vmcs(vcpu); - vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; - vcpu->run->internal.suberror = - KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON; - vcpu->run->internal.ndata = 2; - vcpu->run->internal.data[0] = exit_reason.full; - vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu; + kvm_prepare_unexpected_reason_exit(vcpu, exit_reason.full); return 0; } @@ -6661,77 +6783,6 @@ int vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) return ret; } -/* - * Software based L1D cache flush which is used when microcode providing - * the cache control MSR is not loaded. - * - * The L1D cache is 32 KiB on Nehalem and later microarchitectures, but to - * flush it is required to read in 64 KiB because the replacement algorithm - * is not exactly LRU. This could be sized at runtime via topology - * information but as all relevant affected CPUs have 32KiB L1D cache size - * there is no point in doing so. - */ -static noinstr void vmx_l1d_flush(struct kvm_vcpu *vcpu) -{ - int size = PAGE_SIZE << L1D_CACHE_ORDER; - - /* - * This code is only executed when the flush mode is 'cond' or - * 'always' - */ - if (static_branch_likely(&vmx_l1d_flush_cond)) { - bool flush_l1d; - - /* - * Clear the per-vcpu flush bit, it gets set again if the vCPU - * is reloaded, i.e. if the vCPU is scheduled out or if KVM - * exits to userspace, or if KVM reaches one of the unsafe - * VMEXIT handlers, e.g. if KVM calls into the emulator. - */ - flush_l1d = vcpu->arch.l1tf_flush_l1d; - vcpu->arch.l1tf_flush_l1d = false; - - /* - * Clear the per-cpu flush bit, it gets set again from - * the interrupt handlers. - */ - flush_l1d |= kvm_get_cpu_l1tf_flush_l1d(); - kvm_clear_cpu_l1tf_flush_l1d(); - - if (!flush_l1d) - return; - } - - vcpu->stat.l1d_flush++; - - if (static_cpu_has(X86_FEATURE_FLUSH_L1D)) { - native_wrmsrq(MSR_IA32_FLUSH_CMD, L1D_FLUSH); - return; - } - - asm volatile( - /* First ensure the pages are in the TLB */ - "xorl %%eax, %%eax\n" - ".Lpopulate_tlb:\n\t" - "movzbl (%[flush_pages], %%" _ASM_AX "), %%ecx\n\t" - "addl $4096, %%eax\n\t" - "cmpl %%eax, %[size]\n\t" - "jne .Lpopulate_tlb\n\t" - "xorl %%eax, %%eax\n\t" - "cpuid\n\t" - /* Now fill the cache */ - "xorl %%eax, %%eax\n" - ".Lfill_cache:\n" - "movzbl (%[flush_pages], %%" _ASM_AX "), %%ecx\n\t" - "addl $64, %%eax\n\t" - "cmpl %%eax, %[size]\n\t" - "jne .Lfill_cache\n\t" - "lfence\n" - :: [flush_pages] "r" (vmx_l1d_flush_pages), - [size] "r" (size) - : "eax", "ebx", "ecx", "edx"); -} - void vmx_update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) { struct vmcs12 *vmcs12 = get_vmcs12(vcpu); @@ -6886,15 +6937,6 @@ void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr) * VM-Exit, otherwise L1 with run with a stale SVI. */ if (is_guest_mode(vcpu)) { - /* - * KVM is supposed to forward intercepted L2 EOIs to L1 if VID - * is enabled in vmcs12; as above, the EOIs affect L2's vAPIC. - * Note, userspace can stuff state while L2 is active; assert - * that VID is disabled if and only if the vCPU is in KVM_RUN - * to avoid false positives if userspace is setting APIC state. - */ - WARN_ON_ONCE(vcpu->wants_to_run && - nested_cpu_has_vid(get_vmcs12(vcpu))); to_vmx(vcpu)->nested.update_vmcs01_hwapic_isr = true; return; } @@ -7050,10 +7092,19 @@ void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu) if (to_vt(vcpu)->emulation_required) return; - if (vmx_get_exit_reason(vcpu).basic == EXIT_REASON_EXTERNAL_INTERRUPT) + switch (vmx_get_exit_reason(vcpu).basic) { + case EXIT_REASON_EXTERNAL_INTERRUPT: handle_external_interrupt_irqoff(vcpu, vmx_get_intr_info(vcpu)); - else if (vmx_get_exit_reason(vcpu).basic == EXIT_REASON_EXCEPTION_NMI) + break; + case EXIT_REASON_EXCEPTION_NMI: handle_exception_irqoff(vcpu, vmx_get_intr_info(vcpu)); + break; + case EXIT_REASON_MCE_DURING_VMENTRY: + kvm_machine_check(); + break; + default: + break; + } } /* @@ -7328,21 +7379,7 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu, guest_state_enter_irqoff(); - /* - * L1D Flush includes CPU buffer clear to mitigate MDS, but VERW - * mitigation for MDS is done late in VMentry and is still - * executed in spite of L1D Flush. This is because an extra VERW - * should not matter much after the big hammer L1D Flush. - * - * cpu_buf_vm_clear is used when system is not vulnerable to MDS/TAA, - * and is affected by MMIO Stale Data. In such cases mitigation in only - * needed against an MMIO capable guest. - */ - if (static_branch_unlikely(&vmx_l1d_should_flush)) - vmx_l1d_flush(vcpu); - else if (static_branch_unlikely(&cpu_buf_vm_clear) && - (flags & VMX_RUN_CLEAR_CPU_BUFFERS_FOR_MMIO)) - x86_clear_cpu_buffers(); + vmx_l1d_flush(vcpu); vmx_disable_fb_clear(vmx); @@ -7454,8 +7491,6 @@ fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) vmx_set_interrupt_shadow(vcpu, 0); - kvm_load_guest_xsave_state(vcpu); - pt_guest_enter(vmx); atomic_switch_perf_msrs(vmx); @@ -7499,8 +7534,6 @@ fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) pt_guest_exit(vmx); - kvm_load_host_xsave_state(vcpu); - if (is_guest_mode(vcpu)) { /* * Track VMLAUNCH/VMRESUME that have made past guest state @@ -7516,9 +7549,6 @@ fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) if (unlikely(vmx->fail)) return EXIT_FASTPATH_NONE; - if (unlikely((u16)vmx_get_exit_reason(vcpu).basic == EXIT_REASON_MCE_DURING_VMENTRY)) - kvm_machine_check(); - trace_kvm_exit(vcpu, KVM_ISA_VMX); if (unlikely(vmx_get_exit_reason(vcpu).failed_vmentry)) @@ -8679,16 +8709,6 @@ __init int vmx_hardware_setup(void) return r; } -static void vmx_cleanup_l1d_flush(void) -{ - if (vmx_l1d_flush_pages) { - free_pages((unsigned long)vmx_l1d_flush_pages, L1D_CACHE_ORDER); - vmx_l1d_flush_pages = NULL; - } - /* Restore state so sysfs ignores VMX */ - l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO; -} - void vmx_exit(void) { allow_smaller_maxphyaddr = false; @@ -8724,14 +8744,8 @@ int __init vmx_init(void) if (r) return r; - /* - * Must be called after common x86 init so enable_ept is properly set - * up. Hand the parameter mitigation value in which was stored in - * the pre module init parser. If no parameter was given, it will - * contain 'auto' which will be turned into the default 'cond' - * mitigation mode. - */ - r = vmx_setup_l1d_flush(vmentry_l1d_flush_param); + /* Must be called after common x86 init so enable_ept is setup. */ + r = vmx_setup_l1d_flush(); if (r) goto err_l1d_flush; diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index ea93121029f91..bc3ed3145d7e8 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -369,7 +369,6 @@ void set_cr4_guest_host_mask(struct vcpu_vmx *vmx); void ept_save_pdptrs(struct kvm_vcpu *vcpu); void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); void __vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); -u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level); bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu); void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu); @@ -681,7 +680,6 @@ struct vmcs *alloc_vmcs_cpu(bool shadow, int cpu, gfp_t flags); void free_vmcs(struct vmcs *vmcs); int alloc_loaded_vmcs(struct loaded_vmcs *loaded_vmcs); void free_loaded_vmcs(struct loaded_vmcs *loaded_vmcs); -void loaded_vmcs_clear(struct loaded_vmcs *loaded_vmcs); static inline struct vmcs *alloc_vmcs(bool shadow) { diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h index 9697368d65b3a..d09abeac2b56a 100644 --- a/arch/x86/kvm/vmx/x86_ops.h +++ b/arch/x86/kvm/vmx/x86_ops.h @@ -73,7 +73,6 @@ void vmx_get_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt); void vmx_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt); void vmx_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt); void vmx_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt); -void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val); void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val); void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu); void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg); @@ -149,6 +148,7 @@ int tdx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr); int tdx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr); int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp); +int tdx_vcpu_unlocked_ioctl(struct kvm_vcpu *vcpu, void __user *argp); void tdx_flush_tlb_current(struct kvm_vcpu *vcpu); void tdx_flush_tlb_all(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c9c2aa6f4705e..ff8812f3a1293 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -159,9 +159,6 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(report_ignored_msrs); unsigned int min_timer_period_us = 200; module_param(min_timer_period_us, uint, 0644); -static bool __read_mostly kvmclock_periodic_sync = true; -module_param(kvmclock_periodic_sync, bool, 0444); - /* tsc tolerance in parts per million - default to 1/2 of the NTP threshold */ static u32 __read_mostly tsc_tolerance_ppm = 250; module_param(tsc_tolerance_ppm, uint, 0644); @@ -212,7 +209,7 @@ struct kvm_user_return_msrs { u32 __read_mostly kvm_nr_uret_msrs; EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_nr_uret_msrs); static u32 __read_mostly kvm_uret_msrs_list[KVM_MAX_NR_USER_RETURN_MSRS]; -static struct kvm_user_return_msrs __percpu *user_return_msrs; +static DEFINE_PER_CPU(struct kvm_user_return_msrs, user_return_msrs); #define KVM_SUPPORTED_XCR0 (XFEATURE_MASK_FP | XFEATURE_MASK_SSE \ | XFEATURE_MASK_YMM | XFEATURE_MASK_BNDREGS \ @@ -575,24 +572,26 @@ static inline void kvm_async_pf_hash_reset(struct kvm_vcpu *vcpu) vcpu->arch.apf.gfns[i] = ~0; } +static void kvm_destroy_user_return_msrs(void) +{ + int cpu; + + for_each_possible_cpu(cpu) + WARN_ON_ONCE(per_cpu(user_return_msrs, cpu).registered); + + kvm_nr_uret_msrs = 0; +} + static void kvm_on_user_return(struct user_return_notifier *urn) { unsigned slot; struct kvm_user_return_msrs *msrs = container_of(urn, struct kvm_user_return_msrs, urn); struct kvm_user_return_msr_values *values; - unsigned long flags; - /* - * Disabling irqs at this point since the following code could be - * interrupted and executed through kvm_arch_disable_virtualization_cpu() - */ - local_irq_save(flags); - if (msrs->registered) { - msrs->registered = false; - user_return_notifier_unregister(urn); - } - local_irq_restore(flags); + msrs->registered = false; + user_return_notifier_unregister(urn); + for (slot = 0; slot < kvm_nr_uret_msrs; ++slot) { values = &msrs->values[slot]; if (values->host != values->curr) { @@ -643,7 +642,7 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_find_user_return_msr); static void kvm_user_return_msr_cpu_online(void) { - struct kvm_user_return_msrs *msrs = this_cpu_ptr(user_return_msrs); + struct kvm_user_return_msrs *msrs = this_cpu_ptr(&user_return_msrs); u64 value; int i; @@ -665,7 +664,7 @@ static void kvm_user_return_register_notifier(struct kvm_user_return_msrs *msrs) int kvm_set_user_return_msr(unsigned slot, u64 value, u64 mask) { - struct kvm_user_return_msrs *msrs = this_cpu_ptr(user_return_msrs); + struct kvm_user_return_msrs *msrs = this_cpu_ptr(&user_return_msrs); int err; value = (value & mask) | (msrs->values[slot].host & ~mask); @@ -681,24 +680,15 @@ int kvm_set_user_return_msr(unsigned slot, u64 value, u64 mask) } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_set_user_return_msr); -void kvm_user_return_msr_update_cache(unsigned int slot, u64 value) -{ - struct kvm_user_return_msrs *msrs = this_cpu_ptr(user_return_msrs); - - msrs->values[slot].curr = value; - kvm_user_return_register_notifier(msrs); -} -EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_user_return_msr_update_cache); - u64 kvm_get_user_return_msr(unsigned int slot) { - return this_cpu_ptr(user_return_msrs)->values[slot].curr; + return this_cpu_ptr(&user_return_msrs)->values[slot].curr; } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_get_user_return_msr); static void drop_user_return_notifiers(void) { - struct kvm_user_return_msrs *msrs = this_cpu_ptr(user_return_msrs); + struct kvm_user_return_msrs *msrs = this_cpu_ptr(&user_return_msrs); if (msrs->registered) kvm_on_user_return(&msrs->urn); @@ -1045,6 +1035,13 @@ bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr) } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_require_dr); +static bool kvm_pv_async_pf_enabled(struct kvm_vcpu *vcpu) +{ + u64 mask = KVM_ASYNC_PF_ENABLED | KVM_ASYNC_PF_DELIVERY_AS_INT; + + return (vcpu->arch.apf.msr_en_val & mask) == mask; +} + static inline u64 pdptr_rsvd_bits(struct kvm_vcpu *vcpu) { return vcpu->arch.reserved_gpa_bits | rsvd_bits(5, 8) | rsvd_bits(1, 2); @@ -1137,15 +1134,20 @@ void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned lon } if ((cr0 ^ old_cr0) & X86_CR0_PG) { - kvm_clear_async_pf_completion_queue(vcpu); - kvm_async_pf_hash_reset(vcpu); - /* * Clearing CR0.PG is defined to flush the TLB from the guest's * perspective. */ if (!(cr0 & X86_CR0_PG)) kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); + /* + * Check for async #PF completion events when enabling paging, + * as the vCPU may have previously encountered async #PFs (it's + * entirely legal for the guest to toggle paging on/off without + * waiting for the async #PF queue to drain). + */ + else if (kvm_pv_async_pf_enabled(vcpu)) + kvm_make_request(KVM_REQ_APF_READY, vcpu); } if ((cr0 ^ old_cr0) & KVM_MMU_CR0_ROLE_BITS) @@ -1203,20 +1205,27 @@ void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_lmsw); -void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu) +static void kvm_load_xfeatures(struct kvm_vcpu *vcpu, bool load_guest) { if (vcpu->arch.guest_state_protected) return; - if (kvm_is_cr4_bit_set(vcpu, X86_CR4_OSXSAVE)) { + if (!kvm_is_cr4_bit_set(vcpu, X86_CR4_OSXSAVE)) + return; - if (vcpu->arch.xcr0 != kvm_host.xcr0) - xsetbv(XCR_XFEATURE_ENABLED_MASK, vcpu->arch.xcr0); + if (vcpu->arch.xcr0 != kvm_host.xcr0) + xsetbv(XCR_XFEATURE_ENABLED_MASK, + load_guest ? vcpu->arch.xcr0 : kvm_host.xcr0); - if (guest_cpu_cap_has(vcpu, X86_FEATURE_XSAVES) && - vcpu->arch.ia32_xss != kvm_host.xss) - wrmsrq(MSR_IA32_XSS, vcpu->arch.ia32_xss); - } + if (guest_cpu_cap_has(vcpu, X86_FEATURE_XSAVES) && + vcpu->arch.ia32_xss != kvm_host.xss) + wrmsrq(MSR_IA32_XSS, load_guest ? vcpu->arch.ia32_xss : kvm_host.xss); +} + +static void kvm_load_guest_pkru(struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.guest_state_protected) + return; if (cpu_feature_enabled(X86_FEATURE_PKU) && vcpu->arch.pkru != vcpu->arch.host_pkru && @@ -1224,9 +1233,8 @@ void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu) kvm_is_cr4_bit_set(vcpu, X86_CR4_PKE))) wrpkru(vcpu->arch.pkru); } -EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_load_guest_xsave_state); -void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu) +static void kvm_load_host_pkru(struct kvm_vcpu *vcpu) { if (vcpu->arch.guest_state_protected) return; @@ -1238,19 +1246,7 @@ void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu) if (vcpu->arch.pkru != vcpu->arch.host_pkru) wrpkru(vcpu->arch.host_pkru); } - - if (kvm_is_cr4_bit_set(vcpu, X86_CR4_OSXSAVE)) { - - if (vcpu->arch.xcr0 != kvm_host.xcr0) - xsetbv(XCR_XFEATURE_ENABLED_MASK, kvm_host.xcr0); - - if (guest_cpu_cap_has(vcpu, X86_FEATURE_XSAVES) && - vcpu->arch.ia32_xss != kvm_host.xss) - wrmsrq(MSR_IA32_XSS, kvm_host.xss); - } - } -EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_load_host_xsave_state); #ifdef CONFIG_X86_64 static inline u64 kvm_guest_supported_xfd(struct kvm_vcpu *vcpu) @@ -3505,27 +3501,17 @@ uint64_t kvm_get_wall_clock_epoch(struct kvm *kvm) /* * kvmclock updates which are isolated to a given vcpu, such as * vcpu->cpu migration, should not allow system_timestamp from - * the rest of the vcpus to remain static. Otherwise ntp frequency - * correction applies to one vcpu's system_timestamp but not - * the others. + * the rest of the vcpus to remain static. * * So in those cases, request a kvmclock update for all vcpus. - * We need to rate-limit these requests though, as they can - * considerably slow guests that have a large number of vcpus. - * The time for a remote vcpu to update its kvmclock is bound - * by the delay we use to rate-limit the updates. + * The worst case for a remote vcpu to update its kvmclock + * is then bounded by maximum nohz sleep latency. */ - -#define KVMCLOCK_UPDATE_DELAY msecs_to_jiffies(100) - -static void kvmclock_update_fn(struct work_struct *work) +static void kvm_gen_kvmclock_update(struct kvm_vcpu *v) { unsigned long i; - struct delayed_work *dwork = to_delayed_work(work); - struct kvm_arch *ka = container_of(dwork, struct kvm_arch, - kvmclock_update_work); - struct kvm *kvm = container_of(ka, struct kvm, arch); struct kvm_vcpu *vcpu; + struct kvm *kvm = v->kvm; kvm_for_each_vcpu(i, vcpu, kvm) { kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); @@ -3533,29 +3519,6 @@ static void kvmclock_update_fn(struct work_struct *work) } } -static void kvm_gen_kvmclock_update(struct kvm_vcpu *v) -{ - struct kvm *kvm = v->kvm; - - kvm_make_request(KVM_REQ_CLOCK_UPDATE, v); - schedule_delayed_work(&kvm->arch.kvmclock_update_work, - KVMCLOCK_UPDATE_DELAY); -} - -#define KVMCLOCK_SYNC_PERIOD (300 * HZ) - -static void kvmclock_sync_fn(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct kvm_arch *ka = container_of(dwork, struct kvm_arch, - kvmclock_sync_work); - struct kvm *kvm = container_of(ka, struct kvm, arch); - - schedule_delayed_work(&kvm->arch.kvmclock_update_work, 0); - schedule_delayed_work(&kvm->arch.kvmclock_sync_work, - KVMCLOCK_SYNC_PERIOD); -} - /* These helpers are safe iff @msr is known to be an MCx bank MSR. */ static bool is_mci_control_msr(u32 msr) { @@ -3650,13 +3613,6 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 0; } -static inline bool kvm_pv_async_pf_enabled(struct kvm_vcpu *vcpu) -{ - u64 mask = KVM_ASYNC_PF_ENABLED | KVM_ASYNC_PF_DELIVERY_AS_INT; - - return (vcpu->arch.apf.msr_en_val & mask) == mask; -} - static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) { gpa_t gpa = data & ~0x3f; @@ -4182,7 +4138,12 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_INT)) return 1; if (data & 0x1) { - vcpu->arch.apf.pageready_pending = false; + /* + * Pairs with the smp_mb__after_atomic() in + * kvm_arch_async_page_present_queued(). + */ + smp_store_mb(vcpu->arch.apf.pageready_pending, false); + kvm_check_async_pf_completion(vcpu); } break; @@ -5188,7 +5149,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); - vcpu->arch.l1tf_flush_l1d = true; + kvm_request_l1tf_flush_l1d(); if (vcpu->scheduled_out && pmu->version && pmu->event_count) { pmu->need_cleanup = true; @@ -7239,6 +7200,19 @@ static int kvm_vm_ioctl_set_clock(struct kvm *kvm, void __user *argp) return 0; } +long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) +{ + struct kvm_vcpu *vcpu = filp->private_data; + void __user *argp = (void __user *)arg; + + if (ioctl == KVM_MEMORY_ENCRYPT_OP && + kvm_x86_ops.vcpu_mem_enc_unlocked_ioctl) + return kvm_x86_call(vcpu_mem_enc_unlocked_ioctl)(vcpu, argp); + + return -ENOIOCTLCMD; +} + int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { struct kvm *kvm = filp->private_data; @@ -7998,7 +7972,7 @@ int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val, unsigned int bytes, struct x86_exception *exception) { /* kvm_write_guest_virt_system can pull in tons of pages. */ - vcpu->arch.l1tf_flush_l1d = true; + kvm_request_l1tf_flush_l1d(); return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, PFERR_WRITE_MASK, exception); @@ -8842,6 +8816,14 @@ static void emulator_triple_fault(struct x86_emulate_ctxt *ctxt) kvm_make_request(KVM_REQ_TRIPLE_FAULT, emul_to_vcpu(ctxt)); } +static int emulator_get_xcr(struct x86_emulate_ctxt *ctxt, u32 index, u64 *xcr) +{ + if (index != XCR_XFEATURE_ENABLED_MASK) + return 1; + *xcr = emul_to_vcpu(ctxt)->arch.xcr0; + return 0; +} + static int emulator_set_xcr(struct x86_emulate_ctxt *ctxt, u32 index, u64 xcr) { return __kvm_set_xcr(emul_to_vcpu(ctxt), index, xcr); @@ -8914,6 +8896,7 @@ static const struct x86_emulate_ops emulate_ops = { .is_smm = emulator_is_smm, .leave_smm = emulator_leave_smm, .triple_fault = emulator_triple_fault, + .get_xcr = emulator_get_xcr, .set_xcr = emulator_set_xcr, .get_untagged_addr = emulator_get_untagged_addr, .is_canonical_addr = emulator_is_canonical_addr, @@ -9109,6 +9092,18 @@ void kvm_prepare_event_vectoring_exit(struct kvm_vcpu *vcpu, gpa_t gpa) } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_prepare_event_vectoring_exit); +void kvm_prepare_unexpected_reason_exit(struct kvm_vcpu *vcpu, u64 exit_reason) +{ + vcpu_unimpl(vcpu, "unexpected exit reason 0x%llx\n", exit_reason); + + vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON; + vcpu->run->internal.ndata = 2; + vcpu->run->internal.data[0] = exit_reason; + vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu; +} +EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_prepare_unexpected_reason_exit); + static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type) { struct kvm *kvm = vcpu->kvm; @@ -9337,6 +9332,23 @@ static bool is_vmware_backdoor_opcode(struct x86_emulate_ctxt *ctxt) return false; } +static bool is_soft_int_instruction(struct x86_emulate_ctxt *ctxt, + int emulation_type) +{ + u8 vector = EMULTYPE_GET_SOFT_INT_VECTOR(emulation_type); + + switch (ctxt->b) { + case 0xcc: + return vector == BP_VECTOR; + case 0xcd: + return vector == ctxt->src.val; + case 0xce: + return vector == OF_VECTOR; + default: + return false; + } +} + /* * Decode an instruction for emulation. The caller is responsible for handling * code breakpoints. Note, manually detecting code breakpoints is unnecessary @@ -9394,7 +9406,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, return handle_emulation_failure(vcpu, emulation_type); } - vcpu->arch.l1tf_flush_l1d = true; + kvm_request_l1tf_flush_l1d(); if (!(emulation_type & EMULTYPE_NO_DECODE)) { kvm_clear_exception_queue(vcpu); @@ -9447,6 +9459,10 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, * injecting single-step #DBs. */ if (emulation_type & EMULTYPE_SKIP) { + if (emulation_type & EMULTYPE_SKIP_SOFT_INT && + !is_soft_int_instruction(ctxt, emulation_type)) + return 0; + if (ctxt->mode != X86EMUL_MODE_PROT64) ctxt->eip = (u32)ctxt->_eip; else @@ -10031,17 +10047,9 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops) return -ENOMEM; } - user_return_msrs = alloc_percpu(struct kvm_user_return_msrs); - if (!user_return_msrs) { - pr_err("failed to allocate percpu kvm_user_return_msrs\n"); - r = -ENOMEM; - goto out_free_x86_emulator_cache; - } - kvm_nr_uret_msrs = 0; - r = kvm_mmu_vendor_module_init(); if (r) - goto out_free_percpu; + goto out_free_x86_emulator_cache; kvm_caps.supported_vm_types = BIT(KVM_X86_DEFAULT_VM); kvm_caps.supported_mce_cap = MCG_CTL_P | MCG_SER_P; @@ -10066,6 +10074,8 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops) if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) rdmsrq(MSR_IA32_ARCH_CAPABILITIES, kvm_host.arch_capabilities); + WARN_ON_ONCE(kvm_nr_uret_msrs); + r = ops->hardware_setup(); if (r != 0) goto out_mmu_exit; @@ -10138,9 +10148,8 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops) kvm_x86_ops.enable_virtualization_cpu = NULL; kvm_x86_call(hardware_unsetup)(); out_mmu_exit: + kvm_destroy_user_return_msrs(); kvm_mmu_vendor_module_exit(); -out_free_percpu: - free_percpu(user_return_msrs); out_free_x86_emulator_cache: kmem_cache_destroy(x86_emulator_cache); return r; @@ -10168,8 +10177,8 @@ void kvm_x86_vendor_exit(void) cancel_work_sync(&pvclock_gtod_work); #endif kvm_x86_call(hardware_unsetup)(); + kvm_destroy_user_return_msrs(); kvm_mmu_vendor_module_exit(); - free_percpu(user_return_msrs); kmem_cache_destroy(x86_emulator_cache); #ifdef CONFIG_KVM_XEN static_key_deferred_flush(&kvm_xen_enabled); @@ -10877,9 +10886,16 @@ void __kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu) * pending. At the same time, KVM_REQ_EVENT may not be set as APICv was * still active when the interrupt got accepted. Make sure * kvm_check_and_inject_events() is called to check for that. + * + * Update SVI when APICv gets enabled, otherwise SVI won't reflect the + * highest bit in vISR and the next accelerated EOI in the guest won't + * be virtualized correctly (the CPU uses SVI to determine which vISR + * vector to clear). */ if (!apic->apicv_active) kvm_make_request(KVM_REQ_EVENT, vcpu); + else + kvm_apic_update_hwapic_isr(vcpu); out: preempt_enable(); @@ -11291,6 +11307,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) if (vcpu->arch.guest_fpu.xfd_err) wrmsrq(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err); + kvm_load_xfeatures(vcpu, true); + if (unlikely(vcpu->arch.switch_db_regs && !(vcpu->arch.switch_db_regs & KVM_DEBUGREG_AUTO_SWITCH))) { set_debugreg(DR7_FIXED_1, 7); @@ -11319,6 +11337,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) guest_timing_enter_irqoff(); + /* + * Swap PKRU with hardware breakpoints disabled to minimize the number + * of flows where non-KVM code can run with guest state loaded. + */ + kvm_load_guest_pkru(vcpu); + for (;;) { /* * Assert that vCPU vs. VM APICv state is consistent. An APICv @@ -11347,6 +11371,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) ++vcpu->stat.exits; } + kvm_load_host_pkru(vcpu); + /* * Do this here before restoring debug registers on the host. And * since we do this before handling the vmexit, a DR access vmexit @@ -11377,6 +11403,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) vcpu->mode = OUTSIDE_GUEST_MODE; smp_wmb(); + kvm_load_xfeatures(vcpu, false); + /* * Sync xfd before calling handle_exit_irqoff() which may * rely on the fact that guest_fpu::xfd is up-to-date (e.g. @@ -12734,8 +12762,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) { - struct kvm *kvm = vcpu->kvm; - if (mutex_lock_killable(&vcpu->mutex)) return; vcpu_load(vcpu); @@ -12746,10 +12772,6 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) vcpu->arch.msr_kvm_poll_control = 1; mutex_unlock(&vcpu->mutex); - - if (kvmclock_periodic_sync && vcpu->vcpu_idx == 0) - schedule_delayed_work(&kvm->arch.kvmclock_sync_work, - KVMCLOCK_SYNC_PERIOD); } void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) @@ -13088,7 +13110,21 @@ int kvm_arch_enable_virtualization_cpu(void) void kvm_arch_disable_virtualization_cpu(void) { kvm_x86_call(disable_virtualization_cpu)(); - drop_user_return_notifiers(); + + /* + * Leave the user-return notifiers as-is when disabling virtualization + * for reboot, i.e. when disabling via IPI function call, and instead + * pin kvm.ko (if it's a module) to defend against use-after-free (in + * the *very* unlikely scenario module unload is racing with reboot). + * On a forced reboot, tasks aren't frozen before shutdown, and so KVM + * could be actively modifying user-return MSR state when the IPI to + * disable virtualization arrives. Handle the extreme edge case here + * instead of trying to account for it in the normal flows. + */ + if (in_task() || WARN_ON_ONCE(!kvm_rebooting)) + drop_user_return_notifiers(); + else + __module_get(THIS_MODULE); } bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu) @@ -13160,9 +13196,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) kvm->arch.hv_root_tdp = INVALID_PAGE; #endif - INIT_DELAYED_WORK(&kvm->arch.kvmclock_update_work, kvmclock_update_fn); - INIT_DELAYED_WORK(&kvm->arch.kvmclock_sync_work, kvmclock_sync_fn); - kvm_apicv_init(kvm); kvm_hv_init_vm(kvm); kvm_xen_init_vm(kvm); @@ -13269,9 +13302,6 @@ void kvm_arch_pre_destroy_vm(struct kvm *kvm) * is unsafe, i.e. will lead to use-after-free. The PIT also needs to * be stopped before IRQ routing is freed. */ - cancel_delayed_work_sync(&kvm->arch.kvmclock_sync_work); - cancel_delayed_work_sync(&kvm->arch.kvmclock_update_work); - #ifdef CONFIG_KVM_IOAPIC kvm_free_pit(kvm); #endif @@ -13888,7 +13918,7 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, if ((work->wakeup_all || work->notpresent_injected) && kvm_pv_async_pf_enabled(vcpu) && !apf_put_user_ready(vcpu, work->arch.token)) { - vcpu->arch.apf.pageready_pending = true; + WRITE_ONCE(vcpu->arch.apf.pageready_pending, true); kvm_apic_set_irq(vcpu, &irq, NULL); } @@ -13899,7 +13929,11 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, void kvm_arch_async_page_present_queued(struct kvm_vcpu *vcpu) { kvm_make_request(KVM_REQ_APF_READY, vcpu); - if (!vcpu->arch.apf.pageready_pending) + + /* Pairs with smp_store_mb() in kvm_set_msr_common(). */ + smp_mb__after_atomic(); + + if (!READ_ONCE(vcpu->arch.apf.pageready_pending)) kvm_vcpu_kick(vcpu); } diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index f3dc77f006f90..fdab0ad490988 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -420,6 +420,20 @@ static inline bool kvm_check_has_quirk(struct kvm *kvm, u64 quirk) return !(kvm->arch.disabled_quirks & quirk); } +static __always_inline void kvm_request_l1tf_flush_l1d(void) +{ +#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL) + /* + * Use a raw write to set the per-CPU flag, as KVM will ensure a flush + * even if preemption is currently enabled.. If the current vCPU task + * is migrated to a different CPU (or userspace runs the vCPU on a + * different task) before the next VM-Entry, then kvm_arch_vcpu_load() + * will request a flush on the new CPU. + */ + raw_cpu_write(irq_stat.kvm_cpu_l1tf_flush_l1d, 1); +#endif +} + void kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); u64 get_kvmclock_ns(struct kvm *kvm); @@ -622,8 +636,6 @@ static inline void kvm_machine_check(void) #endif } -void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu); -void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu); int kvm_spec_ctrl_test_value(u64 value); int kvm_handle_memory_failure(struct kvm_vcpu *vcpu, int r, struct x86_exception *e); diff --git a/arch/x86/lib/error-inject.c b/arch/x86/lib/error-inject.c index b5a6d83106bc2..512a2538596f0 100644 --- a/arch/x86/lib/error-inject.c +++ b/arch/x86/lib/error-inject.c @@ -13,7 +13,7 @@ asm( ".globl just_return_func\n" ASM_FUNC_ALIGN "just_return_func:\n" - ANNOTATE_NOENDBR + ANNOTATE_NOENDBR "\n" ASM_RET ".size just_return_func, .-just_return_func\n" ); diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 1044aafd5d94e..9983017ecbe0e 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -1028,7 +1028,7 @@ static void __meminit free_pagetable(struct page *page, int order) free_reserved_pages(page, nr_pages); #endif } else { - __free_pages(page, order); + pagetable_free(page_ptdesc(page)); } } diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index c24890c40138f..7a97327140df8 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c @@ -262,7 +262,7 @@ void __init init_gi_nodes(void) * bringup_nonboot_cpus * cpu_up * __try_online_node - * register_one_node + * register_node * because node_subsys is not initialized yet. * TODO remove dependency on node_online */ @@ -303,7 +303,7 @@ void __init init_cpu_to_node(void) * bringup_nonboot_cpus * cpu_up * __try_online_node - * register_one_node + * register_node * because node_subsys is not initialized yet. * TODO remove dependency on node_online */ diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index 970981893c9b8..6c6eb486f7a61 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -368,7 +368,7 @@ bool cpu_cache_has_invalidate_memregion(void) } EXPORT_SYMBOL_NS_GPL(cpu_cache_has_invalidate_memregion, "DEVMEM"); -int cpu_cache_invalidate_memregion(int res_desc) +int cpu_cache_invalidate_memregion(phys_addr_t start, size_t len) { if (WARN_ON_ONCE(!cpu_cache_has_invalidate_memregion())) return -ENXIO; @@ -429,7 +429,7 @@ static void cpa_collapse_large_pages(struct cpa_data *cpa) list_for_each_entry_safe(ptdesc, tmp, &pgtables, pt_list) { list_del(&ptdesc->pt_list); - __free_page(ptdesc_page(ptdesc)); + pagetable_free(ptdesc); } } diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index ddf248c3ee7dc..2e5ecfdce73c3 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -729,7 +729,7 @@ int pmd_clear_huge(pmd_t *pmd) int pud_free_pmd_page(pud_t *pud, unsigned long addr) { pmd_t *pmd, *pmd_sv; - pte_t *pte; + struct ptdesc *pt; int i; pmd = pud_pgtable(*pud); @@ -750,8 +750,8 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr) for (i = 0; i < PTRS_PER_PMD; i++) { if (!pmd_none(pmd_sv[i])) { - pte = (pte_t *)pmd_page_vaddr(pmd_sv[i]); - pte_free_kernel(&init_mm, pte); + pt = page_ptdesc(pmd_page(pmd_sv[i])); + pagetable_dtor_free(pt); } } @@ -772,15 +772,15 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr) */ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) { - pte_t *pte; + struct ptdesc *pt; - pte = (pte_t *)pmd_page_vaddr(*pmd); + pt = page_ptdesc(pmd_page(*pmd)); pmd_clear(pmd); /* INVLPG to clear all paging-structure caches */ flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1); - pte_free_kernel(&init_mm, pte); + pagetable_dtor_free(pt); return 1; } diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index b69dc7194e2c0..b0bac2a66eff3 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -1678,6 +1678,9 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image emit_prologue(&prog, image, stack_depth, bpf_prog_was_classic(bpf_prog), tail_call_reachable, bpf_is_subprog(bpf_prog), bpf_prog->aux->exception_cb); + + bpf_prog->aux->ksym.fp_start = prog - temp; + /* Exception callback will clobber callee regs for its own use, and * restore the original callee regs from main prog's stack frame. */ @@ -2736,6 +2739,8 @@ st: if (is_imm8(insn->off)) pop_r12(&prog); } EMIT1(0xC9); /* leave */ + bpf_prog->aux->ksym.fp_end = prog - temp; + emit_return(&prog, image + addrs[i - 1] + (prog - temp)); break; @@ -3325,6 +3330,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im } EMIT1(0x55); /* push rbp */ EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */ + if (im) + im->ksym.fp_start = prog - (u8 *)rw_image; + if (!is_imm8(stack_size)) { /* sub rsp, stack_size */ EMIT3_off32(0x48, 0x81, 0xEC, stack_size); @@ -3462,7 +3470,11 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, -8); emit_ldx(&prog, BPF_DW, BPF_REG_6, BPF_REG_FP, -rbx_off); + EMIT1(0xC9); /* leave */ + if (im) + im->ksym.fp_end = prog - (u8 *)rw_image; + if (flags & BPF_TRAMP_F_SKIP_FRAME) { /* skip our return address and return to parent */ EMIT4(0x48, 0x83, 0xC4, 8); /* add rsp, 8 */ diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig index 986045d5e6385..bdd7c8e39b011 100644 --- a/arch/x86/um/Kconfig +++ b/arch/x86/um/Kconfig @@ -8,9 +8,11 @@ endmenu config UML_X86 def_bool y - select ARCH_BINFMT_ELF_EXTRA_PHDRS if X86_32 + select ARCH_USE_QUEUED_RWLOCKS + select ARCH_USE_QUEUED_SPINLOCKS select DCACHE_WORD_ACCESS select HAVE_EFFICIENT_UNALIGNED_ACCESS + select UML_SUBARCH_SUPPORTS_SMP if X86_CX8 config 64BIT bool "64-bit kernel" if "$(SUBARCH)" = "x86" @@ -32,8 +34,5 @@ config X86_64 config ARCH_HAS_SC_SIGNALS def_bool !64BIT -config ARCH_REUSE_HOST_VSYSCALL_AREA - def_bool !64BIT - config GENERIC_HWEIGHT def_bool y diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile index b42c31cd2390c..f9ea75bf43aca 100644 --- a/arch/x86/um/Makefile +++ b/arch/x86/um/Makefile @@ -13,12 +13,11 @@ obj-y = bugs_$(BITS).o delay.o fault.o \ ptrace.o ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal.o \ stub_segv.o \ sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o \ - mem_$(BITS).o subarch.o os-Linux/ + subarch.o os-Linux/ ifeq ($(CONFIG_X86_32),y) obj-y += syscalls_32.o -obj-$(CONFIG_ELF_CORE) += elfcore.o subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o subarch-y += ../lib/cmpxchg8b_emu.o ../lib/atomic64_386_32.o @@ -27,7 +26,7 @@ subarch-y += ../kernel/sys_ia32.o else -obj-y += syscalls_64.o vdso/ +obj-y += mem_64.o syscalls_64.o vdso/ subarch-y = ../lib/csum-partial_64.o ../lib/memcpy_64.o \ ../lib/memmove_64.o ../lib/memset_64.o diff --git a/arch/x86/um/asm/elf.h b/arch/x86/um/asm/elf.h index 62ed5d68a9788..22d0111b543b3 100644 --- a/arch/x86/um/asm/elf.h +++ b/arch/x86/um/asm/elf.h @@ -68,35 +68,7 @@ pr_reg[16] = PT_REGS_SS(regs); \ } while (0); -extern char * elf_aux_platform; -#define ELF_PLATFORM (elf_aux_platform) - -extern unsigned long vsyscall_ehdr; -extern unsigned long vsyscall_end; -extern unsigned long __kernel_vsyscall; - -/* - * This is the range that is readable by user mode, and things - * acting like user mode such as get_user_pages. - */ -#define FIXADDR_USER_START vsyscall_ehdr -#define FIXADDR_USER_END vsyscall_end - - -/* - * Architecture-neutral AT_ values in 0-17, leave some room - * for more of them, start the x86-specific ones at 32. - */ -#define AT_SYSINFO 32 -#define AT_SYSINFO_EHDR 33 - -#define ARCH_DLINFO \ -do { \ - if ( vsyscall_ehdr ) { \ - NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \ - } \ -} while (0) +#define ELF_PLATFORM_FALLBACK "i586" #else @@ -177,11 +149,7 @@ do { \ (pr_reg)[25] = 0; \ (pr_reg)[26] = 0; -#define ELF_PLATFORM "x86_64" - -/* No user-accessible fixmap addresses, i.e. vsyscall */ -#define FIXADDR_USER_START 0 -#define FIXADDR_USER_END 0 +#define ELF_PLATFORM_FALLBACK "x86_64" #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 struct linux_binprm; @@ -210,6 +178,9 @@ struct task_struct; extern long elf_aux_hwcap; #define ELF_HWCAP (elf_aux_hwcap) +extern char *elf_aux_platform; +#define ELF_PLATFORM (elf_aux_platform ?: ELF_PLATFORM_FALLBACK) + #define SET_PERSONALITY(ex) do {} while(0) #endif diff --git a/arch/x86/um/asm/spinlock.h b/arch/x86/um/asm/spinlock.h new file mode 100644 index 0000000000000..20fc775142147 --- /dev/null +++ b/arch/x86/um/asm/spinlock.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_UM_SPINLOCK_H +#define __ASM_UM_SPINLOCK_H + +#include +#include + +#endif /* __ASM_UM_SPINLOCK_H */ diff --git a/arch/x86/um/elfcore.c b/arch/x86/um/elfcore.c deleted file mode 100644 index ef50662fc40d2..0000000000000 --- a/arch/x86/um/elfcore.c +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include - -#include - - -Elf32_Half elf_core_extra_phdrs(struct coredump_params *cprm) -{ - return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; -} - -int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *) vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - Elf32_Off ofs = 0; - - for (i = 0; i < ehdrp->e_phnum; ++i) { - struct elf_phdr phdr = phdrp[i]; - - if (phdr.p_type == PT_LOAD) { - ofs = phdr.p_offset = offset; - offset += phdr.p_filesz; - } else { - phdr.p_offset += ofs; - } - phdr.p_paddr = 0; /* match other core phdrs */ - if (!dump_emit(cprm, &phdr, sizeof(phdr))) - return 0; - } - } - return 1; -} - -int elf_core_write_extra_data(struct coredump_params *cprm) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *) vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - - for (i = 0; i < ehdrp->e_phnum; ++i) { - if (phdrp[i].p_type == PT_LOAD) { - void *addr = (void *) phdrp[i].p_vaddr; - size_t filesz = phdrp[i].p_filesz; - if (!dump_emit(cprm, addr, filesz)) - return 0; - } - } - } - return 1; -} - -size_t elf_core_extra_data_size(struct coredump_params *cprm) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *)vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - - for (i = 0; i < ehdrp->e_phnum; ++i) - if (phdrp[i].p_type == PT_LOAD) - return (size_t) phdrp[i].p_filesz; - } - return 0; -} diff --git a/arch/x86/um/mem_32.c b/arch/x86/um/mem_32.c deleted file mode 100644 index 29b2203bc82cb..0000000000000 --- a/arch/x86/um/mem_32.c +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2011 Richard Weinberger - */ - -#include -#include - -static struct vm_area_struct gate_vma; - -static int __init gate_vma_init(void) -{ - if (!FIXADDR_USER_START) - return 0; - - vma_init(&gate_vma, NULL); - gate_vma.vm_start = FIXADDR_USER_START; - gate_vma.vm_end = FIXADDR_USER_END; - vm_flags_init(&gate_vma, VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC); - gate_vma.vm_page_prot = PAGE_READONLY; - - return 0; -} -__initcall(gate_vma_init); - -struct vm_area_struct *get_gate_vma(struct mm_struct *mm) -{ - return FIXADDR_USER_START ? &gate_vma : NULL; -} - -int in_gate_area_no_mm(unsigned long addr) -{ - if (!FIXADDR_USER_START) - return 0; - - if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END)) - return 1; - - return 0; -} - -int in_gate_area(struct mm_struct *mm, unsigned long addr) -{ - struct vm_area_struct *vma = get_gate_vma(mm); - - if (!vma) - return 0; - - return (addr >= vma->vm_start) && (addr < vma->vm_end); -} diff --git a/arch/x86/um/shared/sysdep/kernel-offsets.h b/arch/x86/um/shared/sysdep/kernel-offsets.h deleted file mode 100644 index 6fd1ed4003992..0000000000000 --- a/arch/x86/um/shared/sysdep/kernel-offsets.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* workaround for a warning with -Wmissing-prototypes */ -void foo(void); - -void foo(void) -{ -#include -} diff --git a/arch/x86/um/vdso/Makefile b/arch/x86/um/vdso/Makefile index 7478d11dacb71..8a7c8b37cb6eb 100644 --- a/arch/x86/um/vdso/Makefile +++ b/arch/x86/um/vdso/Makefile @@ -3,16 +3,13 @@ # Building vDSO images for x86. # -VDSO64-y := y - -vdso-install-$(VDSO64-y) += vdso.so - +vdso-install-y += vdso.so # files to link into the vdso vobjs-y := vdso-note.o um_vdso.o # files to link into kernel -obj-$(VDSO64-y) += vdso.o vma.o +obj-y += vdso.o vma.o vobjs := $(foreach F,$(vobjs-y),$(obj)/$F) diff --git a/arch/x86/um/vdso/um_vdso.c b/arch/x86/um/vdso/um_vdso.c index cbae2584124fd..ca1468865b140 100644 --- a/arch/x86/um/vdso/um_vdso.c +++ b/arch/x86/um/vdso/um_vdso.c @@ -9,17 +9,11 @@ /* Disable profiling for userspace code */ #define DISABLE_BRANCH_PROFILING +#include #include -#include #include -/* workaround for -Wmissing-prototypes warnings */ -int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts); -int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz); -__kernel_old_time_t __vdso_time(__kernel_old_time_t *t); -long __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused); - -int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts) +int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts) { long ret; @@ -30,7 +24,7 @@ int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts) return ret; } -int clock_gettime(clockid_t, struct __kernel_old_timespec *) +int clock_gettime(clockid_t, struct __kernel_timespec *) __attribute__((weak, alias("__vdso_clock_gettime"))); int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) @@ -58,21 +52,3 @@ __kernel_old_time_t __vdso_time(__kernel_old_time_t *t) return secs; } __kernel_old_time_t time(__kernel_old_time_t *t) __attribute__((weak, alias("__vdso_time"))); - -long -__vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused) -{ - /* - * UML does not support SMP, we can cheat here. :) - */ - - if (cpu) - *cpu = 0; - if (node) - *node = 0; - - return 0; -} - -long getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *tcache) - __attribute__((weak, alias("__vdso_getcpu"))); diff --git a/arch/x86/um/vdso/vdso.lds.S b/arch/x86/um/vdso/vdso.lds.S index 73c508587a984..401600effc0a7 100644 --- a/arch/x86/um/vdso/vdso.lds.S +++ b/arch/x86/um/vdso/vdso.lds.S @@ -22,8 +22,6 @@ VERSION { __vdso_clock_gettime; gettimeofday; __vdso_gettimeofday; - getcpu; - __vdso_getcpu; time; __vdso_time; local: *; diff --git a/arch/x86/um/vdso/vma.c b/arch/x86/um/vdso/vma.c index dc8dfb2abd809..51a2b9f2eca95 100644 --- a/arch/x86/um/vdso/vma.c +++ b/arch/x86/um/vdso/vma.c @@ -10,7 +10,6 @@ #include #include -static unsigned int __read_mostly vdso_enabled = 1; unsigned long um_vdso_addr; static struct page *um_vdso; @@ -25,17 +24,11 @@ static int __init init_vdso(void) um_vdso = alloc_page(GFP_KERNEL); if (!um_vdso) - goto oom; + panic("Cannot allocate vdso\n"); copy_page(page_address(um_vdso), vdso_start); return 0; - -oom: - printk(KERN_ERR "Cannot allocate vdso\n"); - vdso_enabled = 0; - - return -ENOMEM; } subsys_initcall(init_vdso); @@ -48,9 +41,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) .pages = &um_vdso, }; - if (!vdso_enabled) - return 0; - if (mmap_write_lock_killable(mm)) return -EINTR; diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 4806cc28d7ca7..b74ff8bc7f2a8 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -108,7 +108,7 @@ static int xen_cpu_dead_pv(unsigned int cpu); * calls. */ DEFINE_PER_CPU(bool, xen_in_preemptible_hcall); -EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall); +EXPORT_PER_CPU_SYMBOL_GPL(xen_in_preemptible_hcall); /* * In case of scheduling the flag must be cleared and restored after diff --git a/arch/xtensa/configs/audio_kc705_defconfig b/arch/xtensa/configs/audio_kc705_defconfig index 4655d6bd7ee07..0772b5a246587 100644 --- a/arch/xtensa/configs/audio_kc705_defconfig +++ b/arch/xtensa/configs/audio_kc705_defconfig @@ -81,7 +81,6 @@ CONFIG_MARVELL_PHY=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_HW_RANDOM=y diff --git a/arch/xtensa/configs/generic_kc705_defconfig b/arch/xtensa/configs/generic_kc705_defconfig index b3de2bd74d545..8327768bbdef9 100644 --- a/arch/xtensa/configs/generic_kc705_defconfig +++ b/arch/xtensa/configs/generic_kc705_defconfig @@ -79,7 +79,6 @@ CONFIG_MARVELL_PHY=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_HW_RANDOM=y diff --git a/arch/xtensa/configs/nommu_kc705_defconfig b/arch/xtensa/configs/nommu_kc705_defconfig index 47dd80930e906..fef9ecc372283 100644 --- a/arch/xtensa/configs/nommu_kc705_defconfig +++ b/arch/xtensa/configs/nommu_kc705_defconfig @@ -81,7 +81,6 @@ CONFIG_MARVELL_PHY=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_HW_RANDOM=y diff --git a/arch/xtensa/configs/smp_lx200_defconfig b/arch/xtensa/configs/smp_lx200_defconfig index c8c92c5b24d5d..b0a8fe3dee7ff 100644 --- a/arch/xtensa/configs/smp_lx200_defconfig +++ b/arch/xtensa/configs/smp_lx200_defconfig @@ -83,7 +83,6 @@ CONFIG_MARVELL_PHY=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_HW_RANDOM=y diff --git a/arch/xtensa/configs/xip_kc705_defconfig b/arch/xtensa/configs/xip_kc705_defconfig index 3e9486222a66c..7c61f7c26318e 100644 --- a/arch/xtensa/configs/xip_kc705_defconfig +++ b/arch/xtensa/configs/xip_kc705_defconfig @@ -72,7 +72,6 @@ CONFIG_MARVELL_PHY=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HWMON is not set diff --git a/block/bio.c b/block/bio.c index e726c0e280a8d..2359c0723b88e 100644 --- a/block/bio.c +++ b/block/bio.c @@ -301,9 +301,12 @@ EXPORT_SYMBOL(bio_init); */ void bio_reset(struct bio *bio, struct block_device *bdev, blk_opf_t opf) { + struct bio_vec *bv = bio->bi_io_vec; + bio_uninit(bio); memset(bio, 0, BIO_RESET_BYTES); atomic_set(&bio->__bi_remaining, 1); + bio->bi_io_vec = bv; bio->bi_bdev = bdev; if (bio->bi_bdev) bio_associate_blkg(bio); @@ -1162,8 +1165,8 @@ void bio_iov_bvec_set(struct bio *bio, const struct iov_iter *iter) { WARN_ON_ONCE(bio->bi_max_vecs); - bio->bi_vcnt = iter->nr_segs; bio->bi_io_vec = (struct bio_vec *)iter->bvec; + bio->bi_iter.bi_idx = 0; bio->bi_iter.bi_bvec_done = iter->iov_offset; bio->bi_iter.bi_size = iov_iter_count(iter); bio_set_flag(bio, BIO_CLONED); diff --git a/block/blk-mq-dma.c b/block/blk-mq-dma.c index 6dc7a3c23ac8d..752060d7261cb 100644 --- a/block/blk-mq-dma.c +++ b/block/blk-mq-dma.c @@ -6,11 +6,6 @@ #include #include "blk.h" -struct phys_vec { - phys_addr_t paddr; - u32 len; -}; - static bool __blk_map_iter_next(struct blk_map_iter *iter) { if (iter->iter.bi_size) @@ -84,7 +79,7 @@ static inline bool blk_can_dma_map_iova(struct request *req, static bool blk_dma_map_bus(struct blk_dma_iter *iter, struct phys_vec *vec) { - iter->addr = pci_p2pdma_bus_addr_map(&iter->p2pdma, vec->paddr); + iter->addr = pci_p2pdma_bus_addr_map(iter->p2pdma.mem, vec->paddr); iter->len = vec->len; return true; } @@ -112,8 +107,8 @@ static bool blk_rq_dma_map_iova(struct request *req, struct device *dma_dev, struct phys_vec *vec) { enum dma_data_direction dir = rq_dma_dir(req); - unsigned int mapped = 0; unsigned int attrs = 0; + size_t mapped = 0; int error; iter->addr = state->addr; @@ -297,6 +292,8 @@ int __blk_rq_map_sg(struct request *rq, struct scatterlist *sglist, blk_rq_map_iter_init(rq, &iter); while (blk_map_iter_next(rq, &iter, &vec)) { *last_sg = blk_next_sg(last_sg, sglist); + + WARN_ON_ONCE(overflows_type(vec.len, unsigned int)); sg_set_page(*last_sg, phys_to_page(vec.paddr), vec.len, offset_in_page(vec.paddr)); nsegs++; @@ -417,6 +414,8 @@ int blk_rq_map_integrity_sg(struct request *rq, struct scatterlist *sglist) while (blk_map_iter_next(rq, &iter, &vec)) { sg = blk_next_sg(&sg, sglist); + + WARN_ON_ONCE(overflows_type(vec.len, unsigned int)); sg_set_page(sg, phys_to_page(vec.paddr), vec.len, offset_in_page(vec.paddr)); segments++; diff --git a/block/blk.h b/block/blk.h index e4c433f62dfc7..98f4dfd4ec758 100644 --- a/block/blk.h +++ b/block/blk.h @@ -371,12 +371,18 @@ struct bio *bio_split_zone_append(struct bio *bio, static inline bool bio_may_need_split(struct bio *bio, const struct queue_limits *lim) { + const struct bio_vec *bv; + if (lim->chunk_sectors) return true; - if (bio->bi_vcnt != 1) + + if (!bio->bi_io_vec) + return true; + + bv = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter); + if (bio->bi_iter.bi_size > bv->bv_len) return true; - return bio->bi_io_vec->bv_len + bio->bi_io_vec->bv_offset > - lim->max_fast_segment_size; + return bv->bv_len + bv->bv_offset > lim->max_fast_segment_size; } /** diff --git a/drivers/Kconfig b/drivers/Kconfig index 3054b50a2f4cb..c0f1fb893ec02 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -161,6 +161,8 @@ source "drivers/greybus/Kconfig" source "drivers/comedi/Kconfig" +source "drivers/gpib/Kconfig" + source "drivers/staging/Kconfig" source "drivers/platform/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 20eb17596b899..ccc05f1eae3eb 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -150,6 +150,7 @@ obj-$(CONFIG_VHOST_IOTLB) += vhost/ obj-$(CONFIG_VHOST) += vhost/ obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_COMEDI) += comedi/ +obj-$(CONFIG_GPIB) += gpib/ obj-$(CONFIG_STAGING) += staging/ obj-y += platform/ @@ -160,7 +161,7 @@ obj-$(CONFIG_RPMSG) += rpmsg/ obj-$(CONFIG_SOUNDWIRE) += soundwire/ # Virtualization drivers -obj-$(CONFIG_VIRT_DRIVERS) += virt/ +obj-y += virt/ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_PM_DEVFREQ) += devfreq/ diff --git a/drivers/accel/Kconfig b/drivers/accel/Kconfig index bb01cebc42bf1..bdf48ccafcf21 100644 --- a/drivers/accel/Kconfig +++ b/drivers/accel/Kconfig @@ -25,6 +25,7 @@ menuconfig DRM_ACCEL and debugfs). source "drivers/accel/amdxdna/Kconfig" +source "drivers/accel/ethosu/Kconfig" source "drivers/accel/habanalabs/Kconfig" source "drivers/accel/ivpu/Kconfig" source "drivers/accel/qaic/Kconfig" diff --git a/drivers/accel/Makefile b/drivers/accel/Makefile index ffc3fa5886661..1d3a7251b950f 100644 --- a/drivers/accel/Makefile +++ b/drivers/accel/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_DRM_ACCEL_AMDXDNA) += amdxdna/ +obj-$(CONFIG_DRM_ACCEL_ARM_ETHOSU) += ethosu/ obj-$(CONFIG_DRM_ACCEL_HABANALABS) += habanalabs/ obj-$(CONFIG_DRM_ACCEL_IVPU) += ivpu/ obj-$(CONFIG_DRM_ACCEL_QAIC) += qaic/ diff --git a/drivers/accel/amdxdna/Makefile b/drivers/accel/amdxdna/Makefile index 6797dac65efaa..6344aaf523fac 100644 --- a/drivers/accel/amdxdna/Makefile +++ b/drivers/accel/amdxdna/Makefile @@ -14,6 +14,7 @@ amdxdna-y := \ amdxdna_mailbox.o \ amdxdna_mailbox_helper.o \ amdxdna_pci_drv.o \ + amdxdna_pm.o \ amdxdna_sysfs.o \ amdxdna_ubuf.o \ npu1_regs.o \ diff --git a/drivers/accel/amdxdna/TODO b/drivers/accel/amdxdna/TODO index ad8ac6e315b6b..0e4bbebeaedfc 100644 --- a/drivers/accel/amdxdna/TODO +++ b/drivers/accel/amdxdna/TODO @@ -1,2 +1 @@ - Add debugfs support -- Add debug BO support diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c index e9f9b1fa5dc1b..42d876a427c59 100644 --- a/drivers/accel/amdxdna/aie2_ctx.c +++ b/drivers/accel/amdxdna/aie2_ctx.c @@ -21,6 +21,7 @@ #include "amdxdna_gem.h" #include "amdxdna_mailbox.h" #include "amdxdna_pci_drv.h" +#include "amdxdna_pm.h" static bool force_cmdlist; module_param(force_cmdlist, bool, 0600); @@ -88,7 +89,7 @@ static int aie2_hwctx_restart(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hw goto out; } - ret = aie2_config_cu(hwctx); + ret = aie2_config_cu(hwctx, NULL); if (ret) { XDNA_ERR(xdna, "Config cu failed, ret %d", ret); goto out; @@ -167,14 +168,11 @@ static int aie2_hwctx_resume_cb(struct amdxdna_hwctx *hwctx, void *arg) int aie2_hwctx_resume(struct amdxdna_client *client) { - struct amdxdna_dev *xdna = client->xdna; - /* * The resume path cannot guarantee that mailbox channel can be * regenerated. If this happen, when submit message to this * mailbox channel, error will return. */ - drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); return amdxdna_hwctx_walk(client, NULL, aie2_hwctx_resume_cb); } @@ -184,12 +182,13 @@ aie2_sched_notify(struct amdxdna_sched_job *job) struct dma_fence *fence = job->fence; trace_xdna_job(&job->base, job->hwctx->name, "signaled fence", job->seq); + + amdxdna_pm_suspend_put(job->hwctx->client->xdna); job->hwctx->priv->completed++; dma_fence_signal(fence); up(&job->hwctx->priv->job_sem); job->job_done = true; - dma_fence_put(fence); mmput_async(job->mm); aie2_job_put(job); } @@ -204,10 +203,13 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size) cmd_abo = job->cmd_bo; - if (unlikely(!data)) + if (unlikely(job->job_timeout)) { + amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT); + ret = -EINVAL; goto out; + } - if (unlikely(size != sizeof(u32))) { + if (unlikely(!data) || unlikely(size != sizeof(u32))) { amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT); ret = -EINVAL; goto out; @@ -226,11 +228,10 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size) } static int -aie2_sched_nocmd_resp_handler(void *handle, void __iomem *data, size_t size) +aie2_sched_drvcmd_resp_handler(void *handle, void __iomem *data, size_t size) { struct amdxdna_sched_job *job = handle; int ret = 0; - u32 status; if (unlikely(!data)) goto out; @@ -240,8 +241,7 @@ aie2_sched_nocmd_resp_handler(void *handle, void __iomem *data, size_t size) goto out; } - status = readl(data); - XDNA_DBG(job->hwctx->client->xdna, "Resp status 0x%x", status); + job->drv_cmd->result = readl(data); out: aie2_sched_notify(job); @@ -260,6 +260,13 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size) int ret = 0; cmd_abo = job->cmd_bo; + + if (unlikely(job->job_timeout)) { + amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT); + ret = -EINVAL; + goto out; + } + if (unlikely(!data) || unlikely(size != sizeof(u32) * 3)) { amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT); ret = -EINVAL; @@ -314,8 +321,18 @@ aie2_sched_job_run(struct drm_sched_job *sched_job) kref_get(&job->refcnt); fence = dma_fence_get(job->fence); - if (unlikely(!cmd_abo)) { - ret = aie2_sync_bo(hwctx, job, aie2_sched_nocmd_resp_handler); + if (job->drv_cmd) { + switch (job->drv_cmd->opcode) { + case SYNC_DEBUG_BO: + ret = aie2_sync_bo(hwctx, job, aie2_sched_drvcmd_resp_handler); + break; + case ATTACH_DEBUG_BO: + ret = aie2_config_debug_bo(hwctx, job, aie2_sched_drvcmd_resp_handler); + break; + default: + ret = -EINVAL; + break; + } goto out; } @@ -362,6 +379,7 @@ aie2_sched_job_timedout(struct drm_sched_job *sched_job) xdna = hwctx->client->xdna; trace_xdna_job(sched_job, hwctx->name, "job timedout", job->seq); + job->job_timeout = true; mutex_lock(&xdna->dev_lock); aie2_hwctx_stop(xdna, hwctx, sched_job); @@ -531,13 +549,12 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx) .num_rqs = DRM_SCHED_PRIORITY_COUNT, .credit_limit = HWCTX_MAX_CMDS, .timeout = msecs_to_jiffies(HWCTX_MAX_TIMEOUT), - .name = hwctx->name, + .name = "amdxdna_js", .dev = xdna->ddev.dev, }; struct drm_gpu_scheduler *sched; struct amdxdna_hwctx_priv *priv; struct amdxdna_gem_obj *heap; - struct amdxdna_dev_hdl *ndev; int i, ret; priv = kzalloc(sizeof(*hwctx->priv), GFP_KERNEL); @@ -610,10 +627,14 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx) goto free_entity; } + ret = amdxdna_pm_resume_get(xdna); + if (ret) + goto free_col_list; + ret = aie2_alloc_resource(hwctx); if (ret) { XDNA_ERR(xdna, "Alloc hw resource failed, ret %d", ret); - goto free_col_list; + goto suspend_put; } ret = aie2_map_host_buf(xdna->dev_handle, hwctx->fw_ctx_id, @@ -628,10 +649,9 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx) XDNA_ERR(xdna, "Create syncobj failed, ret %d", ret); goto release_resource; } + amdxdna_pm_suspend_put(xdna); hwctx->status = HWCTX_STAT_INIT; - ndev = xdna->dev_handle; - ndev->hwctx_num++; init_waitqueue_head(&priv->job_free_wq); XDNA_DBG(xdna, "hwctx %s init completed", hwctx->name); @@ -640,6 +660,8 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx) release_resource: aie2_release_resource(hwctx); +suspend_put: + amdxdna_pm_suspend_put(xdna); free_col_list: kfree(hwctx->col_list); free_entity: @@ -662,26 +684,25 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx) void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx) { - struct amdxdna_dev_hdl *ndev; struct amdxdna_dev *xdna; int idx; xdna = hwctx->client->xdna; - ndev = xdna->dev_handle; - ndev->hwctx_num--; XDNA_DBG(xdna, "%s sequence number %lld", hwctx->name, hwctx->priv->seq); - drm_sched_entity_destroy(&hwctx->priv->entity); - aie2_hwctx_wait_for_idle(hwctx); /* Request fw to destroy hwctx and cancel the rest pending requests */ aie2_release_resource(hwctx); + mutex_unlock(&xdna->dev_lock); + drm_sched_entity_destroy(&hwctx->priv->entity); + /* Wait for all submitted jobs to be completed or canceled */ wait_event(hwctx->priv->job_free_wq, atomic64_read(&hwctx->job_submit_cnt) == atomic64_read(&hwctx->job_free_cnt)); + mutex_lock(&xdna->dev_lock); drm_sched_fini(&hwctx->priv->sched); aie2_ctx_syncobj_destroy(hwctx); @@ -697,6 +718,14 @@ void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx) kfree(hwctx->cus); } +static int aie2_config_cu_resp_handler(void *handle, void __iomem *data, size_t size) +{ + struct amdxdna_hwctx *hwctx = handle; + + amdxdna_pm_suspend_put(hwctx->client->xdna); + return 0; +} + static int aie2_hwctx_cu_config(struct amdxdna_hwctx *hwctx, void *buf, u32 size) { struct amdxdna_hwctx_param_config_cu *config = buf; @@ -728,10 +757,14 @@ static int aie2_hwctx_cu_config(struct amdxdna_hwctx *hwctx, void *buf, u32 size if (!hwctx->cus) return -ENOMEM; - ret = aie2_config_cu(hwctx); + ret = amdxdna_pm_resume_get(xdna); + if (ret) + goto free_cus; + + ret = aie2_config_cu(hwctx, aie2_config_cu_resp_handler); if (ret) { XDNA_ERR(xdna, "Config CU to firmware failed, ret %d", ret); - goto free_cus; + goto pm_suspend_put; } wmb(); /* To avoid locking in command submit when check status */ @@ -739,12 +772,82 @@ static int aie2_hwctx_cu_config(struct amdxdna_hwctx *hwctx, void *buf, u32 size return 0; +pm_suspend_put: + amdxdna_pm_suspend_put(xdna); free_cus: kfree(hwctx->cus); hwctx->cus = NULL; return ret; } +static void aie2_cmd_wait(struct amdxdna_hwctx *hwctx, u64 seq) +{ + struct dma_fence *out_fence = aie2_cmd_get_out_fence(hwctx, seq); + + if (!out_fence) { + XDNA_ERR(hwctx->client->xdna, "Failed to get fence"); + return; + } + + dma_fence_wait_timeout(out_fence, false, MAX_SCHEDULE_TIMEOUT); + dma_fence_put(out_fence); +} + +static int aie2_hwctx_cfg_debug_bo(struct amdxdna_hwctx *hwctx, u32 bo_hdl, + bool attach) +{ + struct amdxdna_client *client = hwctx->client; + struct amdxdna_dev *xdna = client->xdna; + struct amdxdna_drv_cmd cmd = { 0 }; + struct amdxdna_gem_obj *abo; + u64 seq; + int ret; + + abo = amdxdna_gem_get_obj(client, bo_hdl, AMDXDNA_BO_DEV); + if (!abo) { + XDNA_ERR(xdna, "Get bo %d failed", bo_hdl); + return -EINVAL; + } + + if (attach) { + if (abo->assigned_hwctx != AMDXDNA_INVALID_CTX_HANDLE) { + ret = -EBUSY; + goto put_obj; + } + cmd.opcode = ATTACH_DEBUG_BO; + } else { + if (abo->assigned_hwctx != hwctx->id) { + ret = -EINVAL; + goto put_obj; + } + cmd.opcode = DETACH_DEBUG_BO; + } + + ret = amdxdna_cmd_submit(client, &cmd, AMDXDNA_INVALID_BO_HANDLE, + &bo_hdl, 1, hwctx->id, &seq); + if (ret) { + XDNA_ERR(xdna, "Submit command failed"); + goto put_obj; + } + + aie2_cmd_wait(hwctx, seq); + if (cmd.result) { + XDNA_ERR(xdna, "Response failure 0x%x", cmd.result); + goto put_obj; + } + + if (attach) + abo->assigned_hwctx = hwctx->id; + else + abo->assigned_hwctx = AMDXDNA_INVALID_CTX_HANDLE; + + XDNA_DBG(xdna, "Config debug BO %d to %s", bo_hdl, hwctx->name); + +put_obj: + amdxdna_gem_put_obj(abo); + return ret; +} + int aie2_hwctx_config(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *buf, u32 size) { struct amdxdna_dev *xdna = hwctx->client->xdna; @@ -754,14 +857,40 @@ int aie2_hwctx_config(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *bu case DRM_AMDXDNA_HWCTX_CONFIG_CU: return aie2_hwctx_cu_config(hwctx, buf, size); case DRM_AMDXDNA_HWCTX_ASSIGN_DBG_BUF: + return aie2_hwctx_cfg_debug_bo(hwctx, (u32)value, true); case DRM_AMDXDNA_HWCTX_REMOVE_DBG_BUF: - return -EOPNOTSUPP; + return aie2_hwctx_cfg_debug_bo(hwctx, (u32)value, false); default: XDNA_DBG(xdna, "Not supported type %d", type); return -EOPNOTSUPP; } } +int aie2_hwctx_sync_debug_bo(struct amdxdna_hwctx *hwctx, u32 debug_bo_hdl) +{ + struct amdxdna_client *client = hwctx->client; + struct amdxdna_dev *xdna = client->xdna; + struct amdxdna_drv_cmd cmd = { 0 }; + u64 seq; + int ret; + + cmd.opcode = SYNC_DEBUG_BO; + ret = amdxdna_cmd_submit(client, &cmd, AMDXDNA_INVALID_BO_HANDLE, + &debug_bo_hdl, 1, hwctx->id, &seq); + if (ret) { + XDNA_ERR(xdna, "Submit command failed"); + return ret; + } + + aie2_cmd_wait(hwctx, seq); + if (cmd.result) { + XDNA_ERR(xdna, "Response failure 0x%x", cmd.result); + return -EINVAL; + } + + return 0; +} + static int aie2_populate_range(struct amdxdna_gem_obj *abo) { struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev); @@ -862,11 +991,15 @@ int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, goto free_chain; } + ret = amdxdna_pm_resume_get(xdna); + if (ret) + goto cleanup_job; + retry: ret = drm_gem_lock_reservations(job->bos, job->bo_cnt, &acquire_ctx); if (ret) { XDNA_WARN(xdna, "Failed to lock BOs, ret %d", ret); - goto cleanup_job; + goto suspend_put; } for (i = 0; i < job->bo_cnt; i++) { @@ -874,7 +1007,7 @@ int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, if (ret) { XDNA_WARN(xdna, "Failed to reserve fences %d", ret); drm_gem_unlock_reservations(job->bos, job->bo_cnt, &acquire_ctx); - goto cleanup_job; + goto suspend_put; } } @@ -889,12 +1022,12 @@ int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); } else if (time_after(jiffies, timeout)) { ret = -ETIME; - goto cleanup_job; + goto suspend_put; } ret = aie2_populate_range(abo); if (ret) - goto cleanup_job; + goto suspend_put; goto retry; } } @@ -920,6 +1053,8 @@ int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, return 0; +suspend_put: + amdxdna_pm_suspend_put(xdna); cleanup_job: drm_sched_job_cleanup(&job->base); free_chain: diff --git a/drivers/accel/amdxdna/aie2_error.c b/drivers/accel/amdxdna/aie2_error.c index 5ee905632a393..d452008ec4f49 100644 --- a/drivers/accel/amdxdna/aie2_error.c +++ b/drivers/accel/amdxdna/aie2_error.c @@ -13,6 +13,7 @@ #include "aie2_msg_priv.h" #include "aie2_pci.h" +#include "amdxdna_error.h" #include "amdxdna_mailbox.h" #include "amdxdna_pci_drv.h" @@ -46,6 +47,7 @@ enum aie_module_type { AIE_MEM_MOD = 0, AIE_CORE_MOD, AIE_PL_MOD, + AIE_UNKNOWN_MOD, }; enum aie_error_category { @@ -143,6 +145,31 @@ static const struct aie_event_category aie_ml_shim_tile_event_cat[] = { EVENT_CATEGORY(74U, AIE_ERROR_LOCK), }; +static const enum amdxdna_error_num aie_cat_err_num_map[] = { + [AIE_ERROR_SATURATION] = AMDXDNA_ERROR_NUM_AIE_SATURATION, + [AIE_ERROR_FP] = AMDXDNA_ERROR_NUM_AIE_FP, + [AIE_ERROR_STREAM] = AMDXDNA_ERROR_NUM_AIE_STREAM, + [AIE_ERROR_ACCESS] = AMDXDNA_ERROR_NUM_AIE_ACCESS, + [AIE_ERROR_BUS] = AMDXDNA_ERROR_NUM_AIE_BUS, + [AIE_ERROR_INSTRUCTION] = AMDXDNA_ERROR_NUM_AIE_INSTRUCTION, + [AIE_ERROR_ECC] = AMDXDNA_ERROR_NUM_AIE_ECC, + [AIE_ERROR_LOCK] = AMDXDNA_ERROR_NUM_AIE_LOCK, + [AIE_ERROR_DMA] = AMDXDNA_ERROR_NUM_AIE_DMA, + [AIE_ERROR_MEM_PARITY] = AMDXDNA_ERROR_NUM_AIE_MEM_PARITY, + [AIE_ERROR_UNKNOWN] = AMDXDNA_ERROR_NUM_UNKNOWN, +}; + +static_assert(ARRAY_SIZE(aie_cat_err_num_map) == AIE_ERROR_UNKNOWN + 1); + +static const enum amdxdna_error_module aie_err_mod_map[] = { + [AIE_MEM_MOD] = AMDXDNA_ERROR_MODULE_AIE_MEMORY, + [AIE_CORE_MOD] = AMDXDNA_ERROR_MODULE_AIE_CORE, + [AIE_PL_MOD] = AMDXDNA_ERROR_MODULE_AIE_PL, + [AIE_UNKNOWN_MOD] = AMDXDNA_ERROR_MODULE_UNKNOWN, +}; + +static_assert(ARRAY_SIZE(aie_err_mod_map) == AIE_UNKNOWN_MOD + 1); + static enum aie_error_category aie_get_error_category(u8 row, u8 event_id, enum aie_module_type mod_type) { @@ -176,12 +203,40 @@ aie_get_error_category(u8 row, u8 event_id, enum aie_module_type mod_type) if (event_id != lut[i].event_id) continue; + if (lut[i].category > AIE_ERROR_UNKNOWN) + return AIE_ERROR_UNKNOWN; + return lut[i].category; } return AIE_ERROR_UNKNOWN; } +static void aie2_update_last_async_error(struct amdxdna_dev_hdl *ndev, void *err_info, u32 num_err) +{ + struct aie_error *errs = err_info; + enum amdxdna_error_module err_mod; + enum aie_error_category aie_err; + enum amdxdna_error_num err_num; + struct aie_error *last_err; + + last_err = &errs[num_err - 1]; + if (last_err->mod_type >= AIE_UNKNOWN_MOD) { + err_num = aie_cat_err_num_map[AIE_ERROR_UNKNOWN]; + err_mod = aie_err_mod_map[AIE_UNKNOWN_MOD]; + } else { + aie_err = aie_get_error_category(last_err->row, + last_err->event_id, + last_err->mod_type); + err_num = aie_cat_err_num_map[aie_err]; + err_mod = aie_err_mod_map[last_err->mod_type]; + } + + ndev->last_async_err.err_code = AMDXDNA_ERROR_ENCODE(err_num, err_mod); + ndev->last_async_err.ts_us = ktime_to_us(ktime_get_real()); + ndev->last_async_err.ex_err_code = AMDXDNA_EXTRA_ERR_ENCODE(last_err->row, last_err->col); +} + static u32 aie2_error_backtrack(struct amdxdna_dev_hdl *ndev, void *err_info, u32 num_err) { struct aie_error *errs = err_info; @@ -264,29 +319,14 @@ static void aie2_error_worker(struct work_struct *err_work) } mutex_lock(&xdna->dev_lock); + aie2_update_last_async_error(e->ndev, info->payload, info->err_cnt); + /* Re-sent this event to firmware */ if (aie2_error_event_send(e)) XDNA_WARN(xdna, "Unable to register async event"); mutex_unlock(&xdna->dev_lock); } -int aie2_error_async_events_send(struct amdxdna_dev_hdl *ndev) -{ - struct amdxdna_dev *xdna = ndev->xdna; - struct async_event *e; - int i, ret; - - drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); - for (i = 0; i < ndev->async_events->event_cnt; i++) { - e = &ndev->async_events->event[i]; - ret = aie2_error_event_send(e); - if (ret) - return ret; - } - - return 0; -} - void aie2_error_async_events_free(struct amdxdna_dev_hdl *ndev) { struct amdxdna_dev *xdna = ndev->xdna; @@ -341,6 +381,10 @@ int aie2_error_async_events_alloc(struct amdxdna_dev_hdl *ndev) e->size = ASYNC_BUF_SIZE; e->resp.status = MAX_AIE2_STATUS_CODE; INIT_WORK(&e->work, aie2_error_worker); + + ret = aie2_error_event_send(e); + if (ret) + goto free_wq; } ndev->async_events = events; @@ -349,6 +393,8 @@ int aie2_error_async_events_alloc(struct amdxdna_dev_hdl *ndev) events->event_cnt, events->size); return 0; +free_wq: + destroy_workqueue(events->wq); free_buf: dma_free_noncoherent(xdna->ddev.dev, events->size, events->buf, events->addr, DMA_FROM_DEVICE); @@ -356,3 +402,18 @@ int aie2_error_async_events_alloc(struct amdxdna_dev_hdl *ndev) kfree(events); return ret; } + +int aie2_get_array_async_error(struct amdxdna_dev_hdl *ndev, struct amdxdna_drm_get_array *args) +{ + struct amdxdna_dev *xdna = ndev->xdna; + + drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); + + args->num_element = 1; + args->element_size = sizeof(ndev->last_async_err); + if (copy_to_user(u64_to_user_ptr(args->buffer), + &ndev->last_async_err, args->element_size)) + return -EFAULT; + + return 0; +} diff --git a/drivers/accel/amdxdna/aie2_message.c b/drivers/accel/amdxdna/aie2_message.c index 9caad083543dc..d493bb1c33606 100644 --- a/drivers/accel/amdxdna/aie2_message.c +++ b/drivers/accel/amdxdna/aie2_message.c @@ -27,6 +27,8 @@ #define DECLARE_AIE2_MSG(name, op) \ DECLARE_XDNA_MSG_COMMON(name, op, MAX_AIE2_STATUS_CODE) +#define EXEC_MSG_OPS(xdna) ((xdna)->dev_handle->exec_msg_ops) + static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev, struct xdna_mailbox_msg *msg) { @@ -37,7 +39,7 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev, if (!ndev->mgmt_chann) return -ENODEV; - drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); + drm_WARN_ON(&xdna->ddev, xdna->rpm_on && !mutex_is_locked(&xdna->dev_lock)); ret = xdna_send_msg_wait(xdna, ndev->mgmt_chann, msg); if (ret == -ETIME) { xdna_mailbox_stop_channel(ndev->mgmt_chann); @@ -45,7 +47,7 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev, ndev->mgmt_chann = NULL; } - if (!ret && *hdl->data != AIE2_STATUS_SUCCESS) { + if (!ret && *hdl->status != AIE2_STATUS_SUCCESS) { XDNA_ERR(xdna, "command opcode 0x%x failed, status 0x%x", msg->opcode, *hdl->data); ret = -EINVAL; @@ -208,6 +210,14 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct hwctx->fw_ctx_id = resp.context_id; WARN_ONCE(hwctx->fw_ctx_id == -1, "Unexpected context id"); + if (ndev->force_preempt_enabled) { + ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_FORCE_PREEMPT, &hwctx->fw_ctx_id); + if (ret) { + XDNA_ERR(xdna, "failed to enable force preempt %d", ret); + return ret; + } + } + cq_pair = &resp.cq_pair[0]; x2i.mb_head_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->x2i_q.head_addr); x2i.mb_tail_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->x2i_q.tail_addr); @@ -233,6 +243,7 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct ret = -EINVAL; goto out_destroy_context; } + ndev->hwctx_num++; XDNA_DBG(xdna, "%s mailbox channel irq: %d, msix_id: %d", hwctx->name, ret, resp.msix_id); @@ -267,6 +278,7 @@ int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwc hwctx->fw_ctx_id); hwctx->priv->mbox_chann = NULL; hwctx->fw_ctx_id = -1; + ndev->hwctx_num--; return ret; } @@ -332,11 +344,6 @@ int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf, goto fail; } - if (resp.status != AIE2_STATUS_SUCCESS) { - XDNA_ERR(xdna, "Query NPU status failed, status 0x%x", resp.status); - ret = -EINVAL; - goto fail; - } XDNA_DBG(xdna, "Query NPU status completed"); if (size < resp.size) { @@ -358,6 +365,55 @@ int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf, return ret; } +int aie2_query_telemetry(struct amdxdna_dev_hdl *ndev, + char __user *buf, u32 size, + struct amdxdna_drm_query_telemetry_header *header) +{ + DECLARE_AIE2_MSG(get_telemetry, MSG_OP_GET_TELEMETRY); + struct amdxdna_dev *xdna = ndev->xdna; + dma_addr_t dma_addr; + u8 *addr; + int ret; + + if (header->type >= MAX_TELEMETRY_TYPE) + return -EINVAL; + + addr = dma_alloc_noncoherent(xdna->ddev.dev, size, &dma_addr, + DMA_FROM_DEVICE, GFP_KERNEL); + if (!addr) + return -ENOMEM; + + req.buf_addr = dma_addr; + req.buf_size = size; + req.type = header->type; + + drm_clflush_virt_range(addr, size); /* device can access */ + ret = aie2_send_mgmt_msg_wait(ndev, &msg); + if (ret) { + XDNA_ERR(xdna, "Query telemetry failed, status %d", ret); + goto free_buf; + } + + if (size < resp.size) { + ret = -EINVAL; + XDNA_ERR(xdna, "Bad buffer size. Available: %u. Needs: %u", size, resp.size); + goto free_buf; + } + + if (copy_to_user(buf, addr, resp.size)) { + ret = -EFAULT; + XDNA_ERR(xdna, "Failed to copy telemetry to user space"); + goto free_buf; + } + + header->major = resp.major; + header->minor = resp.minor; + +free_buf: + dma_free_noncoherent(xdna->ddev.dev, size, addr, dma_addr, DMA_FROM_DEVICE); + return ret; +} + int aie2_register_asyn_event_msg(struct amdxdna_dev_hdl *ndev, dma_addr_t addr, u32 size, void *handle, int (*cb)(void*, void __iomem *, size_t)) { @@ -377,15 +433,17 @@ int aie2_register_asyn_event_msg(struct amdxdna_dev_hdl *ndev, dma_addr_t addr, return xdna_mailbox_send_msg(ndev->mgmt_chann, &msg, TX_TIMEOUT); } -int aie2_config_cu(struct amdxdna_hwctx *hwctx) +int aie2_config_cu(struct amdxdna_hwctx *hwctx, + int (*notify_cb)(void *, void __iomem *, size_t)) { struct mailbox_channel *chann = hwctx->priv->mbox_chann; struct amdxdna_dev *xdna = hwctx->client->xdna; u32 shift = xdna->dev_info->dev_mem_buf_shift; - DECLARE_AIE2_MSG(config_cu, MSG_OP_CONFIG_CU); + struct config_cu_req req = { 0 }; + struct xdna_mailbox_msg msg; struct drm_gem_object *gobj; struct amdxdna_gem_obj *abo; - int ret, i; + int i; if (!chann) return -ENODEV; @@ -423,191 +481,386 @@ int aie2_config_cu(struct amdxdna_hwctx *hwctx) } req.num_cus = hwctx->cus->num_cus; - ret = xdna_send_msg_wait(xdna, chann, &msg); - if (ret == -ETIME) - aie2_destroy_context(xdna->dev_handle, hwctx); + msg.send_data = (u8 *)&req; + msg.send_size = sizeof(req); + msg.handle = hwctx; + msg.opcode = MSG_OP_CONFIG_CU; + msg.notify_cb = notify_cb; + return xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); +} - if (resp.status == AIE2_STATUS_SUCCESS) { - XDNA_DBG(xdna, "Configure %d CUs, ret %d", req.num_cus, ret); - return 0; - } +static int aie2_init_exec_cu_req(struct amdxdna_gem_obj *cmd_bo, void *req, + size_t *size, u32 *msg_op) +{ + struct execute_buffer_req *cu_req = req; + u32 cmd_len; + void *cmd; - XDNA_ERR(xdna, "Command opcode 0x%x failed, status 0x%x ret %d", - msg.opcode, resp.status, ret); - return ret; + cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); + if (cmd_len > sizeof(cu_req->payload)) + return -EINVAL; + + cu_req->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); + if (cu_req->cu_idx == INVALID_CU_IDX) + return -EINVAL; + + memcpy(cu_req->payload, cmd, cmd_len); + + *size = sizeof(*cu_req); + *msg_op = MSG_OP_EXECUTE_BUFFER_CF; + return 0; } -int aie2_execbuf(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, - int (*notify_cb)(void *, void __iomem *, size_t)) +static int aie2_init_exec_dpu_req(struct amdxdna_gem_obj *cmd_bo, void *req, + size_t *size, u32 *msg_op) { - struct mailbox_channel *chann = hwctx->priv->mbox_chann; - struct amdxdna_dev *xdna = hwctx->client->xdna; - struct amdxdna_gem_obj *cmd_abo = job->cmd_bo; - union { - struct execute_buffer_req ebuf; - struct exec_dpu_req dpu; - } req; - struct xdna_mailbox_msg msg; - u32 payload_len; - void *payload; - int cu_idx; - int ret; - u32 op; + struct exec_dpu_req *dpu_req = req; + struct amdxdna_cmd_start_npu *sn; + u32 cmd_len; - if (!chann) - return -ENODEV; + sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); + if (cmd_len - sizeof(*sn) > sizeof(dpu_req->payload)) + return -EINVAL; - payload = amdxdna_cmd_get_payload(cmd_abo, &payload_len); - if (!payload) { - XDNA_ERR(xdna, "Invalid command, cannot get payload"); + dpu_req->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); + if (dpu_req->cu_idx == INVALID_CU_IDX) return -EINVAL; - } - cu_idx = amdxdna_cmd_get_cu_idx(cmd_abo); - if (cu_idx < 0) { - XDNA_DBG(xdna, "Invalid cu idx"); + dpu_req->inst_buf_addr = sn->buffer; + dpu_req->inst_size = sn->buffer_size; + dpu_req->inst_prop_cnt = sn->prop_count; + memcpy(dpu_req->payload, sn->prop_args, cmd_len - sizeof(*sn)); + + *size = sizeof(*dpu_req); + *msg_op = MSG_OP_EXEC_DPU; + return 0; +} + +static void aie2_init_exec_chain_req(void *req, u64 slot_addr, size_t size, u32 cmd_cnt) +{ + struct cmd_chain_req *chain_req = req; + + chain_req->buf_addr = slot_addr; + chain_req->buf_size = size; + chain_req->count = cmd_cnt; +} + +static void aie2_init_npu_chain_req(void *req, u64 slot_addr, size_t size, u32 cmd_cnt) +{ + struct cmd_chain_npu_req *npu_chain_req = req; + + npu_chain_req->flags = 0; + npu_chain_req->reserved = 0; + npu_chain_req->buf_addr = slot_addr; + npu_chain_req->buf_size = size; + npu_chain_req->count = cmd_cnt; +} + +static int +aie2_cmdlist_fill_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) +{ + struct cmd_chain_slot_execbuf_cf *cf_slot = slot; + u32 cmd_len; + void *cmd; + + cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); + if (*size < sizeof(*cf_slot) + cmd_len) return -EINVAL; - } - op = amdxdna_cmd_get_op(cmd_abo); - switch (op) { + cf_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); + if (cf_slot->cu_idx == INVALID_CU_IDX) + return -EINVAL; + + cf_slot->arg_cnt = cmd_len / sizeof(u32); + memcpy(cf_slot->args, cmd, cmd_len); + /* Accurate slot size to hint firmware to do necessary copy */ + *size = sizeof(*cf_slot) + cmd_len; + return 0; +} + +static int +aie2_cmdlist_fill_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) +{ + struct cmd_chain_slot_dpu *dpu_slot = slot; + struct amdxdna_cmd_start_npu *sn; + u32 cmd_len; + u32 arg_sz; + + sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); + arg_sz = cmd_len - sizeof(*sn); + if (cmd_len < sizeof(*sn) || arg_sz > MAX_DPU_ARGS_SIZE) + return -EINVAL; + + if (*size < sizeof(*dpu_slot) + arg_sz) + return -EINVAL; + + dpu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); + if (dpu_slot->cu_idx == INVALID_CU_IDX) + return -EINVAL; + + dpu_slot->inst_buf_addr = sn->buffer; + dpu_slot->inst_size = sn->buffer_size; + dpu_slot->inst_prop_cnt = sn->prop_count; + dpu_slot->arg_cnt = arg_sz / sizeof(u32); + memcpy(dpu_slot->args, sn->prop_args, arg_sz); + + /* Accurate slot size to hint firmware to do necessary copy */ + *size = sizeof(*dpu_slot) + arg_sz; + return 0; +} + +static int aie2_cmdlist_unsupp(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) +{ + return -EOPNOTSUPP; +} + +static u32 aie2_get_chain_msg_op(u32 cmd_op) +{ + switch (cmd_op) { case ERT_START_CU: - if (unlikely(payload_len > sizeof(req.ebuf.payload))) - XDNA_DBG(xdna, "Invalid ebuf payload len: %d", payload_len); - req.ebuf.cu_idx = cu_idx; - memcpy(req.ebuf.payload, payload, sizeof(req.ebuf.payload)); - msg.send_size = sizeof(req.ebuf); - msg.opcode = MSG_OP_EXECUTE_BUFFER_CF; - break; - case ERT_START_NPU: { - struct amdxdna_cmd_start_npu *sn = payload; - - if (unlikely(payload_len - sizeof(*sn) > sizeof(req.dpu.payload))) - XDNA_DBG(xdna, "Invalid dpu payload len: %d", payload_len); - req.dpu.inst_buf_addr = sn->buffer; - req.dpu.inst_size = sn->buffer_size; - req.dpu.inst_prop_cnt = sn->prop_count; - req.dpu.cu_idx = cu_idx; - memcpy(req.dpu.payload, sn->prop_args, sizeof(req.dpu.payload)); - msg.send_size = sizeof(req.dpu); - msg.opcode = MSG_OP_EXEC_DPU; + return MSG_OP_CHAIN_EXEC_BUFFER_CF; + case ERT_START_NPU: + return MSG_OP_CHAIN_EXEC_DPU; + default: break; } - default: - XDNA_DBG(xdna, "Invalid ERT cmd op code: %d", op); + + return MSG_OP_MAX_OPCODE; +} + +static struct aie2_exec_msg_ops legacy_exec_message_ops = { + .init_cu_req = aie2_init_exec_cu_req, + .init_dpu_req = aie2_init_exec_dpu_req, + .init_chain_req = aie2_init_exec_chain_req, + .fill_cf_slot = aie2_cmdlist_fill_cf, + .fill_dpu_slot = aie2_cmdlist_fill_dpu, + .fill_preempt_slot = aie2_cmdlist_unsupp, + .fill_elf_slot = aie2_cmdlist_unsupp, + .get_chain_msg_op = aie2_get_chain_msg_op, +}; + +static int +aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) +{ + struct cmd_chain_slot_npu *npu_slot = slot; + u32 cmd_len; + void *cmd; + + cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); + if (*size < sizeof(*npu_slot) + cmd_len) return -EINVAL; - } - msg.handle = job; - msg.notify_cb = notify_cb; - msg.send_data = (u8 *)&req; - print_hex_dump_debug("cmd: ", DUMP_PREFIX_OFFSET, 16, 4, &req, - 0x40, false); - ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); - if (ret) { - XDNA_ERR(xdna, "Send message failed"); - return ret; - } + npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); + if (npu_slot->cu_idx == INVALID_CU_IDX) + return -EINVAL; + memset(npu_slot, 0, sizeof(*npu_slot)); + npu_slot->type = EXEC_NPU_TYPE_NON_ELF; + npu_slot->arg_cnt = cmd_len / sizeof(u32); + memcpy(npu_slot->args, cmd, cmd_len); + + *size = sizeof(*npu_slot) + cmd_len; return 0; } static int -aie2_cmdlist_fill_one_slot_cf(void *cmd_buf, u32 offset, - struct amdxdna_gem_obj *abo, u32 *size) +aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) { - struct cmd_chain_slot_execbuf_cf *buf = cmd_buf + offset; - int cu_idx = amdxdna_cmd_get_cu_idx(abo); - u32 payload_len; - void *payload; + struct cmd_chain_slot_npu *npu_slot = slot; + struct amdxdna_cmd_start_npu *sn; + u32 cmd_len; + u32 arg_sz; - if (cu_idx < 0) + sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); + arg_sz = cmd_len - sizeof(*sn); + if (cmd_len < sizeof(*sn) || arg_sz > MAX_NPU_ARGS_SIZE) return -EINVAL; - payload = amdxdna_cmd_get_payload(abo, &payload_len); - if (!payload) + if (*size < sizeof(*npu_slot) + arg_sz) return -EINVAL; - if (!slot_has_space(*buf, offset, payload_len)) - return -ENOSPC; + npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); + if (npu_slot->cu_idx == INVALID_CU_IDX) + return -EINVAL; + + memset(npu_slot, 0, sizeof(*npu_slot)); + npu_slot->type = EXEC_NPU_TYPE_PARTIAL_ELF; + npu_slot->inst_buf_addr = sn->buffer; + npu_slot->inst_size = sn->buffer_size; + npu_slot->inst_prop_cnt = sn->prop_count; + npu_slot->arg_cnt = arg_sz / sizeof(u32); + memcpy(npu_slot->args, sn->prop_args, arg_sz); - buf->cu_idx = cu_idx; - buf->arg_cnt = payload_len / sizeof(u32); - memcpy(buf->args, payload, payload_len); - /* Accurate buf size to hint firmware to do necessary copy */ - *size = sizeof(*buf) + payload_len; + *size = sizeof(*npu_slot) + arg_sz; return 0; } static int -aie2_cmdlist_fill_one_slot_dpu(void *cmd_buf, u32 offset, - struct amdxdna_gem_obj *abo, u32 *size) +aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) { - struct cmd_chain_slot_dpu *buf = cmd_buf + offset; - int cu_idx = amdxdna_cmd_get_cu_idx(abo); - struct amdxdna_cmd_start_npu *sn; - u32 payload_len; - void *payload; + struct cmd_chain_slot_npu *npu_slot = slot; + struct amdxdna_cmd_preempt_data *pd; + u32 cmd_len; u32 arg_sz; - if (cu_idx < 0) + pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); + arg_sz = cmd_len - sizeof(*pd); + if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE) return -EINVAL; - payload = amdxdna_cmd_get_payload(abo, &payload_len); - if (!payload) + if (*size < sizeof(*npu_slot) + arg_sz) return -EINVAL; - sn = payload; - arg_sz = payload_len - sizeof(*sn); - if (payload_len < sizeof(*sn) || arg_sz > MAX_DPU_ARGS_SIZE) + + npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); + if (npu_slot->cu_idx == INVALID_CU_IDX) return -EINVAL; - if (!slot_has_space(*buf, offset, arg_sz)) - return -ENOSPC; + memset(npu_slot, 0, sizeof(*npu_slot)); + npu_slot->type = EXEC_NPU_TYPE_PREEMPT; + npu_slot->inst_buf_addr = pd->inst_buf; + npu_slot->save_buf_addr = pd->save_buf; + npu_slot->restore_buf_addr = pd->restore_buf; + npu_slot->inst_size = pd->inst_size; + npu_slot->save_size = pd->save_size; + npu_slot->restore_size = pd->restore_size; + npu_slot->inst_prop_cnt = pd->inst_prop_cnt; + npu_slot->arg_cnt = arg_sz / sizeof(u32); + memcpy(npu_slot->args, pd->prop_args, arg_sz); + + *size = sizeof(*npu_slot) + arg_sz; + return 0; +} + +static int +aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) +{ + struct cmd_chain_slot_npu *npu_slot = slot; + struct amdxdna_cmd_preempt_data *pd; + u32 cmd_len; + u32 arg_sz; + + pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); + arg_sz = cmd_len - sizeof(*pd); + if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE) + return -EINVAL; - buf->inst_buf_addr = sn->buffer; - buf->inst_size = sn->buffer_size; - buf->inst_prop_cnt = sn->prop_count; - buf->cu_idx = cu_idx; - buf->arg_cnt = arg_sz / sizeof(u32); - memcpy(buf->args, sn->prop_args, arg_sz); + if (*size < sizeof(*npu_slot) + arg_sz) + return -EINVAL; - /* Accurate buf size to hint firmware to do necessary copy */ - *size = sizeof(*buf) + arg_sz; + memset(npu_slot, 0, sizeof(*npu_slot)); + npu_slot->type = EXEC_NPU_TYPE_ELF; + npu_slot->inst_buf_addr = pd->inst_buf; + npu_slot->save_buf_addr = pd->save_buf; + npu_slot->restore_buf_addr = pd->restore_buf; + npu_slot->inst_size = pd->inst_size; + npu_slot->save_size = pd->save_size; + npu_slot->restore_size = pd->restore_size; + npu_slot->inst_prop_cnt = pd->inst_prop_cnt; + npu_slot->arg_cnt = 1; + npu_slot->args[0] = AIE2_EXEC_BUFFER_KERNEL_OP_TXN; + + *size = struct_size(npu_slot, args, npu_slot->arg_cnt); return 0; } -static int -aie2_cmdlist_fill_one_slot(u32 op, struct amdxdna_gem_obj *cmdbuf_abo, u32 offset, - struct amdxdna_gem_obj *abo, u32 *size) +static u32 aie2_get_npu_chain_msg_op(u32 cmd_op) +{ + return MSG_OP_CHAIN_EXEC_NPU; +} + +static struct aie2_exec_msg_ops npu_exec_message_ops = { + .init_cu_req = aie2_init_exec_cu_req, + .init_dpu_req = aie2_init_exec_dpu_req, + .init_chain_req = aie2_init_npu_chain_req, + .fill_cf_slot = aie2_cmdlist_fill_npu_cf, + .fill_dpu_slot = aie2_cmdlist_fill_npu_dpu, + .fill_preempt_slot = aie2_cmdlist_fill_npu_preempt, + .fill_elf_slot = aie2_cmdlist_fill_npu_elf, + .get_chain_msg_op = aie2_get_npu_chain_msg_op, +}; + +static int aie2_init_exec_req(void *req, struct amdxdna_gem_obj *cmd_abo, + size_t *size, u32 *msg_op) { - u32 this_op = amdxdna_cmd_get_op(abo); - void *cmd_buf = cmdbuf_abo->mem.kva; + struct amdxdna_dev *xdna = cmd_abo->client->xdna; int ret; + u32 op; - if (this_op != op) { - ret = -EINVAL; - goto done; - } + op = amdxdna_cmd_get_op(cmd_abo); switch (op) { case ERT_START_CU: - ret = aie2_cmdlist_fill_one_slot_cf(cmd_buf, offset, abo, size); + ret = EXEC_MSG_OPS(xdna)->init_cu_req(cmd_abo, req, size, msg_op); + if (ret) { + XDNA_DBG(xdna, "Init CU req failed ret %d", ret); + return ret; + } break; case ERT_START_NPU: - ret = aie2_cmdlist_fill_one_slot_dpu(cmd_buf, offset, abo, size); + ret = EXEC_MSG_OPS(xdna)->init_dpu_req(cmd_abo, req, size, msg_op); + if (ret) { + XDNA_DBG(xdna, "Init DPU req failed ret %d", ret); + return ret; + } + break; default: + XDNA_ERR(xdna, "Unsupported op %d", op); ret = -EOPNOTSUPP; + break; } -done: - if (ret) { - XDNA_ERR(abo->client->xdna, "Can't fill slot for cmd op %d ret %d", - op, ret); + return ret; +} + +static int +aie2_cmdlist_fill_slot(void *slot, struct amdxdna_gem_obj *cmd_abo, + size_t *size, u32 *cmd_op) +{ + struct amdxdna_dev *xdna = cmd_abo->client->xdna; + int ret; + u32 op; + + op = amdxdna_cmd_get_op(cmd_abo); + if (*cmd_op == ERT_INVALID_CMD) + *cmd_op = op; + else if (op != *cmd_op) + return -EINVAL; + + switch (op) { + case ERT_START_CU: + ret = EXEC_MSG_OPS(xdna)->fill_cf_slot(cmd_abo, slot, size); + break; + case ERT_START_NPU: + ret = EXEC_MSG_OPS(xdna)->fill_dpu_slot(cmd_abo, slot, size); + break; + case ERT_START_NPU_PREEMPT: + if (!AIE2_FEATURE_ON(xdna->dev_handle, AIE2_PREEMPT)) + return -EOPNOTSUPP; + ret = EXEC_MSG_OPS(xdna)->fill_preempt_slot(cmd_abo, slot, size); + break; + case ERT_START_NPU_PREEMPT_ELF: + if (!AIE2_FEATURE_ON(xdna->dev_handle, AIE2_PREEMPT)) + return -EOPNOTSUPP; + ret = EXEC_MSG_OPS(xdna)->fill_elf_slot(cmd_abo, slot, size); + break; + default: + XDNA_INFO(xdna, "Unsupported op %d", op); + ret = -EOPNOTSUPP; + break; } + return ret; } +void aie2_msg_init(struct amdxdna_dev_hdl *ndev) +{ + if (AIE2_FEATURE_ON(ndev, AIE2_NPU_COMMAND)) + ndev->exec_msg_ops = &npu_exec_message_ops; + else + ndev->exec_msg_ops = &legacy_exec_message_ops; +} + static inline struct amdxdna_gem_obj * aie2_cmdlist_get_cmd_buf(struct amdxdna_sched_job *job) { @@ -616,29 +869,36 @@ aie2_cmdlist_get_cmd_buf(struct amdxdna_sched_job *job) return job->hwctx->priv->cmd_buf[idx]; } -static void -aie2_cmdlist_prepare_request(struct cmd_chain_req *req, - struct amdxdna_gem_obj *cmdbuf_abo, u32 size, u32 cnt) +int aie2_execbuf(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, + int (*notify_cb)(void *, void __iomem *, size_t)) { - req->buf_addr = cmdbuf_abo->mem.dev_addr; - req->buf_size = size; - req->count = cnt; - drm_clflush_virt_range(cmdbuf_abo->mem.kva, size); - XDNA_DBG(cmdbuf_abo->client->xdna, "Command buf addr 0x%llx size 0x%x count %d", - req->buf_addr, size, cnt); -} + struct mailbox_channel *chann = hwctx->priv->mbox_chann; + struct amdxdna_dev *xdna = hwctx->client->xdna; + struct amdxdna_gem_obj *cmd_abo = job->cmd_bo; + struct xdna_mailbox_msg msg; + union exec_req req; + int ret; -static inline u32 -aie2_cmd_op_to_msg_op(u32 op) -{ - switch (op) { - case ERT_START_CU: - return MSG_OP_CHAIN_EXEC_BUFFER_CF; - case ERT_START_NPU: - return MSG_OP_CHAIN_EXEC_DPU; - default: - return MSG_OP_MAX_OPCODE; + if (!chann) + return -ENODEV; + + ret = aie2_init_exec_req(&req, cmd_abo, &msg.send_size, &msg.opcode); + if (ret) + return ret; + + msg.handle = job; + msg.notify_cb = notify_cb; + msg.send_data = (u8 *)&req; + print_hex_dump_debug("cmd: ", DUMP_PREFIX_OFFSET, 16, 4, &req, + 0x40, false); + + ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); + if (ret) { + XDNA_ERR(xdna, "Send message failed"); + return ret; } + + return 0; } int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx, @@ -649,12 +909,13 @@ int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx, struct mailbox_channel *chann = hwctx->priv->mbox_chann; struct amdxdna_client *client = hwctx->client; struct amdxdna_gem_obj *cmd_abo = job->cmd_bo; + struct amdxdna_dev *xdna = client->xdna; struct amdxdna_cmd_chain *payload; struct xdna_mailbox_msg msg; - struct cmd_chain_req req; + union exec_chain_req req; u32 payload_len; u32 offset = 0; - u32 size; + size_t size; int ret; u32 op; u32 i; @@ -665,41 +926,42 @@ int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx, payload_len < struct_size(payload, data, payload->command_count)) return -EINVAL; + op = ERT_INVALID_CMD; for (i = 0; i < payload->command_count; i++) { u32 boh = (u32)(payload->data[i]); struct amdxdna_gem_obj *abo; abo = amdxdna_gem_get_obj(client, boh, AMDXDNA_BO_CMD); if (!abo) { - XDNA_ERR(client->xdna, "Failed to find cmd BO %d", boh); + XDNA_ERR(xdna, "Failed to find cmd BO %d", boh); return -ENOENT; } - /* All sub-cmd should have same op, use the first one. */ - if (i == 0) - op = amdxdna_cmd_get_op(abo); - - ret = aie2_cmdlist_fill_one_slot(op, cmdbuf_abo, offset, abo, &size); + size = cmdbuf_abo->mem.size - offset; + ret = aie2_cmdlist_fill_slot(cmdbuf_abo->mem.kva + offset, + abo, &size, &op); amdxdna_gem_put_obj(abo); if (ret) - return -EINVAL; + return ret; offset += size; } + msg.opcode = EXEC_MSG_OPS(xdna)->get_chain_msg_op(op); + if (msg.opcode == MSG_OP_MAX_OPCODE) + return -EOPNOTSUPP; /* The offset is the accumulated total size of the cmd buffer */ - aie2_cmdlist_prepare_request(&req, cmdbuf_abo, offset, payload->command_count); + EXEC_MSG_OPS(xdna)->init_chain_req(&req, cmdbuf_abo->mem.dev_addr, + offset, payload->command_count); + drm_clflush_virt_range(cmdbuf_abo->mem.kva, offset); - msg.opcode = aie2_cmd_op_to_msg_op(op); - if (msg.opcode == MSG_OP_MAX_OPCODE) - return -EOPNOTSUPP; msg.handle = job; msg.notify_cb = notify_cb; msg.send_data = (u8 *)&req; msg.send_size = sizeof(req); ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); if (ret) { - XDNA_ERR(hwctx->client->xdna, "Send message failed"); + XDNA_ERR(xdna, "Send message failed"); return ret; } @@ -712,23 +974,27 @@ int aie2_cmdlist_single_execbuf(struct amdxdna_hwctx *hwctx, { struct amdxdna_gem_obj *cmdbuf_abo = aie2_cmdlist_get_cmd_buf(job); struct mailbox_channel *chann = hwctx->priv->mbox_chann; + struct amdxdna_dev *xdna = hwctx->client->xdna; struct amdxdna_gem_obj *cmd_abo = job->cmd_bo; struct xdna_mailbox_msg msg; - struct cmd_chain_req req; - u32 size; + union exec_chain_req req; + u32 op = ERT_INVALID_CMD; + size_t size; int ret; - u32 op; - op = amdxdna_cmd_get_op(cmd_abo); - ret = aie2_cmdlist_fill_one_slot(op, cmdbuf_abo, 0, cmd_abo, &size); + size = cmdbuf_abo->mem.size; + ret = aie2_cmdlist_fill_slot(cmdbuf_abo->mem.kva, cmd_abo, &size, &op); if (ret) return ret; - aie2_cmdlist_prepare_request(&req, cmdbuf_abo, size, 1); - - msg.opcode = aie2_cmd_op_to_msg_op(op); + msg.opcode = EXEC_MSG_OPS(xdna)->get_chain_msg_op(op); if (msg.opcode == MSG_OP_MAX_OPCODE) return -EOPNOTSUPP; + + EXEC_MSG_OPS(xdna)->init_chain_req(&req, cmdbuf_abo->mem.dev_addr, + size, 1); + drm_clflush_virt_range(cmdbuf_abo->mem.kva, size); + msg.handle = job; msg.notify_cb = notify_cb; msg.send_data = (u8 *)&req; @@ -753,7 +1019,7 @@ int aie2_sync_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, int ret = 0; req.src_addr = 0; - req.dst_addr = abo->mem.dev_addr - hwctx->client->dev_heap->mem.dev_addr; + req.dst_addr = amdxdna_dev_bo_offset(abo); req.size = abo->mem.size; /* Device to Host */ @@ -777,3 +1043,32 @@ int aie2_sync_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, return 0; } + +int aie2_config_debug_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, + int (*notify_cb)(void *, void __iomem *, size_t)) +{ + struct mailbox_channel *chann = hwctx->priv->mbox_chann; + struct amdxdna_gem_obj *abo = to_xdna_obj(job->bos[0]); + struct amdxdna_dev *xdna = hwctx->client->xdna; + struct config_debug_bo_req req; + struct xdna_mailbox_msg msg; + + if (job->drv_cmd->opcode == ATTACH_DEBUG_BO) + req.config = DEBUG_BO_REGISTER; + else + req.config = DEBUG_BO_UNREGISTER; + + req.offset = amdxdna_dev_bo_offset(abo); + req.size = abo->mem.size; + + XDNA_DBG(xdna, "offset 0x%llx size 0x%llx config %d", + req.offset, req.size, req.config); + + msg.handle = job; + msg.notify_cb = notify_cb; + msg.send_data = (u8 *)&req; + msg.send_size = sizeof(req); + msg.opcode = MSG_OP_CONFIG_DEBUG_BO; + + return xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); +} diff --git a/drivers/accel/amdxdna/aie2_msg_priv.h b/drivers/accel/amdxdna/aie2_msg_priv.h index 6df9065b13f68..1c957a6298d39 100644 --- a/drivers/accel/amdxdna/aie2_msg_priv.h +++ b/drivers/accel/amdxdna/aie2_msg_priv.h @@ -9,7 +9,8 @@ enum aie2_msg_opcode { MSG_OP_CREATE_CONTEXT = 0x2, MSG_OP_DESTROY_CONTEXT = 0x3, - MSG_OP_SYNC_BO = 0x7, + MSG_OP_GET_TELEMETRY = 0x4, + MSG_OP_SYNC_BO = 0x7, MSG_OP_EXECUTE_BUFFER_CF = 0xC, MSG_OP_QUERY_COL_STATUS = 0xD, MSG_OP_QUERY_AIE_TILE_INFO = 0xE, @@ -18,6 +19,8 @@ enum aie2_msg_opcode { MSG_OP_CONFIG_CU = 0x11, MSG_OP_CHAIN_EXEC_BUFFER_CF = 0x12, MSG_OP_CHAIN_EXEC_DPU = 0x13, + MSG_OP_CONFIG_DEBUG_BO = 0x14, + MSG_OP_CHAIN_EXEC_NPU = 0x18, MSG_OP_MAX_XRT_OPCODE, MSG_OP_SUSPEND = 0x101, MSG_OP_RESUME = 0x102, @@ -135,6 +138,28 @@ struct destroy_ctx_resp { enum aie2_msg_status status; } __packed; +enum telemetry_type { + TELEMETRY_TYPE_DISABLED, + TELEMETRY_TYPE_HEALTH, + TELEMETRY_TYPE_ERROR_INFO, + TELEMETRY_TYPE_PROFILING, + TELEMETRY_TYPE_DEBUG, + MAX_TELEMETRY_TYPE +}; + +struct get_telemetry_req { + enum telemetry_type type; + __u64 buf_addr; + __u32 buf_size; +} __packed; + +struct get_telemetry_resp { + __u32 major; + __u32 minor; + __u32 size; + enum aie2_msg_status status; +} __packed; + struct execute_buffer_req { __u32 cu_idx; __u32 payload[19]; @@ -148,6 +173,18 @@ struct exec_dpu_req { __u32 payload[35]; } __packed; +enum exec_npu_type { + EXEC_NPU_TYPE_NON_ELF = 0x1, + EXEC_NPU_TYPE_PARTIAL_ELF = 0x2, + EXEC_NPU_TYPE_PREEMPT = 0x3, + EXEC_NPU_TYPE_ELF = 0x4, +}; + +union exec_req { + struct execute_buffer_req ebuf; + struct exec_dpu_req dpu_req; +}; + struct execute_buffer_resp { enum aie2_msg_status status; } __packed; @@ -319,9 +356,6 @@ struct async_event_msg_resp { } __packed; #define MAX_CHAIN_CMDBUF_SIZE SZ_4K -#define slot_has_space(slot, offset, payload_size) \ - (MAX_CHAIN_CMDBUF_SIZE >= (offset) + (payload_size) + \ - sizeof(typeof(slot))) struct cmd_chain_slot_execbuf_cf { __u32 cu_idx; @@ -339,12 +373,41 @@ struct cmd_chain_slot_dpu { __u32 args[] __counted_by(arg_cnt); }; +#define MAX_NPU_ARGS_SIZE (26 * sizeof(__u32)) +#define AIE2_EXEC_BUFFER_KERNEL_OP_TXN 3 +struct cmd_chain_slot_npu { + enum exec_npu_type type; + u64 inst_buf_addr; + u64 save_buf_addr; + u64 restore_buf_addr; + u32 inst_size; + u32 save_size; + u32 restore_size; + u32 inst_prop_cnt; + u32 cu_idx; + u32 arg_cnt; + u32 args[] __counted_by(arg_cnt); +} __packed; + struct cmd_chain_req { __u64 buf_addr; __u32 buf_size; __u32 count; } __packed; +struct cmd_chain_npu_req { + u32 flags; + u32 reserved; + u64 buf_addr; + u32 buf_size; + u32 count; +} __packed; + +union exec_chain_req { + struct cmd_chain_npu_req npu_req; + struct cmd_chain_req req; +}; + struct cmd_chain_resp { enum aie2_msg_status status; __u32 fail_cmd_idx; @@ -365,4 +428,21 @@ struct sync_bo_req { struct sync_bo_resp { enum aie2_msg_status status; } __packed; + +#define DEBUG_BO_UNREGISTER 0 +#define DEBUG_BO_REGISTER 1 +struct config_debug_bo_req { + __u64 offset; + __u64 size; + /* + * config operations. + * DEBUG_BO_REGISTER: Register debug buffer + * DEBUG_BO_UNREGISTER: Unregister debug buffer + */ + __u32 config; +} __packed; + +struct config_debug_bo_resp { + enum aie2_msg_status status; +} __packed; #endif /* _AIE2_MSG_PRIV_H_ */ diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c index 87c425e3d2b99..8141d8e516360 100644 --- a/drivers/accel/amdxdna/aie2_pci.c +++ b/drivers/accel/amdxdna/aie2_pci.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "aie2_msg_priv.h" #include "aie2_pci.h" @@ -25,6 +26,7 @@ #include "amdxdna_gem.h" #include "amdxdna_mailbox.h" #include "amdxdna_pci_drv.h" +#include "amdxdna_pm.h" static int aie2_max_col = XRS_MAX_COL; module_param(aie2_max_col, uint, 0600); @@ -54,6 +56,7 @@ struct mgmt_mbox_chann_info { static int aie2_check_protocol(struct amdxdna_dev_hdl *ndev, u32 fw_major, u32 fw_minor) { + const struct aie2_fw_feature_tbl *feature; struct amdxdna_dev *xdna = ndev->xdna; /* @@ -77,6 +80,17 @@ static int aie2_check_protocol(struct amdxdna_dev_hdl *ndev, u32 fw_major, u32 f XDNA_ERR(xdna, "Firmware minor version smaller than supported"); return -EINVAL; } + + for (feature = ndev->priv->fw_feature_tbl; feature && feature->min_minor; + feature++) { + if (fw_minor < feature->min_minor) + continue; + if (feature->max_minor > 0 && fw_minor > feature->max_minor) + continue; + + set_bit(feature->feature, &ndev->feature_mask); + } + return 0; } @@ -170,6 +184,10 @@ int aie2_runtime_cfg(struct amdxdna_dev_hdl *ndev, if (cfg->category != category) continue; + if (cfg->feature_mask && + bitmap_subset(&cfg->feature_mask, &ndev->feature_mask, AIE2_FEATURE_MAX)) + continue; + value = val ? *val : cfg->value; ret = aie2_set_runtime_cfg(ndev, cfg->type, value); if (ret) { @@ -223,15 +241,6 @@ static int aie2_mgmt_fw_init(struct amdxdna_dev_hdl *ndev) return ret; } - if (!ndev->async_events) - return 0; - - ret = aie2_error_async_events_send(ndev); - if (ret) { - XDNA_ERR(ndev->xdna, "Send async events failed"); - return ret; - } - return 0; } @@ -257,6 +266,8 @@ static int aie2_mgmt_fw_query(struct amdxdna_dev_hdl *ndev) return ret; } + ndev->total_col = min(aie2_max_col, ndev->metadata.cols); + return 0; } @@ -338,6 +349,7 @@ static void aie2_hw_stop(struct amdxdna_dev *xdna) ndev->mbox = NULL; aie2_psp_stop(ndev->psp_hdl); aie2_smu_fini(ndev); + aie2_error_async_events_free(ndev); pci_disable_device(pdev); ndev->dev_status = AIE2_DEV_INIT; @@ -424,6 +436,18 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) goto destroy_mgmt_chann; } + ret = aie2_mgmt_fw_query(ndev); + if (ret) { + XDNA_ERR(xdna, "failed to query fw, ret %d", ret); + goto destroy_mgmt_chann; + } + + ret = aie2_error_async_events_alloc(ndev); + if (ret) { + XDNA_ERR(xdna, "Allocate async events failed, ret %d", ret); + goto destroy_mgmt_chann; + } + ndev->dev_status = AIE2_DEV_START; return 0; @@ -459,7 +483,6 @@ static int aie2_hw_resume(struct amdxdna_dev *xdna) struct amdxdna_client *client; int ret; - guard(mutex)(&xdna->dev_lock); ret = aie2_hw_start(xdna); if (ret) { XDNA_ERR(xdna, "Start hardware failed, %d", ret); @@ -486,6 +509,11 @@ static int aie2_init(struct amdxdna_dev *xdna) unsigned long bars = 0; int i, nvec, ret; + if (!hypervisor_is_type(X86_HYPER_NATIVE)) { + XDNA_ERR(xdna, "Running under hypervisor not supported"); + return -EINVAL; + } + ndev = drmm_kzalloc(&xdna->ddev, sizeof(*ndev), GFP_KERNEL); if (!ndev) return -ENOMEM; @@ -565,13 +593,6 @@ static int aie2_init(struct amdxdna_dev *xdna) goto release_fw; } - ret = aie2_mgmt_fw_query(ndev); - if (ret) { - XDNA_ERR(xdna, "Query firmware failed, ret %d", ret); - goto stop_hw; - } - ndev->total_col = min(aie2_max_col, ndev->metadata.cols); - xrs_cfg.clk_list.num_levels = ndev->max_dpm_level + 1; for (i = 0; i < xrs_cfg.clk_list.num_levels; i++) xrs_cfg.clk_list.cu_clk_list[i] = ndev->priv->dpm_clk_tbl[i].hclk; @@ -587,30 +608,11 @@ static int aie2_init(struct amdxdna_dev *xdna) goto stop_hw; } - ret = aie2_error_async_events_alloc(ndev); - if (ret) { - XDNA_ERR(xdna, "Allocate async events failed, ret %d", ret); - goto stop_hw; - } - - ret = aie2_error_async_events_send(ndev); - if (ret) { - XDNA_ERR(xdna, "Send async events failed, ret %d", ret); - goto async_event_free; - } - - /* Issue a command to make sure firmware handled async events */ - ret = aie2_query_firmware_version(ndev, &ndev->xdna->fw_ver); - if (ret) { - XDNA_ERR(xdna, "Re-query firmware version failed"); - goto async_event_free; - } - release_firmware(fw); + aie2_msg_init(ndev); + amdxdna_pm_init(xdna); return 0; -async_event_free: - aie2_error_async_events_free(ndev); stop_hw: aie2_hw_stop(xdna); release_fw: @@ -621,10 +623,8 @@ static int aie2_init(struct amdxdna_dev *xdna) static void aie2_fini(struct amdxdna_dev *xdna) { - struct amdxdna_dev_hdl *ndev = xdna->dev_handle; - + amdxdna_pm_fini(xdna); aie2_hw_stop(xdna); - aie2_error_async_events_free(ndev); } static int aie2_get_aie_status(struct amdxdna_client *client, @@ -845,7 +845,120 @@ static int aie2_get_hwctx_status(struct amdxdna_client *client, } args->buffer_size -= (u32)(array_args.buffer - args->buffer); - return ret; + return 0; +} + +static int aie2_query_resource_info(struct amdxdna_client *client, + struct amdxdna_drm_get_info *args) +{ + struct amdxdna_drm_get_resource_info res_info; + const struct amdxdna_dev_priv *priv; + struct amdxdna_dev_hdl *ndev; + struct amdxdna_dev *xdna; + + xdna = client->xdna; + ndev = xdna->dev_handle; + priv = ndev->priv; + + res_info.npu_clk_max = priv->dpm_clk_tbl[ndev->max_dpm_level].hclk; + res_info.npu_tops_max = ndev->max_tops; + res_info.npu_task_max = priv->hwctx_limit; + res_info.npu_tops_curr = ndev->curr_tops; + res_info.npu_task_curr = ndev->hwctx_num; + + if (copy_to_user(u64_to_user_ptr(args->buffer), &res_info, sizeof(res_info))) + return -EFAULT; + + return 0; +} + +static int aie2_fill_hwctx_map(struct amdxdna_hwctx *hwctx, void *arg) +{ + struct amdxdna_dev *xdna = hwctx->client->xdna; + u32 *map = arg; + + if (hwctx->fw_ctx_id >= xdna->dev_handle->priv->hwctx_limit) { + XDNA_ERR(xdna, "Invalid fw ctx id %d/%d ", hwctx->fw_ctx_id, + xdna->dev_handle->priv->hwctx_limit); + return -EINVAL; + } + + map[hwctx->fw_ctx_id] = hwctx->id; + return 0; +} + +static int aie2_get_telemetry(struct amdxdna_client *client, + struct amdxdna_drm_get_info *args) +{ + struct amdxdna_drm_query_telemetry_header *header __free(kfree) = NULL; + u32 telemetry_data_sz, header_sz, elem_num; + struct amdxdna_dev *xdna = client->xdna; + struct amdxdna_client *tmp_client; + int ret; + + elem_num = xdna->dev_handle->priv->hwctx_limit; + header_sz = struct_size(header, map, elem_num); + if (args->buffer_size <= header_sz) { + XDNA_ERR(xdna, "Invalid buffer size"); + return -EINVAL; + } + + telemetry_data_sz = args->buffer_size - header_sz; + if (telemetry_data_sz > SZ_4M) { + XDNA_ERR(xdna, "Buffer size is too big, %d", telemetry_data_sz); + return -EINVAL; + } + + header = kzalloc(header_sz, GFP_KERNEL); + if (!header) + return -ENOMEM; + + if (copy_from_user(header, u64_to_user_ptr(args->buffer), sizeof(*header))) { + XDNA_ERR(xdna, "Failed to copy telemetry header from user"); + return -EFAULT; + } + + header->map_num_elements = elem_num; + list_for_each_entry(tmp_client, &xdna->client_list, node) { + ret = amdxdna_hwctx_walk(tmp_client, &header->map, + aie2_fill_hwctx_map); + if (ret) + return ret; + } + + ret = aie2_query_telemetry(xdna->dev_handle, + u64_to_user_ptr(args->buffer + header_sz), + telemetry_data_sz, header); + if (ret) { + XDNA_ERR(xdna, "Query telemetry failed ret %d", ret); + return ret; + } + + if (copy_to_user(u64_to_user_ptr(args->buffer), header, header_sz)) { + XDNA_ERR(xdna, "Copy header failed"); + return -EFAULT; + } + + return 0; +} + +static int aie2_get_preempt_state(struct amdxdna_client *client, + struct amdxdna_drm_get_info *args) +{ + struct amdxdna_drm_attribute_state state = {}; + struct amdxdna_dev *xdna = client->xdna; + struct amdxdna_dev_hdl *ndev; + + ndev = xdna->dev_handle; + if (args->param == DRM_AMDXDNA_GET_FORCE_PREEMPT_STATE) + state.state = ndev->force_preempt_enabled; + else if (args->param == DRM_AMDXDNA_GET_FRAME_BOUNDARY_PREEMPT_STATE) + state.state = ndev->frame_boundary_preempt; + + if (copy_to_user(u64_to_user_ptr(args->buffer), &state, sizeof(state))) + return -EFAULT; + + return 0; } static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_info *args) @@ -856,6 +969,10 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i if (!drm_dev_enter(&xdna->ddev, &idx)) return -ENODEV; + ret = amdxdna_pm_resume_get(xdna); + if (ret) + goto dev_exit; + switch (args->param) { case DRM_AMDXDNA_QUERY_AIE_STATUS: ret = aie2_get_aie_status(client, args); @@ -878,12 +995,25 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i case DRM_AMDXDNA_GET_POWER_MODE: ret = aie2_get_power_mode(client, args); break; + case DRM_AMDXDNA_QUERY_TELEMETRY: + ret = aie2_get_telemetry(client, args); + break; + case DRM_AMDXDNA_QUERY_RESOURCE_INFO: + ret = aie2_query_resource_info(client, args); + break; + case DRM_AMDXDNA_GET_FORCE_PREEMPT_STATE: + case DRM_AMDXDNA_GET_FRAME_BOUNDARY_PREEMPT_STATE: + ret = aie2_get_preempt_state(client, args); + break; default: XDNA_ERR(xdna, "Not supported request parameter %u", args->param); ret = -EOPNOTSUPP; } + + amdxdna_pm_suspend_put(xdna); XDNA_DBG(xdna, "Got param %d", args->param); +dev_exit: drm_dev_exit(idx); return ret; } @@ -898,6 +1028,12 @@ static int aie2_query_ctx_status_array(struct amdxdna_client *client, drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); + if (args->element_size > SZ_4K || args->num_element > SZ_1K) { + XDNA_DBG(xdna, "Invalid element size %d or number of element %d", + args->element_size, args->num_element); + return -EINVAL; + } + array_args.element_size = min(args->element_size, sizeof(struct amdxdna_drm_hwctx_entry)); array_args.buffer = args->buffer; @@ -914,7 +1050,7 @@ static int aie2_query_ctx_status_array(struct amdxdna_client *client, args->num_element = (u32)((array_args.buffer - args->buffer) / args->element_size); - return ret; + return 0; } static int aie2_get_array(struct amdxdna_client *client, @@ -926,16 +1062,26 @@ static int aie2_get_array(struct amdxdna_client *client, if (!drm_dev_enter(&xdna->ddev, &idx)) return -ENODEV; + ret = amdxdna_pm_resume_get(xdna); + if (ret) + goto dev_exit; + switch (args->param) { case DRM_AMDXDNA_HW_CONTEXT_ALL: ret = aie2_query_ctx_status_array(client, args); break; + case DRM_AMDXDNA_HW_LAST_ASYNC_ERR: + ret = aie2_get_array_async_error(xdna->dev_handle, args); + break; default: XDNA_ERR(xdna, "Not supported request parameter %u", args->param); ret = -EOPNOTSUPP; } + + amdxdna_pm_suspend_put(xdna); XDNA_DBG(xdna, "Got param %d", args->param); +dev_exit: drm_dev_exit(idx); return ret; } @@ -965,6 +1111,38 @@ static int aie2_set_power_mode(struct amdxdna_client *client, return aie2_pm_set_mode(xdna->dev_handle, power_mode); } +static int aie2_set_preempt_state(struct amdxdna_client *client, + struct amdxdna_drm_set_state *args) +{ + struct amdxdna_dev_hdl *ndev = client->xdna->dev_handle; + struct amdxdna_drm_attribute_state state; + u32 val; + int ret; + + if (copy_from_user(&state, u64_to_user_ptr(args->buffer), sizeof(state))) + return -EFAULT; + + if (state.state > 1) + return -EINVAL; + + if (XDNA_MBZ_DBG(client->xdna, state.pad, sizeof(state.pad))) + return -EINVAL; + + if (args->param == DRM_AMDXDNA_SET_FORCE_PREEMPT) { + ndev->force_preempt_enabled = state.state; + } else if (args->param == DRM_AMDXDNA_SET_FRAME_BOUNDARY_PREEMPT) { + val = state.state; + ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_FRAME_BOUNDARY_PREEMPT, + &val); + if (ret) + return ret; + + ndev->frame_boundary_preempt = state.state; + } + + return 0; +} + static int aie2_set_state(struct amdxdna_client *client, struct amdxdna_drm_set_state *args) { @@ -974,16 +1152,26 @@ static int aie2_set_state(struct amdxdna_client *client, if (!drm_dev_enter(&xdna->ddev, &idx)) return -ENODEV; + ret = amdxdna_pm_resume_get(xdna); + if (ret) + goto dev_exit; + switch (args->param) { case DRM_AMDXDNA_SET_POWER_MODE: ret = aie2_set_power_mode(client, args); break; + case DRM_AMDXDNA_SET_FORCE_PREEMPT: + case DRM_AMDXDNA_SET_FRAME_BOUNDARY_PREEMPT: + ret = aie2_set_preempt_state(client, args); + break; default: XDNA_ERR(xdna, "Not supported request parameter %u", args->param); ret = -EOPNOTSUPP; break; } + amdxdna_pm_suspend_put(xdna); +dev_exit: drm_dev_exit(idx); return ret; } @@ -998,6 +1186,7 @@ const struct amdxdna_dev_ops aie2_ops = { .hwctx_init = aie2_hwctx_init, .hwctx_fini = aie2_hwctx_fini, .hwctx_config = aie2_hwctx_config, + .hwctx_sync_debug_bo = aie2_hwctx_sync_debug_bo, .cmd_submit = aie2_cmd_submit, .hmm_invalidate = aie2_hmm_invalidate, .get_array = aie2_get_array, diff --git a/drivers/accel/amdxdna/aie2_pci.h b/drivers/accel/amdxdna/aie2_pci.h index 91a8e948f82a4..a5f9c42155d17 100644 --- a/drivers/accel/amdxdna/aie2_pci.h +++ b/drivers/accel/amdxdna/aie2_pci.h @@ -110,12 +110,15 @@ struct aie_metadata { enum rt_config_category { AIE2_RT_CFG_INIT, AIE2_RT_CFG_CLK_GATING, + AIE2_RT_CFG_FORCE_PREEMPT, + AIE2_RT_CFG_FRAME_BOUNDARY_PREEMPT, }; struct rt_config { u32 type; u32 value; u32 category; + unsigned long feature_mask; }; struct dpm_clk_freq { @@ -156,6 +159,19 @@ enum aie2_dev_status { AIE2_DEV_START, }; +struct aie2_exec_msg_ops { + int (*init_cu_req)(struct amdxdna_gem_obj *cmd_bo, void *req, + size_t *size, u32 *msg_op); + int (*init_dpu_req)(struct amdxdna_gem_obj *cmd_bo, void *req, + size_t *size, u32 *msg_op); + void (*init_chain_req)(void *req, u64 slot_addr, size_t size, u32 cmd_cnt); + int (*fill_cf_slot)(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size); + int (*fill_dpu_slot)(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size); + int (*fill_preempt_slot)(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size); + int (*fill_elf_slot)(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size); + u32 (*get_chain_msg_op)(u32 cmd_op); +}; + struct amdxdna_dev_hdl { struct amdxdna_dev *xdna; const struct amdxdna_dev_priv *priv; @@ -173,6 +189,8 @@ struct amdxdna_dev_hdl { u32 total_col; struct aie_version version; struct aie_metadata metadata; + unsigned long feature_mask; + struct aie2_exec_msg_ops *exec_msg_ops; /* power management and clock*/ enum amdxdna_power_mode_type pw_mode; @@ -182,6 +200,10 @@ struct amdxdna_dev_hdl { u32 clk_gating; u32 npuclk_freq; u32 hclk_freq; + u32 max_tops; + u32 curr_tops; + u32 force_preempt_enabled; + u32 frame_boundary_preempt; /* Mailbox and the management channel */ struct mailbox *mbox; @@ -190,6 +212,8 @@ struct amdxdna_dev_hdl { enum aie2_dev_status dev_status; u32 hwctx_num; + + struct amdxdna_async_error last_async_err; }; #define DEFINE_BAR_OFFSET(reg_name, bar, reg_addr) \ @@ -204,12 +228,27 @@ struct aie2_hw_ops { int (*set_dpm)(struct amdxdna_dev_hdl *ndev, u32 dpm_level); }; +enum aie2_fw_feature { + AIE2_NPU_COMMAND, + AIE2_PREEMPT, + AIE2_FEATURE_MAX +}; + +struct aie2_fw_feature_tbl { + enum aie2_fw_feature feature; + u32 max_minor; + u32 min_minor; +}; + +#define AIE2_FEATURE_ON(ndev, feature) test_bit(feature, &(ndev)->feature_mask) + struct amdxdna_dev_priv { const char *fw_path; u64 protocol_major; u64 protocol_minor; const struct rt_config *rt_config; const struct dpm_clk_freq *dpm_clk_tbl; + const struct aie2_fw_feature_tbl *fw_feature_tbl; #define COL_ALIGN_NONE 0 #define COL_ALIGN_NATURE 1 @@ -217,6 +256,7 @@ struct amdxdna_dev_priv { u32 mbox_dev_addr; /* If mbox_size is 0, use BAR size. See MBOX_SIZE macro */ u32 mbox_size; + u32 hwctx_limit; u32 sram_dev_addr; struct aie2_bar_off_pair sram_offs[SRAM_MAX_INDEX]; struct aie2_bar_off_pair psp_regs_off[PSP_MAX_REGS]; @@ -234,6 +274,7 @@ extern const struct dpm_clk_freq npu1_dpm_clk_table[]; extern const struct dpm_clk_freq npu4_dpm_clk_table[]; extern const struct rt_config npu1_default_rt_cfg[]; extern const struct rt_config npu4_default_rt_cfg[]; +extern const struct aie2_fw_feature_tbl npu4_fw_feature_table[]; /* aie2_smu.c */ int aie2_smu_init(struct amdxdna_dev_hdl *ndev); @@ -253,10 +294,12 @@ void aie2_psp_stop(struct psp_device *psp); /* aie2_error.c */ int aie2_error_async_events_alloc(struct amdxdna_dev_hdl *ndev); void aie2_error_async_events_free(struct amdxdna_dev_hdl *ndev); -int aie2_error_async_events_send(struct amdxdna_dev_hdl *ndev); int aie2_error_async_msg_thread(void *data); +int aie2_get_array_async_error(struct amdxdna_dev_hdl *ndev, + struct amdxdna_drm_get_array *args); /* aie2_message.c */ +void aie2_msg_init(struct amdxdna_dev_hdl *ndev); int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev); int aie2_resume_fw(struct amdxdna_dev_hdl *ndev); int aie2_set_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 value); @@ -270,9 +313,13 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx); int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size); int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf, u32 size, u32 *cols_filled); +int aie2_query_telemetry(struct amdxdna_dev_hdl *ndev, + char __user *buf, u32 size, + struct amdxdna_drm_query_telemetry_header *header); int aie2_register_asyn_event_msg(struct amdxdna_dev_hdl *ndev, dma_addr_t addr, u32 size, void *handle, int (*cb)(void*, void __iomem *, size_t)); -int aie2_config_cu(struct amdxdna_hwctx *hwctx); +int aie2_config_cu(struct amdxdna_hwctx *hwctx, + int (*notify_cb)(void *, void __iomem *, size_t)); int aie2_execbuf(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, int (*notify_cb)(void *, void __iomem *, size_t)); int aie2_cmdlist_single_execbuf(struct amdxdna_hwctx *hwctx, @@ -283,11 +330,14 @@ int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx, int (*notify_cb)(void *, void __iomem *, size_t)); int aie2_sync_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, int (*notify_cb)(void *, void __iomem *, size_t)); +int aie2_config_debug_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, + int (*notify_cb)(void *, void __iomem *, size_t)); /* aie2_hwctx.c */ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx); void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx); int aie2_hwctx_config(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *buf, u32 size); +int aie2_hwctx_sync_debug_bo(struct amdxdna_hwctx *hwctx, u32 debug_bo_hdl); void aie2_hwctx_suspend(struct amdxdna_client *client); int aie2_hwctx_resume(struct amdxdna_client *client); int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, u64 *seq); diff --git a/drivers/accel/amdxdna/aie2_smu.c b/drivers/accel/amdxdna/aie2_smu.c index d303701b0ded4..bd94ee96c2bc0 100644 --- a/drivers/accel/amdxdna/aie2_smu.c +++ b/drivers/accel/amdxdna/aie2_smu.c @@ -11,6 +11,7 @@ #include "aie2_pci.h" #include "amdxdna_pci_drv.h" +#include "amdxdna_pm.h" #define SMU_RESULT_OK 1 @@ -22,6 +23,13 @@ #define AIE2_SMU_SET_SOFT_DPMLEVEL 0x7 #define AIE2_SMU_SET_HARD_DPMLEVEL 0x8 +#define NPU4_DPM_TOPS(ndev, dpm_level) \ +({ \ + typeof(ndev) _ndev = ndev; \ + (4096 * (_ndev)->total_col * \ + (_ndev)->priv->dpm_clk_tbl[dpm_level].hclk / 1000000); \ +}) + static int aie2_smu_exec(struct amdxdna_dev_hdl *ndev, u32 reg_cmd, u32 reg_arg, u32 *out) { @@ -59,12 +67,16 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) u32 freq; int ret; + ret = amdxdna_pm_resume_get(ndev->xdna); + if (ret) + return ret; + ret = aie2_smu_exec(ndev, AIE2_SMU_SET_MPNPUCLK_FREQ, ndev->priv->dpm_clk_tbl[dpm_level].npuclk, &freq); if (ret) { XDNA_ERR(ndev->xdna, "Set npu clock to %d failed, ret %d\n", ndev->priv->dpm_clk_tbl[dpm_level].npuclk, ret); - return ret; + goto suspend_put; } ndev->npuclk_freq = freq; @@ -73,49 +85,78 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) if (ret) { XDNA_ERR(ndev->xdna, "Set h clock to %d failed, ret %d\n", ndev->priv->dpm_clk_tbl[dpm_level].hclk, ret); - return ret; + goto suspend_put; } + + amdxdna_pm_suspend_put(ndev->xdna); ndev->hclk_freq = freq; ndev->dpm_level = dpm_level; + ndev->max_tops = 2 * ndev->total_col; + ndev->curr_tops = ndev->max_tops * freq / 1028; XDNA_DBG(ndev->xdna, "MP-NPU clock %d, H clock %d\n", ndev->npuclk_freq, ndev->hclk_freq); return 0; + +suspend_put: + amdxdna_pm_suspend_put(ndev->xdna); + return ret; } int npu4_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) { int ret; + ret = amdxdna_pm_resume_get(ndev->xdna); + if (ret) + return ret; + ret = aie2_smu_exec(ndev, AIE2_SMU_SET_HARD_DPMLEVEL, dpm_level, NULL); if (ret) { XDNA_ERR(ndev->xdna, "Set hard dpm level %d failed, ret %d ", dpm_level, ret); - return ret; + goto suspend_put; } ret = aie2_smu_exec(ndev, AIE2_SMU_SET_SOFT_DPMLEVEL, dpm_level, NULL); if (ret) { XDNA_ERR(ndev->xdna, "Set soft dpm level %d failed, ret %d", dpm_level, ret); - return ret; + goto suspend_put; } + amdxdna_pm_suspend_put(ndev->xdna); ndev->npuclk_freq = ndev->priv->dpm_clk_tbl[dpm_level].npuclk; ndev->hclk_freq = ndev->priv->dpm_clk_tbl[dpm_level].hclk; ndev->dpm_level = dpm_level; + ndev->max_tops = NPU4_DPM_TOPS(ndev, ndev->max_dpm_level); + ndev->curr_tops = NPU4_DPM_TOPS(ndev, dpm_level); XDNA_DBG(ndev->xdna, "MP-NPU clock %d, H clock %d\n", ndev->npuclk_freq, ndev->hclk_freq); return 0; + +suspend_put: + amdxdna_pm_suspend_put(ndev->xdna); + return ret; } int aie2_smu_init(struct amdxdna_dev_hdl *ndev) { int ret; + /* + * Failing to set power off indicates an unrecoverable hardware or + * firmware error. + */ + ret = aie2_smu_exec(ndev, AIE2_SMU_POWER_OFF, 0, NULL); + if (ret) { + XDNA_ERR(ndev->xdna, "Access power failed, ret %d", ret); + return ret; + } + ret = aie2_smu_exec(ndev, AIE2_SMU_POWER_ON, 0, NULL); if (ret) { XDNA_ERR(ndev->xdna, "Power on failed, ret %d", ret); diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c index 4bfe4ef20550f..d17aef89a0add 100644 --- a/drivers/accel/amdxdna/amdxdna_ctx.c +++ b/drivers/accel/amdxdna/amdxdna_ctx.c @@ -113,14 +113,14 @@ void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size) return &cmd->data[num_masks]; } -int amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo) +u32 amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo) { struct amdxdna_cmd *cmd = abo->mem.kva; u32 num_masks, i; u32 *cu_mask; if (amdxdna_cmd_get_op(abo) == ERT_CMD_CHAIN) - return -1; + return INVALID_CU_IDX; num_masks = 1 + FIELD_GET(AMDXDNA_CMD_EXTRA_CU_MASK, cmd->header); cu_mask = cmd->data; @@ -129,7 +129,7 @@ int amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo) return ffs(cu_mask[i]) - 1; } - return -1; + return INVALID_CU_IDX; } /* @@ -161,19 +161,14 @@ int amdxdna_drm_create_hwctx_ioctl(struct drm_device *dev, void *data, struct dr if (args->ext || args->ext_flags) return -EINVAL; - if (!drm_dev_enter(dev, &idx)) - return -ENODEV; - hwctx = kzalloc(sizeof(*hwctx), GFP_KERNEL); - if (!hwctx) { - ret = -ENOMEM; - goto exit; - } + if (!hwctx) + return -ENOMEM; if (copy_from_user(&hwctx->qos, u64_to_user_ptr(args->qos_p), sizeof(hwctx->qos))) { XDNA_ERR(xdna, "Access QoS info failed"); - ret = -EFAULT; - goto free_hwctx; + kfree(hwctx); + return -EFAULT; } hwctx->client = client; @@ -181,30 +176,36 @@ int amdxdna_drm_create_hwctx_ioctl(struct drm_device *dev, void *data, struct dr hwctx->num_tiles = args->num_tiles; hwctx->mem_size = args->mem_size; hwctx->max_opc = args->max_opc; - ret = xa_alloc_cyclic(&client->hwctx_xa, &hwctx->id, hwctx, - XA_LIMIT(AMDXDNA_INVALID_CTX_HANDLE + 1, MAX_HWCTX_ID), - &client->next_hwctxid, GFP_KERNEL); - if (ret < 0) { - XDNA_ERR(xdna, "Allocate hwctx ID failed, ret %d", ret); + + guard(mutex)(&xdna->dev_lock); + + if (!drm_dev_enter(dev, &idx)) { + ret = -ENODEV; goto free_hwctx; } - hwctx->name = kasprintf(GFP_KERNEL, "hwctx.%d.%d", client->pid, hwctx->id); + ret = xdna->dev_info->ops->hwctx_init(hwctx); + if (ret) { + XDNA_ERR(xdna, "Init hwctx failed, ret %d", ret); + goto dev_exit; + } + + hwctx->name = kasprintf(GFP_KERNEL, "hwctx.%d.%d", client->pid, hwctx->fw_ctx_id); if (!hwctx->name) { ret = -ENOMEM; - goto rm_id; + goto fini_hwctx; } - mutex_lock(&xdna->dev_lock); - ret = xdna->dev_info->ops->hwctx_init(hwctx); - if (ret) { - mutex_unlock(&xdna->dev_lock); - XDNA_ERR(xdna, "Init hwctx failed, ret %d", ret); + ret = xa_alloc_cyclic(&client->hwctx_xa, &hwctx->id, hwctx, + XA_LIMIT(AMDXDNA_INVALID_CTX_HANDLE + 1, MAX_HWCTX_ID), + &client->next_hwctxid, GFP_KERNEL); + if (ret < 0) { + XDNA_ERR(xdna, "Allocate hwctx ID failed, ret %d", ret); goto free_name; } + args->handle = hwctx->id; args->syncobj_handle = hwctx->syncobj_hdl; - mutex_unlock(&xdna->dev_lock); atomic64_set(&hwctx->job_submit_cnt, 0); atomic64_set(&hwctx->job_free_cnt, 0); @@ -214,12 +215,12 @@ int amdxdna_drm_create_hwctx_ioctl(struct drm_device *dev, void *data, struct dr free_name: kfree(hwctx->name); -rm_id: - xa_erase(&client->hwctx_xa, hwctx->id); +fini_hwctx: + xdna->dev_info->ops->hwctx_fini(hwctx); +dev_exit: + drm_dev_exit(idx); free_hwctx: kfree(hwctx); -exit: - drm_dev_exit(idx); return ret; } @@ -327,6 +328,38 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr return ret; } +int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl) +{ + struct amdxdna_dev *xdna = client->xdna; + struct amdxdna_hwctx *hwctx; + struct amdxdna_gem_obj *abo; + struct drm_gem_object *gobj; + int ret, idx; + + if (!xdna->dev_info->ops->hwctx_sync_debug_bo) + return -EOPNOTSUPP; + + gobj = drm_gem_object_lookup(client->filp, debug_bo_hdl); + if (!gobj) + return -EINVAL; + + abo = to_xdna_obj(gobj); + guard(mutex)(&xdna->dev_lock); + idx = srcu_read_lock(&client->hwctx_srcu); + hwctx = xa_load(&client->hwctx_xa, abo->assigned_hwctx); + if (!hwctx) { + ret = -EINVAL; + goto unlock_srcu; + } + + ret = xdna->dev_info->ops->hwctx_sync_debug_bo(hwctx, debug_bo_hdl); + +unlock_srcu: + srcu_read_unlock(&client->hwctx_srcu, idx); + drm_gem_object_put(gobj); + return ret; +} + static void amdxdna_arg_bos_put(struct amdxdna_sched_job *job) { @@ -389,9 +422,11 @@ void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job) trace_amdxdna_debug_point(job->hwctx->name, job->seq, "job release"); amdxdna_arg_bos_put(job); amdxdna_gem_put_obj(job->cmd_bo); + dma_fence_put(job->fence); } int amdxdna_cmd_submit(struct amdxdna_client *client, + struct amdxdna_drv_cmd *drv_cmd, u32 cmd_bo_hdl, u32 *arg_bo_hdls, u32 arg_bo_cnt, u32 hwctx_hdl, u64 *seq) { @@ -405,6 +440,8 @@ int amdxdna_cmd_submit(struct amdxdna_client *client, if (!job) return -ENOMEM; + job->drv_cmd = drv_cmd; + if (cmd_bo_hdl != AMDXDNA_INVALID_BO_HANDLE) { job->cmd_bo = amdxdna_gem_get_obj(client, cmd_bo_hdl, AMDXDNA_BO_CMD); if (!job->cmd_bo) { @@ -412,8 +449,6 @@ int amdxdna_cmd_submit(struct amdxdna_client *client, ret = -EINVAL; goto free_job; } - } else { - job->cmd_bo = NULL; } ret = amdxdna_arg_bos_lookup(client, job, arg_bo_hdls, arg_bo_cnt); @@ -431,11 +466,6 @@ int amdxdna_cmd_submit(struct amdxdna_client *client, goto unlock_srcu; } - if (hwctx->status != HWCTX_STAT_READY) { - XDNA_ERR(xdna, "HW Context is not ready"); - ret = -EINVAL; - goto unlock_srcu; - } job->hwctx = hwctx; job->mm = current->mm; @@ -512,7 +542,7 @@ static int amdxdna_drm_submit_execbuf(struct amdxdna_client *client, } } - ret = amdxdna_cmd_submit(client, cmd_bo_hdl, arg_bo_hdls, + ret = amdxdna_cmd_submit(client, NULL, cmd_bo_hdl, arg_bo_hdls, args->arg_count, args->hwctx, &args->seq); if (ret) XDNA_DBG(xdna, "Submit cmds failed, ret %d", ret); diff --git a/drivers/accel/amdxdna/amdxdna_ctx.h b/drivers/accel/amdxdna/amdxdna_ctx.h index 7cd7a55936f09..b6151244d64fe 100644 --- a/drivers/accel/amdxdna/amdxdna_ctx.h +++ b/drivers/accel/amdxdna/amdxdna_ctx.h @@ -13,9 +13,12 @@ struct amdxdna_hwctx_priv; enum ert_cmd_opcode { - ERT_START_CU = 0, - ERT_CMD_CHAIN = 19, - ERT_START_NPU = 20, + ERT_START_CU = 0, + ERT_CMD_CHAIN = 19, + ERT_START_NPU = 20, + ERT_START_NPU_PREEMPT = 21, + ERT_START_NPU_PREEMPT_ELF = 22, + ERT_INVALID_CMD = ~0U, }; enum ert_cmd_state { @@ -54,6 +57,21 @@ struct amdxdna_cmd_chain { u64 data[] __counted_by(command_count); }; +/* + * Interpretation of the beginning of data payload for ERT_START_NPU_PREEMPT in + * amdxdna_cmd. The rest of the payload in amdxdna_cmd is regular kernel args. + */ +struct amdxdna_cmd_preempt_data { + u64 inst_buf; /* instruction buffer address */ + u64 save_buf; /* save buffer address */ + u64 restore_buf; /* restore buffer address */ + u32 inst_size; /* size of instruction buffer in bytes */ + u32 save_size; /* size of save buffer in bytes */ + u32 restore_size; /* size of restore buffer in bytes */ + u32 inst_prop_cnt; /* properties count */ + u32 prop_args[]; /* properties and regular kernel arguments */ +}; + /* Exec buffer command header format */ #define AMDXDNA_CMD_STATE GENMASK(3, 0) #define AMDXDNA_CMD_EXTRA_CU_MASK GENMASK(11, 10) @@ -64,6 +82,8 @@ struct amdxdna_cmd { u32 data[]; }; +#define INVALID_CU_IDX (~0U) + struct amdxdna_hwctx { struct amdxdna_client *client; struct amdxdna_hwctx_priv *priv; @@ -95,6 +115,17 @@ struct amdxdna_hwctx { #define drm_job_to_xdna_job(j) \ container_of(j, struct amdxdna_sched_job, base) +enum amdxdna_job_opcode { + SYNC_DEBUG_BO, + ATTACH_DEBUG_BO, + DETACH_DEBUG_BO, +}; + +struct amdxdna_drv_cmd { + enum amdxdna_job_opcode opcode; + u32 result; +}; + struct amdxdna_sched_job { struct drm_sched_job base; struct kref refcnt; @@ -105,7 +136,9 @@ struct amdxdna_sched_job { /* user can wait on this fence */ struct dma_fence *out_fence; bool job_done; + bool job_timeout; u64 seq; + struct amdxdna_drv_cmd *drv_cmd; struct amdxdna_gem_obj *cmd_bo; size_t bo_cnt; struct drm_gem_object *bos[] __counted_by(bo_cnt); @@ -137,15 +170,17 @@ amdxdna_cmd_get_state(struct amdxdna_gem_obj *abo) } void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size); -int amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo); +u32 amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo); void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job); void amdxdna_hwctx_remove_all(struct amdxdna_client *client); int amdxdna_hwctx_walk(struct amdxdna_client *client, void *arg, int (*walk)(struct amdxdna_hwctx *hwctx, void *arg)); +int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl); int amdxdna_cmd_submit(struct amdxdna_client *client, - u32 cmd_bo_hdls, u32 *arg_bo_hdls, u32 arg_bo_cnt, + struct amdxdna_drv_cmd *drv_cmd, u32 cmd_bo_hdls, + u32 *arg_bo_hdls, u32 arg_bo_cnt, u32 hwctx_hdl, u64 *seq); int amdxdna_cmd_wait(struct amdxdna_client *client, u32 hwctx_hdl, diff --git a/drivers/accel/amdxdna/amdxdna_error.h b/drivers/accel/amdxdna/amdxdna_error.h new file mode 100644 index 0000000000000..c51de86ec12bd --- /dev/null +++ b/drivers/accel/amdxdna/amdxdna_error.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2025, Advanced Micro Devices, Inc. + */ + +#ifndef _AMDXDNA_ERROR_H_ +#define _AMDXDNA_ERROR_H_ + +#include +#include + +#define AMDXDNA_ERR_DRV_AIE 4 +#define AMDXDNA_ERR_SEV_CRITICAL 3 +#define AMDXDNA_ERR_CLASS_AIE 2 + +#define AMDXDNA_ERR_NUM_MASK GENMASK_U64(15, 0) +#define AMDXDNA_ERR_DRV_MASK GENMASK_U64(23, 16) +#define AMDXDNA_ERR_SEV_MASK GENMASK_U64(31, 24) +#define AMDXDNA_ERR_MOD_MASK GENMASK_U64(39, 32) +#define AMDXDNA_ERR_CLASS_MASK GENMASK_U64(47, 40) + +enum amdxdna_error_num { + AMDXDNA_ERROR_NUM_AIE_SATURATION = 3, + AMDXDNA_ERROR_NUM_AIE_FP, + AMDXDNA_ERROR_NUM_AIE_STREAM, + AMDXDNA_ERROR_NUM_AIE_ACCESS, + AMDXDNA_ERROR_NUM_AIE_BUS, + AMDXDNA_ERROR_NUM_AIE_INSTRUCTION, + AMDXDNA_ERROR_NUM_AIE_ECC, + AMDXDNA_ERROR_NUM_AIE_LOCK, + AMDXDNA_ERROR_NUM_AIE_DMA, + AMDXDNA_ERROR_NUM_AIE_MEM_PARITY, + AMDXDNA_ERROR_NUM_UNKNOWN = 15, +}; + +enum amdxdna_error_module { + AMDXDNA_ERROR_MODULE_AIE_CORE = 3, + AMDXDNA_ERROR_MODULE_AIE_MEMORY, + AMDXDNA_ERROR_MODULE_AIE_SHIM, + AMDXDNA_ERROR_MODULE_AIE_NOC, + AMDXDNA_ERROR_MODULE_AIE_PL, + AMDXDNA_ERROR_MODULE_UNKNOWN = 8, +}; + +#define AMDXDNA_ERROR_ENCODE(err_num, err_mod) \ + (FIELD_PREP(AMDXDNA_ERR_NUM_MASK, err_num) | \ + FIELD_PREP_CONST(AMDXDNA_ERR_DRV_MASK, AMDXDNA_ERR_DRV_AIE) | \ + FIELD_PREP_CONST(AMDXDNA_ERR_SEV_MASK, AMDXDNA_ERR_SEV_CRITICAL) | \ + FIELD_PREP(AMDXDNA_ERR_MOD_MASK, err_mod) | \ + FIELD_PREP_CONST(AMDXDNA_ERR_CLASS_MASK, AMDXDNA_ERR_CLASS_AIE)) + +#define AMDXDNA_EXTRA_ERR_COL_MASK GENMASK_U64(7, 0) +#define AMDXDNA_EXTRA_ERR_ROW_MASK GENMASK_U64(15, 8) + +#define AMDXDNA_EXTRA_ERR_ENCODE(row, col) \ + (FIELD_PREP(AMDXDNA_EXTRA_ERR_COL_MASK, col) | \ + FIELD_PREP(AMDXDNA_EXTRA_ERR_ROW_MASK, row)) + +#endif /* _AMDXDNA_ERROR_H_ */ diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c index d407a36eb4126..dfa916eeb2d9c 100644 --- a/drivers/accel/amdxdna/amdxdna_gem.c +++ b/drivers/accel/amdxdna/amdxdna_gem.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -392,35 +393,33 @@ static const struct dma_buf_ops amdxdna_dmabuf_ops = { .vunmap = drm_gem_dmabuf_vunmap, }; -static int amdxdna_gem_obj_vmap(struct drm_gem_object *obj, struct iosys_map *map) +static int amdxdna_gem_obj_vmap(struct amdxdna_gem_obj *abo, void **vaddr) { - struct amdxdna_gem_obj *abo = to_xdna_obj(obj); - - iosys_map_clear(map); - - dma_resv_assert_held(obj->resv); + struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); + int ret; if (is_import_bo(abo)) - dma_buf_vmap(abo->dma_buf, map); + ret = dma_buf_vmap_unlocked(abo->dma_buf, &map); else - drm_gem_shmem_object_vmap(obj, map); + ret = drm_gem_vmap(to_gobj(abo), &map); - if (!map->vaddr) - return -ENOMEM; - - return 0; + *vaddr = map.vaddr; + return ret; } -static void amdxdna_gem_obj_vunmap(struct drm_gem_object *obj, struct iosys_map *map) +static void amdxdna_gem_obj_vunmap(struct amdxdna_gem_obj *abo) { - struct amdxdna_gem_obj *abo = to_xdna_obj(obj); + struct iosys_map map; + + if (!abo->mem.kva) + return; - dma_resv_assert_held(obj->resv); + iosys_map_set_vaddr(&map, abo->mem.kva); if (is_import_bo(abo)) - dma_buf_vunmap(abo->dma_buf, map); + dma_buf_vunmap_unlocked(abo->dma_buf, &map); else - drm_gem_shmem_object_vunmap(obj, map); + drm_gem_vunmap(to_gobj(abo), &map); } static struct dma_buf *amdxdna_gem_prime_export(struct drm_gem_object *gobj, int flags) @@ -455,7 +454,6 @@ static void amdxdna_gem_obj_free(struct drm_gem_object *gobj) { struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev); struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); - struct iosys_map map = IOSYS_MAP_INIT_VADDR(abo->mem.kva); XDNA_DBG(xdna, "BO type %d xdna_addr 0x%llx", abo->type, abo->mem.dev_addr); @@ -468,7 +466,7 @@ static void amdxdna_gem_obj_free(struct drm_gem_object *gobj) if (abo->type == AMDXDNA_BO_DEV_HEAP) drm_mm_takedown(&abo->mm); - drm_gem_vunmap(gobj, &map); + amdxdna_gem_obj_vunmap(abo); mutex_destroy(&abo->lock); if (is_import_bo(abo)) { @@ -489,8 +487,8 @@ static const struct drm_gem_object_funcs amdxdna_gem_shmem_funcs = { .pin = drm_gem_shmem_object_pin, .unpin = drm_gem_shmem_object_unpin, .get_sg_table = drm_gem_shmem_object_get_sg_table, - .vmap = amdxdna_gem_obj_vmap, - .vunmap = amdxdna_gem_obj_vunmap, + .vmap = drm_gem_shmem_object_vmap, + .vunmap = drm_gem_shmem_object_vunmap, .mmap = amdxdna_gem_obj_mmap, .vm_ops = &drm_gem_shmem_vm_ops, .export = amdxdna_gem_prime_export, @@ -663,7 +661,6 @@ amdxdna_drm_create_dev_heap(struct drm_device *dev, struct drm_file *filp) { struct amdxdna_client *client = filp->driver_priv; - struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); struct amdxdna_dev *xdna = to_xdna_dev(dev); struct amdxdna_gem_obj *abo; int ret; @@ -692,12 +689,11 @@ amdxdna_drm_create_dev_heap(struct drm_device *dev, abo->mem.dev_addr = client->xdna->dev_info->dev_mem_base; drm_mm_init(&abo->mm, abo->mem.dev_addr, abo->mem.size); - ret = drm_gem_vmap(to_gobj(abo), &map); + ret = amdxdna_gem_obj_vmap(abo, &abo->mem.kva); if (ret) { XDNA_ERR(xdna, "Vmap heap bo failed, ret %d", ret); goto release_obj; } - abo->mem.kva = map.vaddr; client->dev_heap = abo; drm_gem_object_get(to_gobj(abo)); @@ -748,7 +744,6 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev, struct amdxdna_drm_create_bo *args, struct drm_file *filp) { - struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); struct amdxdna_dev *xdna = to_xdna_dev(dev); struct amdxdna_gem_obj *abo; int ret; @@ -770,12 +765,11 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev, abo->type = AMDXDNA_BO_CMD; abo->client = filp->driver_priv; - ret = drm_gem_vmap(to_gobj(abo), &map); + ret = amdxdna_gem_obj_vmap(abo, &abo->mem.kva); if (ret) { XDNA_ERR(xdna, "Vmap cmd bo failed, ret %d", ret); goto release_obj; } - abo->mem.kva = map.vaddr; return abo; @@ -969,6 +963,9 @@ int amdxdna_drm_sync_bo_ioctl(struct drm_device *dev, XDNA_DBG(xdna, "Sync bo %d offset 0x%llx, size 0x%llx\n", args->handle, args->offset, args->size); + if (args->direction == SYNC_DIRECT_FROM_DEVICE) + ret = amdxdna_hwctx_sync_debug_bo(abo->client, args->handle); + put_obj: drm_gem_object_put(gobj); return ret; diff --git a/drivers/accel/amdxdna/amdxdna_gem.h b/drivers/accel/amdxdna/amdxdna_gem.h index ae29db94a9d33..f79fc7f3c93bc 100644 --- a/drivers/accel/amdxdna/amdxdna_gem.h +++ b/drivers/accel/amdxdna/amdxdna_gem.h @@ -7,6 +7,7 @@ #define _AMDXDNA_GEM_H_ #include +#include "amdxdna_pci_drv.h" struct amdxdna_umap { struct vm_area_struct *vma; @@ -62,6 +63,11 @@ static inline void amdxdna_gem_put_obj(struct amdxdna_gem_obj *abo) drm_gem_object_put(to_gobj(abo)); } +static inline u64 amdxdna_dev_bo_offset(struct amdxdna_gem_obj *abo) +{ + return abo->mem.dev_addr - abo->client->dev_heap->mem.dev_addr; +} + void amdxdna_umap_put(struct amdxdna_umap *mapp); struct drm_gem_object * diff --git a/drivers/accel/amdxdna/amdxdna_mailbox.c b/drivers/accel/amdxdna/amdxdna_mailbox.c index da1ac89bb78f1..858df97cd3fbd 100644 --- a/drivers/accel/amdxdna/amdxdna_mailbox.c +++ b/drivers/accel/amdxdna/amdxdna_mailbox.c @@ -194,7 +194,8 @@ static void mailbox_release_msg(struct mailbox_channel *mb_chann, { MB_DBG(mb_chann, "msg_id 0x%x msg opcode 0x%x", mb_msg->pkg.header.id, mb_msg->pkg.header.opcode); - mb_msg->notify_cb(mb_msg->handle, NULL, 0); + if (mb_msg->notify_cb) + mb_msg->notify_cb(mb_msg->handle, NULL, 0); kfree(mb_msg); } @@ -248,7 +249,7 @@ mailbox_get_resp(struct mailbox_channel *mb_chann, struct xdna_msg_header *heade { struct mailbox_msg *mb_msg; int msg_id; - int ret; + int ret = 0; msg_id = header->id; if (!mailbox_validate_msgid(msg_id)) { @@ -265,9 +266,11 @@ mailbox_get_resp(struct mailbox_channel *mb_chann, struct xdna_msg_header *heade MB_DBG(mb_chann, "opcode 0x%x size %d id 0x%x", header->opcode, header->total_size, header->id); - ret = mb_msg->notify_cb(mb_msg->handle, data, header->total_size); - if (unlikely(ret)) - MB_ERR(mb_chann, "Message callback ret %d", ret); + if (mb_msg->notify_cb) { + ret = mb_msg->notify_cb(mb_msg->handle, data, header->total_size); + if (unlikely(ret)) + MB_ERR(mb_chann, "Message callback ret %d", ret); + } kfree(mb_msg); return ret; @@ -513,6 +516,7 @@ xdna_mailbox_create_channel(struct mailbox *mb, } mb_chann->bad_state = false; + mailbox_reg_write(mb_chann, mb_chann->iohub_int_addr, 0); MB_DBG(mb_chann, "Mailbox channel created (irq: %d)", mb_chann->msix_irq); return mb_chann; diff --git a/drivers/accel/amdxdna/amdxdna_mailbox_helper.h b/drivers/accel/amdxdna/amdxdna_mailbox_helper.h index 710ff8873d617..556c712cad0a4 100644 --- a/drivers/accel/amdxdna/amdxdna_mailbox_helper.h +++ b/drivers/accel/amdxdna/amdxdna_mailbox_helper.h @@ -16,16 +16,18 @@ struct xdna_notify { u32 *data; size_t size; int error; + u32 *status; }; -#define DECLARE_XDNA_MSG_COMMON(name, op, status) \ +#define DECLARE_XDNA_MSG_COMMON(name, op, s) \ struct name##_req req = { 0 }; \ - struct name##_resp resp = { status }; \ + struct name##_resp resp = { .status = s }; \ struct xdna_notify hdl = { \ .error = 0, \ .data = (u32 *)&resp, \ .size = sizeof(resp), \ .comp = COMPLETION_INITIALIZER_ONSTACK(hdl.comp), \ + .status = (u32 *)&resp.status, \ }; \ struct xdna_mailbox_msg msg = { \ .send_data = (u8 *)&req, \ diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c index 569cd703729d3..1973ab67721be 100644 --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c @@ -13,13 +13,11 @@ #include #include #include -#include #include "amdxdna_ctx.h" #include "amdxdna_gem.h" #include "amdxdna_pci_drv.h" - -#define AMDXDNA_AUTOSUSPEND_DELAY 5000 /* milliseconds */ +#include "amdxdna_pm.h" MODULE_FIRMWARE("amdnpu/1502_00/npu.sbin"); MODULE_FIRMWARE("amdnpu/17f0_10/npu.sbin"); @@ -29,9 +27,14 @@ MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin"); /* * 0.0: Initial version * 0.1: Support getting all hardware contexts by DRM_IOCTL_AMDXDNA_GET_ARRAY + * 0.2: Support getting last error hardware error + * 0.3: Support firmware debug buffer + * 0.4: Support getting resource information + * 0.5: Support getting telemetry data + * 0.6: Support preemption */ #define AMDXDNA_DRIVER_MAJOR 0 -#define AMDXDNA_DRIVER_MINOR 1 +#define AMDXDNA_DRIVER_MINOR 6 /* * Bind the driver base on (vendor_id, device_id) pair and later use the @@ -61,17 +64,9 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp) struct amdxdna_client *client; int ret; - ret = pm_runtime_resume_and_get(ddev->dev); - if (ret) { - XDNA_ERR(xdna, "Failed to get rpm, ret %d", ret); - return ret; - } - client = kzalloc(sizeof(*client), GFP_KERNEL); - if (!client) { - ret = -ENOMEM; - goto put_rpm; - } + if (!client) + return -ENOMEM; client->pid = pid_nr(rcu_access_pointer(filp->pid)); client->xdna = xdna; @@ -106,9 +101,6 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp) iommu_sva_unbind_device(client->sva); failed: kfree(client); -put_rpm: - pm_runtime_mark_last_busy(ddev->dev); - pm_runtime_put_autosuspend(ddev->dev); return ret; } @@ -130,8 +122,6 @@ static void amdxdna_drm_close(struct drm_device *ddev, struct drm_file *filp) XDNA_DBG(xdna, "pid %d closed", client->pid); kfree(client); - pm_runtime_mark_last_busy(ddev->dev); - pm_runtime_put_autosuspend(ddev->dev); } static int amdxdna_flush(struct file *f, fl_owner_t id) @@ -310,19 +300,12 @@ static int amdxdna_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto failed_dev_fini; } - pm_runtime_set_autosuspend_delay(dev, AMDXDNA_AUTOSUSPEND_DELAY); - pm_runtime_use_autosuspend(dev); - pm_runtime_allow(dev); - ret = drm_dev_register(&xdna->ddev, 0); if (ret) { XDNA_ERR(xdna, "DRM register failed, ret %d", ret); - pm_runtime_forbid(dev); goto failed_sysfs_fini; } - pm_runtime_mark_last_busy(dev); - pm_runtime_put_autosuspend(dev); return 0; failed_sysfs_fini: @@ -339,14 +322,10 @@ static int amdxdna_probe(struct pci_dev *pdev, const struct pci_device_id *id) static void amdxdna_remove(struct pci_dev *pdev) { struct amdxdna_dev *xdna = pci_get_drvdata(pdev); - struct device *dev = &pdev->dev; struct amdxdna_client *client; destroy_workqueue(xdna->notifier_wq); - pm_runtime_get_noresume(dev); - pm_runtime_forbid(dev); - drm_dev_unplug(&xdna->ddev); amdxdna_sysfs_fini(xdna); @@ -365,29 +344,9 @@ static void amdxdna_remove(struct pci_dev *pdev) mutex_unlock(&xdna->dev_lock); } -static int amdxdna_pmops_suspend(struct device *dev) -{ - struct amdxdna_dev *xdna = pci_get_drvdata(to_pci_dev(dev)); - - if (!xdna->dev_info->ops->suspend) - return -EOPNOTSUPP; - - return xdna->dev_info->ops->suspend(xdna); -} - -static int amdxdna_pmops_resume(struct device *dev) -{ - struct amdxdna_dev *xdna = pci_get_drvdata(to_pci_dev(dev)); - - if (!xdna->dev_info->ops->resume) - return -EOPNOTSUPP; - - return xdna->dev_info->ops->resume(xdna); -} - static const struct dev_pm_ops amdxdna_pm_ops = { - SYSTEM_SLEEP_PM_OPS(amdxdna_pmops_suspend, amdxdna_pmops_resume) - RUNTIME_PM_OPS(amdxdna_pmops_suspend, amdxdna_pmops_resume, NULL) + SYSTEM_SLEEP_PM_OPS(amdxdna_pm_suspend, amdxdna_pm_resume) + RUNTIME_PM_OPS(amdxdna_pm_suspend, amdxdna_pm_resume, NULL) }; static struct pci_driver amdxdna_pci_driver = { diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.h b/drivers/accel/amdxdna/amdxdna_pci_drv.h index 72d6696d49da8..c99477f5e454f 100644 --- a/drivers/accel/amdxdna/amdxdna_pci_drv.h +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.h @@ -6,6 +6,7 @@ #ifndef _AMDXDNA_PCI_DRV_H_ #define _AMDXDNA_PCI_DRV_H_ +#include #include #include @@ -54,6 +55,7 @@ struct amdxdna_dev_ops { int (*hwctx_init)(struct amdxdna_hwctx *hwctx); void (*hwctx_fini)(struct amdxdna_hwctx *hwctx); int (*hwctx_config)(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *buf, u32 size); + int (*hwctx_sync_debug_bo)(struct amdxdna_hwctx *hwctx, u32 debug_bo_hdl); void (*hmm_invalidate)(struct amdxdna_gem_obj *abo, unsigned long cur_seq); int (*cmd_submit)(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, u64 *seq); int (*get_aie_info)(struct amdxdna_client *client, struct amdxdna_drm_get_info *args); @@ -99,6 +101,7 @@ struct amdxdna_dev { struct amdxdna_fw_ver fw_ver; struct rw_semaphore notifier_lock; /* for mmu notifier*/ struct workqueue_struct *notifier_wq; + bool rpm_on; }; /* diff --git a/drivers/accel/amdxdna/amdxdna_pm.c b/drivers/accel/amdxdna/amdxdna_pm.c new file mode 100644 index 0000000000000..fa38e65d617c4 --- /dev/null +++ b/drivers/accel/amdxdna/amdxdna_pm.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025, Advanced Micro Devices, Inc. + */ + +#include +#include +#include + +#include "amdxdna_pm.h" + +#define AMDXDNA_AUTOSUSPEND_DELAY 5000 /* milliseconds */ + +int amdxdna_pm_suspend(struct device *dev) +{ + struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev)); + int ret = -EOPNOTSUPP; + bool rpm; + + if (xdna->dev_info->ops->suspend) { + rpm = xdna->rpm_on; + xdna->rpm_on = false; + ret = xdna->dev_info->ops->suspend(xdna); + xdna->rpm_on = rpm; + } + + XDNA_DBG(xdna, "Suspend done ret %d", ret); + return ret; +} + +int amdxdna_pm_resume(struct device *dev) +{ + struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev)); + int ret = -EOPNOTSUPP; + bool rpm; + + if (xdna->dev_info->ops->resume) { + rpm = xdna->rpm_on; + xdna->rpm_on = false; + ret = xdna->dev_info->ops->resume(xdna); + xdna->rpm_on = rpm; + } + + XDNA_DBG(xdna, "Resume done ret %d", ret); + return ret; +} + +int amdxdna_pm_resume_get(struct amdxdna_dev *xdna) +{ + struct device *dev = xdna->ddev.dev; + int ret; + + if (!xdna->rpm_on) + return 0; + + ret = pm_runtime_resume_and_get(dev); + if (ret) { + XDNA_ERR(xdna, "Resume failed: %d", ret); + pm_runtime_set_suspended(dev); + } + + return ret; +} + +void amdxdna_pm_suspend_put(struct amdxdna_dev *xdna) +{ + struct device *dev = xdna->ddev.dev; + + if (!xdna->rpm_on) + return; + + pm_runtime_put_autosuspend(dev); +} + +void amdxdna_pm_init(struct amdxdna_dev *xdna) +{ + struct device *dev = xdna->ddev.dev; + + pm_runtime_set_active(dev); + pm_runtime_set_autosuspend_delay(dev, AMDXDNA_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(dev); + pm_runtime_allow(dev); + pm_runtime_put_autosuspend(dev); + xdna->rpm_on = true; +} + +void amdxdna_pm_fini(struct amdxdna_dev *xdna) +{ + struct device *dev = xdna->ddev.dev; + + xdna->rpm_on = false; + pm_runtime_get_noresume(dev); + pm_runtime_forbid(dev); +} diff --git a/drivers/accel/amdxdna/amdxdna_pm.h b/drivers/accel/amdxdna/amdxdna_pm.h new file mode 100644 index 0000000000000..77b2d6e455700 --- /dev/null +++ b/drivers/accel/amdxdna/amdxdna_pm.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2025, Advanced Micro Devices, Inc. + */ + +#ifndef _AMDXDNA_PM_H_ +#define _AMDXDNA_PM_H_ + +#include "amdxdna_pci_drv.h" + +int amdxdna_pm_suspend(struct device *dev); +int amdxdna_pm_resume(struct device *dev); +int amdxdna_pm_resume_get(struct amdxdna_dev *xdna); +void amdxdna_pm_suspend_put(struct amdxdna_dev *xdna); +void amdxdna_pm_init(struct amdxdna_dev *xdna); +void amdxdna_pm_fini(struct amdxdna_dev *xdna); + +#endif /* _AMDXDNA_PM_H_ */ diff --git a/drivers/accel/amdxdna/npu1_regs.c b/drivers/accel/amdxdna/npu1_regs.c index e4f6dac7d00fd..ec407f3b48fc7 100644 --- a/drivers/accel/amdxdna/npu1_regs.c +++ b/drivers/accel/amdxdna/npu1_regs.c @@ -46,6 +46,7 @@ const struct rt_config npu1_default_rt_cfg[] = { { 2, 1, AIE2_RT_CFG_INIT }, /* PDI APP LOAD MODE */ + { 4, 1, AIE2_RT_CFG_INIT }, /* Debug BO */ { 1, 1, AIE2_RT_CFG_CLK_GATING }, /* Clock gating on */ { 0 }, }; @@ -62,16 +63,23 @@ const struct dpm_clk_freq npu1_dpm_clk_table[] = { { 0 } }; +static const struct aie2_fw_feature_tbl npu1_fw_feature_table[] = { + { .feature = AIE2_NPU_COMMAND, .min_minor = 8 }, + { 0 } +}; + static const struct amdxdna_dev_priv npu1_dev_priv = { .fw_path = "amdnpu/1502_00/npu.sbin", .protocol_major = 0x5, .protocol_minor = 0x7, .rt_config = npu1_default_rt_cfg, .dpm_clk_tbl = npu1_dpm_clk_table, + .fw_feature_tbl = npu1_fw_feature_table, .col_align = COL_ALIGN_NONE, .mbox_dev_addr = NPU1_MBOX_BAR_BASE, .mbox_size = 0, /* Use BAR size */ .sram_dev_addr = NPU1_SRAM_BAR_BASE, + .hwctx_limit = 6, .sram_offs = { DEFINE_BAR_OFFSET(MBOX_CHANN_OFF, NPU1_SRAM, MPNPU_SRAM_X2I_MAILBOX_0), DEFINE_BAR_OFFSET(FW_ALIVE_OFF, NPU1_SRAM, MPNPU_SRAM_I2X_MAILBOX_15), diff --git a/drivers/accel/amdxdna/npu2_regs.c b/drivers/accel/amdxdna/npu2_regs.c index a081cac75ee0c..86f87d0d13540 100644 --- a/drivers/accel/amdxdna/npu2_regs.c +++ b/drivers/accel/amdxdna/npu2_regs.c @@ -67,10 +67,12 @@ static const struct amdxdna_dev_priv npu2_dev_priv = { .protocol_minor = 0x6, .rt_config = npu4_default_rt_cfg, .dpm_clk_tbl = npu4_dpm_clk_table, + .fw_feature_tbl = npu4_fw_feature_table, .col_align = COL_ALIGN_NATURE, .mbox_dev_addr = NPU2_MBOX_BAR_BASE, .mbox_size = 0, /* Use BAR size */ .sram_dev_addr = NPU2_SRAM_BAR_BASE, + .hwctx_limit = 16, .sram_offs = { DEFINE_BAR_OFFSET(MBOX_CHANN_OFF, NPU2_SRAM, MPNPU_SRAM_X2I_MAILBOX_0), DEFINE_BAR_OFFSET(FW_ALIVE_OFF, NPU2_SRAM, MPNPU_SRAM_X2I_MAILBOX_15), diff --git a/drivers/accel/amdxdna/npu4_regs.c b/drivers/accel/amdxdna/npu4_regs.c index 9f2e33182ec6f..986a5f28ba245 100644 --- a/drivers/accel/amdxdna/npu4_regs.c +++ b/drivers/accel/amdxdna/npu4_regs.c @@ -63,10 +63,14 @@ const struct rt_config npu4_default_rt_cfg[] = { { 5, 1, AIE2_RT_CFG_INIT }, /* PDI APP LOAD MODE */ + { 10, 1, AIE2_RT_CFG_INIT }, /* DEBUG BUF */ + { 14, 0, AIE2_RT_CFG_INIT, BIT_U64(AIE2_PREEMPT) }, /* Frame boundary preemption */ { 1, 1, AIE2_RT_CFG_CLK_GATING }, /* Clock gating on */ { 2, 1, AIE2_RT_CFG_CLK_GATING }, /* Clock gating on */ { 3, 1, AIE2_RT_CFG_CLK_GATING }, /* Clock gating on */ { 4, 1, AIE2_RT_CFG_CLK_GATING }, /* Clock gating on */ + { 13, 0, AIE2_RT_CFG_FORCE_PREEMPT }, + { 14, 0, AIE2_RT_CFG_FRAME_BOUNDARY_PREEMPT }, { 0 }, }; @@ -82,16 +86,24 @@ const struct dpm_clk_freq npu4_dpm_clk_table[] = { { 0 } }; +const struct aie2_fw_feature_tbl npu4_fw_feature_table[] = { + { .feature = AIE2_NPU_COMMAND, .min_minor = 15 }, + { .feature = AIE2_PREEMPT, .min_minor = 12 }, + { 0 } +}; + static const struct amdxdna_dev_priv npu4_dev_priv = { .fw_path = "amdnpu/17f0_10/npu.sbin", .protocol_major = 0x6, .protocol_minor = 12, .rt_config = npu4_default_rt_cfg, .dpm_clk_tbl = npu4_dpm_clk_table, + .fw_feature_tbl = npu4_fw_feature_table, .col_align = COL_ALIGN_NATURE, .mbox_dev_addr = NPU4_MBOX_BAR_BASE, .mbox_size = 0, /* Use BAR size */ .sram_dev_addr = NPU4_SRAM_BAR_BASE, + .hwctx_limit = 16, .sram_offs = { DEFINE_BAR_OFFSET(MBOX_CHANN_OFF, NPU4_SRAM, MPNPU_SRAM_X2I_MAILBOX_0), DEFINE_BAR_OFFSET(FW_ALIVE_OFF, NPU4_SRAM, MPNPU_SRAM_X2I_MAILBOX_15), diff --git a/drivers/accel/amdxdna/npu5_regs.c b/drivers/accel/amdxdna/npu5_regs.c index 5f1cf83461c46..75ad97f0b9370 100644 --- a/drivers/accel/amdxdna/npu5_regs.c +++ b/drivers/accel/amdxdna/npu5_regs.c @@ -67,10 +67,12 @@ static const struct amdxdna_dev_priv npu5_dev_priv = { .protocol_minor = 12, .rt_config = npu4_default_rt_cfg, .dpm_clk_tbl = npu4_dpm_clk_table, + .fw_feature_tbl = npu4_fw_feature_table, .col_align = COL_ALIGN_NATURE, .mbox_dev_addr = NPU5_MBOX_BAR_BASE, .mbox_size = 0, /* Use BAR size */ .sram_dev_addr = NPU5_SRAM_BAR_BASE, + .hwctx_limit = 16, .sram_offs = { DEFINE_BAR_OFFSET(MBOX_CHANN_OFF, NPU5_SRAM, MPNPU_SRAM_X2I_MAILBOX_0), DEFINE_BAR_OFFSET(FW_ALIVE_OFF, NPU5_SRAM, MPNPU_SRAM_X2I_MAILBOX_15), diff --git a/drivers/accel/amdxdna/npu6_regs.c b/drivers/accel/amdxdna/npu6_regs.c index 94a7005685a7b..758dc013fe13b 100644 --- a/drivers/accel/amdxdna/npu6_regs.c +++ b/drivers/accel/amdxdna/npu6_regs.c @@ -67,10 +67,12 @@ static const struct amdxdna_dev_priv npu6_dev_priv = { .protocol_minor = 12, .rt_config = npu4_default_rt_cfg, .dpm_clk_tbl = npu4_dpm_clk_table, + .fw_feature_tbl = npu4_fw_feature_table, .col_align = COL_ALIGN_NATURE, .mbox_dev_addr = NPU6_MBOX_BAR_BASE, .mbox_size = 0, /* Use BAR size */ .sram_dev_addr = NPU6_SRAM_BAR_BASE, + .hwctx_limit = 16, .sram_offs = { DEFINE_BAR_OFFSET(MBOX_CHANN_OFF, NPU6_SRAM, MPNPU_SRAM_X2I_MAILBOX_0), DEFINE_BAR_OFFSET(FW_ALIVE_OFF, NPU6_SRAM, MPNPU_SRAM_X2I_MAILBOX_15), diff --git a/drivers/accel/ethosu/Kconfig b/drivers/accel/ethosu/Kconfig new file mode 100644 index 0000000000000..d25f9b3eb3176 --- /dev/null +++ b/drivers/accel/ethosu/Kconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config DRM_ACCEL_ARM_ETHOSU + tristate "Arm Ethos-U65/U85 NPU" + depends on HAS_IOMEM + depends on DRM_ACCEL + select DRM_GEM_DMA_HELPER + select DRM_SCHED + select GENERIC_ALLOCATOR + help + Enables driver for Arm Ethos-U65/U85 NPUs diff --git a/drivers/accel/ethosu/Makefile b/drivers/accel/ethosu/Makefile new file mode 100644 index 0000000000000..17db5a6004167 --- /dev/null +++ b/drivers/accel/ethosu/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_DRM_ACCEL_ARM_ETHOSU) := ethosu.o +ethosu-y += ethosu_drv.o ethosu_gem.o ethosu_job.o diff --git a/drivers/accel/ethosu/ethosu_device.h b/drivers/accel/ethosu/ethosu_device.h new file mode 100644 index 0000000000000..b189fa783d6a3 --- /dev/null +++ b/drivers/accel/ethosu/ethosu_device.h @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: GPL-2.0-only or MIT */ +/* Copyright 2025 Arm, Ltd. */ + +#ifndef __ETHOSU_DEVICE_H__ +#define __ETHOSU_DEVICE_H__ + +#include +#include +#include + +#include +#include + +#include + +struct clk; +struct gen_pool; + +#define NPU_REG_ID 0x0000 +#define NPU_REG_STATUS 0x0004 +#define NPU_REG_CMD 0x0008 +#define NPU_REG_RESET 0x000c +#define NPU_REG_QBASE 0x0010 +#define NPU_REG_QBASE_HI 0x0014 +#define NPU_REG_QREAD 0x0018 +#define NPU_REG_QCONFIG 0x001c +#define NPU_REG_QSIZE 0x0020 +#define NPU_REG_PROT 0x0024 +#define NPU_REG_CONFIG 0x0028 +#define NPU_REG_REGIONCFG 0x003c +#define NPU_REG_AXILIMIT0 0x0040 // U65 +#define NPU_REG_AXILIMIT1 0x0044 // U65 +#define NPU_REG_AXILIMIT2 0x0048 // U65 +#define NPU_REG_AXILIMIT3 0x004c // U65 +#define NPU_REG_MEM_ATTR0 0x0040 // U85 +#define NPU_REG_MEM_ATTR1 0x0044 // U85 +#define NPU_REG_MEM_ATTR2 0x0048 // U85 +#define NPU_REG_MEM_ATTR3 0x004c // U85 +#define NPU_REG_AXI_SRAM 0x0050 // U85 +#define NPU_REG_AXI_EXT 0x0054 // U85 + +#define NPU_REG_BASEP(x) (0x0080 + (x) * 8) +#define NPU_REG_BASEP_HI(x) (0x0084 + (x) * 8) +#define NPU_BASEP_REGION_MAX 8 + +#define ID_ARCH_MAJOR_MASK GENMASK(31, 28) +#define ID_ARCH_MINOR_MASK GENMASK(27, 20) +#define ID_ARCH_PATCH_MASK GENMASK(19, 16) +#define ID_VER_MAJOR_MASK GENMASK(11, 8) +#define ID_VER_MINOR_MASK GENMASK(7, 4) + +#define CONFIG_MACS_PER_CC_MASK GENMASK(3, 0) +#define CONFIG_CMD_STREAM_VER_MASK GENMASK(7, 4) + +#define STATUS_STATE_RUNNING BIT(0) +#define STATUS_IRQ_RAISED BIT(1) +#define STATUS_BUS_STATUS BIT(2) +#define STATUS_RESET_STATUS BIT(3) +#define STATUS_CMD_PARSE_ERR BIT(4) +#define STATUS_CMD_END_REACHED BIT(5) + +#define CMD_CLEAR_IRQ BIT(1) +#define CMD_TRANSITION_TO_RUN BIT(0) + +#define RESET_PENDING_CSL BIT(1) +#define RESET_PENDING_CPL BIT(0) + +#define PROT_ACTIVE_CSL BIT(1) + +enum ethosu_cmds { + NPU_OP_CONV = 0x2, + NPU_OP_DEPTHWISE = 0x3, + NPU_OP_POOL = 0x5, + NPU_OP_ELEMENTWISE = 0x6, + NPU_OP_RESIZE = 0x7, // U85 only + NPU_OP_DMA_START = 0x10, + NPU_SET_IFM_PAD_TOP = 0x100, + NPU_SET_IFM_PAD_LEFT = 0x101, + NPU_SET_IFM_PAD_RIGHT = 0x102, + NPU_SET_IFM_PAD_BOTTOM = 0x103, + NPU_SET_IFM_DEPTH_M1 = 0x104, + NPU_SET_IFM_PRECISION = 0x105, + NPU_SET_IFM_BROADCAST = 0x108, + NPU_SET_IFM_WIDTH0_M1 = 0x10a, + NPU_SET_IFM_HEIGHT0_M1 = 0x10b, + NPU_SET_IFM_HEIGHT1_M1 = 0x10c, + NPU_SET_IFM_REGION = 0x10f, + NPU_SET_OFM_WIDTH_M1 = 0x111, + NPU_SET_OFM_HEIGHT_M1 = 0x112, + NPU_SET_OFM_DEPTH_M1 = 0x113, + NPU_SET_OFM_PRECISION = 0x114, + NPU_SET_OFM_WIDTH0_M1 = 0x11a, + NPU_SET_OFM_HEIGHT0_M1 = 0x11b, + NPU_SET_OFM_HEIGHT1_M1 = 0x11c, + NPU_SET_OFM_REGION = 0x11f, + NPU_SET_KERNEL_WIDTH_M1 = 0x120, + NPU_SET_KERNEL_HEIGHT_M1 = 0x121, + NPU_SET_KERNEL_STRIDE = 0x122, + NPU_SET_WEIGHT_REGION = 0x128, + NPU_SET_SCALE_REGION = 0x129, + NPU_SET_DMA0_SRC_REGION = 0x130, + NPU_SET_DMA0_DST_REGION = 0x131, + NPU_SET_DMA0_SIZE0 = 0x132, + NPU_SET_DMA0_SIZE1 = 0x133, + NPU_SET_IFM2_BROADCAST = 0x180, + NPU_SET_IFM2_PRECISION = 0x185, + NPU_SET_IFM2_WIDTH0_M1 = 0x18a, + NPU_SET_IFM2_HEIGHT0_M1 = 0x18b, + NPU_SET_IFM2_HEIGHT1_M1 = 0x18c, + NPU_SET_IFM2_REGION = 0x18f, + NPU_SET_IFM_BASE0 = 0x4000, + NPU_SET_IFM_BASE1 = 0x4001, + NPU_SET_IFM_BASE2 = 0x4002, + NPU_SET_IFM_BASE3 = 0x4003, + NPU_SET_IFM_STRIDE_X = 0x4004, + NPU_SET_IFM_STRIDE_Y = 0x4005, + NPU_SET_IFM_STRIDE_C = 0x4006, + NPU_SET_OFM_BASE0 = 0x4010, + NPU_SET_OFM_BASE1 = 0x4011, + NPU_SET_OFM_BASE2 = 0x4012, + NPU_SET_OFM_BASE3 = 0x4013, + NPU_SET_OFM_STRIDE_X = 0x4014, + NPU_SET_OFM_STRIDE_Y = 0x4015, + NPU_SET_OFM_STRIDE_C = 0x4016, + NPU_SET_WEIGHT_BASE = 0x4020, + NPU_SET_WEIGHT_LENGTH = 0x4021, + NPU_SET_SCALE_BASE = 0x4022, + NPU_SET_SCALE_LENGTH = 0x4023, + NPU_SET_DMA0_SRC = 0x4030, + NPU_SET_DMA0_DST = 0x4031, + NPU_SET_DMA0_LEN = 0x4032, + NPU_SET_DMA0_SRC_STRIDE0 = 0x4033, + NPU_SET_DMA0_SRC_STRIDE1 = 0x4034, + NPU_SET_DMA0_DST_STRIDE0 = 0x4035, + NPU_SET_DMA0_DST_STRIDE1 = 0x4036, + NPU_SET_IFM2_BASE0 = 0x4080, + NPU_SET_IFM2_BASE1 = 0x4081, + NPU_SET_IFM2_BASE2 = 0x4082, + NPU_SET_IFM2_BASE3 = 0x4083, + NPU_SET_IFM2_STRIDE_X = 0x4084, + NPU_SET_IFM2_STRIDE_Y = 0x4085, + NPU_SET_IFM2_STRIDE_C = 0x4086, + NPU_SET_WEIGHT1_BASE = 0x4090, + NPU_SET_WEIGHT1_LENGTH = 0x4091, + NPU_SET_SCALE1_BASE = 0x4092, + NPU_SET_WEIGHT2_BASE = 0x4092, + NPU_SET_SCALE1_LENGTH = 0x4093, + NPU_SET_WEIGHT2_LENGTH = 0x4093, + NPU_SET_WEIGHT3_BASE = 0x4094, + NPU_SET_WEIGHT3_LENGTH = 0x4095, +}; + +#define ETHOSU_SRAM_REGION 2 /* Matching Vela compiler */ + +/** + * struct ethosu_device - Ethosu device + */ +struct ethosu_device { + /** @base: Base drm_device. */ + struct drm_device base; + + /** @iomem: CPU mapping of the registers. */ + void __iomem *regs; + + void __iomem *sram; + struct gen_pool *srampool; + dma_addr_t sramphys; + + struct clk_bulk_data *clks; + int num_clks; + int irq; + + struct drm_ethosu_npu_info npu_info; + + struct ethosu_job *in_flight_job; + /* For in_flight_job and ethosu_job_hw_submit() */ + struct mutex job_lock; + + /* For dma_fence */ + spinlock_t fence_lock; + + struct drm_gpu_scheduler sched; + /* For ethosu_job_do_push() */ + struct mutex sched_lock; + u64 fence_context; + u64 emit_seqno; +}; + +#define to_ethosu_device(drm_dev) \ + ((struct ethosu_device *)container_of(drm_dev, struct ethosu_device, base)) + +static inline bool ethosu_is_u65(const struct ethosu_device *ethosudev) +{ + return FIELD_GET(ID_ARCH_MAJOR_MASK, ethosudev->npu_info.id) == 1; +} + +#endif diff --git a/drivers/accel/ethosu/ethosu_drv.c b/drivers/accel/ethosu/ethosu_drv.c new file mode 100644 index 0000000000000..e05a69bf55743 --- /dev/null +++ b/drivers/accel/ethosu/ethosu_drv.c @@ -0,0 +1,403 @@ +// SPDX-License-Identifier: GPL-2.0-only or MIT +// Copyright (C) 2025 Arm, Ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ethosu_drv.h" +#include "ethosu_device.h" +#include "ethosu_gem.h" +#include "ethosu_job.h" + +static int ethosu_ioctl_dev_query(struct drm_device *ddev, void *data, + struct drm_file *file) +{ + struct ethosu_device *ethosudev = to_ethosu_device(ddev); + struct drm_ethosu_dev_query *args = data; + + if (!args->pointer) { + switch (args->type) { + case DRM_ETHOSU_DEV_QUERY_NPU_INFO: + args->size = sizeof(ethosudev->npu_info); + return 0; + default: + return -EINVAL; + } + } + + switch (args->type) { + case DRM_ETHOSU_DEV_QUERY_NPU_INFO: + if (args->size < offsetofend(struct drm_ethosu_npu_info, sram_size)) + return -EINVAL; + return copy_struct_to_user(u64_to_user_ptr(args->pointer), + args->size, + ðosudev->npu_info, + sizeof(ethosudev->npu_info), NULL); + default: + return -EINVAL; + } +} + +#define ETHOSU_BO_FLAGS DRM_ETHOSU_BO_NO_MMAP + +static int ethosu_ioctl_bo_create(struct drm_device *ddev, void *data, + struct drm_file *file) +{ + struct drm_ethosu_bo_create *args = data; + int cookie, ret; + + if (!drm_dev_enter(ddev, &cookie)) + return -ENODEV; + + if (!args->size || (args->flags & ~ETHOSU_BO_FLAGS)) { + ret = -EINVAL; + goto out_dev_exit; + } + + ret = ethosu_gem_create_with_handle(file, ddev, &args->size, + args->flags, &args->handle); + +out_dev_exit: + drm_dev_exit(cookie); + return ret; +} + +static int ethosu_ioctl_bo_wait(struct drm_device *ddev, void *data, + struct drm_file *file) +{ + struct drm_ethosu_bo_wait *args = data; + int cookie, ret; + unsigned long timeout = drm_timeout_abs_to_jiffies(args->timeout_ns); + + if (args->pad) + return -EINVAL; + + if (!drm_dev_enter(ddev, &cookie)) + return -ENODEV; + + ret = drm_gem_dma_resv_wait(file, args->handle, true, timeout); + + drm_dev_exit(cookie); + return ret; +} + +static int ethosu_ioctl_bo_mmap_offset(struct drm_device *ddev, void *data, + struct drm_file *file) +{ + struct drm_ethosu_bo_mmap_offset *args = data; + struct drm_gem_object *obj; + + if (args->pad) + return -EINVAL; + + obj = drm_gem_object_lookup(file, args->handle); + if (!obj) + return -ENOENT; + + args->offset = drm_vma_node_offset_addr(&obj->vma_node); + drm_gem_object_put(obj); + return 0; +} + +static int ethosu_ioctl_cmdstream_bo_create(struct drm_device *ddev, void *data, + struct drm_file *file) +{ + struct drm_ethosu_cmdstream_bo_create *args = data; + int cookie, ret; + + if (!drm_dev_enter(ddev, &cookie)) + return -ENODEV; + + if (!args->size || !args->data || args->pad || args->flags) { + ret = -EINVAL; + goto out_dev_exit; + } + + args->flags |= DRM_ETHOSU_BO_NO_MMAP; + + ret = ethosu_gem_cmdstream_create(file, ddev, args->size, args->data, + args->flags, &args->handle); + +out_dev_exit: + drm_dev_exit(cookie); + return ret; +} + +static int ethosu_open(struct drm_device *ddev, struct drm_file *file) +{ + int ret = 0; + + if (!try_module_get(THIS_MODULE)) + return -EINVAL; + + struct ethosu_file_priv __free(kfree) *priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + goto err_put_mod; + } + priv->edev = to_ethosu_device(ddev); + + ret = ethosu_job_open(priv); + if (ret) + goto err_put_mod; + + file->driver_priv = no_free_ptr(priv); + return 0; + +err_put_mod: + module_put(THIS_MODULE); + return ret; +} + +static void ethosu_postclose(struct drm_device *ddev, struct drm_file *file) +{ + ethosu_job_close(file->driver_priv); + kfree(file->driver_priv); + module_put(THIS_MODULE); +} + +static const struct drm_ioctl_desc ethosu_drm_driver_ioctls[] = { +#define ETHOSU_IOCTL(n, func, flags) \ + DRM_IOCTL_DEF_DRV(ETHOSU_##n, ethosu_ioctl_##func, flags) + + ETHOSU_IOCTL(DEV_QUERY, dev_query, 0), + ETHOSU_IOCTL(BO_CREATE, bo_create, 0), + ETHOSU_IOCTL(BO_WAIT, bo_wait, 0), + ETHOSU_IOCTL(BO_MMAP_OFFSET, bo_mmap_offset, 0), + ETHOSU_IOCTL(CMDSTREAM_BO_CREATE, cmdstream_bo_create, 0), + ETHOSU_IOCTL(SUBMIT, submit, 0), +}; + +DEFINE_DRM_ACCEL_FOPS(ethosu_drm_driver_fops); + +/* + * Ethosu driver version: + * - 1.0 - initial interface + */ +static const struct drm_driver ethosu_drm_driver = { + .driver_features = DRIVER_COMPUTE_ACCEL | DRIVER_GEM, + .open = ethosu_open, + .postclose = ethosu_postclose, + .ioctls = ethosu_drm_driver_ioctls, + .num_ioctls = ARRAY_SIZE(ethosu_drm_driver_ioctls), + .fops = ðosu_drm_driver_fops, + .name = "ethosu", + .desc = "Arm Ethos-U Accel driver", + .major = 1, + .minor = 0, + + .gem_create_object = ethosu_gem_create_object, +}; + +#define U65_DRAM_AXI_LIMIT_CFG 0x1f3f0002 +#define U65_SRAM_AXI_LIMIT_CFG 0x1f3f00b0 +#define U85_AXI_EXT_CFG 0x00021f3f +#define U85_AXI_SRAM_CFG 0x00021f3f +#define U85_MEM_ATTR0_CFG 0x00000000 +#define U85_MEM_ATTR2_CFG 0x000000b7 + +static int ethosu_reset(struct ethosu_device *ethosudev) +{ + int ret; + u32 reg; + + writel_relaxed(RESET_PENDING_CSL, ethosudev->regs + NPU_REG_RESET); + ret = readl_poll_timeout(ethosudev->regs + NPU_REG_STATUS, reg, + !FIELD_GET(STATUS_RESET_STATUS, reg), + USEC_PER_MSEC, USEC_PER_SEC); + if (ret) + return ret; + + if (!FIELD_GET(PROT_ACTIVE_CSL, readl_relaxed(ethosudev->regs + NPU_REG_PROT))) { + dev_warn(ethosudev->base.dev, "Could not reset to non-secure mode (PROT = %x)\n", + readl_relaxed(ethosudev->regs + NPU_REG_PROT)); + } + + /* + * Assign region 2 (SRAM) to AXI M0 (AXILIMIT0), + * everything else to AXI M1 (AXILIMIT2) + */ + writel_relaxed(0x0000aa8a, ethosudev->regs + NPU_REG_REGIONCFG); + if (ethosu_is_u65(ethosudev)) { + writel_relaxed(U65_SRAM_AXI_LIMIT_CFG, ethosudev->regs + NPU_REG_AXILIMIT0); + writel_relaxed(U65_DRAM_AXI_LIMIT_CFG, ethosudev->regs + NPU_REG_AXILIMIT2); + } else { + writel_relaxed(U85_AXI_SRAM_CFG, ethosudev->regs + NPU_REG_AXI_SRAM); + writel_relaxed(U85_AXI_EXT_CFG, ethosudev->regs + NPU_REG_AXI_EXT); + writel_relaxed(U85_MEM_ATTR0_CFG, ethosudev->regs + NPU_REG_MEM_ATTR0); // SRAM + writel_relaxed(U85_MEM_ATTR2_CFG, ethosudev->regs + NPU_REG_MEM_ATTR2); // DRAM + } + + if (ethosudev->sram) + memset_io(ethosudev->sram, 0, ethosudev->npu_info.sram_size); + + return 0; +} + +static int ethosu_device_resume(struct device *dev) +{ + struct ethosu_device *ethosudev = dev_get_drvdata(dev); + int ret; + + ret = clk_bulk_prepare_enable(ethosudev->num_clks, ethosudev->clks); + if (ret) + return ret; + + ret = ethosu_reset(ethosudev); + if (!ret) + return 0; + + clk_bulk_disable_unprepare(ethosudev->num_clks, ethosudev->clks); + return ret; +} + +static int ethosu_device_suspend(struct device *dev) +{ + struct ethosu_device *ethosudev = dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(ethosudev->num_clks, ethosudev->clks); + return 0; +} + +static int ethosu_sram_init(struct ethosu_device *ethosudev) +{ + ethosudev->npu_info.sram_size = 0; + + ethosudev->srampool = of_gen_pool_get(ethosudev->base.dev->of_node, "sram", 0); + if (!ethosudev->srampool) + return 0; + + ethosudev->npu_info.sram_size = gen_pool_size(ethosudev->srampool); + + ethosudev->sram = (void __iomem *)gen_pool_dma_alloc(ethosudev->srampool, + ethosudev->npu_info.sram_size, + ðosudev->sramphys); + if (!ethosudev->sram) { + dev_err(ethosudev->base.dev, "failed to allocate from SRAM pool\n"); + return -ENOMEM; + } + + return 0; +} + +static int ethosu_init(struct ethosu_device *ethosudev) +{ + int ret; + u32 id, config; + + ret = ethosu_device_resume(ethosudev->base.dev); + if (ret) + return ret; + + pm_runtime_set_autosuspend_delay(ethosudev->base.dev, 50); + pm_runtime_use_autosuspend(ethosudev->base.dev); + ret = devm_pm_runtime_set_active_enabled(ethosudev->base.dev); + if (ret) + return ret; + pm_runtime_get_noresume(ethosudev->base.dev); + + ethosudev->npu_info.id = id = readl_relaxed(ethosudev->regs + NPU_REG_ID); + ethosudev->npu_info.config = config = readl_relaxed(ethosudev->regs + NPU_REG_CONFIG); + + ethosu_sram_init(ethosudev); + + dev_info(ethosudev->base.dev, + "Ethos-U NPU, arch v%ld.%ld.%ld, rev r%ldp%ld, cmd stream ver%ld, %d MACs, %dKB SRAM\n", + FIELD_GET(ID_ARCH_MAJOR_MASK, id), + FIELD_GET(ID_ARCH_MINOR_MASK, id), + FIELD_GET(ID_ARCH_PATCH_MASK, id), + FIELD_GET(ID_VER_MAJOR_MASK, id), + FIELD_GET(ID_VER_MINOR_MASK, id), + FIELD_GET(CONFIG_CMD_STREAM_VER_MASK, config), + 1 << FIELD_GET(CONFIG_MACS_PER_CC_MASK, config), + ethosudev->npu_info.sram_size / 1024); + + return 0; +} + +static int ethosu_probe(struct platform_device *pdev) +{ + int ret; + struct ethosu_device *ethosudev; + + ethosudev = devm_drm_dev_alloc(&pdev->dev, ðosu_drm_driver, + struct ethosu_device, base); + if (IS_ERR(ethosudev)) + return -ENOMEM; + platform_set_drvdata(pdev, ethosudev); + + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40)); + + ethosudev->regs = devm_platform_ioremap_resource(pdev, 0); + + ethosudev->num_clks = devm_clk_bulk_get_all(&pdev->dev, ðosudev->clks); + if (ethosudev->num_clks < 0) + return ethosudev->num_clks; + + ret = ethosu_job_init(ethosudev); + if (ret) + return ret; + + ret = ethosu_init(ethosudev); + if (ret) + return ret; + + ret = drm_dev_register(ðosudev->base, 0); + if (ret) + pm_runtime_dont_use_autosuspend(ethosudev->base.dev); + + pm_runtime_put_autosuspend(ethosudev->base.dev); + return ret; +} + +static void ethosu_remove(struct platform_device *pdev) +{ + struct ethosu_device *ethosudev = dev_get_drvdata(&pdev->dev); + + drm_dev_unregister(ðosudev->base); + ethosu_job_fini(ethosudev); + if (ethosudev->sram) + gen_pool_free(ethosudev->srampool, (unsigned long)ethosudev->sram, + ethosudev->npu_info.sram_size); +} + +static const struct of_device_id dt_match[] = { + { .compatible = "arm,ethos-u65" }, + { .compatible = "arm,ethos-u85" }, + {} +}; +MODULE_DEVICE_TABLE(of, dt_match); + +static DEFINE_RUNTIME_DEV_PM_OPS(ethosu_pm_ops, + ethosu_device_suspend, + ethosu_device_resume, + NULL); + +static struct platform_driver ethosu_driver = { + .probe = ethosu_probe, + .remove = ethosu_remove, + .driver = { + .name = "ethosu", + .pm = pm_ptr(ðosu_pm_ops), + .of_match_table = dt_match, + }, +}; +module_platform_driver(ethosu_driver); + +MODULE_AUTHOR("Rob Herring "); +MODULE_DESCRIPTION("Arm Ethos-U Accel Driver"); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/drivers/accel/ethosu/ethosu_drv.h b/drivers/accel/ethosu/ethosu_drv.h new file mode 100644 index 0000000000000..9e21dfe941843 --- /dev/null +++ b/drivers/accel/ethosu/ethosu_drv.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* Copyright 2025 Arm, Ltd. */ +#ifndef __ETHOSU_DRV_H__ +#define __ETHOSU_DRV_H__ + +#include + +struct ethosu_device; + +struct ethosu_file_priv { + struct ethosu_device *edev; + struct drm_sched_entity sched_entity; +}; + +#endif diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c new file mode 100644 index 0000000000000..473b5f5d75144 --- /dev/null +++ b/drivers/accel/ethosu/ethosu_gem.c @@ -0,0 +1,704 @@ +// SPDX-License-Identifier: GPL-2.0-only or MIT +/* Copyright 2025 Arm, Ltd. */ + +#include +#include + +#include + +#include "ethosu_device.h" +#include "ethosu_gem.h" + +static void ethosu_gem_free_object(struct drm_gem_object *obj) +{ + struct ethosu_gem_object *bo = to_ethosu_bo(obj); + + kfree(bo->info); + drm_gem_free_mmap_offset(&bo->base.base); + drm_gem_dma_free(&bo->base); +} + +static int ethosu_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +{ + struct ethosu_gem_object *bo = to_ethosu_bo(obj); + + /* Don't allow mmap on objects that have the NO_MMAP flag set. */ + if (bo->flags & DRM_ETHOSU_BO_NO_MMAP) + return -EINVAL; + + return drm_gem_dma_object_mmap(obj, vma); +} + +static const struct drm_gem_object_funcs ethosu_gem_funcs = { + .free = ethosu_gem_free_object, + .print_info = drm_gem_dma_object_print_info, + .get_sg_table = drm_gem_dma_object_get_sg_table, + .vmap = drm_gem_dma_object_vmap, + .mmap = ethosu_gem_mmap, + .vm_ops = &drm_gem_dma_vm_ops, +}; + +/** + * ethosu_gem_create_object - Implementation of driver->gem_create_object. + * @ddev: DRM device + * @size: Size in bytes of the memory the object will reference + * + * This lets the GEM helpers allocate object structs for us, and keep + * our BO stats correct. + */ +struct drm_gem_object *ethosu_gem_create_object(struct drm_device *ddev, size_t size) +{ + struct ethosu_gem_object *obj; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) + return ERR_PTR(-ENOMEM); + + obj->base.base.funcs = ðosu_gem_funcs; + return &obj->base.base; +} + +/** + * ethosu_gem_create_with_handle() - Create a GEM object and attach it to a handle. + * @file: DRM file. + * @ddev: DRM device. + * @size: Size of the GEM object to allocate. + * @flags: Combination of drm_ethosu_bo_flags flags. + * @handle: Pointer holding the handle pointing to the new GEM object. + * + * Return: Zero on success + */ +int ethosu_gem_create_with_handle(struct drm_file *file, + struct drm_device *ddev, + u64 *size, u32 flags, u32 *handle) +{ + struct drm_gem_dma_object *mem; + struct ethosu_gem_object *bo; + int ret; + + mem = drm_gem_dma_create(ddev, *size); + if (IS_ERR(mem)) + return PTR_ERR(mem); + + bo = to_ethosu_bo(&mem->base); + bo->flags = flags; + + /* + * Allocate an id of idr table where the obj is registered + * and handle has the id what user can see. + */ + ret = drm_gem_handle_create(file, &mem->base, handle); + if (!ret) + *size = bo->base.base.size; + + /* drop reference from allocate - handle holds it now. */ + drm_gem_object_put(&mem->base); + + return ret; +} + +struct dma { + s8 region; + u64 len; + u64 offset; + s64 stride[2]; +}; + +struct dma_state { + u16 size0; + u16 size1; + s8 mode; + struct dma src; + struct dma dst; +}; + +struct buffer { + u64 base; + u32 length; + s8 region; +}; + +struct feat_matrix { + u64 base[4]; + s64 stride_x; + s64 stride_y; + s64 stride_c; + s8 region; + u8 broadcast; + u16 stride_kernel; + u16 precision; + u16 depth; + u16 width; + u16 width0; + u16 height[3]; + u8 pad_top; + u8 pad_left; + u8 pad_bottom; + u8 pad_right; +}; + +struct cmd_state { + struct dma_state dma; + struct buffer scale[2]; + struct buffer weight[4]; + struct feat_matrix ofm; + struct feat_matrix ifm; + struct feat_matrix ifm2; +}; + +static void cmd_state_init(struct cmd_state *st) +{ + /* Initialize to all 1s to detect missing setup */ + memset(st, 0xff, sizeof(*st)); +} + +static u64 cmd_to_addr(u32 *cmd) +{ + return ((u64)((cmd[0] & 0xff0000) << 16)) | cmd[1]; +} + +static u64 dma_length(struct ethosu_validated_cmdstream_info *info, + struct dma_state *dma_st, struct dma *dma) +{ + s8 mode = dma_st->mode; + u64 len = dma->len; + + if (mode >= 1) { + len += dma->stride[0]; + len *= dma_st->size0; + } + if (mode == 2) { + len += dma->stride[1]; + len *= dma_st->size1; + } + if (dma->region >= 0) + info->region_size[dma->region] = max(info->region_size[dma->region], + len + dma->offset); + + return len; +} + +static u64 feat_matrix_length(struct ethosu_validated_cmdstream_info *info, + struct feat_matrix *fm, + u32 x, u32 y, u32 c) +{ + u32 element_size, storage = fm->precision >> 14; + int tile = 0; + u64 addr; + + if (fm->region < 0) + return U64_MAX; + + switch (storage) { + case 0: + if (x >= fm->width0 + 1) { + x -= fm->width0 + 1; + tile += 1; + } + if (y >= fm->height[tile] + 1) { + y -= fm->height[tile] + 1; + tile += 2; + } + break; + case 1: + if (y >= fm->height[1] + 1) { + y -= fm->height[1] + 1; + tile = 2; + } else if (y >= fm->height[0] + 1) { + y -= fm->height[0] + 1; + tile = 1; + } + break; + } + if (fm->base[tile] == U64_MAX) + return U64_MAX; + + addr = fm->base[tile] + y * fm->stride_y; + + switch ((fm->precision >> 6) & 0x3) { // format + case 0: //nhwc: + addr += x * fm->stride_x + c; + break; + case 1: //nhcwb16: + element_size = BIT((fm->precision >> 1) & 0x3); + + addr += (c / 16) * fm->stride_c + (16 * x + (c & 0xf)) * element_size; + break; + } + + info->region_size[fm->region] = max(info->region_size[fm->region], addr + 1); + + return addr; +} + +static int calc_sizes(struct drm_device *ddev, + struct ethosu_validated_cmdstream_info *info, + u16 op, struct cmd_state *st, + bool ifm, bool ifm2, bool weight, bool scale) +{ + u64 len; + + if (ifm) { + if (st->ifm.stride_kernel == U16_MAX) + return -EINVAL; + u32 stride_y = ((st->ifm.stride_kernel >> 8) & 0x2) + + ((st->ifm.stride_kernel >> 1) & 0x1) + 1; + u32 stride_x = ((st->ifm.stride_kernel >> 5) & 0x2) + + (st->ifm.stride_kernel & 0x1) + 1; + u32 ifm_height = st->ofm.height[2] * stride_y + + st->ifm.height[2] - (st->ifm.pad_top + st->ifm.pad_bottom); + u32 ifm_width = st->ofm.width * stride_x + + st->ifm.width - (st->ifm.pad_left + st->ifm.pad_right); + + len = feat_matrix_length(info, &st->ifm, ifm_width, + ifm_height, st->ifm.depth); + dev_dbg(ddev->dev, "op %d: IFM:%d:0x%llx-0x%llx\n", + op, st->ifm.region, st->ifm.base[0], len); + if (len == U64_MAX) + return -EINVAL; + } + + if (ifm2) { + len = feat_matrix_length(info, &st->ifm2, st->ifm.depth, + 0, st->ofm.depth); + dev_dbg(ddev->dev, "op %d: IFM2:%d:0x%llx-0x%llx\n", + op, st->ifm2.region, st->ifm2.base[0], len); + if (len == U64_MAX) + return -EINVAL; + } + + if (weight) { + dev_dbg(ddev->dev, "op %d: W:%d:0x%llx-0x%llx\n", + op, st->weight[0].region, st->weight[0].base, + st->weight[0].base + st->weight[0].length - 1); + if (st->weight[0].region < 0 || st->weight[0].base == U64_MAX || + st->weight[0].length == U32_MAX) + return -EINVAL; + info->region_size[st->weight[0].region] = + max(info->region_size[st->weight[0].region], + st->weight[0].base + st->weight[0].length); + } + + if (scale) { + dev_dbg(ddev->dev, "op %d: S:%d:0x%llx-0x%llx\n", + op, st->scale[0].region, st->scale[0].base, + st->scale[0].base + st->scale[0].length - 1); + if (st->scale[0].region < 0 || st->scale[0].base == U64_MAX || + st->scale[0].length == U32_MAX) + return -EINVAL; + info->region_size[st->scale[0].region] = + max(info->region_size[st->scale[0].region], + st->scale[0].base + st->scale[0].length); + } + + len = feat_matrix_length(info, &st->ofm, st->ofm.width, + st->ofm.height[2], st->ofm.depth); + dev_dbg(ddev->dev, "op %d: OFM:%d:0x%llx-0x%llx\n", + op, st->ofm.region, st->ofm.base[0], len); + if (len == U64_MAX) + return -EINVAL; + info->output_region[st->ofm.region] = true; + + return 0; +} + +static int calc_sizes_elemwise(struct drm_device *ddev, + struct ethosu_validated_cmdstream_info *info, + u16 op, struct cmd_state *st, + bool ifm, bool ifm2) +{ + u32 height, width, depth; + u64 len; + + if (ifm) { + height = st->ifm.broadcast & 0x1 ? 0 : st->ofm.height[2]; + width = st->ifm.broadcast & 0x2 ? 0 : st->ofm.width; + depth = st->ifm.broadcast & 0x4 ? 0 : st->ofm.depth; + + len = feat_matrix_length(info, &st->ifm, width, + height, depth); + dev_dbg(ddev->dev, "op %d: IFM:%d:0x%llx-0x%llx\n", + op, st->ifm.region, st->ifm.base[0], len); + if (len == U64_MAX) + return -EINVAL; + } + + if (ifm2) { + height = st->ifm2.broadcast & 0x1 ? 0 : st->ofm.height[2]; + width = st->ifm2.broadcast & 0x2 ? 0 : st->ofm.width; + depth = st->ifm2.broadcast & 0x4 ? 0 : st->ofm.depth; + + len = feat_matrix_length(info, &st->ifm2, width, + height, depth); + dev_dbg(ddev->dev, "op %d: IFM2:%d:0x%llx-0x%llx\n", + op, st->ifm2.region, st->ifm2.base[0], len); + if (len == U64_MAX) + return -EINVAL; + } + + len = feat_matrix_length(info, &st->ofm, st->ofm.width, + st->ofm.height[2], st->ofm.depth); + dev_dbg(ddev->dev, "op %d: OFM:%d:0x%llx-0x%llx\n", + op, st->ofm.region, st->ofm.base[0], len); + if (len == U64_MAX) + return -EINVAL; + info->output_region[st->ofm.region] = true; + + return 0; +} + +static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev, + u32 __user *ucmds, + struct ethosu_gem_object *bo, + u32 size) +{ + struct ethosu_validated_cmdstream_info __free(kfree) *info = kzalloc(sizeof(*info), GFP_KERNEL); + struct ethosu_device *edev = to_ethosu_device(ddev); + u32 *bocmds = bo->base.vaddr; + struct cmd_state st; + int i, ret; + + if (!info) + return -ENOMEM; + info->cmd_size = size; + + cmd_state_init(&st); + + for (i = 0; i < size / 4; i++) { + bool use_ifm, use_ifm2, use_scale; + u64 dstlen, srclen; + u16 cmd, param; + u32 cmds[2]; + u64 addr; + + if (get_user(cmds[0], ucmds++)) + return -EFAULT; + + bocmds[i] = cmds[0]; + + cmd = cmds[0]; + param = cmds[0] >> 16; + + if (cmd & 0x4000) { + if (get_user(cmds[1], ucmds++)) + return -EFAULT; + + i++; + bocmds[i] = cmds[1]; + addr = cmd_to_addr(cmds); + } + + switch (cmd) { + case NPU_OP_DMA_START: + srclen = dma_length(info, &st.dma, &st.dma.src); + dstlen = dma_length(info, &st.dma, &st.dma.dst); + + if (st.dma.dst.region >= 0) + info->output_region[st.dma.dst.region] = true; + dev_dbg(ddev->dev, "cmd: DMA SRC:%d:0x%llx+0x%llx DST:%d:0x%llx+0x%llx\n", + st.dma.src.region, st.dma.src.offset, srclen, + st.dma.dst.region, st.dma.dst.offset, dstlen); + break; + case NPU_OP_CONV: + case NPU_OP_DEPTHWISE: + use_ifm2 = param & 0x1; // weights_ifm2 + use_scale = !(st.ofm.precision & 0x100); + ret = calc_sizes(ddev, info, cmd, &st, true, use_ifm2, + !use_ifm2, use_scale); + if (ret) + return ret; + break; + case NPU_OP_POOL: + use_ifm = param != 0x4; // pooling mode + use_scale = !(st.ofm.precision & 0x100); + ret = calc_sizes(ddev, info, cmd, &st, use_ifm, false, + false, use_scale); + if (ret) + return ret; + break; + case NPU_OP_ELEMENTWISE: + use_ifm2 = !((st.ifm2.broadcast == 8) || (param == 5) || + (param == 6) || (param == 7) || (param == 0x24)); + use_ifm = st.ifm.broadcast != 8; + ret = calc_sizes_elemwise(ddev, info, cmd, &st, use_ifm, use_ifm2); + if (ret) + return ret; + break; + case NPU_OP_RESIZE: // U85 only + WARN_ON(1); // TODO + break; + case NPU_SET_KERNEL_WIDTH_M1: + st.ifm.width = param; + break; + case NPU_SET_KERNEL_HEIGHT_M1: + st.ifm.height[2] = param; + break; + case NPU_SET_KERNEL_STRIDE: + st.ifm.stride_kernel = param; + break; + case NPU_SET_IFM_PAD_TOP: + st.ifm.pad_top = param & 0x7f; + break; + case NPU_SET_IFM_PAD_LEFT: + st.ifm.pad_left = param & 0x7f; + break; + case NPU_SET_IFM_PAD_RIGHT: + st.ifm.pad_right = param & 0xff; + break; + case NPU_SET_IFM_PAD_BOTTOM: + st.ifm.pad_bottom = param & 0xff; + break; + case NPU_SET_IFM_DEPTH_M1: + st.ifm.depth = param; + break; + case NPU_SET_IFM_PRECISION: + st.ifm.precision = param; + break; + case NPU_SET_IFM_BROADCAST: + st.ifm.broadcast = param; + break; + case NPU_SET_IFM_REGION: + st.ifm.region = param & 0x7f; + break; + case NPU_SET_IFM_WIDTH0_M1: + st.ifm.width0 = param; + break; + case NPU_SET_IFM_HEIGHT0_M1: + st.ifm.height[0] = param; + break; + case NPU_SET_IFM_HEIGHT1_M1: + st.ifm.height[1] = param; + break; + case NPU_SET_IFM_BASE0: + case NPU_SET_IFM_BASE1: + case NPU_SET_IFM_BASE2: + case NPU_SET_IFM_BASE3: + st.ifm.base[cmd & 0x3] = addr; + break; + case NPU_SET_IFM_STRIDE_X: + st.ifm.stride_x = addr; + break; + case NPU_SET_IFM_STRIDE_Y: + st.ifm.stride_y = addr; + break; + case NPU_SET_IFM_STRIDE_C: + st.ifm.stride_c = addr; + break; + + case NPU_SET_OFM_WIDTH_M1: + st.ofm.width = param; + break; + case NPU_SET_OFM_HEIGHT_M1: + st.ofm.height[2] = param; + break; + case NPU_SET_OFM_DEPTH_M1: + st.ofm.depth = param; + break; + case NPU_SET_OFM_PRECISION: + st.ofm.precision = param; + break; + case NPU_SET_OFM_REGION: + st.ofm.region = param & 0x7; + break; + case NPU_SET_OFM_WIDTH0_M1: + st.ofm.width0 = param; + break; + case NPU_SET_OFM_HEIGHT0_M1: + st.ofm.height[0] = param; + break; + case NPU_SET_OFM_HEIGHT1_M1: + st.ofm.height[1] = param; + break; + case NPU_SET_OFM_BASE0: + case NPU_SET_OFM_BASE1: + case NPU_SET_OFM_BASE2: + case NPU_SET_OFM_BASE3: + st.ofm.base[cmd & 0x3] = addr; + break; + case NPU_SET_OFM_STRIDE_X: + st.ofm.stride_x = addr; + break; + case NPU_SET_OFM_STRIDE_Y: + st.ofm.stride_y = addr; + break; + case NPU_SET_OFM_STRIDE_C: + st.ofm.stride_c = addr; + break; + + case NPU_SET_IFM2_BROADCAST: + st.ifm2.broadcast = param; + break; + case NPU_SET_IFM2_PRECISION: + st.ifm2.precision = param; + break; + case NPU_SET_IFM2_REGION: + st.ifm2.region = param & 0x7; + break; + case NPU_SET_IFM2_WIDTH0_M1: + st.ifm2.width0 = param; + break; + case NPU_SET_IFM2_HEIGHT0_M1: + st.ifm2.height[0] = param; + break; + case NPU_SET_IFM2_HEIGHT1_M1: + st.ifm2.height[1] = param; + break; + case NPU_SET_IFM2_BASE0: + case NPU_SET_IFM2_BASE1: + case NPU_SET_IFM2_BASE2: + case NPU_SET_IFM2_BASE3: + st.ifm2.base[cmd & 0x3] = addr; + break; + case NPU_SET_IFM2_STRIDE_X: + st.ifm2.stride_x = addr; + break; + case NPU_SET_IFM2_STRIDE_Y: + st.ifm2.stride_y = addr; + break; + case NPU_SET_IFM2_STRIDE_C: + st.ifm2.stride_c = addr; + break; + + case NPU_SET_WEIGHT_REGION: + st.weight[0].region = param & 0x7; + break; + case NPU_SET_SCALE_REGION: + st.scale[0].region = param & 0x7; + break; + case NPU_SET_WEIGHT_BASE: + st.weight[0].base = addr; + break; + case NPU_SET_WEIGHT_LENGTH: + st.weight[0].length = cmds[1]; + break; + case NPU_SET_SCALE_BASE: + st.scale[0].base = addr; + break; + case NPU_SET_SCALE_LENGTH: + st.scale[0].length = cmds[1]; + break; + case NPU_SET_WEIGHT1_BASE: + st.weight[1].base = addr; + break; + case NPU_SET_WEIGHT1_LENGTH: + st.weight[1].length = cmds[1]; + break; + case NPU_SET_SCALE1_BASE: // NPU_SET_WEIGHT2_BASE (U85) + if (ethosu_is_u65(edev)) + st.scale[1].base = addr; + else + st.weight[2].base = addr; + break; + case NPU_SET_SCALE1_LENGTH: // NPU_SET_WEIGHT2_LENGTH (U85) + if (ethosu_is_u65(edev)) + st.scale[1].length = cmds[1]; + else + st.weight[1].length = cmds[1]; + break; + case NPU_SET_WEIGHT3_BASE: + st.weight[3].base = addr; + break; + case NPU_SET_WEIGHT3_LENGTH: + st.weight[3].length = cmds[1]; + break; + + case NPU_SET_DMA0_SRC_REGION: + if (param & 0x100) + st.dma.src.region = -1; + else + st.dma.src.region = param & 0x7; + st.dma.mode = (param >> 9) & 0x3; + break; + case NPU_SET_DMA0_DST_REGION: + if (param & 0x100) + st.dma.dst.region = -1; + else + st.dma.dst.region = param & 0x7; + break; + case NPU_SET_DMA0_SIZE0: + st.dma.size0 = param; + break; + case NPU_SET_DMA0_SIZE1: + st.dma.size1 = param; + break; + case NPU_SET_DMA0_SRC_STRIDE0: + st.dma.src.stride[0] = ((s64)addr << 24) >> 24; + break; + case NPU_SET_DMA0_SRC_STRIDE1: + st.dma.src.stride[1] = ((s64)addr << 24) >> 24; + break; + case NPU_SET_DMA0_DST_STRIDE0: + st.dma.dst.stride[0] = ((s64)addr << 24) >> 24; + break; + case NPU_SET_DMA0_DST_STRIDE1: + st.dma.dst.stride[1] = ((s64)addr << 24) >> 24; + break; + case NPU_SET_DMA0_SRC: + st.dma.src.offset = addr; + break; + case NPU_SET_DMA0_DST: + st.dma.dst.offset = addr; + break; + case NPU_SET_DMA0_LEN: + st.dma.src.len = st.dma.dst.len = addr; + break; + default: + break; + } + } + + for (i = 0; i < NPU_BASEP_REGION_MAX; i++) { + if (!info->region_size[i]) + continue; + dev_dbg(ddev->dev, "region %d max size: 0x%llx\n", + i, info->region_size[i]); + } + + bo->info = no_free_ptr(info); + return 0; +} + +/** + * ethosu_gem_cmdstream_create() - Create a GEM object and attach it to a handle. + * @file: DRM file. + * @ddev: DRM device. + * @exclusive_vm: Exclusive VM. Not NULL if the GEM object can't be shared. + * @size: Size of the GEM object to allocate. + * @flags: Combination of drm_ethosu_bo_flags flags. + * @handle: Pointer holding the handle pointing to the new GEM object. + * + * Return: Zero on success + */ +int ethosu_gem_cmdstream_create(struct drm_file *file, + struct drm_device *ddev, + u32 size, u64 data, u32 flags, u32 *handle) +{ + int ret; + struct drm_gem_dma_object *mem; + struct ethosu_gem_object *bo; + + mem = drm_gem_dma_create(ddev, size); + if (IS_ERR(mem)) + return PTR_ERR(mem); + + bo = to_ethosu_bo(&mem->base); + bo->flags = flags; + + ret = ethosu_gem_cmdstream_copy_and_validate(ddev, + (void __user *)(uintptr_t)data, + bo, size); + if (ret) + goto fail; + + /* + * Allocate an id of idr table where the obj is registered + * and handle has the id what user can see. + */ + ret = drm_gem_handle_create(file, &mem->base, handle); + +fail: + /* drop reference from allocate - handle holds it now. */ + drm_gem_object_put(&mem->base); + + return ret; +} diff --git a/drivers/accel/ethosu/ethosu_gem.h b/drivers/accel/ethosu/ethosu_gem.h new file mode 100644 index 0000000000000..3922895a60fbb --- /dev/null +++ b/drivers/accel/ethosu/ethosu_gem.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 or MIT */ +/* Copyright 2025 Arm, Ltd. */ + +#ifndef __ETHOSU_GEM_H__ +#define __ETHOSU_GEM_H__ + +#include "ethosu_device.h" +#include + +struct ethosu_validated_cmdstream_info { + u32 cmd_size; + u64 region_size[NPU_BASEP_REGION_MAX]; + bool output_region[NPU_BASEP_REGION_MAX]; +}; + +/** + * struct ethosu_gem_object - Driver specific GEM object. + */ +struct ethosu_gem_object { + /** @base: Inherit from drm_gem_shmem_object. */ + struct drm_gem_dma_object base; + + struct ethosu_validated_cmdstream_info *info; + + /** @flags: Combination of drm_ethosu_bo_flags flags. */ + u32 flags; +}; + +static inline +struct ethosu_gem_object *to_ethosu_bo(struct drm_gem_object *obj) +{ + return container_of(to_drm_gem_dma_obj(obj), struct ethosu_gem_object, base); +} + +struct drm_gem_object *ethosu_gem_create_object(struct drm_device *ddev, + size_t size); + +int ethosu_gem_create_with_handle(struct drm_file *file, + struct drm_device *ddev, + u64 *size, u32 flags, uint32_t *handle); + +int ethosu_gem_cmdstream_create(struct drm_file *file, + struct drm_device *ddev, + u32 size, u64 data, u32 flags, u32 *handle); + +#endif /* __ETHOSU_GEM_H__ */ diff --git a/drivers/accel/ethosu/ethosu_job.c b/drivers/accel/ethosu/ethosu_job.c new file mode 100644 index 0000000000000..26e7a2f64d71a --- /dev/null +++ b/drivers/accel/ethosu/ethosu_job.c @@ -0,0 +1,497 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* Copyright 2024-2025 Tomeu Vizoso */ +/* Copyright 2025 Arm, Ltd. */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ethosu_device.h" +#include "ethosu_drv.h" +#include "ethosu_gem.h" +#include "ethosu_job.h" + +#define JOB_TIMEOUT_MS 500 + +static struct ethosu_job *to_ethosu_job(struct drm_sched_job *sched_job) +{ + return container_of(sched_job, struct ethosu_job, base); +} + +static const char *ethosu_fence_get_driver_name(struct dma_fence *fence) +{ + return "ethosu"; +} + +static const char *ethosu_fence_get_timeline_name(struct dma_fence *fence) +{ + return "ethosu-npu"; +} + +static const struct dma_fence_ops ethosu_fence_ops = { + .get_driver_name = ethosu_fence_get_driver_name, + .get_timeline_name = ethosu_fence_get_timeline_name, +}; + +static void ethosu_job_hw_submit(struct ethosu_device *dev, struct ethosu_job *job) +{ + struct drm_gem_dma_object *cmd_bo = to_drm_gem_dma_obj(job->cmd_bo); + struct ethosu_validated_cmdstream_info *cmd_info = to_ethosu_bo(job->cmd_bo)->info; + + for (int i = 0; i < job->region_cnt; i++) { + struct drm_gem_dma_object *bo; + int region = job->region_bo_num[i]; + + bo = to_drm_gem_dma_obj(job->region_bo[i]); + writel_relaxed(lower_32_bits(bo->dma_addr), dev->regs + NPU_REG_BASEP(region)); + writel_relaxed(upper_32_bits(bo->dma_addr), dev->regs + NPU_REG_BASEP_HI(region)); + dev_dbg(dev->base.dev, "Region %d base addr = %pad\n", region, &bo->dma_addr); + } + + if (job->sram_size) { + writel_relaxed(lower_32_bits(dev->sramphys), + dev->regs + NPU_REG_BASEP(ETHOSU_SRAM_REGION)); + writel_relaxed(upper_32_bits(dev->sramphys), + dev->regs + NPU_REG_BASEP_HI(ETHOSU_SRAM_REGION)); + dev_dbg(dev->base.dev, "Region %d base addr = %pad (SRAM)\n", + ETHOSU_SRAM_REGION, &dev->sramphys); + } + + writel_relaxed(lower_32_bits(cmd_bo->dma_addr), dev->regs + NPU_REG_QBASE); + writel_relaxed(upper_32_bits(cmd_bo->dma_addr), dev->regs + NPU_REG_QBASE_HI); + writel_relaxed(cmd_info->cmd_size, dev->regs + NPU_REG_QSIZE); + + writel(CMD_TRANSITION_TO_RUN, dev->regs + NPU_REG_CMD); + + dev_dbg(dev->base.dev, + "Submitted cmd at %pad to core\n", &cmd_bo->dma_addr); +} + +static int ethosu_acquire_object_fences(struct ethosu_job *job) +{ + int i, ret; + struct drm_gem_object **bos = job->region_bo; + struct ethosu_validated_cmdstream_info *info = to_ethosu_bo(job->cmd_bo)->info; + + for (i = 0; i < job->region_cnt; i++) { + bool is_write; + + if (!bos[i]) + break; + + ret = dma_resv_reserve_fences(bos[i]->resv, 1); + if (ret) + return ret; + + is_write = info->output_region[job->region_bo_num[i]]; + ret = drm_sched_job_add_implicit_dependencies(&job->base, bos[i], + is_write); + if (ret) + return ret; + } + + return 0; +} + +static void ethosu_attach_object_fences(struct ethosu_job *job) +{ + int i; + struct dma_fence *fence = job->inference_done_fence; + struct drm_gem_object **bos = job->region_bo; + struct ethosu_validated_cmdstream_info *info = to_ethosu_bo(job->cmd_bo)->info; + + for (i = 0; i < job->region_cnt; i++) + if (info->output_region[job->region_bo_num[i]]) + dma_resv_add_fence(bos[i]->resv, fence, DMA_RESV_USAGE_WRITE); +} + +static int ethosu_job_push(struct ethosu_job *job) +{ + struct ww_acquire_ctx acquire_ctx; + int ret; + + ret = drm_gem_lock_reservations(job->region_bo, job->region_cnt, &acquire_ctx); + if (ret) + return ret; + + ret = ethosu_acquire_object_fences(job); + if (ret) + goto out; + + ret = pm_runtime_resume_and_get(job->dev->base.dev); + if (!ret) { + guard(mutex)(&job->dev->sched_lock); + + drm_sched_job_arm(&job->base); + job->inference_done_fence = dma_fence_get(&job->base.s_fence->finished); + kref_get(&job->refcount); /* put by scheduler job completion */ + drm_sched_entity_push_job(&job->base); + ethosu_attach_object_fences(job); + } + +out: + drm_gem_unlock_reservations(job->region_bo, job->region_cnt, &acquire_ctx); + return ret; +} + +static void ethosu_job_cleanup(struct kref *ref) +{ + struct ethosu_job *job = container_of(ref, struct ethosu_job, + refcount); + unsigned int i; + + pm_runtime_put_autosuspend(job->dev->base.dev); + + dma_fence_put(job->done_fence); + dma_fence_put(job->inference_done_fence); + + for (i = 0; i < job->region_cnt; i++) + drm_gem_object_put(job->region_bo[i]); + + drm_gem_object_put(job->cmd_bo); + + kfree(job); +} + +static void ethosu_job_put(struct ethosu_job *job) +{ + kref_put(&job->refcount, ethosu_job_cleanup); +} + +static void ethosu_job_free(struct drm_sched_job *sched_job) +{ + struct ethosu_job *job = to_ethosu_job(sched_job); + + drm_sched_job_cleanup(sched_job); + ethosu_job_put(job); +} + +static struct dma_fence *ethosu_job_run(struct drm_sched_job *sched_job) +{ + struct ethosu_job *job = to_ethosu_job(sched_job); + struct ethosu_device *dev = job->dev; + struct dma_fence *fence = job->done_fence; + + if (unlikely(job->base.s_fence->finished.error)) + return NULL; + + dma_fence_init(fence, ðosu_fence_ops, &dev->fence_lock, + dev->fence_context, ++dev->emit_seqno); + dma_fence_get(fence); + + scoped_guard(mutex, &dev->job_lock) { + dev->in_flight_job = job; + ethosu_job_hw_submit(dev, job); + } + + return fence; +} + +static void ethosu_job_handle_irq(struct ethosu_device *dev) +{ + u32 status = readl_relaxed(dev->regs + NPU_REG_STATUS); + + if (status & (STATUS_BUS_STATUS | STATUS_CMD_PARSE_ERR)) { + dev_err(dev->base.dev, "Error IRQ - %x\n", status); + drm_sched_fault(&dev->sched); + return; + } + + scoped_guard(mutex, &dev->job_lock) { + if (dev->in_flight_job) { + dma_fence_signal(dev->in_flight_job->done_fence); + dev->in_flight_job = NULL; + } + } +} + +static irqreturn_t ethosu_job_irq_handler_thread(int irq, void *data) +{ + struct ethosu_device *dev = data; + + ethosu_job_handle_irq(dev); + + return IRQ_HANDLED; +} + +static irqreturn_t ethosu_job_irq_handler(int irq, void *data) +{ + struct ethosu_device *dev = data; + u32 status = readl_relaxed(dev->regs + NPU_REG_STATUS); + + if (!(status & STATUS_IRQ_RAISED)) + return IRQ_NONE; + + writel_relaxed(CMD_CLEAR_IRQ, dev->regs + NPU_REG_CMD); + return IRQ_WAKE_THREAD; +} + +static enum drm_gpu_sched_stat ethosu_job_timedout(struct drm_sched_job *bad) +{ + struct ethosu_job *job = to_ethosu_job(bad); + struct ethosu_device *dev = job->dev; + bool running; + u32 *bocmds = to_drm_gem_dma_obj(job->cmd_bo)->vaddr; + u32 cmdaddr; + + cmdaddr = readl_relaxed(dev->regs + NPU_REG_QREAD); + running = FIELD_GET(STATUS_STATE_RUNNING, readl_relaxed(dev->regs + NPU_REG_STATUS)); + + if (running) { + int ret; + u32 reg; + + ret = readl_relaxed_poll_timeout(dev->regs + NPU_REG_QREAD, + reg, + reg != cmdaddr, + USEC_PER_MSEC, 100 * USEC_PER_MSEC); + + /* If still running and progress is being made, just return */ + if (!ret) + return DRM_GPU_SCHED_STAT_NO_HANG; + } + + dev_err(dev->base.dev, "NPU sched timed out: NPU %s, cmdstream offset 0x%x: 0x%x\n", + running ? "running" : "stopped", + cmdaddr, bocmds[cmdaddr / 4]); + + drm_sched_stop(&dev->sched, bad); + + scoped_guard(mutex, &dev->job_lock) + dev->in_flight_job = NULL; + + /* Proceed with reset now. */ + pm_runtime_force_suspend(dev->base.dev); + pm_runtime_force_resume(dev->base.dev); + + /* Restart the scheduler */ + drm_sched_start(&dev->sched, 0); + + return DRM_GPU_SCHED_STAT_RESET; +} + +static const struct drm_sched_backend_ops ethosu_sched_ops = { + .run_job = ethosu_job_run, + .timedout_job = ethosu_job_timedout, + .free_job = ethosu_job_free +}; + +int ethosu_job_init(struct ethosu_device *edev) +{ + struct device *dev = edev->base.dev; + struct drm_sched_init_args args = { + .ops = ðosu_sched_ops, + .num_rqs = DRM_SCHED_PRIORITY_COUNT, + .credit_limit = 1, + .timeout = msecs_to_jiffies(JOB_TIMEOUT_MS), + .name = dev_name(dev), + .dev = dev, + }; + int ret; + + spin_lock_init(&edev->fence_lock); + ret = devm_mutex_init(dev, &edev->job_lock); + if (ret) + return ret; + ret = devm_mutex_init(dev, &edev->sched_lock); + if (ret) + return ret; + + edev->irq = platform_get_irq(to_platform_device(dev), 0); + if (edev->irq < 0) + return edev->irq; + + ret = devm_request_threaded_irq(dev, edev->irq, + ethosu_job_irq_handler, + ethosu_job_irq_handler_thread, + IRQF_SHARED, KBUILD_MODNAME, + edev); + if (ret) { + dev_err(dev, "failed to request irq\n"); + return ret; + } + + edev->fence_context = dma_fence_context_alloc(1); + + ret = drm_sched_init(&edev->sched, &args); + if (ret) { + dev_err(dev, "Failed to create scheduler: %d\n", ret); + goto err_sched; + } + + return 0; + +err_sched: + drm_sched_fini(&edev->sched); + return ret; +} + +void ethosu_job_fini(struct ethosu_device *dev) +{ + drm_sched_fini(&dev->sched); +} + +int ethosu_job_open(struct ethosu_file_priv *ethosu_priv) +{ + struct ethosu_device *dev = ethosu_priv->edev; + struct drm_gpu_scheduler *sched = &dev->sched; + int ret; + + ret = drm_sched_entity_init(ðosu_priv->sched_entity, + DRM_SCHED_PRIORITY_NORMAL, + &sched, 1, NULL); + return WARN_ON(ret); +} + +void ethosu_job_close(struct ethosu_file_priv *ethosu_priv) +{ + struct drm_sched_entity *entity = ðosu_priv->sched_entity; + + drm_sched_entity_destroy(entity); +} + +static int ethosu_ioctl_submit_job(struct drm_device *dev, struct drm_file *file, + struct drm_ethosu_job *job) +{ + struct ethosu_device *edev = to_ethosu_device(dev); + struct ethosu_file_priv *file_priv = file->driver_priv; + struct ethosu_job *ejob = NULL; + struct ethosu_validated_cmdstream_info *cmd_info; + int ret = 0; + + /* BO region 2 is reserved if SRAM is used */ + if (job->region_bo_handles[ETHOSU_SRAM_REGION] && job->sram_size) + return -EINVAL; + + if (edev->npu_info.sram_size < job->sram_size) + return -EINVAL; + + ejob = kzalloc(sizeof(*ejob), GFP_KERNEL); + if (!ejob) + return -ENOMEM; + + kref_init(&ejob->refcount); + + ejob->dev = edev; + ejob->sram_size = job->sram_size; + + ejob->done_fence = kzalloc(sizeof(*ejob->done_fence), GFP_KERNEL); + if (!ejob->done_fence) { + ret = -ENOMEM; + goto out_cleanup_job; + } + + ret = drm_sched_job_init(&ejob->base, + &file_priv->sched_entity, + 1, NULL, file->client_id); + if (ret) + goto out_put_job; + + ejob->cmd_bo = drm_gem_object_lookup(file, job->cmd_bo); + if (!ejob->cmd_bo) { + ret = -ENOENT; + goto out_cleanup_job; + } + cmd_info = to_ethosu_bo(ejob->cmd_bo)->info; + if (!cmd_info) { + ret = -EINVAL; + goto out_cleanup_job; + } + + for (int i = 0; i < NPU_BASEP_REGION_MAX; i++) { + struct drm_gem_object *gem; + + /* Can only omit a BO handle if the region is not used or used for SRAM */ + if (!job->region_bo_handles[i] && + (!cmd_info->region_size[i] || (i == ETHOSU_SRAM_REGION && job->sram_size))) + continue; + + if (job->region_bo_handles[i] && !cmd_info->region_size[i]) { + dev_err(dev->dev, + "Cmdstream BO handle %d set for unused region %d\n", + job->region_bo_handles[i], i); + ret = -EINVAL; + goto out_cleanup_job; + } + + gem = drm_gem_object_lookup(file, job->region_bo_handles[i]); + if (!gem) { + dev_err(dev->dev, + "Invalid BO handle %d for region %d\n", + job->region_bo_handles[i], i); + ret = -ENOENT; + goto out_cleanup_job; + } + + ejob->region_bo[ejob->region_cnt] = gem; + ejob->region_bo_num[ejob->region_cnt] = i; + ejob->region_cnt++; + + if (to_ethosu_bo(gem)->info) { + dev_err(dev->dev, + "Cmdstream BO handle %d used for region %d\n", + job->region_bo_handles[i], i); + ret = -EINVAL; + goto out_cleanup_job; + } + + /* Verify the command stream doesn't have accesses outside the BO */ + if (cmd_info->region_size[i] > gem->size) { + dev_err(dev->dev, + "cmd stream region %d size greater than BO size (%llu > %zu)\n", + i, cmd_info->region_size[i], gem->size); + ret = -EOVERFLOW; + goto out_cleanup_job; + } + } + ret = ethosu_job_push(ejob); + +out_cleanup_job: + if (ret) + drm_sched_job_cleanup(&ejob->base); +out_put_job: + ethosu_job_put(ejob); + + return ret; +} + +int ethosu_ioctl_submit(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct drm_ethosu_submit *args = data; + int ret = 0; + unsigned int i = 0; + + if (args->pad) { + drm_dbg(dev, "Reserved field in drm_ethosu_submit struct should be 0.\n"); + return -EINVAL; + } + + struct drm_ethosu_job __free(kvfree) *jobs = + kvmalloc_array(args->job_count, sizeof(*jobs), GFP_KERNEL); + if (!jobs) + return -ENOMEM; + + if (copy_from_user(jobs, + (void __user *)(uintptr_t)args->jobs, + args->job_count * sizeof(*jobs))) { + drm_dbg(dev, "Failed to copy incoming job array\n"); + return -EFAULT; + } + + for (i = 0; i < args->job_count; i++) { + ret = ethosu_ioctl_submit_job(dev, file, &jobs[i]); + if (ret) + return ret; + } + + return 0; +} diff --git a/drivers/accel/ethosu/ethosu_job.h b/drivers/accel/ethosu/ethosu_job.h new file mode 100644 index 0000000000000..ff1cf448d094d --- /dev/null +++ b/drivers/accel/ethosu/ethosu_job.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* Copyright 2024-2025 Tomeu Vizoso */ +/* Copyright 2025 Arm, Ltd. */ + +#ifndef __ETHOSU_JOB_H__ +#define __ETHOSU_JOB_H__ + +#include +#include + +struct ethosu_device; +struct ethosu_file_priv; + +struct ethosu_job { + struct drm_sched_job base; + struct ethosu_device *dev; + + struct drm_gem_object *cmd_bo; + struct drm_gem_object *region_bo[NPU_BASEP_REGION_MAX]; + u8 region_bo_num[NPU_BASEP_REGION_MAX]; + u8 region_cnt; + u32 sram_size; + + /* Fence to be signaled by drm-sched once its done with the job */ + struct dma_fence *inference_done_fence; + + /* Fence to be signaled by IRQ handler when the job is complete. */ + struct dma_fence *done_fence; + + struct kref refcount; +}; + +int ethosu_ioctl_submit(struct drm_device *dev, void *data, struct drm_file *file); + +int ethosu_job_init(struct ethosu_device *dev); +void ethosu_job_fini(struct ethosu_device *dev); +int ethosu_job_open(struct ethosu_file_priv *ethosu_priv); +void ethosu_job_close(struct ethosu_file_priv *ethosu_priv); + +#endif diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index 1029e0bab0615..dbf76b8a5b4ca 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -6,6 +6,7 @@ intel_vpu-y := \ ivpu_fw.o \ ivpu_fw_log.o \ ivpu_gem.o \ + ivpu_gem_userptr.o \ ivpu_hw.o \ ivpu_hw_btrs.o \ ivpu_hw_ip.o \ diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index cd24ccd20ba6c..3bd85ee6c26b7 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -398,35 +398,25 @@ static int dct_active_set(void *data, u64 active_percent) DEFINE_DEBUGFS_ATTRIBUTE(ivpu_dct_fops, dct_active_get, dct_active_set, "%llu\n"); +static void print_priority_band(struct seq_file *s, struct ivpu_hw_info *hw, + int band, const char *name) +{ + seq_printf(s, "%-9s: grace_period %9u process_grace_period %9u process_quantum %9u\n", + name, + hw->hws.grace_period[band], + hw->hws.process_grace_period[band], + hw->hws.process_quantum[band]); +} + static int priority_bands_show(struct seq_file *s, void *v) { struct ivpu_device *vdev = s->private; struct ivpu_hw_info *hw = vdev->hw; - for (int band = VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE; - band < VPU_JOB_SCHEDULING_PRIORITY_BAND_COUNT; band++) { - switch (band) { - case VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE: - seq_puts(s, "Idle: "); - break; - - case VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL: - seq_puts(s, "Normal: "); - break; - - case VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS: - seq_puts(s, "Focus: "); - break; - - case VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME: - seq_puts(s, "Realtime: "); - break; - } - - seq_printf(s, "grace_period %9u process_grace_period %9u process_quantum %9u\n", - hw->hws.grace_period[band], hw->hws.process_grace_period[band], - hw->hws.process_quantum[band]); - } + print_priority_band(s, hw, VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE, "Idle"); + print_priority_band(s, hw, VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL, "Normal"); + print_priority_band(s, hw, VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS, "Focus"); + print_priority_band(s, hw, VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME, "Realtime"); return 0; } diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 3289751b47573..3d6fccdefdd64 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -57,7 +57,7 @@ MODULE_PARM_DESC(pll_max_ratio, "Maximum PLL ratio used to set NPU frequency"); int ivpu_sched_mode = IVPU_SCHED_MODE_AUTO; module_param_named(sched_mode, ivpu_sched_mode, int, 0444); -MODULE_PARM_DESC(sched_mode, "Scheduler mode: -1 - Use default scheduler, 0 - Use OS scheduler, 1 - Use HW scheduler"); +MODULE_PARM_DESC(sched_mode, "Scheduler mode: -1 - Use default scheduler, 0 - Use OS scheduler (supported on 27XX - 50XX), 1 - Use HW scheduler"); bool ivpu_disable_mmu_cont_pages; module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0444); @@ -134,6 +134,8 @@ bool ivpu_is_capable(struct ivpu_device *vdev, u32 capability) return true; case DRM_IVPU_CAP_DMA_MEMORY_RANGE: return true; + case DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR: + return true; case DRM_IVPU_CAP_MANAGE_CMDQ: return vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW; default: @@ -200,6 +202,9 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f case DRM_IVPU_PARAM_CAPABILITIES: args->value = ivpu_is_capable(vdev, args->index); break; + case DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE: + args->value = ivpu_fw_preempt_buf_size(vdev); + break; default: ret = -EINVAL; break; @@ -310,6 +315,7 @@ static const struct drm_ioctl_desc ivpu_drm_ioctls[] = { DRM_IOCTL_DEF_DRV(IVPU_CMDQ_CREATE, ivpu_cmdq_create_ioctl, 0), DRM_IOCTL_DEF_DRV(IVPU_CMDQ_DESTROY, ivpu_cmdq_destroy_ioctl, 0), DRM_IOCTL_DEF_DRV(IVPU_CMDQ_SUBMIT, ivpu_cmdq_submit_ioctl, 0), + DRM_IOCTL_DEF_DRV(IVPU_BO_CREATE_FROM_USERPTR, ivpu_bo_create_from_userptr_ioctl, 0), }; static int ivpu_wait_for_ready(struct ivpu_device *vdev) @@ -377,8 +383,7 @@ int ivpu_boot(struct ivpu_device *vdev) drm_WARN_ON(&vdev->drm, atomic_read(&vdev->job_timeout_counter)); drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->submitted_jobs_xa)); - /* Update boot params located at first 4KB of FW memory */ - ivpu_fw_boot_params_setup(vdev, ivpu_bo_vaddr(vdev->fw->mem)); + ivpu_fw_boot_params_setup(vdev, ivpu_bo_vaddr(vdev->fw->mem_bp)); ret = ivpu_hw_boot_fw(vdev); if (ret) { @@ -450,6 +455,9 @@ int ivpu_shutdown(struct ivpu_device *vdev) static const struct file_operations ivpu_fops = { .owner = THIS_MODULE, DRM_ACCEL_FOPS, +#ifdef CONFIG_PROC_FS + .show_fdinfo = drm_show_fdinfo, +#endif }; static const struct drm_driver driver = { @@ -464,6 +472,9 @@ static const struct drm_driver driver = { .ioctls = ivpu_drm_ioctls, .num_ioctls = ARRAY_SIZE(ivpu_drm_ioctls), .fops = &ivpu_fops, +#ifdef CONFIG_PROC_FS + .show_fdinfo = drm_show_memory_stats, +#endif .name = DRIVER_NAME, .desc = DRIVER_DESC, @@ -705,6 +716,7 @@ static struct pci_device_id ivpu_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PTL_P) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_WCL) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_NVL) }, { } }; MODULE_DEVICE_TABLE(pci, ivpu_pci_ids); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 62ab1c654e634..5b34b6f50e696 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -27,6 +27,7 @@ #define PCI_DEVICE_ID_LNL 0x643e #define PCI_DEVICE_ID_PTL_P 0xb03e #define PCI_DEVICE_ID_WCL 0xfd3e +#define PCI_DEVICE_ID_NVL 0xd71d #define IVPU_HW_IP_37XX 37 #define IVPU_HW_IP_40XX 40 @@ -78,6 +79,7 @@ #define IVPU_DBG_KREF BIT(11) #define IVPU_DBG_RPM BIT(12) #define IVPU_DBG_MMU_MAP BIT(13) +#define IVPU_DBG_IOCTL BIT(14) #define ivpu_err(vdev, fmt, ...) \ drm_err(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) @@ -245,6 +247,8 @@ static inline int ivpu_hw_ip_gen(struct ivpu_device *vdev) case PCI_DEVICE_ID_PTL_P: case PCI_DEVICE_ID_WCL: return IVPU_HW_IP_50XX; + case PCI_DEVICE_ID_NVL: + return IVPU_HW_IP_60XX; default: dump_stack(); ivpu_err(vdev, "Unknown NPU IP generation\n"); @@ -261,6 +265,7 @@ static inline int ivpu_hw_btrs_gen(struct ivpu_device *vdev) case PCI_DEVICE_ID_LNL: case PCI_DEVICE_ID_PTL_P: case PCI_DEVICE_ID_WCL: + case PCI_DEVICE_ID_NVL: return IVPU_HW_BTRS_LNL; default: dump_stack(); diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 9db741695401e..48386d2cddbb2 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -17,15 +17,10 @@ #include "ivpu_ipc.h" #include "ivpu_pm.h" -#define FW_GLOBAL_MEM_START (2ull * SZ_1G) -#define FW_GLOBAL_MEM_END (3ull * SZ_1G) -#define FW_SHARED_MEM_SIZE SZ_256M /* Must be aligned to FW_SHARED_MEM_ALIGNMENT */ -#define FW_SHARED_MEM_ALIGNMENT SZ_128K /* VPU MTRR limitation */ -#define FW_RUNTIME_MAX_SIZE SZ_512M #define FW_SHAVE_NN_MAX_SIZE SZ_2M -#define FW_RUNTIME_MIN_ADDR (FW_GLOBAL_MEM_START) -#define FW_RUNTIME_MAX_ADDR (FW_GLOBAL_MEM_END - FW_SHARED_MEM_SIZE) #define FW_FILE_IMAGE_OFFSET (VPU_FW_HEADER_SIZE + FW_VERSION_HEADER_SIZE) +#define FW_PREEMPT_BUF_MIN_SIZE SZ_4K +#define FW_PREEMPT_BUF_MAX_SIZE SZ_32M #define WATCHDOG_MSS_REDIRECT 32 #define WATCHDOG_NCE_REDIRECT 33 @@ -61,12 +56,14 @@ static struct { { IVPU_HW_IP_40XX, "intel/vpu/vpu_40xx_v0.0.bin" }, { IVPU_HW_IP_50XX, "intel/vpu/vpu_50xx_v1.bin" }, { IVPU_HW_IP_50XX, "intel/vpu/vpu_50xx_v0.0.bin" }, + { IVPU_HW_IP_60XX, "intel/vpu/vpu_60xx_v1.bin" }, }; /* Production fw_names from the table above */ MODULE_FIRMWARE("intel/vpu/vpu_37xx_v1.bin"); MODULE_FIRMWARE("intel/vpu/vpu_40xx_v1.bin"); MODULE_FIRMWARE("intel/vpu/vpu_50xx_v1.bin"); +MODULE_FIRMWARE("intel/vpu/vpu_60xx_v1.bin"); static int ivpu_fw_request(struct ivpu_device *vdev) { @@ -131,9 +128,14 @@ ivpu_fw_check_api_ver_lt(struct ivpu_device *vdev, const struct vpu_firmware_hea return false; } -static bool is_within_range(u64 addr, size_t size, u64 range_start, size_t range_size) +bool ivpu_is_within_range(u64 addr, size_t size, struct ivpu_addr_range *range) { - if (addr < range_start || addr + size > range_start + range_size) + u64 addr_end; + + if (!range || check_add_overflow(addr, size, &addr_end)) + return false; + + if (addr < range->start || addr_end > range->end) return false; return true; @@ -142,6 +144,12 @@ static bool is_within_range(u64 addr, size_t size, u64 range_start, size_t range static u32 ivpu_fw_sched_mode_select(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr) { + if (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_60XX && + ivpu_sched_mode == VPU_SCHEDULING_MODE_OS) { + ivpu_warn(vdev, "OS sched mode is not supported, using HW mode\n"); + return VPU_SCHEDULING_MODE_HW; + } + if (ivpu_sched_mode != IVPU_SCHED_MODE_AUTO) return ivpu_sched_mode; @@ -151,11 +159,56 @@ ivpu_fw_sched_mode_select(struct ivpu_device *vdev, const struct vpu_firmware_he return VPU_SCHEDULING_MODE_HW; } +static void +ivpu_preemption_config_parse(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr) +{ + struct ivpu_fw_info *fw = vdev->fw; + u32 primary_preempt_buf_size, secondary_preempt_buf_size; + + if (fw_hdr->preemption_buffer_1_max_size) + primary_preempt_buf_size = fw_hdr->preemption_buffer_1_max_size; + else + primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size; + + if (fw_hdr->preemption_buffer_2_max_size) + secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_max_size; + else + secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size; + + ivpu_dbg(vdev, FW_BOOT, "Preemption buffer size, primary: %u, secondary: %u\n", + primary_preempt_buf_size, secondary_preempt_buf_size); + + if (primary_preempt_buf_size < FW_PREEMPT_BUF_MIN_SIZE || + secondary_preempt_buf_size < FW_PREEMPT_BUF_MIN_SIZE) { + ivpu_warn(vdev, "Preemption buffers size too small\n"); + return; + } + + if (primary_preempt_buf_size > FW_PREEMPT_BUF_MAX_SIZE || + secondary_preempt_buf_size > FW_PREEMPT_BUF_MAX_SIZE) { + ivpu_warn(vdev, "Preemption buffers size too big\n"); + return; + } + + if (fw->sched_mode != VPU_SCHEDULING_MODE_HW) + return; + + if (ivpu_test_mode & IVPU_TEST_MODE_MIP_DISABLE) + return; + + vdev->fw->primary_preempt_buf_size = ALIGN(primary_preempt_buf_size, PAGE_SIZE); + vdev->fw->secondary_preempt_buf_size = ALIGN(secondary_preempt_buf_size, PAGE_SIZE); +} + static int ivpu_fw_parse(struct ivpu_device *vdev) { struct ivpu_fw_info *fw = vdev->fw; const struct vpu_firmware_header *fw_hdr = (const void *)fw->file->data; - u64 runtime_addr, image_load_addr, runtime_size, image_size; + struct ivpu_addr_range fw_image_range; + u64 boot_params_addr, boot_params_size; + u64 fw_version_addr, fw_version_size; + u64 runtime_addr, runtime_size; + u64 image_load_addr, image_size; if (fw->file->size <= FW_FILE_IMAGE_OFFSET) { ivpu_err(vdev, "Firmware file is too small: %zu\n", fw->file->size); @@ -167,18 +220,37 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) return -EINVAL; } - runtime_addr = fw_hdr->boot_params_load_address; - runtime_size = fw_hdr->runtime_size; - image_load_addr = fw_hdr->image_load_address; - image_size = fw_hdr->image_size; + boot_params_addr = fw_hdr->boot_params_load_address; + boot_params_size = SZ_4K; - if (runtime_addr < FW_RUNTIME_MIN_ADDR || runtime_addr > FW_RUNTIME_MAX_ADDR) { - ivpu_err(vdev, "Invalid firmware runtime address: 0x%llx\n", runtime_addr); + if (!ivpu_is_within_range(boot_params_addr, boot_params_size, &vdev->hw->ranges.runtime)) { + ivpu_err(vdev, "Invalid boot params address: 0x%llx\n", boot_params_addr); return -EINVAL; } - if (runtime_size < fw->file->size || runtime_size > FW_RUNTIME_MAX_SIZE) { - ivpu_err(vdev, "Invalid firmware runtime size: %llu\n", runtime_size); + fw_version_addr = fw_hdr->firmware_version_load_address; + fw_version_size = ALIGN(fw_hdr->firmware_version_size, SZ_4K); + + if (fw_version_size != SZ_4K) { + ivpu_err(vdev, "Invalid firmware version size: %u\n", + fw_hdr->firmware_version_size); + return -EINVAL; + } + + if (!ivpu_is_within_range(fw_version_addr, fw_version_size, &vdev->hw->ranges.runtime)) { + ivpu_err(vdev, "Invalid firmware version address: 0x%llx\n", fw_version_addr); + return -EINVAL; + } + + runtime_addr = fw_hdr->image_load_address; + runtime_size = fw_hdr->runtime_size - boot_params_size - fw_version_size; + + image_load_addr = fw_hdr->image_load_address; + image_size = fw_hdr->image_size; + + if (!ivpu_is_within_range(runtime_addr, runtime_size, &vdev->hw->ranges.runtime)) { + ivpu_err(vdev, "Invalid firmware runtime address: 0x%llx and size %llu\n", + runtime_addr, runtime_size); return -EINVAL; } @@ -187,23 +259,25 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) return -EINVAL; } - if (image_load_addr < runtime_addr || - image_load_addr + image_size > runtime_addr + runtime_size) { - ivpu_err(vdev, "Invalid firmware load address size: 0x%llx and size %llu\n", + if (!ivpu_is_within_range(image_load_addr, image_size, &vdev->hw->ranges.runtime)) { + ivpu_err(vdev, "Invalid firmware load address: 0x%llx and size %llu\n", image_load_addr, image_size); return -EINVAL; } - if (fw_hdr->shave_nn_fw_size > FW_SHAVE_NN_MAX_SIZE) { - ivpu_err(vdev, "SHAVE NN firmware is too big: %u\n", fw_hdr->shave_nn_fw_size); + if (ivpu_hw_range_init(vdev, &fw_image_range, image_load_addr, image_size)) return -EINVAL; - } - if (fw_hdr->entry_point < image_load_addr || - fw_hdr->entry_point >= image_load_addr + image_size) { + if (!ivpu_is_within_range(fw_hdr->entry_point, SZ_4K, &fw_image_range)) { ivpu_err(vdev, "Invalid entry point: 0x%llx\n", fw_hdr->entry_point); return -EINVAL; } + + if (fw_hdr->shave_nn_fw_size > FW_SHAVE_NN_MAX_SIZE) { + ivpu_err(vdev, "SHAVE NN firmware is too big: %u\n", fw_hdr->shave_nn_fw_size); + return -EINVAL; + } + ivpu_dbg(vdev, FW_BOOT, "Header version: 0x%x, format 0x%x\n", fw_hdr->header_version, fw_hdr->image_format); @@ -217,6 +291,10 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) if (IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, JSM, 3)) return -EINVAL; + fw->boot_params_addr = boot_params_addr; + fw->boot_params_size = boot_params_size; + fw->fw_version_addr = fw_version_addr; + fw->fw_version_size = fw_version_size; fw->runtime_addr = runtime_addr; fw->runtime_size = runtime_size; fw->image_load_offset = image_load_addr - runtime_addr; @@ -235,22 +313,13 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr); ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS"); - if (fw_hdr->preemption_buffer_1_max_size) - fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_max_size; - else - fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size; + ivpu_preemption_config_parse(vdev, fw_hdr); + ivpu_dbg(vdev, FW_BOOT, "Mid-inference preemption %s supported\n", + ivpu_fw_preempt_buf_size(vdev) ? "is" : "is not"); - if (fw_hdr->preemption_buffer_2_max_size) - fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_max_size; - else - fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size; - ivpu_dbg(vdev, FW_BOOT, "Preemption buffer sizes: primary %u, secondary %u\n", - fw->primary_preempt_buf_size, fw->secondary_preempt_buf_size); - - if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address, - fw_hdr->ro_section_size, - fw_hdr->image_load_address, - fw_hdr->image_size)) { + if (fw_hdr->ro_section_start_address && + !ivpu_is_within_range(fw_hdr->ro_section_start_address, fw_hdr->ro_section_size, + &fw_image_range)) { ivpu_err(vdev, "Invalid read-only section: start address 0x%llx, size %u\n", fw_hdr->ro_section_start_address, fw_hdr->ro_section_size); return -EINVAL; @@ -259,12 +328,18 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) fw->read_only_addr = fw_hdr->ro_section_start_address; fw->read_only_size = fw_hdr->ro_section_size; - ivpu_dbg(vdev, FW_BOOT, "Size: file %lu image %u runtime %u shavenn %u\n", - fw->file->size, fw->image_size, fw->runtime_size, fw->shave_nn_size); - ivpu_dbg(vdev, FW_BOOT, "Address: runtime 0x%llx, load 0x%llx, entry point 0x%llx\n", - fw->runtime_addr, image_load_addr, fw->entry_point); + ivpu_dbg(vdev, FW_BOOT, "Boot params: address 0x%llx, size %llu\n", + fw->boot_params_addr, fw->boot_params_size); + ivpu_dbg(vdev, FW_BOOT, "FW version: address 0x%llx, size %llu\n", + fw->fw_version_addr, fw->fw_version_size); + ivpu_dbg(vdev, FW_BOOT, "Runtime: address 0x%llx, size %u\n", + fw->runtime_addr, fw->runtime_size); + ivpu_dbg(vdev, FW_BOOT, "Image load offset: 0x%llx, size %u\n", + fw->image_load_offset, fw->image_size); ivpu_dbg(vdev, FW_BOOT, "Read-only section: address 0x%llx, size %u\n", fw->read_only_addr, fw->read_only_size); + ivpu_dbg(vdev, FW_BOOT, "FW entry point: 0x%llx\n", fw->entry_point); + ivpu_dbg(vdev, FW_BOOT, "SHAVE NN size: %u\n", fw->shave_nn_size); return 0; } @@ -291,39 +366,33 @@ ivpu_fw_init_wa(struct ivpu_device *vdev) IVPU_PRINT_WA(disable_d0i3_msg); } -static int ivpu_fw_update_global_range(struct ivpu_device *vdev) -{ - struct ivpu_fw_info *fw = vdev->fw; - u64 start = ALIGN(fw->runtime_addr + fw->runtime_size, FW_SHARED_MEM_ALIGNMENT); - u64 size = FW_SHARED_MEM_SIZE; - - if (start + size > FW_GLOBAL_MEM_END) { - ivpu_err(vdev, "No space for shared region, start %lld, size %lld\n", start, size); - return -EINVAL; - } - - ivpu_hw_range_init(&vdev->hw->ranges.global, start, size); - return 0; -} - static int ivpu_fw_mem_init(struct ivpu_device *vdev) { struct ivpu_fw_info *fw = vdev->fw; - struct ivpu_addr_range fw_range; int log_verb_size; int ret; - ret = ivpu_fw_update_global_range(vdev); - if (ret) - return ret; + fw->mem_bp = ivpu_bo_create_runtime(vdev, fw->boot_params_addr, fw->boot_params_size, + DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE); + if (!fw->mem_bp) { + ivpu_err(vdev, "Failed to create firmware boot params memory buffer\n"); + return -ENOMEM; + } - fw_range.start = fw->runtime_addr; - fw_range.end = fw->runtime_addr + fw->runtime_size; - fw->mem = ivpu_bo_create(vdev, &vdev->gctx, &fw_range, fw->runtime_size, - DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE); + fw->mem_fw_ver = ivpu_bo_create_runtime(vdev, fw->fw_version_addr, fw->fw_version_size, + DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE); + if (!fw->mem_fw_ver) { + ivpu_err(vdev, "Failed to create firmware version memory buffer\n"); + ret = -ENOMEM; + goto err_free_bp; + } + + fw->mem = ivpu_bo_create_runtime(vdev, fw->runtime_addr, fw->runtime_size, + DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE); if (!fw->mem) { ivpu_err(vdev, "Failed to create firmware runtime memory buffer\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_free_fw_ver; } ret = ivpu_mmu_context_set_pages_ro(vdev, &vdev->gctx, fw->read_only_addr, @@ -372,6 +441,10 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev) ivpu_bo_free(fw->mem_log_crit); err_free_fw_mem: ivpu_bo_free(fw->mem); +err_free_fw_ver: + ivpu_bo_free(fw->mem_fw_ver); +err_free_bp: + ivpu_bo_free(fw->mem_bp); return ret; } @@ -387,10 +460,14 @@ static void ivpu_fw_mem_fini(struct ivpu_device *vdev) ivpu_bo_free(fw->mem_log_verb); ivpu_bo_free(fw->mem_log_crit); ivpu_bo_free(fw->mem); + ivpu_bo_free(fw->mem_fw_ver); + ivpu_bo_free(fw->mem_bp); fw->mem_log_verb = NULL; fw->mem_log_crit = NULL; fw->mem = NULL; + fw->mem_fw_ver = NULL; + fw->mem_bp = NULL; } int ivpu_fw_init(struct ivpu_device *vdev) @@ -483,11 +560,6 @@ static void ivpu_fw_boot_params_print(struct ivpu_device *vdev, struct vpu_boot_ ivpu_dbg(vdev, FW_BOOT, "boot_params.cache_defaults[VPU_BOOT_L2_CACHE_CFG_NN].cfg = 0x%x\n", boot_params->cache_defaults[VPU_BOOT_L2_CACHE_CFG_NN].cfg); - ivpu_dbg(vdev, FW_BOOT, "boot_params.global_memory_allocator_base = 0x%llx\n", - boot_params->global_memory_allocator_base); - ivpu_dbg(vdev, FW_BOOT, "boot_params.global_memory_allocator_size = 0x%x\n", - boot_params->global_memory_allocator_size); - ivpu_dbg(vdev, FW_BOOT, "boot_params.shave_nn_fw_base = 0x%llx\n", boot_params->shave_nn_fw_base); @@ -495,10 +567,6 @@ static void ivpu_fw_boot_params_print(struct ivpu_device *vdev, struct vpu_boot_ boot_params->watchdog_irq_mss); ivpu_dbg(vdev, FW_BOOT, "boot_params.watchdog_irq_nce = 0x%x\n", boot_params->watchdog_irq_nce); - ivpu_dbg(vdev, FW_BOOT, "boot_params.host_to_vpu_irq = 0x%x\n", - boot_params->host_to_vpu_irq); - ivpu_dbg(vdev, FW_BOOT, "boot_params.job_done_irq = 0x%x\n", - boot_params->job_done_irq); ivpu_dbg(vdev, FW_BOOT, "boot_params.host_version_id = 0x%x\n", boot_params->host_version_id); @@ -546,6 +614,8 @@ static void ivpu_fw_boot_params_print(struct ivpu_device *vdev, struct vpu_boot_ boot_params->system_time_us); ivpu_dbg(vdev, FW_BOOT, "boot_params.power_profile = 0x%x\n", boot_params->power_profile); + ivpu_dbg(vdev, FW_BOOT, "boot_params.vpu_uses_ecc_mca_signal = 0x%x\n", + boot_params->vpu_uses_ecc_mca_signal); } void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params *boot_params) @@ -572,6 +642,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params return; } + memset(boot_params, 0, sizeof(*boot_params)); vdev->pm->is_warmboot = false; boot_params->magic = VPU_BOOT_PARAMS_MAGIC; @@ -647,6 +718,8 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->d0i3_entry_vpu_ts = 0; if (IVPU_WA(disable_d0i2)) boot_params->power_profile |= BIT(1); + boot_params->vpu_uses_ecc_mca_signal = + ivpu_hw_uses_ecc_mca_signal(vdev) ? VPU_BOOT_MCA_ECC_BOTH : 0; boot_params->system_time_us = ktime_to_us(ktime_get_real()); wmb(); /* Flush WC buffers after writing bootparams */ diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h index 7081913fb0dde..00945892b55ef 100644 --- a/drivers/accel/ivpu/ivpu_fw.h +++ b/drivers/accel/ivpu/ivpu_fw.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation */ #ifndef __IVPU_FW_H__ @@ -19,10 +19,16 @@ struct ivpu_fw_info { const struct firmware *file; const char *name; char version[FW_VERSION_STR_SIZE]; + struct ivpu_bo *mem_bp; + struct ivpu_bo *mem_fw_ver; struct ivpu_bo *mem; struct ivpu_bo *mem_shave_nn; struct ivpu_bo *mem_log_crit; struct ivpu_bo *mem_log_verb; + u64 boot_params_addr; + u64 boot_params_size; + u64 fw_version_addr; + u64 fw_version_size; u64 runtime_addr; u32 runtime_size; u64 image_load_offset; @@ -42,6 +48,7 @@ struct ivpu_fw_info { u64 last_heartbeat; }; +bool ivpu_is_within_range(u64 addr, size_t size, struct ivpu_addr_range *range); int ivpu_fw_init(struct ivpu_device *vdev); void ivpu_fw_fini(struct ivpu_device *vdev); void ivpu_fw_load(struct ivpu_device *vdev); @@ -52,4 +59,9 @@ static inline bool ivpu_fw_is_cold_boot(struct ivpu_device *vdev) return vdev->fw->entry_point == vdev->fw->cold_boot_entry_point; } +static inline u32 ivpu_fw_preempt_buf_size(struct ivpu_device *vdev) +{ + return vdev->fw->primary_preempt_buf_size + vdev->fw->secondary_preempt_buf_size; +} + #endif /* __IVPU_FW_H__ */ diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c index 59cfcf3eaded9..ece68f570b7ea 100644 --- a/drivers/accel/ivpu/ivpu_gem.c +++ b/drivers/accel/ivpu/ivpu_gem.c @@ -15,6 +15,7 @@ #include #include "ivpu_drv.h" +#include "ivpu_fw.h" #include "ivpu_gem.h" #include "ivpu_hw.h" #include "ivpu_mmu.h" @@ -27,8 +28,8 @@ static const struct drm_gem_object_funcs ivpu_gem_funcs; static inline void ivpu_dbg_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, const char *action) { ivpu_dbg(vdev, BO, - "%6s: bo %8p vpu_addr %9llx size %8zu ctx %d has_pages %d dma_mapped %d mmu_mapped %d wc %d imported %d\n", - action, bo, bo->vpu_addr, ivpu_bo_size(bo), bo->ctx_id, + "%6s: bo %8p size %9zu ctx %d vpu_addr %9llx pages %d sgt %d mmu_mapped %d wc %d imported %d\n", + action, bo, ivpu_bo_size(bo), bo->ctx_id, bo->vpu_addr, (bool)bo->base.pages, (bool)bo->base.sgt, bo->mmu_mapped, bo->base.map_wc, (bool)drm_gem_is_imported(&bo->base.base)); } @@ -43,22 +44,47 @@ static inline void ivpu_bo_unlock(struct ivpu_bo *bo) dma_resv_unlock(bo->base.base.resv); } +static struct sg_table *ivpu_bo_map_attachment(struct ivpu_device *vdev, struct ivpu_bo *bo) +{ + struct sg_table *sgt; + + drm_WARN_ON(&vdev->drm, !bo->base.base.import_attach); + + ivpu_bo_lock(bo); + + sgt = bo->base.sgt; + if (!sgt) { + sgt = dma_buf_map_attachment(bo->base.base.import_attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) + ivpu_err(vdev, "Failed to map BO in IOMMU: %ld\n", PTR_ERR(sgt)); + else + bo->base.sgt = sgt; + } + + ivpu_bo_unlock(bo); + + return sgt; +} + /* - * ivpu_bo_pin() - pin the backing physical pages and map them to VPU. + * ivpu_bo_bind() - pin the backing physical pages and map them to VPU. * * This function pins physical memory pages, then maps the physical pages * to IOMMU address space and finally updates the VPU MMU page tables * to allow the VPU to translate VPU address to IOMMU address. */ -int __must_check ivpu_bo_pin(struct ivpu_bo *bo) +int __must_check ivpu_bo_bind(struct ivpu_bo *bo) { struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); struct sg_table *sgt; int ret = 0; - ivpu_dbg_bo(vdev, bo, "pin"); + ivpu_dbg_bo(vdev, bo, "bind"); - sgt = drm_gem_shmem_get_pages_sgt(&bo->base); + if (bo->base.base.import_attach) + sgt = ivpu_bo_map_attachment(vdev, bo); + else + sgt = drm_gem_shmem_get_pages_sgt(&bo->base); if (IS_ERR(sgt)) { ret = PTR_ERR(sgt); ivpu_err(vdev, "Failed to map BO in IOMMU: %d\n", ret); @@ -70,7 +96,7 @@ int __must_check ivpu_bo_pin(struct ivpu_bo *bo) if (!bo->mmu_mapped) { drm_WARN_ON(&vdev->drm, !bo->ctx); ret = ivpu_mmu_context_map_sgt(vdev, bo->ctx, bo->vpu_addr, sgt, - ivpu_bo_is_snooped(bo)); + ivpu_bo_is_snooped(bo), ivpu_bo_is_read_only(bo)); if (ret) { ivpu_err(vdev, "Failed to map BO in MMU: %d\n", ret); goto unlock; @@ -99,9 +125,9 @@ ivpu_bo_alloc_vpu_addr(struct ivpu_bo *bo, struct ivpu_mmu_context *ctx, ret = ivpu_mmu_context_insert_node(ctx, range, ivpu_bo_size(bo), &bo->mm_node); if (!ret) { bo->ctx = ctx; + bo->ctx_id = ctx->id; bo->vpu_addr = bo->mm_node.start; - } else { - ivpu_err(vdev, "Failed to add BO to context %u: %d\n", ctx->id, ret); + ivpu_dbg_bo(vdev, bo, "vaddr"); } ivpu_bo_unlock(bo); @@ -115,7 +141,7 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo) { struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); - lockdep_assert(dma_resv_held(bo->base.base.resv) || !kref_read(&bo->base.base.refcount)); + dma_resv_assert_held(bo->base.base.resv); if (bo->mmu_mapped) { drm_WARN_ON(&vdev->drm, !bo->ctx); @@ -130,13 +156,15 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo) bo->ctx = NULL; } - if (drm_gem_is_imported(&bo->base.base)) - return; - if (bo->base.sgt) { - dma_unmap_sgtable(vdev->drm.dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0); - sg_free_table(bo->base.sgt); - kfree(bo->base.sgt); + if (bo->base.base.import_attach) { + dma_buf_unmap_attachment(bo->base.base.import_attach, + bo->base.sgt, DMA_BIDIRECTIONAL); + } else { + dma_unmap_sgtable(vdev->drm.dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0); + sg_free_table(bo->base.sgt); + kfree(bo->base.sgt); + } bo->base.sgt = NULL; } } @@ -182,10 +210,11 @@ struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t siz struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf) { + struct ivpu_device *vdev = to_ivpu_device(dev); struct device *attach_dev = dev->dev; struct dma_buf_attachment *attach; - struct sg_table *sgt; struct drm_gem_object *obj; + struct ivpu_bo *bo; int ret; attach = dma_buf_attach(dma_buf, attach_dev); @@ -194,25 +223,25 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, get_dma_buf(dma_buf); - sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL); - if (IS_ERR(sgt)) { - ret = PTR_ERR(sgt); - goto fail_detach; - } - - obj = drm_gem_shmem_prime_import_sg_table(dev, attach, sgt); + obj = drm_gem_shmem_prime_import_sg_table(dev, attach, NULL); if (IS_ERR(obj)) { ret = PTR_ERR(obj); - goto fail_unmap; + goto fail_detach; } obj->import_attach = attach; obj->resv = dma_buf->resv; + bo = to_ivpu_bo(obj); + + mutex_lock(&vdev->bo_list_lock); + list_add_tail(&bo->bo_list_node, &vdev->bo_list); + mutex_unlock(&vdev->bo_list_lock); + + ivpu_dbg(vdev, BO, "import: bo %8p size %9zu\n", bo, ivpu_bo_size(bo)); + return obj; -fail_unmap: - dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL); fail_detach: dma_buf_detach(dma_buf, attach); dma_buf_put(dma_buf); @@ -220,7 +249,7 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, return ERR_PTR(ret); } -static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 flags, u32 ctx_id) +static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 flags) { struct drm_gem_shmem_object *shmem; struct ivpu_bo *bo; @@ -238,7 +267,6 @@ static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 fla return ERR_CAST(shmem); bo = to_ivpu_bo(&shmem->base); - bo->ctx_id = ctx_id; bo->base.map_wc = flags & DRM_IVPU_BO_WC; bo->flags = flags; @@ -246,7 +274,7 @@ static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 fla list_add_tail(&bo->bo_list_node, &vdev->bo_list); mutex_unlock(&vdev->bo_list_lock); - ivpu_dbg_bo(vdev, bo, "alloc"); + ivpu_dbg(vdev, BO, " alloc: bo %8p size %9llu\n", bo, size); return bo; } @@ -259,8 +287,8 @@ static int ivpu_gem_bo_open(struct drm_gem_object *obj, struct drm_file *file) struct ivpu_addr_range *range; if (bo->ctx) { - ivpu_warn(vdev, "Can't add BO to ctx %u: already in ctx %u\n", - file_priv->ctx.id, bo->ctx->id); + ivpu_dbg(vdev, IOCTL, "Can't add BO %pe to ctx %u: already in ctx %u\n", + bo, file_priv->ctx.id, bo->ctx->id); return -EALREADY; } @@ -281,23 +309,41 @@ static void ivpu_gem_bo_free(struct drm_gem_object *obj) ivpu_dbg_bo(vdev, bo, "free"); + drm_WARN_ON(&vdev->drm, list_empty(&bo->bo_list_node)); + mutex_lock(&vdev->bo_list_lock); list_del(&bo->bo_list_node); - mutex_unlock(&vdev->bo_list_lock); drm_WARN_ON(&vdev->drm, !drm_gem_is_imported(&bo->base.base) && !dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_READ)); drm_WARN_ON(&vdev->drm, ivpu_bo_size(bo) == 0); drm_WARN_ON(&vdev->drm, bo->base.vaddr); + ivpu_bo_lock(bo); ivpu_bo_unbind_locked(bo); + ivpu_bo_unlock(bo); + + mutex_unlock(&vdev->bo_list_lock); + drm_WARN_ON(&vdev->drm, bo->mmu_mapped); drm_WARN_ON(&vdev->drm, bo->ctx); drm_WARN_ON(obj->dev, refcount_read(&bo->base.pages_use_count) > 1); + drm_WARN_ON(obj->dev, bo->base.base.vma_node.vm_files.rb_node); drm_gem_shmem_free(&bo->base); } +static enum drm_gem_object_status ivpu_gem_status(struct drm_gem_object *obj) +{ + struct ivpu_bo *bo = to_ivpu_bo(obj); + enum drm_gem_object_status status = 0; + + if (ivpu_bo_is_resident(bo)) + status |= DRM_GEM_OBJECT_RESIDENT; + + return status; +} + static const struct drm_gem_object_funcs ivpu_gem_funcs = { .free = ivpu_gem_bo_free, .open = ivpu_gem_bo_open, @@ -308,6 +354,7 @@ static const struct drm_gem_object_funcs ivpu_gem_funcs = { .vmap = drm_gem_shmem_object_vmap, .vunmap = drm_gem_shmem_object_vunmap, .mmap = drm_gem_shmem_object_mmap, + .status = ivpu_gem_status, .vm_ops = &drm_gem_shmem_vm_ops, }; @@ -320,25 +367,33 @@ int ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fi struct ivpu_bo *bo; int ret; - if (args->flags & ~DRM_IVPU_BO_FLAGS) + if (args->flags & ~DRM_IVPU_BO_FLAGS) { + ivpu_dbg(vdev, IOCTL, "Invalid BO flags 0x%x\n", args->flags); return -EINVAL; + } - if (size == 0) + if (size == 0) { + ivpu_dbg(vdev, IOCTL, "Invalid BO size %llu\n", args->size); return -EINVAL; + } - bo = ivpu_bo_alloc(vdev, size, args->flags, file_priv->ctx.id); + bo = ivpu_bo_alloc(vdev, size, args->flags); if (IS_ERR(bo)) { - ivpu_err(vdev, "Failed to allocate BO: %pe (ctx %u size %llu flags 0x%x)", + ivpu_dbg(vdev, IOCTL, "Failed to allocate BO: %pe ctx %u size %llu flags 0x%x\n", bo, file_priv->ctx.id, args->size, args->flags); return PTR_ERR(bo); } + drm_WARN_ON(&vdev->drm, bo->base.base.handle_count != 0); + ret = drm_gem_handle_create(file, &bo->base.base, &args->handle); - if (ret) - ivpu_err(vdev, "Failed to create handle for BO: %pe (ctx %u size %llu flags 0x%x)", + if (ret) { + ivpu_dbg(vdev, IOCTL, "Failed to create handle for BO: %pe ctx %u size %llu flags 0x%x\n", bo, file_priv->ctx.id, args->size, args->flags); - else + } else { args->vpu_addr = bo->vpu_addr; + drm_WARN_ON(&vdev->drm, bo->base.base.handle_count != 1); + } drm_gem_object_put(&bo->base.base); @@ -360,18 +415,21 @@ ivpu_bo_create(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, drm_WARN_ON(&vdev->drm, !PAGE_ALIGNED(range->end)); drm_WARN_ON(&vdev->drm, !PAGE_ALIGNED(size)); - bo = ivpu_bo_alloc(vdev, size, flags, IVPU_GLOBAL_CONTEXT_MMU_SSID); + bo = ivpu_bo_alloc(vdev, size, flags); if (IS_ERR(bo)) { - ivpu_err(vdev, "Failed to allocate BO: %pe (vpu_addr 0x%llx size %llu flags 0x%x)", + ivpu_err(vdev, "Failed to allocate BO: %pe vpu_addr 0x%llx size %llu flags 0x%x\n", bo, range->start, size, flags); return NULL; } ret = ivpu_bo_alloc_vpu_addr(bo, ctx, range); - if (ret) + if (ret) { + ivpu_err(vdev, "Failed to allocate NPU address for BO: %pe ctx %u size %llu: %d\n", + bo, ctx->id, size, ret); goto err_put; + } - ret = ivpu_bo_pin(bo); + ret = ivpu_bo_bind(bo); if (ret) goto err_put; @@ -391,6 +449,21 @@ ivpu_bo_create(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, return NULL; } +struct ivpu_bo *ivpu_bo_create_runtime(struct ivpu_device *vdev, u64 addr, u64 size, u32 flags) +{ + struct ivpu_addr_range range; + + if (!ivpu_is_within_range(addr, size, &vdev->hw->ranges.runtime)) { + ivpu_err(vdev, "Invalid runtime BO address 0x%llx size %llu\n", addr, size); + return NULL; + } + + if (ivpu_hw_range_init(vdev, &range, addr, size)) + return NULL; + + return ivpu_bo_create(vdev, &vdev->gctx, &range, size, flags); +} + struct ivpu_bo *ivpu_bo_create_global(struct ivpu_device *vdev, u64 size, u32 flags) { return ivpu_bo_create(vdev, &vdev->gctx, &vdev->hw->ranges.global, size, flags); diff --git a/drivers/accel/ivpu/ivpu_gem.h b/drivers/accel/ivpu/ivpu_gem.h index aa8ff14f7aae1..0c3350f22b558 100644 --- a/drivers/accel/ivpu/ivpu_gem.h +++ b/drivers/accel/ivpu/ivpu_gem.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation */ #ifndef __IVPU_GEM_H__ #define __IVPU_GEM_H__ @@ -24,19 +24,22 @@ struct ivpu_bo { bool mmu_mapped; }; -int ivpu_bo_pin(struct ivpu_bo *bo); +int ivpu_bo_bind(struct ivpu_bo *bo); void ivpu_bo_unbind_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size); struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); struct ivpu_bo *ivpu_bo_create(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, struct ivpu_addr_range *range, u64 size, u32 flags); +struct ivpu_bo *ivpu_bo_create_runtime(struct ivpu_device *vdev, u64 addr, u64 size, u32 flags); struct ivpu_bo *ivpu_bo_create_global(struct ivpu_device *vdev, u64 size, u32 flags); void ivpu_bo_free(struct ivpu_bo *bo); int ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file); int ivpu_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file); int ivpu_bo_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +int ivpu_bo_create_from_userptr_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); void ivpu_bo_list(struct drm_device *dev, struct drm_printer *p); void ivpu_bo_list_print(struct drm_device *dev); @@ -74,6 +77,16 @@ static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo) return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED; } +static inline bool ivpu_bo_is_read_only(struct ivpu_bo *bo) +{ + return bo->flags & DRM_IVPU_BO_READ_ONLY; +} + +static inline bool ivpu_bo_is_resident(struct ivpu_bo *bo) +{ + return !!bo->base.pages; +} + static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr) { if (vpu_addr < bo->vpu_addr) @@ -96,4 +109,9 @@ static inline u32 cpu_to_vpu_addr(struct ivpu_bo *bo, void *cpu_addr) return bo->vpu_addr + (cpu_addr - ivpu_bo_vaddr(bo)); } +static inline bool ivpu_bo_is_mappable(struct ivpu_bo *bo) +{ + return bo->flags & DRM_IVPU_BO_MAPPABLE; +} + #endif /* __IVPU_GEM_H__ */ diff --git a/drivers/accel/ivpu/ivpu_gem_userptr.c b/drivers/accel/ivpu/ivpu_gem_userptr.c new file mode 100644 index 0000000000000..25ba606164c03 --- /dev/null +++ b/drivers/accel/ivpu/ivpu_gem_userptr.c @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020-2025 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ivpu_drv.h" +#include "ivpu_gem.h" + +static struct sg_table * +ivpu_gem_userptr_dmabuf_map(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) +{ + struct sg_table *sgt = attachment->dmabuf->priv; + int ret; + + ret = dma_map_sgtable(attachment->dev, sgt, direction, DMA_ATTR_SKIP_CPU_SYNC); + if (ret) + return ERR_PTR(ret); + + return sgt; +} + +static void ivpu_gem_userptr_dmabuf_unmap(struct dma_buf_attachment *attachment, + struct sg_table *sgt, + enum dma_data_direction direction) +{ + dma_unmap_sgtable(attachment->dev, sgt, direction, DMA_ATTR_SKIP_CPU_SYNC); +} + +static void ivpu_gem_userptr_dmabuf_release(struct dma_buf *dma_buf) +{ + struct sg_table *sgt = dma_buf->priv; + struct sg_page_iter page_iter; + struct page *page; + + for_each_sgtable_page(sgt, &page_iter, 0) { + page = sg_page_iter_page(&page_iter); + unpin_user_page(page); + } + + sg_free_table(sgt); + kfree(sgt); +} + +static const struct dma_buf_ops ivpu_gem_userptr_dmabuf_ops = { + .map_dma_buf = ivpu_gem_userptr_dmabuf_map, + .unmap_dma_buf = ivpu_gem_userptr_dmabuf_unmap, + .release = ivpu_gem_userptr_dmabuf_release, +}; + +static struct dma_buf * +ivpu_create_userptr_dmabuf(struct ivpu_device *vdev, void __user *user_ptr, + size_t size, uint32_t flags) +{ + struct dma_buf_export_info exp_info = {}; + struct dma_buf *dma_buf; + struct sg_table *sgt; + struct page **pages; + unsigned long nr_pages = size >> PAGE_SHIFT; + unsigned int gup_flags = FOLL_LONGTERM; + int ret, i, pinned; + + /* Add FOLL_WRITE only if the BO is not read-only */ + if (!(flags & DRM_IVPU_BO_READ_ONLY)) + gup_flags |= FOLL_WRITE; + + pages = kvmalloc_array(nr_pages, sizeof(*pages), GFP_KERNEL); + if (!pages) + return ERR_PTR(-ENOMEM); + + pinned = pin_user_pages_fast((unsigned long)user_ptr, nr_pages, gup_flags, pages); + if (pinned < 0) { + ret = pinned; + ivpu_dbg(vdev, IOCTL, "Failed to pin user pages: %d\n", ret); + goto free_pages_array; + } + + if (pinned != nr_pages) { + ivpu_dbg(vdev, IOCTL, "Pinned %d pages, expected %lu\n", pinned, nr_pages); + ret = -EFAULT; + goto unpin_pages; + } + + sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) { + ret = -ENOMEM; + goto unpin_pages; + } + + ret = sg_alloc_table_from_pages(sgt, pages, nr_pages, 0, size, GFP_KERNEL); + if (ret) { + ivpu_dbg(vdev, IOCTL, "Failed to create sg table: %d\n", ret); + goto free_sgt; + } + + exp_info.exp_name = "ivpu_userptr_dmabuf"; + exp_info.owner = THIS_MODULE; + exp_info.ops = &ivpu_gem_userptr_dmabuf_ops; + exp_info.size = size; + exp_info.flags = O_RDWR | O_CLOEXEC; + exp_info.priv = sgt; + + dma_buf = dma_buf_export(&exp_info); + if (IS_ERR(dma_buf)) { + ret = PTR_ERR(dma_buf); + ivpu_dbg(vdev, IOCTL, "Failed to export userptr dma-buf: %d\n", ret); + goto free_sg_table; + } + + kvfree(pages); + return dma_buf; + +free_sg_table: + sg_free_table(sgt); +free_sgt: + kfree(sgt); +unpin_pages: + for (i = 0; i < pinned; i++) + unpin_user_page(pages[i]); +free_pages_array: + kvfree(pages); + return ERR_PTR(ret); +} + +static struct ivpu_bo * +ivpu_bo_create_from_userptr(struct ivpu_device *vdev, void __user *user_ptr, + size_t size, uint32_t flags) +{ + struct dma_buf *dma_buf; + struct drm_gem_object *obj; + struct ivpu_bo *bo; + + dma_buf = ivpu_create_userptr_dmabuf(vdev, user_ptr, size, flags); + if (IS_ERR(dma_buf)) + return ERR_CAST(dma_buf); + + obj = ivpu_gem_prime_import(&vdev->drm, dma_buf); + if (IS_ERR(obj)) { + dma_buf_put(dma_buf); + return ERR_CAST(obj); + } + + dma_buf_put(dma_buf); + + bo = to_ivpu_bo(obj); + bo->flags = flags; + + return bo; +} + +int ivpu_bo_create_from_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct drm_ivpu_bo_create_from_userptr *args = data; + struct ivpu_file_priv *file_priv = file->driver_priv; + struct ivpu_device *vdev = to_ivpu_device(dev); + void __user *user_ptr = u64_to_user_ptr(args->user_ptr); + struct ivpu_bo *bo; + int ret; + + if (args->flags & ~(DRM_IVPU_BO_HIGH_MEM | DRM_IVPU_BO_DMA_MEM | DRM_IVPU_BO_READ_ONLY)) { + ivpu_dbg(vdev, IOCTL, "Invalid BO flags: 0x%x\n", args->flags); + return -EINVAL; + } + + if (!args->user_ptr || !args->size) { + ivpu_dbg(vdev, IOCTL, "Userptr or size are zero: ptr %llx size %llu\n", + args->user_ptr, args->size); + return -EINVAL; + } + + if (!PAGE_ALIGNED(args->user_ptr) || !PAGE_ALIGNED(args->size)) { + ivpu_dbg(vdev, IOCTL, "Userptr or size not page aligned: ptr %llx size %llu\n", + args->user_ptr, args->size); + return -EINVAL; + } + + if (!access_ok(user_ptr, args->size)) { + ivpu_dbg(vdev, IOCTL, "Userptr is not accessible: ptr %llx size %llu\n", + args->user_ptr, args->size); + return -EFAULT; + } + + bo = ivpu_bo_create_from_userptr(vdev, user_ptr, args->size, args->flags); + if (IS_ERR(bo)) + return PTR_ERR(bo); + + ret = drm_gem_handle_create(file, &bo->base.base, &args->handle); + if (ret) { + ivpu_dbg(vdev, IOCTL, "Failed to create handle for BO: %pe ctx %u size %llu flags 0x%x\n", + bo, file_priv->ctx.id, args->size, args->flags); + } else { + ivpu_dbg(vdev, BO, "Created userptr BO: handle=%u vpu_addr=0x%llx size=%llu flags=0x%x\n", + args->handle, bo->vpu_addr, args->size, bo->flags); + args->vpu_addr = bo->vpu_addr; + } + + drm_gem_object_put(&bo->base.base); + + return ret; +} diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 08dcc31b56f4d..d69cd0d935694 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -8,6 +8,8 @@ #include "ivpu_hw_btrs.h" #include "ivpu_hw_ip.h" +#include +#include #include #include #include @@ -20,6 +22,10 @@ module_param_named_unsafe(fail_hw, ivpu_fail_hw, charp, 0444); MODULE_PARM_DESC(fail_hw, ",,,"); #endif +#define FW_SHARED_MEM_ALIGNMENT SZ_512K /* VPU MTRR limitation */ + +#define ECC_MCA_SIGNAL_ENABLE_MASK 0xff + static char *platform_to_str(u32 platform) { switch (platform) { @@ -147,19 +153,39 @@ static void priority_bands_init(struct ivpu_device *vdev) vdev->hw->hws.process_quantum[VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME] = 200000; } +int ivpu_hw_range_init(struct ivpu_device *vdev, struct ivpu_addr_range *range, u64 start, u64 size) +{ + u64 end; + + if (!range || check_add_overflow(start, size, &end)) { + ivpu_err(vdev, "Invalid range: start 0x%llx size %llu\n", start, size); + return -EINVAL; + } + + range->start = start; + range->end = end; + + return 0; +} + static void memory_ranges_init(struct ivpu_device *vdev) { if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { - ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M); - ivpu_hw_range_init(&vdev->hw->ranges.user, 0x88000000, 511 * SZ_1M); - ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x180000000, SZ_2G); - ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_128G); + ivpu_hw_range_init(vdev, &vdev->hw->ranges.runtime, 0x84800000, SZ_64M); + ivpu_hw_range_init(vdev, &vdev->hw->ranges.global, 0x90000000, SZ_256M); + ivpu_hw_range_init(vdev, &vdev->hw->ranges.user, 0xa0000000, 511 * SZ_1M); + ivpu_hw_range_init(vdev, &vdev->hw->ranges.shave, 0x180000000, SZ_2G); + ivpu_hw_range_init(vdev, &vdev->hw->ranges.dma, 0x200000000, SZ_128G); } else { - ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M); - ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000, SZ_2G); - ivpu_hw_range_init(&vdev->hw->ranges.user, 0x100000000, SZ_256G); + ivpu_hw_range_init(vdev, &vdev->hw->ranges.runtime, 0x80000000, SZ_64M); + ivpu_hw_range_init(vdev, &vdev->hw->ranges.global, 0x90000000, SZ_256M); + ivpu_hw_range_init(vdev, &vdev->hw->ranges.shave, 0x80000000, SZ_2G); + ivpu_hw_range_init(vdev, &vdev->hw->ranges.user, 0x100000000, SZ_256G); vdev->hw->ranges.dma = vdev->hw->ranges.user; } + + drm_WARN_ON(&vdev->drm, !IS_ALIGNED(vdev->hw->ranges.global.start, + FW_SHARED_MEM_ALIGNMENT)); } static int wp_enable(struct ivpu_device *vdev) @@ -373,3 +399,22 @@ irqreturn_t ivpu_hw_irq_handler(int irq, void *ptr) pm_runtime_mark_last_busy(vdev->drm.dev); return IRQ_HANDLED; } + +bool ivpu_hw_uses_ecc_mca_signal(struct ivpu_device *vdev) +{ + unsigned long long msr_integrity_caps; + int ret; + + if (ivpu_hw_ip_gen(vdev) < IVPU_HW_IP_50XX) + return false; + + ret = rdmsrq_safe(MSR_INTEGRITY_CAPS, &msr_integrity_caps); + if (ret) { + ivpu_warn(vdev, "Error reading MSR_INTEGRITY_CAPS: %d", ret); + return false; + } + + ivpu_dbg(vdev, MISC, "MSR_INTEGRITY_CAPS: 0x%llx\n", msr_integrity_caps); + + return msr_integrity_caps & ECC_MCA_SIGNAL_ENABLE_MASK; +} diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h index d79668fe1609f..b6d0f0d0dcccd 100644 --- a/drivers/accel/ivpu/ivpu_hw.h +++ b/drivers/accel/ivpu/ivpu_hw.h @@ -21,6 +21,7 @@ struct ivpu_hw_info { bool (*ip_irq_handler)(struct ivpu_device *vdev, int irq); } irq; struct { + struct ivpu_addr_range runtime; struct ivpu_addr_range global; struct ivpu_addr_range user; struct ivpu_addr_range shave; @@ -51,6 +52,8 @@ struct ivpu_hw_info { }; int ivpu_hw_init(struct ivpu_device *vdev); +int ivpu_hw_range_init(struct ivpu_device *vdev, struct ivpu_addr_range *range, u64 start, + u64 size); int ivpu_hw_power_up(struct ivpu_device *vdev); int ivpu_hw_power_down(struct ivpu_device *vdev); int ivpu_hw_reset(struct ivpu_device *vdev); @@ -60,6 +63,7 @@ void ivpu_irq_handlers_init(struct ivpu_device *vdev); void ivpu_hw_irq_enable(struct ivpu_device *vdev); void ivpu_hw_irq_disable(struct ivpu_device *vdev); irqreturn_t ivpu_hw_irq_handler(int irq, void *ptr); +bool ivpu_hw_uses_ecc_mca_signal(struct ivpu_device *vdev); static inline u32 ivpu_hw_btrs_irq_handler(struct ivpu_device *vdev, int irq) { @@ -71,12 +75,6 @@ static inline u32 ivpu_hw_ip_irq_handler(struct ivpu_device *vdev, int irq) return vdev->hw->irq.ip_irq_handler(vdev, irq); } -static inline void ivpu_hw_range_init(struct ivpu_addr_range *range, u64 start, u64 size) -{ - range->start = start; - range->end = start + size; -} - static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range) { return range->end - range->start; diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index afdb3b2aa72a7..06e65c5926185 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -321,6 +321,14 @@ static int wait_for_pll_lock(struct ivpu_device *vdev, bool enable) return REGB_POLL_FLD(VPU_HW_BTRS_MTL_PLL_STATUS, LOCK, exp_val, PLL_TIMEOUT_US); } +static int wait_for_cdyn_deassert(struct ivpu_device *vdev) +{ + if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) + return 0; + + return REGB_POLL_FLD(VPU_HW_BTRS_LNL_CDYN, CDYN, 0, PLL_TIMEOUT_US); +} + int ivpu_hw_btrs_wp_drive(struct ivpu_device *vdev, bool enable) { struct wp_request wp; @@ -354,6 +362,14 @@ int ivpu_hw_btrs_wp_drive(struct ivpu_device *vdev, bool enable) return ret; } + if (!enable) { + ret = wait_for_cdyn_deassert(vdev); + if (ret) { + ivpu_err(vdev, "Timed out waiting for CDYN deassert\n"); + return ret; + } + } + return 0; } @@ -673,7 +689,7 @@ bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq) if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, SURV_ERR, status)) { ivpu_dbg(vdev, IRQ, "Survivability IRQ\n"); - queue_work(system_wq, &vdev->irq_dct_work); + queue_work(system_percpu_wq, &vdev->irq_dct_work); } if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status)) { @@ -752,7 +768,7 @@ int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable) } } -void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent) +void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u8 active_percent) { u32 val = 0; u32 cmd = enable ? DCT_ENABLE : DCT_DISABLE; diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h index 032c384ac3d4d..c4c10e22f30f3 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.h +++ b/drivers/accel/ivpu/ivpu_hw_btrs.h @@ -36,7 +36,7 @@ u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev); bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq); bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq); int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable); -void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent); +void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u8 active_percent); u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev); u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev); u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_hw_btrs_lnl_reg.h b/drivers/accel/ivpu/ivpu_hw_btrs_lnl_reg.h index fff2ef2cada63..a81a9ba540fa8 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs_lnl_reg.h +++ b/drivers/accel/ivpu/ivpu_hw_btrs_lnl_reg.h @@ -74,6 +74,9 @@ #define VPU_HW_BTRS_LNL_PLL_FREQ 0x00000148u #define VPU_HW_BTRS_LNL_PLL_FREQ_RATIO_MASK GENMASK(15, 0) +#define VPU_HW_BTRS_LNL_CDYN 0x0000014cu +#define VPU_HW_BTRS_LNL_CDYN_CDYN_MASK GENMASK(15, 0) + #define VPU_HW_BTRS_LNL_TILE_FUSE 0x00000150u #define VPU_HW_BTRS_LNL_TILE_FUSE_VALID_MASK BIT_MASK(0) #define VPU_HW_BTRS_LNL_TILE_FUSE_CONFIG_MASK GENMASK(6, 1) diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index 2bf9882ab52e2..06aa1e7dc50b1 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -691,6 +691,13 @@ static void pwr_island_delay_set(struct ivpu_device *vdev) status = high ? 46 : 3; break; + case PCI_DEVICE_ID_NVL: + post = high ? 198 : 17; + post1 = 0; + post2 = high ? 198 : 17; + status = 0; + break; + default: dump_stack(); ivpu_err(vdev, "Unknown device ID\n"); @@ -889,6 +896,9 @@ static int soc_cpu_drive_40xx(struct ivpu_device *vdev, bool enable) static int soc_cpu_enable(struct ivpu_device *vdev) { + if (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_60XX) + return 0; + return soc_cpu_drive_40xx(vdev, true); } diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 5f00809d448af..1f13bf95b2b32 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -459,7 +459,7 @@ void ivpu_ipc_irq_handler(struct ivpu_device *vdev) } } - queue_work(system_wq, &vdev->irq_ipc_work); + queue_work(system_percpu_wq, &vdev->irq_ipc_work); } void ivpu_ipc_irq_work_fn(struct work_struct *work) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 060f1fc031d34..4f8564e2878a8 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -34,22 +34,20 @@ static void ivpu_cmdq_ring_db(struct ivpu_device *vdev, struct ivpu_cmdq *cmdq) static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq) { - u64 primary_size = ALIGN(vdev->fw->primary_preempt_buf_size, PAGE_SIZE); - u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE); - - if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW || - ivpu_test_mode & IVPU_TEST_MODE_MIP_DISABLE) + if (ivpu_fw_preempt_buf_size(vdev) == 0) return 0; cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.user, - primary_size, DRM_IVPU_BO_WC); + vdev->fw->primary_preempt_buf_size, + DRM_IVPU_BO_WC); if (!cmdq->primary_preempt_buf) { ivpu_err(vdev, "Failed to create primary preemption buffer\n"); return -ENOMEM; } cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.dma, - secondary_size, DRM_IVPU_BO_WC); + vdev->fw->secondary_preempt_buf_size, + DRM_IVPU_BO_WC); if (!cmdq->secondary_preempt_buf) { ivpu_err(vdev, "Failed to create secondary preemption buffer\n"); goto err_free_primary; @@ -66,20 +64,39 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq) { - if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) - return; - if (cmdq->primary_preempt_buf) ivpu_bo_free(cmdq->primary_preempt_buf); if (cmdq->secondary_preempt_buf) ivpu_bo_free(cmdq->secondary_preempt_buf); } +static int ivpu_preemption_job_init(struct ivpu_device *vdev, struct ivpu_file_priv *file_priv, + struct ivpu_cmdq *cmdq, struct ivpu_job *job) +{ + int ret; + + /* Use preemption buffer provided by the user space */ + if (job->primary_preempt_buf) + return 0; + + if (!cmdq->primary_preempt_buf) { + /* Allocate per command queue preemption buffers */ + ret = ivpu_preemption_buffers_create(vdev, file_priv, cmdq); + if (ret) + return ret; + } + + /* Use preemption buffers allocated by the kernel */ + job->primary_preempt_buf = cmdq->primary_preempt_buf; + job->secondary_preempt_buf = cmdq->secondary_preempt_buf; + + return 0; +} + static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) { struct ivpu_device *vdev = file_priv->vdev; struct ivpu_cmdq *cmdq; - int ret; cmdq = kzalloc(sizeof(*cmdq), GFP_KERNEL); if (!cmdq) @@ -89,10 +106,6 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) if (!cmdq->mem) goto err_free_cmdq; - ret = ivpu_preemption_buffers_create(vdev, file_priv, cmdq); - if (ret) - ivpu_warn(vdev, "Failed to allocate preemption buffers, preemption limited\n"); - return cmdq; err_free_cmdq: @@ -219,11 +232,13 @@ static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq * ret = ivpu_jsm_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); - if (!ret) + if (!ret) { ivpu_dbg(vdev, JOB, "DB %d registered to cmdq %d ctx %d priority %d\n", cmdq->db_id, cmdq->id, file_priv->ctx.id, cmdq->priority); - else + } else { xa_erase(&vdev->db_xa, cmdq->db_id); + cmdq->db_id = 0; + } return ret; } @@ -333,7 +348,7 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u32 cmdq = xa_load(&file_priv->cmdq_xa, cmdq_id); if (!cmdq) { - ivpu_warn_ratelimited(vdev, "Failed to find command queue with ID: %u\n", cmdq_id); + ivpu_dbg(vdev, IOCTL, "Failed to find command queue with ID: %u\n", cmdq_id); return NULL; } @@ -427,17 +442,14 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_SUBMISSION)) entry->flags = VPU_JOB_FLAGS_NULL_SUBMISSION_MASK; - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { - if (cmdq->primary_preempt_buf) { - entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; - entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); - } + if (job->primary_preempt_buf) { + entry->primary_preempt_buf_addr = job->primary_preempt_buf->vpu_addr; + entry->primary_preempt_buf_size = ivpu_bo_size(job->primary_preempt_buf); + } - if (cmdq->secondary_preempt_buf) { - entry->secondary_preempt_buf_addr = cmdq->secondary_preempt_buf->vpu_addr; - entry->secondary_preempt_buf_size = - ivpu_bo_size(cmdq->secondary_preempt_buf); - } + if (job->secondary_preempt_buf) { + entry->secondary_preempt_buf_addr = job->secondary_preempt_buf->vpu_addr; + entry->secondary_preempt_buf_size = ivpu_bo_size(job->secondary_preempt_buf); } wmb(); /* Ensure that tail is updated after filling entry */ @@ -522,7 +534,7 @@ ivpu_job_create(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) job->bo_count = bo_count; job->done_fence = ivpu_fence_create(vdev); if (!job->done_fence) { - ivpu_warn_ratelimited(vdev, "Failed to create a fence\n"); + ivpu_err(vdev, "Failed to create a fence\n"); goto err_free_job; } @@ -552,21 +564,26 @@ static struct ivpu_job *ivpu_job_remove_from_submitted_jobs(struct ivpu_device * return job; } -static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 job_status) +bool ivpu_job_handle_engine_error(struct ivpu_device *vdev, u32 job_id, u32 job_status) { - struct ivpu_job *job; - lockdep_assert_held(&vdev->submitted_jobs_lock); - job = xa_load(&vdev->submitted_jobs_xa, job_id); - if (!job) - return -ENOENT; + switch (job_status) { + case VPU_JSM_STATUS_PROCESSING_ERR: + case VPU_JSM_STATUS_ENGINE_RESET_REQUIRED_MIN ... VPU_JSM_STATUS_ENGINE_RESET_REQUIRED_MAX: + { + struct ivpu_job *job = xa_load(&vdev->submitted_jobs_xa, job_id); - if (job_status == VPU_JSM_STATUS_MVNCI_CONTEXT_VIOLATION_HW) { + if (!job) + return false; + + /* Trigger an engine reset */ guard(mutex)(&job->file_priv->lock); + job->job_status = job_status; + if (job->file_priv->has_mmu_faults) - return 0; + return false; /* * Mark context as faulty and defer destruction of the job to jobs abort thread @@ -574,23 +591,43 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 * status and ensure both are handled in the same way */ job->file_priv->has_mmu_faults = true; - queue_work(system_wq, &vdev->context_abort_work); - return 0; + queue_work(system_percpu_wq, &vdev->context_abort_work); + return true; } + default: + /* Complete job with error status, engine reset not required */ + break; + } + + return false; +} - job = ivpu_job_remove_from_submitted_jobs(vdev, job_id); +static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 job_status) +{ + struct ivpu_job *job; + + lockdep_assert_held(&vdev->submitted_jobs_lock); + + job = xa_load(&vdev->submitted_jobs_xa, job_id); if (!job) return -ENOENT; - if (job->file_priv->has_mmu_faults) - job_status = DRM_IVPU_JOB_STATUS_ABORTED; + ivpu_job_remove_from_submitted_jobs(vdev, job_id); - job->bos[CMD_BUF_IDX]->job_status = job_status; + if (job->job_status == VPU_JSM_STATUS_SUCCESS) { + if (job->file_priv->has_mmu_faults) + job->job_status = DRM_IVPU_JOB_STATUS_ABORTED; + else + job->job_status = job_status; + } + + job->bos[CMD_BUF_IDX]->job_status = job->job_status; dma_fence_signal(job->done_fence); trace_job("done", job); ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d cmdq_id %u engine %d status 0x%x\n", - job->job_id, job->file_priv->ctx.id, job->cmdq_id, job->engine_idx, job_status); + job->job_id, job->file_priv->ctx.id, job->cmdq_id, job->engine_idx, + job->job_status); ivpu_job_destroy(job); ivpu_stop_job_timeout_detection(vdev); @@ -650,7 +687,6 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority, u32 cmdq_id) else cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id); if (!cmdq) { - ivpu_warn_ratelimited(vdev, "Failed to get job queue, ctx %d\n", file_priv->ctx.id); ret = -EINVAL; goto err_unlock; } @@ -661,6 +697,13 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority, u32 cmdq_id) goto err_unlock; } + ret = ivpu_preemption_job_init(vdev, file_priv, cmdq, job); + if (ret) { + ivpu_err(vdev, "Failed to initialize preemption buffers for job %d: %d\n", + job->job_id, ret); + goto err_unlock; + } + job->cmdq_id = cmdq->id; is_first_job = xa_empty(&vdev->submitted_jobs_xa); @@ -714,7 +757,7 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority, u32 cmdq_id) static int ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 *buf_handles, - u32 buf_count, u32 commands_offset) + u32 buf_count, u32 commands_offset, u32 preempt_buffer_index) { struct ivpu_file_priv *file_priv = job->file_priv; struct ivpu_device *vdev = file_priv->vdev; @@ -727,40 +770,58 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 for (i = 0; i < buf_count; i++) { struct drm_gem_object *obj = drm_gem_object_lookup(file, buf_handles[i]); - if (!obj) + if (!obj) { + ivpu_dbg(vdev, IOCTL, "Failed to lookup GEM object with handle %u\n", + buf_handles[i]); return -ENOENT; + } job->bos[i] = to_ivpu_bo(obj); - ret = ivpu_bo_pin(job->bos[i]); + ret = ivpu_bo_bind(job->bos[i]); if (ret) return ret; } bo = job->bos[CMD_BUF_IDX]; if (!dma_resv_test_signaled(bo->base.base.resv, DMA_RESV_USAGE_READ)) { - ivpu_warn(vdev, "Buffer is already in use\n"); + ivpu_dbg(vdev, IOCTL, "Buffer is already in use by another job\n"); return -EBUSY; } if (commands_offset >= ivpu_bo_size(bo)) { - ivpu_warn(vdev, "Invalid command buffer offset %u\n", commands_offset); + ivpu_dbg(vdev, IOCTL, "Invalid commands offset %u for buffer size %zu\n", + commands_offset, ivpu_bo_size(bo)); return -EINVAL; } job->cmd_buf_vpu_addr = bo->vpu_addr + commands_offset; + if (preempt_buffer_index) { + struct ivpu_bo *preempt_bo = job->bos[preempt_buffer_index]; + + if (ivpu_bo_size(preempt_bo) < ivpu_fw_preempt_buf_size(vdev)) { + ivpu_dbg(vdev, IOCTL, "Preemption buffer is too small\n"); + return -EINVAL; + } + if (ivpu_bo_is_mappable(preempt_bo)) { + ivpu_dbg(vdev, IOCTL, "Preemption buffer cannot be mappable\n"); + return -EINVAL; + } + job->primary_preempt_buf = preempt_bo; + } + ret = drm_gem_lock_reservations((struct drm_gem_object **)job->bos, buf_count, &acquire_ctx); if (ret) { - ivpu_warn(vdev, "Failed to lock reservations: %d\n", ret); + ivpu_warn_ratelimited(vdev, "Failed to lock reservations: %d\n", ret); return ret; } for (i = 0; i < buf_count; i++) { ret = dma_resv_reserve_fences(job->bos[i]->base.base.resv, 1); if (ret) { - ivpu_warn(vdev, "Failed to reserve fences: %d\n", ret); + ivpu_warn_ratelimited(vdev, "Failed to reserve fences: %d\n", ret); goto unlock_reservations; } } @@ -780,7 +841,7 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 static int ivpu_submit(struct drm_file *file, struct ivpu_file_priv *file_priv, u32 cmdq_id, u32 buffer_count, u32 engine, void __user *buffers_ptr, u32 cmds_offset, - u8 priority) + u32 preempt_buffer_index, u8 priority) { struct ivpu_device *vdev = file_priv->vdev; struct ivpu_job *job; @@ -807,16 +868,14 @@ static int ivpu_submit(struct drm_file *file, struct ivpu_file_priv *file_priv, job = ivpu_job_create(file_priv, engine, buffer_count); if (!job) { - ivpu_err(vdev, "Failed to create job\n"); ret = -ENOMEM; goto err_exit_dev; } - ret = ivpu_job_prepare_bos_for_submit(file, job, buf_handles, buffer_count, cmds_offset); - if (ret) { - ivpu_err(vdev, "Failed to prepare job: %d\n", ret); + ret = ivpu_job_prepare_bos_for_submit(file, job, buf_handles, buffer_count, cmds_offset, + preempt_buffer_index); + if (ret) goto err_destroy_job; - } down_read(&vdev->pm->reset_lock); ret = ivpu_job_submit(job, priority, cmdq_id); @@ -842,58 +901,91 @@ static int ivpu_submit(struct drm_file *file, struct ivpu_file_priv *file_priv, int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct ivpu_file_priv *file_priv = file->driver_priv; + struct ivpu_device *vdev = file_priv->vdev; struct drm_ivpu_submit *args = data; u8 priority; - if (args->engine != DRM_IVPU_ENGINE_COMPUTE) + if (args->engine != DRM_IVPU_ENGINE_COMPUTE) { + ivpu_dbg(vdev, IOCTL, "Invalid engine %d\n", args->engine); return -EINVAL; + } - if (args->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) + if (args->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) { + ivpu_dbg(vdev, IOCTL, "Invalid priority %d\n", args->priority); return -EINVAL; + } - if (args->buffer_count == 0 || args->buffer_count > JOB_MAX_BUFFER_COUNT) + if (args->buffer_count == 0 || args->buffer_count > JOB_MAX_BUFFER_COUNT) { + ivpu_dbg(vdev, IOCTL, "Invalid buffer count %u\n", args->buffer_count); return -EINVAL; + } - if (!IS_ALIGNED(args->commands_offset, 8)) + if (!IS_ALIGNED(args->commands_offset, 8)) { + ivpu_dbg(vdev, IOCTL, "Invalid commands offset %u\n", args->commands_offset); return -EINVAL; + } - if (!file_priv->ctx.id) + if (!file_priv->ctx.id) { + ivpu_dbg(vdev, IOCTL, "Context not initialized\n"); return -EINVAL; + } - if (file_priv->has_mmu_faults) + if (file_priv->has_mmu_faults) { + ivpu_dbg(vdev, IOCTL, "Context %u has MMU faults\n", file_priv->ctx.id); return -EBADFD; + } priority = ivpu_job_to_jsm_priority(args->priority); return ivpu_submit(file, file_priv, 0, args->buffer_count, args->engine, - (void __user *)args->buffers_ptr, args->commands_offset, priority); + (void __user *)args->buffers_ptr, args->commands_offset, 0, priority); } int ivpu_cmdq_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct ivpu_file_priv *file_priv = file->driver_priv; + struct ivpu_device *vdev = file_priv->vdev; struct drm_ivpu_cmdq_submit *args = data; - if (!ivpu_is_capable(file_priv->vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) + if (!ivpu_is_capable(file_priv->vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) { + ivpu_dbg(vdev, IOCTL, "Command queue management not supported\n"); return -ENODEV; + } - if (args->cmdq_id < IVPU_CMDQ_MIN_ID || args->cmdq_id > IVPU_CMDQ_MAX_ID) + if (args->cmdq_id < IVPU_CMDQ_MIN_ID || args->cmdq_id > IVPU_CMDQ_MAX_ID) { + ivpu_dbg(vdev, IOCTL, "Invalid command queue ID %u\n", args->cmdq_id); return -EINVAL; + } - if (args->buffer_count == 0 || args->buffer_count > JOB_MAX_BUFFER_COUNT) + if (args->buffer_count == 0 || args->buffer_count > JOB_MAX_BUFFER_COUNT) { + ivpu_dbg(vdev, IOCTL, "Invalid buffer count %u\n", args->buffer_count); return -EINVAL; + } - if (!IS_ALIGNED(args->commands_offset, 8)) + if (args->preempt_buffer_index >= args->buffer_count) { + ivpu_dbg(vdev, IOCTL, "Invalid preemption buffer index %u\n", + args->preempt_buffer_index); return -EINVAL; + } - if (!file_priv->ctx.id) + if (!IS_ALIGNED(args->commands_offset, 8)) { + ivpu_dbg(vdev, IOCTL, "Invalid commands offset %u\n", args->commands_offset); return -EINVAL; + } - if (file_priv->has_mmu_faults) + if (!file_priv->ctx.id) { + ivpu_dbg(vdev, IOCTL, "Context not initialized\n"); + return -EINVAL; + } + + if (file_priv->has_mmu_faults) { + ivpu_dbg(vdev, IOCTL, "Context %u has MMU faults\n", file_priv->ctx.id); return -EBADFD; + } return ivpu_submit(file, file_priv, args->cmdq_id, args->buffer_count, VPU_ENGINE_COMPUTE, - (void __user *)args->buffers_ptr, args->commands_offset, 0); + (void __user *)args->buffers_ptr, args->commands_offset, + args->preempt_buffer_index, 0); } int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file) @@ -904,11 +996,15 @@ int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file * struct ivpu_cmdq *cmdq; int ret; - if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) + if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) { + ivpu_dbg(vdev, IOCTL, "Command queue management not supported\n"); return -ENODEV; + } - if (args->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) + if (args->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) { + ivpu_dbg(vdev, IOCTL, "Invalid priority %d\n", args->priority); return -EINVAL; + } ret = ivpu_rpm_get(vdev); if (ret < 0) @@ -936,8 +1032,10 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file u32 cmdq_id = 0; int ret; - if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) + if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_MANAGE_CMDQ)) { + ivpu_dbg(vdev, IOCTL, "Command queue management not supported\n"); return -ENODEV; + } ret = ivpu_rpm_get(vdev); if (ret < 0) @@ -984,7 +1082,9 @@ ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr, payload = (struct vpu_ipc_msg_payload_job_done *)&jsm_msg->payload; mutex_lock(&vdev->submitted_jobs_lock); - ivpu_job_signal_and_destroy(vdev, payload->job_id, payload->job_status); + if (!ivpu_job_handle_engine_error(vdev, payload->job_id, payload->job_status)) + /* No engine error, complete the job normally */ + ivpu_job_signal_and_destroy(vdev, payload->job_id, payload->job_status); mutex_unlock(&vdev->submitted_jobs_lock); } @@ -1012,7 +1112,7 @@ void ivpu_context_abort_work_fn(struct work_struct *work) if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) if (ivpu_jsm_reset_engine(vdev, 0)) - return; + goto runtime_put; mutex_lock(&vdev->context_list_lock); xa_for_each(&vdev->context_xa, ctx_id, file_priv) { @@ -1036,7 +1136,7 @@ void ivpu_context_abort_work_fn(struct work_struct *work) goto runtime_put; if (ivpu_jsm_hws_resume_engine(vdev, 0)) - return; + goto runtime_put; /* * In hardware scheduling mode NPU already has stopped processing jobs * and won't send us any further notifications, thus we have to free job related resources @@ -1049,6 +1149,5 @@ void ivpu_context_abort_work_fn(struct work_struct *work) mutex_unlock(&vdev->submitted_jobs_lock); runtime_put: - pm_runtime_mark_last_busy(vdev->drm.dev); pm_runtime_put_autosuspend(vdev->drm.dev); } diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/ivpu_job.h index 2e301c2eea7b9..3ab61e6a5616c 100644 --- a/drivers/accel/ivpu/ivpu_job.h +++ b/drivers/accel/ivpu/ivpu_job.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation */ #ifndef __IVPU_JOB_H__ @@ -15,12 +15,17 @@ struct ivpu_device; struct ivpu_file_priv; /** - * struct ivpu_cmdq - Object representing device queue used to send jobs. - * @jobq: Pointer to job queue memory shared with the device - * @mem: Memory allocated for the job queue, shared with device - * @entry_count Number of job entries in the queue - * @db_id: Doorbell assigned to this job queue - * @db_registered: True if doorbell is registered in device + * struct ivpu_cmdq - Represents a command queue for submitting jobs to the VPU. + * Tracks queue memory, preemption buffers, and metadata for job management. + * @jobq: Pointer to job queue memory shared with the device + * @primary_preempt_buf: Primary preemption buffer for this queue (optional) + * @secondary_preempt_buf: Secondary preemption buffer for this queue (optional) + * @mem: Memory allocated for the job queue, shared with device + * @entry_count: Number of job entries in the queue + * @id: Unique command queue ID + * @db_id: Doorbell ID assigned to this job queue + * @priority: Priority level of the command queue + * @is_legacy: True if this is a legacy command queue */ struct ivpu_cmdq { struct vpu_job_queue *jobq; @@ -35,16 +40,22 @@ struct ivpu_cmdq { }; /** - * struct ivpu_job - KMD object that represents batchbuffer / DMA buffer. - * Each batch / DMA buffer is a job to be submitted and executed by the VPU FW. - * This is a unit of execution, and be tracked by the job_id for - * any status reporting from VPU FW through IPC JOB RET/DONE message. - * @file_priv: The client that submitted this job - * @job_id: Job ID for KMD tracking and job status reporting from VPU FW - * @status: Status of the Job from IPC JOB RET/DONE message - * @batch_buffer: CPU vaddr points to the batch buffer memory allocated for the job - * @submit_status_offset: Offset within batch buffer where job completion handler - will update the job status + * struct ivpu_job - Representing a batch or DMA buffer submitted to the VPU. + * Each job is a unit of execution, tracked by job_id for status reporting from VPU FW. + * The structure holds all resources and metadata needed for job submission, execution, + * and completion handling. + * @vdev: Pointer to the VPU device + * @file_priv: The client context that submitted this job + * @done_fence: Fence signaled when job completes + * @cmd_buf_vpu_addr: VPU address of the command buffer for this job + * @cmdq_id: Command queue ID used for submission + * @job_id: Unique job ID for tracking and status reporting + * @engine_idx: Engine index for job execution + * @job_status: Status reported by firmware for this job + * @primary_preempt_buf: Primary preemption buffer for job + * @secondary_preempt_buf: Secondary preemption buffer for job (optional) + * @bo_count: Number of buffer objects associated with this job + * @bos: Array of buffer objects used by the job (batch buffer is at index 0) */ struct ivpu_job { struct ivpu_device *vdev; @@ -54,6 +65,9 @@ struct ivpu_job { u32 cmdq_id; u32 job_id; u32 engine_idx; + u32 job_status; + struct ivpu_bo *primary_preempt_buf; + struct ivpu_bo *secondary_preempt_buf; size_t bo_count; struct ivpu_bo *bos[] __counted_by(bo_count); }; @@ -71,6 +85,7 @@ void ivpu_cmdq_abort_all_jobs(struct ivpu_device *vdev, u32 ctx_id, u32 cmdq_id) void ivpu_job_done_consumer_init(struct ivpu_device *vdev); void ivpu_job_done_consumer_fini(struct ivpu_device *vdev); +bool ivpu_job_handle_engine_error(struct ivpu_device *vdev, u32 job_id, u32 job_status); void ivpu_context_abort_work_fn(struct work_struct *work); void ivpu_jobs_abort_all(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index 5ea010568faa4..e1baf6b649351 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -970,7 +970,7 @@ void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev) } } - queue_work(system_wq, &vdev->context_abort_work); + queue_work(system_percpu_wq, &vdev->context_abort_work); } void ivpu_mmu_evtq_dump(struct ivpu_device *vdev) diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index f0267efa55aa8..87ad593ef47d3 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -430,7 +430,7 @@ static void ivpu_mmu_context_unmap_pages(struct ivpu_mmu_context *ctx, u64 vpu_a int ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, - u64 vpu_addr, struct sg_table *sgt, bool llc_coherent) + u64 vpu_addr, struct sg_table *sgt, bool llc_coherent, bool read_only) { size_t start_vpu_addr = vpu_addr; struct scatterlist *sg; @@ -450,6 +450,8 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, prot = IVPU_MMU_ENTRY_MAPPED; if (llc_coherent) prot |= IVPU_MMU_ENTRY_FLAG_LLC_COHERENT; + if (read_only) + prot |= IVPU_MMU_ENTRY_FLAG_RO; mutex_lock(&ctx->lock); @@ -527,7 +529,8 @@ ivpu_mmu_context_unmap_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ct ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id); if (ret) - ivpu_warn(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret); + ivpu_warn_ratelimited(vdev, "Failed to invalidate TLB for ctx %u: %d\n", + ctx->id, ret); } int @@ -568,7 +571,7 @@ void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ct mutex_init(&ctx->lock); if (!context_id) { - start = vdev->hw->ranges.global.start; + start = vdev->hw->ranges.runtime.start; end = vdev->hw->ranges.shave.end; } else { start = min_t(u64, vdev->hw->ranges.user.start, vdev->hw->ranges.shave.start); diff --git a/drivers/accel/ivpu/ivpu_mmu_context.h b/drivers/accel/ivpu/ivpu_mmu_context.h index f255310968cfe..663a11a9db111 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.h +++ b/drivers/accel/ivpu/ivpu_mmu_context.h @@ -42,7 +42,7 @@ int ivpu_mmu_context_insert_node(struct ivpu_mmu_context *ctx, const struct ivpu void ivpu_mmu_context_remove_node(struct ivpu_mmu_context *ctx, struct drm_mm_node *node); int ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, - u64 vpu_addr, struct sg_table *sgt, bool llc_coherent); + u64 vpu_addr, struct sg_table *sgt, bool llc_coherent, bool read_only); void ivpu_mmu_context_unmap_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u64 vpu_addr, struct sg_table *sgt); int ivpu_mmu_context_set_pages_ro(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, diff --git a/drivers/accel/ivpu/ivpu_ms.c b/drivers/accel/ivpu/ivpu_ms.c index 2a043baf10ca1..1d9c1cb17924f 100644 --- a/drivers/accel/ivpu/ivpu_ms.c +++ b/drivers/accel/ivpu/ivpu_ms.c @@ -8,6 +8,7 @@ #include "ivpu_drv.h" #include "ivpu_gem.h" +#include "ivpu_hw.h" #include "ivpu_jsm_msg.h" #include "ivpu_ms.h" #include "ivpu_pm.h" @@ -37,8 +38,8 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil struct drm_ivpu_metric_streamer_start *args = data; struct ivpu_device *vdev = file_priv->vdev; struct ivpu_ms_instance *ms; - u64 single_buff_size; u32 sample_size; + u64 buf_size; int ret; if (!args->metric_group_mask || !args->read_period_samples || @@ -52,7 +53,8 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil mutex_lock(&file_priv->ms_lock); if (get_instance_by_mask(file_priv, args->metric_group_mask)) { - ivpu_err(vdev, "Instance already exists (mask %#llx)\n", args->metric_group_mask); + ivpu_dbg(vdev, IOCTL, "Instance already exists (mask %#llx)\n", + args->metric_group_mask); ret = -EALREADY; goto unlock; } @@ -69,12 +71,18 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil if (ret) goto err_free_ms; - single_buff_size = sample_size * - ((u64)args->read_period_samples * MS_READ_PERIOD_MULTIPLIER); - ms->bo = ivpu_bo_create_global(vdev, PAGE_ALIGN(single_buff_size * MS_NUM_BUFFERS), - DRM_IVPU_BO_CACHED | DRM_IVPU_BO_MAPPABLE); + buf_size = PAGE_ALIGN((u64)args->read_period_samples * sample_size * + MS_READ_PERIOD_MULTIPLIER * MS_NUM_BUFFERS); + if (buf_size > ivpu_hw_range_size(&vdev->hw->ranges.global)) { + ivpu_dbg(vdev, IOCTL, "Requested MS buffer size %llu exceeds range size %llu\n", + buf_size, ivpu_hw_range_size(&vdev->hw->ranges.global)); + ret = -EINVAL; + goto err_free_ms; + } + + ms->bo = ivpu_bo_create_global(vdev, buf_size, DRM_IVPU_BO_CACHED | DRM_IVPU_BO_MAPPABLE); if (!ms->bo) { - ivpu_err(vdev, "Failed to allocate MS buffer (size %llu)\n", single_buff_size); + ivpu_dbg(vdev, IOCTL, "Failed to allocate MS buffer (size %llu)\n", buf_size); ret = -ENOMEM; goto err_free_ms; } @@ -175,7 +183,8 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file * ms = get_instance_by_mask(file_priv, args->metric_group_mask); if (!ms) { - ivpu_err(vdev, "Instance doesn't exist for mask: %#llx\n", args->metric_group_mask); + ivpu_dbg(vdev, IOCTL, "Instance doesn't exist for mask: %#llx\n", + args->metric_group_mask); ret = -EINVAL; goto unlock; } diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 475ddc94f1cfe..480c075d87f69 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -54,7 +54,7 @@ static void ivpu_pm_prepare_cold_boot(struct ivpu_device *vdev) static void ivpu_pm_prepare_warm_boot(struct ivpu_device *vdev) { struct ivpu_fw_info *fw = vdev->fw; - struct vpu_boot_params *bp = ivpu_bo_vaddr(fw->mem); + struct vpu_boot_params *bp = ivpu_bo_vaddr(fw->mem_bp); if (!bp->save_restore_ret_address) { ivpu_pm_prepare_cold_boot(vdev); @@ -186,7 +186,7 @@ void ivpu_pm_trigger_recovery(struct ivpu_device *vdev, const char *reason) if (atomic_cmpxchg(&vdev->pm->reset_pending, 0, 1) == 0) { ivpu_hw_diagnose_failure(vdev); ivpu_hw_irq_disable(vdev); /* Disable IRQ early to protect from IRQ storm */ - queue_work(system_unbound_wq, &vdev->pm->recovery_work); + queue_work(system_dfl_wq, &vdev->pm->recovery_work); } } @@ -226,7 +226,8 @@ void ivpu_start_job_timeout_detection(struct ivpu_device *vdev) unsigned long timeout_ms = ivpu_tdr_timeout_ms ? ivpu_tdr_timeout_ms : vdev->timeout.tdr; /* No-op if already queued */ - queue_delayed_work(system_wq, &vdev->pm->job_timeout_work, msecs_to_jiffies(timeout_ms)); + queue_delayed_work(system_percpu_wq, &vdev->pm->job_timeout_work, + msecs_to_jiffies(timeout_ms)); } void ivpu_stop_job_timeout_detection(struct ivpu_device *vdev) @@ -359,7 +360,6 @@ int ivpu_rpm_get(struct ivpu_device *vdev) void ivpu_rpm_put(struct ivpu_device *vdev) { - pm_runtime_mark_last_busy(vdev->drm.dev); pm_runtime_put_autosuspend(vdev->drm.dev); } @@ -428,7 +428,6 @@ void ivpu_pm_enable(struct ivpu_device *vdev) struct device *dev = vdev->drm.dev; pm_runtime_allow(dev); - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); } @@ -502,6 +501,11 @@ void ivpu_pm_irq_dct_work_fn(struct work_struct *work) else ret = ivpu_pm_dct_disable(vdev); - if (!ret) - ivpu_hw_btrs_dct_set_status(vdev, enable, vdev->pm->dct_active_percent); + if (!ret) { + /* Convert percent to U1.7 format */ + u8 val = DIV_ROUND_CLOSEST(vdev->pm->dct_active_percent * 128, 100); + + ivpu_hw_btrs_dct_set_status(vdev, enable, val); + } + } diff --git a/drivers/accel/ivpu/ivpu_sysfs.c b/drivers/accel/ivpu/ivpu_sysfs.c index 268ab7744a8bb..d250a10caca9b 100644 --- a/drivers/accel/ivpu/ivpu_sysfs.c +++ b/drivers/accel/ivpu/ivpu_sysfs.c @@ -63,7 +63,8 @@ npu_memory_utilization_show(struct device *dev, struct device_attribute *attr, c mutex_lock(&vdev->bo_list_lock); list_for_each_entry(bo, &vdev->bo_list, bo_list_node) - total_npu_memory += bo->base.base.size; + if (ivpu_bo_is_resident(bo)) + total_npu_memory += ivpu_bo_size(bo); mutex_unlock(&vdev->bo_list_lock); return sysfs_emit(buf, "%lld\n", total_npu_memory); diff --git a/drivers/accel/ivpu/vpu_jsm_api.h b/drivers/accel/ivpu/vpu_jsm_api.h index 4b6b2b3d2583a..bca6a44dc041e 100644 --- a/drivers/accel/ivpu/vpu_jsm_api.h +++ b/drivers/accel/ivpu/vpu_jsm_api.h @@ -1,15 +1,16 @@ /* SPDX-License-Identifier: MIT */ /* - * Copyright (c) 2020-2024, Intel Corporation. + * Copyright (c) 2020-2025, Intel Corporation. + */ + +/** + * @addtogroup Jsm + * @{ */ /** * @file * @brief JSM shared definitions - * - * @ingroup Jsm - * @brief JSM shared definitions - * @{ */ #ifndef VPU_JSM_API_H #define VPU_JSM_API_H @@ -22,7 +23,7 @@ /* * Minor version changes when API backward compatibility is preserved. */ -#define VPU_JSM_API_VER_MINOR 29 +#define VPU_JSM_API_VER_MINOR 33 /* * API header changed (field names, documentation, formatting) but API itself has not been changed @@ -71,9 +72,15 @@ #define VPU_JSM_STATUS_MVNCI_OUT_OF_RESOURCES 0xAU #define VPU_JSM_STATUS_MVNCI_NOT_IMPLEMENTED 0xBU #define VPU_JSM_STATUS_MVNCI_INTERNAL_ERROR 0xCU -/* Job status returned when the job was preempted mid-inference */ +/* @deprecated (use VPU_JSM_STATUS_PREEMPTED_MID_COMMAND instead) */ #define VPU_JSM_STATUS_PREEMPTED_MID_INFERENCE 0xDU +/* Job status returned when the job was preempted mid-command */ +#define VPU_JSM_STATUS_PREEMPTED_MID_COMMAND 0xDU +/* Range of status codes that require engine reset */ +#define VPU_JSM_STATUS_ENGINE_RESET_REQUIRED_MIN 0xEU #define VPU_JSM_STATUS_MVNCI_CONTEXT_VIOLATION_HW 0xEU +#define VPU_JSM_STATUS_MVNCI_PREEMPTION_TIMED_OUT 0xFU +#define VPU_JSM_STATUS_ENGINE_RESET_REQUIRED_MAX 0x1FU /* * Host <-> VPU IPC channels. @@ -134,11 +141,21 @@ enum { * 2. Native fence queues are only supported on VPU 40xx onwards. */ VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U), - /* * Enable turbo mode for testing NPU performance; not recommended for regular usage. */ - VPU_JOB_QUEUE_FLAGS_TURBO_MODE = (1 << 2U) + VPU_JOB_QUEUE_FLAGS_TURBO_MODE = (1 << 2U), + /* + * Queue error detection mode flag + * For 'interactive' queues (this bit not set), the FW will identify queues that have not + * completed a job inside the TDR timeout as in error as part of engine reset sequence. + * For 'non-interactive' queues (this bit set), the FW will identify queues that have not + * progressed the heartbeat inside the non-interactive no-progress timeout as in error as + * part of engine reset sequence. Additionally, there is an upper limit applied to these + * queues: even if they progress the heartbeat, if they run longer than non-interactive + * timeout, then the FW will also identify them as in error. + */ + VPU_JOB_QUEUE_FLAGS_NON_INTERACTIVE = (1 << 3U) }; /* @@ -209,7 +226,7 @@ enum { */ #define VPU_INLINE_CMD_TYPE_FENCE_SIGNAL 0x2 -/* +/** * Job scheduling priority bands for both hardware scheduling and OS scheduling. */ enum vpu_job_scheduling_priority_band { @@ -220,16 +237,16 @@ enum vpu_job_scheduling_priority_band { VPU_JOB_SCHEDULING_PRIORITY_BAND_COUNT = 4, }; -/* +/** * Job format. * Jobs defines the actual workloads to be executed by a given engine. */ struct vpu_job_queue_entry { - /**< Address of VPU commands batch buffer */ + /** Address of VPU commands batch buffer */ u64 batch_buf_addr; - /**< Job ID */ + /** Job ID */ u32 job_id; - /**< Flags bit field, see VPU_JOB_FLAGS_* above */ + /** Flags bit field, see VPU_JOB_FLAGS_* above */ u32 flags; /** * Doorbell ring timestamp taken by KMD from SoC's global system clock, in @@ -237,20 +254,20 @@ struct vpu_job_queue_entry { * to match other profiling timestamps. */ u64 doorbell_timestamp; - /**< Extra id for job tracking, used only in the firmware perf traces */ + /** Extra id for job tracking, used only in the firmware perf traces */ u64 host_tracking_id; - /**< Address of the primary preemption buffer to use for this job */ + /** Address of the primary preemption buffer to use for this job */ u64 primary_preempt_buf_addr; - /**< Size of the primary preemption buffer to use for this job */ + /** Size of the primary preemption buffer to use for this job */ u32 primary_preempt_buf_size; - /**< Size of secondary preemption buffer to use for this job */ + /** Size of secondary preemption buffer to use for this job */ u32 secondary_preempt_buf_size; - /**< Address of secondary preemption buffer to use for this job */ + /** Address of secondary preemption buffer to use for this job */ u64 secondary_preempt_buf_addr; u64 reserved_0; }; -/* +/** * Inline command format. * Inline commands are the commands executed at scheduler level (typically, * synchronization directives). Inline command and job objects must be of @@ -258,34 +275,36 @@ struct vpu_job_queue_entry { */ struct vpu_inline_cmd { u64 reserved_0; - /* Inline command type, see VPU_INLINE_CMD_TYPE_* defines. */ + /** Inline command type, see VPU_INLINE_CMD_TYPE_* defines. */ u32 type; - /* Flags bit field, see VPU_JOB_FLAGS_* above. */ + /** Flags bit field, see VPU_JOB_FLAGS_* above. */ u32 flags; - /* Inline command payload. Depends on inline command type. */ - union { - /* Fence (wait and signal) commands' payload. */ - struct { - /* Fence object handle. */ + /** Inline command payload. Depends on inline command type. */ + union payload { + /** Fence (wait and signal) commands' payload. */ + struct fence { + /** Fence object handle. */ u64 fence_handle; - /* User VA of the current fence value. */ + /** User VA of the current fence value. */ u64 current_value_va; - /* User VA of the monitored fence value (read-only). */ + /** User VA of the monitored fence value (read-only). */ u64 monitored_value_va; - /* Value to wait for or write in fence location. */ + /** Value to wait for or write in fence location. */ u64 value; - /* User VA of the log buffer in which to add log entry on completion. */ + /** User VA of the log buffer in which to add log entry on completion. */ u64 log_buffer_va; - /* NPU private data. */ + /** NPU private data. */ u64 npu_private_data; } fence; - /* Other commands do not have a payload. */ - /* Payload definition for future inline commands can be inserted here. */ + /** + * Other commands do not have a payload: + * Payload definition for future inline commands can be inserted here. + */ u64 reserved_1[6]; } payload; }; -/* +/** * Job queue slots can be populated either with job objects or inline command objects. */ union vpu_jobq_slot { @@ -293,7 +312,7 @@ union vpu_jobq_slot { struct vpu_inline_cmd inline_cmd; }; -/* +/** * Job queue control registers. */ struct vpu_job_queue_header { @@ -301,18 +320,18 @@ struct vpu_job_queue_header { u32 head; u32 tail; u32 flags; - /* Set to 1 to indicate priority_band field is valid */ + /** Set to 1 to indicate priority_band field is valid */ u32 priority_band_valid; - /* + /** * Priority for the work of this job queue, valid only if the HWS is NOT used - * and the `priority_band_valid` is set to 1. It is applied only during - * the VPU_JSM_MSG_REGISTER_DB message processing. - * The device firmware might use the `priority_band` to optimize the power + * and the @ref priority_band_valid is set to 1. It is applied only during + * the @ref VPU_JSM_MSG_REGISTER_DB message processing. + * The device firmware might use the priority_band to optimize the power * management logic, but it will not affect the order of jobs. * Available priority bands: @see enum vpu_job_scheduling_priority_band */ u32 priority_band; - /* Inside realtime band assigns a further priority, limited to 0..31 range */ + /** Inside realtime band assigns a further priority, limited to 0..31 range */ u32 realtime_priority_level; u32 reserved_0[9]; }; @@ -337,16 +356,16 @@ enum vpu_trace_entity_type { VPU_TRACE_ENTITY_TYPE_HW_COMPONENT = 2, }; -/* +/** * HWS specific log buffer header details. * Total size is 32 bytes. */ struct vpu_hws_log_buffer_header { - /* Written by VPU after adding a log entry. Initialised by host to 0. */ + /** Written by VPU after adding a log entry. Initialised by host to 0. */ u32 first_free_entry_index; - /* Incremented by VPU every time the VPU writes the 0th entry; initialised by host to 0. */ + /** Incremented by VPU every time the VPU writes the 0th entry; initialised by host to 0. */ u32 wraparound_count; - /* + /** * This is the number of buffers that can be stored in the log buffer provided by the host. * It is written by host before passing buffer to VPU. VPU should consider it read-only. */ @@ -354,14 +373,14 @@ struct vpu_hws_log_buffer_header { u64 reserved[2]; }; -/* +/** * HWS specific log buffer entry details. * Total size is 32 bytes. */ struct vpu_hws_log_buffer_entry { - /* VPU timestamp must be an invariant timer tick (not impacted by DVFS) */ + /** VPU timestamp must be an invariant timer tick (not impacted by DVFS) */ u64 vpu_timestamp; - /* + /** * Operation type: * 0 - context state change * 1 - queue new work @@ -371,7 +390,7 @@ struct vpu_hws_log_buffer_entry { */ u32 operation_type; u32 reserved; - /* Operation data depends on operation type */ + /** Operation data depends on operation type */ u64 operation_data[2]; }; @@ -381,51 +400,54 @@ enum vpu_hws_native_fence_log_type { VPU_HWS_NATIVE_FENCE_LOG_TYPE_SIGNALS = 2 }; -/* HWS native fence log buffer header. */ +/** HWS native fence log buffer header. */ struct vpu_hws_native_fence_log_header { union { struct { - /* Index of the first free entry in buffer. */ + /** Index of the first free entry in buffer. */ u32 first_free_entry_idx; - /* Incremented each time NPU wraps around the buffer to write next entry. */ + /** + * Incremented whenever the NPU wraps around the buffer and writes + * to the first entry again. + */ u32 wraparound_count; }; - /* Field allowing atomic update of both fields above. */ + /** Field allowing atomic update of both fields above. */ u64 atomic_wraparound_and_entry_idx; }; - /* Log buffer type, see enum vpu_hws_native_fence_log_type. */ + /** Log buffer type, see enum vpu_hws_native_fence_log_type. */ u64 type; - /* Allocated number of entries in the log buffer. */ + /** Allocated number of entries in the log buffer. */ u64 entry_nb; u64 reserved[2]; }; -/* Native fence log operation types. */ +/** Native fence log operation types. */ enum vpu_hws_native_fence_log_op { VPU_HWS_NATIVE_FENCE_LOG_OP_SIGNAL_EXECUTED = 0, VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED = 1 }; -/* HWS native fence log entry. */ +/** HWS native fence log entry. */ struct vpu_hws_native_fence_log_entry { - /* Newly signaled/unblocked fence value. */ + /** Newly signaled/unblocked fence value. */ u64 fence_value; - /* Native fence object handle to which this operation belongs. */ + /** Native fence object handle to which this operation belongs. */ u64 fence_handle; - /* Operation type, see enum vpu_hws_native_fence_log_op. */ + /** Operation type, see enum vpu_hws_native_fence_log_op. */ u64 op_type; u64 reserved_0; - /* + /** * VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED only: Timestamp at which fence * wait was started (in NPU SysTime). */ u64 fence_wait_start_ts; u64 reserved_1; - /* Timestamp at which fence operation was completed (in NPU SysTime). */ + /** Timestamp at which fence operation was completed (in NPU SysTime). */ u64 fence_end_ts; }; -/* Native fence log buffer. */ +/** Native fence log buffer. */ struct vpu_hws_native_fence_log_buffer { struct vpu_hws_native_fence_log_header header; struct vpu_hws_native_fence_log_entry entry[]; @@ -435,10 +457,17 @@ struct vpu_hws_native_fence_log_buffer { * Host <-> VPU IPC messages types. */ enum vpu_ipc_msg_type { + /** Unsupported command */ VPU_JSM_MSG_UNKNOWN = 0xFFFFFFFF, - /* IPC Host -> Device, Async commands */ + /** IPC Host -> Device, base id for async commands */ VPU_JSM_MSG_ASYNC_CMD = 0x1100, + /** + * Reset engine. The NPU cancels all the jobs currently executing on the target + * engine making the engine become idle and then does a HW reset, before returning + * to the host. + * @see struct vpu_ipc_msg_payload_engine_reset + */ VPU_JSM_MSG_ENGINE_RESET = VPU_JSM_MSG_ASYNC_CMD, /** * Preempt engine. The NPU stops (preempts) all the jobs currently @@ -448,10 +477,24 @@ enum vpu_ipc_msg_type { * the target engine, but it stops processing them (until the queue doorbell * is rung again); the host is responsible to reset the job queue, either * after preemption or when resubmitting jobs to the queue. + * @see vpu_ipc_msg_payload_engine_preempt */ VPU_JSM_MSG_ENGINE_PREEMPT = 0x1101, + /** + * OS scheduling doorbell register command + * @see vpu_ipc_msg_payload_register_db + */ VPU_JSM_MSG_REGISTER_DB = 0x1102, + /** + * OS scheduling doorbell unregister command + * @see vpu_ipc_msg_payload_unregister_db + */ VPU_JSM_MSG_UNREGISTER_DB = 0x1103, + /** + * Query engine heartbeat. Heartbeat is expected to increase monotonically + * and increase while work is being progressed by NPU. + * @see vpu_ipc_msg_payload_query_engine_hb + */ VPU_JSM_MSG_QUERY_ENGINE_HB = 0x1104, VPU_JSM_MSG_GET_POWER_LEVEL_COUNT = 0x1105, VPU_JSM_MSG_GET_POWER_LEVEL = 0x1106, @@ -477,6 +520,7 @@ enum vpu_ipc_msg_type { * aborted and removed from internal scheduling queues. All doorbells assigned * to the host_ssid are unregistered and any internal FW resources belonging to * the host_ssid are released. + * @see vpu_ipc_msg_payload_ssid_release */ VPU_JSM_MSG_SSID_RELEASE = 0x110e, /** @@ -504,43 +548,78 @@ enum vpu_ipc_msg_type { * @see vpu_jsm_metric_streamer_start */ VPU_JSM_MSG_METRIC_STREAMER_INFO = 0x1112, - /** Control command: Priority band setup */ + /** + * Control command: Priority band setup + * @see vpu_ipc_msg_payload_hws_priority_band_setup + */ VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP = 0x1113, - /** Control command: Create command queue */ + /** + * Control command: Create command queue + * @see vpu_ipc_msg_payload_hws_create_cmdq + */ VPU_JSM_MSG_CREATE_CMD_QUEUE = 0x1114, - /** Control command: Destroy command queue */ + /** + * Control command: Destroy command queue + * @see vpu_ipc_msg_payload_hws_destroy_cmdq + */ VPU_JSM_MSG_DESTROY_CMD_QUEUE = 0x1115, - /** Control command: Set context scheduling properties */ + /** + * Control command: Set context scheduling properties + * @see vpu_ipc_msg_payload_hws_set_context_sched_properties + */ VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES = 0x1116, - /* + /** * Register a doorbell to notify VPU of new work. The doorbell may later be * deallocated or reassigned to another context. + * @see vpu_jsm_hws_register_db */ VPU_JSM_MSG_HWS_REGISTER_DB = 0x1117, - /** Control command: Log buffer setting */ + /** + * Control command: Log buffer setting + * @see vpu_ipc_msg_payload_hws_set_scheduling_log + */ VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG = 0x1118, - /* Control command: Suspend command queue. */ + /** + * Control command: Suspend command queue. + * @see vpu_ipc_msg_payload_hws_suspend_cmdq + */ VPU_JSM_MSG_HWS_SUSPEND_CMDQ = 0x1119, - /* Control command: Resume command queue */ + /** + * Control command: Resume command queue + * @see vpu_ipc_msg_payload_hws_resume_cmdq + */ VPU_JSM_MSG_HWS_RESUME_CMDQ = 0x111a, - /* Control command: Resume engine after reset */ + /** + * Control command: Resume engine after reset + * @see vpu_ipc_msg_payload_hws_resume_engine + */ VPU_JSM_MSG_HWS_ENGINE_RESUME = 0x111b, - /* Control command: Enable survivability/DCT mode */ + /** + * Control command: Enable survivability/DCT mode + * @see vpu_ipc_msg_payload_pwr_dct_control + */ VPU_JSM_MSG_DCT_ENABLE = 0x111c, - /* Control command: Disable survivability/DCT mode */ + /** + * Control command: Disable survivability/DCT mode + * This command has no payload + */ VPU_JSM_MSG_DCT_DISABLE = 0x111d, /** * Dump VPU state. To be used for debug purposes only. - * NOTE: Please introduce new ASYNC commands before this one. * + * This command has no payload. + * NOTE: Please introduce new ASYNC commands before this one. */ VPU_JSM_MSG_STATE_DUMP = 0x11FF, - /* IPC Host -> Device, General commands */ + /** IPC Host -> Device, base id for general commands */ VPU_JSM_MSG_GENERAL_CMD = 0x1200, + /** Unsupported command */ VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED = VPU_JSM_MSG_GENERAL_CMD, /** * Control dyndbg behavior by executing a dyndbg command; equivalent to - * Linux command: `echo '' > /dynamic_debug/control`. + * Linux command: + * @verbatim echo '' > /dynamic_debug/control @endverbatim + * @see vpu_ipc_msg_payload_dyndbg_control */ VPU_JSM_MSG_DYNDBG_CONTROL = 0x1201, /** @@ -548,17 +627,35 @@ enum vpu_ipc_msg_type { */ VPU_JSM_MSG_PWR_D0I3_ENTER = 0x1202, - /* IPC Device -> Host, Job completion */ + /** + * IPC Device -> Host, Job completion + * @see struct vpu_ipc_msg_payload_job_done + */ VPU_JSM_MSG_JOB_DONE = 0x2100, - /* IPC Device -> Host, Fence signalled */ + /** + * IPC Device -> Host, Fence signalled + * @see vpu_ipc_msg_payload_native_fence_signalled + */ VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED = 0x2101, /* IPC Device -> Host, Async command completion */ VPU_JSM_MSG_ASYNC_CMD_DONE = 0x2200, + /** + * IPC Device -> Host, engine reset complete + * @see vpu_ipc_msg_payload_engine_reset_done + */ VPU_JSM_MSG_ENGINE_RESET_DONE = VPU_JSM_MSG_ASYNC_CMD_DONE, + /** + * Preempt complete message + * @see vpu_ipc_msg_payload_engine_preempt_done + */ VPU_JSM_MSG_ENGINE_PREEMPT_DONE = 0x2201, VPU_JSM_MSG_REGISTER_DB_DONE = 0x2202, VPU_JSM_MSG_UNREGISTER_DB_DONE = 0x2203, + /** + * Response to query engine heartbeat. + * @see vpu_ipc_msg_payload_query_engine_hb_done + */ VPU_JSM_MSG_QUERY_ENGINE_HB_DONE = 0x2204, VPU_JSM_MSG_GET_POWER_LEVEL_COUNT_DONE = 0x2205, VPU_JSM_MSG_GET_POWER_LEVEL_DONE = 0x2206, @@ -575,7 +672,10 @@ enum vpu_ipc_msg_type { VPU_JSM_MSG_TRACE_GET_CAPABILITY_RSP = 0x220c, /** Response to VPU_JSM_MSG_TRACE_GET_NAME. */ VPU_JSM_MSG_TRACE_GET_NAME_RSP = 0x220d, - /** Response to VPU_JSM_MSG_SSID_RELEASE. */ + /** + * Response to VPU_JSM_MSG_SSID_RELEASE. + * @see vpu_ipc_msg_payload_ssid_release + */ VPU_JSM_MSG_SSID_RELEASE_DONE = 0x220e, /** * Response to VPU_JSM_MSG_METRIC_STREAMER_START. @@ -605,37 +705,71 @@ enum vpu_ipc_msg_type { /** * Asynchronous event sent from the VPU to the host either when the current * metric buffer is full or when the VPU has collected a multiple of - * @notify_sample_count samples as indicated through the start command - * (VPU_JSM_MSG_METRIC_STREAMER_START). Returns information about collected - * metric data. + * @ref vpu_jsm_metric_streamer_start::notify_sample_count samples as indicated + * through the start command (VPU_JSM_MSG_METRIC_STREAMER_START). Returns + * information about collected metric data. * @see vpu_jsm_metric_streamer_done */ VPU_JSM_MSG_METRIC_STREAMER_NOTIFICATION = 0x2213, - /** Response to control command: Priority band setup */ + /** + * Response to control command: Priority band setup + * @see vpu_ipc_msg_payload_hws_priority_band_setup + */ VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP = 0x2214, - /** Response to control command: Create command queue */ + /** + * Response to control command: Create command queue + * @see vpu_ipc_msg_payload_hws_create_cmdq_rsp + */ VPU_JSM_MSG_CREATE_CMD_QUEUE_RSP = 0x2215, - /** Response to control command: Destroy command queue */ + /** + * Response to control command: Destroy command queue + * @see vpu_ipc_msg_payload_hws_destroy_cmdq + */ VPU_JSM_MSG_DESTROY_CMD_QUEUE_RSP = 0x2216, - /** Response to control command: Set context scheduling properties */ + /** + * Response to control command: Set context scheduling properties + * @see vpu_ipc_msg_payload_hws_set_context_sched_properties + */ VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES_RSP = 0x2217, - /** Response to control command: Log buffer setting */ + /** + * Response to control command: Log buffer setting + * @see vpu_ipc_msg_payload_hws_set_scheduling_log + */ VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG_RSP = 0x2218, - /* IPC Device -> Host, HWS notify index entry of log buffer written */ + /** + * IPC Device -> Host, HWS notify index entry of log buffer written + * @see vpu_ipc_msg_payload_hws_scheduling_log_notification + */ VPU_JSM_MSG_HWS_SCHEDULING_LOG_NOTIFICATION = 0x2219, - /* IPC Device -> Host, HWS completion of a context suspend request */ + /** + * IPC Device -> Host, HWS completion of a context suspend request + * @see vpu_ipc_msg_payload_hws_suspend_cmdq + */ VPU_JSM_MSG_HWS_SUSPEND_CMDQ_DONE = 0x221a, - /* Response to control command: Resume command queue */ + /** + * Response to control command: Resume command queue + * @see vpu_ipc_msg_payload_hws_resume_cmdq + */ VPU_JSM_MSG_HWS_RESUME_CMDQ_RSP = 0x221b, - /* Response to control command: Resume engine command response */ + /** + * Response to control command: Resume engine command response + * @see vpu_ipc_msg_payload_hws_resume_engine + */ VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE = 0x221c, - /* Response to control command: Enable survivability/DCT mode */ + /** + * Response to control command: Enable survivability/DCT mode + * This command has no payload + */ VPU_JSM_MSG_DCT_ENABLE_DONE = 0x221d, - /* Response to control command: Disable survivability/DCT mode */ + /** + * Response to control command: Disable survivability/DCT mode + * This command has no payload + */ VPU_JSM_MSG_DCT_DISABLE_DONE = 0x221e, /** * Response to state dump control command. - * NOTE: Please introduce new ASYNC responses before this one. * + * This command has no payload. + * NOTE: Please introduce new ASYNC responses before this one. */ VPU_JSM_MSG_STATE_DUMP_RSP = 0x22FF, @@ -653,57 +787,66 @@ enum vpu_ipc_msg_type { enum vpu_ipc_msg_status { VPU_JSM_MSG_FREE, VPU_JSM_MSG_ALLOCATED }; -/* - * Host <-> LRT IPC message payload definitions +/** + * Engine reset request payload + * @see VPU_JSM_MSG_ENGINE_RESET */ struct vpu_ipc_msg_payload_engine_reset { - /* Engine to be reset. */ + /** Engine to be reset. */ u32 engine_idx; - /* Reserved */ + /** Reserved */ u32 reserved_0; }; +/** + * Engine preemption request struct + * @see VPU_JSM_MSG_ENGINE_PREEMPT + */ struct vpu_ipc_msg_payload_engine_preempt { - /* Engine to be preempted. */ + /** Engine to be preempted. */ u32 engine_idx; - /* ID of the preemption request. */ + /** ID of the preemption request. */ u32 preempt_id; }; -/* - * @brief Register doorbell command structure. +/** + * Register doorbell command structure. * This structure supports doorbell registration for only OS scheduling. * @see VPU_JSM_MSG_REGISTER_DB */ struct vpu_ipc_msg_payload_register_db { - /* Index of the doorbell to register. */ + /** Index of the doorbell to register. */ u32 db_idx; - /* Reserved */ + /** Reserved */ u32 reserved_0; - /* Virtual address in Global GTT pointing to the start of job queue. */ + /** Virtual address in Global GTT pointing to the start of job queue. */ u64 jobq_base; - /* Size of the job queue in bytes. */ + /** Size of the job queue in bytes. */ u32 jobq_size; - /* Host sub-stream ID for the context assigned to the doorbell. */ + /** Host sub-stream ID for the context assigned to the doorbell. */ u32 host_ssid; }; /** - * @brief Unregister doorbell command structure. + * Unregister doorbell command structure. * Request structure to unregister a doorbell for both HW and OS scheduling. * @see VPU_JSM_MSG_UNREGISTER_DB */ struct vpu_ipc_msg_payload_unregister_db { - /* Index of the doorbell to unregister. */ + /** Index of the doorbell to unregister. */ u32 db_idx; - /* Reserved */ + /** Reserved */ u32 reserved_0; }; +/** + * Heartbeat request structure + * @see VPU_JSM_MSG_QUERY_ENGINE_HB + */ struct vpu_ipc_msg_payload_query_engine_hb { - /* Engine to return heartbeat value. */ + /** Engine to return heartbeat value. */ u32 engine_idx; - /* Reserved */ + /** Reserved */ u32 reserved_0; }; @@ -723,10 +866,14 @@ struct vpu_ipc_msg_payload_power_level { u32 reserved_0; }; +/** + * Structure for requesting ssid release + * @see VPU_JSM_MSG_SSID_RELEASE + */ struct vpu_ipc_msg_payload_ssid_release { - /* Host sub-stream ID for the context to be released. */ + /** Host sub-stream ID for the context to be released. */ u32 host_ssid; - /* Reserved */ + /** Reserved */ u32 reserved_0; }; @@ -752,7 +899,7 @@ struct vpu_jsm_metric_streamer_start { u64 sampling_rate; /** * If > 0 the VPU will send a VPU_JSM_MSG_METRIC_STREAMER_NOTIFICATION message - * after every @notify_sample_count samples is collected or dropped by the VPU. + * after every @ref notify_sample_count samples is collected or dropped by the VPU. * If set to UINT_MAX the VPU will only generate a notification when the metric * buffer is full. If set to 0 the VPU will never generate a notification. */ @@ -762,9 +909,9 @@ struct vpu_jsm_metric_streamer_start { * Address and size of the buffer where the VPU will write metric data. The * VPU writes all counters from enabled metric groups one after another. If * there is no space left to write data at the next sample period the VPU - * will switch to the next buffer (@see next_buffer_addr) and will optionally - * send a notification to the host driver if @notify_sample_count is non-zero. - * If @next_buffer_addr is NULL the VPU will stop collecting metric data. + * will switch to the next buffer (@ref next_buffer_addr) and will optionally + * send a notification to the host driver if @ref notify_sample_count is non-zero. + * If @ref next_buffer_addr is NULL the VPU will stop collecting metric data. */ u64 buffer_addr; u64 buffer_size; @@ -827,63 +974,80 @@ struct vpu_jsm_metric_streamer_update { u64 next_buffer_size; }; +/** + * Device -> host job completion message. + * @see VPU_JSM_MSG_JOB_DONE + */ struct vpu_ipc_msg_payload_job_done { - /* Engine to which the job was submitted. */ + /** Engine to which the job was submitted. */ u32 engine_idx; - /* Index of the doorbell to which the job was submitted */ + /** Index of the doorbell to which the job was submitted */ u32 db_idx; - /* ID of the completed job */ + /** ID of the completed job */ u32 job_id; - /* Status of the completed job */ + /** Status of the completed job */ u32 job_status; - /* Host SSID */ + /** Host SSID */ u32 host_ssid; - /* Zero Padding */ + /** Zero Padding */ u32 reserved_0; - /* Command queue id */ + /** Command queue id */ u64 cmdq_id; }; -/* +/** * Notification message upon native fence signalling. * @see VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED */ struct vpu_ipc_msg_payload_native_fence_signalled { - /* Engine ID. */ + /** Engine ID. */ u32 engine_idx; - /* Host SSID. */ + /** Host SSID. */ u32 host_ssid; - /* CMDQ ID */ + /** CMDQ ID */ u64 cmdq_id; - /* Fence object handle. */ + /** Fence object handle. */ u64 fence_handle; }; +/** + * vpu_ipc_msg_payload_engine_reset_done will contain an array of this structure + * which contains which queues caused reset if FW was able to detect any error. + * @see vpu_ipc_msg_payload_engine_reset_done + */ struct vpu_jsm_engine_reset_context { - /* Host SSID */ + /** Host SSID */ u32 host_ssid; - /* Zero Padding */ + /** Zero Padding */ u32 reserved_0; - /* Command queue id */ + /** Command queue id */ u64 cmdq_id; - /* See VPU_ENGINE_RESET_CONTEXT_* defines */ + /** See VPU_ENGINE_RESET_CONTEXT_* defines */ u64 flags; }; +/** + * Engine reset response. + * @see VPU_JSM_MSG_ENGINE_RESET_DONE + */ struct vpu_ipc_msg_payload_engine_reset_done { - /* Engine ordinal */ + /** Engine ordinal */ u32 engine_idx; - /* Number of impacted contexts */ + /** Number of impacted contexts */ u32 num_impacted_contexts; - /* Array of impacted command queue ids and their flags */ + /** Array of impacted command queue ids and their flags */ struct vpu_jsm_engine_reset_context impacted_contexts[VPU_MAX_ENGINE_RESET_IMPACTED_CONTEXTS]; }; +/** + * Preemption response struct + * @see VPU_JSM_MSG_ENGINE_PREEMPT_DONE + */ struct vpu_ipc_msg_payload_engine_preempt_done { - /* Engine preempted. */ + /** Engine preempted. */ u32 engine_idx; - /* ID of the preemption request. */ + /** ID of the preemption request. */ u32 preempt_id; }; @@ -912,12 +1076,16 @@ struct vpu_ipc_msg_payload_unregister_db_done { u32 reserved_0; }; +/** + * Structure for heartbeat response + * @see VPU_JSM_MSG_QUERY_ENGINE_HB_DONE + */ struct vpu_ipc_msg_payload_query_engine_hb_done { - /* Engine returning heartbeat value. */ + /** Engine returning heartbeat value. */ u32 engine_idx; - /* Reserved */ + /** Reserved */ u32 reserved_0; - /* Heartbeat value. */ + /** Heartbeat value. */ u64 heartbeat; }; @@ -937,7 +1105,10 @@ struct vpu_ipc_msg_payload_get_power_level_count_done { u8 power_limit[16]; }; -/* HWS priority band setup request / response */ +/** + * HWS priority band setup request / response + * @see VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP + */ struct vpu_ipc_msg_payload_hws_priority_band_setup { /* * Grace period in 100ns units when preempting another priority band for @@ -964,15 +1135,23 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup { * TDR timeout value in milliseconds. Default value of 0 meaning no timeout. */ u32 tdr_timeout; + /* Non-interactive queue timeout for no progress of heartbeat in milliseconds. + * Default value of 0 meaning no timeout. + */ + u32 non_interactive_no_progress_timeout; + /* + * Non-interactive queue upper limit timeout value in milliseconds. Default + * value of 0 meaning no timeout. + */ + u32 non_interactive_timeout; }; -/* +/** * @brief HWS create command queue request. * Host will create a command queue via this command. * Note: Cmdq group is a handle of an object which * may contain one or more command queues. * @see VPU_JSM_MSG_CREATE_CMD_QUEUE - * @see VPU_JSM_MSG_CREATE_CMD_QUEUE_RSP */ struct vpu_ipc_msg_payload_hws_create_cmdq { /* Process id */ @@ -993,66 +1172,73 @@ struct vpu_ipc_msg_payload_hws_create_cmdq { u32 reserved_0; }; -/* - * @brief HWS create command queue response. - * @see VPU_JSM_MSG_CREATE_CMD_QUEUE +/** + * HWS create command queue response. * @see VPU_JSM_MSG_CREATE_CMD_QUEUE_RSP */ struct vpu_ipc_msg_payload_hws_create_cmdq_rsp { - /* Process id */ + /** Process id */ u64 process_id; - /* Host SSID */ + /** Host SSID */ u32 host_ssid; - /* Engine for which queue is being created */ + /** Engine for which queue is being created */ u32 engine_idx; - /* Command queue group */ + /** Command queue group */ u64 cmdq_group; - /* Command queue id */ + /** Command queue id */ u64 cmdq_id; }; -/* HWS destroy command queue request / response */ +/** + * HWS destroy command queue request / response + * @see VPU_JSM_MSG_DESTROY_CMD_QUEUE + * @see VPU_JSM_MSG_DESTROY_CMD_QUEUE_RSP + */ struct vpu_ipc_msg_payload_hws_destroy_cmdq { - /* Host SSID */ + /** Host SSID */ u32 host_ssid; - /* Zero Padding */ + /** Zero Padding */ u32 reserved; - /* Command queue id */ + /** Command queue id */ u64 cmdq_id; }; -/* HWS set context scheduling properties request / response */ +/** + * HWS set context scheduling properties request / response + * @see VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES + * @see VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES_RSP + */ struct vpu_ipc_msg_payload_hws_set_context_sched_properties { - /* Host SSID */ + /** Host SSID */ u32 host_ssid; - /* Zero Padding */ + /** Zero Padding */ u32 reserved_0; - /* Command queue id */ + /** Command queue id */ u64 cmdq_id; - /* + /** * Priority band to assign to work of this context. * Available priority bands: @see enum vpu_job_scheduling_priority_band */ u32 priority_band; - /* Inside realtime band assigns a further priority */ + /** Inside realtime band assigns a further priority */ u32 realtime_priority_level; - /* Priority relative to other contexts in the same process */ + /** Priority relative to other contexts in the same process */ s32 in_process_priority; - /* Zero padding / Reserved */ + /** Zero padding / Reserved */ u32 reserved_1; - /* + /** * Context quantum relative to other contexts of same priority in the same process * Minimum value supported by NPU is 1ms (10000 in 100ns units). */ u64 context_quantum; - /* Grace period when preempting context of the same priority within the same process */ + /** Grace period when preempting context of the same priority within the same process */ u64 grace_period_same_priority; - /* Grace period when preempting context of a lower priority within the same process */ + /** Grace period when preempting context of a lower priority within the same process */ u64 grace_period_lower_priority; }; -/* - * @brief Register doorbell command structure. +/** + * Register doorbell command structure. * This structure supports doorbell registration for both HW and OS scheduling. * Note: Queue base and size are added here so that the same structure can be used for * OS scheduling and HW scheduling. For OS scheduling, cmdq_id will be ignored @@ -1061,27 +1247,27 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties { * @see VPU_JSM_MSG_HWS_REGISTER_DB */ struct vpu_jsm_hws_register_db { - /* Index of the doorbell to register. */ + /** Index of the doorbell to register. */ u32 db_id; - /* Host sub-stream ID for the context assigned to the doorbell. */ + /** Host sub-stream ID for the context assigned to the doorbell. */ u32 host_ssid; - /* ID of the command queue associated with the doorbell. */ + /** ID of the command queue associated with the doorbell. */ u64 cmdq_id; - /* Virtual address pointing to the start of command queue. */ + /** Virtual address pointing to the start of command queue. */ u64 cmdq_base; - /* Size of the command queue in bytes. */ + /** Size of the command queue in bytes. */ u64 cmdq_size; }; -/* - * @brief Structure to set another buffer to be used for scheduling-related logging. +/** + * Structure to set another buffer to be used for scheduling-related logging. * The size of the logging buffer and the number of entries is defined as part of the * buffer itself as described next. * The log buffer received from the host is made up of; - * - header: 32 bytes in size, as shown in 'struct vpu_hws_log_buffer_header'. + * - header: 32 bytes in size, as shown in @ref vpu_hws_log_buffer_header. * The header contains the number of log entries in the buffer. * - log entry: 0 to n-1, each log entry is 32 bytes in size, as shown in - * 'struct vpu_hws_log_buffer_entry'. + * @ref vpu_hws_log_buffer_entry. * The entry contains the VPU timestamp, operation type and data. * The host should provide the notify index value of log buffer to VPU. This is a * value defined within the log buffer and when written to will generate the @@ -1095,30 +1281,30 @@ struct vpu_jsm_hws_register_db { * @see VPU_JSM_MSG_HWS_SCHEDULING_LOG_NOTIFICATION */ struct vpu_ipc_msg_payload_hws_set_scheduling_log { - /* Engine ordinal */ + /** Engine ordinal */ u32 engine_idx; - /* Host SSID */ + /** Host SSID */ u32 host_ssid; - /* + /** * VPU log buffer virtual address. * Set to 0 to disable logging for this engine. */ u64 vpu_log_buffer_va; - /* + /** * Notify index of log buffer. VPU_JSM_MSG_HWS_SCHEDULING_LOG_NOTIFICATION * is generated when an event log is written to this index. */ u64 notify_index; - /* + /** * Field is now deprecated, will be removed when KMD is updated to support removal */ u32 enable_extra_events; - /* Zero Padding */ + /** Zero Padding */ u32 reserved_0; }; -/* - * @brief The scheduling log notification is generated by VPU when it writes +/** + * The scheduling log notification is generated by VPU when it writes * an event into the log buffer at the notify_index. VPU notifies host with * VPU_JSM_MSG_HWS_SCHEDULING_LOG_NOTIFICATION. This is an asynchronous * message from VPU to host. @@ -1126,14 +1312,14 @@ struct vpu_ipc_msg_payload_hws_set_scheduling_log { * @see VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG */ struct vpu_ipc_msg_payload_hws_scheduling_log_notification { - /* Engine ordinal */ + /** Engine ordinal */ u32 engine_idx; - /* Zero Padding */ + /** Zero Padding */ u32 reserved_0; }; -/* - * @brief HWS suspend command queue request and done structure. +/** + * HWS suspend command queue request and done structure. * Host will request the suspend of contexts and VPU will; * - Suspend all work on this context * - Preempt any running work @@ -1152,21 +1338,21 @@ struct vpu_ipc_msg_payload_hws_scheduling_log_notification { * @see VPU_JSM_MSG_HWS_SUSPEND_CMDQ_DONE */ struct vpu_ipc_msg_payload_hws_suspend_cmdq { - /* Host SSID */ + /** Host SSID */ u32 host_ssid; - /* Zero Padding */ + /** Zero Padding */ u32 reserved_0; - /* Command queue id */ + /** Command queue id */ u64 cmdq_id; - /* + /** * Suspend fence value - reported by the VPU suspend context * completed once suspend is complete. */ u64 suspend_fence_value; }; -/* - * @brief HWS Resume command queue request / response structure. +/** + * HWS Resume command queue request / response structure. * Host will request the resume of a context; * - VPU will resume all work on this context * - Scheduler will allow this context to be scheduled @@ -1174,25 +1360,25 @@ struct vpu_ipc_msg_payload_hws_suspend_cmdq { * @see VPU_JSM_MSG_HWS_RESUME_CMDQ_RSP */ struct vpu_ipc_msg_payload_hws_resume_cmdq { - /* Host SSID */ + /** Host SSID */ u32 host_ssid; - /* Zero Padding */ + /** Zero Padding */ u32 reserved_0; - /* Command queue id */ + /** Command queue id */ u64 cmdq_id; }; -/* - * @brief HWS Resume engine request / response structure. - * After a HWS engine reset, all scheduling is stopped on VPU until a engine resume. +/** + * HWS Resume engine request / response structure. + * After a HWS engine reset, all scheduling is stopped on VPU until an engine resume. * Host shall send this command to resume scheduling of any valid queue. - * @see VPU_JSM_MSG_HWS_RESUME_ENGINE + * @see VPU_JSM_MSG_HWS_ENGINE_RESUME * @see VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE */ struct vpu_ipc_msg_payload_hws_resume_engine { - /* Engine to be resumed */ + /** Engine to be resumed */ u32 engine_idx; - /* Reserved */ + /** Reserved */ u32 reserved_0; }; @@ -1326,7 +1512,7 @@ struct vpu_jsm_metric_streamer_done { /** * Metric group description placed in the metric buffer after successful completion * of the VPU_JSM_MSG_METRIC_STREAMER_INFO command. This is followed by one or more - * @vpu_jsm_metric_counter_descriptor records. + * @ref vpu_jsm_metric_counter_descriptor records. * @see VPU_JSM_MSG_METRIC_STREAMER_INFO */ struct vpu_jsm_metric_group_descriptor { @@ -1413,29 +1599,24 @@ struct vpu_jsm_metric_counter_descriptor { }; /** - * Payload for VPU_JSM_MSG_DYNDBG_CONTROL requests. + * Payload for @ref VPU_JSM_MSG_DYNDBG_CONTROL requests. * - * VPU_JSM_MSG_DYNDBG_CONTROL are used to control the VPU FW Dynamic Debug - * feature, which allows developers to selectively enable / disable MVLOG_DEBUG - * messages. This is equivalent to the Dynamic Debug functionality provided by - * Linux - * (https://www.kernel.org/doc/html/latest/admin-guide/dynamic-debug-howto.html) - * The host can control Dynamic Debug behavior by sending dyndbg commands, which - * have the same syntax as Linux - * dyndbg commands. + * VPU_JSM_MSG_DYNDBG_CONTROL requests are used to control the VPU FW dynamic debug + * feature, which allows developers to selectively enable/disable code to obtain + * additional FW information. This is equivalent to the dynamic debug functionality + * provided by Linux. The host can control dynamic debug behavior by sending dyndbg + * commands, using the same syntax as for Linux dynamic debug commands. * - * NOTE: in order for MVLOG_DEBUG messages to be actually printed, the host - * still has to set the logging level to MVLOG_DEBUG, using the - * VPU_JSM_MSG_TRACE_SET_CONFIG command. + * @see https://www.kernel.org/doc/html/latest/admin-guide/dynamic-debug-howto.html. * - * The host can see the current dynamic debug configuration by executing a - * special 'show' command. The dyndbg configuration will be printed to the - * configured logging destination using MVLOG_INFO logging level. + * NOTE: + * As the dynamic debug feature uses MVLOG messages to provide information, the host + * must first set the logging level to MVLOG_DEBUG, using the @ref VPU_JSM_MSG_TRACE_SET_CONFIG + * command. */ struct vpu_ipc_msg_payload_dyndbg_control { /** - * Dyndbg command (same format as Linux dyndbg); must be a NULL-terminated - * string. + * Dyndbg command to be executed. */ char dyndbg_cmd[VPU_DYNDBG_CMD_MAX_LEN]; }; @@ -1456,7 +1637,7 @@ struct vpu_ipc_msg_payload_pwr_d0i3_enter { }; /** - * Payload for VPU_JSM_MSG_DCT_ENABLE message. + * Payload for @ref VPU_JSM_MSG_DCT_ENABLE message. * * Default values for DCT active/inactive times are 5.3ms and 30ms respectively, * corresponding to a 85% duty cycle. This payload allows the host to tune these @@ -1513,28 +1694,28 @@ union vpu_ipc_msg_payload { struct vpu_ipc_msg_payload_pwr_dct_control pwr_dct_control; }; -/* - * Host <-> LRT IPC message base structure. +/** + * Host <-> NPU IPC message base structure. * * NOTE: All instances of this object must be aligned on a 64B boundary * to allow proper handling of VPU cache operations. */ struct vpu_jsm_msg { - /* Reserved */ + /** Reserved */ u64 reserved_0; - /* Message type, see vpu_ipc_msg_type enum. */ + /** Message type, see @ref vpu_ipc_msg_type. */ u32 type; - /* Buffer status, see vpu_ipc_msg_status enum. */ + /** Buffer status, see @ref vpu_ipc_msg_status. */ u32 status; - /* + /** * Request ID, provided by the host in a request message and passed * back by VPU in the response message. */ u32 request_id; - /* Request return code set by the VPU, see VPU_JSM_STATUS_* defines. */ + /** Request return code set by the VPU, see VPU_JSM_STATUS_* defines. */ u32 result; u64 reserved_1; - /* Message payload depending on message type, see vpu_ipc_msg_payload union. */ + /** Message payload depending on message type, see vpu_ipc_msg_payload union. */ union vpu_ipc_msg_payload payload; }; diff --git a/drivers/accel/qaic/Kconfig b/drivers/accel/qaic/Kconfig index 5e405a19c1573..116e42d152ca8 100644 --- a/drivers/accel/qaic/Kconfig +++ b/drivers/accel/qaic/Kconfig @@ -9,6 +9,7 @@ config DRM_ACCEL_QAIC depends on PCI && HAS_IOMEM depends on MHI_BUS select CRC32 + select WANT_DEV_COREDUMP help Enables driver for Qualcomm's Cloud AI accelerator PCIe cards that are designed to accelerate Deep Learning inference workloads. diff --git a/drivers/accel/qaic/Makefile b/drivers/accel/qaic/Makefile index 1106b876f737e..71f727b74da3b 100644 --- a/drivers/accel/qaic/Makefile +++ b/drivers/accel/qaic/Makefile @@ -11,6 +11,8 @@ qaic-y := \ qaic_data.o \ qaic_drv.o \ qaic_ras.o \ + qaic_ssr.o \ + qaic_sysfs.o \ qaic_timesync.o \ sahara.o diff --git a/drivers/accel/qaic/qaic.h b/drivers/accel/qaic/qaic.h index 820d133236dd1..fa7a8155658c4 100644 --- a/drivers/accel/qaic/qaic.h +++ b/drivers/accel/qaic/qaic.h @@ -21,6 +21,7 @@ #define QAIC_DBC_BASE SZ_128K #define QAIC_DBC_SIZE SZ_4K +#define QAIC_SSR_DBC_SENTINEL U32_MAX /* No ongoing SSR sentinel */ #define QAIC_NO_PARTITION -1 @@ -47,6 +48,22 @@ enum __packed dev_states { QAIC_ONLINE, }; +enum dbc_states { + /* DBC is free and can be activated */ + DBC_STATE_IDLE, + /* DBC is activated and a workload is running on device */ + DBC_STATE_ASSIGNED, + /* Sub-system associated with this workload has crashed and it will shutdown soon */ + DBC_STATE_BEFORE_SHUTDOWN, + /* Sub-system associated with this workload has crashed and it has shutdown */ + DBC_STATE_AFTER_SHUTDOWN, + /* Sub-system associated with this workload is shutdown and it will be powered up soon */ + DBC_STATE_BEFORE_POWER_UP, + /* Sub-system associated with this workload is now powered up */ + DBC_STATE_AFTER_POWER_UP, + DBC_STATE_MAX, +}; + extern bool datapath_polling; struct qaic_user { @@ -114,6 +131,8 @@ struct dma_bridge_chan { unsigned int irq; /* Polling work item to simulate interrupts */ struct work_struct poll_work; + /* Represents various states of this DBC from enum dbc_states */ + unsigned int state; }; struct qaic_device { @@ -161,6 +180,8 @@ struct qaic_device { struct mhi_device *qts_ch; /* Work queue for tasks related to MHI "QAIC_TIMESYNC" channel */ struct workqueue_struct *qts_wq; + /* MHI "QAIC_TIMESYNC_PERIODIC" channel device */ + struct mhi_device *mqts_ch; /* Head of list of page allocated by MHI bootlog device */ struct list_head bootlog; /* MHI bootlog channel device */ @@ -177,6 +198,14 @@ struct qaic_device { unsigned int ue_count; /* Un-correctable non-fatal error count */ unsigned int ue_nf_count; + /* MHI SSR channel device */ + struct mhi_device *ssr_ch; + /* Work queue for tasks related to MHI SSR device */ + struct workqueue_struct *ssr_wq; + /* Buffer to collect SSR crashdump via SSR MHI channel */ + void *ssr_mhi_buf; + /* DBC which is under SSR. Sentinel U32_MAX would mean that no SSR in progress */ + u32 ssr_dbc; }; struct qaic_drm_device { @@ -195,6 +224,8 @@ struct qaic_drm_device { struct list_head users; /* Synchronizes access to users list */ struct mutex users_mutex; + /* Pointer to array of DBC sysfs attributes */ + void *sysfs_attrs; }; struct qaic_bo { @@ -317,6 +348,13 @@ int qaic_partial_execute_bo_ioctl(struct drm_device *dev, void *data, struct drm int qaic_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int qaic_perf_stats_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int qaic_detach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -void irq_polling_work(struct work_struct *work); +void qaic_irq_polling_work(struct work_struct *work); +void qaic_dbc_enter_ssr(struct qaic_device *qdev, u32 dbc_id); +void qaic_dbc_exit_ssr(struct qaic_device *qdev); + +/* qaic_sysfs.c */ +int qaic_sysfs_init(struct qaic_drm_device *qddev); +void qaic_sysfs_remove(struct qaic_drm_device *qddev); +void set_dbc_state(struct qaic_device *qdev, u32 dbc_id, unsigned int state); #endif /* _QAIC_H_ */ diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c index b86a8e48e731b..428d8f65bff36 100644 --- a/drivers/accel/qaic/qaic_control.c +++ b/drivers/accel/qaic/qaic_control.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -30,7 +31,7 @@ #define MANAGE_MAGIC_NUMBER ((__force __le32)0x43494151) /* "QAIC" in little endian */ #define QAIC_DBC_Q_GAP SZ_256 #define QAIC_DBC_Q_BUF_ALIGN SZ_4K -#define QAIC_MANAGE_EXT_MSG_LENGTH SZ_64K /* Max DMA message length */ +#define QAIC_MANAGE_WIRE_MSG_LENGTH SZ_64K /* Max DMA message length */ #define QAIC_WRAPPER_MAX_SIZE SZ_4K #define QAIC_MHI_RETRY_WAIT_MS 100 #define QAIC_MHI_RETRY_MAX 20 @@ -309,6 +310,7 @@ static void save_dbc_buf(struct qaic_device *qdev, struct ioctl_resources *resou enable_dbc(qdev, dbc_id, usr); qdev->dbc[dbc_id].in_use = true; resources->buf = NULL; + set_dbc_state(qdev, dbc_id, DBC_STATE_ASSIGNED); } } @@ -367,7 +369,7 @@ static int encode_passthrough(struct qaic_device *qdev, void *trans, struct wrap if (in_trans->hdr.len % 8 != 0) return -EINVAL; - if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_EXT_MSG_LENGTH) + if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_WIRE_MSG_LENGTH) return -ENOSPC; trans_wrapper = add_wrapper(wrappers, @@ -495,7 +497,7 @@ static int encode_addr_size_pairs(struct dma_xfer *xfer, struct wrapper_list *wr nents = sgt->nents; nents_dma = nents; - *size = QAIC_MANAGE_EXT_MSG_LENGTH - msg_hdr_len - sizeof(**out_trans); + *size = QAIC_MANAGE_WIRE_MSG_LENGTH - msg_hdr_len - sizeof(**out_trans); for_each_sgtable_dma_sg(sgt, sg, i) { *size -= sizeof(*asp); /* Save 1K for possible follow-up transactions. */ @@ -576,7 +578,7 @@ static int encode_dma(struct qaic_device *qdev, void *trans, struct wrapper_list /* There should be enough space to hold at least one ASP entry. */ if (size_add(msg_hdr_len, sizeof(*out_trans) + sizeof(struct wire_addr_size_pair)) > - QAIC_MANAGE_EXT_MSG_LENGTH) + QAIC_MANAGE_WIRE_MSG_LENGTH) return -ENOMEM; xfer = kmalloc(sizeof(*xfer), GFP_KERNEL); @@ -645,7 +647,7 @@ static int encode_activate(struct qaic_device *qdev, void *trans, struct wrapper msg = &wrapper->msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (size_add(msg_hdr_len, sizeof(*out_trans)) > QAIC_MANAGE_MAX_MSG_LENGTH) + if (size_add(msg_hdr_len, sizeof(*out_trans)) > QAIC_MANAGE_WIRE_MSG_LENGTH) return -ENOSPC; if (!in_trans->queue_size) @@ -655,8 +657,9 @@ static int encode_activate(struct qaic_device *qdev, void *trans, struct wrapper return -EINVAL; nelem = in_trans->queue_size; - size = (get_dbc_req_elem_size() + get_dbc_rsp_elem_size()) * nelem; - if (size / nelem != get_dbc_req_elem_size() + get_dbc_rsp_elem_size()) + if (check_mul_overflow((u32)(get_dbc_req_elem_size() + get_dbc_rsp_elem_size()), + nelem, + &size)) return -EINVAL; if (size + QAIC_DBC_Q_GAP + QAIC_DBC_Q_BUF_ALIGN < size) @@ -729,7 +732,7 @@ static int encode_status(struct qaic_device *qdev, void *trans, struct wrapper_l msg = &wrapper->msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_MAX_MSG_LENGTH) + if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_WIRE_MSG_LENGTH) return -ENOSPC; trans_wrapper = add_wrapper(wrappers, sizeof(*trans_wrapper)); @@ -810,7 +813,7 @@ static int encode_message(struct qaic_device *qdev, struct manage_msg *user_msg, } if (ret) - break; + goto out; } if (user_len != user_msg->len) @@ -921,6 +924,7 @@ static int decode_deactivate(struct qaic_device *qdev, void *trans, u32 *msg_len } release_dbc(qdev, dbc_id); + set_dbc_state(qdev, dbc_id, DBC_STATE_IDLE); *msg_len += sizeof(*in_trans); return 0; @@ -1052,7 +1056,7 @@ static void *msg_xfer(struct qaic_device *qdev, struct wrapper_list *wrappers, u init_completion(&elem.xfer_done); if (likely(!qdev->cntl_lost_buf)) { /* - * The max size of request to device is QAIC_MANAGE_EXT_MSG_LENGTH. + * The max size of request to device is QAIC_MANAGE_WIRE_MSG_LENGTH. * The max size of response from device is QAIC_MANAGE_MAX_MSG_LENGTH. */ out_buf = kmalloc(QAIC_MANAGE_MAX_MSG_LENGTH, GFP_KERNEL); @@ -1079,7 +1083,6 @@ static void *msg_xfer(struct qaic_device *qdev, struct wrapper_list *wrappers, u list_for_each_entry(w, &wrappers->list, list) { kref_get(&w->ref_count); - retry_count = 0; ret = mhi_queue_buf(qdev->cntl_ch, DMA_TO_DEVICE, &w->msg, w->len, list_is_last(&w->list, &wrappers->list) ? MHI_EOT : MHI_CHAIN); if (ret) { diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c index c4f117edb266e..60cb4d65d48ee 100644 --- a/drivers/accel/qaic/qaic_data.c +++ b/drivers/accel/qaic/qaic_data.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -165,7 +166,7 @@ static void free_slice(struct kref *kref) drm_gem_object_put(&slice->bo->base); sg_free_table(slice->sgt); kfree(slice->sgt); - kfree(slice->reqs); + kvfree(slice->reqs); kfree(slice); } @@ -404,7 +405,7 @@ static int qaic_map_one_slice(struct qaic_device *qdev, struct qaic_bo *bo, goto free_sgt; } - slice->reqs = kcalloc(sgt->nents, sizeof(*slice->reqs), GFP_KERNEL); + slice->reqs = kvcalloc(sgt->nents, sizeof(*slice->reqs), GFP_KERNEL); if (!slice->reqs) { ret = -ENOMEM; goto free_slice; @@ -430,7 +431,7 @@ static int qaic_map_one_slice(struct qaic_device *qdev, struct qaic_bo *bo, return 0; free_req: - kfree(slice->reqs); + kvfree(slice->reqs); free_slice: kfree(slice); free_sgt: @@ -643,8 +644,36 @@ static void qaic_free_object(struct drm_gem_object *obj) kfree(bo); } +static struct sg_table *qaic_get_sg_table(struct drm_gem_object *obj) +{ + struct qaic_bo *bo = to_qaic_bo(obj); + struct scatterlist *sg, *sg_in; + struct sg_table *sgt, *sgt_in; + int i; + + sgt_in = bo->sgt; + + sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) + return ERR_PTR(-ENOMEM); + + if (sg_alloc_table(sgt, sgt_in->orig_nents, GFP_KERNEL)) { + kfree(sgt); + return ERR_PTR(-ENOMEM); + } + + sg = sgt->sgl; + for_each_sgtable_sg(sgt_in, sg_in, i) { + memcpy(sg, sg_in, sizeof(*sg)); + sg = sg_next(sg); + } + + return sgt; +} + static const struct drm_gem_object_funcs qaic_gem_funcs = { .free = qaic_free_object, + .get_sg_table = qaic_get_sg_table, .print_info = qaic_gem_print_info, .mmap = qaic_gem_object_mmap, .vm_ops = &drm_vm_ops, @@ -953,8 +982,9 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi if (args->hdr.count == 0) return -EINVAL; - arg_size = args->hdr.count * sizeof(*slice_ent); - if (arg_size / args->hdr.count != sizeof(*slice_ent)) + if (check_mul_overflow((unsigned long)args->hdr.count, + (unsigned long)sizeof(*slice_ent), + &arg_size)) return -EINVAL; if (!(args->hdr.dir == DMA_TO_DEVICE || args->hdr.dir == DMA_FROM_DEVICE)) @@ -984,18 +1014,12 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi user_data = u64_to_user_ptr(args->data); - slice_ent = kzalloc(arg_size, GFP_KERNEL); - if (!slice_ent) { - ret = -EINVAL; + slice_ent = memdup_user(user_data, arg_size); + if (IS_ERR(slice_ent)) { + ret = PTR_ERR(slice_ent); goto unlock_dev_srcu; } - ret = copy_from_user(slice_ent, user_data, arg_size); - if (ret) { - ret = -EFAULT; - goto free_slice_ent; - } - obj = drm_gem_object_lookup(file_priv, args->hdr.handle); if (!obj) { ret = -ENOENT; @@ -1023,6 +1047,11 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi goto unlock_ch_srcu; } + if (dbc->id == qdev->ssr_dbc) { + ret = -EPIPE; + goto unlock_ch_srcu; + } + ret = qaic_prepare_bo(qdev, bo, &args->hdr); if (ret) goto unlock_ch_srcu; @@ -1300,8 +1329,6 @@ static int __qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct dr int usr_rcu_id, qdev_rcu_id; struct qaic_device *qdev; struct qaic_user *usr; - u8 __user *user_data; - unsigned long n; u64 received_ts; u32 queue_level; u64 submit_ts; @@ -1314,20 +1341,12 @@ static int __qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct dr received_ts = ktime_get_ns(); size = is_partial ? sizeof(struct qaic_partial_execute_entry) : sizeof(*exec); - n = (unsigned long)size * args->hdr.count; - if (args->hdr.count == 0 || n / args->hdr.count != size) + if (args->hdr.count == 0) return -EINVAL; - user_data = u64_to_user_ptr(args->data); - - exec = kcalloc(args->hdr.count, size, GFP_KERNEL); - if (!exec) - return -ENOMEM; - - if (copy_from_user(exec, user_data, n)) { - ret = -EFAULT; - goto free_exec; - } + exec = memdup_array_user(u64_to_user_ptr(args->data), args->hdr.count, size); + if (IS_ERR(exec)) + return PTR_ERR(exec); usr = file_priv->driver_priv; usr_rcu_id = srcu_read_lock(&usr->qddev_lock); @@ -1356,6 +1375,11 @@ static int __qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct dr goto release_ch_rcu; } + if (dbc->id == qdev->ssr_dbc) { + ret = -EPIPE; + goto release_ch_rcu; + } + ret = mutex_lock_interruptible(&dbc->req_lock); if (ret) goto release_ch_rcu; @@ -1396,7 +1420,6 @@ static int __qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct dr srcu_read_unlock(&qdev->dev_lock, qdev_rcu_id); unlock_usr_srcu: srcu_read_unlock(&usr->qddev_lock, usr_rcu_id); -free_exec: kfree(exec); return ret; } @@ -1491,7 +1514,7 @@ irqreturn_t dbc_irq_handler(int irq, void *data) return IRQ_WAKE_THREAD; } -void irq_polling_work(struct work_struct *work) +void qaic_irq_polling_work(struct work_struct *work) { struct dma_bridge_chan *dbc = container_of(work, struct dma_bridge_chan, poll_work); unsigned long flags; @@ -1709,6 +1732,11 @@ int qaic_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file goto unlock_ch_srcu; } + if (dbc->id == qdev->ssr_dbc) { + ret = -EPIPE; + goto unlock_ch_srcu; + } + obj = drm_gem_object_lookup(file_priv, args->handle); if (!obj) { ret = -ENOENT; @@ -1729,6 +1757,9 @@ int qaic_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file if (!dbc->usr) ret = -EPERM; + if (dbc->id == qdev->ssr_dbc) + ret = -EPIPE; + put_obj: drm_gem_object_put(obj); unlock_ch_srcu: @@ -1749,7 +1780,8 @@ int qaic_perf_stats_bo_ioctl(struct drm_device *dev, void *data, struct drm_file struct qaic_device *qdev; struct qaic_user *usr; struct qaic_bo *bo; - int ret, i; + int ret = 0; + int i; usr = file_priv->driver_priv; usr_rcu_id = srcu_read_lock(&usr->qddev_lock); @@ -1770,18 +1802,12 @@ int qaic_perf_stats_bo_ioctl(struct drm_device *dev, void *data, struct drm_file goto unlock_dev_srcu; } - ent = kcalloc(args->hdr.count, sizeof(*ent), GFP_KERNEL); - if (!ent) { - ret = -EINVAL; + ent = memdup_array_user(u64_to_user_ptr(args->data), args->hdr.count, sizeof(*ent)); + if (IS_ERR(ent)) { + ret = PTR_ERR(ent); goto unlock_dev_srcu; } - ret = copy_from_user(ent, u64_to_user_ptr(args->data), args->hdr.count * sizeof(*ent)); - if (ret) { - ret = -EFAULT; - goto free_ent; - } - for (i = 0; i < args->hdr.count; i++) { obj = drm_gem_object_lookup(file_priv, ent[i].handle); if (!obj) { @@ -1789,6 +1815,16 @@ int qaic_perf_stats_bo_ioctl(struct drm_device *dev, void *data, struct drm_file goto free_ent; } bo = to_qaic_bo(obj); + if (!bo->sliced) { + drm_gem_object_put(obj); + ret = -EINVAL; + goto free_ent; + } + if (bo->dbc->id != args->hdr.dbc_id) { + drm_gem_object_put(obj); + ret = -EINVAL; + goto free_ent; + } /* * perf stats ioctl is called before wait ioctl is complete then * the latency information is invalid. @@ -1927,6 +1963,17 @@ static void empty_xfer_list(struct qaic_device *qdev, struct dma_bridge_chan *db spin_unlock_irqrestore(&dbc->xfer_lock, flags); } +static void sync_empty_xfer_list(struct qaic_device *qdev, struct dma_bridge_chan *dbc) +{ + empty_xfer_list(qdev, dbc); + synchronize_srcu(&dbc->ch_lock); + /* + * Threads holding channel lock, may add more elements in the xfer_list. + * Flush out these elements from xfer_list. + */ + empty_xfer_list(qdev, dbc); +} + int disable_dbc(struct qaic_device *qdev, u32 dbc_id, struct qaic_user *usr) { if (!qdev->dbc[dbc_id].usr || qdev->dbc[dbc_id].usr->handle != usr->handle) @@ -1941,7 +1988,7 @@ int disable_dbc(struct qaic_device *qdev, u32 dbc_id, struct qaic_user *usr) * enable_dbc - Enable the DBC. DBCs are disabled by removing the context of * user. Add user context back to DBC to enable it. This function trusts the * DBC ID passed and expects the DBC to be disabled. - * @qdev: Qranium device handle + * @qdev: qaic device handle * @dbc_id: ID of the DBC * @usr: User context */ @@ -1955,13 +2002,7 @@ void wakeup_dbc(struct qaic_device *qdev, u32 dbc_id) struct dma_bridge_chan *dbc = &qdev->dbc[dbc_id]; dbc->usr = NULL; - empty_xfer_list(qdev, dbc); - synchronize_srcu(&dbc->ch_lock); - /* - * Threads holding channel lock, may add more elements in the xfer_list. - * Flush out these elements from xfer_list. - */ - empty_xfer_list(qdev, dbc); + sync_empty_xfer_list(qdev, dbc); } void release_dbc(struct qaic_device *qdev, u32 dbc_id) @@ -2002,3 +2043,30 @@ void qaic_data_get_fifo_info(struct dma_bridge_chan *dbc, u32 *head, u32 *tail) *head = readl(dbc->dbc_base + REQHP_OFF); *tail = readl(dbc->dbc_base + REQTP_OFF); } + +/* + * qaic_dbc_enter_ssr - Prepare to enter in sub system reset(SSR) for given DBC ID. + * @qdev: qaic device handle + * @dbc_id: ID of the DBC which will enter SSR + * + * The device will automatically deactivate the workload as not + * all errors can be silently recovered. The user will be + * notified and will need to decide the required recovery + * action to take. + */ +void qaic_dbc_enter_ssr(struct qaic_device *qdev, u32 dbc_id) +{ + qdev->ssr_dbc = dbc_id; + release_dbc(qdev, dbc_id); +} + +/* + * qaic_dbc_exit_ssr - Prepare to exit from sub system reset(SSR) for given DBC ID. + * @qdev: qaic device handle + * + * The DBC returns to an operational state and begins accepting work after exiting SSR. + */ +void qaic_dbc_exit_ssr(struct qaic_device *qdev) +{ + qdev->ssr_dbc = QAIC_SSR_DBC_SENTINEL; +} diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c index e162f4b8a262a..4c70bd949d539 100644 --- a/drivers/accel/qaic/qaic_drv.c +++ b/drivers/accel/qaic/qaic_drv.c @@ -30,6 +30,7 @@ #include "qaic.h" #include "qaic_debugfs.h" #include "qaic_ras.h" +#include "qaic_ssr.h" #include "qaic_timesync.h" #include "sahara.h" @@ -270,6 +271,13 @@ static int qaic_create_drm_device(struct qaic_device *qdev, s32 partition_id) return ret; } + ret = qaic_sysfs_init(qddev); + if (ret) { + drm_dev_unregister(drm); + pci_dbg(qdev->pdev, "qaic_sysfs_init failed %d\n", ret); + return ret; + } + qaic_debugfs_init(qddev); return ret; @@ -281,6 +289,7 @@ static void qaic_destroy_drm_device(struct qaic_device *qdev, s32 partition_id) struct drm_device *drm = to_drm(qddev); struct qaic_user *usr; + qaic_sysfs_remove(qddev); drm_dev_unregister(drm); qddev->partition_id = 0; /* @@ -382,6 +391,7 @@ void qaic_dev_reset_clean_local_state(struct qaic_device *qdev) qaic_notify_reset(qdev); /* start tearing things down */ + qaic_clean_up_ssr(qdev); for (i = 0; i < qdev->num_dbc; ++i) release_dbc(qdev, i); } @@ -431,11 +441,18 @@ static struct qaic_device *create_qdev(struct pci_dev *pdev, qdev->qts_wq = qaicm_wq_init(drm, "qaic_ts"); if (IS_ERR(qdev->qts_wq)) return NULL; + qdev->ssr_wq = qaicm_wq_init(drm, "qaic_ssr"); + if (IS_ERR(qdev->ssr_wq)) + return NULL; ret = qaicm_srcu_init(drm, &qdev->dev_lock); if (ret) return NULL; + ret = qaic_ssr_init(qdev, drm); + if (ret) + pci_info(pdev, "QAIC SSR crashdump collection not supported.\n"); + qdev->qddev = qddev; qdev->pdev = pdev; qddev->qdev = qdev; @@ -545,7 +562,7 @@ static int init_msi(struct qaic_device *qdev, struct pci_dev *pdev) qdev->dbc[i].irq = pci_irq_vector(pdev, qdev->single_msi ? 0 : i + 1); if (!qdev->single_msi) disable_irq_nosync(qdev->dbc[i].irq); - INIT_WORK(&qdev->dbc[i].poll_work, irq_polling_work); + INIT_WORK(&qdev->dbc[i].poll_work, qaic_irq_polling_work); } } @@ -660,6 +677,92 @@ static const struct pci_error_handlers qaic_pci_err_handler = { .reset_done = qaic_pci_reset_done, }; +static bool qaic_is_under_reset(struct qaic_device *qdev) +{ + int rcu_id; + bool ret; + + rcu_id = srcu_read_lock(&qdev->dev_lock); + ret = qdev->dev_state != QAIC_ONLINE; + srcu_read_unlock(&qdev->dev_lock, rcu_id); + return ret; +} + +static bool qaic_data_path_busy(struct qaic_device *qdev) +{ + bool ret = false; + int dev_rcu_id; + int i; + + dev_rcu_id = srcu_read_lock(&qdev->dev_lock); + if (qdev->dev_state != QAIC_ONLINE) { + srcu_read_unlock(&qdev->dev_lock, dev_rcu_id); + return false; + } + for (i = 0; i < qdev->num_dbc; i++) { + struct dma_bridge_chan *dbc = &qdev->dbc[i]; + unsigned long flags; + int ch_rcu_id; + + ch_rcu_id = srcu_read_lock(&dbc->ch_lock); + if (!dbc->usr || !dbc->in_use) { + srcu_read_unlock(&dbc->ch_lock, ch_rcu_id); + continue; + } + spin_lock_irqsave(&dbc->xfer_lock, flags); + ret = !list_empty(&dbc->xfer_list); + spin_unlock_irqrestore(&dbc->xfer_lock, flags); + srcu_read_unlock(&dbc->ch_lock, ch_rcu_id); + if (ret) + break; + } + srcu_read_unlock(&qdev->dev_lock, dev_rcu_id); + return ret; +} + +static int qaic_pm_suspend(struct device *dev) +{ + struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(dev)); + + dev_dbg(dev, "Suspending..\n"); + if (qaic_data_path_busy(qdev)) { + dev_dbg(dev, "Device's datapath is busy. Aborting suspend..\n"); + return -EBUSY; + } + if (qaic_is_under_reset(qdev)) { + dev_dbg(dev, "Device is under reset. Aborting suspend..\n"); + return -EBUSY; + } + qaic_mqts_ch_stop_timer(qdev->mqts_ch); + qaic_pci_reset_prepare(qdev->pdev); + pci_save_state(qdev->pdev); + pci_disable_device(qdev->pdev); + pci_set_power_state(qdev->pdev, PCI_D3hot); + return 0; +} + +static int qaic_pm_resume(struct device *dev) +{ + struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(dev)); + int ret; + + dev_dbg(dev, "Resuming..\n"); + pci_set_power_state(qdev->pdev, PCI_D0); + pci_restore_state(qdev->pdev); + ret = pci_enable_device(qdev->pdev); + if (ret) { + dev_err(dev, "pci_enable_device failed on resume %d\n", ret); + return ret; + } + pci_set_master(qdev->pdev); + qaic_pci_reset_done(qdev->pdev); + return 0; +} + +static const struct dev_pm_ops qaic_pm_ops = { + SYSTEM_SLEEP_PM_OPS(qaic_pm_suspend, qaic_pm_resume) +}; + static struct pci_driver qaic_pci_driver = { .name = QAIC_NAME, .id_table = qaic_ids, @@ -667,6 +770,9 @@ static struct pci_driver qaic_pci_driver = { .remove = qaic_pci_remove, .shutdown = qaic_pci_shutdown, .err_handler = &qaic_pci_err_handler, + .driver = { + .pm = pm_sleep_ptr(&qaic_pm_ops), + }, }; static int __init qaic_init(void) @@ -702,9 +808,16 @@ static int __init qaic_init(void) ret = qaic_ras_register(); if (ret) pr_debug("qaic: qaic_ras_register failed %d\n", ret); + ret = qaic_ssr_register(); + if (ret) { + pr_debug("qaic: qaic_ssr_register failed %d\n", ret); + goto free_bootlog; + } return 0; +free_bootlog: + qaic_bootlog_unregister(); free_mhi: mhi_driver_unregister(&qaic_mhi_driver); free_pci: @@ -730,6 +843,7 @@ static void __exit qaic_exit(void) * reinitializing the link_up state after the cleanup is done. */ link_up = true; + qaic_ssr_unregister(); qaic_ras_unregister(); qaic_bootlog_unregister(); qaic_timesync_deinit(); diff --git a/drivers/accel/qaic/qaic_ras.c b/drivers/accel/qaic/qaic_ras.c index 914ffc4a9970d..f1d52a710136a 100644 --- a/drivers/accel/qaic/qaic_ras.c +++ b/drivers/accel/qaic/qaic_ras.c @@ -514,21 +514,21 @@ static ssize_t ce_count_show(struct device *dev, struct device_attribute *attr, { struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(dev)); - return snprintf(buf, PAGE_SIZE, "%d\n", qdev->ce_count); + return sysfs_emit(buf, "%d\n", qdev->ce_count); } static ssize_t ue_count_show(struct device *dev, struct device_attribute *attr, char *buf) { struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(dev)); - return snprintf(buf, PAGE_SIZE, "%d\n", qdev->ue_count); + return sysfs_emit(buf, "%d\n", qdev->ue_count); } static ssize_t ue_nonfatal_count_show(struct device *dev, struct device_attribute *attr, char *buf) { struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(dev)); - return snprintf(buf, PAGE_SIZE, "%d\n", qdev->ue_nf_count); + return sysfs_emit(buf, "%d\n", qdev->ue_nf_count); } static DEVICE_ATTR_RO(ce_count); diff --git a/drivers/accel/qaic/qaic_ssr.c b/drivers/accel/qaic/qaic_ssr.c new file mode 100644 index 0000000000000..9b662d6903712 --- /dev/null +++ b/drivers/accel/qaic/qaic_ssr.c @@ -0,0 +1,815 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ +/* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qaic.h" +#include "qaic_ssr.h" + +#define SSR_RESP_MSG_SZ 32 +#define SSR_MHI_BUF_SIZE SZ_64K +#define SSR_MEM_READ_DATA_SIZE ((u64)SSR_MHI_BUF_SIZE - sizeof(struct ssr_crashdump)) +#define SSR_MEM_READ_CHUNK_SIZE ((u64)SSR_MEM_READ_DATA_SIZE - sizeof(struct ssr_memory_read_rsp)) + +#define DEBUG_TRANSFER_INFO BIT(0) +#define DEBUG_TRANSFER_INFO_RSP BIT(1) +#define MEMORY_READ BIT(2) +#define MEMORY_READ_RSP BIT(3) +#define DEBUG_TRANSFER_DONE BIT(4) +#define DEBUG_TRANSFER_DONE_RSP BIT(5) +#define SSR_EVENT BIT(8) +#define SSR_EVENT_RSP BIT(9) + +#define SSR_EVENT_NACK BIT(0) +#define BEFORE_SHUTDOWN BIT(1) +#define AFTER_SHUTDOWN BIT(2) +#define BEFORE_POWER_UP BIT(3) +#define AFTER_POWER_UP BIT(4) + +struct debug_info_table { + /* Save preferences. Default is mandatory */ + u64 save_perf; + /* Base address of the debug region */ + u64 mem_base; + /* Size of debug region in bytes */ + u64 len; + /* Description */ + char desc[20]; + /* Filename of debug region */ + char filename[20]; +}; + +struct _ssr_hdr { + __le32 cmd; + __le32 len; + __le32 dbc_id; +}; + +struct ssr_hdr { + u32 cmd; + u32 len; + u32 dbc_id; +}; + +struct ssr_debug_transfer_info { + struct ssr_hdr hdr; + u32 resv; + u64 tbl_addr; + u64 tbl_len; +} __packed; + +struct ssr_debug_transfer_info_rsp { + struct _ssr_hdr hdr; + __le32 ret; +} __packed; + +struct ssr_memory_read { + struct _ssr_hdr hdr; + __le32 resv; + __le64 addr; + __le64 len; +} __packed; + +struct ssr_memory_read_rsp { + struct _ssr_hdr hdr; + __le32 resv; + u8 data[]; +} __packed; + +struct ssr_debug_transfer_done { + struct _ssr_hdr hdr; + __le32 resv; +} __packed; + +struct ssr_debug_transfer_done_rsp { + struct _ssr_hdr hdr; + __le32 ret; +} __packed; + +struct ssr_event { + struct ssr_hdr hdr; + u32 event; +} __packed; + +struct ssr_event_rsp { + struct _ssr_hdr hdr; + __le32 event; +} __packed; + +struct ssr_resp { + /* Work struct to schedule work coming on QAIC_SSR channel */ + struct work_struct work; + /* Root struct of device, used to access device resources */ + struct qaic_device *qdev; + /* Buffer used by MHI for transfer requests */ + u8 data[] __aligned(8); +}; + +/* SSR crashdump book keeping structure */ +struct ssr_dump_info { + /* DBC associated with this SSR crashdump */ + struct dma_bridge_chan *dbc; + /* + * It will be used when we complete the crashdump download and switch + * to waiting on SSR events + */ + struct ssr_resp *resp; + /* MEMORY READ request MHI buffer.*/ + struct ssr_memory_read *read_buf_req; + /* TRUE: ->read_buf_req is queued for MHI transaction. FALSE: Otherwise */ + bool read_buf_req_queued; + /* Address of table in host */ + void *tbl_addr; + /* Total size of table */ + u64 tbl_len; + /* Offset of table(->tbl_addr) where the new chunk will be dumped */ + u64 tbl_off; + /* Address of table in device/target */ + u64 tbl_addr_dev; + /* Ptr to the entire dump */ + void *dump_addr; + /* Entire crashdump size */ + u64 dump_sz; + /* Offset of crashdump(->dump_addr) where the new chunk will be dumped */ + u64 dump_off; + /* Points to the table entry we are currently downloading */ + struct debug_info_table *tbl_ent; + /* Offset in the current table entry(->tbl_ent) for next chuck */ + u64 tbl_ent_off; +}; + +struct ssr_crashdump { + /* + * Points to a book keeping struct maintained by MHI SSR device while + * downloading a SSR crashdump. It is NULL when crashdump downloading + * not in progress. + */ + struct ssr_dump_info *dump_info; + /* Work struct to schedule work coming on QAIC_SSR channel */ + struct work_struct work; + /* Root struct of device, used to access device resources */ + struct qaic_device *qdev; + /* Buffer used by MHI for transfer requests */ + u8 data[]; +}; + +#define QAIC_SSR_DUMP_V1_MAGIC 0x1234567890abcdef +#define QAIC_SSR_DUMP_V1_VER 1 +struct dump_file_meta { + u64 magic; + u64 version; + u64 size; /* Total size of the entire dump */ + u64 tbl_len; /* Length of the table in byte */ +}; + +/* + * Layout of crashdump + * +------------------------------------------+ + * | Crashdump Meta structure | + * | type: struct dump_file_meta | + * +------------------------------------------+ + * | Crashdump Table | + * | type: array of struct debug_info_table | + * | | + * | | + * | | + * +------------------------------------------+ + * | Crashdump | + * | | + * | | + * | | + * | | + * | | + * +------------------------------------------+ + */ + +static void free_ssr_dump_info(struct ssr_crashdump *ssr_crash) +{ + struct ssr_dump_info *dump_info = ssr_crash->dump_info; + + ssr_crash->dump_info = NULL; + if (!dump_info) + return; + if (!dump_info->read_buf_req_queued) + kfree(dump_info->read_buf_req); + vfree(dump_info->tbl_addr); + vfree(dump_info->dump_addr); + kfree(dump_info); +} + +void qaic_clean_up_ssr(struct qaic_device *qdev) +{ + struct ssr_crashdump *ssr_crash = qdev->ssr_mhi_buf; + + if (!ssr_crash) + return; + + qaic_dbc_exit_ssr(qdev); + free_ssr_dump_info(ssr_crash); +} + +static int alloc_dump(struct ssr_dump_info *dump_info) +{ + struct debug_info_table *tbl_ent = dump_info->tbl_addr; + struct dump_file_meta *dump_meta; + u64 tbl_sz_lp = 0; + u64 dump_size = 0; + + while (tbl_sz_lp < dump_info->tbl_len) { + le64_to_cpus(&tbl_ent->save_perf); + le64_to_cpus(&tbl_ent->mem_base); + le64_to_cpus(&tbl_ent->len); + + if (tbl_ent->len == 0) + return -EINVAL; + + dump_size += tbl_ent->len; + tbl_ent++; + tbl_sz_lp += sizeof(*tbl_ent); + } + + dump_info->dump_sz = dump_size + dump_info->tbl_len + sizeof(*dump_meta); + dump_info->dump_addr = vzalloc(dump_info->dump_sz); + if (!dump_info->dump_addr) + return -ENOMEM; + + /* Copy crashdump meta and table */ + dump_meta = dump_info->dump_addr; + dump_meta->magic = QAIC_SSR_DUMP_V1_MAGIC; + dump_meta->version = QAIC_SSR_DUMP_V1_VER; + dump_meta->size = dump_info->dump_sz; + dump_meta->tbl_len = dump_info->tbl_len; + memcpy(dump_info->dump_addr + sizeof(*dump_meta), dump_info->tbl_addr, dump_info->tbl_len); + /* Offset by crashdump meta and table (copied above) */ + dump_info->dump_off = dump_info->tbl_len + sizeof(*dump_meta); + + return 0; +} + +static int send_xfer_done(struct qaic_device *qdev, void *resp, u32 dbc_id) +{ + struct ssr_debug_transfer_done *xfer_done; + int ret; + + xfer_done = kmalloc(sizeof(*xfer_done), GFP_KERNEL); + if (!xfer_done) { + ret = -ENOMEM; + goto out; + } + + ret = mhi_queue_buf(qdev->ssr_ch, DMA_FROM_DEVICE, resp, SSR_RESP_MSG_SZ, MHI_EOT); + if (ret) + goto free_xfer_done; + + xfer_done->hdr.cmd = cpu_to_le32(DEBUG_TRANSFER_DONE); + xfer_done->hdr.len = cpu_to_le32(sizeof(*xfer_done)); + xfer_done->hdr.dbc_id = cpu_to_le32(dbc_id); + + ret = mhi_queue_buf(qdev->ssr_ch, DMA_TO_DEVICE, xfer_done, sizeof(*xfer_done), MHI_EOT); + if (ret) + goto free_xfer_done; + + return 0; + +free_xfer_done: + kfree(xfer_done); +out: + return ret; +} + +static int mem_read_req(struct qaic_device *qdev, u64 dest_addr, u64 dest_len) +{ + struct ssr_crashdump *ssr_crash = qdev->ssr_mhi_buf; + struct ssr_memory_read *read_buf_req; + struct ssr_dump_info *dump_info; + int ret; + + dump_info = ssr_crash->dump_info; + ret = mhi_queue_buf(qdev->ssr_ch, DMA_FROM_DEVICE, ssr_crash->data, SSR_MEM_READ_DATA_SIZE, + MHI_EOT); + if (ret) + goto out; + + read_buf_req = dump_info->read_buf_req; + read_buf_req->hdr.cmd = cpu_to_le32(MEMORY_READ); + read_buf_req->hdr.len = cpu_to_le32(sizeof(*read_buf_req)); + read_buf_req->hdr.dbc_id = cpu_to_le32(qdev->ssr_dbc); + read_buf_req->addr = cpu_to_le64(dest_addr); + read_buf_req->len = cpu_to_le64(dest_len); + + ret = mhi_queue_buf(qdev->ssr_ch, DMA_TO_DEVICE, read_buf_req, sizeof(*read_buf_req), + MHI_EOT); + if (!ret) + dump_info->read_buf_req_queued = true; + +out: + return ret; +} + +static int ssr_copy_table(struct ssr_dump_info *dump_info, void *data, u64 len) +{ + if (len > dump_info->tbl_len - dump_info->tbl_off) + return -EINVAL; + + memcpy(dump_info->tbl_addr + dump_info->tbl_off, data, len); + dump_info->tbl_off += len; + + /* Entire table has been downloaded, alloc dump memory */ + if (dump_info->tbl_off == dump_info->tbl_len) { + dump_info->tbl_ent = dump_info->tbl_addr; + return alloc_dump(dump_info); + } + + return 0; +} + +static int ssr_copy_dump(struct ssr_dump_info *dump_info, void *data, u64 len) +{ + struct debug_info_table *tbl_ent; + + tbl_ent = dump_info->tbl_ent; + + if (len > tbl_ent->len - dump_info->tbl_ent_off) + return -EINVAL; + + memcpy(dump_info->dump_addr + dump_info->dump_off, data, len); + dump_info->dump_off += len; + dump_info->tbl_ent_off += len; + + /* + * Current segment (a entry in table) of the crashdump is complete, + * move to next one + */ + if (tbl_ent->len == dump_info->tbl_ent_off) { + dump_info->tbl_ent++; + dump_info->tbl_ent_off = 0; + } + + return 0; +} + +static void ssr_dump_worker(struct work_struct *work) +{ + struct ssr_crashdump *ssr_crash = container_of(work, struct ssr_crashdump, work); + struct qaic_device *qdev = ssr_crash->qdev; + struct ssr_memory_read_rsp *mem_rd_resp; + struct debug_info_table *tbl_ent; + struct ssr_dump_info *dump_info; + u64 dest_addr, dest_len; + struct _ssr_hdr *_hdr; + struct ssr_hdr hdr; + u64 data_len; + int ret; + + mem_rd_resp = (struct ssr_memory_read_rsp *)ssr_crash->data; + _hdr = &mem_rd_resp->hdr; + hdr.cmd = le32_to_cpu(_hdr->cmd); + hdr.len = le32_to_cpu(_hdr->len); + hdr.dbc_id = le32_to_cpu(_hdr->dbc_id); + + if (hdr.dbc_id != qdev->ssr_dbc) + goto reset_device; + + dump_info = ssr_crash->dump_info; + if (!dump_info) + goto reset_device; + + if (hdr.cmd != MEMORY_READ_RSP) + goto free_dump_info; + + if (hdr.len > SSR_MEM_READ_DATA_SIZE) + goto free_dump_info; + + data_len = hdr.len - sizeof(*mem_rd_resp); + + if (dump_info->tbl_off < dump_info->tbl_len) /* Chunk belongs to table */ + ret = ssr_copy_table(dump_info, mem_rd_resp->data, data_len); + else /* Chunk belongs to crashdump */ + ret = ssr_copy_dump(dump_info, mem_rd_resp->data, data_len); + + if (ret) + goto free_dump_info; + + if (dump_info->tbl_off < dump_info->tbl_len) { + /* Continue downloading table */ + dest_addr = dump_info->tbl_addr_dev + dump_info->tbl_off; + dest_len = min(SSR_MEM_READ_CHUNK_SIZE, dump_info->tbl_len - dump_info->tbl_off); + ret = mem_read_req(qdev, dest_addr, dest_len); + } else if (dump_info->dump_off < dump_info->dump_sz) { + /* Continue downloading crashdump */ + tbl_ent = dump_info->tbl_ent; + dest_addr = tbl_ent->mem_base + dump_info->tbl_ent_off; + dest_len = min(SSR_MEM_READ_CHUNK_SIZE, tbl_ent->len - dump_info->tbl_ent_off); + ret = mem_read_req(qdev, dest_addr, dest_len); + } else { + /* Crashdump download complete */ + ret = send_xfer_done(qdev, dump_info->resp->data, hdr.dbc_id); + } + + /* Most likely a MHI xfer has failed */ + if (ret) + goto free_dump_info; + + return; + +free_dump_info: + /* Free the allocated memory */ + free_ssr_dump_info(ssr_crash); +reset_device: + /* + * After subsystem crashes in device crashdump collection begins but + * something went wrong while collecting crashdump, now instead of + * handling this error we just reset the device as the best effort has + * been made + */ + mhi_soc_reset(qdev->mhi_cntrl); +} + +static struct ssr_dump_info *alloc_dump_info(struct qaic_device *qdev, + struct ssr_debug_transfer_info *debug_info) +{ + struct ssr_dump_info *dump_info; + int ret; + + le64_to_cpus(&debug_info->tbl_len); + le64_to_cpus(&debug_info->tbl_addr); + + if (debug_info->tbl_len == 0 || + debug_info->tbl_len % sizeof(struct debug_info_table) != 0) { + ret = -EINVAL; + goto out; + } + + /* Allocate SSR crashdump book keeping structure */ + dump_info = kzalloc(sizeof(*dump_info), GFP_KERNEL); + if (!dump_info) { + ret = -ENOMEM; + goto out; + } + + /* Buffer used to send MEMORY READ request to device via MHI */ + dump_info->read_buf_req = kzalloc(sizeof(*dump_info->read_buf_req), GFP_KERNEL); + if (!dump_info->read_buf_req) { + ret = -ENOMEM; + goto free_dump_info; + } + + /* Crashdump meta table buffer */ + dump_info->tbl_addr = vzalloc(debug_info->tbl_len); + if (!dump_info->tbl_addr) { + ret = -ENOMEM; + goto free_read_buf_req; + } + + dump_info->tbl_addr_dev = debug_info->tbl_addr; + dump_info->tbl_len = debug_info->tbl_len; + + return dump_info; + +free_read_buf_req: + kfree(dump_info->read_buf_req); +free_dump_info: + kfree(dump_info); +out: + return ERR_PTR(ret); +} + +static int dbg_xfer_info_rsp(struct qaic_device *qdev, struct dma_bridge_chan *dbc, + struct ssr_debug_transfer_info *debug_info) +{ + struct ssr_debug_transfer_info_rsp *debug_rsp; + struct ssr_crashdump *ssr_crash = NULL; + int ret = 0, ret2; + + debug_rsp = kmalloc(sizeof(*debug_rsp), GFP_KERNEL); + if (!debug_rsp) + return -ENOMEM; + + if (!qdev->ssr_mhi_buf) { + ret = -ENOMEM; + goto send_rsp; + } + + if (dbc->state != DBC_STATE_BEFORE_POWER_UP) { + ret = -EINVAL; + goto send_rsp; + } + + ssr_crash = qdev->ssr_mhi_buf; + ssr_crash->dump_info = alloc_dump_info(qdev, debug_info); + if (IS_ERR(ssr_crash->dump_info)) { + ret = PTR_ERR(ssr_crash->dump_info); + ssr_crash->dump_info = NULL; + } + +send_rsp: + debug_rsp->hdr.cmd = cpu_to_le32(DEBUG_TRANSFER_INFO_RSP); + debug_rsp->hdr.len = cpu_to_le32(sizeof(*debug_rsp)); + debug_rsp->hdr.dbc_id = cpu_to_le32(dbc->id); + /* + * 0 = Return an ACK confirming the host is ready to download crashdump + * 1 = Return an NACK confirming the host is not ready to download crashdump + */ + debug_rsp->ret = cpu_to_le32(ret ? 1 : 0); + + ret2 = mhi_queue_buf(qdev->ssr_ch, DMA_TO_DEVICE, debug_rsp, sizeof(*debug_rsp), MHI_EOT); + if (ret2) { + free_ssr_dump_info(ssr_crash); + kfree(debug_rsp); + return ret2; + } + + return ret; +} + +static void dbg_xfer_done_rsp(struct qaic_device *qdev, struct dma_bridge_chan *dbc, + struct ssr_debug_transfer_done_rsp *xfer_rsp) +{ + struct ssr_crashdump *ssr_crash = qdev->ssr_mhi_buf; + u32 status = le32_to_cpu(xfer_rsp->ret); + struct device *dev = &qdev->pdev->dev; + struct ssr_dump_info *dump_info; + + dump_info = ssr_crash->dump_info; + if (!dump_info) + return; + + if (status) { + free_ssr_dump_info(ssr_crash); + return; + } + + dev_coredumpv(dev, dump_info->dump_addr, dump_info->dump_sz, GFP_KERNEL); + /* dev_coredumpv will free dump_info->dump_addr */ + dump_info->dump_addr = NULL; + free_ssr_dump_info(ssr_crash); +} + +static void ssr_worker(struct work_struct *work) +{ + struct ssr_resp *resp = container_of(work, struct ssr_resp, work); + struct ssr_hdr *hdr = (struct ssr_hdr *)resp->data; + struct ssr_dump_info *dump_info = NULL; + struct qaic_device *qdev = resp->qdev; + struct ssr_crashdump *ssr_crash; + struct ssr_event_rsp *event_rsp; + struct dma_bridge_chan *dbc; + struct ssr_event *event; + u32 ssr_event_ack; + int ret; + + le32_to_cpus(&hdr->cmd); + le32_to_cpus(&hdr->len); + le32_to_cpus(&hdr->dbc_id); + + if (hdr->len > SSR_RESP_MSG_SZ) + goto out; + + if (hdr->dbc_id >= qdev->num_dbc) + goto out; + + dbc = &qdev->dbc[hdr->dbc_id]; + + switch (hdr->cmd) { + case DEBUG_TRANSFER_INFO: + ret = dbg_xfer_info_rsp(qdev, dbc, (struct ssr_debug_transfer_info *)resp->data); + if (ret) + break; + + ssr_crash = qdev->ssr_mhi_buf; + dump_info = ssr_crash->dump_info; + dump_info->dbc = dbc; + dump_info->resp = resp; + + /* Start by downloading debug table */ + ret = mem_read_req(qdev, dump_info->tbl_addr_dev, + min(dump_info->tbl_len, SSR_MEM_READ_CHUNK_SIZE)); + if (ret) { + free_ssr_dump_info(ssr_crash); + break; + } + + /* + * Till now everything went fine, which means that we will be + * collecting crashdump chunk by chunk. Do not queue a response + * buffer for SSR cmds till the crashdump is complete. + */ + return; + case SSR_EVENT: + event = (struct ssr_event *)hdr; + le32_to_cpus(&event->event); + ssr_event_ack = event->event; + ssr_crash = qdev->ssr_mhi_buf; + + switch (event->event) { + case BEFORE_SHUTDOWN: + set_dbc_state(qdev, hdr->dbc_id, DBC_STATE_BEFORE_SHUTDOWN); + qaic_dbc_enter_ssr(qdev, hdr->dbc_id); + break; + case AFTER_SHUTDOWN: + set_dbc_state(qdev, hdr->dbc_id, DBC_STATE_AFTER_SHUTDOWN); + break; + case BEFORE_POWER_UP: + set_dbc_state(qdev, hdr->dbc_id, DBC_STATE_BEFORE_POWER_UP); + break; + case AFTER_POWER_UP: + /* + * If dump info is a non NULL value it means that we + * have received this SSR event while downloading a + * crashdump for this DBC is still in progress. NACK + * the SSR event + */ + if (ssr_crash && ssr_crash->dump_info) { + free_ssr_dump_info(ssr_crash); + ssr_event_ack = SSR_EVENT_NACK; + break; + } + + set_dbc_state(qdev, hdr->dbc_id, DBC_STATE_AFTER_POWER_UP); + break; + default: + break; + } + + event_rsp = kmalloc(sizeof(*event_rsp), GFP_KERNEL); + if (!event_rsp) + break; + + event_rsp->hdr.cmd = cpu_to_le32(SSR_EVENT_RSP); + event_rsp->hdr.len = cpu_to_le32(sizeof(*event_rsp)); + event_rsp->hdr.dbc_id = cpu_to_le32(hdr->dbc_id); + event_rsp->event = cpu_to_le32(ssr_event_ack); + + ret = mhi_queue_buf(qdev->ssr_ch, DMA_TO_DEVICE, event_rsp, sizeof(*event_rsp), + MHI_EOT); + if (ret) + kfree(event_rsp); + + if (event->event == AFTER_POWER_UP && ssr_event_ack != SSR_EVENT_NACK) { + qaic_dbc_exit_ssr(qdev); + set_dbc_state(qdev, hdr->dbc_id, DBC_STATE_IDLE); + } + + break; + case DEBUG_TRANSFER_DONE_RSP: + dbg_xfer_done_rsp(qdev, dbc, (struct ssr_debug_transfer_done_rsp *)hdr); + break; + default: + break; + } + +out: + ret = mhi_queue_buf(qdev->ssr_ch, DMA_FROM_DEVICE, resp->data, SSR_RESP_MSG_SZ, MHI_EOT); + if (ret) + kfree(resp); +} + +static int qaic_ssr_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id) +{ + struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_dev->mhi_cntrl->cntrl_dev)); + struct ssr_resp *resp; + int ret; + + ret = mhi_prepare_for_transfer(mhi_dev); + if (ret) + return ret; + + resp = kzalloc(sizeof(*resp) + SSR_RESP_MSG_SZ, GFP_KERNEL); + if (!resp) { + mhi_unprepare_from_transfer(mhi_dev); + return -ENOMEM; + } + + resp->qdev = qdev; + INIT_WORK(&resp->work, ssr_worker); + + ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, resp->data, SSR_RESP_MSG_SZ, MHI_EOT); + if (ret) { + kfree(resp); + mhi_unprepare_from_transfer(mhi_dev); + return ret; + } + + dev_set_drvdata(&mhi_dev->dev, qdev); + qdev->ssr_ch = mhi_dev; + + return 0; +} + +static void qaic_ssr_mhi_remove(struct mhi_device *mhi_dev) +{ + struct qaic_device *qdev; + + qdev = dev_get_drvdata(&mhi_dev->dev); + mhi_unprepare_from_transfer(qdev->ssr_ch); + qdev->ssr_ch = NULL; +} + +static void qaic_ssr_mhi_ul_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result) +{ + struct qaic_device *qdev = dev_get_drvdata(&mhi_dev->dev); + struct ssr_crashdump *ssr_crash = qdev->ssr_mhi_buf; + struct _ssr_hdr *hdr = mhi_result->buf_addr; + struct ssr_dump_info *dump_info; + + if (mhi_result->transaction_status) { + kfree(mhi_result->buf_addr); + return; + } + + /* + * MEMORY READ is used to download crashdump. And crashdump is + * downloaded chunk by chunk in a series of MEMORY READ SSR commands. + * Hence to avoid too many kmalloc() and kfree() of the same MEMORY READ + * request buffer, we allocate only one such buffer and free it only + * once. + */ + if (le32_to_cpu(hdr->cmd) == MEMORY_READ) { + dump_info = ssr_crash->dump_info; + if (dump_info) { + dump_info->read_buf_req_queued = false; + return; + } + } + + kfree(mhi_result->buf_addr); +} + +static void qaic_ssr_mhi_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result) +{ + struct ssr_resp *resp = container_of(mhi_result->buf_addr, struct ssr_resp, data); + struct qaic_device *qdev = dev_get_drvdata(&mhi_dev->dev); + struct ssr_crashdump *ssr_crash = qdev->ssr_mhi_buf; + bool memory_read_rsp = false; + + if (ssr_crash && ssr_crash->data == mhi_result->buf_addr) + memory_read_rsp = true; + + if (mhi_result->transaction_status) { + /* Do not free SSR crashdump buffer as it allocated via managed APIs */ + if (!memory_read_rsp) + kfree(resp); + return; + } + + if (memory_read_rsp) + queue_work(qdev->ssr_wq, &ssr_crash->work); + else + queue_work(qdev->ssr_wq, &resp->work); +} + +static const struct mhi_device_id qaic_ssr_mhi_match_table[] = { + { .chan = "QAIC_SSR", }, + {}, +}; + +static struct mhi_driver qaic_ssr_mhi_driver = { + .id_table = qaic_ssr_mhi_match_table, + .remove = qaic_ssr_mhi_remove, + .probe = qaic_ssr_mhi_probe, + .ul_xfer_cb = qaic_ssr_mhi_ul_xfer_cb, + .dl_xfer_cb = qaic_ssr_mhi_dl_xfer_cb, + .driver = { + .name = "qaic_ssr", + }, +}; + +int qaic_ssr_init(struct qaic_device *qdev, struct drm_device *drm) +{ + struct ssr_crashdump *ssr_crash; + + qdev->ssr_dbc = QAIC_SSR_DBC_SENTINEL; + + /* + * Device requests only one SSR at a time. So allocating only one + * buffer to download crashdump is good enough. + */ + ssr_crash = drmm_kzalloc(drm, SSR_MHI_BUF_SIZE, GFP_KERNEL); + if (!ssr_crash) + return -ENOMEM; + + ssr_crash->qdev = qdev; + INIT_WORK(&ssr_crash->work, ssr_dump_worker); + qdev->ssr_mhi_buf = ssr_crash; + + return 0; +} + +int qaic_ssr_register(void) +{ + return mhi_driver_register(&qaic_ssr_mhi_driver); +} + +void qaic_ssr_unregister(void) +{ + mhi_driver_unregister(&qaic_ssr_mhi_driver); +} diff --git a/drivers/accel/qaic/qaic_ssr.h b/drivers/accel/qaic/qaic_ssr.h new file mode 100644 index 0000000000000..97ccff305750f --- /dev/null +++ b/drivers/accel/qaic/qaic_ssr.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021, 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __QAIC_SSR_H__ +#define __QAIC_SSR_H__ + +struct drm_device; +struct qaic_device; + +int qaic_ssr_register(void); +void qaic_ssr_unregister(void); +void qaic_clean_up_ssr(struct qaic_device *qdev); +int qaic_ssr_init(struct qaic_device *qdev, struct drm_device *drm); +#endif /* __QAIC_SSR_H__ */ diff --git a/drivers/accel/qaic/qaic_sysfs.c b/drivers/accel/qaic/qaic_sysfs.c new file mode 100644 index 0000000000000..e0afb0ffb5892 --- /dev/null +++ b/drivers/accel/qaic/qaic_sysfs.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* Copyright (c) 2020-2025, The Linux Foundation. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include + +#include "qaic.h" + +#define NAME_LEN 14 + +struct dbc_attribute { + struct device_attribute dev_attr; + u32 dbc_id; + char name[NAME_LEN]; +}; + +static ssize_t dbc_state_show(struct device *dev, struct device_attribute *a, char *buf) +{ + struct dbc_attribute *dbc_attr = container_of(a, struct dbc_attribute, dev_attr); + struct drm_minor *minor = dev_get_drvdata(dev); + struct qaic_device *qdev; + + qdev = to_qaic_device(minor->dev); + return sysfs_emit(buf, "%d\n", qdev->dbc[dbc_attr->dbc_id].state); +} + +void set_dbc_state(struct qaic_device *qdev, u32 dbc_id, unsigned int state) +{ + struct device *kdev = to_accel_kdev(qdev->qddev); + char *envp[3] = {}; + char state_str[16]; + char id_str[12]; + + envp[0] = id_str; + envp[1] = state_str; + + if (state >= DBC_STATE_MAX) + return; + if (dbc_id >= qdev->num_dbc) + return; + if (state == qdev->dbc[dbc_id].state) + return; + + scnprintf(id_str, ARRAY_SIZE(id_str), "DBC_ID=%d", dbc_id); + scnprintf(state_str, ARRAY_SIZE(state_str), "DBC_STATE=%d", state); + + qdev->dbc[dbc_id].state = state; + kobject_uevent_env(&kdev->kobj, KOBJ_CHANGE, envp); +} + +int qaic_sysfs_init(struct qaic_drm_device *qddev) +{ + struct device *kdev = to_accel_kdev(qddev); + struct drm_device *drm = to_drm(qddev); + u32 num_dbc = qddev->qdev->num_dbc; + struct dbc_attribute *dbc_attrs; + int i, ret; + + dbc_attrs = drmm_kcalloc(drm, num_dbc, sizeof(*dbc_attrs), GFP_KERNEL); + if (!dbc_attrs) + return -ENOMEM; + + for (i = 0; i < num_dbc; ++i) { + struct dbc_attribute *dbc_attr = &dbc_attrs[i]; + + sysfs_attr_init(&dbc_attr->dev_attr.attr); + dbc_attr->dbc_id = i; + scnprintf(dbc_attr->name, NAME_LEN, "dbc%d_state", i); + dbc_attr->dev_attr.attr.name = dbc_attr->name; + dbc_attr->dev_attr.attr.mode = 0444; + dbc_attr->dev_attr.show = dbc_state_show; + ret = sysfs_create_file(&kdev->kobj, &dbc_attr->dev_attr.attr); + if (ret) { + int j; + + for (j = 0; j < i; ++j) { + dbc_attr = &dbc_attrs[j]; + sysfs_remove_file(&kdev->kobj, &dbc_attr->dev_attr.attr); + } + drmm_kfree(drm, dbc_attrs); + return ret; + } + } + + qddev->sysfs_attrs = dbc_attrs; + return 0; +} + +void qaic_sysfs_remove(struct qaic_drm_device *qddev) +{ + struct dbc_attribute *dbc_attrs = qddev->sysfs_attrs; + struct device *kdev = to_accel_kdev(qddev); + u32 num_dbc = qddev->qdev->num_dbc; + int i; + + if (!dbc_attrs) + return; + + qddev->sysfs_attrs = NULL; + for (i = 0; i < num_dbc; ++i) + sysfs_remove_file(&kdev->kobj, &dbc_attrs[i].dev_attr.attr); + drmm_kfree(to_drm(qddev), dbc_attrs); +} diff --git a/drivers/accel/qaic/qaic_timesync.c b/drivers/accel/qaic/qaic_timesync.c index 3fac540f8e03d..8af2475f4f369 100644 --- a/drivers/accel/qaic/qaic_timesync.c +++ b/drivers/accel/qaic/qaic_timesync.c @@ -171,6 +171,13 @@ static void qaic_timesync_timer(struct timer_list *t) dev_err(mqtsdev->dev, "%s mod_timer error:%d\n", __func__, ret); } +void qaic_mqts_ch_stop_timer(struct mhi_device *mhi_dev) +{ + struct mqts_dev *mqtsdev = dev_get_drvdata(&mhi_dev->dev); + + timer_delete_sync(&mqtsdev->timer); +} + static int qaic_timesync_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id) { struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_dev->mhi_cntrl->cntrl_dev)); @@ -206,6 +213,7 @@ static int qaic_timesync_probe(struct mhi_device *mhi_dev, const struct mhi_devi timer->expires = jiffies + msecs_to_jiffies(timesync_delay_ms); add_timer(timer); dev_set_drvdata(&mhi_dev->dev, mqtsdev); + qdev->mqts_ch = mhi_dev; return 0; @@ -221,6 +229,7 @@ static void qaic_timesync_remove(struct mhi_device *mhi_dev) { struct mqts_dev *mqtsdev = dev_get_drvdata(&mhi_dev->dev); + mqtsdev->qdev->mqts_ch = NULL; timer_delete_sync(&mqtsdev->timer); mhi_unprepare_from_transfer(mqtsdev->mhi_dev); kfree(mqtsdev->sync_msg); diff --git a/drivers/accel/qaic/qaic_timesync.h b/drivers/accel/qaic/qaic_timesync.h index 851b7acd43bbb..77b9c2b55057c 100644 --- a/drivers/accel/qaic/qaic_timesync.h +++ b/drivers/accel/qaic/qaic_timesync.h @@ -6,6 +6,9 @@ #ifndef __QAIC_TIMESYNC_H__ #define __QAIC_TIMESYNC_H__ +#include + int qaic_timesync_init(void); void qaic_timesync_deinit(void); +void qaic_mqts_ch_stop_timer(struct mhi_device *mhi_dev); #endif /* __QAIC_TIMESYNC_H__ */ diff --git a/drivers/accel/qaic/sahara.c b/drivers/accel/qaic/sahara.c index 3ebcc1f7ff581..fd3c3b2d1fd3b 100644 --- a/drivers/accel/qaic/sahara.c +++ b/drivers/accel/qaic/sahara.c @@ -159,6 +159,7 @@ struct sahara_context { struct sahara_packet *rx; struct work_struct fw_work; struct work_struct dump_work; + struct work_struct read_data_work; struct mhi_device *mhi_dev; const char * const *image_table; u32 table_size; @@ -174,7 +175,10 @@ struct sahara_context { u64 dump_image_offset; void *mem_dump_freespace; u64 dump_images_left; + u32 read_data_offset; + u32 read_data_length; bool is_mem_dump_mode; + bool non_streaming; }; static const char * const aic100_image_table[] = { @@ -194,6 +198,7 @@ static const char * const aic200_image_table[] = { [23] = "qcom/aic200/aop.mbn", [32] = "qcom/aic200/tz.mbn", [33] = "qcom/aic200/hypvm.mbn", + [38] = "qcom/aic200/xbl_config.elf", [39] = "qcom/aic200/aic200_abl.elf", [40] = "qcom/aic200/apdp.mbn", [41] = "qcom/aic200/devcfg.mbn", @@ -202,6 +207,7 @@ static const char * const aic200_image_table[] = { [49] = "qcom/aic200/shrm.elf", [50] = "qcom/aic200/cpucp.elf", [51] = "qcom/aic200/aop_devcfg.mbn", + [54] = "qcom/aic200/qupv3fw.elf", [57] = "qcom/aic200/cpucp_dtbs.elf", [62] = "qcom/aic200/uefi_dtbs.elf", [63] = "qcom/aic200/xbl_ac_config.mbn", @@ -213,9 +219,15 @@ static const char * const aic200_image_table[] = { [69] = "qcom/aic200/dcd.mbn", [73] = "qcom/aic200/gearvm.mbn", [74] = "qcom/aic200/sti.bin", - [75] = "qcom/aic200/pvs.bin", + [76] = "qcom/aic200/tz_qti_config.mbn", + [78] = "qcom/aic200/pvs.bin", }; +static bool is_streaming(struct sahara_context *context) +{ + return !context->non_streaming; +} + static int sahara_find_image(struct sahara_context *context, u32 image_id) { int ret; @@ -265,6 +277,8 @@ static void sahara_send_reset(struct sahara_context *context) int ret; context->is_mem_dump_mode = false; + context->read_data_offset = 0; + context->read_data_length = 0; context->tx[0]->cmd = cpu_to_le32(SAHARA_RESET_CMD); context->tx[0]->length = cpu_to_le32(SAHARA_RESET_LENGTH); @@ -319,9 +333,39 @@ static void sahara_hello(struct sahara_context *context) dev_err(&context->mhi_dev->dev, "Unable to send hello response %d\n", ret); } +static int read_data_helper(struct sahara_context *context, int buf_index) +{ + enum mhi_flags mhi_flag; + u32 pkt_data_len; + int ret; + + pkt_data_len = min(context->read_data_length, SAHARA_PACKET_MAX_SIZE); + + memcpy(context->tx[buf_index], + &context->firmware->data[context->read_data_offset], + pkt_data_len); + + context->read_data_offset += pkt_data_len; + context->read_data_length -= pkt_data_len; + + if (is_streaming(context) || !context->read_data_length) + mhi_flag = MHI_EOT; + else + mhi_flag = MHI_CHAIN; + + ret = mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, + context->tx[buf_index], pkt_data_len, mhi_flag); + if (ret) { + dev_err(&context->mhi_dev->dev, "Unable to send read_data response %d\n", ret); + return ret; + } + + return 0; +} + static void sahara_read_data(struct sahara_context *context) { - u32 image_id, data_offset, data_len, pkt_data_len; + u32 image_id, data_offset, data_len; int ret; int i; @@ -357,7 +401,7 @@ static void sahara_read_data(struct sahara_context *context) * and is not needed here on error. */ - if (data_len > SAHARA_TRANSFER_MAX_SIZE) { + if (context->non_streaming && data_len > SAHARA_TRANSFER_MAX_SIZE) { dev_err(&context->mhi_dev->dev, "Malformed read_data packet - data len %d exceeds max xfer size %d\n", data_len, SAHARA_TRANSFER_MAX_SIZE); sahara_send_reset(context); @@ -378,22 +422,18 @@ static void sahara_read_data(struct sahara_context *context) return; } - for (i = 0; i < SAHARA_NUM_TX_BUF && data_len; ++i) { - pkt_data_len = min(data_len, SAHARA_PACKET_MAX_SIZE); - - memcpy(context->tx[i], &context->firmware->data[data_offset], pkt_data_len); + context->read_data_offset = data_offset; + context->read_data_length = data_len; - data_offset += pkt_data_len; - data_len -= pkt_data_len; + if (is_streaming(context)) { + schedule_work(&context->read_data_work); + return; + } - ret = mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, - context->tx[i], pkt_data_len, - !data_len ? MHI_EOT : MHI_CHAIN); - if (ret) { - dev_err(&context->mhi_dev->dev, "Unable to send read_data response %d\n", - ret); - return; - } + for (i = 0; i < SAHARA_NUM_TX_BUF && context->read_data_length; ++i) { + ret = read_data_helper(context, i); + if (ret) + break; } } @@ -538,6 +578,7 @@ static void sahara_parse_dump_table(struct sahara_context *context) struct sahara_memory_dump_meta_v1 *dump_meta; u64 table_nents; u64 dump_length; + u64 mul_bytes; int ret; u64 i; @@ -551,8 +592,9 @@ static void sahara_parse_dump_table(struct sahara_context *context) dev_table[i].description[SAHARA_TABLE_ENTRY_STR_LEN - 1] = 0; dev_table[i].filename[SAHARA_TABLE_ENTRY_STR_LEN - 1] = 0; - dump_length = size_add(dump_length, le64_to_cpu(dev_table[i].length)); - if (dump_length == SIZE_MAX) { + if (check_add_overflow(dump_length, + le64_to_cpu(dev_table[i].length), + &dump_length)) { /* Discard the dump */ sahara_send_reset(context); return; @@ -568,14 +610,17 @@ static void sahara_parse_dump_table(struct sahara_context *context) dev_table[i].filename); } - dump_length = size_add(dump_length, sizeof(*dump_meta)); - if (dump_length == SIZE_MAX) { + if (check_add_overflow(dump_length, (u64)sizeof(*dump_meta), &dump_length)) { /* Discard the dump */ sahara_send_reset(context); return; } - dump_length = size_add(dump_length, size_mul(sizeof(*image_out_table), table_nents)); - if (dump_length == SIZE_MAX) { + if (check_mul_overflow((u64)sizeof(*image_out_table), table_nents, &mul_bytes)) { + /* Discard the dump */ + sahara_send_reset(context); + return; + } + if (check_add_overflow(dump_length, mul_bytes, &dump_length)) { /* Discard the dump */ sahara_send_reset(context); return; @@ -615,7 +660,7 @@ static void sahara_parse_dump_table(struct sahara_context *context) /* Request the first chunk of the first image */ context->dump_image = &image_out_table[0]; - dump_length = min(context->dump_image->length, SAHARA_READ_MAX_SIZE); + dump_length = min_t(u64, context->dump_image->length, SAHARA_READ_MAX_SIZE); /* Avoid requesting EOI sized data so that we can identify errors */ if (dump_length == SAHARA_END_OF_IMAGE_LENGTH) dump_length = SAHARA_END_OF_IMAGE_LENGTH / 2; @@ -663,7 +708,7 @@ static void sahara_parse_dump_image(struct sahara_context *context) /* Get next image chunk */ dump_length = context->dump_image->length - context->dump_image_offset; - dump_length = min(dump_length, SAHARA_READ_MAX_SIZE); + dump_length = min_t(u64, dump_length, SAHARA_READ_MAX_SIZE); /* Avoid requesting EOI sized data so that we can identify errors */ if (dump_length == SAHARA_END_OF_IMAGE_LENGTH) dump_length = SAHARA_END_OF_IMAGE_LENGTH / 2; @@ -742,6 +787,13 @@ static void sahara_dump_processing(struct work_struct *work) sahara_send_reset(context); } +static void sahara_read_data_processing(struct work_struct *work) +{ + struct sahara_context *context = container_of(work, struct sahara_context, read_data_work); + + read_data_helper(context, 0); +} + static int sahara_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id) { struct sahara_context *context; @@ -756,34 +808,56 @@ static int sahara_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_ if (!context->rx) return -ENOMEM; + if (!strcmp(mhi_dev->mhi_cntrl->name, "AIC200")) { + context->image_table = aic200_image_table; + context->table_size = ARRAY_SIZE(aic200_image_table); + } else { + context->image_table = aic100_image_table; + context->table_size = ARRAY_SIZE(aic100_image_table); + context->non_streaming = true; + } + /* - * AIC100 defines SAHARA_TRANSFER_MAX_SIZE as the largest value it - * will request for READ_DATA. This is larger than - * SAHARA_PACKET_MAX_SIZE, and we need 9x SAHARA_PACKET_MAX_SIZE to - * cover SAHARA_TRANSFER_MAX_SIZE. When the remote side issues a - * READ_DATA, it requires a transfer of the exact size requested. We - * can use MHI_CHAIN to link multiple buffers into a single transfer - * but the remote side will not consume the buffers until it sees an - * EOT, thus we need to allocate enough buffers to put in the tx fifo - * to cover an entire READ_DATA request of the max size. + * There are two firmware implementations for READ_DATA handling. + * The older "SBL" implementation defines a Sahara transfer size, and + * expects that the response is a single transport transfer. If the + * FW wants to transfer a file that is larger than the transfer size, + * the FW will issue multiple READ_DATA commands. For this + * implementation, we need to allocate enough buffers to contain the + * entire Sahara transfer size. + * + * The newer "XBL" implementation does not define a maximum transfer + * size and instead expects the data to be streamed over using the + * transport level MTU. The FW will issue a single READ_DATA command + * of whatever size, and consume multiple transport level transfers + * until the expected amount of data is consumed. For this + * implementation we only need a single buffer of the transport MTU + * but we'll need to be able to use it multiple times for a single + * READ_DATA request. + * + * AIC100 is the SBL implementation and defines SAHARA_TRANSFER_MAX_SIZE + * and we need 9x SAHARA_PACKET_MAX_SIZE to cover that. We can use + * MHI_CHAIN to link multiple buffers into a single transfer but the + * remote side will not consume the buffers until it sees an EOT, thus + * we need to allocate enough buffers to put in the tx fifo to cover an + * entire READ_DATA request of the max size. + * + * AIC200 is the XBL implementation, and so a single buffer will work. */ for (i = 0; i < SAHARA_NUM_TX_BUF; ++i) { - context->tx[i] = devm_kzalloc(&mhi_dev->dev, SAHARA_PACKET_MAX_SIZE, GFP_KERNEL); + context->tx[i] = devm_kzalloc(&mhi_dev->dev, + SAHARA_PACKET_MAX_SIZE, + GFP_KERNEL); if (!context->tx[i]) return -ENOMEM; + if (is_streaming(context)) + break; } context->mhi_dev = mhi_dev; INIT_WORK(&context->fw_work, sahara_processing); INIT_WORK(&context->dump_work, sahara_dump_processing); - - if (!strcmp(mhi_dev->mhi_cntrl->name, "AIC200")) { - context->image_table = aic200_image_table; - context->table_size = ARRAY_SIZE(aic200_image_table); - } else { - context->image_table = aic100_image_table; - context->table_size = ARRAY_SIZE(aic100_image_table); - } + INIT_WORK(&context->read_data_work, sahara_read_data_processing); context->active_image_id = SAHARA_IMAGE_ID_NONE; dev_set_drvdata(&mhi_dev->dev, context); @@ -814,6 +888,10 @@ static void sahara_mhi_remove(struct mhi_device *mhi_dev) static void sahara_mhi_ul_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result) { + struct sahara_context *context = dev_get_drvdata(&mhi_dev->dev); + + if (!mhi_result->transaction_status && context->read_data_length && is_streaming(context)) + schedule_work(&context->read_data_work); } static void sahara_mhi_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result) diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocket_gem.c index 0551e11cc1841..624c4ecf5a342 100644 --- a/drivers/accel/rocket/rocket_gem.c +++ b/drivers/accel/rocket/rocket_gem.c @@ -2,6 +2,7 @@ /* Copyright 2024-2025 Tomeu Vizoso */ #include +#include #include #include #include diff --git a/drivers/acpi/acpi_pcc.c b/drivers/acpi/acpi_pcc.c index 97064e943768a..e3f302b9dee5f 100644 --- a/drivers/acpi/acpi_pcc.c +++ b/drivers/acpi/acpi_pcc.c @@ -52,7 +52,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function, struct pcc_data *data; struct acpi_pcc_info *ctx = handler_context; struct pcc_mbox_chan *pcc_chan; - static acpi_status ret; + acpi_status ret; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 97ee19f2cae06..0dc767392a6c6 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,7 @@ #include #include #include +#include #include #include @@ -505,12 +507,6 @@ static bool ghes_do_memory_failure(u64 physical_addr, int flags) return false; pfn = PHYS_PFN(physical_addr); - if (!pfn_valid(pfn) && !arch_is_platform_page(physical_addr)) { - pr_warn_ratelimited(FW_WARN GHES_PFX - "Invalid address in generic error data: %#llx\n", - physical_addr); - return false; - } if (flags == MF_ACTION_REQUIRED && current->mm) { twcb = (void *)gen_pool_alloc(ghes_estatus_pool, sizeof(*twcb)); @@ -552,26 +548,25 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, } static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, - int sev, bool sync) + int sev, bool sync) { struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); int flags = sync ? MF_ACTION_REQUIRED : 0; + char error_type[120]; bool queued = false; int sec_sev, i; char *p; - log_arm_hw_error(err); - sec_sev = ghes_severity(gdata->error_severity); + log_arm_hw_error(err, sec_sev); if (sev != GHES_SEV_RECOVERABLE || sec_sev != GHES_SEV_RECOVERABLE) return false; p = (char *)(err + 1); for (i = 0; i < err->err_info_num; i++) { struct cper_arm_err_info *err_info = (struct cper_arm_err_info *)p; - bool is_cache = (err_info->type == CPER_ARM_CACHE_ERROR); + bool is_cache = err_info->type & CPER_ARM_CACHE_ERROR; bool has_pa = (err_info->validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR); - const char *error_type = "unknown error"; /* * The field (err_info->error_info & BIT(26)) is fixed to set to @@ -585,12 +580,15 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, continue; } - if (err_info->type < ARRAY_SIZE(cper_proc_error_type_strs)) - error_type = cper_proc_error_type_strs[err_info->type]; + cper_bits_to_str(error_type, sizeof(error_type), + FIELD_GET(CPER_ARM_ERR_TYPE_MASK, err_info->type), + cper_proc_error_type_strs, + ARRAY_SIZE(cper_proc_error_type_strs)); pr_warn_ratelimited(FW_WARN GHES_PFX - "Unhandled processor error type: %s\n", - error_type); + "Unhandled processor error type 0x%02x: %s%s\n", + err_info->type, error_type, + (err_info->type & ~CPER_ARM_ERR_TYPE_MASK) ? " with reserved bit(s)" : ""); p += err_info->length; } @@ -867,6 +865,40 @@ int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd) } EXPORT_SYMBOL_NS_GPL(cxl_cper_kfifo_get, "CXL"); +static void ghes_log_hwerr(int sev, guid_t *sec_type) +{ + if (sev != CPER_SEV_RECOVERABLE) + return; + + if (guid_equal(sec_type, &CPER_SEC_PROC_ARM) || + guid_equal(sec_type, &CPER_SEC_PROC_GENERIC) || + guid_equal(sec_type, &CPER_SEC_PROC_IA)) { + hwerr_log_error_type(HWERR_RECOV_CPU); + return; + } + + if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR) || + guid_equal(sec_type, &CPER_SEC_CXL_GEN_MEDIA_GUID) || + guid_equal(sec_type, &CPER_SEC_CXL_DRAM_GUID) || + guid_equal(sec_type, &CPER_SEC_CXL_MEM_MODULE_GUID)) { + hwerr_log_error_type(HWERR_RECOV_CXL); + return; + } + + if (guid_equal(sec_type, &CPER_SEC_PCIE) || + guid_equal(sec_type, &CPER_SEC_PCI_X_BUS)) { + hwerr_log_error_type(HWERR_RECOV_PCI); + return; + } + + if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { + hwerr_log_error_type(HWERR_RECOV_MEMORY); + return; + } + + hwerr_log_error_type(HWERR_RECOV_OTHERS); +} + static void ghes_do_proc(struct ghes *ghes, const struct acpi_hest_generic_status *estatus) { @@ -888,6 +920,7 @@ static void ghes_do_proc(struct ghes *ghes, if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) fru_text = gdata->fru_text; + ghes_log_hwerr(sev, sec_type); if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata); @@ -895,11 +928,9 @@ static void ghes_do_proc(struct ghes *ghes, arch_apei_report_mem_error(sev, mem_err); queued = ghes_handle_memory_failure(gdata, sev, sync); - } - else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { + } else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { ghes_handle_aer(gdata); - } - else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { + } else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { queued = ghes_handle_arm_hw_error(gdata, sev, sync); } else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) { struct cxl_cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata); diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 3bdeeee3414e6..e66e20d1f31b7 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1366,7 +1366,8 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) /* Are any of the regs PCC ?*/ if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg) || - CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg)) { + CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg) || + CPC_IN_PCC(guaranteed_reg)) { if (pcc_ss_id < 0) { pr_debug("Invalid pcc_ss_id\n"); return -ENODEV; diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c index 11e4483685c9c..77a81627aaefd 100644 --- a/drivers/acpi/numa/hmat.c +++ b/drivers/acpi/numa/hmat.c @@ -910,12 +910,13 @@ static void hmat_register_target(struct memory_target *target) * Register generic port perf numbers. The nid may not be * initialized and is still NUMA_NO_NODE. */ - mutex_lock(&target_lock); - if (*(u16 *)target->gen_port_device_handle) { - hmat_update_generic_target(target); - target->registered = true; + scoped_guard(mutex, &target_lock) { + if (*(u16 *)target->gen_port_device_handle) { + hmat_update_generic_target(target); + target->registered = true; + return; + } } - mutex_unlock(&target_lock); hmat_hotplug_target(target); } diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index e4560b33b8ad1..bed7dc85612e3 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -761,7 +761,7 @@ static int acpi_pci_link_resume(struct acpi_pci_link *link) return 0; } -static void irqrouter_resume(void) +static void irqrouter_resume(void *data) { struct acpi_pci_link *link; @@ -888,10 +888,14 @@ static int __init acpi_irq_balance_set(char *str) __setup("acpi_irq_balance", acpi_irq_balance_set); -static struct syscore_ops irqrouter_syscore_ops = { +static const struct syscore_ops irqrouter_syscore_ops = { .resume = irqrouter_resume, }; +static struct syscore irqrouter_syscore = { + .ops = &irqrouter_syscore_ops, +}; + void __init acpi_pci_link_init(void) { if (acpi_noirq) @@ -904,6 +908,6 @@ void __init acpi_pci_link_init(void) else acpi_irq_balance = 0; } - register_syscore_ops(&irqrouter_syscore_ops); + register_syscore(&irqrouter_syscore); acpi_scan_add_handler(&pci_link_handler); } diff --git a/drivers/acpi/platform_profile.c b/drivers/acpi/platform_profile.c index b43f4459a4f61..ea04a8c692154 100644 --- a/drivers/acpi/platform_profile.c +++ b/drivers/acpi/platform_profile.c @@ -37,6 +37,7 @@ static const char * const profile_names[] = { [PLATFORM_PROFILE_BALANCED] = "balanced", [PLATFORM_PROFILE_BALANCED_PERFORMANCE] = "balanced-performance", [PLATFORM_PROFILE_PERFORMANCE] = "performance", + [PLATFORM_PROFILE_MAX_POWER] = "max-power", [PLATFORM_PROFILE_CUSTOM] = "custom", }; static_assert(ARRAY_SIZE(profile_names) == PLATFORM_PROFILE_LAST); @@ -506,7 +507,8 @@ int platform_profile_cycle(void) if (err) return err; - if (profile == PLATFORM_PROFILE_CUSTOM || + if (profile == PLATFORM_PROFILE_MAX_POWER || + profile == PLATFORM_PROFILE_CUSTOM || profile == PLATFORM_PROFILE_LAST) return -EINVAL; @@ -515,7 +517,8 @@ int platform_profile_cycle(void) if (err) return err; - /* never iterate into a custom if all drivers supported it */ + /* never iterate into a custom or max power if all drivers supported it */ + clear_bit(PLATFORM_PROFILE_MAX_POWER, data.aggregate); clear_bit(PLATFORM_PROFILE_CUSTOM, data.aggregate); next = find_next_bit_wrap(data.aggregate, diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 68943b98333dd..66ec81e306d47 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -884,13 +884,13 @@ bool acpi_s2idle_wakeup(void) #ifdef CONFIG_PM_SLEEP static u32 saved_bm_rld; -static int acpi_save_bm_rld(void) +static int acpi_save_bm_rld(void *data) { acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld); return 0; } -static void acpi_restore_bm_rld(void) +static void acpi_restore_bm_rld(void *data) { u32 resumed_bm_rld = 0; @@ -901,14 +901,18 @@ static void acpi_restore_bm_rld(void) acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); } -static struct syscore_ops acpi_sleep_syscore_ops = { +static const struct syscore_ops acpi_sleep_syscore_ops = { .suspend = acpi_save_bm_rld, .resume = acpi_restore_bm_rld, }; +static struct syscore acpi_sleep_syscore = { + .ops = &acpi_sleep_syscore_ops, +}; + static void acpi_sleep_syscore_init(void) { - register_syscore_ops(&acpi_sleep_syscore_ops); + register_syscore(&acpi_sleep_syscore); } #else static inline void acpi_sleep_syscore_init(void) {} diff --git a/drivers/amba/Kconfig b/drivers/amba/Kconfig index fb6c7e0b4cce2..14bb61ff801e6 100644 --- a/drivers/amba/Kconfig +++ b/drivers/amba/Kconfig @@ -5,7 +5,7 @@ config ARM_AMBA if ARM_AMBA config TEGRA_AHB - bool + bool "Enable AHB driver for NVIDIA Tegra SoCs" if COMPILE_TEST default y if ARCH_TEGRA help Adds AHB configuration functionality for NVIDIA Tegra SoCs, diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 74e34a07ef72f..952c45ca6e48f 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -291,15 +291,14 @@ static int amba_probe(struct device *dev) if (ret < 0) break; - ret = dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON); + ret = dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON | + PD_FLAG_DETACH_POWER_OFF); if (ret) break; ret = amba_get_enable_pclk(pcdev); - if (ret) { - dev_pm_domain_detach(dev, true); + if (ret) break; - } pm_runtime_get_noresume(dev); pm_runtime_set_active(dev); @@ -314,7 +313,6 @@ static int amba_probe(struct device *dev) pm_runtime_put_noidle(dev); amba_put_disable_pclk(pcdev); - dev_pm_domain_detach(dev, true); } while (0); return ret; @@ -336,7 +334,6 @@ static void amba_remove(struct device *dev) pm_runtime_put_noidle(dev); amba_put_disable_pclk(pcdev); - dev_pm_domain_detach(dev, true); } static void amba_shutdown(struct device *dev) diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c index c0e8b765522dc..f23c3ed018101 100644 --- a/drivers/amba/tegra-ahb.c +++ b/drivers/amba/tegra-ahb.c @@ -144,6 +144,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn) if (!dev) return -EPROBE_DEFER; ahb = dev_get_drvdata(dev); + put_device(dev); val = gizmo_readl(ahb, AHB_ARBITRATION_XBAR_CTRL); val |= AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE; gizmo_writel(ahb, val, AHB_ARBITRATION_XBAR_CTRL); diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a3a1b5c33ba36..535fc881c8daa 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -4669,6 +4669,8 @@ static int binder_wait_for_work(struct binder_thread *thread, * * If we fail to allocate an fd, skip the install and release * any fds that have already been allocated. + * + * Return: 0 on success, a negative errno code on failure. */ static int binder_apply_fd_fixups(struct binder_proc *proc, struct binder_transaction *t) diff --git a/drivers/android/binder/node.rs b/drivers/android/binder/node.rs index 08d362deaf61e..c26d113ede966 100644 --- a/drivers/android/binder/node.rs +++ b/drivers/android/binder/node.rs @@ -541,10 +541,10 @@ impl Node { guard = self.owner.inner.lock(); } - let death_list = core::mem::take(&mut self.inner.access_mut(&mut guard).death_list); - drop(guard); - for death in death_list { + while let Some(death) = self.inner.access_mut(&mut guard).death_list.pop_front() { + drop(guard); death.into_arc().set_dead(); + guard = self.owner.inner.lock(); } } diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs index e5237e9ec552f..132055b4790f0 100644 --- a/drivers/android/binder/process.rs +++ b/drivers/android/binder/process.rs @@ -19,6 +19,7 @@ use kernel::{ cred::Credential, error::Error, fs::file::{self, File}, + id_pool::IdPool, list::{List, ListArc, ListArcField, ListLinks}, mm, prelude::*, @@ -394,6 +395,8 @@ kernel::list::impl_list_item! { struct ProcessNodeRefs { /// Used to look up nodes using the 32-bit id that this process knows it by. by_handle: RBTree>, + /// Used to quickly find unused ids in `by_handle`. + handle_is_present: IdPool, /// Used to look up nodes without knowing their local 32-bit id. The usize is the address of /// the underlying `Node` struct as returned by `Node::global_id`. by_node: RBTree, @@ -408,6 +411,7 @@ impl ProcessNodeRefs { fn new() -> Self { Self { by_handle: RBTree::new(), + handle_is_present: IdPool::new(), by_node: RBTree::new(), freeze_listeners: RBTree::new(), } @@ -802,7 +806,7 @@ impl Process { pub(crate) fn insert_or_update_handle( self: ArcBorrow<'_, Process>, node_ref: NodeRef, - is_mananger: bool, + is_manager: bool, ) -> Result { { let mut refs = self.node_refs.lock(); @@ -821,7 +825,33 @@ impl Process { let reserve2 = RBTreeNodeReservation::new(GFP_KERNEL)?; let info = UniqueArc::new_uninit(GFP_KERNEL)?; - let mut refs = self.node_refs.lock(); + let mut refs_lock = self.node_refs.lock(); + let mut refs = &mut *refs_lock; + + let (unused_id, by_handle_slot) = loop { + // ID 0 may only be used by the manager. + let start = if is_manager { 0 } else { 1 }; + + if let Some(res) = refs.handle_is_present.find_unused_id(start) { + match refs.by_handle.entry(res.as_u32()) { + rbtree::Entry::Vacant(entry) => break (res, entry), + rbtree::Entry::Occupied(_) => { + pr_err!("Detected mismatch between handle_is_present and by_handle"); + res.acquire(); + kernel::warn_on!(true); + return Err(EINVAL); + } + } + } + + let grow_request = refs.handle_is_present.grow_request().ok_or(ENOMEM)?; + drop(refs_lock); + let resizer = grow_request.realloc(GFP_KERNEL)?; + refs_lock = self.node_refs.lock(); + refs = &mut *refs_lock; + refs.handle_is_present.grow(resizer); + }; + let handle = unused_id.as_u32(); // Do a lookup again as node may have been inserted before the lock was reacquired. if let Some(handle_ref) = refs.by_node.get(&node_ref.node.global_id()) { @@ -831,20 +861,9 @@ impl Process { return Ok(handle); } - // Find id. - let mut target: u32 = if is_mananger { 0 } else { 1 }; - for handle in refs.by_handle.keys() { - if *handle > target { - break; - } - if *handle == target { - target = target.checked_add(1).ok_or(ENOMEM)?; - } - } - let gid = node_ref.node.global_id(); let (info_proc, info_node) = { - let info_init = NodeRefInfo::new(node_ref, target, self.into()); + let info_init = NodeRefInfo::new(node_ref, handle, self.into()); match info.pin_init_with(info_init) { Ok(info) => ListArc::pair_from_pin_unique(info), // error is infallible @@ -865,9 +884,10 @@ impl Process { // `info_node` into the right node's `refs` list. unsafe { info_proc.node_ref2().node.insert_node_info(info_node) }; - refs.by_node.insert(reserve1.into_node(gid, target)); - refs.by_handle.insert(reserve2.into_node(target, info_proc)); - Ok(target) + refs.by_node.insert(reserve1.into_node(gid, handle)); + by_handle_slot.insert(info_proc, reserve2); + unused_id.acquire(); + Ok(handle) } pub(crate) fn get_transaction_node(&self, handle: u32) -> BinderResult { @@ -932,6 +952,16 @@ impl Process { let id = info.node_ref().node.global_id(); refs.by_handle.remove(&handle); refs.by_node.remove(&id); + refs.handle_is_present.release_id(handle as usize); + + if let Some(shrink) = refs.handle_is_present.shrink_request() { + drop(refs); + // This intentionally ignores allocation failures. + if let Ok(new_bitmap) = shrink.realloc(GFP_KERNEL) { + refs = self.node_refs.lock(); + refs.handle_is_present.shrink(new_bitmap); + } + } } } else { // All refs are cleared in process exit, so this warning is expected in that case. @@ -1362,8 +1392,12 @@ impl Process { work.into_arc().cancel(); } - let delivered_deaths = take(&mut self.inner.lock().delivered_deaths); - drop(delivered_deaths); + // Clear delivered_deaths list. + // + // Scope ensures that MutexGuard is dropped while executing the body. + while let Some(delivered_death) = { self.inner.lock().delivered_deaths.pop_front() } { + drop(delivered_death); + } // Free any resources kept alive by allocated buffers. let omapping = self.inner.lock().mapping.take(); @@ -1623,15 +1657,6 @@ impl Process { } } - pub(crate) fn compat_ioctl( - this: ArcBorrow<'_, Process>, - file: &File, - cmd: u32, - arg: usize, - ) -> Result { - Self::ioctl(this, file, cmd, arg) - } - pub(crate) fn mmap( this: ArcBorrow<'_, Process>, _file: &File, diff --git a/drivers/android/binder/rust_binder_main.rs b/drivers/android/binder/rust_binder_main.rs index 6773b7c273ec9..c79a9e7422401 100644 --- a/drivers/android/binder/rust_binder_main.rs +++ b/drivers/android/binder/rust_binder_main.rs @@ -313,8 +313,8 @@ pub static rust_binder_fops: AssertSync = { let ops = kernel::bindings::file_operations { owner: THIS_MODULE.as_ptr(), poll: Some(rust_binder_poll), - unlocked_ioctl: Some(rust_binder_unlocked_ioctl), - compat_ioctl: Some(rust_binder_compat_ioctl), + unlocked_ioctl: Some(rust_binder_ioctl), + compat_ioctl: Some(bindings::compat_ptr_ioctl), mmap: Some(rust_binder_mmap), open: Some(rust_binder_open), release: Some(rust_binder_release), @@ -402,23 +402,7 @@ unsafe extern "C" fn rust_binder_release( /// # Safety /// Only called by binderfs. -unsafe extern "C" fn rust_binder_compat_ioctl( - file: *mut bindings::file, - cmd: kernel::ffi::c_uint, - arg: kernel::ffi::c_ulong, -) -> kernel::ffi::c_long { - // SAFETY: We previously set `private_data` in `rust_binder_open`. - let f = unsafe { Arc::::borrow((*file).private_data) }; - // SAFETY: The caller ensures that the file is valid. - match Process::compat_ioctl(f, unsafe { File::from_raw_file(file) }, cmd as _, arg as _) { - Ok(()) => 0, - Err(err) => err.to_errno() as isize, - } -} - -/// # Safety -/// Only called by binderfs. -unsafe extern "C" fn rust_binder_unlocked_ioctl( +unsafe extern "C" fn rust_binder_ioctl( file: *mut bindings::file, cmd: kernel::ffi::c_uint, arg: kernel::ffi::c_ulong, diff --git a/drivers/android/binder/rust_binderfs.c b/drivers/android/binder/rust_binderfs.c index 6b497146b698b..c69026df775c2 100644 --- a/drivers/android/binder/rust_binderfs.c +++ b/drivers/android/binder/rust_binderfs.c @@ -178,28 +178,17 @@ static int binderfs_binder_device_create(struct inode *ref_inode, } root = sb->s_root; - inode_lock(d_inode(root)); - - /* look it up */ - dentry = lookup_noperm(&QSTR(req->name), root); + dentry = simple_start_creating(root, req->name); if (IS_ERR(dentry)) { - inode_unlock(d_inode(root)); ret = PTR_ERR(dentry); goto err; } - if (d_really_is_positive(dentry)) { - /* already exists */ - dput(dentry); - inode_unlock(d_inode(root)); - ret = -EEXIST; - goto err; - } - inode->i_private = device; - d_instantiate(dentry, inode); + d_make_persistent(dentry, inode); + fsnotify_create(root->d_inode, dentry); - inode_unlock(d_inode(root)); + simple_done_creating(dentry); return 0; @@ -472,37 +461,9 @@ static struct inode *binderfs_make_inode(struct super_block *sb, int mode) return ret; } -static struct dentry *binderfs_create_dentry(struct dentry *parent, - const char *name) -{ - struct dentry *dentry; - - dentry = lookup_noperm(&QSTR(name), parent); - if (IS_ERR(dentry)) - return dentry; - - /* Return error if the file/dir already exists. */ - if (d_really_is_positive(dentry)) { - dput(dentry); - return ERR_PTR(-EEXIST); - } - - return dentry; -} - void rust_binderfs_remove_file(struct dentry *dentry) { - struct inode *parent_inode; - - parent_inode = d_inode(dentry->d_parent); - inode_lock(parent_inode); - if (simple_positive(dentry)) { - dget(dentry); - simple_unlink(parent_inode, dentry); - d_delete(dentry); - dput(dentry); - } - inode_unlock(parent_inode); + simple_recursive_removal(dentry, NULL); } static struct dentry *rust_binderfs_create_file(struct dentry *parent, const char *name, @@ -510,31 +471,23 @@ static struct dentry *rust_binderfs_create_file(struct dentry *parent, const cha void *data) { struct dentry *dentry; - struct inode *new_inode, *parent_inode; - struct super_block *sb; - - parent_inode = d_inode(parent); - inode_lock(parent_inode); - - dentry = binderfs_create_dentry(parent, name); - if (IS_ERR(dentry)) - goto out; - - sb = parent_inode->i_sb; - new_inode = binderfs_make_inode(sb, S_IFREG | 0444); - if (!new_inode) { - dput(dentry); - dentry = ERR_PTR(-ENOMEM); - goto out; - } + struct inode *new_inode; + new_inode = binderfs_make_inode(parent->d_sb, S_IFREG | 0444); + if (!new_inode) + return ERR_PTR(-ENOMEM); new_inode->i_fop = fops; new_inode->i_private = data; - d_instantiate(dentry, new_inode); - fsnotify_create(parent_inode, dentry); -out: - inode_unlock(parent_inode); + dentry = simple_start_creating(parent, name); + if (IS_ERR(dentry)) { + iput(new_inode); + return dentry; + } + + d_make_persistent(dentry, new_inode); + fsnotify_create(parent->d_inode, dentry); + simple_done_creating(dentry); return dentry; } @@ -556,34 +509,26 @@ static struct dentry *binderfs_create_dir(struct dentry *parent, const char *name) { struct dentry *dentry; - struct inode *new_inode, *parent_inode; - struct super_block *sb; - - parent_inode = d_inode(parent); - inode_lock(parent_inode); - - dentry = binderfs_create_dentry(parent, name); - if (IS_ERR(dentry)) - goto out; + struct inode *new_inode; - sb = parent_inode->i_sb; - new_inode = binderfs_make_inode(sb, S_IFDIR | 0755); - if (!new_inode) { - dput(dentry); - dentry = ERR_PTR(-ENOMEM); - goto out; - } + new_inode = binderfs_make_inode(parent->d_sb, S_IFDIR | 0755); + if (!new_inode) + return ERR_PTR(-ENOMEM); new_inode->i_fop = &simple_dir_operations; new_inode->i_op = &simple_dir_inode_operations; - set_nlink(new_inode, 2); - d_instantiate(dentry, new_inode); - inc_nlink(parent_inode); - fsnotify_mkdir(parent_inode, dentry); + dentry = simple_start_creating(parent, name); + if (IS_ERR(dentry)) { + iput(new_inode); + return dentry; + } -out: - inode_unlock(parent_inode); + inc_nlink(parent->d_inode); + set_nlink(new_inode, 2); + d_make_persistent(dentry, new_inode); + fsnotify_mkdir(parent->d_inode, dentry); + simple_done_creating(dentry); return dentry; } @@ -802,7 +747,7 @@ static void binderfs_kill_super(struct super_block *sb) * During inode eviction struct binderfs_info is needed. * So first wipe the super_block then free struct binderfs_info. */ - kill_litter_super(sb); + kill_anon_super(sb); if (info && info->ipc_ns) put_ipc_ns(info->ipc_ns); diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs index 7e34ccd394f80..1a8e6fdc0dc42 100644 --- a/drivers/android/binder/thread.rs +++ b/drivers/android/binder/thread.rs @@ -1323,12 +1323,12 @@ impl Thread { } BC_FREE_BUFFER => { let buffer = self.process.buffer_get(reader.read()?); - if let Some(buffer) = &buffer { + if let Some(buffer) = buffer { if buffer.looper_need_return_on_free() { self.inner.lock().looper_need_return = true; } + drop(buffer); } - drop(buffer); } BC_INCREFS => { self.process diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index be8e64eb39ec5..b46bcb91072de 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -183,28 +183,15 @@ static int binderfs_binder_device_create(struct inode *ref_inode, } root = sb->s_root; - inode_lock(d_inode(root)); - - /* look it up */ - dentry = lookup_noperm(&QSTR(name), root); + dentry = simple_start_creating(root, name); if (IS_ERR(dentry)) { - inode_unlock(d_inode(root)); ret = PTR_ERR(dentry); goto err; } - - if (d_really_is_positive(dentry)) { - /* already exists */ - dput(dentry); - inode_unlock(d_inode(root)); - ret = -EEXIST; - goto err; - } - inode->i_private = device; - d_instantiate(dentry, inode); + d_make_persistent(dentry, inode); fsnotify_create(root->d_inode, dentry); - inode_unlock(d_inode(root)); + simple_done_creating(dentry); binder_add_device(device); @@ -224,6 +211,9 @@ static int binderfs_binder_device_create(struct inode *ref_inode, /** * binder_ctl_ioctl - handle binder device node allocation requests + * @file: The file pointer for the binder-control device node. + * @cmd: The ioctl command. + * @arg: The ioctl argument. * * The request handler for the binder-control device. All requests operate on * the binderfs mount the binder-control device resides in: @@ -410,12 +400,6 @@ static int binderfs_binder_ctl_create(struct super_block *sb) if (!device) return -ENOMEM; - /* If we have already created a binder-control node, return. */ - if (info->control_dentry) { - ret = 0; - goto out; - } - ret = -ENOMEM; inode = new_inode(sb); if (!inode) @@ -451,7 +435,8 @@ static int binderfs_binder_ctl_create(struct super_block *sb) inode->i_private = device; info->control_dentry = dentry; - d_add(dentry, inode); + d_make_persistent(dentry, inode); + dput(dentry); return 0; @@ -481,24 +466,6 @@ static struct inode *binderfs_make_inode(struct super_block *sb, int mode) return ret; } -static struct dentry *binderfs_create_dentry(struct dentry *parent, - const char *name) -{ - struct dentry *dentry; - - dentry = lookup_noperm(&QSTR(name), parent); - if (IS_ERR(dentry)) - return dentry; - - /* Return error if the file/dir already exists. */ - if (d_really_is_positive(dentry)) { - dput(dentry); - return ERR_PTR(-EEXIST); - } - - return dentry; -} - struct dentry *binderfs_create_file(struct dentry *parent, const char *name, const struct file_operations *fops, void *data) @@ -508,28 +475,24 @@ struct dentry *binderfs_create_file(struct dentry *parent, const char *name, struct super_block *sb; parent_inode = d_inode(parent); - inode_lock(parent_inode); - dentry = binderfs_create_dentry(parent, name); + dentry = simple_start_creating(parent, name); if (IS_ERR(dentry)) - goto out; + return dentry; sb = parent_inode->i_sb; new_inode = binderfs_make_inode(sb, S_IFREG | 0444); if (!new_inode) { - dput(dentry); - dentry = ERR_PTR(-ENOMEM); - goto out; + simple_done_creating(dentry); + return ERR_PTR(-ENOMEM); } new_inode->i_fop = fops; new_inode->i_private = data; - d_instantiate(dentry, new_inode); + d_make_persistent(dentry, new_inode); fsnotify_create(parent_inode, dentry); - -out: - inode_unlock(parent_inode); - return dentry; + simple_done_creating(dentry); + return dentry; // borrowed } static struct dentry *binderfs_create_dir(struct dentry *parent, @@ -540,30 +503,26 @@ static struct dentry *binderfs_create_dir(struct dentry *parent, struct super_block *sb; parent_inode = d_inode(parent); - inode_lock(parent_inode); - dentry = binderfs_create_dentry(parent, name); + dentry = simple_start_creating(parent, name); if (IS_ERR(dentry)) - goto out; + return dentry; sb = parent_inode->i_sb; new_inode = binderfs_make_inode(sb, S_IFDIR | 0755); if (!new_inode) { - dput(dentry); - dentry = ERR_PTR(-ENOMEM); - goto out; + simple_done_creating(dentry); + return ERR_PTR(-ENOMEM); } new_inode->i_fop = &simple_dir_operations; new_inode->i_op = &simple_dir_inode_operations; set_nlink(new_inode, 2); - d_instantiate(dentry, new_inode); + d_make_persistent(dentry, new_inode); inc_nlink(parent_inode); fsnotify_mkdir(parent_inode, dentry); - -out: - inode_unlock(parent_inode); + simple_done_creating(dentry); return dentry; } @@ -779,7 +738,7 @@ static void binderfs_kill_super(struct super_block *sb) * During inode eviction struct binderfs_info is needed. * So first wipe the super_block then free struct binderfs_info. */ - kill_litter_super(sb); + kill_anon_super(sb); if (info && info->ipc_ns) put_ipc_ns(info->ipc_ns); diff --git a/drivers/android/tests/binder_alloc_kunit.c b/drivers/android/tests/binder_alloc_kunit.c index 9b884d977f765..7f9cc003bbe3b 100644 --- a/drivers/android/tests/binder_alloc_kunit.c +++ b/drivers/android/tests/binder_alloc_kunit.c @@ -554,7 +554,7 @@ static void binder_alloc_test_exit(struct kunit *test) static struct kunit_case binder_alloc_test_cases[] = { KUNIT_CASE(binder_alloc_test_init_freelist), KUNIT_CASE(binder_alloc_test_mmap), - KUNIT_CASE(binder_alloc_exhaustive_test), + KUNIT_CASE_SLOW(binder_alloc_exhaustive_test), {} }; diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index f2140fc06ba0f..15e18d50dcc6d 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -245,6 +245,73 @@ void ata_acpi_bind_dev(struct ata_device *dev) ata_acpi_dev_uevent); } +/** + * ata_acpi_dev_manage_restart - if the disk should be stopped (spun down) on + * system restart. + * @dev: target ATA device + * + * RETURNS: + * true if the disk should be stopped, otherwise false. + */ +bool ata_acpi_dev_manage_restart(struct ata_device *dev) +{ + struct device *tdev; + + /* + * If ATA_FLAG_ACPI_SATA is set, the acpi fwnode is attached to the + * ata_device instead of the ata_port. + */ + if (dev->link->ap->flags & ATA_FLAG_ACPI_SATA) + tdev = &dev->tdev; + else + tdev = &dev->link->ap->tdev; + + if (!is_acpi_device_node(tdev->fwnode)) + return false; + return acpi_bus_power_manageable(ACPI_HANDLE(tdev)); +} + +/** + * ata_acpi_port_power_on - set the power state of the ata port to D0 + * @ap: target ATA port + * + * This function is called at the beginning of ata_port_probe(). + */ +void ata_acpi_port_power_on(struct ata_port *ap) +{ + acpi_handle handle; + int i; + + /* + * If ATA_FLAG_ACPI_SATA is set, the acpi fwnode is attached to the + * ata_device instead of the ata_port. + */ + if (ap->flags & ATA_FLAG_ACPI_SATA) { + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->link.device[i]; + + if (!is_acpi_device_node(dev->tdev.fwnode)) + continue; + handle = ACPI_HANDLE(&dev->tdev); + if (!acpi_bus_power_manageable(handle)) + continue; + if (acpi_bus_set_power(handle, ACPI_STATE_D0)) + ata_dev_err(dev, + "acpi: failed to set power state to D0\n"); + } + return; + } + + if (!is_acpi_device_node(ap->tdev.fwnode)) + return; + handle = ACPI_HANDLE(&ap->tdev); + if (!acpi_bus_power_manageable(handle)) + return; + + if (acpi_bus_set_power(handle, ACPI_STATE_D0)) + ata_port_err(ap, "acpi: failed to set power state to D0\n"); +} + /** * ata_acpi_dissociate - dissociate ATA host from ACPI objects * @host: target ATA host diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f48fb63d7e854..09d8c035fcdf9 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3146,6 +3146,10 @@ int ata_dev_configure(struct ata_device *dev) dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_1024, dev->max_sectors); + if (dev->quirks & ATA_QUIRK_MAX_SEC_8191) + dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_8191, + dev->max_sectors); + if (dev->quirks & ATA_QUIRK_MAX_SEC_LBA48) dev->max_sectors = ATA_MAX_SECTORS_LBA48; @@ -3998,6 +4002,7 @@ static const char * const ata_quirk_names[] = { [__ATA_QUIRK_NO_DMA_LOG] = "nodmalog", [__ATA_QUIRK_NOTRIM] = "notrim", [__ATA_QUIRK_MAX_SEC_1024] = "maxsec1024", + [__ATA_QUIRK_MAX_SEC_8191] = "maxsec8191", [__ATA_QUIRK_MAX_TRIM_128M] = "maxtrim128m", [__ATA_QUIRK_NO_NCQ_ON_ATI] = "noncqonati", [__ATA_QUIRK_NO_LPM_ON_ATI] = "nolpmonati", @@ -4104,6 +4109,12 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { { "LITEON CX1-JB*-HP", NULL, ATA_QUIRK_MAX_SEC_1024 }, { "LITEON EP1-*", NULL, ATA_QUIRK_MAX_SEC_1024 }, + /* + * These devices time out with higher max sects. + * https://bugzilla.kernel.org/show_bug.cgi?id=220693 + */ + { "DELLBOSS VD", "MV.R00-0", ATA_QUIRK_MAX_SEC_8191 }, + /* Devices we expect to fail diagnostics */ /* Devices where NCQ should be avoided */ @@ -4132,6 +4143,9 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { { "ST3320[68]13AS", "SD1[5-9]", ATA_QUIRK_NONCQ | ATA_QUIRK_FIRMWARE_WARN }, + /* Seagate disks with LPM issues */ + { "ST2000DM008-2FR102", NULL, ATA_QUIRK_NOLPM }, + /* drives which fail FPDMA_AA activation (some may freeze afterwards) the ST disks also have LPM issues */ { "ST1000LM024 HN-M101MBB", NULL, ATA_QUIRK_BROKEN_FPDMA_AA | @@ -4216,6 +4230,10 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { /* Apacer models with LPM issues */ { "Apacer AS340*", NULL, ATA_QUIRK_NOLPM }, + /* Silicon Motion models with LPM issues */ + { "MD619HXCLDE3TC", "TCVAID", ATA_QUIRK_NOLPM }, + { "MD619GXCLDE3TC", "TCV35D", ATA_QUIRK_NOLPM }, + /* These specific Samsung models/firmware-revs do not handle LPM well */ { "SAMSUNG MZMPC128HBFU-000MV", "CXM14M1Q", ATA_QUIRK_NOLPM }, { "SAMSUNG SSD PM830 mSATA *", "CXM13D1Q", ATA_QUIRK_NOLPM }, @@ -5911,6 +5929,8 @@ void ata_port_probe(struct ata_port *ap) struct ata_eh_info *ehi = &ap->link.eh_info; unsigned long flags; + ata_acpi_port_power_on(ap); + /* kick EH for boot probing */ spin_lock_irqsave(ap->lock, flags); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 434774e71fe61..721d3f270c8ec 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1102,6 +1102,7 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct queue_limits *lim, */ sdev->manage_runtime_start_stop = 1; sdev->manage_shutdown = 1; + sdev->manage_restart = ata_acpi_dev_manage_restart(dev); sdev->force_runtime_start_on_system_start = 1; } diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 1e2a2c33cdc80..785b6e371abfb 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -3191,7 +3191,8 @@ void ata_sff_port_init(struct ata_port *ap) int __init ata_sff_init(void) { - ata_sff_wq = alloc_workqueue("ata_sff", WQ_MEM_RECLAIM, WQ_MAX_ACTIVE); + ata_sff_wq = alloc_workqueue("ata_sff", WQ_MEM_RECLAIM | WQ_PERCPU, + WQ_MAX_ACTIVE); if (!ata_sff_wq) return -ENOMEM; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index e5b977a8d3e1e..0e7ecac736809 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -130,6 +130,8 @@ extern void ata_acpi_on_disable(struct ata_device *dev); extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); extern void ata_acpi_bind_port(struct ata_port *ap); extern void ata_acpi_bind_dev(struct ata_device *dev); +extern void ata_acpi_port_power_on(struct ata_port *ap); +extern bool ata_acpi_dev_manage_restart(struct ata_device *dev); extern acpi_handle ata_dev_acpi_handle(struct ata_device *dev); #else static inline void ata_acpi_dissociate(struct ata_host *host) { } @@ -140,6 +142,8 @@ static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { } static inline void ata_acpi_bind_port(struct ata_port *ap) {} static inline void ata_acpi_bind_dev(struct ata_device *dev) {} +static inline void ata_acpi_port_power_on(struct ata_port *ap) {} +static inline bool ata_acpi_dev_manage_restart(struct ata_device *dev) { return 0; } #endif /* libata-scsi.c */ diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 042f6ad1f7c69..fc762dcc61bfd 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include @@ -632,9 +633,9 @@ static void it821x_display_disk(struct ata_port *ap, int n, u8 *buf) cbl = ""; if (mode) - snprintf(mbuf, 8, "%5s%d", mtype, mode - 1); + snprintf(mbuf, sizeof(mbuf), "%5s%d", mtype, mode - 1); else - strcpy(mbuf, "PIO"); + strscpy(mbuf, "PIO"); if (buf[52] == 4) ata_port_info(ap, "%d: %-6s %-8s %s %s\n", n, mbuf, types[buf[52]], id, cbl); diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index cf3810933a27c..caefcd8c4b3c1 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -344,6 +344,7 @@ static const struct pcmcia_device_id pcmcia_devices[] = { PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79), PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), + PCMCIA_DEVICE_PROD_ID2("PCMCIA ATA/ATAPI Adapter", 0x888d7b73), PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883), PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d), diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c index 8590a4cd21e06..4e22373fcc1a9 100644 --- a/drivers/auxdisplay/line-display.c +++ b/drivers/auxdisplay/line-display.c @@ -6,20 +6,23 @@ * Author: Paul Burton * * Copyright (C) 2021 Glider bv + * Copyright (C) 2025 Jean-François Lessard */ #ifndef CONFIG_PANEL_BOOT_MESSAGE #include #endif -#include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -31,6 +34,87 @@ #define DEFAULT_SCROLL_RATE (HZ / 2) +/** + * struct linedisp_attachment - Holds the device to linedisp mapping + * @list: List entry for the linedisp_attachments list + * @device: Pointer to the device where linedisp attributes are added + * @linedisp: Pointer to the linedisp mapped to the device + * @direct: true for directly attached device using linedisp_attach(), + * false for child registered device using linedisp_register() + */ +struct linedisp_attachment { + struct list_head list; + struct device *device; + struct linedisp *linedisp; + bool direct; +}; + +static LIST_HEAD(linedisp_attachments); +static DEFINE_SPINLOCK(linedisp_attachments_lock); + +static int create_attachment(struct device *dev, struct linedisp *linedisp, bool direct) +{ + struct linedisp_attachment *attachment; + + attachment = kzalloc(sizeof(*attachment), GFP_KERNEL); + if (!attachment) + return -ENOMEM; + + attachment->device = dev; + attachment->linedisp = linedisp; + attachment->direct = direct; + + guard(spinlock)(&linedisp_attachments_lock); + list_add(&attachment->list, &linedisp_attachments); + + return 0; +} + +static struct linedisp *delete_attachment(struct device *dev, bool direct) +{ + struct linedisp_attachment *attachment; + struct linedisp *linedisp; + + guard(spinlock)(&linedisp_attachments_lock); + + list_for_each_entry(attachment, &linedisp_attachments, list) { + if (attachment->device == dev && + attachment->direct == direct) + break; + } + + if (list_entry_is_head(attachment, &linedisp_attachments, list)) + return NULL; + + linedisp = attachment->linedisp; + list_del(&attachment->list); + kfree(attachment); + + return linedisp; +} + +static struct linedisp *to_linedisp(struct device *dev) +{ + struct linedisp_attachment *attachment; + + guard(spinlock)(&linedisp_attachments_lock); + + list_for_each_entry(attachment, &linedisp_attachments, list) { + if (attachment->device == dev) + break; + } + + if (list_entry_is_head(attachment, &linedisp_attachments, list)) + return NULL; + + return attachment->linedisp; +} + +static inline bool should_scroll(struct linedisp *linedisp) +{ + return linedisp->message_len > linedisp->num_chars && linedisp->scroll_rate; +} + /** * linedisp_scroll() - scroll the display by a character * @t: really a pointer to the private data structure @@ -62,8 +146,7 @@ static void linedisp_scroll(struct timer_list *t) linedisp->scroll_pos %= linedisp->message_len; /* rearm the timer */ - if (linedisp->message_len > num_chars && linedisp->scroll_rate) - mod_timer(&linedisp->timer, jiffies + linedisp->scroll_rate); + mod_timer(&linedisp->timer, jiffies + linedisp->scroll_rate); } /** @@ -113,8 +196,16 @@ static int linedisp_display(struct linedisp *linedisp, const char *msg, linedisp->message_len = count; linedisp->scroll_pos = 0; - /* update the display */ - linedisp_scroll(&linedisp->timer); + if (should_scroll(linedisp)) { + /* display scrolling message */ + linedisp_scroll(&linedisp->timer); + } else { + /* display static message */ + memset(linedisp->buf, ' ', linedisp->num_chars); + memcpy(linedisp->buf, linedisp->message, + umin(linedisp->num_chars, linedisp->message_len)); + linedisp->ops->update(linedisp); + } return 0; } @@ -133,7 +224,7 @@ static int linedisp_display(struct linedisp *linedisp, const char *msg, static ssize_t message_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct linedisp *linedisp = container_of(dev, struct linedisp, dev); + struct linedisp *linedisp = to_linedisp(dev); return sysfs_emit(buf, "%s\n", linedisp->message); } @@ -152,7 +243,7 @@ static ssize_t message_show(struct device *dev, struct device_attribute *attr, static ssize_t message_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct linedisp *linedisp = container_of(dev, struct linedisp, dev); + struct linedisp *linedisp = to_linedisp(dev); int err; err = linedisp_display(linedisp, buf, count); @@ -161,10 +252,20 @@ static ssize_t message_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RW(message); +static ssize_t num_chars_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct linedisp *linedisp = to_linedisp(dev); + + return sysfs_emit(buf, "%u\n", linedisp->num_chars); +} + +static DEVICE_ATTR_RO(num_chars); + static ssize_t scroll_step_ms_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct linedisp *linedisp = container_of(dev, struct linedisp, dev); + struct linedisp *linedisp = to_linedisp(dev); return sysfs_emit(buf, "%u\n", jiffies_to_msecs(linedisp->scroll_rate)); } @@ -173,7 +274,7 @@ static ssize_t scroll_step_ms_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct linedisp *linedisp = container_of(dev, struct linedisp, dev); + struct linedisp *linedisp = to_linedisp(dev); unsigned int ms; int err; @@ -181,12 +282,12 @@ static ssize_t scroll_step_ms_store(struct device *dev, if (err) return err; + timer_delete_sync(&linedisp->timer); + linedisp->scroll_rate = msecs_to_jiffies(ms); - if (linedisp->message && linedisp->message_len > linedisp->num_chars) { - timer_delete_sync(&linedisp->timer); - if (linedisp->scroll_rate) - linedisp_scroll(&linedisp->timer); - } + + if (should_scroll(linedisp)) + linedisp_scroll(&linedisp->timer); return count; } @@ -195,7 +296,7 @@ static DEVICE_ATTR_RW(scroll_step_ms); static ssize_t map_seg_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct linedisp *linedisp = container_of(dev, struct linedisp, dev); + struct linedisp *linedisp = to_linedisp(dev); struct linedisp_map *map = linedisp->map; memcpy(buf, &map->map, map->size); @@ -205,7 +306,7 @@ static ssize_t map_seg_show(struct device *dev, struct device_attribute *attr, c static ssize_t map_seg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct linedisp *linedisp = container_of(dev, struct linedisp, dev); + struct linedisp *linedisp = to_linedisp(dev); struct linedisp_map *map = linedisp->map; if (count != map->size) @@ -223,6 +324,7 @@ static DEVICE_ATTR(map_seg14, 0644, map_seg_show, map_seg_store); static struct attribute *linedisp_attrs[] = { &dev_attr_message.attr, + &dev_attr_num_chars.attr, &dev_attr_scroll_step_ms.attr, &dev_attr_map_seg7.attr, &dev_attr_map_seg14.attr, @@ -232,7 +334,7 @@ static struct attribute *linedisp_attrs[] = { static umode_t linedisp_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { struct device *dev = kobj_to_dev(kobj); - struct linedisp *linedisp = container_of(dev, struct linedisp, dev); + struct linedisp *linedisp = to_linedisp(dev); struct linedisp_map *map = linedisp->map; umode_t mode = attr->mode; @@ -263,7 +365,7 @@ static DEFINE_IDA(linedisp_id); static void linedisp_release(struct device *dev) { - struct linedisp *linedisp = container_of(dev, struct linedisp, dev); + struct linedisp *linedisp = to_linedisp(dev); kfree(linedisp->map); kfree(linedisp->message); @@ -320,6 +422,90 @@ static int linedisp_init_map(struct linedisp *linedisp) #define LINEDISP_INIT_TEXT "Linux " UTS_RELEASE " " #endif +/** + * linedisp_attach - attach a character line display + * @linedisp: pointer to character line display structure + * @dev: pointer of the device to attach to + * @num_chars: the number of characters that can be displayed + * @ops: character line display operations + * + * Directly attach the line-display sysfs attributes to the passed device. + * The caller is responsible for calling linedisp_detach() to release resources + * after use. + * + * Return: zero on success, else a negative error code. + */ +int linedisp_attach(struct linedisp *linedisp, struct device *dev, + unsigned int num_chars, const struct linedisp_ops *ops) +{ + int err; + + memset(linedisp, 0, sizeof(*linedisp)); + linedisp->ops = ops; + linedisp->num_chars = num_chars; + linedisp->scroll_rate = DEFAULT_SCROLL_RATE; + + linedisp->buf = kzalloc(linedisp->num_chars, GFP_KERNEL); + if (!linedisp->buf) + return -ENOMEM; + + /* initialise a character mapping, if required */ + err = linedisp_init_map(linedisp); + if (err) + goto out_free_buf; + + /* initialise a timer for scrolling the message */ + timer_setup(&linedisp->timer, linedisp_scroll, 0); + + err = create_attachment(dev, linedisp, true); + if (err) + goto out_del_timer; + + /* display a default message */ + err = linedisp_display(linedisp, LINEDISP_INIT_TEXT, -1); + if (err) + goto out_del_attach; + + /* add attribute groups to target device */ + err = device_add_groups(dev, linedisp_groups); + if (err) + goto out_del_attach; + + return 0; + +out_del_attach: + delete_attachment(dev, true); +out_del_timer: + timer_delete_sync(&linedisp->timer); +out_free_buf: + kfree(linedisp->buf); + return err; +} +EXPORT_SYMBOL_NS_GPL(linedisp_attach, "LINEDISP"); + +/** + * linedisp_detach - detach a character line display + * @dev: pointer of the device to detach from, that was previously + * attached with linedisp_attach() + */ +void linedisp_detach(struct device *dev) +{ + struct linedisp *linedisp; + + linedisp = delete_attachment(dev, true); + if (!linedisp) + return; + + timer_delete_sync(&linedisp->timer); + + device_remove_groups(dev, linedisp_groups); + + kfree(linedisp->map); + kfree(linedisp->message); + kfree(linedisp->buf); +} +EXPORT_SYMBOL_NS_GPL(linedisp_detach, "LINEDISP"); + /** * linedisp_register - register a character line display * @linedisp: pointer to character line display structure @@ -327,6 +513,11 @@ static int linedisp_init_map(struct linedisp *linedisp) * @num_chars: the number of characters that can be displayed * @ops: character line display operations * + * Register the line-display sysfs attributes to a new device named + * "linedisp.N" added to the passed parent device. + * The caller is responsible for calling linedisp_unregister() to release + * resources after use. + * * Return: zero on success, else a negative error code. */ int linedisp_register(struct linedisp *linedisp, struct device *parent, @@ -362,19 +553,23 @@ int linedisp_register(struct linedisp *linedisp, struct device *parent, /* initialise a timer for scrolling the message */ timer_setup(&linedisp->timer, linedisp_scroll, 0); - err = device_add(&linedisp->dev); + err = create_attachment(&linedisp->dev, linedisp, false); if (err) goto out_del_timer; /* display a default message */ err = linedisp_display(linedisp, LINEDISP_INIT_TEXT, -1); if (err) - goto out_del_dev; + goto out_del_attach; + + err = device_add(&linedisp->dev); + if (err) + goto out_del_attach; return 0; -out_del_dev: - device_del(&linedisp->dev); +out_del_attach: + delete_attachment(&linedisp->dev, false); out_del_timer: timer_delete_sync(&linedisp->timer); out_put_device: @@ -391,6 +586,7 @@ EXPORT_SYMBOL_NS_GPL(linedisp_register, "LINEDISP"); void linedisp_unregister(struct linedisp *linedisp) { device_del(&linedisp->dev); + delete_attachment(&linedisp->dev, false); timer_delete_sync(&linedisp->timer); put_device(&linedisp->dev); } diff --git a/drivers/auxdisplay/line-display.h b/drivers/auxdisplay/line-display.h index 4348d7a2f69ad..36853b6397115 100644 --- a/drivers/auxdisplay/line-display.h +++ b/drivers/auxdisplay/line-display.h @@ -6,6 +6,7 @@ * Author: Paul Burton * * Copyright (C) 2021 Glider bv + * Copyright (C) 2025 Jean-François Lessard */ #ifndef _LINEDISP_H @@ -81,6 +82,9 @@ struct linedisp { unsigned int id; }; +int linedisp_attach(struct linedisp *linedisp, struct device *dev, + unsigned int num_chars, const struct linedisp_ops *ops); +void linedisp_detach(struct device *dev); int linedisp_register(struct linedisp *linedisp, struct device *parent, unsigned int num_chars, const struct linedisp_ops *ops); void linedisp_unregister(struct linedisp *linedisp); diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index e1eff05bea4aa..84ec92bff642c 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -823,12 +823,106 @@ void remove_cpu_topology(unsigned int cpu) clear_cpu_topology(cpu); } +#if defined(CONFIG_ARM64) || defined(CONFIG_RISCV) +struct cpu_smt_info { + unsigned int thread_num; + int core_id; +}; + +static bool __init acpi_cpu_is_threaded(int cpu) +{ + int is_threaded = acpi_pptt_cpu_is_thread(cpu); + + /* + * if the PPTT doesn't have thread information, check for architecture + * specific fallback if available + */ + if (is_threaded < 0) + is_threaded = arch_cpu_is_threaded(); + + return !!is_threaded; +} + +/* + * Propagate the topology information of the processor_topology_node tree to the + * cpu_topology array. + */ __weak int __init parse_acpi_topology(void) { + unsigned int max_smt_thread_num = 1; + struct cpu_smt_info *entry; + struct xarray hetero_cpu; + unsigned long hetero_id; + int cpu, topology_id; + + if (acpi_disabled) + return 0; + + xa_init(&hetero_cpu); + + for_each_possible_cpu(cpu) { + topology_id = find_acpi_cpu_topology(cpu, 0); + if (topology_id < 0) + return topology_id; + + if (acpi_cpu_is_threaded(cpu)) { + cpu_topology[cpu].thread_id = topology_id; + topology_id = find_acpi_cpu_topology(cpu, 1); + cpu_topology[cpu].core_id = topology_id; + + /* + * In the PPTT, CPUs below a node with the 'identical + * implementation' flag have the same number of threads. + * Count the number of threads for only one CPU (i.e. + * one core_id) among those with the same hetero_id. + * See the comment of find_acpi_cpu_topology_hetero_id() + * for more details. + * + * One entry is created for each node having: + * - the 'identical implementation' flag + * - its parent not having the flag + */ + hetero_id = find_acpi_cpu_topology_hetero_id(cpu); + entry = xa_load(&hetero_cpu, hetero_id); + if (!entry) { + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + WARN_ON_ONCE(!entry); + + if (entry) { + entry->core_id = topology_id; + entry->thread_num = 1; + xa_store(&hetero_cpu, hetero_id, + entry, GFP_KERNEL); + } + } else if (entry->core_id == topology_id) { + entry->thread_num++; + } + } else { + cpu_topology[cpu].thread_id = -1; + cpu_topology[cpu].core_id = topology_id; + } + topology_id = find_acpi_cpu_topology_cluster(cpu); + cpu_topology[cpu].cluster_id = topology_id; + topology_id = find_acpi_cpu_topology_package(cpu); + cpu_topology[cpu].package_id = topology_id; + } + + /* + * This is a short loop since the number of XArray elements is the + * number of heterogeneous CPU clusters. On a homogeneous system + * there's only one entry in the XArray. + */ + xa_for_each(&hetero_cpu, hetero_id, entry) { + max_smt_thread_num = max(max_smt_thread_num, entry->thread_num); + xa_erase(&hetero_cpu, hetero_id); + kfree(entry); + } + + cpu_smt_set_num_threads(max_smt_thread_num, max_smt_thread_num); + xa_destroy(&hetero_cpu); return 0; } -#if defined(CONFIG_ARM64) || defined(CONFIG_RISCV) void __init init_cpu_topology(void) { int cpu, ret; diff --git a/drivers/base/base.h b/drivers/base/base.h index 86fa7fbb35489..430cbefbc97ff 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -85,6 +85,18 @@ struct driver_private { }; #define to_driver(obj) container_of(obj, struct driver_private, kobj) +#ifdef CONFIG_RUST +/** + * struct driver_type - Representation of a Rust driver type. + */ +struct driver_type { + /** + * @id: Representation of core::any::TypeId. + */ + u8 id[16]; +} __packed; +#endif + /** * struct device_private - structure to hold the private to the driver core portions of the device structure. * @@ -100,6 +112,7 @@ struct driver_private { * @async_driver - pointer to device driver awaiting probe via async_probe * @device - pointer back to the struct device that this structure is * associated with. + * @driver_type - The type of the bound Rust driver. * @dead - This device is currently either in the process of or has been * removed from the system. Any asynchronous events scheduled for this * device should exit without taking any action. @@ -116,6 +129,9 @@ struct device_private { const struct device_driver *async_driver; char *deferred_probe_reason; struct device *device; +#ifdef CONFIG_RUST + struct driver_type driver_type; +#endif u8 dead:1; }; #define to_device_private_parent(obj) \ diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 5e75e1bce5516..9eb7771706f01 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -334,6 +334,19 @@ static struct device *next_device(struct klist_iter *i) return dev; } +static struct device *prev_device(struct klist_iter *i) +{ + struct klist_node *n = klist_prev(i); + struct device *dev = NULL; + struct device_private *dev_prv; + + if (n) { + dev_prv = to_device_private_bus(n); + dev = dev_prv->device; + } + return dev; +} + /** * bus_for_each_dev - device iterator. * @bus: bus type. @@ -414,6 +427,31 @@ struct device *bus_find_device(const struct bus_type *bus, } EXPORT_SYMBOL_GPL(bus_find_device); +struct device *bus_find_device_reverse(const struct bus_type *bus, + struct device *start, const void *data, + device_match_t match) +{ + struct subsys_private *sp = bus_to_subsys(bus); + struct klist_iter i; + struct device *dev; + + if (!sp) + return NULL; + + klist_iter_init_node(&sp->klist_devices, &i, + (start ? &start->p->knode_bus : NULL)); + while ((dev = prev_device(&i))) { + if (match(dev, data)) { + get_device(dev); + break; + } + } + klist_iter_exit(&i); + subsys_put(sp); + return dev; +} +EXPORT_SYMBOL_GPL(bus_find_device_reverse); + static struct device_driver *next_driver(struct klist_iter *i) { struct klist_node *n = klist_next(i); @@ -533,8 +571,7 @@ void bus_probe_device(struct device *dev) if (!sp) return; - if (sp->drivers_autoprobe) - device_initial_probe(dev); + device_initial_probe(dev); mutex_lock(&sp->mutex); list_for_each_entry(sif, &sp->interfaces, node) diff --git a/drivers/base/core.c b/drivers/base/core.c index f69dc9c859545..40de2f51a1b1a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -4138,7 +4138,7 @@ int __init devices_init(void) 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); + device_link_wq = alloc_workqueue("device_link_wq", WQ_PERCPU, 0); if (!device_link_wq) goto wq_err; diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index fa0a2eef93ac8..c6c57b6f61c60 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -300,13 +300,30 @@ static ssize_t print_cpus_isolated(struct device *dev, } static DEVICE_ATTR(isolated, 0444, print_cpus_isolated, NULL); +static ssize_t housekeeping_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const struct cpumask *hk_mask; + + hk_mask = housekeeping_cpumask(HK_TYPE_KERNEL_NOISE); + + if (housekeeping_enabled(HK_TYPE_KERNEL_NOISE)) + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(hk_mask)); + return sysfs_emit(buf, "\n"); +} +static DEVICE_ATTR_RO(housekeeping); + #ifdef CONFIG_NO_HZ_FULL -static ssize_t print_cpus_nohz_full(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t nohz_full_show(struct device *dev, + struct device_attribute *attr, + char *buf) { - return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask)); + if (cpumask_available(tick_nohz_full_mask)) + return sysfs_emit(buf, "%*pbl\n", + cpumask_pr_args(tick_nohz_full_mask)); + return sysfs_emit(buf, "\n"); } -static DEVICE_ATTR(nohz_full, 0444, print_cpus_nohz_full, NULL); +static DEVICE_ATTR_RO(nohz_full); #endif #ifdef CONFIG_CRASH_HOTPLUG @@ -505,6 +522,7 @@ static struct attribute *cpu_root_attrs[] = { &dev_attr_offline.attr, &dev_attr_enabled.attr, &dev_attr_isolated.attr, + &dev_attr_housekeeping.attr, #ifdef CONFIG_NO_HZ_FULL &dev_attr_nohz_full.attr, #endif diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 13ab98e033eaa..349f31bedfa17 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -193,7 +193,7 @@ void driver_deferred_probe_trigger(void) * Kick the re-probe thread. It may already be scheduled, but it is * safe to kick it again. */ - queue_work(system_unbound_wq, &deferred_probe_work); + queue_work(system_dfl_wq, &deferred_probe_work); } /** @@ -1077,7 +1077,15 @@ EXPORT_SYMBOL_GPL(device_attach); void device_initial_probe(struct device *dev) { - __device_attach(dev, true); + struct subsys_private *sp = bus_to_subsys(dev->bus); + + if (!sp) + return; + + if (sp->drivers_autoprobe) + __device_attach(dev, true); + + subsys_put(sp); } /* diff --git a/drivers/base/devres.c b/drivers/base/devres.c index c948c88d39560..f54db6d138aba 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -1222,13 +1222,6 @@ static void devm_percpu_release(struct device *dev, void *pdata) free_percpu(p); } -static int devm_percpu_match(struct device *dev, void *data, void *p) -{ - struct devres *devr = container_of(data, struct devres, data); - - return *(void **)devr->data == p; -} - /** * __devm_alloc_percpu - Resource-managed alloc_percpu * @dev: Device to allocate per-cpu memory for @@ -1264,21 +1257,3 @@ void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, return pcpu; } EXPORT_SYMBOL_GPL(__devm_alloc_percpu); - -/** - * devm_free_percpu - Resource-managed free_percpu - * @dev: Device this memory belongs to - * @pdata: Per-cpu memory to free - * - * Free memory allocated with devm_alloc_percpu(). - */ -void devm_free_percpu(struct device *dev, void __percpu *pdata) -{ - /* - * Use devres_release() to prevent memory leakage as - * devm_free_pages() does. - */ - WARN_ON(devres_release(dev, devm_percpu_release, devm_percpu_match, - (void *)(__force unsigned long)pdata)); -} -EXPORT_SYMBOL_GPL(devm_free_percpu); diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 2f576ecf18324..194b44075ac72 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -70,7 +70,7 @@ static struct file_system_type internal_fs_type = { #else .init_fs_context = ramfs_init_fs_context, #endif - .kill_sb = kill_litter_super, + .kill_sb = kill_anon_super, }; /* Simply take a ref on the existing mount */ diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig index 752b9a9bea038..15eff8a4b5053 100644 --- a/drivers/base/firmware_loader/Kconfig +++ b/drivers/base/firmware_loader/Kconfig @@ -38,7 +38,7 @@ config FW_LOADER_DEBUG config RUST_FW_LOADER_ABSTRACTIONS bool "Rust Firmware Loader abstractions" depends on RUST - depends on FW_LOADER=y + select FW_LOADER help This enables the Rust abstractions for the firmware loader API. diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index bee3050a20d9e..4ebdca9e4da47 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -1576,16 +1576,20 @@ static int fw_pm_notify(struct notifier_block *notify_block, } /* stop caching firmware once syscore_suspend is reached */ -static int fw_suspend(void) +static int fw_suspend(void *data) { fw_cache.state = FW_LOADER_NO_CACHE; return 0; } -static struct syscore_ops fw_syscore_ops = { +static const struct syscore_ops fw_syscore_ops = { .suspend = fw_suspend, }; +static struct syscore fw_syscore = { + .ops = &fw_syscore_ops, +}; + static int __init register_fw_pm_ops(void) { int ret; @@ -1601,14 +1605,14 @@ static int __init register_fw_pm_ops(void) if (ret) return ret; - register_syscore_ops(&fw_syscore_ops); + register_syscore(&fw_syscore); return ret; } static inline void unregister_fw_pm_ops(void) { - unregister_syscore_ops(&fw_syscore_ops); + unregister_syscore(&fw_syscore); unregister_pm_notifier(&fw_cache.pm_notify); } #else diff --git a/drivers/base/firmware_loader/sysfs.c b/drivers/base/firmware_loader/sysfs.c index add0b9b75eddc..92e91050f96ab 100644 --- a/drivers/base/firmware_loader/sysfs.c +++ b/drivers/base/firmware_loader/sysfs.c @@ -47,7 +47,10 @@ static ssize_t timeout_show(const struct class *class, const struct class_attrib static ssize_t timeout_store(const struct class *class, const struct class_attribute *attr, const char *buf, size_t count) { - int tmp_loading_timeout = simple_strtol(buf, NULL, 10); + int tmp_loading_timeout; + + if (kstrtoint(buf, 10, &tmp_loading_timeout)) + return -EINVAL; if (tmp_loading_timeout < 0) tmp_loading_timeout = 0; @@ -157,7 +160,10 @@ static ssize_t firmware_loading_store(struct device *dev, struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); struct fw_priv *fw_priv; ssize_t written = count; - int loading = simple_strtol(buf, NULL, 10); + int loading; + + if (kstrtoint(buf, 10, &loading)) + return -EINVAL; mutex_lock(&fw_lock); fw_priv = fw_sysfs->fw_priv; diff --git a/drivers/base/firmware_loader/sysfs_upload.c b/drivers/base/firmware_loader/sysfs_upload.c index 829270067d163..c3797b93c5f5a 100644 --- a/drivers/base/firmware_loader/sysfs_upload.c +++ b/drivers/base/firmware_loader/sysfs_upload.c @@ -100,8 +100,10 @@ static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, return -EINVAL; mutex_lock(&fwlp->lock); - if (fwlp->progress == FW_UPLOAD_PROG_IDLE) - ret = -ENODEV; + if (fwlp->progress == FW_UPLOAD_PROG_IDLE) { + mutex_unlock(&fwlp->lock); + return -ENODEV; + } fwlp->ops->cancel(fwlp->fw_upload); mutex_unlock(&fwlp->lock); diff --git a/drivers/base/memory.c b/drivers/base/memory.c index fc43f2703ae0a..751f248ca4a85 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -198,15 +198,15 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr, break; default: WARN_ON(1); - return sysfs_emit(buf, "ERROR-UNKNOWN-%ld\n", mem->state); + return sysfs_emit(buf, "ERROR-UNKNOWN-%d\n", mem->state); } return sysfs_emit(buf, "%s\n", output); } -int memory_notify(unsigned long val, void *v) +int memory_notify(enum memory_block_state state, void *v) { - return blocking_notifier_call_chain(&memory_chain, val, v); + return blocking_notifier_call_chain(&memory_chain, state, v); } #if defined(CONFIG_MEMORY_FAILURE) && defined(CONFIG_MEMORY_HOTPLUG) diff --git a/drivers/base/node.c b/drivers/base/node.c index 83aeb0518e1da..00cf4532f121e 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -676,50 +676,6 @@ static void node_device_release(struct device *dev) kfree(to_node(dev)); } -/* - * register_node - Setup a sysfs device for a node. - * @num - Node number to use when creating the device. - * - * Initialize and register the node device. - */ -static int register_node(struct node *node, int num) -{ - int error; - - node->dev.id = num; - node->dev.bus = &node_subsys; - node->dev.release = node_device_release; - node->dev.groups = node_dev_groups; - error = device_register(&node->dev); - - if (error) { - put_device(&node->dev); - } else { - hugetlb_register_node(node); - compaction_register_node(node); - reclaim_register_node(node); - } - - return error; -} - -/** - * unregister_node - unregister a node device - * @node: node going away - * - * Unregisters a node device @node. All the devices on the node must be - * unregistered before calling this function. - */ -void unregister_node(struct node *node) -{ - hugetlb_unregister_node(node); - compaction_unregister_node(node); - reclaim_unregister_node(node); - node_remove_accesses(node); - node_remove_caches(node); - device_unregister(&node->dev); -} - struct node *node_devices[MAX_NUMNODES]; /* @@ -907,7 +863,13 @@ void register_memory_blocks_under_node_hotplug(int nid, unsigned long start_pfn, } #endif /* CONFIG_MEMORY_HOTPLUG */ -int register_one_node(int nid) +/** + * register_node - Initialize and register the node device. + * @nid: Node number to use when creating the device. + * + * Return: 0 on success, -errno otherwise + */ +int register_node(int nid) { int error; int cpu; @@ -918,14 +880,23 @@ int register_one_node(int nid) return -ENOMEM; INIT_LIST_HEAD(&node->access_list); - node_devices[nid] = node; - error = register_node(node_devices[nid], nid); + node->dev.id = nid; + node->dev.bus = &node_subsys; + node->dev.release = node_device_release; + node->dev.groups = node_dev_groups; + + error = device_register(&node->dev); if (error) { - node_devices[nid] = NULL; + put_device(&node->dev); return error; } + node_devices[nid] = node; + hugetlb_register_node(node); + compaction_register_node(node); + reclaim_register_node(node); + /* link cpu under this node */ for_each_present_cpu(cpu) { if (cpu_to_node(cpu) == nid) @@ -936,13 +907,26 @@ int register_one_node(int nid) return error; } - -void unregister_one_node(int nid) +/** + * unregister_node - unregister a node device + * @nid: nid of the node going away + * + * Unregisters the node device at node id @nid. All the devices on the + * node must be unregistered before calling this function. + */ +void unregister_node(int nid) { - if (!node_devices[nid]) + struct node *node = node_devices[nid]; + + if (!node) return; - unregister_node(node_devices[nid]); + hugetlb_unregister_node(node); + compaction_unregister_node(node); + reclaim_unregister_node(node); + node_remove_accesses(node); + node_remove_caches(node); + device_unregister(&node->dev); node_devices[nid] = NULL; } @@ -1018,7 +1002,7 @@ void __init node_dev_init(void) * to already created cpu devices. */ for_each_online_node(i) { - ret = register_one_node(i); + ret = register_node(i); if (ret) panic("%s() failed to add node: %d\n", __func__, ret); } diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index a0225a83f50cd..97a8b4fcf4718 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -2148,6 +2148,7 @@ static int device_prepare(struct device *dev, pm_message_t state) device_lock(dev); dev->power.wakeup_path = false; + dev->power.out_band_wakeup = false; if (dev->power.no_pm_callbacks) goto unlock; diff --git a/drivers/base/power/runtime-test.c b/drivers/base/power/runtime-test.c index 477feca804c7c..1535ad2b02649 100644 --- a/drivers/base/power/runtime-test.c +++ b/drivers/base/power/runtime-test.c @@ -37,10 +37,6 @@ static void pm_runtime_already_suspended_test(struct kunit *test) pm_runtime_enable(dev); KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); - pm_runtime_get_noresume(dev); - KUNIT_EXPECT_EQ(test, 0, pm_runtime_barrier(dev)); /* no wakeup needed */ - pm_runtime_put(dev); - pm_runtime_get_noresume(dev); KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync(dev)); @@ -174,7 +170,7 @@ static void pm_runtime_error_test(struct kunit *test) KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); KUNIT_EXPECT_EQ(test, 0, pm_runtime_get(dev)); - KUNIT_EXPECT_EQ(test, 1, pm_runtime_barrier(dev)); /* resume was pending */ + pm_runtime_barrier(dev); pm_runtime_put(dev); pm_runtime_suspend(dev); /* flush the put(), to suspend */ KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); @@ -225,7 +221,7 @@ static void pm_runtime_probe_active_test(struct kunit *test) KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); /* Nothing to flush. We stay active. */ - KUNIT_EXPECT_EQ(test, 0, pm_runtime_barrier(dev)); + pm_runtime_barrier(dev); KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); /* Ask for idle? Now we suspend. */ diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 62707738caa4f..0ee8ea971aa46 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1467,30 +1467,20 @@ static void __pm_runtime_barrier(struct device *dev) * Next, make sure that all pending requests for the device have been flushed * from pm_wq and wait for all runtime PM operations involving the device in * progress to complete. - * - * Return value: - * 1, if there was a resume request pending and the device had to be woken up, - * 0, otherwise */ -int pm_runtime_barrier(struct device *dev) +void pm_runtime_barrier(struct device *dev) { - int retval = 0; - pm_runtime_get_noresume(dev); spin_lock_irq(&dev->power.lock); if (dev->power.request_pending - && dev->power.request == RPM_REQ_RESUME) { + && dev->power.request == RPM_REQ_RESUME) rpm_resume(dev, 0); - retval = 1; - } __pm_runtime_barrier(dev); spin_unlock_irq(&dev->power.lock); pm_runtime_put_noidle(dev); - - return retval; } EXPORT_SYMBOL_GPL(pm_runtime_barrier); @@ -1878,16 +1868,18 @@ void pm_runtime_init(struct device *dev) */ void pm_runtime_reinit(struct device *dev) { - if (!pm_runtime_enabled(dev)) { - if (dev->power.runtime_status == RPM_ACTIVE) - pm_runtime_set_suspended(dev); - if (dev->power.irq_safe) { - spin_lock_irq(&dev->power.lock); - dev->power.irq_safe = 0; - spin_unlock_irq(&dev->power.lock); - if (dev->parent) - pm_runtime_put(dev->parent); - } + if (pm_runtime_enabled(dev)) + return; + + if (dev->power.runtime_status == RPM_ACTIVE) + pm_runtime_set_suspended(dev); + + if (dev->power.irq_safe) { + spin_lock_irq(&dev->power.lock); + dev->power.irq_safe = 0; + spin_unlock_irq(&dev->power.lock); + if (dev->parent) + pm_runtime_put(dev->parent); } /* * Clear power.needs_force_resume in case it has been set by diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 6f31240ee4a9a..1477329410ec4 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -186,6 +186,7 @@ struct regcache_ops { enum regcache_type type; int (*init)(struct regmap *map); int (*exit)(struct regmap *map); + int (*populate)(struct regmap *map); #ifdef CONFIG_DEBUG_FS void (*debugfs_init)(struct regmap *map); #endif @@ -288,6 +289,7 @@ enum regmap_endian regmap_get_val_endian(struct device *dev, const struct regmap_bus *bus, const struct regmap_config *config); +extern struct regcache_ops regcache_flat_sparse_ops; extern struct regcache_ops regcache_rbtree_ops; extern struct regcache_ops regcache_maple_ops; extern struct regcache_ops regcache_flat_ops; diff --git a/drivers/base/regmap/regcache-flat.c b/drivers/base/regmap/regcache-flat.c index f36d3618b67c1..53cc59c84e2f0 100644 --- a/drivers/base/regmap/regcache-flat.c +++ b/drivers/base/regmap/regcache-flat.c @@ -6,7 +6,11 @@ // // Author: Mark Brown +#include +#include #include +#include +#include #include #include @@ -18,46 +22,92 @@ static inline unsigned int regcache_flat_get_index(const struct regmap *map, return regcache_get_index_by_order(map, reg); } +struct regcache_flat_data { + unsigned long *valid; + unsigned int data[]; +}; + static int regcache_flat_init(struct regmap *map) { - int i; - unsigned int *cache; + unsigned int cache_size; + struct regcache_flat_data *cache; if (!map || map->reg_stride_order < 0 || !map->max_register_is_set) return -EINVAL; - map->cache = kcalloc(regcache_flat_get_index(map, map->max_register) - + 1, sizeof(unsigned int), map->alloc_flags); - if (!map->cache) + cache_size = regcache_flat_get_index(map, map->max_register) + 1; + cache = kzalloc(struct_size(cache, data, cache_size), map->alloc_flags); + if (!cache) return -ENOMEM; - cache = map->cache; + cache->valid = bitmap_zalloc(cache_size, map->alloc_flags); + if (!cache->valid) + goto err_free; + + map->cache = cache; + + return 0; + +err_free: + kfree(cache); + return -ENOMEM; +} + +static int regcache_flat_exit(struct regmap *map) +{ + struct regcache_flat_data *cache = map->cache; + + if (cache) + bitmap_free(cache->valid); + + kfree(cache); + map->cache = NULL; + + return 0; +} + +static int regcache_flat_populate(struct regmap *map) +{ + struct regcache_flat_data *cache = map->cache; + unsigned int i; for (i = 0; i < map->num_reg_defaults; i++) { unsigned int reg = map->reg_defaults[i].reg; unsigned int index = regcache_flat_get_index(map, reg); - cache[index] = map->reg_defaults[i].def; + cache->data[index] = map->reg_defaults[i].def; + __set_bit(index, cache->valid); } return 0; } -static int regcache_flat_exit(struct regmap *map) +static int regcache_flat_read(struct regmap *map, + unsigned int reg, unsigned int *value) { - kfree(map->cache); - map->cache = NULL; + struct regcache_flat_data *cache = map->cache; + unsigned int index = regcache_flat_get_index(map, reg); + + /* legacy behavior: ignore validity, but warn the user */ + if (unlikely(!test_bit(index, cache->valid))) + dev_warn_once(map->dev, + "using zero-initialized flat cache, this may cause unexpected behavior"); + + *value = cache->data[index]; return 0; } -static int regcache_flat_read(struct regmap *map, - unsigned int reg, unsigned int *value) +static int regcache_flat_sparse_read(struct regmap *map, + unsigned int reg, unsigned int *value) { - unsigned int *cache = map->cache; + struct regcache_flat_data *cache = map->cache; unsigned int index = regcache_flat_get_index(map, reg); - *value = cache[index]; + if (unlikely(!test_bit(index, cache->valid))) + return -ENOENT; + + *value = cache->data[index]; return 0; } @@ -65,10 +115,23 @@ static int regcache_flat_read(struct regmap *map, static int regcache_flat_write(struct regmap *map, unsigned int reg, unsigned int value) { - unsigned int *cache = map->cache; + struct regcache_flat_data *cache = map->cache; unsigned int index = regcache_flat_get_index(map, reg); - cache[index] = value; + cache->data[index] = value; + __set_bit(index, cache->valid); + + return 0; +} + +static int regcache_flat_drop(struct regmap *map, unsigned int min, + unsigned int max) +{ + struct regcache_flat_data *cache = map->cache; + unsigned int bitmap_min = regcache_flat_get_index(map, min); + unsigned int bitmap_max = regcache_flat_get_index(map, max); + + bitmap_clear(cache->valid, bitmap_min, bitmap_max + 1 - bitmap_min); return 0; } @@ -78,6 +141,18 @@ struct regcache_ops regcache_flat_ops = { .name = "flat", .init = regcache_flat_init, .exit = regcache_flat_exit, + .populate = regcache_flat_populate, .read = regcache_flat_read, .write = regcache_flat_write, }; + +struct regcache_ops regcache_flat_sparse_ops = { + .type = REGCACHE_FLAT_S, + .name = "flat-sparse", + .init = regcache_flat_init, + .exit = regcache_flat_exit, + .populate = regcache_flat_populate, + .read = regcache_flat_sparse_read, + .write = regcache_flat_write, + .drop = regcache_flat_drop, +}; diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c index 2319c30283a6d..ca1c72b68f313 100644 --- a/drivers/base/regmap/regcache-maple.c +++ b/drivers/base/regmap/regcache-maple.c @@ -289,6 +289,23 @@ static int regcache_maple_sync(struct regmap *map, unsigned int min, return ret; } +static int regcache_maple_init(struct regmap *map) +{ + struct maple_tree *mt; + + mt = kmalloc(sizeof(*mt), map->alloc_flags); + if (!mt) + return -ENOMEM; + map->cache = mt; + + mt_init(mt); + + if (!mt_external_lock(mt) && map->lock_key) + lockdep_set_class_and_subclass(&mt->ma_lock, map->lock_key, 1); + + return 0; +} + static int regcache_maple_exit(struct regmap *map) { struct maple_tree *mt = map->cache; @@ -340,26 +357,12 @@ static int regcache_maple_insert_block(struct regmap *map, int first, return ret; } -static int regcache_maple_init(struct regmap *map) +static int regcache_maple_populate(struct regmap *map) { - struct maple_tree *mt; int i; int ret; int range_start; - mt = kmalloc(sizeof(*mt), map->alloc_flags); - if (!mt) - return -ENOMEM; - map->cache = mt; - - mt_init(mt); - - if (!mt_external_lock(mt) && map->lock_key) - lockdep_set_class_and_subclass(&mt->ma_lock, map->lock_key, 1); - - if (!map->num_reg_defaults) - return 0; - range_start = 0; /* Scan for ranges of contiguous registers */ @@ -369,23 +372,14 @@ static int regcache_maple_init(struct regmap *map) ret = regcache_maple_insert_block(map, range_start, i - 1); if (ret != 0) - goto err; + return ret; range_start = i; } } /* Add the last block */ - ret = regcache_maple_insert_block(map, range_start, - map->num_reg_defaults - 1); - if (ret != 0) - goto err; - - return 0; - -err: - regcache_maple_exit(map); - return ret; + return regcache_maple_insert_block(map, range_start, map->num_reg_defaults - 1); } struct regcache_ops regcache_maple_ops = { @@ -393,6 +387,7 @@ struct regcache_ops regcache_maple_ops = { .name = "maple", .init = regcache_maple_init, .exit = regcache_maple_exit, + .populate = regcache_maple_populate, .read = regcache_maple_read, .write = regcache_maple_write, .drop = regcache_maple_drop, diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index a9d17f316e55c..3344b82c3799c 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -184,8 +184,6 @@ static void rbtree_debugfs_init(struct regmap *map) static int regcache_rbtree_init(struct regmap *map) { struct regcache_rbtree_ctx *rbtree_ctx; - int i; - int ret; map->cache = kmalloc(sizeof *rbtree_ctx, map->alloc_flags); if (!map->cache) @@ -195,19 +193,7 @@ static int regcache_rbtree_init(struct regmap *map) rbtree_ctx->root = RB_ROOT; rbtree_ctx->cached_rbnode = NULL; - for (i = 0; i < map->num_reg_defaults; i++) { - ret = regcache_rbtree_write(map, - map->reg_defaults[i].reg, - map->reg_defaults[i].def); - if (ret) - goto err; - } - return 0; - -err: - regcache_rbtree_exit(map); - return ret; } static int regcache_rbtree_exit(struct regmap *map) @@ -239,6 +225,22 @@ static int regcache_rbtree_exit(struct regmap *map) return 0; } +static int regcache_rbtree_populate(struct regmap *map) +{ + unsigned int i; + int ret; + + for (i = 0; i < map->num_reg_defaults; i++) { + ret = regcache_rbtree_write(map, + map->reg_defaults[i].reg, + map->reg_defaults[i].def); + if (ret) + return ret; + } + + return 0; +} + static int regcache_rbtree_read(struct regmap *map, unsigned int reg, unsigned int *value) { @@ -546,6 +548,7 @@ struct regcache_ops regcache_rbtree_ops = { .name = "rbtree", .init = regcache_rbtree_init, .exit = regcache_rbtree_exit, + .populate = regcache_rbtree_populate, #ifdef CONFIG_DEBUG_FS .debugfs_init = rbtree_debugfs_init, #endif diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index c7650fa434add..319c342bf5a06 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -16,6 +16,7 @@ #include "internal.h" static const struct regcache_ops *cache_types[] = { + ®cache_flat_sparse_ops, ®cache_rbtree_ops, ®cache_maple_ops, ®cache_flat_ops, @@ -221,8 +222,24 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) if (ret) goto err_free; } + + if (map->num_reg_defaults && map->cache_ops->populate) { + dev_dbg(map->dev, "Populating %s cache\n", map->cache_ops->name); + map->lock(map->lock_arg); + ret = map->cache_ops->populate(map); + map->unlock(map->lock_arg); + if (ret) + goto err_exit; + } return 0; +err_exit: + if (map->cache_ops->exit) { + dev_dbg(map->dev, "Destroying %s cache\n", map->cache_ops->name); + map->lock(map->lock_arg); + ret = map->cache_ops->exit(map); + map->unlock(map->lock_arg); + } err_free: kfree(map->reg_defaults); if (map->cache_free) diff --git a/drivers/base/regmap/regmap-i3c.c b/drivers/base/regmap/regmap-i3c.c index b5300b7c477e4..863b348704dcc 100644 --- a/drivers/base/regmap/regmap-i3c.c +++ b/drivers/base/regmap/regmap-i3c.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2018 Synopsys, Inc. and/or its affiliates. +#include #include #include #include @@ -10,7 +11,7 @@ static int regmap_i3c_write(void *context, const void *data, size_t count) { struct device *dev = context; struct i3c_device *i3c = dev_to_i3cdev(dev); - struct i3c_priv_xfer xfers[] = { + struct i3c_xfer xfers[] = { { .rnw = false, .len = count, @@ -18,7 +19,7 @@ static int regmap_i3c_write(void *context, const void *data, size_t count) }, }; - return i3c_device_do_priv_xfers(i3c, xfers, 1); + return i3c_device_do_xfers(i3c, xfers, ARRAY_SIZE(xfers), I3C_SDR); } static int regmap_i3c_read(void *context, @@ -27,7 +28,7 @@ static int regmap_i3c_read(void *context, { struct device *dev = context; struct i3c_device *i3c = dev_to_i3cdev(dev); - struct i3c_priv_xfer xfers[2]; + struct i3c_xfer xfers[2]; xfers[0].rnw = false; xfers[0].len = reg_size; @@ -37,7 +38,7 @@ static int regmap_i3c_read(void *context, xfers[1].len = val_size; xfers[1].data.in = val; - return i3c_device_do_priv_xfers(i3c, xfers, 2); + return i3c_device_do_xfers(i3c, xfers, ARRAY_SIZE(xfers), I3C_SDR); } static const struct regmap_bus regmap_i3c = { diff --git a/drivers/base/regmap/regmap-kunit.c b/drivers/base/regmap/regmap-kunit.c index 95c5bf2a78eeb..f6fc5ed016da1 100644 --- a/drivers/base/regmap/regmap-kunit.c +++ b/drivers/base/regmap/regmap-kunit.c @@ -54,6 +54,8 @@ static const char *regcache_type_name(enum regcache_type type) return "none"; case REGCACHE_FLAT: return "flat"; + case REGCACHE_FLAT_S: + return "flat-sparse"; case REGCACHE_RBTREE: return "rbtree"; case REGCACHE_MAPLE: @@ -93,6 +95,8 @@ static const struct regmap_test_param regcache_types_list[] = { { .cache = REGCACHE_NONE, .fast_io = true }, { .cache = REGCACHE_FLAT }, { .cache = REGCACHE_FLAT, .fast_io = true }, + { .cache = REGCACHE_FLAT_S }, + { .cache = REGCACHE_FLAT_S, .fast_io = true }, { .cache = REGCACHE_RBTREE }, { .cache = REGCACHE_RBTREE, .fast_io = true }, { .cache = REGCACHE_MAPLE }, @@ -104,6 +108,8 @@ KUNIT_ARRAY_PARAM(regcache_types, regcache_types_list, param_to_desc); static const struct regmap_test_param real_cache_types_only_list[] = { { .cache = REGCACHE_FLAT }, { .cache = REGCACHE_FLAT, .fast_io = true }, + { .cache = REGCACHE_FLAT_S }, + { .cache = REGCACHE_FLAT_S, .fast_io = true }, { .cache = REGCACHE_RBTREE }, { .cache = REGCACHE_RBTREE, .fast_io = true }, { .cache = REGCACHE_MAPLE }, @@ -119,6 +125,12 @@ static const struct regmap_test_param real_cache_types_list[] = { { .cache = REGCACHE_FLAT, .from_reg = 0x2002 }, { .cache = REGCACHE_FLAT, .from_reg = 0x2003 }, { .cache = REGCACHE_FLAT, .from_reg = 0x2004 }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0 }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0, .fast_io = true }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0x2001 }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0x2002 }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0x2003 }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0x2004 }, { .cache = REGCACHE_RBTREE, .from_reg = 0 }, { .cache = REGCACHE_RBTREE, .from_reg = 0, .fast_io = true }, { .cache = REGCACHE_RBTREE, .from_reg = 0x2001 }, @@ -136,6 +148,12 @@ static const struct regmap_test_param real_cache_types_list[] = { KUNIT_ARRAY_PARAM(real_cache_types, real_cache_types_list, param_to_desc); static const struct regmap_test_param sparse_cache_types_list[] = { + { .cache = REGCACHE_FLAT_S, .from_reg = 0 }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0, .fast_io = true }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0x2001 }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0x2002 }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0x2003 }, + { .cache = REGCACHE_FLAT_S, .from_reg = 0x2004 }, { .cache = REGCACHE_RBTREE, .from_reg = 0 }, { .cache = REGCACHE_RBTREE, .from_reg = 0, .fast_io = true }, { .cache = REGCACHE_RBTREE, .from_reg = 0x2001 }, @@ -1597,6 +1615,8 @@ static const struct regmap_test_param raw_types_list[] = { { .cache = REGCACHE_NONE, .val_endian = REGMAP_ENDIAN_BIG }, { .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_LITTLE }, { .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_BIG }, + { .cache = REGCACHE_FLAT_S, .val_endian = REGMAP_ENDIAN_LITTLE }, + { .cache = REGCACHE_FLAT_S, .val_endian = REGMAP_ENDIAN_BIG }, { .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_LITTLE }, { .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_BIG }, { .cache = REGCACHE_MAPLE, .val_endian = REGMAP_ENDIAN_LITTLE }, @@ -1608,6 +1628,8 @@ KUNIT_ARRAY_PARAM(raw_test_types, raw_types_list, param_to_desc); static const struct regmap_test_param raw_cache_types_list[] = { { .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_LITTLE }, { .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_BIG }, + { .cache = REGCACHE_FLAT_S, .val_endian = REGMAP_ENDIAN_LITTLE }, + { .cache = REGCACHE_FLAT_S, .val_endian = REGMAP_ENDIAN_BIG }, { .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_LITTLE }, { .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_BIG }, { .cache = REGCACHE_MAPLE, .val_endian = REGMAP_ENDIAN_LITTLE }, diff --git a/drivers/base/regmap/regmap-sdw-mbq.c b/drivers/base/regmap/regmap-sdw-mbq.c index 86644bbd07100..6a61629f5f895 100644 --- a/drivers/base/regmap/regmap-sdw-mbq.c +++ b/drivers/base/regmap/regmap-sdw-mbq.c @@ -15,11 +15,13 @@ struct regmap_mbq_context { struct device *dev; + struct sdw_slave *sdw; + + bool (*readable_reg)(struct device *dev, unsigned int reg); struct regmap_sdw_mbq_cfg cfg; int val_size; - bool (*readable_reg)(struct device *dev, unsigned int reg); }; static int regmap_sdw_mbq_size(struct regmap_mbq_context *ctx, unsigned int reg) @@ -46,7 +48,7 @@ static bool regmap_sdw_mbq_deferrable(struct regmap_mbq_context *ctx, unsigned i static int regmap_sdw_mbq_poll_busy(struct sdw_slave *slave, unsigned int reg, struct regmap_mbq_context *ctx) { - struct device *dev = &slave->dev; + struct device *dev = ctx->dev; int val, ret = 0; dev_dbg(dev, "Deferring transaction for 0x%x\n", reg); @@ -96,8 +98,7 @@ static int regmap_sdw_mbq_write_impl(struct sdw_slave *slave, static int regmap_sdw_mbq_write(void *context, unsigned int reg, unsigned int val) { struct regmap_mbq_context *ctx = context; - struct device *dev = ctx->dev; - struct sdw_slave *slave = dev_to_sdw_dev(dev); + struct sdw_slave *slave = ctx->sdw; bool deferrable = regmap_sdw_mbq_deferrable(ctx, reg); int mbq_size = regmap_sdw_mbq_size(ctx, reg); int ret; @@ -156,8 +157,7 @@ static int regmap_sdw_mbq_read_impl(struct sdw_slave *slave, static int regmap_sdw_mbq_read(void *context, unsigned int reg, unsigned int *val) { struct regmap_mbq_context *ctx = context; - struct device *dev = ctx->dev; - struct sdw_slave *slave = dev_to_sdw_dev(dev); + struct sdw_slave *slave = ctx->sdw; bool deferrable = regmap_sdw_mbq_deferrable(ctx, reg); int mbq_size = regmap_sdw_mbq_size(ctx, reg); int ret; @@ -208,6 +208,7 @@ static int regmap_sdw_mbq_config_check(const struct regmap_config *config) static struct regmap_mbq_context * regmap_sdw_mbq_gen_context(struct device *dev, + struct sdw_slave *sdw, const struct regmap_config *config, const struct regmap_sdw_mbq_cfg *mbq_config) { @@ -218,6 +219,7 @@ regmap_sdw_mbq_gen_context(struct device *dev, return ERR_PTR(-ENOMEM); ctx->dev = dev; + ctx->sdw = sdw; if (mbq_config) ctx->cfg = *mbq_config; @@ -228,7 +230,7 @@ regmap_sdw_mbq_gen_context(struct device *dev, return ctx; } -struct regmap *__regmap_init_sdw_mbq(struct sdw_slave *sdw, +struct regmap *__regmap_init_sdw_mbq(struct device *dev, struct sdw_slave *sdw, const struct regmap_config *config, const struct regmap_sdw_mbq_cfg *mbq_config, struct lock_class_key *lock_key, @@ -241,16 +243,16 @@ struct regmap *__regmap_init_sdw_mbq(struct sdw_slave *sdw, if (ret) return ERR_PTR(ret); - ctx = regmap_sdw_mbq_gen_context(&sdw->dev, config, mbq_config); + ctx = regmap_sdw_mbq_gen_context(dev, sdw, config, mbq_config); if (IS_ERR(ctx)) return ERR_CAST(ctx); - return __regmap_init(&sdw->dev, ®map_sdw_mbq, ctx, + return __regmap_init(dev, ®map_sdw_mbq, ctx, config, lock_key, lock_name); } EXPORT_SYMBOL_GPL(__regmap_init_sdw_mbq); -struct regmap *__devm_regmap_init_sdw_mbq(struct sdw_slave *sdw, +struct regmap *__devm_regmap_init_sdw_mbq(struct device *dev, struct sdw_slave *sdw, const struct regmap_config *config, const struct regmap_sdw_mbq_cfg *mbq_config, struct lock_class_key *lock_key, @@ -263,11 +265,11 @@ struct regmap *__devm_regmap_init_sdw_mbq(struct sdw_slave *sdw, if (ret) return ERR_PTR(ret); - ctx = regmap_sdw_mbq_gen_context(&sdw->dev, config, mbq_config); + ctx = regmap_sdw_mbq_gen_context(dev, sdw, config, mbq_config); if (IS_ERR(ctx)) return ERR_CAST(ctx); - return __devm_regmap_init(&sdw->dev, ®map_sdw_mbq, ctx, + return __devm_regmap_init(dev, ®map_sdw_mbq, ctx, config, lock_key, lock_name); } EXPORT_SYMBOL_GPL(__devm_regmap_init_sdw_mbq); diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index be1e9e61a7bf4..16a8301c25d63 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -535,14 +535,29 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, ref_array = prop->pointer; ref = &ref_array[index]; - refnode = software_node_fwnode(ref->node); + /* + * A software node can reference other software nodes or firmware + * nodes (which are the abstraction layer sitting on top of them). + * This is done to ensure we can create references to static software + * nodes before they're registered with the firmware node framework. + * At the time the reference is being resolved, we expect the swnodes + * in question to already have been registered and to be backed by + * a firmware node. This is why we use the fwnode API below to read the + * relevant properties and bump the reference count. + */ + + if (ref->swnode) + refnode = software_node_fwnode(ref->swnode); + else if (ref->fwnode) + refnode = ref->fwnode; + else + return -EINVAL; + if (!refnode) return -ENOENT; if (nargs_prop) { - error = property_entry_read_int_array(ref->node->properties, - nargs_prop, sizeof(u32), - &nargs_prop_val, 1); + error = fwnode_property_read_u32(refnode, nargs_prop, &nargs_prop_val); if (error) return error; @@ -555,7 +570,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, if (!args) return 0; - args->fwnode = software_node_get(refnode); + args->fwnode = fwnode_handle_get(refnode); args->nargs = nargs; for (i = 0; i < nargs; i++) @@ -635,7 +650,10 @@ software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode) ref = prop->pointer; - return software_node_get(software_node_fwnode(ref[0].node)); + if (!ref->swnode) + return NULL; + + return software_node_get(software_node_fwnode(ref->swnode)); } static struct fwnode_handle * diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c index 13db1f78d2ce9..483adb796654f 100644 --- a/drivers/base/syscore.c +++ b/drivers/base/syscore.c @@ -11,32 +11,32 @@ #include #include -static LIST_HEAD(syscore_ops_list); -static DEFINE_MUTEX(syscore_ops_lock); +static LIST_HEAD(syscore_list); +static DEFINE_MUTEX(syscore_lock); /** - * register_syscore_ops - Register a set of system core operations. - * @ops: System core operations to register. + * register_syscore - Register a set of system core operations. + * @syscore: System core operations to register. */ -void register_syscore_ops(struct syscore_ops *ops) +void register_syscore(struct syscore *syscore) { - mutex_lock(&syscore_ops_lock); - list_add_tail(&ops->node, &syscore_ops_list); - mutex_unlock(&syscore_ops_lock); + mutex_lock(&syscore_lock); + list_add_tail(&syscore->node, &syscore_list); + mutex_unlock(&syscore_lock); } -EXPORT_SYMBOL_GPL(register_syscore_ops); +EXPORT_SYMBOL_GPL(register_syscore); /** - * unregister_syscore_ops - Unregister a set of system core operations. - * @ops: System core operations to unregister. + * unregister_syscore - Unregister a set of system core operations. + * @syscore: System core operations to unregister. */ -void unregister_syscore_ops(struct syscore_ops *ops) +void unregister_syscore(struct syscore *syscore) { - mutex_lock(&syscore_ops_lock); - list_del(&ops->node); - mutex_unlock(&syscore_ops_lock); + mutex_lock(&syscore_lock); + list_del(&syscore->node); + mutex_unlock(&syscore_lock); } -EXPORT_SYMBOL_GPL(unregister_syscore_ops); +EXPORT_SYMBOL_GPL(unregister_syscore); #ifdef CONFIG_PM_SLEEP /** @@ -46,7 +46,7 @@ EXPORT_SYMBOL_GPL(unregister_syscore_ops); */ int syscore_suspend(void) { - struct syscore_ops *ops; + struct syscore *syscore; int ret = 0; trace_suspend_resume(TPS("syscore_suspend"), 0, true); @@ -59,25 +59,27 @@ int syscore_suspend(void) WARN_ONCE(!irqs_disabled(), "Interrupts enabled before system core suspend.\n"); - list_for_each_entry_reverse(ops, &syscore_ops_list, node) - if (ops->suspend) { - pm_pr_dbg("Calling %pS\n", ops->suspend); - ret = ops->suspend(); + list_for_each_entry_reverse(syscore, &syscore_list, node) + if (syscore->ops->suspend) { + pm_pr_dbg("Calling %pS\n", syscore->ops->suspend); + ret = syscore->ops->suspend(syscore->data); if (ret) goto err_out; WARN_ONCE(!irqs_disabled(), - "Interrupts enabled after %pS\n", ops->suspend); + "Interrupts enabled after %pS\n", + syscore->ops->suspend); } trace_suspend_resume(TPS("syscore_suspend"), 0, false); return 0; err_out: - pr_err("PM: System core suspend callback %pS failed.\n", ops->suspend); + pr_err("PM: System core suspend callback %pS failed.\n", + syscore->ops->suspend); - list_for_each_entry_continue(ops, &syscore_ops_list, node) - if (ops->resume) - ops->resume(); + list_for_each_entry_continue(syscore, &syscore_list, node) + if (syscore->ops->resume) + syscore->ops->resume(syscore->data); return ret; } @@ -90,18 +92,19 @@ EXPORT_SYMBOL_GPL(syscore_suspend); */ void syscore_resume(void) { - struct syscore_ops *ops; + struct syscore *syscore; trace_suspend_resume(TPS("syscore_resume"), 0, true); WARN_ONCE(!irqs_disabled(), "Interrupts enabled before system core resume.\n"); - list_for_each_entry(ops, &syscore_ops_list, node) - if (ops->resume) { - pm_pr_dbg("Calling %pS\n", ops->resume); - ops->resume(); + list_for_each_entry(syscore, &syscore_list, node) + if (syscore->ops->resume) { + pm_pr_dbg("Calling %pS\n", syscore->ops->resume); + syscore->ops->resume(syscore->data); WARN_ONCE(!irqs_disabled(), - "Interrupts enabled after %pS\n", ops->resume); + "Interrupts enabled after %pS\n", + syscore->ops->resume); } trace_suspend_resume(TPS("syscore_resume"), 0, false); } @@ -113,16 +116,17 @@ EXPORT_SYMBOL_GPL(syscore_resume); */ void syscore_shutdown(void) { - struct syscore_ops *ops; + struct syscore *syscore; - mutex_lock(&syscore_ops_lock); + mutex_lock(&syscore_lock); - list_for_each_entry_reverse(ops, &syscore_ops_list, node) - if (ops->shutdown) { + list_for_each_entry_reverse(syscore, &syscore_list, node) + if (syscore->ops->shutdown) { if (initcall_debug) - pr_info("PM: Calling %pS\n", ops->shutdown); - ops->shutdown(); + pr_info("PM: Calling %pS\n", + syscore->ops->shutdown); + syscore->ops->shutdown(syscore->data); } - mutex_unlock(&syscore_ops_lock); + mutex_unlock(&syscore_lock); } diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 77d6944489905..858320b6ebb7e 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -316,9 +316,6 @@ config BLK_DEV_RBD tristate "Rados block device (RBD)" depends on INET && BLOCK select CEPH_LIB - select CRC32 - select CRYPTO_AES - select CRYPTO help Say Y here if you want include the Rados block device, which stripes a block device over objects stored in the Ceph distributed object diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 9778259b30d4a..a5104cf96609c 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -247,8 +247,7 @@ MODULE_ALIAS("rd"); /* Legacy boot options - nonmodular */ static int __init ramdisk_size(char *str) { - rd_size = simple_strtol(str, NULL, 0); - return 1; + return kstrtoul(str, 0, &rd_size) == 0; } __setup("ramdisk_size=", ramdisk_size); #endif diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index c7c0fb79a6bf6..29a371f48b578 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -642,7 +642,7 @@ static void nullb_device_release(struct config_item *item) null_free_dev(dev); } -static struct configfs_item_operations nullb_device_ops = { +static const struct configfs_item_operations nullb_device_ops = { .release = nullb_device_release, }; @@ -739,7 +739,7 @@ static struct configfs_attribute *nullb_group_attrs[] = { NULL, }; -static struct configfs_group_operations nullb_group_ops = { +static const struct configfs_group_operations nullb_group_ops = { .make_group = nullb_group_make_group, .drop_item = nullb_group_drop_item, }; diff --git a/drivers/block/rnbd/rnbd-clt-sysfs.c b/drivers/block/rnbd/rnbd-clt-sysfs.c index 6ea7c12e3a871..144aea1466a4d 100644 --- a/drivers/block/rnbd/rnbd-clt-sysfs.c +++ b/drivers/block/rnbd/rnbd-clt-sysfs.c @@ -475,9 +475,17 @@ void rnbd_clt_remove_dev_symlink(struct rnbd_clt_dev *dev) } } +static void rnbd_dev_release(struct kobject *kobj) +{ + struct rnbd_clt_dev *dev = container_of(kobj, struct rnbd_clt_dev, kobj); + + kfree(dev); +} + static const struct kobj_type rnbd_dev_ktype = { .sysfs_ops = &kobj_sysfs_ops, .default_groups = rnbd_dev_groups, + .release = rnbd_dev_release, }; static int rnbd_clt_add_dev_kobj(struct rnbd_clt_dev *dev) diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c index d1c354636315d..094ecc174f416 100644 --- a/drivers/block/rnbd/rnbd-clt.c +++ b/drivers/block/rnbd/rnbd-clt.c @@ -60,7 +60,9 @@ static void rnbd_clt_put_dev(struct rnbd_clt_dev *dev) kfree(dev->pathname); rnbd_clt_put_sess(dev->sess); mutex_destroy(&dev->lock); - kfree(dev); + + if (dev->kobj.state_initialized) + kobject_put(&dev->kobj); } static inline bool rnbd_clt_get_dev(struct rnbd_clt_dev *dev) @@ -1517,7 +1519,7 @@ static bool insert_dev_if_not_exists_devpath(struct rnbd_clt_dev *dev) return found; } -static void delete_dev(struct rnbd_clt_dev *dev) +static void rnbd_delete_dev(struct rnbd_clt_dev *dev) { struct rnbd_clt_session *sess = dev->sess; @@ -1638,7 +1640,7 @@ struct rnbd_clt_dev *rnbd_clt_map_device(const char *sessname, kfree(rsp); rnbd_put_iu(sess, iu); del_dev: - delete_dev(dev); + rnbd_delete_dev(dev); put_dev: rnbd_clt_put_dev(dev); put_sess: @@ -1647,13 +1649,13 @@ struct rnbd_clt_dev *rnbd_clt_map_device(const char *sessname, return ERR_PTR(ret); } -static void destroy_gen_disk(struct rnbd_clt_dev *dev) +static void rnbd_destroy_gen_disk(struct rnbd_clt_dev *dev) { del_gendisk(dev->gd); put_disk(dev->gd); } -static void destroy_sysfs(struct rnbd_clt_dev *dev, +static void rnbd_destroy_sysfs(struct rnbd_clt_dev *dev, const struct attribute *sysfs_self) { rnbd_clt_remove_dev_symlink(dev); @@ -1691,9 +1693,9 @@ int rnbd_clt_unmap_device(struct rnbd_clt_dev *dev, bool force, dev->dev_state = DEV_STATE_UNMAPPED; mutex_unlock(&dev->lock); - delete_dev(dev); - destroy_sysfs(dev, sysfs_self); - destroy_gen_disk(dev); + rnbd_delete_dev(dev); + rnbd_destroy_sysfs(dev, sysfs_self); + rnbd_destroy_gen_disk(dev); if (was_mapped && sess->rtrs) send_msg_close(dev, dev->device_id, RTRS_PERMIT_WAIT); diff --git a/drivers/block/rnbd/rnbd-proto.h b/drivers/block/rnbd/rnbd-proto.h index 77360c2a6069c..64f1cfe9f8efb 100644 --- a/drivers/block/rnbd/rnbd-proto.h +++ b/drivers/block/rnbd/rnbd-proto.h @@ -18,7 +18,7 @@ #include #define RNBD_PROTO_VER_MAJOR 2 -#define RNBD_PROTO_VER_MINOR 0 +#define RNBD_PROTO_VER_MINOR 2 /* The default port number the RTRS server is listening on. */ #define RTRS_PORT 1234 @@ -197,6 +197,8 @@ struct rnbd_msg_io { * * @RNBD_F_SYNC: request is sync (sync write or read) * @RNBD_F_FUA: forced unit access + * @RNBD_F_PREFLUSH: request for cache flush + * @RNBD_F_NOUNMAP: do not free blocks when zeroing */ enum rnbd_io_flags { @@ -211,6 +213,8 @@ enum rnbd_io_flags { /* Flags */ RNBD_F_SYNC = 1<<(RNBD_OP_BITS + 0), RNBD_F_FUA = 1<<(RNBD_OP_BITS + 1), + RNBD_F_PREFLUSH = 1<<(RNBD_OP_BITS + 2), + RNBD_F_NOUNMAP = 1<<(RNBD_OP_BITS + 3) }; static inline u32 rnbd_op(u32 flags) @@ -245,6 +249,9 @@ static inline blk_opf_t rnbd_to_bio_flags(u32 rnbd_opf) break; case RNBD_OP_WRITE_ZEROES: bio_opf = REQ_OP_WRITE_ZEROES; + + if (rnbd_opf & RNBD_F_NOUNMAP) + bio_opf |= REQ_NOUNMAP; break; default: WARN(1, "Unknown RNBD type: %d (flags %d)\n", @@ -258,6 +265,9 @@ static inline blk_opf_t rnbd_to_bio_flags(u32 rnbd_opf) if (rnbd_opf & RNBD_F_FUA) bio_opf |= REQ_FUA; + if (rnbd_opf & RNBD_F_PREFLUSH) + bio_opf |= REQ_PREFLUSH; + return bio_opf; } @@ -280,6 +290,9 @@ static inline u32 rq_to_rnbd_flags(struct request *rq) break; case REQ_OP_WRITE_ZEROES: rnbd_opf = RNBD_OP_WRITE_ZEROES; + + if (rq->cmd_flags & REQ_NOUNMAP) + rnbd_opf |= RNBD_F_NOUNMAP; break; case REQ_OP_FLUSH: rnbd_opf = RNBD_OP_FLUSH; @@ -297,6 +310,9 @@ static inline u32 rq_to_rnbd_flags(struct request *rq) if (op_is_flush(rq->cmd_flags)) rnbd_opf |= RNBD_F_FUA; + if (rq->cmd_flags & REQ_PREFLUSH) + rnbd_opf |= RNBD_F_PREFLUSH; + return rnbd_opf; } diff --git a/drivers/block/rnbd/rnbd-srv-trace.h b/drivers/block/rnbd/rnbd-srv-trace.h index 89d0bcb171958..18ae2ed5537a0 100644 --- a/drivers/block/rnbd/rnbd-srv-trace.h +++ b/drivers/block/rnbd/rnbd-srv-trace.h @@ -44,24 +44,6 @@ DEFINE_EVENT(rnbd_srv_link_class, name, \ DEFINE_LINK_EVENT(create_sess); DEFINE_LINK_EVENT(destroy_sess); -TRACE_DEFINE_ENUM(RNBD_OP_READ); -TRACE_DEFINE_ENUM(RNBD_OP_WRITE); -TRACE_DEFINE_ENUM(RNBD_OP_FLUSH); -TRACE_DEFINE_ENUM(RNBD_OP_DISCARD); -TRACE_DEFINE_ENUM(RNBD_OP_SECURE_ERASE); -TRACE_DEFINE_ENUM(RNBD_F_SYNC); -TRACE_DEFINE_ENUM(RNBD_F_FUA); - -#define show_rnbd_rw_flags(x) \ - __print_flags(x, "|", \ - { RNBD_OP_READ, "READ" }, \ - { RNBD_OP_WRITE, "WRITE" }, \ - { RNBD_OP_FLUSH, "FLUSH" }, \ - { RNBD_OP_DISCARD, "DISCARD" }, \ - { RNBD_OP_SECURE_ERASE, "SECURE_ERASE" }, \ - { RNBD_F_SYNC, "SYNC" }, \ - { RNBD_F_FUA, "FUA" }) - TRACE_EVENT(process_rdma, TP_PROTO(struct rnbd_srv_session *srv, const struct rnbd_msg_io *msg, @@ -97,7 +79,7 @@ TRACE_EVENT(process_rdma, __entry->usrlen = usrlen; ), - TP_printk("I/O req: sess: %s, type: %s, ver: %d, devid: %u, sector: %llu, bsize: %u, flags: %s, ioprio: %d, datalen: %u, usrlen: %zu", + TP_printk("I/O req: sess: %s, type: %s, ver: %d, devid: %u, sector: %llu, bsize: %u, flags: %u, ioprio: %d, datalen: %u, usrlen: %zu", __get_str(sessname), __print_symbolic(__entry->dir, { READ, "READ" }, @@ -106,7 +88,7 @@ TRACE_EVENT(process_rdma, __entry->device_id, __entry->sector, __entry->bi_size, - show_rnbd_rw_flags(__entry->flags), + __entry->flags, __entry->ioprio, __entry->datalen, __entry->usrlen diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c index 2df8941a6b146..7eeb321d61402 100644 --- a/drivers/block/rnbd/rnbd-srv.c +++ b/drivers/block/rnbd/rnbd-srv.c @@ -145,18 +145,30 @@ static int process_rdma(struct rnbd_srv_session *srv_sess, priv->sess_dev = sess_dev; priv->id = id; - bio = bio_alloc(file_bdev(sess_dev->bdev_file), 1, + bio = bio_alloc(file_bdev(sess_dev->bdev_file), !!datalen, rnbd_to_bio_flags(le32_to_cpu(msg->rw)), GFP_KERNEL); - bio_add_virt_nofail(bio, data, datalen); - - bio->bi_opf = rnbd_to_bio_flags(le32_to_cpu(msg->rw)); - if (bio_has_data(bio) && - bio->bi_iter.bi_size != le32_to_cpu(msg->bi_size)) { - rnbd_srv_err_rl(sess_dev, "Datalen mismatch: bio bi_size (%u), bi_size (%u)\n", - bio->bi_iter.bi_size, msg->bi_size); - err = -EINVAL; - goto bio_put; + if (unlikely(!bio)) { + err = -ENOMEM; + goto put_sess_dev; } + + if (!datalen) { + /* + * For special requests like DISCARD and WRITE_ZEROES, the datalen is zero. + */ + bio->bi_iter.bi_size = le32_to_cpu(msg->bi_size); + } else { + bio_add_virt_nofail(bio, data, datalen); + bio->bi_opf = rnbd_to_bio_flags(le32_to_cpu(msg->rw)); + if (bio->bi_iter.bi_size != le32_to_cpu(msg->bi_size)) { + rnbd_srv_err_rl(sess_dev, + "Datalen mismatch: bio bi_size (%u), bi_size (%u)\n", + bio->bi_iter.bi_size, msg->bi_size); + err = -EINVAL; + goto bio_put; + } + } + bio->bi_end_io = rnbd_dev_bi_end_io; bio->bi_private = priv; bio->bi_iter.bi_sector = le64_to_cpu(msg->sector); @@ -170,6 +182,7 @@ static int process_rdma(struct rnbd_srv_session *srv_sess, bio_put: bio_put(bio); +put_sess_dev: rnbd_put_sess_dev(sess_dev); err: kfree(priv); @@ -538,6 +551,8 @@ static void rnbd_srv_fill_msg_open_rsp(struct rnbd_msg_open_rsp *rsp, { struct block_device *bdev = file_bdev(sess_dev->bdev_file); + memset(rsp, 0, sizeof(*rsp)); + rsp->hdr.type = cpu_to_le16(RNBD_MSG_OPEN_RSP); rsp->device_id = cpu_to_le32(sess_dev->device_id); rsp->nsectors = cpu_to_le64(bdev_nr_sectors(bdev)); @@ -644,6 +659,7 @@ static void process_msg_sess_info(struct rnbd_srv_session *srv_sess, trace_process_msg_sess_info(srv_sess, sess_info_msg); + memset(rsp, 0, sizeof(*rsp)); rsp->hdr.type = cpu_to_le16(RNBD_MSG_SESS_INFO_RSP); rsp->ver = srv_sess->ver; } diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs index 6713a6d92391d..2f5a7da03af5d 100644 --- a/drivers/block/rnull/configfs.rs +++ b/drivers/block/rnull/configfs.rs @@ -25,7 +25,7 @@ pub(crate) fn subsystem() -> impl PinInit, E ], }; - kernel::configfs::Subsystem::new(c_str!("rnull"), item_type, try_pin_init!(Config {})) + kernel::configfs::Subsystem::new(c"rnull", item_type, try_pin_init!(Config {})) } #[pin_data] diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index a430746575312..5759823d63148 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -500,8 +500,31 @@ static ssize_t idle_store(struct device *dev, } #ifdef CONFIG_ZRAM_WRITEBACK +#define INVALID_BDEV_BLOCK (~0UL) + +struct zram_wb_ctl { + /* idle list is accessed only by the writeback task, no concurency */ + struct list_head idle_reqs; + /* done list is accessed concurrently, protect by done_lock */ + struct list_head done_reqs; + wait_queue_head_t done_wait; + spinlock_t done_lock; + atomic_t num_inflight; +}; + +struct zram_wb_req { + unsigned long blk_idx; + struct page *page; + struct zram_pp_slot *pps; + struct bio_vec bio_vec; + struct bio bio; + + struct list_head entry; +}; + static ssize_t writeback_limit_enable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct zram *zram = dev_to_zram(dev); u64 val; @@ -510,33 +533,31 @@ static ssize_t writeback_limit_enable_store(struct device *dev, if (kstrtoull(buf, 10, &val)) return ret; - down_read(&zram->init_lock); - spin_lock(&zram->wb_limit_lock); + down_write(&zram->init_lock); zram->wb_limit_enable = val; - spin_unlock(&zram->wb_limit_lock); - up_read(&zram->init_lock); + up_write(&zram->init_lock); ret = len; return ret; } static ssize_t writeback_limit_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { bool val; struct zram *zram = dev_to_zram(dev); down_read(&zram->init_lock); - spin_lock(&zram->wb_limit_lock); val = zram->wb_limit_enable; - spin_unlock(&zram->wb_limit_lock); up_read(&zram->init_lock); return sysfs_emit(buf, "%d\n", val); } static ssize_t writeback_limit_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { struct zram *zram = dev_to_zram(dev); u64 val; @@ -545,31 +566,71 @@ static ssize_t writeback_limit_store(struct device *dev, if (kstrtoull(buf, 10, &val)) return ret; - down_read(&zram->init_lock); - spin_lock(&zram->wb_limit_lock); + /* + * When the page size is greater than 4KB, if bd_wb_limit is set to + * a value that is not page - size aligned, it will cause value + * wrapping. For example, when the page size is set to 16KB and + * bd_wb_limit is set to 3, a single write - back operation will + * cause bd_wb_limit to become -1. Even more terrifying is that + * bd_wb_limit is an unsigned number. + */ + val = rounddown(val, PAGE_SIZE / 4096); + + down_write(&zram->init_lock); zram->bd_wb_limit = val; - spin_unlock(&zram->wb_limit_lock); - up_read(&zram->init_lock); + up_write(&zram->init_lock); ret = len; return ret; } static ssize_t writeback_limit_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { u64 val; struct zram *zram = dev_to_zram(dev); down_read(&zram->init_lock); - spin_lock(&zram->wb_limit_lock); val = zram->bd_wb_limit; - spin_unlock(&zram->wb_limit_lock); up_read(&zram->init_lock); return sysfs_emit(buf, "%llu\n", val); } +static ssize_t writeback_batch_size_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct zram *zram = dev_to_zram(dev); + u32 val; + + if (kstrtouint(buf, 10, &val)) + return -EINVAL; + + if (!val) + return -EINVAL; + + down_write(&zram->init_lock); + zram->wb_batch_size = val; + up_write(&zram->init_lock); + + return len; +} + +static ssize_t writeback_batch_size_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + u32 val; + struct zram *zram = dev_to_zram(dev); + + down_read(&zram->init_lock); + val = zram->wb_batch_size; + up_read(&zram->init_lock); + + return sysfs_emit(buf, "%u\n", val); +} + static void reset_bdev(struct zram *zram) { if (!zram->backing_dev) @@ -697,23 +758,20 @@ static ssize_t backing_dev_store(struct device *dev, return err; } -static unsigned long alloc_block_bdev(struct zram *zram) +static unsigned long zram_reserve_bdev_block(struct zram *zram) { - unsigned long blk_idx = 1; -retry: - /* skip 0 bit to confuse zram.handle = 0 */ - blk_idx = find_next_zero_bit(zram->bitmap, zram->nr_pages, blk_idx); - if (blk_idx == zram->nr_pages) - return 0; + unsigned long blk_idx; - if (test_and_set_bit(blk_idx, zram->bitmap)) - goto retry; + blk_idx = find_next_zero_bit(zram->bitmap, zram->nr_pages, 0); + if (blk_idx == zram->nr_pages) + return INVALID_BDEV_BLOCK; + set_bit(blk_idx, zram->bitmap); atomic64_inc(&zram->stats.bd_count); return blk_idx; } -static void free_block_bdev(struct zram *zram, unsigned long blk_idx) +static void zram_release_bdev_block(struct zram *zram, unsigned long blk_idx) { int was_set; @@ -734,32 +792,249 @@ static void read_from_bdev_async(struct zram *zram, struct page *page, submit_bio(bio); } -static int zram_writeback_slots(struct zram *zram, struct zram_pp_ctl *ctl) +static void release_wb_req(struct zram_wb_req *req) { - unsigned long blk_idx = 0; - struct page *page = NULL; - struct zram_pp_slot *pps; - struct bio_vec bio_vec; - struct bio bio; + __free_page(req->page); + kfree(req); +} + +static void release_wb_ctl(struct zram_wb_ctl *wb_ctl) +{ + if (!wb_ctl) + return; + + /* We should never have inflight requests at this point */ + WARN_ON(atomic_read(&wb_ctl->num_inflight)); + WARN_ON(!list_empty(&wb_ctl->done_reqs)); + + while (!list_empty(&wb_ctl->idle_reqs)) { + struct zram_wb_req *req; + + req = list_first_entry(&wb_ctl->idle_reqs, + struct zram_wb_req, entry); + list_del(&req->entry); + release_wb_req(req); + } + + kfree(wb_ctl); +} + +static struct zram_wb_ctl *init_wb_ctl(struct zram *zram) +{ + struct zram_wb_ctl *wb_ctl; + int i; + + wb_ctl = kmalloc(sizeof(*wb_ctl), GFP_KERNEL); + if (!wb_ctl) + return NULL; + + INIT_LIST_HEAD(&wb_ctl->idle_reqs); + INIT_LIST_HEAD(&wb_ctl->done_reqs); + atomic_set(&wb_ctl->num_inflight, 0); + init_waitqueue_head(&wb_ctl->done_wait); + spin_lock_init(&wb_ctl->done_lock); + + for (i = 0; i < zram->wb_batch_size; i++) { + struct zram_wb_req *req; + + /* + * This is fatal condition only if we couldn't allocate + * any requests at all. Otherwise we just work with the + * requests that we have successfully allocated, so that + * writeback can still proceed, even if there is only one + * request on the idle list. + */ + req = kzalloc(sizeof(*req), GFP_KERNEL | __GFP_NOWARN); + if (!req) + break; + + req->page = alloc_page(GFP_KERNEL | __GFP_NOWARN); + if (!req->page) { + kfree(req); + break; + } + + list_add(&req->entry, &wb_ctl->idle_reqs); + } + + /* We couldn't allocate any requests, so writeabck is not possible */ + if (list_empty(&wb_ctl->idle_reqs)) + goto release_wb_ctl; + + return wb_ctl; + +release_wb_ctl: + release_wb_ctl(wb_ctl); + return NULL; +} + +static void zram_account_writeback_rollback(struct zram *zram) +{ + lockdep_assert_held_read(&zram->init_lock); + + if (zram->wb_limit_enable) + zram->bd_wb_limit += 1UL << (PAGE_SHIFT - 12); +} + +static void zram_account_writeback_submit(struct zram *zram) +{ + lockdep_assert_held_read(&zram->init_lock); + + if (zram->wb_limit_enable && zram->bd_wb_limit > 0) + zram->bd_wb_limit -= 1UL << (PAGE_SHIFT - 12); +} + +static int zram_writeback_complete(struct zram *zram, struct zram_wb_req *req) +{ + u32 index = req->pps->index; + int err; + + err = blk_status_to_errno(req->bio.bi_status); + if (err) { + /* + * Failed wb requests should not be accounted in wb_limit + * (if enabled). + */ + zram_account_writeback_rollback(zram); + zram_release_bdev_block(zram, req->blk_idx); + return err; + } + + atomic64_inc(&zram->stats.bd_writes); + zram_slot_lock(zram, index); + /* + * We release slot lock during writeback so slot can change under us: + * slot_free() or slot_free() and zram_write_page(). In both cases + * slot loses ZRAM_PP_SLOT flag. No concurrent post-processing can + * set ZRAM_PP_SLOT on such slots until current post-processing + * finishes. + */ + if (!zram_test_flag(zram, index, ZRAM_PP_SLOT)) { + zram_release_bdev_block(zram, req->blk_idx); + goto out; + } + + zram_free_page(zram, index); + zram_set_flag(zram, index, ZRAM_WB); + zram_set_handle(zram, index, req->blk_idx); + atomic64_inc(&zram->stats.pages_stored); + +out: + zram_slot_unlock(zram, index); + return 0; +} + +static void zram_writeback_endio(struct bio *bio) +{ + struct zram_wb_req *req = container_of(bio, struct zram_wb_req, bio); + struct zram_wb_ctl *wb_ctl = bio->bi_private; + unsigned long flags; + + spin_lock_irqsave(&wb_ctl->done_lock, flags); + list_add(&req->entry, &wb_ctl->done_reqs); + spin_unlock_irqrestore(&wb_ctl->done_lock, flags); + + wake_up(&wb_ctl->done_wait); +} + +static void zram_submit_wb_request(struct zram *zram, + struct zram_wb_ctl *wb_ctl, + struct zram_wb_req *req) +{ + /* + * wb_limit (if enabled) should be adjusted before submission, + * so that we don't over-submit. + */ + zram_account_writeback_submit(zram); + atomic_inc(&wb_ctl->num_inflight); + req->bio.bi_private = wb_ctl; + submit_bio(&req->bio); +} + +static int zram_complete_done_reqs(struct zram *zram, + struct zram_wb_ctl *wb_ctl) +{ + struct zram_wb_req *req; + unsigned long flags; int ret = 0, err; - u32 index; - page = alloc_page(GFP_KERNEL); - if (!page) - return -ENOMEM; + while (atomic_read(&wb_ctl->num_inflight) > 0) { + spin_lock_irqsave(&wb_ctl->done_lock, flags); + req = list_first_entry_or_null(&wb_ctl->done_reqs, + struct zram_wb_req, entry); + if (req) + list_del(&req->entry); + spin_unlock_irqrestore(&wb_ctl->done_lock, flags); + + /* ->num_inflight > 0 doesn't mean we have done requests */ + if (!req) + break; + + err = zram_writeback_complete(zram, req); + if (err) + ret = err; + + atomic_dec(&wb_ctl->num_inflight); + release_pp_slot(zram, req->pps); + req->pps = NULL; + + list_add(&req->entry, &wb_ctl->idle_reqs); + } + + return ret; +} + +static struct zram_wb_req *zram_select_idle_req(struct zram_wb_ctl *wb_ctl) +{ + struct zram_wb_req *req; + + req = list_first_entry_or_null(&wb_ctl->idle_reqs, + struct zram_wb_req, entry); + if (req) + list_del(&req->entry); + return req; +} + +static int zram_writeback_slots(struct zram *zram, + struct zram_pp_ctl *ctl, + struct zram_wb_ctl *wb_ctl) +{ + unsigned long blk_idx = INVALID_BDEV_BLOCK; + struct zram_wb_req *req = NULL; + struct zram_pp_slot *pps; + int ret = 0, err = 0; + u32 index = 0; while ((pps = select_pp_slot(ctl))) { - spin_lock(&zram->wb_limit_lock); if (zram->wb_limit_enable && !zram->bd_wb_limit) { - spin_unlock(&zram->wb_limit_lock); ret = -EIO; break; } - spin_unlock(&zram->wb_limit_lock); - if (!blk_idx) { - blk_idx = alloc_block_bdev(zram); - if (!blk_idx) { + while (!req) { + req = zram_select_idle_req(wb_ctl); + if (req) + break; + + wait_event(wb_ctl->done_wait, + !list_empty(&wb_ctl->done_reqs)); + + err = zram_complete_done_reqs(zram, wb_ctl); + /* + * BIO errors are not fatal, we continue and simply + * attempt to writeback the remaining objects (pages). + * At the same time we need to signal user-space that + * some writes (at least one, but also could be all of + * them) were not successful and we do so by returning + * the most recent BIO error. + */ + if (err) + ret = err; + } + + if (blk_idx == INVALID_BDEV_BLOCK) { + blk_idx = zram_reserve_bdev_block(zram); + if (blk_idx == INVALID_BDEV_BLOCK) { ret = -ENOSPC; break; } @@ -768,74 +1043,54 @@ static int zram_writeback_slots(struct zram *zram, struct zram_pp_ctl *ctl) index = pps->index; zram_slot_lock(zram, index); /* - * scan_slots() sets ZRAM_PP_SLOT and relases slot lock, so + * scan_slots() sets ZRAM_PP_SLOT and releases slot lock, so * slots can change in the meantime. If slots are accessed or * freed they lose ZRAM_PP_SLOT flag and hence we don't * post-process them. */ if (!zram_test_flag(zram, index, ZRAM_PP_SLOT)) goto next; - if (zram_read_from_zspool(zram, page, index)) + if (zram_read_from_zspool(zram, req->page, index)) goto next; zram_slot_unlock(zram, index); - bio_init(&bio, zram->bdev, &bio_vec, 1, - REQ_OP_WRITE | REQ_SYNC); - bio.bi_iter.bi_sector = blk_idx * (PAGE_SIZE >> 9); - __bio_add_page(&bio, page, PAGE_SIZE, 0); - - /* - * XXX: A single page IO would be inefficient for write - * but it would be not bad as starter. - */ - err = submit_bio_wait(&bio); - if (err) { - release_pp_slot(zram, pps); - /* - * BIO errors are not fatal, we continue and simply - * attempt to writeback the remaining objects (pages). - * At the same time we need to signal user-space that - * some writes (at least one, but also could be all of - * them) were not successful and we do so by returning - * the most recent BIO error. - */ - ret = err; - continue; - } - - atomic64_inc(&zram->stats.bd_writes); - zram_slot_lock(zram, index); /* - * Same as above, we release slot lock during writeback so - * slot can change under us: slot_free() or slot_free() and - * reallocation (zram_write_page()). In both cases slot loses - * ZRAM_PP_SLOT flag. No concurrent post-processing can set - * ZRAM_PP_SLOT on such slots until current post-processing - * finishes. + * From now on pp-slot is owned by the req, remove it from + * its pp bucket. */ - if (!zram_test_flag(zram, index, ZRAM_PP_SLOT)) - goto next; + list_del_init(&pps->entry); + + req->blk_idx = blk_idx; + req->pps = pps; + bio_init(&req->bio, zram->bdev, &req->bio_vec, 1, REQ_OP_WRITE); + req->bio.bi_iter.bi_sector = req->blk_idx * (PAGE_SIZE >> 9); + req->bio.bi_end_io = zram_writeback_endio; + __bio_add_page(&req->bio, req->page, PAGE_SIZE, 0); + + zram_submit_wb_request(zram, wb_ctl, req); + blk_idx = INVALID_BDEV_BLOCK; + req = NULL; + cond_resched(); + continue; - zram_free_page(zram, index); - zram_set_flag(zram, index, ZRAM_WB); - zram_set_handle(zram, index, blk_idx); - blk_idx = 0; - atomic64_inc(&zram->stats.pages_stored); - spin_lock(&zram->wb_limit_lock); - if (zram->wb_limit_enable && zram->bd_wb_limit > 0) - zram->bd_wb_limit -= 1UL << (PAGE_SHIFT - 12); - spin_unlock(&zram->wb_limit_lock); next: zram_slot_unlock(zram, index); release_pp_slot(zram, pps); - - cond_resched(); } - if (blk_idx) - free_block_bdev(zram, blk_idx); - if (page) - __free_page(page); + /* + * Selected idle req, but never submitted it due to some error or + * wb limit. + */ + if (req) + release_wb_req(req); + + while (atomic_read(&wb_ctl->num_inflight) > 0) { + wait_event(wb_ctl->done_wait, !list_empty(&wb_ctl->done_reqs)); + err = zram_complete_done_reqs(zram, wb_ctl); + if (err) + ret = err; + } return ret; } @@ -948,7 +1203,8 @@ static ssize_t writeback_store(struct device *dev, struct zram *zram = dev_to_zram(dev); u64 nr_pages = zram->disksize >> PAGE_SHIFT; unsigned long lo = 0, hi = nr_pages; - struct zram_pp_ctl *ctl = NULL; + struct zram_pp_ctl *pp_ctl = NULL; + struct zram_wb_ctl *wb_ctl = NULL; char *args, *param, *val; ssize_t ret = len; int err, mode = 0; @@ -970,8 +1226,14 @@ static ssize_t writeback_store(struct device *dev, goto release_init_lock; } - ctl = init_pp_ctl(); - if (!ctl) { + pp_ctl = init_pp_ctl(); + if (!pp_ctl) { + ret = -ENOMEM; + goto release_init_lock; + } + + wb_ctl = init_wb_ctl(zram); + if (!wb_ctl) { ret = -ENOMEM; goto release_init_lock; } @@ -1000,7 +1262,7 @@ static ssize_t writeback_store(struct device *dev, goto release_init_lock; } - scan_slots_for_writeback(zram, mode, lo, hi, ctl); + scan_slots_for_writeback(zram, mode, lo, hi, pp_ctl); break; } @@ -1011,7 +1273,7 @@ static ssize_t writeback_store(struct device *dev, goto release_init_lock; } - scan_slots_for_writeback(zram, mode, lo, hi, ctl); + scan_slots_for_writeback(zram, mode, lo, hi, pp_ctl); break; } @@ -1022,7 +1284,7 @@ static ssize_t writeback_store(struct device *dev, goto release_init_lock; } - scan_slots_for_writeback(zram, mode, lo, hi, ctl); + scan_slots_for_writeback(zram, mode, lo, hi, pp_ctl); continue; } @@ -1033,17 +1295,18 @@ static ssize_t writeback_store(struct device *dev, goto release_init_lock; } - scan_slots_for_writeback(zram, mode, lo, hi, ctl); + scan_slots_for_writeback(zram, mode, lo, hi, pp_ctl); continue; } } - err = zram_writeback_slots(zram, ctl); + err = zram_writeback_slots(zram, pp_ctl, wb_ctl); if (err) ret = err; release_init_lock: - release_pp_ctl(zram, ctl); + release_pp_ctl(zram, pp_ctl); + release_wb_ctl(wb_ctl); atomic_set(&zram->pp_in_progress, 0); up_read(&zram->init_lock); @@ -1112,7 +1375,9 @@ static int read_from_bdev(struct zram *zram, struct page *page, return -EIO; } -static void free_block_bdev(struct zram *zram, unsigned long blk_idx) {}; +static void zram_release_bdev_block(struct zram *zram, unsigned long blk_idx) +{ +} #endif #ifdef CONFIG_ZRAM_MEMORY_TRACKING @@ -1634,7 +1899,7 @@ static void zram_free_page(struct zram *zram, size_t index) if (zram_test_flag(zram, index, ZRAM_WB)) { zram_clear_flag(zram, index, ZRAM_WB); - free_block_bdev(zram, zram_get_handle(zram, index)); + zram_release_bdev_block(zram, zram_get_handle(zram, index)); goto out; } @@ -1740,14 +2005,14 @@ static int zram_read_page(struct zram *zram, struct page *page, u32 index, ret = zram_read_from_zspool(zram, page, index); zram_slot_unlock(zram, index); } else { + unsigned long blk_idx = zram_get_handle(zram, index); + /* * The slot should be unlocked before reading from the backing * device. */ zram_slot_unlock(zram, index); - - ret = read_from_bdev(zram, page, zram_get_handle(zram, index), - parent); + ret = read_from_bdev(zram, page, blk_idx, parent); } /* Should NEVER happen. Return bio error if it does. */ @@ -2610,6 +2875,7 @@ static DEVICE_ATTR_RW(backing_dev); static DEVICE_ATTR_WO(writeback); static DEVICE_ATTR_RW(writeback_limit); static DEVICE_ATTR_RW(writeback_limit_enable); +static DEVICE_ATTR_RW(writeback_batch_size); #endif #ifdef CONFIG_ZRAM_MULTI_COMP static DEVICE_ATTR_RW(recomp_algorithm); @@ -2631,6 +2897,7 @@ static struct attribute *zram_disk_attrs[] = { &dev_attr_writeback.attr, &dev_attr_writeback_limit.attr, &dev_attr_writeback_limit_enable.attr, + &dev_attr_writeback_batch_size.attr, #endif &dev_attr_io_stat.attr, &dev_attr_mm_stat.attr, @@ -2692,7 +2959,7 @@ static int zram_add(void) init_rwsem(&zram->init_lock); #ifdef CONFIG_ZRAM_WRITEBACK - spin_lock_init(&zram->wb_limit_lock); + zram->wb_batch_size = 32; #endif /* gendisk structure */ diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index 6cee93f9c0d06..c6d94501376c6 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h @@ -127,8 +127,8 @@ struct zram { bool claim; /* Protected by disk->open_mutex */ #ifdef CONFIG_ZRAM_WRITEBACK struct file *backing_dev; - spinlock_t wb_limit_lock; bool wb_limit_enable; + u32 wb_batch_size; u64 bd_wb_limit; struct block_device *bdev; unsigned long *bitmap; diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 577965f95fda9..512da7482acc1 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -11,7 +11,7 @@ #include "../common.h" -extern struct bus_type mhi_ep_bus_type; +extern const struct bus_type mhi_ep_bus_type; #define MHI_REG_OFFSET 0x100 #define BHI_REG_OFFSET 0x200 diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index cdea24e929195..3c208b5c84468 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1494,7 +1494,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, INIT_WORK(&mhi_cntrl->cmd_ring_work, mhi_ep_cmd_ring_worker); INIT_WORK(&mhi_cntrl->ch_ring_work, mhi_ep_ch_ring_worker); - mhi_cntrl->wq = alloc_workqueue("mhi_ep_wq", 0, 0); + mhi_cntrl->wq = alloc_workqueue("mhi_ep_wq", WQ_PERCPU, 0); if (!mhi_cntrl->wq) { ret = -ENOMEM; goto err_destroy_ring_item_cache; @@ -1703,7 +1703,7 @@ static int mhi_ep_match(struct device *dev, const struct device_driver *drv) return 0; }; -struct bus_type mhi_ep_bus_type = { +const struct bus_type mhi_ep_bus_type = { .name = "mhi_ep", .dev_name = "mhi_ep", .match = mhi_ep_match, diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index b188bbf7de042..e3bc737313a2f 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -663,6 +663,17 @@ static const struct mhi_pci_dev_info mhi_foxconn_t99w696_info = { .sideband_wake = false, }; +static const struct mhi_pci_dev_info mhi_foxconn_t99w760_info = { + .name = "foxconn-t99w760", + .edl = "qcom/sdx35/foxconn/xbl_s_devprg_ns.melf", + .edl_trigger = true, + .config = &modem_foxconn_sdx61_config, + .bar_num = MHI_PCI_DEFAULT_BAR_NUM, + .dma_data_width = 32, + .mru_default = 32768, + .sideband_wake = false, +}; + static const struct mhi_channel_config mhi_mv3x_channels[] = { MHI_CHANNEL_CONFIG_UL(0, "LOOPBACK", 64, 0), MHI_CHANNEL_CONFIG_DL(1, "LOOPBACK", 64, 0), @@ -877,6 +888,16 @@ static const struct mhi_pci_dev_info mhi_telit_fn990b40_info = { .edl_trigger = true, }; +static const struct mhi_pci_dev_info mhi_telit_fe990b40_info = { + .name = "telit-fe990b40", + .config = &modem_telit_fn920c04_config, + .bar_num = MHI_PCI_DEFAULT_BAR_NUM, + .dma_data_width = 32, + .sideband_wake = false, + .mru_default = 32768, + .edl_trigger = true, +}; + static const struct mhi_pci_dev_info mhi_netprisma_lcur57_info = { .name = "netprisma-lcur57", .edl = "qcom/prog_firehose_sdx24.mbn", @@ -933,6 +954,9 @@ static const struct pci_device_id mhi_pci_id_table[] = { /* Telit FN990B40 (sdx72) */ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0309, 0x1c5d, 0x201a), .driver_data = (kernel_ulong_t) &mhi_telit_fn990b40_info }, + /* Telit FE990B40 (sdx72) */ + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0309, 0x1c5d, 0x2025), + .driver_data = (kernel_ulong_t) &mhi_telit_fe990b40_info }, { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0309), .driver_data = (kernel_ulong_t) &mhi_qcom_sdx75_info }, /* QDU100, x100-DU */ @@ -997,6 +1021,8 @@ static const struct pci_device_id mhi_pci_id_table[] = { /* DW5934e(sdx72), Non-eSIM */ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe11e), .driver_data = (kernel_ulong_t) &mhi_foxconn_dw5934e_info }, + { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe123), + .driver_data = (kernel_ulong_t) &mhi_foxconn_t99w760_info }, /* MV31-W (Cinterion) */ { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b3), .driver_data = (kernel_ulong_t) &mhi_mv31_info }, diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 00cb792bda18b..dd94145c9b222 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -1006,7 +1006,7 @@ static __init int mvebu_mbus_debugfs_init(void) } fs_initcall(mvebu_mbus_debugfs_init); -static int mvebu_mbus_suspend(void) +static int mvebu_mbus_suspend(void *data) { struct mvebu_mbus_state *s = &mbus_state; int win; @@ -1040,7 +1040,7 @@ static int mvebu_mbus_suspend(void) return 0; } -static void mvebu_mbus_resume(void) +static void mvebu_mbus_resume(void *data) { struct mvebu_mbus_state *s = &mbus_state; int win; @@ -1069,9 +1069,13 @@ static void mvebu_mbus_resume(void) } } -static struct syscore_ops mvebu_mbus_syscore_ops = { - .suspend = mvebu_mbus_suspend, - .resume = mvebu_mbus_resume, +static const struct syscore_ops mvebu_mbus_syscore_ops = { + .suspend = mvebu_mbus_suspend, + .resume = mvebu_mbus_resume, +}; + +static struct syscore mvebu_mbus_syscore = { + .ops = &mvebu_mbus_syscore_ops, }; static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, @@ -1118,7 +1122,7 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, writel(UNIT_SYNC_BARRIER_ALL, mbus->mbuswins_base + UNIT_SYNC_BARRIER_OFF); - register_syscore_ops(&mvebu_mbus_syscore_ops); + register_syscore(&mvebu_mbus_syscore); return 0; } diff --git a/drivers/bus/stm32_rifsc.c b/drivers/bus/stm32_rifsc.c index 4cf1b60014b77..debeaf8ea1bd2 100644 --- a/drivers/bus/stm32_rifsc.c +++ b/drivers/bus/stm32_rifsc.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -25,6 +26,8 @@ #define RIFSC_RISC_PRIVCFGR0 0x30 #define RIFSC_RISC_PER0_CIDCFGR 0x100 #define RIFSC_RISC_PER0_SEMCR 0x104 +#define RIFSC_RISC_REG0_ACFGR 0x900 +#define RIFSC_RISC_REG3_AADDR 0x924 #define RIFSC_RISC_HWCFGR2 0xFEC /* @@ -70,6 +73,565 @@ #define RIF_CID0 0x0 #define RIF_CID1 0x1 +#if defined(CONFIG_DEBUG_FS) +#define RIFSC_RISUP_ENTRIES 128 +#define RIFSC_RIMU_ENTRIES 16 +#define RIFSC_RISAL_SUBREGIONS 2 +#define RIFSC_RISAL_GRANULARITY 8 + +#define RIFSC_RIMC_ATTR0 0xC10 + +#define RIFSC_RIMC_CIDSEL BIT(2) +#define RIFSC_RIMC_MCID_MASK GENMASK(6, 4) +#define RIFSC_RIMC_MSEC BIT(8) +#define RIFSC_RIMC_MPRIV BIT(9) + +#define RIFSC_RISC_SRCID_MASK GENMASK(6, 4) +#define RIFSC_RISC_SRPRIV BIT(9) +#define RIFSC_RISC_SRSEC BIT(8) +#define RIFSC_RISC_SRRLOCK BIT(1) +#define RIFSC_RISC_SREN BIT(0) +#define RIFSC_RISC_SRLENGTH_MASK GENMASK(27, 16) +#define RIFSC_RISC_SRSTART_MASK GENMASK(10, 0) + +static const char *stm32mp21_rifsc_rimu_names[RIFSC_RIMU_ENTRIES] = { + "ETR", + "SDMMC1", + "SDMMC2", + "SDMMC3", + "OTG_HS", + "USBH", + "ETH1", + "ETH2", + "RESERVED", + "RESERVED", + "DCMIPP", + "LTDC_L1/L2", + "LTDC_L3", + "RESERVED", + "RESERVED", + "RESERVED", +}; + +static const char *stm32mp25_rifsc_rimu_names[RIFSC_RIMU_ENTRIES] = { + "ETR", + "SDMMC1", + "SDMMC2", + "SDMMC3", + "USB3DR", + "USBH", + "ETH1", + "ETH2", + "PCIE", + "GPU", + "DMCIPP", + "LTDC_L0/L1", + "LTDC_L2", + "LTDC_ROT", + "VDEC", + "VENC" +}; + +static const char *stm32mp21_rifsc_risup_names[RIFSC_RISUP_ENTRIES] = { + "TIM1", + "TIM2", + "TIM3", + "TIM4", + "TIM5", + "TIM6", + "TIM7", + "TIM8", + "TIM10", + "TIM11", + "TIM12", + "TIM13", + "TIM14", + "TIM15", + "TIM16", + "TIM17", + "RESERVED", + "LPTIM1", + "LPTIM2", + "LPTIM3", + "LPTIM4", + "LPTIM5", + "SPI1", + "SPI2", + "SPI3", + "SPI4", + "SPI5", + "SPI6", + "RESERVED", + "RESERVED", + "SPDIFRX", + "USART1", + "USART2", + "USART3", + "UART4", + "UART5", + "USART6", + "UART7", + "RESERVED", + "RESERVED", + "LPUART1", + "I2C1", + "I2C2", + "I2C3", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "SAI1", + "SAI2", + "SAI3", + "SAI4", + "RESERVED", + "MDF1", + "RESERVED", + "FDCAN", + "HDP", + "ADC1", + "ADC2", + "ETH1", + "ETH2", + "RESERVED", + "USBH", + "RESERVED", + "RESERVED", + "OTG_HS", + "DDRPERFM", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "STGEN", + "OCTOSPI1", + "RESERVED", + "SDMMC1", + "SDMMC2", + "SDMMC3", + "RESERVED", + "LTDC_CMN", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "CSI", + "DCMIPP", + "DCMI_PSSI", + "RESERVED", + "RESERVED", + "RESERVED", + "RNG1", + "RNG2", + "PKA", + "SAES", + "HASH1", + "HASH2", + "CRYP1", + "CRYP2", + "IWDG1", + "IWDG2", + "IWDG3", + "IWDG4", + "WWDG1", + "RESERVED", + "VREFBUF", + "DTS", + "RAMCFG", + "CRC", + "SERC", + "RESERVED", + "RESERVED", + "RESERVED", + "I3C1", + "I3C2", + "I3C3", + "RESERVED", + "ICACHE_DCACHE", + "LTDC_L1L2", + "LTDC_L3", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "OTFDEC1", + "RESERVED", + "IAC", +}; + +static const char *stm32mp25_rifsc_risup_names[RIFSC_RISUP_ENTRIES] = { + "TIM1", + "TIM2", + "TIM3", + "TIM4", + "TIM5", + "TIM6", + "TIM7", + "TIM8", + "TIM10", + "TIM11", + "TIM12", + "TIM13", + "TIM14", + "TIM15", + "TIM16", + "TIM17", + "TIM20", + "LPTIM1", + "LPTIM2", + "LPTIM3", + "LPTIM4", + "LPTIM5", + "SPI1", + "SPI2", + "SPI3", + "SPI4", + "SPI5", + "SPI6", + "SPI7", + "SPI8", + "SPDIFRX", + "USART1", + "USART2", + "USART3", + "UART4", + "UART5", + "USART6", + "UART7", + "UART8", + "UART9", + "LPUART1", + "I2C1", + "I2C2", + "I2C3", + "I2C4", + "I2C5", + "I2C6", + "I2C7", + "I2C8", + "SAI1", + "SAI2", + "SAI3", + "SAI4", + "RESERVED", + "MDF1", + "ADF1", + "FDCAN", + "HDP", + "ADC12", + "ADC3", + "ETH1", + "ETH2", + "RESERVED", + "USBH", + "RESERVED", + "RESERVED", + "USB3DR", + "COMBOPHY", + "PCIE", + "UCPD1", + "ETHSW_DEIP", + "ETHSW_ACM_CF", + "ETHSW_ACM_MSGBU", + "STGEN", + "OCTOSPI1", + "OCTOSPI2", + "SDMMC1", + "SDMMC2", + "SDMMC3", + "GPU", + "LTDC_CMN", + "DSI_CMN", + "RESERVED", + "RESERVED", + "LVDS", + "RESERVED", + "CSI", + "DCMIPP", + "DCMI_PSSI", + "VDEC", + "VENC", + "RESERVED", + "RNG", + "PKA", + "SAES", + "HASH", + "CRYP1", + "CRYP2", + "IWDG1", + "IWDG2", + "IWDG3", + "IWDG4", + "IWDG5", + "WWDG1", + "WWDG2", + "RESERVED", + "VREFBUF", + "DTS", + "RAMCFG", + "CRC", + "SERC", + "OCTOSPIM", + "GICV2M", + "RESERVED", + "I3C1", + "I3C2", + "I3C3", + "I3C4", + "ICACHE_DCACHE", + "LTDC_L0L1", + "LTDC_L2", + "LTDC_ROT", + "DSI_TRIG", + "DSI_RDFIFO", + "RESERVED", + "OTFDEC1", + "OTFDEC2", + "IAC", +}; +struct rifsc_risup_debug_data { + char dev_name[15]; + u8 dev_cid; + u8 dev_sem_cids; + u8 dev_id; + bool dev_cid_filt_en; + bool dev_sem_en; + bool dev_priv; + bool dev_sec; +}; + +struct rifsc_rimu_debug_data { + char m_name[11]; + u8 m_cid; + bool cidsel; + bool m_sec; + bool m_priv; +}; + +struct rifsc_subreg_debug_data { + bool sr_sec; + bool sr_priv; + u8 sr_cid; + bool sr_rlock; + bool sr_enable; + u16 sr_start; + u16 sr_length; +}; + +struct stm32_rifsc_resources_names { + const char **device_names; + const char **initiator_names; +}; +struct rifsc_dbg_private { + const struct stm32_rifsc_resources_names *res_names; + void __iomem *mmio; + unsigned int nb_risup; + unsigned int nb_rimu; + unsigned int nb_risal; +}; + +static const struct stm32_rifsc_resources_names rifsc_mp21_res_names = { + .device_names = stm32mp21_rifsc_risup_names, + .initiator_names = stm32mp21_rifsc_rimu_names, +}; + +static const struct stm32_rifsc_resources_names rifsc_mp25_res_names = { + .device_names = stm32mp25_rifsc_risup_names, + .initiator_names = stm32mp25_rifsc_rimu_names, +}; + +static void stm32_rifsc_fill_rimu_dbg_entry(struct rifsc_dbg_private *rifsc, + struct rifsc_rimu_debug_data *dbg_entry, int i) +{ + const struct stm32_rifsc_resources_names *dbg_names = rifsc->res_names; + u32 rimc_attr = readl_relaxed(rifsc->mmio + RIFSC_RIMC_ATTR0 + 0x4 * i); + + snprintf(dbg_entry->m_name, sizeof(dbg_entry->m_name), "%s", dbg_names->initiator_names[i]); + dbg_entry->m_cid = FIELD_GET(RIFSC_RIMC_MCID_MASK, rimc_attr); + dbg_entry->cidsel = rimc_attr & RIFSC_RIMC_CIDSEL; + dbg_entry->m_sec = rimc_attr & RIFSC_RIMC_MSEC; + dbg_entry->m_priv = rimc_attr & RIFSC_RIMC_MPRIV; +} + +static void stm32_rifsc_fill_dev_dbg_entry(struct rifsc_dbg_private *rifsc, + struct rifsc_risup_debug_data *dbg_entry, int i) +{ + const struct stm32_rifsc_resources_names *dbg_names = rifsc->res_names; + u32 cid_cfgr, sec_cfgr, priv_cfgr; + u8 reg_id = i / IDS_PER_RISC_SEC_PRIV_REGS; + u8 reg_offset = i % IDS_PER_RISC_SEC_PRIV_REGS; + + cid_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_PER0_CIDCFGR + 0x8 * i); + sec_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_SECCFGR0 + 0x4 * reg_id); + priv_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_PRIVCFGR0 + 0x4 * reg_id); + + snprintf(dbg_entry->dev_name, sizeof(dbg_entry->dev_name), "%s", + dbg_names->device_names[i]); + dbg_entry->dev_id = i; + dbg_entry->dev_cid_filt_en = cid_cfgr & CIDCFGR_CFEN; + dbg_entry->dev_sem_en = cid_cfgr & CIDCFGR_SEMEN; + dbg_entry->dev_cid = FIELD_GET(RIFSC_RISC_SCID_MASK, cid_cfgr); + dbg_entry->dev_sem_cids = FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_cfgr); + dbg_entry->dev_sec = sec_cfgr & BIT(reg_offset) ? true : false; + dbg_entry->dev_priv = priv_cfgr & BIT(reg_offset) ? true : false; +} + + +static void stm32_rifsc_fill_subreg_dbg_entry(struct rifsc_dbg_private *rifsc, + struct rifsc_subreg_debug_data *dbg_entry, int i, + int j) +{ + u32 risc_xcfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_REG0_ACFGR + 0x10 * i + 0x8 * j); + u32 risc_xaddr; + + dbg_entry->sr_sec = risc_xcfgr & RIFSC_RISC_SRSEC; + dbg_entry->sr_priv = risc_xcfgr & RIFSC_RISC_SRPRIV; + dbg_entry->sr_cid = FIELD_GET(RIFSC_RISC_SRCID_MASK, risc_xcfgr); + dbg_entry->sr_rlock = risc_xcfgr & RIFSC_RISC_SRRLOCK; + dbg_entry->sr_enable = risc_xcfgr & RIFSC_RISC_SREN; + if (i == 2) { + risc_xaddr = readl_relaxed(rifsc->mmio + RIFSC_RISC_REG3_AADDR + 0x8 * j); + dbg_entry->sr_length = FIELD_GET(RIFSC_RISC_SRLENGTH_MASK, risc_xaddr); + dbg_entry->sr_start = FIELD_GET(RIFSC_RISC_SRSTART_MASK, risc_xaddr); + } else { + dbg_entry->sr_start = 0; + dbg_entry->sr_length = U16_MAX; + } +} + +static int stm32_rifsc_conf_dump_show(struct seq_file *s, void *data) +{ + struct rifsc_dbg_private *rifsc = (struct rifsc_dbg_private *)s->private; + int i, j; + + seq_puts(s, "\n=============================================\n"); + seq_puts(s, " RIFSC dump\n"); + seq_puts(s, "=============================================\n\n"); + + seq_puts(s, "\n=============================================\n"); + seq_puts(s, " RISUP dump\n"); + seq_puts(s, "=============================================\n"); + + seq_printf(s, "\n| %-15s |", "Peripheral name"); + seq_puts(s, "| Firewall ID |"); + seq_puts(s, "| N/SECURE |"); + seq_puts(s, "| N/PRIVILEGED |"); + seq_puts(s, "| CID filtering |"); + seq_puts(s, "| Semaphore mode |"); + seq_puts(s, "| SCID |"); + seq_printf(s, "| %7s |\n", "SEMWL"); + + for (i = 0; i < RIFSC_RISUP_ENTRIES && i < rifsc->nb_risup; i++) { + struct rifsc_risup_debug_data d_dbg_entry; + + stm32_rifsc_fill_dev_dbg_entry(rifsc, &d_dbg_entry, i); + + seq_printf(s, "| %-15s |", d_dbg_entry.dev_name); + seq_printf(s, "| %-11d |", d_dbg_entry.dev_id); + seq_printf(s, "| %-8s |", d_dbg_entry.dev_sec ? "SEC" : "NSEC"); + seq_printf(s, "| %-12s |", d_dbg_entry.dev_priv ? "PRIV" : "NPRIV"); + seq_printf(s, "| %-13s |", str_enabled_disabled(d_dbg_entry.dev_cid_filt_en)); + seq_printf(s, "| %-14s |", str_enabled_disabled(d_dbg_entry.dev_sem_en)); + seq_printf(s, "| %-4d |", d_dbg_entry.dev_cid); + seq_printf(s, "| %#-7x |\n", d_dbg_entry.dev_sem_cids); + } + + seq_puts(s, "\n=============================================\n"); + seq_puts(s, " RIMU dump\n"); + seq_puts(s, "=============================================\n"); + + seq_puts(s, "| RIMU's name |"); + seq_puts(s, "| CIDSEL |"); + seq_puts(s, "| MCID |"); + seq_puts(s, "| N/SECURE |"); + seq_puts(s, "| N/PRIVILEGED |\n"); + + for (i = 0; i < RIFSC_RIMU_ENTRIES && rifsc->nb_rimu; i++) { + struct rifsc_rimu_debug_data m_dbg_entry; + + stm32_rifsc_fill_rimu_dbg_entry(rifsc, &m_dbg_entry, i); + + seq_printf(s, "| %-11s |", m_dbg_entry.m_name); + seq_printf(s, "| %-6s |", m_dbg_entry.cidsel ? "CIDSEL" : ""); + seq_printf(s, "| %-4d |", m_dbg_entry.m_cid); + seq_printf(s, "| %-8s |", m_dbg_entry.m_sec ? "SEC" : "NSEC"); + seq_printf(s, "| %-12s |\n", m_dbg_entry.m_priv ? "PRIV" : "NPRIV"); + } + + if (rifsc->nb_risal > 0) { + seq_puts(s, "\n=============================================\n"); + seq_puts(s, " RISAL dump\n"); + seq_puts(s, "=============================================\n"); + + seq_puts(s, "| Memory |"); + seq_puts(s, "| Subreg. |"); + seq_puts(s, "| N/SECURE |"); + seq_puts(s, "| N/PRIVILEGED |"); + seq_puts(s, "| Subreg. CID |"); + seq_puts(s, "| Resource lock |"); + seq_puts(s, "| Subreg. enable |"); + seq_puts(s, "| Subreg. start |"); + seq_puts(s, "| Subreg. end |\n"); + + for (i = 0; i < rifsc->nb_risal; i++) { + for (j = 0; j < RIFSC_RISAL_SUBREGIONS; j++) { + struct rifsc_subreg_debug_data sr_dbg_entry; + + stm32_rifsc_fill_subreg_dbg_entry(rifsc, &sr_dbg_entry, i, j); + + seq_printf(s, "| LPSRAM%1d |", i + 1); + seq_printf(s, "| %1s |", (j == 0) ? "A" : "B"); + seq_printf(s, "| %-8s |", sr_dbg_entry.sr_sec ? "SEC" : "NSEC"); + seq_printf(s, "| %-12s |", sr_dbg_entry.sr_priv ? "PRIV" : "NPRIV"); + seq_printf(s, "| 0x%-9x |", sr_dbg_entry.sr_cid); + seq_printf(s, "| %-13s |", + sr_dbg_entry.sr_rlock ? "locked (1)" : "unlocked (0)"); + seq_printf(s, "| %-14s |", + str_enabled_disabled(sr_dbg_entry.sr_enable)); + seq_printf(s, "| 0x%-11x |", sr_dbg_entry.sr_start); + seq_printf(s, "| 0x%-11x |\n", sr_dbg_entry.sr_start + + sr_dbg_entry.sr_length - 1); + } + } + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(stm32_rifsc_conf_dump); + +static int stm32_rifsc_register_debugfs(struct stm32_firewall_controller *rifsc_controller, + u32 nb_risup, u32 nb_rimu, u32 nb_risal) +{ + struct rifsc_dbg_private *rifsc_priv; + struct dentry *root = NULL; + + rifsc_priv = devm_kzalloc(rifsc_controller->dev, sizeof(*rifsc_priv), GFP_KERNEL); + if (!rifsc_priv) + return -ENOMEM; + + rifsc_priv->mmio = rifsc_controller->mmio; + rifsc_priv->nb_risup = nb_risup; + rifsc_priv->nb_rimu = nb_rimu; + rifsc_priv->nb_risal = nb_risal; + rifsc_priv->res_names = of_device_get_match_data(rifsc_controller->dev); + + root = debugfs_lookup("stm32_firewall", NULL); + if (!root) + root = debugfs_create_dir("stm32_firewall", NULL); + + if (IS_ERR(root)) + return PTR_ERR(root); + + debugfs_create_file("rifsc", 0444, root, rifsc_priv, &stm32_rifsc_conf_dump_fops); + + return 0; +} +#endif /* defined(CONFIG_DEBUG_FS) */ + static bool stm32_rifsc_is_semaphore_available(void __iomem *addr) { return !(readl(addr) & SEMCR_MUTEX); @@ -207,9 +769,19 @@ static int stm32_rifsc_probe(struct platform_device *pdev) rifsc_controller->release_access = stm32_rifsc_release_access; /* Get number of RIFSC entries*/ - nb_risup = readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2) & HWCFGR2_CONF1_MASK; - nb_rimu = readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2) & HWCFGR2_CONF2_MASK; - nb_risal = readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2) & HWCFGR2_CONF3_MASK; + nb_risup = FIELD_GET(HWCFGR2_CONF1_MASK, + readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2)); + nb_rimu = FIELD_GET(HWCFGR2_CONF2_MASK, + readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2)); + nb_risal = FIELD_GET(HWCFGR2_CONF3_MASK, + readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2)); + /* + * On STM32MP21, RIFSC_RISC_HWCFGR2 shows an incorrect number of RISAL (NUM_RISAL is 3 + * instead of 0). A software workaround is implemented using the st,mem-map property in the + * device tree. This property is absent or left empty if there is no RISAL. + */ + if (of_device_is_compatible(np, "st,stm32mp21-rifsc")) + nb_risal = 0; rifsc_controller->max_entries = nb_risup + nb_rimu + nb_risal; platform_set_drvdata(pdev, rifsc_controller); @@ -228,12 +800,29 @@ static int stm32_rifsc_probe(struct platform_device *pdev) return rc; } +#if defined(CONFIG_DEBUG_FS) + rc = stm32_rifsc_register_debugfs(rifsc_controller, nb_risup, nb_rimu, nb_risal); + if (rc) + return dev_err_probe(rifsc_controller->dev, rc, "Failed creating debugfs entry\n"); +#endif + /* Populate all allowed nodes */ return of_platform_populate(np, NULL, NULL, &pdev->dev); } static const struct of_device_id stm32_rifsc_of_match[] = { - { .compatible = "st,stm32mp25-rifsc" }, + { + .compatible = "st,stm32mp25-rifsc", +#if defined(CONFIG_DEBUG_FS) + .data = &rifsc_mp25_res_names, +#endif + }, + { + .compatible = "st,stm32mp21-rifsc", +#if defined(CONFIG_DEBUG_FS) + .data = &rifsc_mp21_res_names, +#endif + }, {} }; MODULE_DEVICE_TABLE(of, stm32_rifsc_of_match); diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 7a33c3b31d1e9..82735c58be114 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -373,7 +373,6 @@ static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, unlock: mutex_unlock(&rsb->lock); - pm_runtime_mark_last_busy(rsb->dev); pm_runtime_put_autosuspend(rsb->dev); return ret; @@ -417,7 +416,6 @@ static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, mutex_unlock(&rsb->lock); - pm_runtime_mark_last_busy(rsb->dev); pm_runtime_put_autosuspend(rsb->dev); return ret; diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 5566ad11399e7..610354ce7f8f0 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -48,6 +48,7 @@ enum sysc_soc { SOC_UNKNOWN, SOC_2420, SOC_2430, + SOC_AM33, SOC_3430, SOC_AM35, SOC_3630, @@ -2912,6 +2913,7 @@ static void ti_sysc_idle(struct work_struct *work) static const struct soc_device_attribute sysc_soc_match[] = { SOC_FLAG("OMAP242*", SOC_2420), SOC_FLAG("OMAP243*", SOC_2430), + SOC_FLAG("AM33*", SOC_AM33), SOC_FLAG("AM35*", SOC_AM35), SOC_FLAG("OMAP3[45]*", SOC_3430), SOC_FLAG("OMAP3[67]*", SOC_3630), @@ -3117,10 +3119,15 @@ static int sysc_check_active_timer(struct sysc *ddata) * can be dropped if we stop supporting old beagleboard revisions * A to B4 at some point. */ - if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) + switch (sysc_soc->soc) { + case SOC_AM33: + case SOC_3430: + case SOC_AM35: error = -ENXIO; - else + break; + default: error = -EBUSY; + } if ((ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) && (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)) diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig index db51386c663a6..1518449d47b51 100644 --- a/drivers/cache/Kconfig +++ b/drivers/cache/Kconfig @@ -1,9 +1,17 @@ # SPDX-License-Identifier: GPL-2.0 -menu "Cache Drivers" + +menuconfig CACHEMAINT_FOR_DMA + bool "Cache management for noncoherent DMA" + depends on RISCV + default y + help + These drivers implement support for noncoherent DMA master devices + on platforms that lack the standard CPU interfaces for this. + +if CACHEMAINT_FOR_DMA config AX45MP_L2_CACHE bool "Andes Technology AX45MP L2 Cache controller" - depends on RISCV select RISCV_NONSTANDARD_CACHE_OPS help Support for the L2 cache controller on Andes Technology AX45MP platforms. @@ -16,7 +24,6 @@ config SIFIVE_CCACHE config STARFIVE_STARLINK_CACHE bool "StarFive StarLink Cache controller" - depends on RISCV depends on ARCH_STARFIVE depends on 64BIT select RISCV_DMA_NONCOHERENT @@ -24,4 +31,26 @@ config STARFIVE_STARLINK_CACHE help Support for the StarLink cache controller IP from StarFive. -endmenu +endif #CACHEMAINT_FOR_DMA + +menuconfig CACHEMAINT_FOR_HOTPLUG + bool "Cache management for memory hot plug like operations" + depends on GENERIC_CPU_CACHE_MAINTENANCE + help + These drivers implement cache management for flows where it is necessary + to flush data from all host caches. + +if CACHEMAINT_FOR_HOTPLUG + +config HISI_SOC_HHA + tristate "HiSilicon Hydra Home Agent (HHA) device driver" + depends on (ARM64 && ACPI) || COMPILE_TEST + help + The Hydra Home Agent (HHA) is responsible for cache coherency + on the SoC. This drivers enables the cache maintenance functions of + the HHA. + + This driver can be built as a module. If so, the module will be + called hisi_soc_hha. + +endif #CACHEMAINT_FOR_HOTPLUG diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile index 55c5e851034da..b3362b15d6c15 100644 --- a/drivers/cache/Makefile +++ b/drivers/cache/Makefile @@ -3,3 +3,5 @@ obj-$(CONFIG_AX45MP_L2_CACHE) += ax45mp_cache.o obj-$(CONFIG_SIFIVE_CCACHE) += sifive_ccache.o obj-$(CONFIG_STARFIVE_STARLINK_CACHE) += starfive_starlink_cache.o + +obj-$(CONFIG_HISI_SOC_HHA) += hisi_soc_hha.o diff --git a/drivers/cache/hisi_soc_hha.c b/drivers/cache/hisi_soc_hha.c new file mode 100644 index 0000000000000..25ff0f5ae79b3 --- /dev/null +++ b/drivers/cache/hisi_soc_hha.c @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for HiSilicon Hydra Home Agent (HHA). + * + * Copyright (c) 2025 HiSilicon Technologies Co., Ltd. + * Author: Yicong Yang + * Yushan Wang + * + * A system typically contains multiple HHAs. Each is responsible for a subset + * of the physical addresses in the system, but interleave can make the mapping + * from a particular cache line to a responsible HHA complex. As such no + * filtering is done in the driver, with the hardware being responsible for + * responding with success for even if it was not responsible for any addresses + * in the range on which the operation was requested. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HISI_HHA_CTRL 0x5004 +#define HISI_HHA_CTRL_EN BIT(0) +#define HISI_HHA_CTRL_RANGE BIT(1) +#define HISI_HHA_CTRL_TYPE GENMASK(3, 2) +#define HISI_HHA_START_L 0x5008 +#define HISI_HHA_START_H 0x500c +#define HISI_HHA_LEN_L 0x5010 +#define HISI_HHA_LEN_H 0x5014 + +/* The maintain operation performs in a 128 Byte granularity */ +#define HISI_HHA_MAINT_ALIGN 128 + +#define HISI_HHA_POLL_GAP_US 10 +#define HISI_HHA_POLL_TIMEOUT_US 50000 + +struct hisi_soc_hha { + /* Must be first element */ + struct cache_coherency_ops_inst cci; + /* Locks HHA instance to forbid overlapping access. */ + struct mutex lock; + void __iomem *base; +}; + +static bool hisi_hha_cache_maintain_wait_finished(struct hisi_soc_hha *soc_hha) +{ + u32 val; + + return !readl_poll_timeout_atomic(soc_hha->base + HISI_HHA_CTRL, val, + !(val & HISI_HHA_CTRL_EN), + HISI_HHA_POLL_GAP_US, + HISI_HHA_POLL_TIMEOUT_US); +} + +static int hisi_soc_hha_wbinv(struct cache_coherency_ops_inst *cci, + struct cc_inval_params *invp) +{ + struct hisi_soc_hha *soc_hha = + container_of(cci, struct hisi_soc_hha, cci); + phys_addr_t top, addr = invp->addr; + size_t size = invp->size; + u32 reg; + + if (!size) + return -EINVAL; + + addr = ALIGN_DOWN(addr, HISI_HHA_MAINT_ALIGN); + top = ALIGN(addr + size, HISI_HHA_MAINT_ALIGN); + size = top - addr; + + guard(mutex)(&soc_hha->lock); + + if (!hisi_hha_cache_maintain_wait_finished(soc_hha)) + return -EBUSY; + + /* + * Hardware will search for addresses ranging [addr, addr + size - 1], + * last byte included, and perform maintenance in 128 byte granules + * on those cachelines which contain the addresses. If a given instance + * is either not responsible for a cacheline or that cacheline is not + * currently present then the search will fail, no operation will be + * necessary and the device will report success. + */ + size -= 1; + + writel(lower_32_bits(addr), soc_hha->base + HISI_HHA_START_L); + writel(upper_32_bits(addr), soc_hha->base + HISI_HHA_START_H); + writel(lower_32_bits(size), soc_hha->base + HISI_HHA_LEN_L); + writel(upper_32_bits(size), soc_hha->base + HISI_HHA_LEN_H); + + reg = FIELD_PREP(HISI_HHA_CTRL_TYPE, 1); /* Clean Invalid */ + reg |= HISI_HHA_CTRL_RANGE | HISI_HHA_CTRL_EN; + writel(reg, soc_hha->base + HISI_HHA_CTRL); + + return 0; +} + +static int hisi_soc_hha_done(struct cache_coherency_ops_inst *cci) +{ + struct hisi_soc_hha *soc_hha = + container_of(cci, struct hisi_soc_hha, cci); + + guard(mutex)(&soc_hha->lock); + if (!hisi_hha_cache_maintain_wait_finished(soc_hha)) + return -ETIMEDOUT; + + return 0; +} + +static const struct cache_coherency_ops hha_ops = { + .wbinv = hisi_soc_hha_wbinv, + .done = hisi_soc_hha_done, +}; + +static int hisi_soc_hha_probe(struct platform_device *pdev) +{ + struct hisi_soc_hha *soc_hha; + struct resource *mem; + int ret; + + soc_hha = cache_coherency_ops_instance_alloc(&hha_ops, + struct hisi_soc_hha, cci); + if (!soc_hha) + return -ENOMEM; + + platform_set_drvdata(pdev, soc_hha); + + mutex_init(&soc_hha->lock); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + ret = -ENOMEM; + goto err_free_cci; + } + + soc_hha->base = ioremap(mem->start, resource_size(mem)); + if (!soc_hha->base) { + ret = dev_err_probe(&pdev->dev, -ENOMEM, + "failed to remap io memory"); + goto err_free_cci; + } + + ret = cache_coherency_ops_instance_register(&soc_hha->cci); + if (ret) + goto err_iounmap; + + return 0; + +err_iounmap: + iounmap(soc_hha->base); +err_free_cci: + cache_coherency_ops_instance_put(&soc_hha->cci); + return ret; +} + +static void hisi_soc_hha_remove(struct platform_device *pdev) +{ + struct hisi_soc_hha *soc_hha = platform_get_drvdata(pdev); + + cache_coherency_ops_instance_unregister(&soc_hha->cci); + iounmap(soc_hha->base); + cache_coherency_ops_instance_put(&soc_hha->cci); +} + +static const struct acpi_device_id hisi_soc_hha_ids[] = { + { "HISI0511", }, + { } +}; +MODULE_DEVICE_TABLE(acpi, hisi_soc_hha_ids); + +static struct platform_driver hisi_soc_hha_driver = { + .driver = { + .name = "hisi_soc_hha", + .acpi_match_table = hisi_soc_hha_ids, + }, + .probe = hisi_soc_hha_probe, + .remove = hisi_soc_hha_remove, +}; + +module_platform_driver(hisi_soc_hha_driver); + +MODULE_IMPORT_NS("CACHE_COHERENCY"); +MODULE_DESCRIPTION("HiSilicon Hydra Home Agent driver supporting cache maintenance"); +MODULE_AUTHOR("Yicong Yang "); +MODULE_AUTHOR("Yushan Wang "); +MODULE_LICENSE("GPL"); diff --git a/drivers/cdx/cdx.c b/drivers/cdx/cdx.c index 3d50f8cd9c0bd..b39af2f1937f7 100644 --- a/drivers/cdx/cdx.c +++ b/drivers/cdx/cdx.c @@ -170,7 +170,7 @@ static int cdx_unregister_device(struct device *dev, return 0; } -static void cdx_unregister_devices(struct bus_type *bus) +static void cdx_unregister_devices(const struct bus_type *bus) { /* Reset all the devices attached to cdx bus */ bus_for_each_dev(bus, NULL, NULL, cdx_unregister_device); @@ -651,7 +651,7 @@ static struct attribute *cdx_bus_attrs[] = { }; ATTRIBUTE_GROUPS(cdx_bus); -struct bus_type cdx_bus_type = { +const struct bus_type cdx_bus_type = { .name = "cdx", .match = cdx_bus_match, .probe = cdx_probe, diff --git a/drivers/char/adi.c b/drivers/char/adi.c index 4312b0cc391cd..0849d933a2d54 100644 --- a/drivers/char/adi.c +++ b/drivers/char/adi.c @@ -80,8 +80,8 @@ static ssize_t adi_read(struct file *file, char __user *buf, bytes_read += ver_buf_sz; ver_buf_idx = 0; - ver_buf_sz = min(count - bytes_read, - (size_t)MAX_BUF_SZ); + ver_buf_sz = min_t(size_t, count - bytes_read, + MAX_BUF_SZ); } } @@ -157,7 +157,7 @@ static ssize_t adi_write(struct file *file, const char __user *buf, } bytes_written += ver_buf_sz; - ver_buf_sz = min(count - bytes_written, (size_t)MAX_BUF_SZ); + ver_buf_sz = min_t(size_t, count - bytes_written, MAX_BUF_SZ); } while (bytes_written < count); (*offp) += bytes_written; diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index 53ce352f7197d..4aa5d1c76f83b 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c @@ -142,18 +142,10 @@ static struct apm_queue kapmd_queue; static DEFINE_MUTEX(state_lock); -/* - * Compatibility cruft until the IPAQ people move over to the new - * interface. - */ -static void __apm_get_power_status(struct apm_power_info *info) -{ -} - /* * This allows machines to provide their own "apm get power status" function. */ -void (*apm_get_power_status)(struct apm_power_info *) = __apm_get_power_status; +void (*apm_get_power_status)(struct apm_power_info *); EXPORT_SYMBOL(apm_get_power_status); diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 9fed9706d9cd2..c138c468f3a44 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c @@ -835,7 +835,10 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ret = -ENOTTY; break; } - Dummy = readb(apbs[IndexCard].RamIO + VERS); + + if (cmd != 6) + Dummy = readb(apbs[IndexCard].RamIO + VERS); + kfree(adgl); mutex_unlock(&ac_mutex); return ret; diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index 497fc167cb8ca..231cbf7b300f1 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c @@ -69,7 +69,8 @@ MODULE_VERSION(VERSION_STR); static int __init hangcheck_parse_tick(char *str) { int par; - if (get_option(&str,&par)) + + if (get_option(&str, &par)) hangcheck_tick = par; return 1; } @@ -77,7 +78,8 @@ static int __init hangcheck_parse_tick(char *str) static int __init hangcheck_parse_margin(char *str) { int par; - if (get_option(&str,&par)) + + if (get_option(&str, &par)) hangcheck_margin = par; return 1; } @@ -85,7 +87,8 @@ static int __init hangcheck_parse_margin(char *str) static int __init hangcheck_parse_reboot(char *str) { int par; - if (get_option(&str,&par)) + + if (get_option(&str, &par)) hangcheck_reboot = par; return 1; } @@ -93,7 +96,8 @@ static int __init hangcheck_parse_reboot(char *str) static int __init hangcheck_parse_dump_tasks(char *str) { int par; - if (get_option(&str,&par)) + + if (get_option(&str, &par)) hangcheck_dump_tasks = par; return 1; } @@ -126,23 +130,23 @@ static void hangcheck_fire(struct timer_list *unused) if (tsc_diff > hangcheck_tsc_margin) { if (hangcheck_dump_tasks) { - printk(KERN_CRIT "Hangcheck: Task state:\n"); + pr_crit("Hangcheck: Task state:\n"); #ifdef CONFIG_MAGIC_SYSRQ handle_sysrq('t'); #endif /* CONFIG_MAGIC_SYSRQ */ } if (hangcheck_reboot) { - printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n"); + pr_crit("Hangcheck: hangcheck is restarting the machine.\n"); emergency_restart(); } else { - printk(KERN_CRIT "Hangcheck: hangcheck value past margin!\n"); + pr_crit("Hangcheck: hangcheck value past margin!\n"); } } #if 0 /* * Enable to investigate delays in detail */ - printk("Hangcheck: called %Ld ns since last time (%Ld ns overshoot)\n", + pr_debug("Hangcheck: called %lld ns since last time (%lld ns overshoot)\n", tsc_diff, tsc_diff - hangcheck_tick*TIMER_FREQ); #endif mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); @@ -152,7 +156,7 @@ static void hangcheck_fire(struct timer_list *unused) static int __init hangcheck_init(void) { - printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n", + pr_debug("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n", VERSION_STR, hangcheck_tick, hangcheck_margin); hangcheck_tsc_margin = (unsigned long long)hangcheck_margin + hangcheck_tick; @@ -168,7 +172,7 @@ static int __init hangcheck_init(void) static void __exit hangcheck_exit(void) { timer_delete_sync(&hangcheck_ticktock); - printk("Hangcheck: Stopped hangcheck timer.\n"); + pr_debug("Hangcheck: Stopped hangcheck timer.\n"); } module_init(hangcheck_init); diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 3700ab4eba3e7..3f48fc6ab596d 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -599,7 +599,8 @@ static void __ipmi_bmc_unregister(struct ipmi_smi *intf); static int __ipmi_bmc_register(struct ipmi_smi *intf, struct ipmi_device_id *id, bool guid_set, guid_t *guid, int intf_num); -static int __scan_channels(struct ipmi_smi *intf, struct ipmi_device_id *id); +static int __scan_channels(struct ipmi_smi *intf, + struct ipmi_device_id *id, bool rescan); static void free_ipmi_user(struct kref *ref) { @@ -2668,7 +2669,7 @@ static int __bmc_get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc, if (__ipmi_bmc_register(intf, &id, guid_set, &guid, intf_num)) need_waiter(intf); /* Retry later on an error. */ else - __scan_channels(intf, &id); + __scan_channels(intf, &id, false); if (!intf_set) { @@ -2688,7 +2689,7 @@ static int __bmc_get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc, goto out_noprocessing; } else if (memcmp(&bmc->fetch_id, &bmc->id, sizeof(bmc->id))) /* Version info changes, scan the channels again. */ - __scan_channels(intf, &bmc->fetch_id); + __scan_channels(intf, &bmc->fetch_id, true); bmc->dyn_id_expiry = jiffies + IPMI_DYN_DEV_ID_EXPIRY; @@ -3417,8 +3418,6 @@ channel_handler(struct ipmi_smi *intf, struct ipmi_recv_msg *msg) intf->channels_ready = true; wake_up(&intf->waitq); } else { - intf->channel_list = intf->wchannels + set; - intf->channels_ready = true; rv = send_channel_info_cmd(intf, intf->curr_channel); } @@ -3440,10 +3439,21 @@ channel_handler(struct ipmi_smi *intf, struct ipmi_recv_msg *msg) /* * Must be holding intf->bmc_reg_mutex to call this. */ -static int __scan_channels(struct ipmi_smi *intf, struct ipmi_device_id *id) +static int __scan_channels(struct ipmi_smi *intf, + struct ipmi_device_id *id, + bool rescan) { int rv; + if (rescan) { + /* Clear channels_ready to force channels rescan. */ + intf->channels_ready = false; + } + + /* Skip channel scan if channels are already marked ready */ + if (intf->channels_ready) + return 0; + if (ipmi_version_major(id) > 1 || (ipmi_version_major(id) == 1 && ipmi_version_minor(id) >= 5)) { @@ -3658,7 +3668,7 @@ int ipmi_add_smi(struct module *owner, } mutex_lock(&intf->bmc_reg_mutex); - rv = __scan_channels(intf, &id); + rv = __scan_channels(intf, &id, false); mutex_unlock(&intf->bmc_reg_mutex); if (rv) goto out_err_bmc_reg; diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 34b815901b205..52039fae1594c 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -304,13 +304,13 @@ static unsigned zero_mmap_capabilities(struct file *file) } /* can't do an in-place private mapping if there's no MMU */ -static inline int private_mapping_ok(struct vm_area_struct *vma) +static inline int private_mapping_ok(struct vm_area_desc *desc) { - return is_nommu_shared_mapping(vma->vm_flags); + return is_nommu_shared_mapping(desc->vm_flags); } #else -static inline int private_mapping_ok(struct vm_area_struct *vma) +static inline int private_mapping_ok(struct vm_area_desc *desc) { return 1; } @@ -322,46 +322,49 @@ static const struct vm_operations_struct mmap_mem_ops = { #endif }; -static int mmap_mem(struct file *file, struct vm_area_struct *vma) +static int mmap_filter_error(int err) { - size_t size = vma->vm_end - vma->vm_start; - phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT; + return -EAGAIN; +} + +static int mmap_mem_prepare(struct vm_area_desc *desc) +{ + struct file *file = desc->file; + const size_t size = vma_desc_size(desc); + const phys_addr_t offset = (phys_addr_t)desc->pgoff << PAGE_SHIFT; /* Does it even fit in phys_addr_t? */ - if (offset >> PAGE_SHIFT != vma->vm_pgoff) + if (offset >> PAGE_SHIFT != desc->pgoff) return -EINVAL; /* It's illegal to wrap around the end of the physical address space. */ if (offset + (phys_addr_t)size - 1 < offset) return -EINVAL; - if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) + if (!valid_mmap_phys_addr_range(desc->pgoff, size)) return -EINVAL; - if (!private_mapping_ok(vma)) + if (!private_mapping_ok(desc)) return -ENOSYS; - if (!range_is_allowed(vma->vm_pgoff, size)) + if (!range_is_allowed(desc->pgoff, size)) return -EPERM; - if (!phys_mem_access_prot_allowed(file, vma->vm_pgoff, size, - &vma->vm_page_prot)) + if (!phys_mem_access_prot_allowed(file, desc->pgoff, size, + &desc->page_prot)) return -EINVAL; - vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, - size, - vma->vm_page_prot); + desc->page_prot = phys_mem_access_prot(file, desc->pgoff, + size, + desc->page_prot); - vma->vm_ops = &mmap_mem_ops; + desc->vm_ops = &mmap_mem_ops; + + /* Remap-pfn-range will mark the range VM_IO. */ + mmap_action_remap_full(desc, desc->pgoff); + /* We filter remap errors to -EAGAIN. */ + desc->action.error_hook = mmap_filter_error; - /* Remap-pfn-range will mark the range VM_IO */ - if (remap_pfn_range(vma, - vma->vm_start, - vma->vm_pgoff, - size, - vma->vm_page_prot)) { - return -EAGAIN; - } return 0; } @@ -501,14 +504,26 @@ static ssize_t read_zero(struct file *file, char __user *buf, return cleared; } -static int mmap_zero(struct file *file, struct vm_area_struct *vma) +static int mmap_zero_private_success(const struct vm_area_struct *vma) +{ + /* + * This is a highly unique situation where we mark a MAP_PRIVATE mapping + * of /dev/zero anonymous, despite it not being. + */ + vma_set_anonymous((struct vm_area_struct *)vma); + + return 0; +} + +static int mmap_zero_prepare(struct vm_area_desc *desc) { #ifndef CONFIG_MMU return -ENOSYS; #endif - if (vma->vm_flags & VM_SHARED) - return shmem_zero_setup(vma); - vma_set_anonymous(vma); + if (desc->vm_flags & VM_SHARED) + return shmem_zero_setup_desc(desc); + + desc->action.success_hook = mmap_zero_private_success; return 0; } @@ -526,10 +541,11 @@ static unsigned long get_unmapped_area_zero(struct file *file, { if (flags & MAP_SHARED) { /* - * mmap_zero() will call shmem_zero_setup() to create a file, - * so use shmem's get_unmapped_area in case it can be huge; - * and pass NULL for file as in mmap.c's get_unmapped_area(), - * so as not to confuse shmem with our handle on "/dev/zero". + * mmap_zero_prepare() will call shmem_zero_setup() to create a + * file, so use shmem's get_unmapped_area in case it can be + * huge; and pass NULL for file as in mmap.c's + * get_unmapped_area(), so as not to confuse shmem with our + * handle on "/dev/zero". */ return shmem_get_unmapped_area(NULL, addr, len, pgoff, flags); } @@ -542,7 +558,7 @@ static unsigned long get_unmapped_area_zero(struct file *file, #ifdef CONFIG_TRANSPARENT_HUGEPAGE return thp_get_unmapped_area(file, addr, len, pgoff, flags); #else - return mm_get_unmapped_area(current->mm, file, addr, len, pgoff, flags); + return mm_get_unmapped_area(file, addr, len, pgoff, flags); #endif } #endif /* CONFIG_MMU */ @@ -632,7 +648,7 @@ static const struct file_operations __maybe_unused mem_fops = { .llseek = memory_lseek, .read = read_mem, .write = write_mem, - .mmap = mmap_mem, + .mmap_prepare = mmap_mem_prepare, .open = open_mem, #ifndef CONFIG_MMU .get_unmapped_area = get_unmapped_area_mem, @@ -668,7 +684,7 @@ static const struct file_operations zero_fops = { .write_iter = write_iter_zero, .splice_read = copy_splice_read, .splice_write = splice_write_zero, - .mmap = mmap_zero, + .mmap_prepare = mmap_zero_prepare, .get_unmapped_area = get_unmapped_area_zero, #ifndef CONFIG_MMU .mmap_capabilities = zero_mmap_capabilities, diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c index 4a8937f805701..90f93cefb21c4 100644 --- a/drivers/char/mwave/3780i.c +++ b/drivers/char/mwave/3780i.c @@ -46,6 +46,8 @@ * First release to the public */ +#define pr_fmt(fmt) "3780i: " fmt + #include #include #include @@ -75,18 +77,12 @@ unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO, unsigned long flags; unsigned short val; - PRINTK_3(TRACE_3780I, - "3780i::dsp3780I_ReadMsaCfg entry usDspBaseIO %x ulMsaAddr %lx\n", - usDspBaseIO, ulMsaAddr); - spin_lock_irqsave(&dsp_lock, flags); OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr); OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16)); val = InWordDsp(DSP_MsaDataDSISHigh); spin_unlock_irqrestore(&dsp_lock, flags); - PRINTK_2(TRACE_3780I, "3780i::dsp3780I_ReadMsaCfg exit val %x\n", val); - return val; } @@ -95,10 +91,6 @@ void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, { unsigned long flags; - PRINTK_4(TRACE_3780I, - "3780i::dsp3780i_WriteMsaCfg entry usDspBaseIO %x ulMsaAddr %lx usValue %x\n", - usDspBaseIO, ulMsaAddr, usValue); - spin_lock_irqsave(&dsp_lock, flags); OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr); OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16)); @@ -112,64 +104,18 @@ static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, DSP_ISA_SLAVE_CONTROL rSlaveControl; DSP_ISA_SLAVE_CONTROL rSlaveControl_Save; - - PRINTK_4(TRACE_3780I, - "3780i::dsp3780i_WriteGenCfg entry usDspBaseIO %x uIndex %x ucValue %x\n", - usDspBaseIO, uIndex, ucValue); - MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl); - PRINTK_2(TRACE_3780I, - "3780i::dsp3780i_WriteGenCfg rSlaveControl %x\n", - MKBYTE(rSlaveControl)); - rSlaveControl_Save = rSlaveControl; rSlaveControl.ConfigMode = true; - PRINTK_2(TRACE_3780I, - "3780i::dsp3780i_WriteGenCfg entry rSlaveControl+ConfigMode %x\n", - MKBYTE(rSlaveControl)); - OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl)); OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex); OutByteDsp(DSP_ConfigData, ucValue); OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save)); - - PRINTK_1(TRACE_3780I, "3780i::dsp3780i_WriteGenCfg exit\n"); - - } -#if 0 -unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, - unsigned uIndex) -{ - DSP_ISA_SLAVE_CONTROL rSlaveControl; - DSP_ISA_SLAVE_CONTROL rSlaveControl_Save; - unsigned char ucValue; - - - PRINTK_3(TRACE_3780I, - "3780i::dsp3780i_ReadGenCfg entry usDspBaseIO %x uIndex %x\n", - usDspBaseIO, uIndex); - - MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl); - rSlaveControl_Save = rSlaveControl; - rSlaveControl.ConfigMode = true; - OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl)); - OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex); - ucValue = InByteDsp(DSP_ConfigData); - OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save)); - - PRINTK_2(TRACE_3780I, - "3780i::dsp3780i_ReadGenCfg exit ucValue %x\n", ucValue); - - - return ucValue; -} -#endif /* 0 */ - -int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, +int dsp3780I_EnableDSP(struct dsp_3780i_config_settings *pSettings, unsigned short *pIrqMap, unsigned short *pDmaMap) { @@ -191,25 +137,13 @@ int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, DSP_CLOCK_CONTROL_2 rClockControl2; DSP_ISA_SLAVE_CONTROL rSlaveControl; DSP_HBRIDGE_CONTROL rHBridgeControl; - unsigned short ChipID = 0; unsigned short tval; - - PRINTK_2(TRACE_3780I, - "3780i::dsp3780I_EnableDSP entry pSettings->bDSPEnabled %x\n", - pSettings->bDSPEnabled); - - if (!pSettings->bDSPEnabled) { - PRINTK_ERROR( KERN_ERR "3780i::dsp3780I_EnableDSP: Error: DSP not enabled. Aborting.\n" ); + pr_err("%s: Error: DSP not enabled. Aborting.\n", __func__); return -EIO; } - - PRINTK_2(TRACE_3780I, - "3780i::dsp3780i_EnableDSP entry pSettings->bModemEnabled %x\n", - pSettings->bModemEnabled); - if (pSettings->bModemEnabled) { rUartCfg1.Reserved = rUartCfg2.Reserved = 0; rUartCfg1.IrqActiveLow = pSettings->bUartIrqActiveLow; @@ -282,23 +216,10 @@ int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, rSlaveControl.ConfigMode = false; rSlaveControl.Reserved = 0; - PRINTK_4(TRACE_3780I, - "3780i::dsp3780i_EnableDSP usDspBaseIO %x index %x taddr %x\n", - usDspBaseIO, DSP_IsaSlaveControl, - usDspBaseIO + DSP_IsaSlaveControl); - - PRINTK_2(TRACE_3780I, - "3780i::dsp3780i_EnableDSP rSlaveContrl %x\n", - MKWORD(rSlaveControl)); - spin_lock_irqsave(&dsp_lock, flags); OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl); - PRINTK_2(TRACE_3780I, - "3780i::dsp3780i_EnableDSP rSlaveControl 2 %x\n", tval); - - for (i = 0; i < 11; i++) udelay(2000); @@ -307,10 +228,6 @@ int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl); - PRINTK_2(TRACE_3780I, - "3780i::dsp3780i_EnableDSP rSlaveControl 3 %x\n", tval); - - /* Program our general configuration registers */ WriteGenCfg(DSP_HBridgeCfg1Index, MKBYTE(rHBridgeCfg1)); WriteGenCfg(DSP_HBridgeCfg2Index, MKBYTE(rHBridgeCfg2)); @@ -331,10 +248,6 @@ int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, rHBridgeControl.IoAutoInc = false; rHBridgeControl.DiagnosticMode = false; - PRINTK_3(TRACE_3780I, - "3780i::dsp3780i_EnableDSP DSP_HBridgeControl %x rHBridgeControl %x\n", - DSP_HBridgeControl, MKWORD(rHBridgeControl)); - OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); spin_unlock_irqrestore(&dsp_lock, flags); WriteMsaCfg(DSP_LBusTimeoutDisable, MKWORD(rLBusTimeoutDisable)); @@ -342,24 +255,17 @@ int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, WriteMsaCfg(DSP_ClockControl_2, MKWORD(rClockControl2)); WriteMsaCfg(DSP_ChipReset, MKWORD(rChipReset)); - ChipID = ReadMsaCfg(DSP_ChipID); - - PRINTK_2(TRACE_3780I, - "3780i::dsp3780I_EnableDSP exiting bRC=true, ChipID %x\n", - ChipID); + ReadMsaCfg(DSP_ChipID); return 0; } -int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings) +int dsp3780I_DisableDSP(struct dsp_3780i_config_settings *pSettings) { unsigned long flags; unsigned short usDspBaseIO = pSettings->usDspBaseIO; DSP_ISA_SLAVE_CONTROL rSlaveControl; - - PRINTK_1(TRACE_3780I, "3780i::dsp3780i_DisableDSP entry\n"); - rSlaveControl.ClockControl = 0; rSlaveControl.SoftReset = true; rSlaveControl.ConfigMode = false; @@ -375,29 +281,20 @@ int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings) udelay(5); - - PRINTK_1(TRACE_3780I, "3780i::dsp3780i_DisableDSP exit\n"); - return 0; } -int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings) +int dsp3780I_Reset(struct dsp_3780i_config_settings *pSettings) { unsigned long flags; unsigned short usDspBaseIO = pSettings->usDspBaseIO; DSP_BOOT_DOMAIN rBootDomain; DSP_HBRIDGE_CONTROL rHBridgeControl; - - PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Reset entry\n"); - spin_lock_irqsave(&dsp_lock, flags); /* Mask DSP to PC interrupt */ MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); - PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Reset rHBridgeControl %x\n", - MKWORD(rHBridgeControl)); - rHBridgeControl.EnableDspInt = false; OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); spin_unlock_irqrestore(&dsp_lock, flags); @@ -408,9 +305,6 @@ int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings) rBootDomain.NMI = true; rBootDomain.Reserved = 0; - PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Reset rBootDomain %x\n", - MKWORD(rBootDomain)); - WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); /* Reset all the chiplets and then reactivate them */ @@ -419,24 +313,17 @@ int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings) WriteMsaCfg(DSP_ChipReset, (unsigned short) (~pSettings->usChipletEnable)); - - PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Reset exit bRC=0\n"); - return 0; } -int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings) +int dsp3780I_Run(struct dsp_3780i_config_settings *pSettings) { unsigned long flags; unsigned short usDspBaseIO = pSettings->usDspBaseIO; DSP_BOOT_DOMAIN rBootDomain; DSP_HBRIDGE_CONTROL rHBridgeControl; - - PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Run entry\n"); - - /* Transition the core to a running state */ rBootDomain.ResetCore = true; rBootDomain.Halt = false; @@ -459,15 +346,9 @@ int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings) MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); rHBridgeControl.EnableDspInt = true; - PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Run rHBridgeControl %x\n", - MKWORD(rHBridgeControl)); - OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); spin_unlock_irqrestore(&dsp_lock, flags); - - PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Run exit bRC=true\n"); - return 0; } @@ -479,12 +360,6 @@ int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned short __user *pusBuffer = pvBuffer; unsigned short val; - - PRINTK_5(TRACE_3780I, - "3780i::dsp3780I_ReadDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", - usDspBaseIO, pusBuffer, uCount, ulDSPAddr); - - /* Set the initial MSA address. No adjustments need to be made to data store addresses */ spin_lock_irqsave(&dsp_lock, flags); OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); @@ -499,17 +374,9 @@ int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer, if(put_user(val, pusBuffer++)) return -EFAULT; - PRINTK_3(TRACE_3780I, - "3780I::dsp3780I_ReadDStore uCount %x val %x\n", - uCount, val); - PaceMsaAccess(usDspBaseIO); } - - PRINTK_1(TRACE_3780I, - "3780I::dsp3780I_ReadDStore exit bRC=true\n"); - return 0; } @@ -521,12 +388,6 @@ int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO, unsigned short __user *pusBuffer = pvBuffer; unsigned short val; - - PRINTK_5(TRACE_3780I, - "3780i::dsp3780I_ReadAndDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", - usDspBaseIO, pusBuffer, uCount, ulDSPAddr); - - /* Set the initial MSA address. No adjustments need to be made to data store addresses */ spin_lock_irqsave(&dsp_lock, flags); OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); @@ -541,17 +402,9 @@ int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO, if(put_user(val, pusBuffer++)) return -EFAULT; - PRINTK_3(TRACE_3780I, - "3780I::dsp3780I_ReadAndCleanDStore uCount %x val %x\n", - uCount, val); - PaceMsaAccess(usDspBaseIO); } - - PRINTK_1(TRACE_3780I, - "3780I::dsp3780I_ReadAndClearDStore exit bRC=true\n"); - return 0; } @@ -562,12 +415,6 @@ int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned long flags; unsigned short __user *pusBuffer = pvBuffer; - - PRINTK_5(TRACE_3780I, - "3780i::dsp3780D_WriteDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", - usDspBaseIO, pusBuffer, uCount, ulDSPAddr); - - /* Set the initial MSA address. No adjustments need to be made to data store addresses */ spin_lock_irqsave(&dsp_lock, flags); OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); @@ -583,17 +430,9 @@ int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer, OutWordDsp(DSP_MsaDataDSISHigh, val); spin_unlock_irqrestore(&dsp_lock, flags); - PRINTK_3(TRACE_3780I, - "3780I::dsp3780I_WriteDStore uCount %x val %x\n", - uCount, val); - PaceMsaAccess(usDspBaseIO); } - - PRINTK_1(TRACE_3780I, - "3780I::dsp3780D_WriteDStore exit bRC=true\n"); - return 0; } @@ -604,10 +443,6 @@ int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned long flags; unsigned short __user *pusBuffer = pvBuffer; - PRINTK_5(TRACE_3780I, - "3780i::dsp3780I_ReadIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", - usDspBaseIO, pusBuffer, uCount, ulDSPAddr); - /* * Set the initial MSA address. To convert from an instruction store * address to an MSA address @@ -631,17 +466,10 @@ int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer, if(put_user(val_hi, pusBuffer++)) return -EFAULT; - PRINTK_4(TRACE_3780I, - "3780I::dsp3780I_ReadIStore uCount %x val_lo %x val_hi %x\n", - uCount, val_lo, val_hi); - PaceMsaAccess(usDspBaseIO); } - PRINTK_1(TRACE_3780I, - "3780I::dsp3780I_ReadIStore exit bRC=true\n"); - return 0; } @@ -652,11 +480,6 @@ int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned long flags; unsigned short __user *pusBuffer = pvBuffer; - PRINTK_5(TRACE_3780I, - "3780i::dsp3780I_WriteIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", - usDspBaseIO, pusBuffer, uCount, ulDSPAddr); - - /* * Set the initial MSA address. To convert from an instruction store * address to an MSA address @@ -680,17 +503,9 @@ int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer, OutWordDsp(DSP_MsaDataDSISHigh, val_hi); spin_unlock_irqrestore(&dsp_lock, flags); - PRINTK_4(TRACE_3780I, - "3780I::dsp3780I_WriteIStore uCount %x val_lo %x val_hi %x\n", - uCount, val_lo, val_hi); - PaceMsaAccess(usDspBaseIO); - } - PRINTK_1(TRACE_3780I, - "3780I::dsp3780I_WriteIStore exit bRC=true\n"); - return 0; } @@ -700,12 +515,6 @@ int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, { unsigned long flags; DSP_HBRIDGE_CONTROL rHBridgeControl; - unsigned short temp; - - - PRINTK_3(TRACE_3780I, - "3780i::dsp3780I_GetIPCSource entry usDspBaseIO %x pusIPCSource %p\n", - usDspBaseIO, pusIPCSource); /* * Disable DSP to PC interrupts, read the interrupt register, @@ -717,22 +526,11 @@ int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); *pusIPCSource = InWordDsp(DSP_Interrupt); - temp = (unsigned short) ~(*pusIPCSource); - - PRINTK_3(TRACE_3780I, - "3780i::dsp3780I_GetIPCSource, usIPCSource %x ~ %x\n", - *pusIPCSource, temp); - OutWordDsp(DSP_Interrupt, (unsigned short) ~(*pusIPCSource)); rHBridgeControl.EnableDspInt = true; OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); spin_unlock_irqrestore(&dsp_lock, flags); - - PRINTK_2(TRACE_3780I, - "3780i::dsp3780I_GetIPCSource exit usIPCSource %x\n", - *pusIPCSource); - return 0; } diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h index 95164246afd1a..53dafceb20e0e 100644 --- a/drivers/char/mwave/3780i.h +++ b/drivers/char/mwave/3780i.h @@ -261,7 +261,7 @@ typedef struct { * the only values maintained by the 3780i support layer are the saved UART * registers. */ -typedef struct _DSP_3780I_CONFIG_SETTINGS { +struct dsp_3780i_config_settings { /* Location of base configuration register */ unsigned short usBaseConfigIO; @@ -313,16 +313,16 @@ typedef struct _DSP_3780I_CONFIG_SETTINGS { unsigned char ucSCR; /* Scratch register */ unsigned char ucDLL; /* Divisor latch, low byte */ unsigned char ucDLM; /* Divisor latch, high byte */ -} DSP_3780I_CONFIG_SETTINGS; +}; /* 3780i support functions */ -int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, +int dsp3780I_EnableDSP(struct dsp_3780i_config_settings *pSettings, unsigned short *pIrqMap, unsigned short *pDmaMap); -int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings); -int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings); -int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings); +int dsp3780I_DisableDSP(struct dsp_3780i_config_settings *pSettings); +int dsp3780I_Reset(struct dsp_3780i_config_settings *pSettings); +int dsp3780I_Run(struct dsp_3780i_config_settings *pSettings); int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer, unsigned uCount, unsigned long ulDSPAddr); int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO, diff --git a/drivers/char/mwave/Makefile b/drivers/char/mwave/Makefile index a24fe96e3c969..e56c1a3755353 100644 --- a/drivers/char/mwave/Makefile +++ b/drivers/char/mwave/Makefile @@ -8,9 +8,3 @@ obj-$(CONFIG_MWAVE) += mwave.o mwave-y := mwavedd.o smapi.o tp3780i.o 3780i.o - -# To have the mwave driver disable other uarts if necessary -# ccflags-y := -DMWAVE_FUTZ_WITH_OTHER_DEVICES - -# To compile in lots (~20 KiB) of run-time enablable printk()s for debugging: -ccflags-y += -DMW_TRACE diff --git a/drivers/char/mwave/README b/drivers/char/mwave/README index c2a58f428bc84..6224aa814c628 100644 --- a/drivers/char/mwave/README +++ b/drivers/char/mwave/README @@ -4,16 +4,6 @@ Module options The mwave module takes the following options. Note that these options are not saved by the BIOS and so do not persist after unload and reload. - mwave_debug=value, where value is bitwise OR of trace flags: - 0x0001 mwavedd api tracing - 0x0002 smapi api tracing - 0x0004 3780i tracing - 0x0008 tp3780i tracing - - Tracing only occurs if the driver has been compiled with the - MW_TRACE macro #defined (i.e. let ccflags-y := -DMW_TRACE - in the Makefile). - mwave_3780i_irq=5/7/10/11/15 If the dsp irq has not been setup and stored in bios by the thinkpad configuration utility then this parameter allows the diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c index 11272d605ecd5..640a9cb0dd8d6 100644 --- a/drivers/char/mwave/mwavedd.c +++ b/drivers/char/mwave/mwavedd.c @@ -46,6 +46,8 @@ * First release to the public */ +#define pr_fmt(fmt) "mwavedd: " fmt + #include #include #include @@ -75,131 +77,62 @@ MODULE_LICENSE("GPL"); * We'll depend on users using the tpctl utility to do that for now */ static DEFINE_MUTEX(mwave_mutex); -int mwave_debug = 0; int mwave_3780i_irq = 0; int mwave_3780i_io = 0; int mwave_uart_irq = 0; int mwave_uart_io = 0; -module_param(mwave_debug, int, 0); module_param_hw(mwave_3780i_irq, int, irq, 0); module_param_hw(mwave_3780i_io, int, ioport, 0); module_param_hw(mwave_uart_irq, int, irq, 0); module_param_hw(mwave_uart_io, int, ioport, 0); -static int mwave_open(struct inode *inode, struct file *file); -static int mwave_close(struct inode *inode, struct file *file); -static long mwave_ioctl(struct file *filp, unsigned int iocmd, - unsigned long ioarg); - -MWAVE_DEVICE_DATA mwave_s_mdd; - -static int mwave_open(struct inode *inode, struct file *file) -{ - unsigned int retval = 0; - - PRINTK_3(TRACE_MWAVE, - "mwavedd::mwave_open, entry inode %p file %p\n", - inode, file); - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_open, exit return retval %x\n", retval); - - return retval; -} - -static int mwave_close(struct inode *inode, struct file *file) -{ - unsigned int retval = 0; - - PRINTK_3(TRACE_MWAVE, - "mwavedd::mwave_close, entry inode %p file %p\n", - inode, file); - - PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_close, exit retval %x\n", - retval); - - return retval; -} +struct mwave_device_data mwave_s_mdd; static long mwave_ioctl(struct file *file, unsigned int iocmd, unsigned long ioarg) { unsigned int retval = 0; - pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; + struct mwave_device_data *pDrvData = &mwave_s_mdd; void __user *arg = (void __user *)ioarg; - PRINTK_4(TRACE_MWAVE, - "mwavedd::mwave_ioctl, entry file %p cmd %x arg %x\n", - file, iocmd, (int) ioarg); - switch (iocmd) { case IOCTL_MW_RESET: - PRINTK_1(TRACE_MWAVE, - "mwavedd::mwave_ioctl, IOCTL_MW_RESET" - " calling tp3780I_ResetDSP\n"); mutex_lock(&mwave_mutex); retval = tp3780I_ResetDSP(&pDrvData->rBDData); mutex_unlock(&mwave_mutex); - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_ioctl, IOCTL_MW_RESET" - " retval %x from tp3780I_ResetDSP\n", - retval); break; case IOCTL_MW_RUN: - PRINTK_1(TRACE_MWAVE, - "mwavedd::mwave_ioctl, IOCTL_MW_RUN" - " calling tp3780I_StartDSP\n"); mutex_lock(&mwave_mutex); retval = tp3780I_StartDSP(&pDrvData->rBDData); mutex_unlock(&mwave_mutex); - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_ioctl, IOCTL_MW_RUN" - " retval %x from tp3780I_StartDSP\n", - retval); break; case IOCTL_MW_DSP_ABILITIES: { - MW_ABILITIES rAbilities; + struct mw_abilities rAbilities; - PRINTK_1(TRACE_MWAVE, - "mwavedd::mwave_ioctl," - " IOCTL_MW_DSP_ABILITIES calling" - " tp3780I_QueryAbilities\n"); mutex_lock(&mwave_mutex); retval = tp3780I_QueryAbilities(&pDrvData->rBDData, &rAbilities); mutex_unlock(&mwave_mutex); - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES" - " retval %x from tp3780I_QueryAbilities\n", - retval); if (retval == 0) { - if( copy_to_user(arg, &rAbilities, - sizeof(MW_ABILITIES)) ) + if (copy_to_user(arg, &rAbilities, sizeof(rAbilities))) return -EFAULT; } - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES" - " exit retval %x\n", - retval); } break; case IOCTL_MW_READ_DATA: case IOCTL_MW_READCLEAR_DATA: { - MW_READWRITE rReadData; + struct mw_readwrite rReadData; unsigned short __user *pusBuffer = NULL; if( copy_from_user(&rReadData, arg, - sizeof(MW_READWRITE)) ) + sizeof(struct mw_readwrite)) ) return -EFAULT; pusBuffer = (unsigned short __user *) (rReadData.pBuf); - PRINTK_4(TRACE_MWAVE, - "mwavedd::mwave_ioctl IOCTL_MW_READ_DATA," - " size %lx, ioarg %lx pusBuffer %p\n", - rReadData.ulDataLength, ioarg, pusBuffer); mutex_lock(&mwave_mutex); retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd, @@ -211,19 +144,13 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, break; case IOCTL_MW_READ_INST: { - MW_READWRITE rReadData; + struct mw_readwrite rReadData; unsigned short __user *pusBuffer = NULL; - if( copy_from_user(&rReadData, arg, - sizeof(MW_READWRITE)) ) + if (copy_from_user(&rReadData, arg, sizeof(rReadData))) return -EFAULT; pusBuffer = (unsigned short __user *) (rReadData.pBuf); - PRINTK_4(TRACE_MWAVE, - "mwavedd::mwave_ioctl IOCTL_MW_READ_INST," - " size %lx, ioarg %lx pusBuffer %p\n", - rReadData.ulDataLength / 2, ioarg, - pusBuffer); mutex_lock(&mwave_mutex); retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd, pusBuffer, @@ -234,19 +161,13 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, break; case IOCTL_MW_WRITE_DATA: { - MW_READWRITE rWriteData; + struct mw_readwrite rWriteData; unsigned short __user *pusBuffer = NULL; - if( copy_from_user(&rWriteData, arg, - sizeof(MW_READWRITE)) ) + if (copy_from_user(&rWriteData, arg, sizeof(rWriteData))) return -EFAULT; pusBuffer = (unsigned short __user *) (rWriteData.pBuf); - PRINTK_4(TRACE_MWAVE, - "mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA," - " size %lx, ioarg %lx pusBuffer %p\n", - rWriteData.ulDataLength, ioarg, - pusBuffer); mutex_lock(&mwave_mutex); retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd, pusBuffer, @@ -257,19 +178,13 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, break; case IOCTL_MW_WRITE_INST: { - MW_READWRITE rWriteData; + struct mw_readwrite rWriteData; unsigned short __user *pusBuffer = NULL; - if( copy_from_user(&rWriteData, arg, - sizeof(MW_READWRITE)) ) + if (copy_from_user(&rWriteData, arg, sizeof(rWriteData))) return -EFAULT; pusBuffer = (unsigned short __user *)(rWriteData.pBuf); - PRINTK_4(TRACE_MWAVE, - "mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST," - " size %lx, ioarg %lx pusBuffer %p\n", - rWriteData.ulDataLength, ioarg, - pusBuffer); mutex_lock(&mwave_mutex); retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData, iocmd, pusBuffer, @@ -283,30 +198,17 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, unsigned int ipcnum = (unsigned int) ioarg; if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) { - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd::mwave_ioctl:" - " IOCTL_MW_REGISTER_IPC:" - " Error: Invalid ipcnum %x\n", - ipcnum); + pr_err("%s: IOCTL_MW_REGISTER_IPC: Error: Invalid ipcnum %x\n", + __func__, ipcnum); return -EINVAL; } ipcnum = array_index_nospec(ipcnum, ARRAY_SIZE(pDrvData->IPCs)); - PRINTK_3(TRACE_MWAVE, - "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC" - " ipcnum %x entry usIntCount %x\n", - ipcnum, - pDrvData->IPCs[ipcnum].usIntCount); mutex_lock(&mwave_mutex); pDrvData->IPCs[ipcnum].bIsHere = false; pDrvData->IPCs[ipcnum].bIsEnabled = true; mutex_unlock(&mwave_mutex); - - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC" - " ipcnum %x exit\n", - ipcnum); } break; @@ -314,28 +216,17 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, unsigned int ipcnum = (unsigned int) ioarg; if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) { - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd::mwave_ioctl:" - " IOCTL_MW_GET_IPC: Error:" - " Invalid ipcnum %x\n", ipcnum); + pr_err("%s: IOCTL_MW_GET_IPC: Error: Invalid ipcnum %x\n", __func__, + ipcnum); return -EINVAL; } ipcnum = array_index_nospec(ipcnum, ARRAY_SIZE(pDrvData->IPCs)); - PRINTK_3(TRACE_MWAVE, - "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC" - " ipcnum %x, usIntCount %x\n", - ipcnum, - pDrvData->IPCs[ipcnum].usIntCount); - + mutex_lock(&mwave_mutex); if (pDrvData->IPCs[ipcnum].bIsEnabled == true) { DECLARE_WAITQUEUE(wait, current); - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_ioctl, thread for" - " ipc %x going to sleep\n", - ipcnum); add_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait); pDrvData->IPCs[ipcnum].bIsHere = true; set_current_state(TASK_INTERRUPTIBLE); @@ -343,31 +234,15 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, /* the interrupt handler while we were gone */ if (pDrvData->IPCs[ipcnum].usIntCount == 1) { /* first int has occurred (race condition) */ pDrvData->IPCs[ipcnum].usIntCount = 2; /* first int has been handled */ - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_ioctl" - " IOCTL_MW_GET_IPC ipcnum %x" - " handling first int\n", - ipcnum); } else { /* either 1st int has not yet occurred, or we have already handled the first int */ schedule(); if (pDrvData->IPCs[ipcnum].usIntCount == 1) { pDrvData->IPCs[ipcnum].usIntCount = 2; } - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_ioctl" - " IOCTL_MW_GET_IPC ipcnum %x" - " woke up and returning to" - " application\n", - ipcnum); } pDrvData->IPCs[ipcnum].bIsHere = false; remove_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait); set_current_state(TASK_RUNNING); - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC," - " returning thread for ipc %x" - " processing\n", - ipcnum); } mutex_unlock(&mwave_mutex); } @@ -376,16 +251,9 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, case IOCTL_MW_UNREGISTER_IPC: { unsigned int ipcnum = (unsigned int) ioarg; - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC" - " ipcnum %x\n", - ipcnum); if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) { - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd::mwave_ioctl:" - " IOCTL_MW_UNREGISTER_IPC:" - " Error: Invalid ipcnum %x\n", - ipcnum); + pr_err("%s: IOCTL_MW_UNREGISTER_IPC: Error: Invalid ipcnum %x\n", + __func__, ipcnum); return -EINVAL; } ipcnum = array_index_nospec(ipcnum, @@ -405,35 +273,9 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, return -ENOTTY; } /* switch */ - PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_ioctl, exit retval %x\n", retval); - return retval; } - -static ssize_t mwave_read(struct file *file, char __user *buf, size_t count, - loff_t * ppos) -{ - PRINTK_5(TRACE_MWAVE, - "mwavedd::mwave_read entry file %p, buf %p, count %zx ppos %p\n", - file, buf, count, ppos); - - return -EINVAL; -} - - -static ssize_t mwave_write(struct file *file, const char __user *buf, - size_t count, loff_t * ppos) -{ - PRINTK_5(TRACE_MWAVE, - "mwavedd::mwave_write entry file %p, buf %p," - " count %zx ppos %p\n", - file, buf, count, ppos); - - return -EINVAL; -} - - static int register_serial_portandirq(unsigned int port, int irq) { struct uart_8250_port uart; @@ -446,9 +288,7 @@ static int register_serial_portandirq(unsigned int port, int irq) /* OK */ break; default: - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd::register_serial_portandirq:" - " Error: Illegal port %x\n", port ); + pr_err("%s: Error: Illegal port %x\n", __func__, port); return -1; } /* switch */ /* port is okay */ @@ -461,9 +301,7 @@ static int register_serial_portandirq(unsigned int port, int irq) /* OK */ break; default: - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd::register_serial_portandirq:" - " Error: Illegal irq %x\n", irq ); + pr_err("%s: Error: Illegal irq %x\n", __func__, irq); return -1; } /* switch */ /* irq is okay */ @@ -478,56 +316,14 @@ static int register_serial_portandirq(unsigned int port, int irq) return serial8250_register_8250_port(&uart); } - static const struct file_operations mwave_fops = { .owner = THIS_MODULE, - .read = mwave_read, - .write = mwave_write, .unlocked_ioctl = mwave_ioctl, - .open = mwave_open, - .release = mwave_close, .llseek = default_llseek, }; - static struct miscdevice mwave_misc_dev = { MWAVE_MINOR, "mwave", &mwave_fops }; -#if 0 /* totally b0rked */ -/* - * sysfs support - */ - -struct device mwave_device; - -/* Prevent code redundancy, create a macro for mwave_show_* functions. */ -#define mwave_show_function(attr_name, format_string, field) \ -static ssize_t mwave_show_##attr_name(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - DSP_3780I_CONFIG_SETTINGS *pSettings = \ - &mwave_s_mdd.rBDData.rDspSettings; \ - return sprintf(buf, format_string, pSettings->field); \ -} - -/* All of our attributes are read attributes. */ -#define mwave_dev_rd_attr(attr_name, format_string, field) \ - mwave_show_function(attr_name, format_string, field) \ -static DEVICE_ATTR(attr_name, S_IRUGO, mwave_show_##attr_name, NULL) - -mwave_dev_rd_attr (3780i_dma, "%i\n", usDspDma); -mwave_dev_rd_attr (3780i_irq, "%i\n", usDspIrq); -mwave_dev_rd_attr (3780i_io, "%#.4x\n", usDspBaseIO); -mwave_dev_rd_attr (uart_irq, "%i\n", usUartIrq); -mwave_dev_rd_attr (uart_io, "%#.4x\n", usUartBaseIO); - -static struct device_attribute * const mwave_dev_attrs[] = { - &dev_attr_3780i_dma, - &dev_attr_3780i_irq, - &dev_attr_3780i_io, - &dev_attr_uart_irq, - &dev_attr_uart_io, -}; -#endif - /* * mwave_init is called on module load * @@ -536,20 +332,7 @@ static struct device_attribute * const mwave_dev_attrs[] = { */ static void mwave_exit(void) { - pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; - - PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit entry\n"); - -#if 0 - for (i = 0; i < pDrvData->nr_registered_attrs; i++) - device_remove_file(&mwave_device, mwave_dev_attrs[i]); - pDrvData->nr_registered_attrs = 0; - - if (pDrvData->device_registered) { - device_unregister(&mwave_device); - pDrvData->device_registered = false; - } -#endif + struct mwave_device_data *pDrvData = &mwave_s_mdd; if ( pDrvData->sLine >= 0 ) { serial8250_unregister_port(pDrvData->sLine); @@ -566,8 +349,6 @@ static void mwave_exit(void) if (pDrvData->bBDInitialized) { tp3780I_Cleanup(&pDrvData->rBDData); } - - PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit exit\n"); } module_exit(mwave_exit); @@ -576,11 +357,9 @@ static int __init mwave_init(void) { int i; int retval = 0; - pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; + struct mwave_device_data *pDrvData = &mwave_s_mdd; - PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_init entry\n"); - - memset(&mwave_s_mdd, 0, sizeof(MWAVE_DEVICE_DATA)); + memset(&mwave_s_mdd, 0, sizeof(mwave_s_mdd)); pDrvData->bBDInitialized = false; pDrvData->bResourcesClaimed = false; @@ -597,60 +376,34 @@ static int __init mwave_init(void) } retval = tp3780I_InitializeBoardData(&pDrvData->rBDData); - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_init, return from tp3780I_InitializeBoardData" - " retval %x\n", - retval); if (retval) { - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd::mwave_init: Error:" - " Failed to initialize board data\n"); + pr_err("%s: Error: Failed to initialize board data\n", __func__); goto cleanup_error; } pDrvData->bBDInitialized = true; retval = tp3780I_CalcResources(&pDrvData->rBDData); - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_init, return from tp3780I_CalcResources" - " retval %x\n", - retval); if (retval) { - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd:mwave_init: Error:" - " Failed to calculate resources\n"); + pr_err("%s: Error: Failed to calculate resources\n", __func__); goto cleanup_error; } retval = tp3780I_ClaimResources(&pDrvData->rBDData); - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_init, return from tp3780I_ClaimResources" - " retval %x\n", - retval); if (retval) { - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd:mwave_init: Error:" - " Failed to claim resources\n"); + pr_err("%s: Error: Failed to claim resources\n", __func__); goto cleanup_error; } pDrvData->bResourcesClaimed = true; retval = tp3780I_EnableDSP(&pDrvData->rBDData); - PRINTK_2(TRACE_MWAVE, - "mwavedd::mwave_init, return from tp3780I_EnableDSP" - " retval %x\n", - retval); if (retval) { - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd:mwave_init: Error:" - " Failed to enable DSP\n"); + pr_err("%s: Error: Failed to enable DSP\n", __func__); goto cleanup_error; } pDrvData->bDSPEnabled = true; if (misc_register(&mwave_misc_dev) < 0) { - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd:mwave_init: Error:" - " Failed to register misc device\n"); + pr_err("%s: Error: Failed to register misc device\n", __func__); goto cleanup_error; } pDrvData->bMwaveDevRegistered = true; @@ -660,40 +413,16 @@ static int __init mwave_init(void) pDrvData->rBDData.rDspSettings.usUartIrq ); if (pDrvData->sLine < 0) { - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd:mwave_init: Error:" - " Failed to register serial driver\n"); + pr_err("%s: Error: Failed to register serial driver\n", __func__); goto cleanup_error; } /* uart is registered */ -#if 0 - /* sysfs */ - memset(&mwave_device, 0, sizeof (struct device)); - dev_set_name(&mwave_device, "mwave"); - - if (device_register(&mwave_device)) - goto cleanup_error; - pDrvData->device_registered = true; - for (i = 0; i < ARRAY_SIZE(mwave_dev_attrs); i++) { - if(device_create_file(&mwave_device, mwave_dev_attrs[i])) { - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd:mwave_init: Error:" - " Failed to create sysfs file %s\n", - mwave_dev_attrs[i]->attr.name); - goto cleanup_error; - } - pDrvData->nr_registered_attrs++; - } -#endif - /* SUCCESS! */ return 0; cleanup_error: - PRINTK_ERROR(KERN_ERR_MWAVE - "mwavedd::mwave_init: Error:" - " Failed to initialize\n"); + pr_err("%s: Error: Failed to initialize\n", __func__); mwave_exit(); /* clean up */ return -EIO; diff --git a/drivers/char/mwave/mwavedd.h b/drivers/char/mwave/mwavedd.h index 21cb09c7bed70..e1da1493eec57 100644 --- a/drivers/char/mwave/mwavedd.h +++ b/drivers/char/mwave/mwavedd.h @@ -56,97 +56,35 @@ #include #include -extern int mwave_debug; extern int mwave_3780i_irq; extern int mwave_3780i_io; extern int mwave_uart_irq; extern int mwave_uart_io; -#define PRINTK_ERROR printk -#define KERN_ERR_MWAVE KERN_ERR "mwave: " - -#define TRACE_MWAVE 0x0001 -#define TRACE_SMAPI 0x0002 -#define TRACE_3780I 0x0004 -#define TRACE_TP3780I 0x0008 - -#ifdef MW_TRACE -#define PRINTK_1(f,s) \ - if (f & (mwave_debug)) { \ - printk(s); \ - } - -#define PRINTK_2(f,s,v1) \ - if (f & (mwave_debug)) { \ - printk(s,v1); \ - } - -#define PRINTK_3(f,s,v1,v2) \ - if (f & (mwave_debug)) { \ - printk(s,v1,v2); \ - } - -#define PRINTK_4(f,s,v1,v2,v3) \ - if (f & (mwave_debug)) { \ - printk(s,v1,v2,v3); \ - } - -#define PRINTK_5(f,s,v1,v2,v3,v4) \ - if (f & (mwave_debug)) { \ - printk(s,v1,v2,v3,v4); \ - } - -#define PRINTK_6(f,s,v1,v2,v3,v4,v5) \ - if (f & (mwave_debug)) { \ - printk(s,v1,v2,v3,v4,v5); \ - } - -#define PRINTK_7(f,s,v1,v2,v3,v4,v5,v6) \ - if (f & (mwave_debug)) { \ - printk(s,v1,v2,v3,v4,v5,v6); \ - } - -#define PRINTK_8(f,s,v1,v2,v3,v4,v5,v6,v7) \ - if (f & (mwave_debug)) { \ - printk(s,v1,v2,v3,v4,v5,v6,v7); \ - } - -#else -#define PRINTK_1(f,s) -#define PRINTK_2(f,s,v1) -#define PRINTK_3(f,s,v1,v2) -#define PRINTK_4(f,s,v1,v2,v3) -#define PRINTK_5(f,s,v1,v2,v3,v4) -#define PRINTK_6(f,s,v1,v2,v3,v4,v5) -#define PRINTK_7(f,s,v1,v2,v3,v4,v5,v6) -#define PRINTK_8(f,s,v1,v2,v3,v4,v5,v6,v7) -#endif - - -typedef struct _MWAVE_IPC { +struct mwave_ipc { unsigned short usIntCount; /* 0=none, 1=first, 2=greater than 1st */ bool bIsEnabled; bool bIsHere; /* entry spin lock */ wait_queue_head_t ipc_wait_queue; -} MWAVE_IPC; +}; -typedef struct _MWAVE_DEVICE_DATA { - THINKPAD_BD_DATA rBDData; /* board driver's data area */ +struct mwave_device_data { + struct thinkpad_bd_data rBDData; /* board driver's data area */ unsigned long ulIPCSource_ISR; /* IPC source bits for recently processed intr, set during ISR processing */ unsigned long ulIPCSource_DPC; /* IPC source bits for recently processed intr, set during DPC processing */ bool bBDInitialized; bool bResourcesClaimed; bool bDSPEnabled; bool bDSPReset; - MWAVE_IPC IPCs[16]; + struct mwave_ipc IPCs[16]; bool bMwaveDevRegistered; short sLine; int nr_registered_attrs; int device_registered; -} MWAVE_DEVICE_DATA, *pMWAVE_DEVICE_DATA; +}; -extern MWAVE_DEVICE_DATA mwave_s_mdd; +extern struct mwave_device_data mwave_s_mdd; #endif diff --git a/drivers/char/mwave/mwavepub.h b/drivers/char/mwave/mwavepub.h index 60c961ae23b4c..280327bdaa38f 100644 --- a/drivers/char/mwave/mwavepub.h +++ b/drivers/char/mwave/mwavepub.h @@ -53,7 +53,7 @@ #include -typedef struct _MW_ABILITIES { +struct mw_abilities { unsigned long instr_per_sec; unsigned long data_size; unsigned long inst_size; @@ -63,27 +63,27 @@ typedef struct _MW_ABILITIES { unsigned long component_list[7]; char mwave_os_name[16]; char bios_task_name[16]; -} MW_ABILITIES, *pMW_ABILITIES; +}; -typedef struct _MW_READWRITE { +struct mw_readwrite { unsigned short usDspAddress; /* The dsp address */ unsigned long ulDataLength; /* The size in bytes of the data or user buffer */ void __user *pBuf; /* Input:variable sized buffer */ -} MW_READWRITE, *pMW_READWRITE; +}; #define IOCTL_MW_RESET _IO(MWAVE_MINOR,1) #define IOCTL_MW_RUN _IO(MWAVE_MINOR,2) -#define IOCTL_MW_DSP_ABILITIES _IOR(MWAVE_MINOR,3,MW_ABILITIES) -#define IOCTL_MW_READ_DATA _IOR(MWAVE_MINOR,4,MW_READWRITE) -#define IOCTL_MW_READCLEAR_DATA _IOR(MWAVE_MINOR,5,MW_READWRITE) -#define IOCTL_MW_READ_INST _IOR(MWAVE_MINOR,6,MW_READWRITE) -#define IOCTL_MW_WRITE_DATA _IOW(MWAVE_MINOR,7,MW_READWRITE) -#define IOCTL_MW_WRITE_INST _IOW(MWAVE_MINOR,8,MW_READWRITE) +#define IOCTL_MW_DSP_ABILITIES _IOR(MWAVE_MINOR,3,struct mw_abilities) +#define IOCTL_MW_READ_DATA _IOR(MWAVE_MINOR,4,struct mw_readwrite) +#define IOCTL_MW_READCLEAR_DATA _IOR(MWAVE_MINOR,5,struct mw_readwrite) +#define IOCTL_MW_READ_INST _IOR(MWAVE_MINOR,6,struct mw_readwrite) +#define IOCTL_MW_WRITE_DATA _IOW(MWAVE_MINOR,7,struct mw_readwrite) +#define IOCTL_MW_WRITE_INST _IOW(MWAVE_MINOR,8,struct mw_readwrite) #define IOCTL_MW_REGISTER_IPC _IOW(MWAVE_MINOR,9,int) #define IOCTL_MW_UNREGISTER_IPC _IOW(MWAVE_MINOR,10,int) #define IOCTL_MW_GET_IPC _IOW(MWAVE_MINOR,11,int) -#define IOCTL_MW_TRACE _IOR(MWAVE_MINOR,12,MW_READWRITE) +#define IOCTL_MW_TRACE _IOR(MWAVE_MINOR,12,struct mw_readwrite) #endif diff --git a/drivers/char/mwave/smapi.c b/drivers/char/mwave/smapi.c index f8d79d393b692..df6354b24339c 100644 --- a/drivers/char/mwave/smapi.c +++ b/drivers/char/mwave/smapi.c @@ -46,6 +46,8 @@ * First release to the public */ +#define pr_fmt(fmt) "smapi: " fmt + #include #include /* CMOS defines */ #include "smapi.h" @@ -69,10 +71,6 @@ static int smapi_request(unsigned short inBX, unsigned short inCX, unsigned short usSmapiOK = -EIO, *pusSmapiOK = &usSmapiOK; unsigned int inBXCX = (inBX << 16) | inCX; unsigned int inDISI = (inDI << 16) | inSI; - int retval = 0; - - PRINTK_5(TRACE_SMAPI, "inBX %x inCX %x inDI %x inSI %x\n", - inBX, inCX, inDI, inSI); __asm__ __volatile__("movw $0x5380,%%ax\n\t" "movl %7,%%ebx\n\t" @@ -107,10 +105,6 @@ static int smapi_request(unsigned short inBX, unsigned short inCX, :"%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi"); - PRINTK_8(TRACE_SMAPI, - "myoutAX %x myoutBX %x myoutCX %x myoutDX %x myoutDI %x myoutSI %x usSmapiOK %x\n", - myoutAX, myoutBX, myoutCX, myoutDX, myoutDI, myoutSI, - usSmapiOK); *outAX = myoutAX; *outBX = myoutBX; *outCX = myoutCX; @@ -118,13 +112,11 @@ static int smapi_request(unsigned short inBX, unsigned short inCX, *outDI = myoutDI; *outSI = myoutSI; - retval = (usSmapiOK == 1) ? 0 : -EIO; - PRINTK_2(TRACE_SMAPI, "smapi::smapi_request exit retval %x\n", retval); - return retval; + return usSmapiOK == 1 ? 0 : -EIO; } -int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings) +int smapi_query_DSP_cfg(struct smapi_dsp_settings *pSettings) { int bRC; unsigned short usAX, usBX, usCX, usDX, usDI, usSI; @@ -134,17 +126,13 @@ int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings) static const unsigned short ausUartBases[] = { 0x03F8, 0x02F8, 0x03E8, 0x02E8 }; - PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg entry\n"); - bRC = smapi_request(0x1802, 0x0000, 0, 0, &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); if (bRC) { - PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Error: Could not get DSP Settings. Aborting.\n"); + pr_err("%s: Error: Could not get DSP Settings. Aborting.\n", __func__); return bRC; } - PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n"); - pSettings->bDSPPresent = ((usBX & 0x0100) != 0); pSettings->bDSPEnabled = ((usCX & 0x0001) != 0); pSettings->usDspIRQ = usSI & 0x00FF; @@ -154,27 +142,20 @@ int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings) } else { pSettings->usDspBaseIO = 0; } - PRINTK_6(TRACE_SMAPI, - "smapi::smapi_query_DSP_cfg get DSP Settings bDSPPresent %x bDSPEnabled %x usDspIRQ %x usDspDMA %x usDspBaseIO %x\n", - pSettings->bDSPPresent, pSettings->bDSPEnabled, - pSettings->usDspIRQ, pSettings->usDspDMA, - pSettings->usDspBaseIO); /* check for illegal values */ if ( pSettings->usDspBaseIO == 0 ) - PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP base I/O address is 0\n"); + pr_err("%s: Worry: DSP base I/O address is 0\n", __func__); if ( pSettings->usDspIRQ == 0 ) - PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP IRQ line is 0\n"); + pr_err("%s: Worry: DSP IRQ line is 0\n", __func__); bRC = smapi_request(0x1804, 0x0000, 0, 0, &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); if (bRC) { - PRINTK_ERROR("smapi::smapi_query_DSP_cfg: Error: Could not get DSP modem settings. Aborting.\n"); + pr_err("%s: Error: Could not get DSP modem settings. Aborting.\n", __func__); return bRC; } - PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n"); - pSettings->bModemEnabled = ((usCX & 0x0001) != 0); pSettings->usUartIRQ = usSI & 0x000F; if (((usSI & 0xFF00) >> 8) < ARRAY_SIZE(ausUartBases)) { @@ -183,19 +164,11 @@ int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings) pSettings->usUartBaseIO = 0; } - PRINTK_4(TRACE_SMAPI, - "smapi::smapi_query_DSP_cfg get DSP modem settings bModemEnabled %x usUartIRQ %x usUartBaseIO %x\n", - pSettings->bModemEnabled, - pSettings->usUartIRQ, - pSettings->usUartBaseIO); - /* check for illegal values */ if ( pSettings->usUartBaseIO == 0 ) - PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART base I/O address is 0\n"); + pr_err("%s: Worry: UART base I/O address is 0\n", __func__); if ( pSettings->usUartIRQ == 0 ) - PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART IRQ line is 0\n"); - - PRINTK_2(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg exit bRC %x\n", bRC); + pr_err("%s: Worry: UART IRQ line is 0\n", __func__); return bRC; } @@ -218,17 +191,14 @@ int smapi_set_DSP_cfg(void) unsigned short dspio_index = 0, uartio_index = 0; - PRINTK_5(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg entry mwave_3780i_irq %x mwave_3780i_io %x mwave_uart_irq %x mwave_uart_io %x\n", - mwave_3780i_irq, mwave_3780i_io, mwave_uart_irq, mwave_uart_io); - if (mwave_3780i_io) { for (i = 0; i < ARRAY_SIZE(ausDspBases); i++) { if (mwave_3780i_io == ausDspBases[i]) break; } if (i == ARRAY_SIZE(ausDspBases)) { - PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_io address %x. Aborting.\n", mwave_3780i_io); + pr_err("%s: Error: Invalid mwave_3780i_io address %x. Aborting.\n", + __func__, mwave_3780i_io); return bRC; } dspio_index = i; @@ -240,7 +210,8 @@ int smapi_set_DSP_cfg(void) break; } if (i == ARRAY_SIZE(ausDspIrqs)) { - PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_irq %x. Aborting.\n", mwave_3780i_irq); + pr_err("%s: Error: Invalid mwave_3780i_irq %x. Aborting.\n", __func__, + mwave_3780i_irq); return bRC; } } @@ -251,7 +222,8 @@ int smapi_set_DSP_cfg(void) break; } if (i == ARRAY_SIZE(ausUartBases)) { - PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_io address %x. Aborting.\n", mwave_uart_io); + pr_err("%s: Error: Invalid mwave_uart_io address %x. Aborting.\n", __func__, + mwave_uart_io); return bRC; } uartio_index = i; @@ -264,7 +236,8 @@ int smapi_set_DSP_cfg(void) break; } if (i == ARRAY_SIZE(ausUartIrqs)) { - PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_irq %x. Aborting.\n", mwave_uart_irq); + pr_err("%s: Error: Invalid mwave_uart_irq %x. Aborting.\n", __func__, + mwave_uart_irq); return bRC; } } @@ -279,46 +252,15 @@ int smapi_set_DSP_cfg(void) if (usBX & 0x0100) { /* serial port A is present */ if (usCX & 1) { /* serial port is enabled */ if ((usSI & 0xFF) == mwave_uart_irq) { -#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_ERROR(KERN_ERR_MWAVE - "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); -#else - PRINTK_3(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); -#endif -#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_1(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n"); - bRC = smapi_request(0x1403, 0x0100, 0, usSI, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request(0x1402, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; -#else + pr_err("%s: Serial port A irq %x conflicts with mwave_uart_irq %x\n", + __func__, usSI & 0xFF, mwave_uart_irq); goto exit_conflict; -#endif } else { if ((usSI >> 8) == uartio_index) { -#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_ERROR(KERN_ERR_MWAVE - "smapi::smapi_set_DSP_cfg: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]); -#else - PRINTK_3(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]); -#endif -#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_1(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg Disabling conflicting serial port A\n"); - bRC = smapi_request (0x1403, 0x0100, 0, usSI, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request (0x1402, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; -#else + pr_err("%s: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", + __func__, ausUartBases[usSI >> 8], + ausUartBases[uartio_index]); goto exit_conflict; -#endif } } } @@ -332,46 +274,15 @@ int smapi_set_DSP_cfg(void) if (usBX & 0x0100) { /* serial port B is present */ if (usCX & 1) { /* serial port is enabled */ if ((usSI & 0xFF) == mwave_uart_irq) { -#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_ERROR(KERN_ERR_MWAVE - "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); -#else - PRINTK_3(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq); -#endif -#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_1(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n"); - bRC = smapi_request(0x1405, 0x0100, 0, usSI, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request(0x1404, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; -#else + pr_err("%s: Serial port B irq %x conflicts with mwave_uart_irq %x\n", + __func__, usSI & 0xFF, mwave_uart_irq); goto exit_conflict; -#endif } else { if ((usSI >> 8) == uartio_index) { -#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_ERROR(KERN_ERR_MWAVE - "smapi::smapi_set_DSP_cfg: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]); -#else - PRINTK_3(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]); -#endif -#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_1 (TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n"); - bRC = smapi_request (0x1405, 0x0100, 0, usSI, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request (0x1404, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; -#else + pr_err("%s: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", + __func__, ausUartBases[usSI >> 8], + ausUartBases[uartio_index]); goto exit_conflict; -#endif } } } @@ -387,58 +298,15 @@ int smapi_set_DSP_cfg(void) /* bRC == 0 */ if ((usCX & 0xff) != 0xff) { /* IR port not disabled */ if ((usCX & 0xff) == mwave_uart_irq) { -#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_ERROR(KERN_ERR_MWAVE - "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq); -#else - PRINTK_3(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq); -#endif -#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_1(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n"); - bRC = smapi_request(0x1701, 0x0100, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request(0x1700, 0, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request(0x1705, 0x01ff, 0, usSI, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request(0x1704, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; -#else + pr_err("%s: IR port irq %x conflicts with mwave_uart_irq %x\n", + __func__, usCX & 0xff, mwave_uart_irq); goto exit_conflict; -#endif } else { if ((usSI & 0xff) == uartio_index) { -#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_ERROR(KERN_ERR_MWAVE - "smapi::smapi_set_DSP_cfg: IR port base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI & 0xff], ausUartBases[uartio_index]); -#else - PRINTK_3(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg: IR port base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI & 0xff], ausUartBases[uartio_index]); -#endif -#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES - PRINTK_1(TRACE_SMAPI, - "smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n"); - bRC = smapi_request(0x1701, 0x0100, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request(0x1700, 0, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request(0x1705, 0x01ff, 0, usSI, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request(0x1704, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; -#else + pr_err("%s: IR port base I/O address %x conflicts with mwave uart I/O %x\n", + __func__, ausUartBases[usSI & 0xff], + ausUartBases[uartio_index]); goto exit_conflict; -#endif } } } @@ -482,7 +350,6 @@ int smapi_set_DSP_cfg(void) if (bRC) goto exit_smapi_request_error; /* normal exit: */ - PRINTK_1(TRACE_SMAPI, "smapi::smapi_set_DSP_cfg exit\n"); return 0; exit_conflict: @@ -490,64 +357,32 @@ int smapi_set_DSP_cfg(void) return -EIO; exit_smapi_request_error: - PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg exit on smapi_request error bRC %x\n", bRC); + pr_err("%s: exit on smapi_request error bRC %x\n", __func__, bRC); return bRC; } int smapi_set_DSP_power_state(bool bOn) { - int bRC; unsigned short usAX, usBX, usCX, usDX, usDI, usSI; unsigned short usPowerFunction; - PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state entry bOn %x\n", bOn); - usPowerFunction = (bOn) ? 1 : 0; - bRC = smapi_request(0x4901, 0x0000, 0, usPowerFunction, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - - PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state exit bRC %x\n", bRC); - - return bRC; + return smapi_request(0x4901, 0x0000, 0, usPowerFunction, &usAX, &usBX, &usCX, &usDX, &usDI, + &usSI); } -#if 0 -static int SmapiQuerySystemID(void) -{ - int bRC = -EIO; - unsigned short usAX = 0xffff, usBX = 0xffff, usCX = 0xffff, - usDX = 0xffff, usDI = 0xffff, usSI = 0xffff; - - printk("smapi::SmapiQUerySystemID entry\n"); - bRC = smapi_request(0x0000, 0, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - - if (bRC == 0) { - printk("AX=%x, BX=%x, CX=%x, DX=%x, DI=%x, SI=%x\n", - usAX, usBX, usCX, usDX, usDI, usSI); - } else { - printk("smapi::SmapiQuerySystemID smapi_request error\n"); - } - - return bRC; -} -#endif /* 0 */ - int smapi_init(void) { int retval = -EIO; unsigned short usSmapiID = 0; unsigned long flags; - PRINTK_1(TRACE_SMAPI, "smapi::smapi_init entry\n"); - spin_lock_irqsave(&rtc_lock, flags); usSmapiID = CMOS_READ(0x7C); usSmapiID |= (CMOS_READ(0x7D) << 8); spin_unlock_irqrestore(&rtc_lock, flags); - PRINTK_2(TRACE_SMAPI, "smapi::smapi_init usSmapiID %x\n", usSmapiID); if (usSmapiID == 0x5349) { spin_lock_irqsave(&rtc_lock, flags); @@ -555,16 +390,13 @@ int smapi_init(void) g_usSmapiPort |= (CMOS_READ(0x7F) << 8); spin_unlock_irqrestore(&rtc_lock, flags); if (g_usSmapiPort == 0) { - PRINTK_ERROR("smapi::smapi_init, ERROR unable to read from SMAPI port\n"); + pr_err("%s: ERROR unable to read from SMAPI port\n", __func__); } else { - PRINTK_2(TRACE_SMAPI, - "smapi::smapi_init, exit true g_usSmapiPort %x\n", - g_usSmapiPort); retval = 0; //SmapiQuerySystemID(); } } else { - PRINTK_ERROR("smapi::smapi_init, ERROR invalid usSmapiID\n"); + pr_err("%s: ERROR invalid usSmapiID\n", __func__); retval = -ENXIO; } diff --git a/drivers/char/mwave/smapi.h b/drivers/char/mwave/smapi.h index ebc206b000b92..e605b16ed23cb 100644 --- a/drivers/char/mwave/smapi.h +++ b/drivers/char/mwave/smapi.h @@ -49,7 +49,7 @@ #ifndef _LINUX_SMAPI_H #define _LINUX_SMAPI_H -typedef struct { +struct smapi_dsp_settings { int bDSPPresent; int bDSPEnabled; int bModemEnabled; @@ -65,10 +65,10 @@ typedef struct { unsigned short usSndblstIRQ; unsigned short usSndblstDMA; unsigned short usSndblstBaseIO; -} SMAPI_DSP_SETTINGS; +}; int smapi_init(void); -int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings); +int smapi_query_DSP_cfg(struct smapi_dsp_settings *pSettings); int smapi_set_DSP_cfg(void); int smapi_set_DSP_power_state(bool bOn); diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c index 83eaffeb22c81..7363b0f764e09 100644 --- a/drivers/char/mwave/tp3780i.c +++ b/drivers/char/mwave/tp3780i.c @@ -46,6 +46,8 @@ * First release to the public */ +#define pr_fmt(fmt) "tp3780i: " fmt + #include #include #include @@ -65,16 +67,14 @@ static unsigned short s_ausThinkpadDmaToField[8] = static unsigned short s_numIrqs = 16, s_numDmas = 8; -static void EnableSRAM(THINKPAD_BD_DATA * pBDData) +static void EnableSRAM(struct thinkpad_bd_data *pBDData) { - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; unsigned short usDspBaseIO = pSettings->usDspBaseIO; DSP_GPIO_OUTPUT_DATA_15_8 rGpioOutputData; DSP_GPIO_DRIVER_ENABLE_15_8 rGpioDriverEnable; DSP_GPIO_MODE_15_8 rGpioMode; - PRINTK_1(TRACE_TP3780I, "tp3780i::EnableSRAM, entry\n"); - MKWORD(rGpioMode) = ReadMsaCfg(DSP_GpioModeControl_15_8); rGpioMode.GpioMode10 = 0; WriteMsaCfg(DSP_GpioModeControl_15_8, MKWORD(rGpioMode)); @@ -88,54 +88,31 @@ static void EnableSRAM(THINKPAD_BD_DATA * pBDData) rGpioOutputData.Latch10 = 0; rGpioOutputData.Mask10 = true; WriteMsaCfg(DSP_GpioOutputData_15_8, MKWORD(rGpioOutputData)); - - PRINTK_1(TRACE_TP3780I, "tp3780i::EnableSRAM exit\n"); } static irqreturn_t UartInterrupt(int irq, void *dev_id) { - PRINTK_3(TRACE_TP3780I, - "tp3780i::UartInterrupt entry irq %x dev_id %p\n", irq, dev_id); return IRQ_HANDLED; } static irqreturn_t DspInterrupt(int irq, void *dev_id) { - pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; - DSP_3780I_CONFIG_SETTINGS *pSettings = &pDrvData->rBDData.rDspSettings; + struct mwave_device_data *pDrvData = &mwave_s_mdd; + struct dsp_3780i_config_settings *pSettings = &pDrvData->rBDData.rDspSettings; unsigned short usDspBaseIO = pSettings->usDspBaseIO; unsigned short usIPCSource = 0, usIsolationMask, usPCNum; - PRINTK_3(TRACE_TP3780I, - "tp3780i::DspInterrupt entry irq %x dev_id %p\n", irq, dev_id); - if (dsp3780I_GetIPCSource(usDspBaseIO, &usIPCSource) == 0) { - PRINTK_2(TRACE_TP3780I, - "tp3780i::DspInterrupt, return from dsp3780i_GetIPCSource, usIPCSource %x\n", - usIPCSource); usIsolationMask = 1; for (usPCNum = 1; usPCNum <= 16; usPCNum++) { if (usIPCSource & usIsolationMask) { usIPCSource &= ~usIsolationMask; - PRINTK_3(TRACE_TP3780I, - "tp3780i::DspInterrupt usPCNum %x usIPCSource %x\n", - usPCNum, usIPCSource); if (pDrvData->IPCs[usPCNum - 1].usIntCount == 0) { pDrvData->IPCs[usPCNum - 1].usIntCount = 1; } - PRINTK_2(TRACE_TP3780I, - "tp3780i::DspInterrupt usIntCount %x\n", - pDrvData->IPCs[usPCNum - 1].usIntCount); if (pDrvData->IPCs[usPCNum - 1].bIsEnabled == true) { - PRINTK_2(TRACE_TP3780I, - "tp3780i::DspInterrupt, waking up usPCNum %x\n", - usPCNum - 1); wake_up_interruptible(&pDrvData->IPCs[usPCNum - 1].ipc_wait_queue); - } else { - PRINTK_2(TRACE_TP3780I, - "tp3780i::DspInterrupt, no one waiting for IPC %x\n", - usPCNum - 1); } } if (usIPCSource == 0) @@ -143,56 +120,42 @@ static irqreturn_t DspInterrupt(int irq, void *dev_id) /* try next IPC */ usIsolationMask = usIsolationMask << 1; } - } else { - PRINTK_1(TRACE_TP3780I, - "tp3780i::DspInterrupt, return false from dsp3780i_GetIPCSource\n"); } - PRINTK_1(TRACE_TP3780I, "tp3780i::DspInterrupt exit\n"); return IRQ_HANDLED; } -int tp3780I_InitializeBoardData(THINKPAD_BD_DATA * pBDData) +int tp3780I_InitializeBoardData(struct thinkpad_bd_data *pBDData) { int retval = 0; - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; - - - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_InitializeBoardData entry pBDData %p\n", pBDData); + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; pBDData->bDSPEnabled = false; pSettings->bInterruptClaimed = false; retval = smapi_init(); if (retval) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_InitializeBoardData: Error: SMAPI is not available on this machine\n"); + pr_err("%s: Error: SMAPI is not available on this machine\n", __func__); } else { if (mwave_3780i_irq || mwave_3780i_io || mwave_uart_irq || mwave_uart_io) { retval = smapi_set_DSP_cfg(); } } - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_InitializeBoardData exit retval %x\n", retval); - return retval; } -void tp3780I_Cleanup(THINKPAD_BD_DATA *pBDData) +void tp3780I_Cleanup(struct thinkpad_bd_data *pBDData) { - PRINTK_2(TRACE_TP3780I, - "tp3780i::tp3780I_Cleanup entry and exit pBDData %p\n", pBDData); } -int tp3780I_CalcResources(THINKPAD_BD_DATA * pBDData) +int tp3780I_CalcResources(struct thinkpad_bd_data *pBDData) { - SMAPI_DSP_SETTINGS rSmapiInfo; - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; - - PRINTK_2(TRACE_TP3780I, - "tp3780i::tp3780I_CalcResources entry pBDData %p\n", pBDData); + struct smapi_dsp_settings rSmapiInfo; + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; if (smapi_query_DSP_cfg(&rSmapiInfo)) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_CalcResources: Error: Could not query DSP config. Aborting.\n"); + pr_err("%s: Error: Could not query DSP config. Aborting.\n", __func__); return -EIO; } @@ -203,7 +166,7 @@ int tp3780I_CalcResources(THINKPAD_BD_DATA * pBDData) || ( rSmapiInfo.usUartIRQ == 0 ) || ( rSmapiInfo.usUartBaseIO == 0 ) ) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_CalcResources: Error: Illegal resource setting. Aborting.\n"); + pr_err("%s: Error: Illegal resource setting. Aborting.\n", __func__); return -EIO; } @@ -225,41 +188,31 @@ int tp3780I_CalcResources(THINKPAD_BD_DATA * pBDData) pBDData->bShareDspIrq = pBDData->bShareUartIrq = 0; } - PRINTK_1(TRACE_TP3780I, "tp3780i::tp3780I_CalcResources exit\n"); - return 0; } -int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData) +int tp3780I_ClaimResources(struct thinkpad_bd_data *pBDData) { int retval = 0; - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; struct resource *pres; - PRINTK_2(TRACE_TP3780I, - "tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData); - pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i"); if ( pres == NULL ) retval = -EIO; if (retval) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO); - retval = -EIO; + pr_err("%s: Error: Could not claim I/O region starting at %x\n", __func__, + pSettings->usDspBaseIO); + return -EIO; } - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ClaimResources exit retval %x\n", retval); - return retval; } -int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData) +int tp3780I_ReleaseResources(struct thinkpad_bd_data *pBDData) { - int retval = 0; - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; - - PRINTK_2(TRACE_TP3780I, - "tp3780i::tp3780I_ReleaseResources entry pBDData %p\n", pBDData); + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; release_region(pSettings->usDspBaseIO & (~3), 16); @@ -268,28 +221,23 @@ int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData) pSettings->bInterruptClaimed = false; } - PRINTK_2(TRACE_TP3780I, - "tp3780i::tp3780I_ReleaseResources exit retval %x\n", retval); - - return retval; + return 0; } -int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) +int tp3780I_EnableDSP(struct thinkpad_bd_data *pBDData) { - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; bool bDSPPoweredUp = false, bInterruptAllocated = false; - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData); - if (pBDData->bDSPEnabled) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: DSP already enabled!\n"); + pr_err("%s: Error: DSP already enabled!\n", __func__); goto exit_cleanup; } if (!pSettings->bDSPEnabled) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780::tp3780I_EnableDSP: Error: pSettings->bDSPEnabled not set\n"); + pr_err("%s: Error: pSettings->bDSPEnabled not set\n", __func__); goto exit_cleanup; } @@ -299,7 +247,7 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) || (s_ausThinkpadIrqToField[pSettings->usDspIrq] == 0xFFFF) || (s_ausThinkpadDmaToField[pSettings->usDspDma] == 0xFFFF) ) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: invalid irq %x\n", pSettings->usDspIrq); + pr_err("%s: Error: invalid irq %x\n", __func__, pSettings->usDspIrq); goto exit_cleanup; } @@ -307,7 +255,8 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) ((pSettings->usDspBaseIO & 0xF00F) != 0) || (pSettings->usDspBaseIO & 0x0FF0) == 0 ) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Invalid DSP base I/O address %x\n", pSettings->usDspBaseIO); + pr_err("%s: Error: Invalid DSP base I/O address %x\n", __func__, + pSettings->usDspBaseIO); goto exit_cleanup; } @@ -316,7 +265,7 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) pSettings->usUartIrq >= s_numIrqs || s_ausThinkpadIrqToField[pSettings->usUartIrq] == 0xFFFF ) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Invalid UART IRQ %x\n", pSettings->usUartIrq); + pr_err("%s: Error: Invalid UART IRQ %x\n", __func__, pSettings->usUartIrq); goto exit_cleanup; } switch (pSettings->usUartBaseIO) { @@ -327,7 +276,8 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) break; default: - PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: Invalid UART base I/O address %x\n", pSettings->usUartBaseIO); + pr_err("%s: Error: Invalid UART base I/O address %x\n", __func__, + pSettings->usUartBaseIO); goto exit_cleanup; } } @@ -356,33 +306,30 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) pSettings->usChipletEnable = TP_CFG_ChipletEnable; if (request_irq(pSettings->usUartIrq, &UartInterrupt, 0, "mwave_uart", NULL)) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Could not get UART IRQ %x\n", pSettings->usUartIrq); + pr_err("%s: Error: Could not get UART IRQ %x\n", __func__, pSettings->usUartIrq); goto exit_cleanup; } else { /* no conflict just release */ free_irq(pSettings->usUartIrq, NULL); } if (request_irq(pSettings->usDspIrq, &DspInterrupt, 0, "mwave_3780i", NULL)) { - PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: Could not get 3780i IRQ %x\n", pSettings->usDspIrq); + pr_err("%s: Error: Could not get 3780i IRQ %x\n", __func__, pSettings->usDspIrq); goto exit_cleanup; } else { - PRINTK_3(TRACE_TP3780I, - "tp3780i::tp3780I_EnableDSP, got interrupt %x bShareDspIrq %x\n", - pSettings->usDspIrq, pBDData->bShareDspIrq); bInterruptAllocated = true; pSettings->bInterruptClaimed = true; } smapi_set_DSP_power_state(false); if (smapi_set_DSP_power_state(true)) { - PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: smapi_set_DSP_power_state(true) failed\n"); + pr_err("%s: Error: smapi_set_DSP_power_state(true) failed\n", __func__); goto exit_cleanup; } else { bDSPPoweredUp = true; } if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) { - PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n"); + pr_err("%s: Error: dsp7880I_EnableDSP() failed\n", __func__); goto exit_cleanup; } @@ -390,12 +337,10 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) pBDData->bDSPEnabled = true; - PRINTK_1(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP exit\n"); - return 0; exit_cleanup: - PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n"); + pr_err("%s: Cleaning up\n", __func__); if (bDSPPoweredUp) smapi_set_DSP_power_state(false); if (bInterruptAllocated) { @@ -406,12 +351,9 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) } -int tp3780I_DisableDSP(THINKPAD_BD_DATA * pBDData) +int tp3780I_DisableDSP(struct thinkpad_bd_data *pBDData) { - int retval = 0; - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; - - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_DisableDSP entry pBDData %p\n", pBDData); + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; if (pBDData->bDSPEnabled) { dsp3780I_DisableDSP(&pBDData->rDspSettings); @@ -423,56 +365,38 @@ int tp3780I_DisableDSP(THINKPAD_BD_DATA * pBDData) pBDData->bDSPEnabled = false; } - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_DisableDSP exit retval %x\n", retval); - - return retval; + return 0; } -int tp3780I_ResetDSP(THINKPAD_BD_DATA * pBDData) +int tp3780I_ResetDSP(struct thinkpad_bd_data *pBDData) { - int retval = 0; - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; - - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ResetDSP entry pBDData %p\n", - pBDData); + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; if (dsp3780I_Reset(pSettings) == 0) { EnableSRAM(pBDData); - } else { - retval = -EIO; + return 0; } - - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ResetDSP exit retval %x\n", retval); - - return retval; + return -EIO; } -int tp3780I_StartDSP(THINKPAD_BD_DATA * pBDData) +int tp3780I_StartDSP(struct thinkpad_bd_data *pBDData) { - int retval = 0; - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; - - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_StartDSP entry pBDData %p\n", pBDData); + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; if (dsp3780I_Run(pSettings) == 0) { // @BUG @TBD EnableSRAM(pBDData); } else { - retval = -EIO; + return -EIO; } - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_StartDSP exit retval %x\n", retval); - - return retval; + return 0; } -int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities) +int tp3780I_QueryAbilities(struct thinkpad_bd_data *pBDData, struct mw_abilities *pAbilities) { - PRINTK_2(TRACE_TP3780I, - "tp3780i::tp3780I_QueryAbilities entry pBDData %p\n", pBDData); - memset(pAbilities, 0, sizeof(*pAbilities)); /* fill out standard constant fields */ pAbilities->instr_per_sec = pBDData->rDspSettings.uIps; @@ -497,25 +421,17 @@ int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities memcpy(pAbilities->bios_task_name, TP_ABILITIES_BIOSTASK_NAME, sizeof(TP_ABILITIES_BIOSTASK_NAME)); - PRINTK_1(TRACE_TP3780I, - "tp3780i::tp3780I_QueryAbilities exit retval=SUCCESSFUL\n"); - return 0; } -int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, +int tp3780I_ReadWriteDspDStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode, void __user *pvBuffer, unsigned int uCount, unsigned long ulDSPAddr) { - int retval = 0; - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; unsigned short usDspBaseIO = pSettings->usDspBaseIO; bool bRC = 0; - PRINTK_6(TRACE_TP3780I, - "tp3780i::tp3780I_ReadWriteDspDStore entry pBDData %p, uOpcode %x, pvBuffer %p, uCount %x, ulDSPAddr %lx\n", - pBDData, uOpcode, pvBuffer, uCount, ulDSPAddr); - if (pBDData->bDSPEnabled) { switch (uOpcode) { case IOCTL_MW_READ_DATA: @@ -532,26 +448,18 @@ int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, } } - retval = (bRC) ? -EIO : 0; - PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ReadWriteDspDStore exit retval %x\n", retval); - - return retval; + return bRC ? -EIO : 0; } -int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, +int tp3780I_ReadWriteDspIStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode, void __user *pvBuffer, unsigned int uCount, unsigned long ulDSPAddr) { - int retval = 0; - DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; + struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; unsigned short usDspBaseIO = pSettings->usDspBaseIO; bool bRC = 0; - PRINTK_6(TRACE_TP3780I, - "tp3780i::tp3780I_ReadWriteDspIStore entry pBDData %p, uOpcode %x, pvBuffer %p, uCount %x, ulDSPAddr %lx\n", - pBDData, uOpcode, pvBuffer, uCount, ulDSPAddr); - if (pBDData->bDSPEnabled) { switch (uOpcode) { case IOCTL_MW_READ_INST: @@ -564,11 +472,6 @@ int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, } } - retval = (bRC) ? -EIO : 0; - - PRINTK_2(TRACE_TP3780I, - "tp3780i::tp3780I_ReadWriteDspIStore exit retval %x\n", retval); - - return retval; + return bRC ? -EIO : 0; } diff --git a/drivers/char/mwave/tp3780i.h b/drivers/char/mwave/tp3780i.h index 8bd976d42faef..c0001a344741b 100644 --- a/drivers/char/mwave/tp3780i.h +++ b/drivers/char/mwave/tp3780i.h @@ -75,27 +75,27 @@ #define TP_CFG_PllBypass 0 /* don't bypass */ #define TP_CFG_ChipletEnable 0xFFFF /* Enable all chiplets */ -typedef struct { +struct thinkpad_bd_data { int bDSPEnabled; int bShareDspIrq; int bShareUartIrq; - DSP_3780I_CONFIG_SETTINGS rDspSettings; -} THINKPAD_BD_DATA; + struct dsp_3780i_config_settings rDspSettings; +}; -int tp3780I_InitializeBoardData(THINKPAD_BD_DATA * pBDData); -int tp3780I_CalcResources(THINKPAD_BD_DATA * pBDData); -int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData); -int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData); -int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData); -int tp3780I_DisableDSP(THINKPAD_BD_DATA * pBDData); -int tp3780I_ResetDSP(THINKPAD_BD_DATA * pBDData); -int tp3780I_StartDSP(THINKPAD_BD_DATA * pBDData); -int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities); -void tp3780I_Cleanup(THINKPAD_BD_DATA *pBDData); -int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, +int tp3780I_InitializeBoardData(struct thinkpad_bd_data *pBDData); +int tp3780I_CalcResources(struct thinkpad_bd_data *pBDData); +int tp3780I_ClaimResources(struct thinkpad_bd_data *pBDData); +int tp3780I_ReleaseResources(struct thinkpad_bd_data *pBDData); +int tp3780I_EnableDSP(struct thinkpad_bd_data *pBDData); +int tp3780I_DisableDSP(struct thinkpad_bd_data *pBDData); +int tp3780I_ResetDSP(struct thinkpad_bd_data *pBDData); +int tp3780I_StartDSP(struct thinkpad_bd_data *pBDData); +int tp3780I_QueryAbilities(struct thinkpad_bd_data *pBDData, struct mw_abilities *pAbilities); +void tp3780I_Cleanup(struct thinkpad_bd_data *pBDData); +int tp3780I_ReadWriteDspDStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode, void __user *pvBuffer, unsigned int uCount, unsigned long ulDSPAddr); -int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode, +int tp3780I_ReadWriteDspIStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode, void __user *pvBuffer, unsigned int uCount, unsigned long ulDSPAddr); diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index e25daf2396d37..082b910ddf0dd 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -230,42 +230,6 @@ struct tpm_chip *tpm_default_chip(void) } EXPORT_SYMBOL_GPL(tpm_default_chip); -/** - * tpm_find_get_ops() - find and reserve a TPM chip - * @chip: a &struct tpm_chip instance, %NULL for the default chip - * - * Finds a TPM chip and reserves its class device and operations. The chip must - * be released with tpm_put_ops() after use. - * This function is for internal use only. It supports existing TPM callers - * by accepting NULL, but those callers should be converted to pass in a chip - * directly. - * - * Return: - * A reserved &struct tpm_chip instance. - * %NULL if a chip is not found. - * %NULL if the chip is not available. - */ -struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip) -{ - int rc; - - if (chip) { - if (!tpm_try_get_ops(chip)) - return chip; - return NULL; - } - - chip = tpm_default_chip(); - if (!chip) - return NULL; - rc = tpm_try_get_ops(chip); - /* release additional reference we got from tpm_default_chip() */ - put_device(&chip->dev); - if (rc) - return NULL; - return chip; -} - /** * tpm_dev_release() - free chip memory and the device number * @dev: the character device for the TPM chip @@ -282,7 +246,6 @@ static void tpm_dev_release(struct device *dev) kfree(chip->work_space.context_buf); kfree(chip->work_space.session_buf); - kfree(chip->allocated_banks); #ifdef CONFIG_TCG_TPM2_HMAC kfree(chip->auth); #endif diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c index f2a5e09257ddd..f942c0c8e402f 100644 --- a/drivers/char/tpm/tpm-dev-common.c +++ b/drivers/char/tpm/tpm-dev-common.c @@ -275,7 +275,8 @@ void tpm_common_release(struct file *file, struct file_priv *priv) int __init tpm_dev_common_init(void) { - tpm_dev_wq = alloc_workqueue("tpm_dev_wq", WQ_MEM_RECLAIM, 0); + tpm_dev_wq = alloc_workqueue("tpm_dev_wq", WQ_MEM_RECLAIM | WQ_PERCPU, + 0); return !tpm_dev_wq ? -ENOMEM : 0; } diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index c9f173001d0e9..f745a098908b3 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -313,10 +313,13 @@ int tpm_is_tpm2(struct tpm_chip *chip) { int rc; - chip = tpm_find_get_ops(chip); if (!chip) return -ENODEV; + rc = tpm_try_get_ops(chip); + if (rc) + return rc; + rc = (chip->flags & TPM_CHIP_FLAG_TPM2) != 0; tpm_put_ops(chip); @@ -338,10 +341,13 @@ int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, { int rc; - chip = tpm_find_get_ops(chip); if (!chip) return -ENODEV; + rc = tpm_try_get_ops(chip); + if (rc) + return rc; + if (chip->flags & TPM_CHIP_FLAG_TPM2) rc = tpm2_pcr_read(chip, pcr_idx, digest, NULL); else @@ -369,10 +375,13 @@ int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, int rc; int i; - chip = tpm_find_get_ops(chip); if (!chip) return -ENODEV; + rc = tpm_try_get_ops(chip); + if (rc) + return rc; + for (i = 0; i < chip->nr_allocated_banks; i++) { if (digests[i].alg_id != chip->allocated_banks[i].alg_id) { rc = -EINVAL; @@ -492,10 +501,13 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max) if (!out || max > TPM_MAX_RNG_DATA) return -EINVAL; - chip = tpm_find_get_ops(chip); if (!chip) return -ENODEV; + rc = tpm_try_get_ops(chip); + if (rc) + return rc; + if (chip->flags & TPM_CHIP_FLAG_TPM2) rc = tpm2_get_random(chip, out, max); else diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 2726bd38e5ac5..02c07fef41baf 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -267,7 +267,6 @@ static inline void tpm_msleep(unsigned int delay_msec) int tpm_chip_bootstrap(struct tpm_chip *chip); int tpm_chip_start(struct tpm_chip *chip); void tpm_chip_stop(struct tpm_chip *chip); -struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip); struct tpm_chip *tpm_chip_alloc(struct device *dev, const struct tpm_class_ops *ops); diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c index cf64c73851052..b49a790f1bd53 100644 --- a/drivers/char/tpm/tpm1-cmd.c +++ b/drivers/char/tpm/tpm1-cmd.c @@ -799,11 +799,6 @@ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr) */ int tpm1_get_pcr_allocation(struct tpm_chip *chip) { - chip->allocated_banks = kcalloc(1, sizeof(*chip->allocated_banks), - GFP_KERNEL); - if (!chip->allocated_banks) - return -ENOMEM; - chip->allocated_banks[0].alg_id = TPM_ALG_SHA1; chip->allocated_banks[0].digest_size = hash_digest_size[HASH_ALGO_SHA1]; chip->allocated_banks[0].crypto_id = HASH_ALGO_SHA1; diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 5532e53a2dd3d..3a77be7ebf4aa 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -11,8 +11,11 @@ * used by the kernel internally. */ +#include "linux/dev_printk.h" +#include "linux/tpm.h" #include "tpm.h" #include +#include static bool disable_pcr_integrity; module_param(disable_pcr_integrity, bool, 0444); @@ -199,11 +202,15 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, } if (!disable_pcr_integrity) { - tpm_buf_append_name(chip, &buf, pcr_idx, NULL); + rc = tpm_buf_append_name(chip, &buf, pcr_idx, NULL); + if (rc) { + tpm_buf_destroy(&buf); + return rc; + } tpm_buf_append_hmac_session(chip, &buf, 0, NULL, 0); } else { tpm_buf_append_handle(chip, &buf, pcr_idx); - tpm_buf_append_auth(chip, &buf, 0, NULL, 0); + tpm_buf_append_auth(chip, &buf, NULL, 0); } tpm_buf_append_u32(&buf, chip->nr_allocated_banks); @@ -214,8 +221,14 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, chip->allocated_banks[i].digest_size); } - if (!disable_pcr_integrity) - tpm_buf_fill_hmac_session(chip, &buf); + if (!disable_pcr_integrity) { + rc = tpm_buf_fill_hmac_session(chip, &buf); + if (rc) { + tpm_buf_destroy(&buf); + return rc; + } + } + rc = tpm_transmit_cmd(chip, &buf, 0, "attempting extend a PCR value"); if (!disable_pcr_integrity) rc = tpm_buf_check_hmac_response(chip, &buf, rc); @@ -269,11 +282,24 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max) do { tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM); - tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT - | TPM2_SA_CONTINUE_SESSION, - NULL, 0); + if (tpm2_chip_auth(chip)) { + tpm_buf_append_hmac_session(chip, &buf, + TPM2_SA_ENCRYPT | + TPM2_SA_CONTINUE_SESSION, + NULL, 0); + } else { + offset = buf.handles * 4 + TPM_HEADER_SIZE; + head = (struct tpm_header *)buf.data; + if (tpm_buf_length(&buf) == offset) + head->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS); + } tpm_buf_append_u16(&buf, num_bytes); - tpm_buf_fill_hmac_session(chip, &buf); + err = tpm_buf_fill_hmac_session(chip, &buf); + if (err) { + tpm_buf_destroy(&buf); + return err; + } + err = tpm_transmit_cmd(chip, &buf, offsetof(struct tpm2_get_random_out, buffer), @@ -550,11 +576,9 @@ ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) nr_possible_banks = be32_to_cpup( (__be32 *)&buf.data[TPM_HEADER_SIZE + 5]); - - chip->allocated_banks = kcalloc(nr_possible_banks, - sizeof(*chip->allocated_banks), - GFP_KERNEL); - if (!chip->allocated_banks) { + if (nr_possible_banks > TPM2_MAX_PCR_BANKS) { + pr_err("tpm: out of bank capacity: %u > %u\n", + nr_possible_banks, TPM2_MAX_PCR_BANKS); rc = -ENOMEM; goto out; } diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index 6d03c224e6b21..4149379665c49 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -144,59 +144,80 @@ struct tpm2_auth { /* * Name Size based on TPM algorithm (assumes no hash bigger than 255) */ -static u8 name_size(const u8 *name) +static int name_size(const u8 *name) { - static u8 size_map[] = { - [TPM_ALG_SHA1] = SHA1_DIGEST_SIZE, - [TPM_ALG_SHA256] = SHA256_DIGEST_SIZE, - [TPM_ALG_SHA384] = SHA384_DIGEST_SIZE, - [TPM_ALG_SHA512] = SHA512_DIGEST_SIZE, - }; - u16 alg = get_unaligned_be16(name); - return size_map[alg] + 2; -} - -static int tpm2_parse_read_public(char *name, struct tpm_buf *buf) -{ - struct tpm_header *head = (struct tpm_header *)buf->data; - off_t offset = TPM_HEADER_SIZE; - u32 tot_len = be32_to_cpu(head->length); - u32 val; - - /* we're starting after the header so adjust the length */ - tot_len -= TPM_HEADER_SIZE; - - /* skip public */ - val = tpm_buf_read_u16(buf, &offset); - if (val > tot_len) - return -EINVAL; - offset += val; - /* name */ - val = tpm_buf_read_u16(buf, &offset); - if (val != name_size(&buf->data[offset])) + u16 hash_alg = get_unaligned_be16(name); + + switch (hash_alg) { + case TPM_ALG_SHA1: + return SHA1_DIGEST_SIZE + 2; + case TPM_ALG_SHA256: + return SHA256_DIGEST_SIZE + 2; + case TPM_ALG_SHA384: + return SHA384_DIGEST_SIZE + 2; + case TPM_ALG_SHA512: + return SHA512_DIGEST_SIZE + 2; + default: + pr_warn("tpm: unsupported name algorithm: 0x%04x\n", hash_alg); return -EINVAL; - memcpy(name, &buf->data[offset], val); - /* forget the rest */ - return 0; + } } -static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name) +static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name) { + u32 mso = tpm2_handle_mso(handle); + off_t offset = TPM_HEADER_SIZE; + int rc, name_size_alg; struct tpm_buf buf; - int rc; + + if (mso != TPM2_MSO_PERSISTENT && mso != TPM2_MSO_VOLATILE && + mso != TPM2_MSO_NVRAM) { + memcpy(name, &handle, sizeof(u32)); + return sizeof(u32); + } rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_READ_PUBLIC); if (rc) return rc; tpm_buf_append_u32(&buf, handle); - rc = tpm_transmit_cmd(chip, &buf, 0, "read public"); - if (rc == TPM2_RC_SUCCESS) - rc = tpm2_parse_read_public(name, &buf); - tpm_buf_destroy(&buf); + rc = tpm_transmit_cmd(chip, &buf, 0, "TPM2_ReadPublic"); + if (rc) { + tpm_buf_destroy(&buf); + return tpm_ret_to_err(rc); + } - return rc; + /* Skip TPMT_PUBLIC: */ + offset += tpm_buf_read_u16(&buf, &offset); + + /* + * Ensure space for the length field of TPM2B_NAME and hashAlg field of + * TPMT_HA (the extra four bytes). + */ + if (offset + 4 > tpm_buf_length(&buf)) { + tpm_buf_destroy(&buf); + return -EIO; + } + + rc = tpm_buf_read_u16(&buf, &offset); + name_size_alg = name_size(&buf.data[offset]); + + if (name_size_alg < 0) + return name_size_alg; + + if (rc != name_size_alg) { + tpm_buf_destroy(&buf); + return -EIO; + } + + if (offset + rc > tpm_buf_length(&buf)) { + tpm_buf_destroy(&buf); + return -EIO; + } + + memcpy(name, &buf.data[offset], rc); + return name_size_alg; } #endif /* CONFIG_TCG_TPM2_HMAC */ @@ -221,52 +242,76 @@ static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name) * As with most tpm_buf operations, success is assumed because failure * will be caused by an incorrect programming model and indicated by a * kernel message. + * + * Ends the authorization session on failure. */ -void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, - u32 handle, u8 *name) +int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, + u32 handle, u8 *name) { #ifdef CONFIG_TCG_TPM2_HMAC enum tpm2_mso_type mso = tpm2_handle_mso(handle); struct tpm2_auth *auth; + u16 name_size_alg; int slot; + int ret; #endif if (!tpm2_chip_auth(chip)) { tpm_buf_append_handle(chip, buf, handle); - return; + return 0; } #ifdef CONFIG_TCG_TPM2_HMAC slot = (tpm_buf_length(buf) - TPM_HEADER_SIZE) / 4; if (slot >= AUTH_MAX_NAMES) { - dev_err(&chip->dev, "TPM: too many handles\n"); - return; + dev_err(&chip->dev, "too many handles\n"); + ret = -EIO; + goto err; } auth = chip->auth; - WARN(auth->session != tpm_buf_length(buf), - "name added in wrong place\n"); + if (auth->session != tpm_buf_length(buf)) { + dev_err(&chip->dev, "session state malformed"); + ret = -EIO; + goto err; + } tpm_buf_append_u32(buf, handle); auth->session += 4; if (mso == TPM2_MSO_PERSISTENT || mso == TPM2_MSO_VOLATILE || mso == TPM2_MSO_NVRAM) { - if (!name) - tpm2_read_public(chip, handle, auth->name[slot]); + if (!name) { + ret = tpm2_read_public(chip, handle, auth->name[slot]); + if (ret < 0) + goto err; + + name_size_alg = ret; + } } else { - if (name) - dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n"); + if (name) { + dev_err(&chip->dev, "handle 0x%08x does not use a name\n", + handle); + ret = -EIO; + goto err; + } } auth->name_h[slot] = handle; if (name) - memcpy(auth->name[slot], name, name_size(name)); + memcpy(auth->name[slot], name, name_size_alg); +#endif + return 0; + +#ifdef CONFIG_TCG_TPM2_HMAC +err: + tpm2_end_auth_session(chip); + return tpm_ret_to_err(ret); #endif } EXPORT_SYMBOL_GPL(tpm_buf_append_name); void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf, - u8 attributes, u8 *passphrase, int passphrase_len) + u8 *passphrase, int passphrase_len) { /* offset tells us where the sessions area begins */ int offset = buf->handles * 4 + TPM_HEADER_SIZE; @@ -327,8 +372,7 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf, #endif if (!tpm2_chip_auth(chip)) { - tpm_buf_append_auth(chip, buf, attributes, passphrase, - passphrase_len); + tpm_buf_append_auth(chip, buf, passphrase, passphrase_len); return; } @@ -533,11 +577,9 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip, * encryption key and encrypts the first parameter of the command * buffer with it. * - * As with most tpm_buf operations, success is assumed because failure - * will be caused by an incorrect programming model and indicated by a - * kernel message. + * Ends the authorization session on failure. */ -void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) +int tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) { u32 cc, handles, val; struct tpm2_auth *auth = chip->auth; @@ -549,9 +591,12 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) u8 cphash[SHA256_DIGEST_SIZE]; struct sha256_ctx sctx; struct hmac_sha256_ctx hctx; + int ret; - if (!auth) - return; + if (!auth) { + ret = -EIO; + goto err; + } /* save the command code in BE format */ auth->ordinal = head->ordinal; @@ -560,9 +605,11 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) i = tpm2_find_cc(chip, cc); if (i < 0) { - dev_err(&chip->dev, "Command 0x%x not found in TPM\n", cc); - return; + dev_err(&chip->dev, "command 0x%08x not found\n", cc); + ret = -EIO; + goto err; } + attrs = chip->cc_attrs_tbl[i]; handles = (attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0); @@ -576,9 +623,9 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) u32 handle = tpm_buf_read_u32(buf, &offset_s); if (auth->name_h[i] != handle) { - dev_err(&chip->dev, "TPM: handle %d wrong for name\n", - i); - return; + dev_err(&chip->dev, "invalid handle 0x%08x\n", handle); + ret = -EIO; + goto err; } } /* point offset_s to the start of the sessions */ @@ -609,12 +656,14 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) offset_s += len; } if (offset_s != offset_p) { - dev_err(&chip->dev, "TPM session length is incorrect\n"); - return; + dev_err(&chip->dev, "session length is incorrect\n"); + ret = -EIO; + goto err; } if (!hmac) { - dev_err(&chip->dev, "TPM could not find HMAC session\n"); - return; + dev_err(&chip->dev, "could not find HMAC session\n"); + ret = -EIO; + goto err; } /* encrypt before HMAC */ @@ -646,8 +695,11 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) if (mso == TPM2_MSO_PERSISTENT || mso == TPM2_MSO_VOLATILE || mso == TPM2_MSO_NVRAM) { - sha256_update(&sctx, auth->name[i], - name_size(auth->name[i])); + ret = name_size(auth->name[i]); + if (ret < 0) + goto err; + + sha256_update(&sctx, auth->name[i], ret); } else { __be32 h = cpu_to_be32(auth->name_h[i]); @@ -668,6 +720,11 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce)); hmac_sha256_update(&hctx, &auth->attrs, 1); hmac_sha256_final(&hctx, hmac); + return 0; + +err: + tpm2_end_auth_session(chip); + return ret; } EXPORT_SYMBOL(tpm_buf_fill_hmac_session); diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index c75a531cfb98e..6c25305c256ef 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -179,6 +179,7 @@ static int crb_try_pluton_doorbell(struct crb_priv *priv, bool wait_for_complete * * @dev: crb device * @priv: crb private data + * @loc: locality * * Write CRB_CTRL_REQ_GO_IDLE to TPM_CRB_CTRL_REQ * The device should respond within TIMEOUT_C by clearing the bit. @@ -233,6 +234,7 @@ static int crb_go_idle(struct tpm_chip *chip) * * @dev: crb device * @priv: crb private data + * @loc: locality * * Write CRB_CTRL_REQ_CMD_READY to TPM_CRB_CTRL_REQ * and poll till the device acknowledge it by clearing the bit. @@ -412,7 +414,7 @@ static int crb_do_acpi_start(struct tpm_chip *chip) #ifdef CONFIG_ARM64 /* * This is a TPM Command Response Buffer start method that invokes a - * Secure Monitor Call to requrest the firmware to execute or cancel + * Secure Monitor Call to request the firmware to execute or cancel * a TPM 2.0 command. */ static int tpm_crb_smc_start(struct device *dev, unsigned long func_id) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 8954a8660ffc5..e2a1769081b1a 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -265,8 +265,7 @@ static u8 tpm_tis_status(struct tpm_chip *chip) /* * Dump stack for forensics, as invalid TPM_STS.x could be - * potentially triggered by impaired tpm_try_get_ops() or - * tpm_find_get_ops(). + * potentially triggered by impaired tpm_try_get_ops(). */ dump_stack(); } diff --git a/drivers/char/xillybus/xillybus_core.c b/drivers/char/xillybus/xillybus_core.c index efb1ae834265a..fc4e69b5cb6ae 100644 --- a/drivers/char/xillybus/xillybus_core.c +++ b/drivers/char/xillybus/xillybus_core.c @@ -1973,7 +1973,7 @@ EXPORT_SYMBOL(xillybus_endpoint_remove); static int __init xillybus_init(void) { - xillybus_wq = alloc_workqueue(xillyname, 0, 0); + xillybus_wq = alloc_workqueue(xillyname, WQ_UNBOUND, 0); if (!xillybus_wq) return -ENOMEM; diff --git a/drivers/char/xillybus/xillyusb.c b/drivers/char/xillybus/xillyusb.c index 45771b1a3716a..3865314742132 100644 --- a/drivers/char/xillybus/xillyusb.c +++ b/drivers/char/xillybus/xillyusb.c @@ -2163,7 +2163,7 @@ static int xillyusb_probe(struct usb_interface *interface, spin_lock_init(&xdev->error_lock); xdev->in_counter = 0; xdev->in_bytes_left = 0; - xdev->workq = alloc_workqueue(xillyname, WQ_HIGHPRI, 0); + xdev->workq = alloc_workqueue(xillyname, WQ_HIGHPRI | WQ_UNBOUND, 0); if (!xdev->workq) { dev_err(&interface->dev, "Failed to allocate work queue\n"); @@ -2275,7 +2275,7 @@ static int __init xillyusb_init(void) { int rc = 0; - wakeup_wq = alloc_workqueue(xillyname, 0, 0); + wakeup_wq = alloc_workqueue(xillyname, WQ_UNBOUND, 0); if (!wakeup_wq) return -ENOMEM; diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index b74a1767ca278..61ec08404442b 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -125,8 +125,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/ obj-y += imgtec/ obj-y += imx/ obj-y += ingenic/ -obj-$(CONFIG_ARCH_K3) += keystone/ -obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ +obj-y += keystone/ obj-y += mediatek/ obj-$(CONFIG_ARCH_MESON) += meson/ obj-y += microchip/ diff --git a/drivers/clk/actions/owl-common.h b/drivers/clk/actions/owl-common.h index 8fb65f3e82d79..5768a2e0f6a07 100644 --- a/drivers/clk/actions/owl-common.h +++ b/drivers/clk/actions/owl-common.h @@ -32,7 +32,7 @@ struct owl_clk_desc { }; static inline struct owl_clk_common * - hw_to_owl_clk_common(const struct clk_hw *hw) + hw_to_owl_clk_common(struct clk_hw *hw) { return container_of(hw, struct owl_clk_common, hw); } diff --git a/drivers/clk/actions/owl-composite.h b/drivers/clk/actions/owl-composite.h index bca38bf8f218c..6d7c6f0c47c8b 100644 --- a/drivers/clk/actions/owl-composite.h +++ b/drivers/clk/actions/owl-composite.h @@ -108,7 +108,7 @@ struct owl_composite { }, \ } -static inline struct owl_composite *hw_to_owl_comp(const struct clk_hw *hw) +static inline struct owl_composite *hw_to_owl_comp(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/actions/owl-divider.h b/drivers/clk/actions/owl-divider.h index 083be6d80954d..d76f58782c528 100644 --- a/drivers/clk/actions/owl-divider.h +++ b/drivers/clk/actions/owl-divider.h @@ -49,7 +49,7 @@ struct owl_divider { }, \ } -static inline struct owl_divider *hw_to_owl_divider(const struct clk_hw *hw) +static inline struct owl_divider *hw_to_owl_divider(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/actions/owl-factor.h b/drivers/clk/actions/owl-factor.h index 04b89cbfdccbb..24c704d409258 100644 --- a/drivers/clk/actions/owl-factor.h +++ b/drivers/clk/actions/owl-factor.h @@ -57,7 +57,7 @@ struct owl_factor { #define div_mask(d) ((1 << ((d)->width)) - 1) -static inline struct owl_factor *hw_to_owl_factor(const struct clk_hw *hw) +static inline struct owl_factor *hw_to_owl_factor(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/actions/owl-gate.h b/drivers/clk/actions/owl-gate.h index c2f161c93fda5..ac458d4385ee7 100644 --- a/drivers/clk/actions/owl-gate.h +++ b/drivers/clk/actions/owl-gate.h @@ -56,7 +56,7 @@ struct owl_gate { }, \ } \ -static inline struct owl_gate *hw_to_owl_gate(const struct clk_hw *hw) +static inline struct owl_gate *hw_to_owl_gate(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/actions/owl-mux.h b/drivers/clk/actions/owl-mux.h index 53b9ab665294c..dc0ecc2d5e10a 100644 --- a/drivers/clk/actions/owl-mux.h +++ b/drivers/clk/actions/owl-mux.h @@ -44,7 +44,7 @@ struct owl_mux { }, \ } -static inline struct owl_mux *hw_to_owl_mux(const struct clk_hw *hw) +static inline struct owl_mux *hw_to_owl_mux(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/actions/owl-pll.h b/drivers/clk/actions/owl-pll.h index 78e5fc360b03b..58e19f1ade43f 100644 --- a/drivers/clk/actions/owl-pll.h +++ b/drivers/clk/actions/owl-pll.h @@ -98,7 +98,7 @@ struct owl_pll { #define mul_mask(m) ((1 << ((m)->width)) - 1) -static inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw) +static inline struct owl_pll *hw_to_owl_pll(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c index e700f40fd87f9..e7208c47268b6 100644 --- a/drivers/clk/at91/clk-peripheral.c +++ b/drivers/clk/at91/clk-peripheral.c @@ -3,6 +3,7 @@ * Copyright (C) 2013 Boris BREZILLON */ +#include #include #include #include diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index acf780a815890..2310f6f731627 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -115,7 +115,7 @@ struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, /* Address in SECURAM that say if we suspend to backup mode. */ static void __iomem *at91_pmc_backup_suspend; -static int at91_pmc_suspend(void) +static int at91_pmc_suspend(void *data) { unsigned int backup; @@ -129,7 +129,7 @@ static int at91_pmc_suspend(void) return clk_save_context(); } -static void at91_pmc_resume(void) +static void at91_pmc_resume(void *data) { unsigned int backup; @@ -143,11 +143,15 @@ static void at91_pmc_resume(void) clk_restore_context(); } -static struct syscore_ops pmc_syscore_ops = { +static const struct syscore_ops pmc_syscore_ops = { .suspend = at91_pmc_suspend, .resume = at91_pmc_resume, }; +static struct syscore pmc_syscore = { + .ops = &pmc_syscore_ops, +}; + static const struct of_device_id pmc_dt_ids[] = { { .compatible = "atmel,sama5d2-pmc" }, { .compatible = "microchip,sama7g5-pmc", }, @@ -185,7 +189,7 @@ static int __init pmc_register_ops(void) return -ENOMEM; } - register_syscore_ops(&pmc_syscore_ops); + register_syscore(&pmc_syscore); return 0; } diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 5daa32c4cf254..543d7aee8d248 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -117,9 +117,6 @@ struct at91_clk_pms { unsigned int parent; }; -#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) -#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask)) - #define ndck(a, s) (a[s - 1].id + 1) #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1) diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 15bbdeb60b8e6..08cc8e5acf437 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #define RST_NR_PER_BANK 32 @@ -299,6 +300,53 @@ static const u16 en7581_rst_ofs[] = { REG_RST_CTRL1, }; +static const u16 en7523_rst_map[] = { + /* RST_CTRL2 */ + [EN7523_XPON_PHY_RST] = 0, + [EN7523_XSI_MAC_RST] = 7, + [EN7523_XSI_PHY_RST] = 8, + [EN7523_NPU_RST] = 9, + [EN7523_I2S_RST] = 10, + [EN7523_TRNG_RST] = 11, + [EN7523_TRNG_MSTART_RST] = 12, + [EN7523_DUAL_HSI0_RST] = 13, + [EN7523_DUAL_HSI1_RST] = 14, + [EN7523_HSI_RST] = 15, + [EN7523_DUAL_HSI0_MAC_RST] = 16, + [EN7523_DUAL_HSI1_MAC_RST] = 17, + [EN7523_HSI_MAC_RST] = 18, + [EN7523_WDMA_RST] = 19, + [EN7523_WOE0_RST] = 20, + [EN7523_WOE1_RST] = 21, + [EN7523_HSDMA_RST] = 22, + [EN7523_I2C2RBUS_RST] = 23, + [EN7523_TDMA_RST] = 24, + /* RST_CTRL1 */ + [EN7523_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0, + [EN7523_FE_PDMA_RST] = RST_NR_PER_BANK + 1, + [EN7523_FE_QDMA_RST] = RST_NR_PER_BANK + 2, + [EN7523_PCM_SPIWP_RST] = RST_NR_PER_BANK + 4, + [EN7523_CRYPTO_RST] = RST_NR_PER_BANK + 6, + [EN7523_TIMER_RST] = RST_NR_PER_BANK + 8, + [EN7523_PCM1_RST] = RST_NR_PER_BANK + 11, + [EN7523_UART_RST] = RST_NR_PER_BANK + 12, + [EN7523_GPIO_RST] = RST_NR_PER_BANK + 13, + [EN7523_GDMA_RST] = RST_NR_PER_BANK + 14, + [EN7523_I2C_MASTER_RST] = RST_NR_PER_BANK + 16, + [EN7523_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17, + [EN7523_SFC_RST] = RST_NR_PER_BANK + 18, + [EN7523_UART2_RST] = RST_NR_PER_BANK + 19, + [EN7523_GDMP_RST] = RST_NR_PER_BANK + 20, + [EN7523_FE_RST] = RST_NR_PER_BANK + 21, + [EN7523_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22, + [EN7523_GSW_RST] = RST_NR_PER_BANK + 23, + [EN7523_SFC2_PCM_RST] = RST_NR_PER_BANK + 25, + [EN7523_PCIE0_RST] = RST_NR_PER_BANK + 26, + [EN7523_PCIE1_RST] = RST_NR_PER_BANK + 27, + [EN7523_PCIE_HB_RST] = RST_NR_PER_BANK + 29, + [EN7523_XPON_MAC_RST] = RST_NR_PER_BANK + 31, +}; + static const u16 en7581_rst_map[] = { /* RST_CTRL2 */ [EN7581_XPON_PHY_RST] = 0, @@ -357,6 +405,9 @@ static const u16 en7581_rst_map[] = { [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31, }; +static int en7581_reset_register(struct device *dev, void __iomem *base, + const u16 *rst_map, int nr_resets); + static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val) { if (!desc->base_bits) @@ -552,7 +603,8 @@ static int en7523_clk_hw_init(struct platform_device *pdev, en7523_register_clocks(&pdev->dev, clk_data, base, np_base); - return 0; + return en7581_reset_register(&pdev->dev, np_base, en7523_rst_map, + ARRAY_SIZE(en7523_rst_map)); } static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, @@ -652,7 +704,8 @@ static const struct reset_control_ops en7581_reset_ops = { .status = en7523_reset_status, }; -static int en7581_reset_register(struct device *dev, void __iomem *base) +static int en7581_reset_register(struct device *dev, void __iomem *base, + const u16 *rst_map, int nr_resets) { struct en_rst_data *rst_data; @@ -661,10 +714,10 @@ static int en7581_reset_register(struct device *dev, void __iomem *base) return -ENOMEM; rst_data->bank_ofs = en7581_rst_ofs; - rst_data->idx_map = en7581_rst_map; + rst_data->idx_map = rst_map; rst_data->base = base; - rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map); + rst_data->rcdev.nr_resets = nr_resets; rst_data->rcdev.of_xlate = en7523_reset_xlate; rst_data->rcdev.ops = &en7581_reset_ops; rst_data->rcdev.of_node = dev->of_node; @@ -698,7 +751,8 @@ static int en7581_clk_hw_init(struct platform_device *pdev, val = readl(base + REG_NP_SCU_PCIC); writel(val | 3, base + REG_NP_SCU_PCIC); - return en7581_reset_register(&pdev->dev, base); + return en7581_reset_register(&pdev->dev, base, en7581_rst_map, + ARRAY_SIZE(en7581_rst_map)); } static int en7523_clk_probe(struct platform_device *pdev) diff --git a/drivers/clk/clk-lan966x.c b/drivers/clk/clk-lan966x.c index 16e0405fe28bf..3c7a48c616bbc 100644 --- a/drivers/clk/clk-lan966x.c +++ b/drivers/clk/clk-lan966x.c @@ -16,8 +16,6 @@ #include #include -#include - #define GCK_ENA BIT(0) #define GCK_SRC_SEL GENMASK(9, 8) #define GCK_PRESCALER GENMASK(23, 16) diff --git a/drivers/clk/davinci/psc-da850.c b/drivers/clk/davinci/psc-da850.c index 5a18bca464cda..94081ab1e6887 100644 --- a/drivers/clk/davinci/psc-da850.c +++ b/drivers/clk/davinci/psc-da850.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include @@ -66,14 +65,8 @@ LPSC_CLKDEV3(ecap_clkdev, "fck", "ecap.0", "fck", "ecap.1", "fck", "ecap.2"); -static struct reset_control_lookup da850_psc0_reset_lookup_table[] = { - RESET_LOOKUP("da850-psc0", 15, "davinci-rproc.0", NULL), -}; - static int da850_psc0_init(struct device *dev, void __iomem *base) { - reset_controller_add_lookup(da850_psc0_reset_lookup_table, - ARRAY_SIZE(da850_psc0_reset_lookup_table)); return davinci_psc_register_clocks(dev, da850_psc0_info, 16, base); } diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index 6ff6d934848a3..b292e7ca5c248 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -105,6 +105,7 @@ config CLK_IMX8ULP tristate "IMX8ULP CCM Clock Driver" depends on ARCH_MXC || COMPILE_TEST select MXC_CLK + select AUXILIARY_BUS help Build the driver for i.MX8ULP CCM Clock Driver diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 03f2b2a1ab631..208b46873a18c 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -41,6 +41,7 @@ clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o clk-imx-acm-$(CONFIG_CLK_IMX8QXP) = clk-imx8-acm.o obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp.o +obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp-sim-lpav.o obj-$(CONFIG_CLK_IMX1) += clk-imx1.o obj-$(CONFIG_CLK_IMX25) += clk-imx25.o diff --git a/drivers/clk/imx/clk-composite-7ulp.c b/drivers/clk/imx/clk-composite-7ulp.c index 8ed2e0ad2769c..37d2fc197be67 100644 --- a/drivers/clk/imx/clk-composite-7ulp.c +++ b/drivers/clk/imx/clk-composite-7ulp.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,9 @@ static int pcc_gate_enable(struct clk_hw *hw) if (ret) return ret; + /* Make sure the IP's clock is ready before release reset */ + udelay(1); + spin_lock_irqsave(gate->lock, flags); /* * release the sw reset for peripherals associated with @@ -47,6 +51,15 @@ static int pcc_gate_enable(struct clk_hw *hw) spin_unlock_irqrestore(gate->lock, flags); + /* + * Read back the register to make sure the previous write has been + * done in the target HW register. For IP like GPU, after deassert + * the reset, need to wait for a while to make sure the sync reset + * is done + */ + readl(gate->reg); + udelay(1); + return 0; } diff --git a/drivers/clk/imx/clk-imx8mp-audiomix.c b/drivers/clk/imx/clk-imx8mp-audiomix.c index 775f62dddb11d..131702f2c9ecf 100644 --- a/drivers/clk/imx/clk-imx8mp-audiomix.c +++ b/drivers/clk/imx/clk-imx8mp-audiomix.c @@ -230,50 +230,19 @@ struct clk_imx8mp_audiomix_priv { #if IS_ENABLED(CONFIG_RESET_CONTROLLER) -static void clk_imx8mp_audiomix_reset_unregister_adev(void *_adev) -{ - struct auxiliary_device *adev = _adev; - - auxiliary_device_delete(adev); - auxiliary_device_uninit(adev); -} - -static void clk_imx8mp_audiomix_reset_adev_release(struct device *dev) -{ - struct auxiliary_device *adev = to_auxiliary_dev(dev); - - kfree(adev); -} - static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev, struct clk_imx8mp_audiomix_priv *priv) { - struct auxiliary_device *adev __free(kfree) = NULL; - int ret; + struct auxiliary_device *adev; if (!of_property_present(dev->of_node, "#reset-cells")) return 0; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = devm_auxiliary_device_create(dev, "reset", NULL); if (!adev) - return -ENOMEM; - - adev->name = "reset"; - adev->dev.parent = dev; - adev->dev.release = clk_imx8mp_audiomix_reset_adev_release; - - ret = auxiliary_device_init(adev); - if (ret) - return ret; + return -ENODEV; - ret = auxiliary_device_add(adev); - if (ret) { - auxiliary_device_uninit(adev); - return ret; - } - - return devm_add_action_or_reset(dev, clk_imx8mp_audiomix_reset_unregister_adev, - no_free_ptr(adev)); + return 0; } #else /* !CONFIG_RESET_CONTROLLER */ diff --git a/drivers/clk/imx/clk-imx8ulp-sim-lpav.c b/drivers/clk/imx/clk-imx8ulp-sim-lpav.c new file mode 100644 index 0000000000000..990c95b89b75c --- /dev/null +++ b/drivers/clk/imx/clk-imx8ulp-sim-lpav.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2025 NXP + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SYSCTRL0 0x8 + +#define IMX8ULP_HIFI_CLK_GATE(gname, cname, pname, bidx) \ + { \ + .name = gname "_cg", \ + .id = IMX8ULP_CLK_SIM_LPAV_HIFI_##cname, \ + .parent = { .fw_name = pname }, \ + .bit = bidx, \ + } + +struct clk_imx8ulp_sim_lpav_data { + spinlock_t lock; /* shared by MUX, clock gate and reset */ + unsigned long flags; /* for spinlock usage */ + struct clk_hw_onecell_data clk_data; /* keep last */ +}; + +struct clk_imx8ulp_sim_lpav_gate { + const char *name; + int id; + const struct clk_parent_data parent; + u8 bit; +}; + +static struct clk_imx8ulp_sim_lpav_gate gates[] = { + IMX8ULP_HIFI_CLK_GATE("hifi_core", CORE, "core", 17), + IMX8ULP_HIFI_CLK_GATE("hifi_pbclk", PBCLK, "bus", 18), + IMX8ULP_HIFI_CLK_GATE("hifi_plat", PLAT, "plat", 19) +}; + +static void clk_imx8ulp_sim_lpav_lock(void *arg) __acquires(&data->lock) +{ + struct clk_imx8ulp_sim_lpav_data *data = dev_get_drvdata(arg); + + spin_lock_irqsave(&data->lock, data->flags); +} + +static void clk_imx8ulp_sim_lpav_unlock(void *arg) __releases(&data->lock) +{ + struct clk_imx8ulp_sim_lpav_data *data = dev_get_drvdata(arg); + + spin_unlock_irqrestore(&data->lock, data->flags); +} + +static int clk_imx8ulp_sim_lpav_probe(struct platform_device *pdev) +{ + const struct regmap_config regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .lock = clk_imx8ulp_sim_lpav_lock, + .unlock = clk_imx8ulp_sim_lpav_unlock, + .lock_arg = &pdev->dev, + }; + struct clk_imx8ulp_sim_lpav_data *data; + struct auxiliary_device *adev; + struct regmap *regmap; + void __iomem *base; + struct clk_hw *hw; + int i, ret; + + data = devm_kzalloc(&pdev->dev, + struct_size(data, clk_data.hws, ARRAY_SIZE(gates)), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + dev_set_drvdata(&pdev->dev, data); + + /* + * this lock is used directly by the clock gate and indirectly + * by the reset and mux controller via the regmap API + */ + spin_lock_init(&data->lock); + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return dev_err_probe(&pdev->dev, PTR_ERR(base), + "failed to ioremap base\n"); + /* + * although the clock gate doesn't use the regmap API to modify the + * registers, we still need the regmap because of the reset auxiliary + * driver and the MUX drivers, which use the parent device's regmap + */ + regmap = devm_regmap_init_mmio(&pdev->dev, base, ®map_config); + if (IS_ERR(regmap)) + return dev_err_probe(&pdev->dev, PTR_ERR(regmap), + "failed to initialize regmap\n"); + + data->clk_data.num = ARRAY_SIZE(gates); + + for (i = 0; i < ARRAY_SIZE(gates); i++) { + hw = devm_clk_hw_register_gate_parent_data(&pdev->dev, + gates[i].name, + &gates[i].parent, + CLK_SET_RATE_PARENT, + base + SYSCTRL0, + gates[i].bit, + 0x0, &data->lock); + if (IS_ERR(hw)) + return dev_err_probe(&pdev->dev, PTR_ERR(hw), + "failed to register %s gate\n", + gates[i].name); + + data->clk_data.hws[i] = hw; + } + + adev = devm_auxiliary_device_create(&pdev->dev, "reset", NULL); + if (!adev) + return dev_err_probe(&pdev->dev, -ENODEV, + "failed to register aux reset\n"); + + ret = devm_of_clk_add_hw_provider(&pdev->dev, + of_clk_hw_onecell_get, + &data->clk_data); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to register clk hw provider\n"); + + /* used to probe MUX child device */ + return devm_of_platform_populate(&pdev->dev); +} + +static const struct of_device_id clk_imx8ulp_sim_lpav_of_match[] = { + { .compatible = "fsl,imx8ulp-sim-lpav" }, + { } +}; +MODULE_DEVICE_TABLE(of, clk_imx8ulp_sim_lpav_of_match); + +static struct platform_driver clk_imx8ulp_sim_lpav_driver = { + .probe = clk_imx8ulp_sim_lpav_probe, + .driver = { + .name = "clk-imx8ulp-sim-lpav", + .of_match_table = clk_imx8ulp_sim_lpav_of_match, + }, +}; +module_platform_driver(clk_imx8ulp_sim_lpav_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("i.MX8ULP LPAV System Integration Module (SIM) clock driver"); +MODULE_AUTHOR("Laurentiu Mihalcea "); diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index 9e11f1c7c397e..41eb38552a9c7 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -139,7 +139,7 @@ static struct clk * __init vf610_get_fixed_clock( return clk; }; -static int vf610_clk_suspend(void) +static int vf610_clk_suspend(void *data) { int i; @@ -156,7 +156,7 @@ static int vf610_clk_suspend(void) return 0; } -static void vf610_clk_resume(void) +static void vf610_clk_resume(void *data) { int i; @@ -171,11 +171,15 @@ static void vf610_clk_resume(void) writel_relaxed(ccgr[i], CCM_CCGRx(i)); } -static struct syscore_ops vf610_clk_syscore_ops = { +static const struct syscore_ops vf610_clk_syscore_ops = { .suspend = vf610_clk_suspend, .resume = vf610_clk_resume, }; +static struct syscore vf610_clk_syscore = { + .ops = &vf610_clk_syscore_ops, +}; + static void __init vf610_clocks_init(struct device_node *ccm_node) { struct device_node *np; @@ -462,7 +466,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) clk_prepare_enable(clk[clks_init_on[i]]); - register_syscore_ops(&vf610_clk_syscore_ops); + register_syscore(&vf610_clk_syscore); /* Add the clocks to provider list */ clk_data.clks = clk; diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c index 590e9c85cb25b..94cee44c854f9 100644 --- a/drivers/clk/ingenic/jz4725b-cgu.c +++ b/drivers/clk/ingenic/jz4725b-cgu.c @@ -268,6 +268,6 @@ static void __init jz4725b_cgu_init(struct device_node *np) if (retval) pr_err("%s: failed to register CGU Clocks\n", __func__); - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init); diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c index 3e0a30574ebb3..2def3aedc8dd2 100644 --- a/drivers/clk/ingenic/jz4740-cgu.c +++ b/drivers/clk/ingenic/jz4740-cgu.c @@ -266,6 +266,6 @@ static void __init jz4740_cgu_init(struct device_node *np) if (retval) pr_err("%s: failed to register CGU Clocks\n", __func__); - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init); diff --git a/drivers/clk/ingenic/jz4755-cgu.c b/drivers/clk/ingenic/jz4755-cgu.c index f2c2d848dab7a..17cf5dcaece99 100644 --- a/drivers/clk/ingenic/jz4755-cgu.c +++ b/drivers/clk/ingenic/jz4755-cgu.c @@ -337,7 +337,7 @@ static void __init jz4755_cgu_init(struct device_node *np) if (retval) pr_err("%s: failed to register CGU Clocks\n", __func__); - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } /* * CGU has some children devices, this is useful for probing children devices diff --git a/drivers/clk/ingenic/jz4760-cgu.c b/drivers/clk/ingenic/jz4760-cgu.c index e407f00bd5942..372fe4b079927 100644 --- a/drivers/clk/ingenic/jz4760-cgu.c +++ b/drivers/clk/ingenic/jz4760-cgu.c @@ -436,7 +436,7 @@ static void __init jz4760_cgu_init(struct device_node *np) if (retval) pr_err("%s: failed to register CGU Clocks\n", __func__); - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } /* We only probe via devicetree, no need for a platform driver */ diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c index 6ae1740367f9e..58f1d3bad6774 100644 --- a/drivers/clk/ingenic/jz4770-cgu.c +++ b/drivers/clk/ingenic/jz4770-cgu.c @@ -456,7 +456,7 @@ static void __init jz4770_cgu_init(struct device_node *np) if (retval) pr_err("%s: failed to register CGU Clocks\n", __func__); - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } /* We only probe via devicetree, no need for a platform driver */ diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c index 07e2f3c5c4549..1e88aef7ac0f3 100644 --- a/drivers/clk/ingenic/jz4780-cgu.c +++ b/drivers/clk/ingenic/jz4780-cgu.c @@ -803,6 +803,6 @@ static void __init jz4780_cgu_init(struct device_node *np) return; } - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init); diff --git a/drivers/clk/ingenic/pm.c b/drivers/clk/ingenic/pm.c index 341752b640d2b..206d5cf2872f6 100644 --- a/drivers/clk/ingenic/pm.c +++ b/drivers/clk/ingenic/pm.c @@ -15,7 +15,7 @@ static void __iomem * __maybe_unused ingenic_cgu_base; -static int __maybe_unused ingenic_cgu_pm_suspend(void) +static int __maybe_unused ingenic_cgu_pm_suspend(void *data) { u32 val = readl(ingenic_cgu_base + CGU_REG_LCR); @@ -24,22 +24,26 @@ static int __maybe_unused ingenic_cgu_pm_suspend(void) return 0; } -static void __maybe_unused ingenic_cgu_pm_resume(void) +static void __maybe_unused ingenic_cgu_pm_resume(void *data) { u32 val = readl(ingenic_cgu_base + CGU_REG_LCR); writel(val & ~LCR_LOW_POWER_MODE, ingenic_cgu_base + CGU_REG_LCR); } -static struct syscore_ops __maybe_unused ingenic_cgu_pm_ops = { +static const struct syscore_ops __maybe_unused ingenic_cgu_pm_ops = { .suspend = ingenic_cgu_pm_suspend, .resume = ingenic_cgu_pm_resume, }; -void ingenic_cgu_register_syscore_ops(struct ingenic_cgu *cgu) +static struct syscore __maybe_unused ingenic_cgu_pm = { + .ops = &ingenic_cgu_pm_ops, +}; + +void ingenic_cgu_register_syscore(struct ingenic_cgu *cgu) { if (IS_ENABLED(CONFIG_PM_SLEEP)) { ingenic_cgu_base = cgu->base; - register_syscore_ops(&ingenic_cgu_pm_ops); + register_syscore(&ingenic_cgu_pm); } } diff --git a/drivers/clk/ingenic/pm.h b/drivers/clk/ingenic/pm.h index fa7540407b6b7..0dcb57dc64cb4 100644 --- a/drivers/clk/ingenic/pm.h +++ b/drivers/clk/ingenic/pm.h @@ -7,6 +7,6 @@ struct ingenic_cgu; -void ingenic_cgu_register_syscore_ops(struct ingenic_cgu *cgu); +void ingenic_cgu_register_syscore(struct ingenic_cgu *cgu); #endif /* DRIVERS_CLK_INGENIC_PM_H */ diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c index 7d04ef40b7cf9..bc6a51da20725 100644 --- a/drivers/clk/ingenic/tcu.c +++ b/drivers/clk/ingenic/tcu.c @@ -455,7 +455,7 @@ static int __init ingenic_tcu_probe(struct device_node *np) return ret; } -static int __maybe_unused tcu_pm_suspend(void) +static int __maybe_unused tcu_pm_suspend(void *data) { struct ingenic_tcu *tcu = ingenic_tcu; @@ -465,7 +465,7 @@ static int __maybe_unused tcu_pm_suspend(void) return 0; } -static void __maybe_unused tcu_pm_resume(void) +static void __maybe_unused tcu_pm_resume(void *data) { struct ingenic_tcu *tcu = ingenic_tcu; @@ -473,11 +473,15 @@ static void __maybe_unused tcu_pm_resume(void) clk_enable(tcu->clk); } -static struct syscore_ops __maybe_unused tcu_pm_ops = { +static const struct syscore_ops __maybe_unused tcu_pm_ops = { .suspend = tcu_pm_suspend, .resume = tcu_pm_resume, }; +static struct syscore __maybe_unused tcu_pm = { + .ops = &tcu_pm_ops, +}; + static void __init ingenic_tcu_init(struct device_node *np) { int ret = ingenic_tcu_probe(np); @@ -486,7 +490,7 @@ static void __init ingenic_tcu_init(struct device_node *np) pr_crit("Failed to initialize TCU clocks: %d\n", ret); if (IS_ENABLED(CONFIG_PM_SLEEP)) - register_syscore_ops(&tcu_pm_ops); + register_syscore(&tcu_pm); } CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-tcu", ingenic_tcu_init); diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c index d80886caf3933..d89bdfb7c219a 100644 --- a/drivers/clk/ingenic/x1000-cgu.c +++ b/drivers/clk/ingenic/x1000-cgu.c @@ -556,7 +556,7 @@ static void __init x1000_cgu_init(struct device_node *np) return; } - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } /* * CGU has some children devices, this is useful for probing children devices diff --git a/drivers/clk/ingenic/x1830-cgu.c b/drivers/clk/ingenic/x1830-cgu.c index 0fd46e50a513f..acf856e5009e0 100644 --- a/drivers/clk/ingenic/x1830-cgu.c +++ b/drivers/clk/ingenic/x1830-cgu.c @@ -463,7 +463,7 @@ static void __init x1830_cgu_init(struct device_node *np) return; } - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } /* * CGU has some children devices, this is useful for probing children devices diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index a4b42811de55d..9d5071223f4cb 100644 --- a/drivers/clk/keystone/sci-clk.c +++ b/drivers/clk/keystone/sci-clk.c @@ -496,8 +496,8 @@ static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider) static int _cmp_sci_clk_list(void *priv, const struct list_head *a, const struct list_head *b) { - struct sci_clk *ca = container_of(a, struct sci_clk, node); - struct sci_clk *cb = container_of(b, struct sci_clk, node); + const struct sci_clk *ca = container_of(a, struct sci_clk, node); + const struct sci_clk *cb = container_of(b, struct sci_clk, node); return _cmp_sci_clk(ca, &cb); } diff --git a/drivers/clk/keystone/syscon-clk.c b/drivers/clk/keystone/syscon-clk.c index c509929da8545..ecf180a7949c9 100644 --- a/drivers/clk/keystone/syscon-clk.c +++ b/drivers/clk/keystone/syscon-clk.c @@ -129,7 +129,7 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - regmap = regmap_init_mmio(dev, base, &ti_syscon_regmap_cfg); + regmap = devm_regmap_init_mmio(dev, base, &ti_syscon_regmap_cfg); if (IS_ERR(regmap)) return dev_err_probe(dev, PTR_ERR(regmap), "failed to get regmap\n"); diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig index 0724ce65898f3..1b9e43eb54976 100644 --- a/drivers/clk/microchip/Kconfig +++ b/drivers/clk/microchip/Kconfig @@ -7,6 +7,8 @@ config MCHP_CLK_MPFS bool "Clk driver for PolarFire SoC" depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST default ARCH_MICROCHIP_POLARFIRE + depends on MFD_SYSCON select AUXILIARY_BUS + select REGMAP_MMIO help Supports Clock Configuration for PolarFire SoC diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c index c22632a7439c5..ee58304913ef1 100644 --- a/drivers/clk/microchip/clk-mpfs.c +++ b/drivers/clk/microchip/clk-mpfs.c @@ -4,10 +4,13 @@ * * Copyright (C) 2020-2022 Microchip Technology Inc. All rights reserved. */ +#include #include #include +#include #include #include +#include #include #include @@ -30,6 +33,14 @@ #define MSSPLL_POSTDIV_WIDTH 0x07u #define MSSPLL_FIXED_DIV 4u +static const struct regmap_config mpfs_clk_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .val_format_endian = REGMAP_ENDIAN_LITTLE, + .max_register = REG_SUBBLK_RESET_CR, +}; + /* * This clock ID is defined here, rather than the binding headers, as it is an * internal clock only, and therefore has no consumers in other peripheral @@ -39,6 +50,7 @@ struct mpfs_clock_data { struct device *dev; + struct regmap *regmap; void __iomem *base; void __iomem *msspll_base; struct clk_hw_onecell_data hw_data; @@ -67,21 +79,39 @@ struct mpfs_msspll_out_hw_clock { #define to_mpfs_msspll_out_clk(_hw) container_of(_hw, struct mpfs_msspll_out_hw_clock, hw) +struct mpfs_cfg_clock { + struct regmap *map; + const struct clk_div_table *table; + u8 map_offset; + u8 shift; + u8 width; + u8 flags; +}; + struct mpfs_cfg_hw_clock { - struct clk_divider cfg; - struct clk_init_data init; + struct clk_hw hw; + struct mpfs_cfg_clock cfg; unsigned int id; - u32 reg_offset; +}; + +#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw) + +struct mpfs_periph_clock { + struct regmap *map; + u8 map_offset; + u8 shift; }; struct mpfs_periph_hw_clock { - struct clk_gate periph; + struct clk_hw hw; + struct mpfs_periph_clock periph; unsigned int id; }; +#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw) + /* - * mpfs_clk_lock prevents anything else from writing to the - * mpfs clk block while a software locked register is being written. + * Protects MSSPLL outputs, since there's two to a register */ static DEFINE_SPINLOCK(mpfs_clk_lock); @@ -219,16 +249,61 @@ static int mpfs_clk_register_msspll_outs(struct device *dev, /* * "CFG" clocks */ +static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + u32 val; -#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \ - .id = _id, \ - .cfg.shift = _shift, \ - .cfg.width = _width, \ - .cfg.table = _table, \ - .reg_offset = _offset, \ - .cfg.flags = _flags, \ - .cfg.hw.init = CLK_HW_INIT(_name, _parent, &clk_divider_ops, 0), \ - .cfg.lock = &mpfs_clk_lock, \ + regmap_read(cfg->map, cfg->map_offset, &val); + val >>= cfg->shift; + val &= clk_div_mask(cfg->width); + + return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width); +} + +static int mpfs_cfg_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + + return divider_determine_rate(hw, req, cfg->table, cfg->width, 0); +} + +static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + int divider_setting; + u32 val; + u32 mask; + + divider_setting = divider_get_val(rate, prate, cfg->table, cfg->width, 0); + + if (divider_setting < 0) + return divider_setting; + + mask = clk_div_mask(cfg->width) << cfg->shift; + val = divider_setting << cfg->shift; + regmap_update_bits(cfg->map, cfg->map_offset, val, mask); + + return 0; +} + +static const struct clk_ops mpfs_clk_cfg_ops = { + .recalc_rate = mpfs_cfg_clk_recalc_rate, + .determine_rate = mpfs_cfg_clk_determine_rate, + .set_rate = mpfs_cfg_clk_set_rate, +}; + +#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \ + .id = _id, \ + .cfg.shift = _shift, \ + .cfg.width = _width, \ + .cfg.table = _table, \ + .cfg.map_offset = _offset, \ + .cfg.flags = _flags, \ + .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \ } #define CLK_CPU_OFFSET 0u @@ -248,10 +323,10 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = { .cfg.shift = 0, .cfg.width = 12, .cfg.table = mpfs_div_rtcref_table, - .reg_offset = REG_RTC_CLOCK_CR, + .cfg.map_offset = REG_RTC_CLOCK_CR, .cfg.flags = CLK_DIVIDER_ONE_BASED, - .cfg.hw.init = - CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &clk_divider_ops, 0), + .hw.init = + CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0), } }; @@ -264,14 +339,14 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock * for (i = 0; i < num_clks; i++) { struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i]; - cfg_hw->cfg.reg = data->base + cfg_hw->reg_offset; - ret = devm_clk_hw_register(dev, &cfg_hw->cfg.hw); + cfg_hw->cfg.map = data->regmap; + ret = devm_clk_hw_register(dev, &cfg_hw->hw); if (ret) return dev_err_probe(dev, ret, "failed to register clock id: %d\n", cfg_hw->id); id = cfg_hw->id; - data->hw_data.hws[id] = &cfg_hw->cfg.hw; + data->hw_data.hws[id] = &cfg_hw->hw; } return 0; @@ -281,15 +356,50 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock * * peripheral clocks - devices connected to axi or ahb buses. */ -#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \ - .id = _id, \ - .periph.bit_idx = _shift, \ - .periph.hw.init = CLK_HW_INIT_HW(_name, _parent, &clk_gate_ops, \ - _flags), \ - .periph.lock = &mpfs_clk_lock, \ +static int mpfs_periph_clk_enable(struct clk_hw *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + + regmap_update_bits(periph->map, periph->map_offset, + BIT(periph->shift), BIT(periph->shift)); + + return 0; } -#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].cfg.hw) +static void mpfs_periph_clk_disable(struct clk_hw *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + + regmap_update_bits(periph->map, periph->map_offset, BIT(periph->shift), 0); +} + +static int mpfs_periph_clk_is_enabled(struct clk_hw *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + u32 val; + + regmap_read(periph->map, periph->map_offset, &val); + + return !!(val & BIT(periph->shift)); +} + +static const struct clk_ops mpfs_periph_clk_ops = { + .enable = mpfs_periph_clk_enable, + .disable = mpfs_periph_clk_disable, + .is_enabled = mpfs_periph_clk_is_enabled, +}; + +#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \ + .id = _id, \ + .periph.map_offset = REG_SUBBLK_CLOCK_CR, \ + .periph.shift = _shift, \ + .hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops, _flags), \ +} + +#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].hw) /* * Critical clocks: @@ -346,19 +456,55 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c for (i = 0; i < num_clks; i++) { struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i]; - periph_hw->periph.reg = data->base + REG_SUBBLK_CLOCK_CR; - ret = devm_clk_hw_register(dev, &periph_hw->periph.hw); + periph_hw->periph.map = data->regmap; + ret = devm_clk_hw_register(dev, &periph_hw->hw); if (ret) return dev_err_probe(dev, ret, "failed to register clock id: %d\n", periph_hw->id); id = periph_hws[i].id; - data->hw_data.hws[id] = &periph_hw->periph.hw; + data->hw_data.hws[id] = &periph_hw->hw; } return 0; } +static inline int mpfs_clk_syscon_probe(struct mpfs_clock_data *clk_data, + struct platform_device *pdev) +{ + clk_data->regmap = syscon_regmap_lookup_by_compatible("microchip,mpfs-mss-top-sysreg"); + if (IS_ERR(clk_data->regmap)) + return PTR_ERR(clk_data->regmap); + + clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_data->msspll_base)) + return PTR_ERR(clk_data->msspll_base); + + return 0; +} + +static inline int mpfs_clk_old_format_probe(struct mpfs_clock_data *clk_data, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + dev_warn(&pdev->dev, "falling back to old devicetree format"); + + clk_data->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_data->base)) + return PTR_ERR(clk_data->base); + + clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(clk_data->msspll_base)) + return PTR_ERR(clk_data->msspll_base); + + clk_data->regmap = devm_regmap_init_mmio(dev, clk_data->base, &mpfs_clk_regmap_config); + if (IS_ERR(clk_data->regmap)) + return PTR_ERR(clk_data->regmap); + + return mpfs_reset_controller_register(dev, clk_data->regmap); +} + static int mpfs_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -374,13 +520,12 @@ static int mpfs_clk_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - clk_data->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(clk_data->base)) - return PTR_ERR(clk_data->base); - - clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(clk_data->msspll_base)) - return PTR_ERR(clk_data->msspll_base); + ret = mpfs_clk_syscon_probe(clk_data, pdev); + if (ret) { + ret = mpfs_clk_old_format_probe(clk_data, pdev); + if (ret) + return ret; + } clk_data->hw_data.num = num_clks; clk_data->dev = dev; @@ -406,11 +551,7 @@ static int mpfs_clk_probe(struct platform_device *pdev) if (ret) return ret; - ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &clk_data->hw_data); - if (ret) - return ret; - - return mpfs_reset_controller_register(dev, clk_data->base + REG_SUBBLK_RESET_CR); + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &clk_data->hw_data); } static const struct of_device_id mpfs_clk_of_match_table[] = { diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index 785dbede48354..5adbbd91a6db3 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -215,22 +215,26 @@ static struct clk *clk_gating_get_src( return ERR_PTR(-ENODEV); } -static int mvebu_clk_gating_suspend(void) +static int mvebu_clk_gating_suspend(void *data) { ctrl->saved_reg = readl(ctrl->base); return 0; } -static void mvebu_clk_gating_resume(void) +static void mvebu_clk_gating_resume(void *data) { writel(ctrl->saved_reg, ctrl->base); } -static struct syscore_ops clk_gate_syscore_ops = { +static const struct syscore_ops clk_gate_syscore_ops = { .suspend = mvebu_clk_gating_suspend, .resume = mvebu_clk_gating_resume, }; +static struct syscore clk_gate_syscore = { + .ops = &clk_gate_syscore_ops, +}; + void __init mvebu_clk_gating_setup(struct device_node *np, const struct clk_gating_soc_desc *desc) { @@ -284,7 +288,7 @@ void __init mvebu_clk_gating_setup(struct device_node *np, of_clk_add_provider(np, clk_gating_get_src, ctrl); - register_syscore_ops(&clk_gate_syscore_ops); + register_syscore(&clk_gate_syscore); return; gates_out: diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c index 03c59bf221060..b47c869060466 100644 --- a/drivers/clk/mvebu/cp110-system-controller.c +++ b/drivers/clk/mvebu/cp110-system-controller.c @@ -110,6 +110,25 @@ static const char * const gate_base_names[] = { [CP110_GATE_EIP197] = "eip197" }; +static unsigned long gate_flags(const u8 bit_idx) +{ + switch (bit_idx) { + case CP110_GATE_PCIE_X1_0: + case CP110_GATE_PCIE_X1_1: + case CP110_GATE_PCIE_X4: + /* + * If a port had an active link at boot time, stopping + * the clock creates a failed state from which controller + * driver can not recover. + * Prevent stopping this clock till after a driver has taken + * ownership. + */ + return CLK_IGNORE_UNUSED; + default: + return 0; + } +}; + struct cp110_gate_clk { struct clk_hw hw; struct regmap *regmap; @@ -171,6 +190,7 @@ static struct clk_hw *cp110_register_gate(const char *name, init.ops = &cp110_gate_ops; init.parent_names = &parent_name; init.num_parents = 1; + init.flags = gate_flags(bit_idx); gate->regmap = regmap; gate->bit_idx = bit_idx; diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 78a3038426136..a284ba040b78b 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -215,16 +215,16 @@ config IPQ_APSS_PLL devices. config IPQ_APSS_5424 - tristate "IPQ APSS Clock Controller" + tristate "IPQ5424 APSS Clock Controller" select IPQ_APSS_PLL default y if IPQ_GCC_5424 help - Support for APSS Clock controller on Qualcom IPQ5424 platform. + Support for APSS Clock controller on Qualcomm IPQ5424 platform. Say Y if you want to support CPU frequency scaling on ipq based devices. config IPQ_APSS_6018 - tristate "IPQ APSS Clock Controller" + tristate "IPQ6018 APSS Clock Controller" select IPQ_APSS_PLL depends on QCOM_APCS_IPC || COMPILE_TEST depends on QCOM_SMEM @@ -317,6 +317,17 @@ config IPQ_GCC_9574 i2c, USB, SD/eMMC, etc. Select this for the root clock of ipq9574. +config IPQ_NSSCC_5424 + tristate "IPQ5424 NSS Clock Controller" + depends on ARM64 || COMPILE_TEST + depends on IPQ_GCC_5424 + help + Support for NSS clock controller on ipq5424 devices. + NSSCC receives the clock sources from GCC, CMN PLL and UNIPHY (PCS). + It in turn supplies the clocks and resets to the networking hardware. + Say Y or M if you want to enable networking function on the + IPQ5424 devices. + config IPQ_NSSCC_9574 tristate "IPQ9574 NSS Clock Controller" depends on ARM64 || COMPILE_TEST @@ -531,6 +542,7 @@ config QCM_DISPCC_2290 config QCS_DISPCC_615 tristate "QCS615 Display Clock Controller" + depends on ARM64 || COMPILE_TEST select QCS_GCC_615 help Support for the display clock controller on Qualcomm Technologies, Inc @@ -586,6 +598,7 @@ config QCS_GCC_615 config QCS_GPUCC_615 tristate "QCS615 Graphics clock controller" + depends on ARM64 || COMPILE_TEST select QCS_GCC_615 help Support for the graphics clock controller on QCS615 devices. @@ -594,6 +607,7 @@ config QCS_GPUCC_615 config QCS_VIDEOCC_615 tristate "QCS615 Video Clock Controller" + depends on ARM64 || COMPILE_TEST select QCS_GCC_615 help Support for the video clock controller on QCS615 devices. @@ -1448,6 +1462,7 @@ config SA_VIDEOCC_8775P config SM_VIDEOCC_6350 tristate "SM6350 Video Clock Controller" + depends on ARM64 || COMPILE_TEST select SM_GCC_6350 select QCOM_GDSC help @@ -1516,6 +1531,17 @@ config SM_VIDEOCC_8550 Say Y if you want to support video devices and functionality such as video encode/decode. +config SM_VIDEOCC_8750 + tristate "SM8750 Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select SM_GCC_8750 + select QCOM_GDSC + help + Support for the video clock controller on Qualcomm Technologies, Inc. + SM8750 devices. + Say Y if you want to support video devices and functionality such as + video encode/decode. + config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" depends on SPMI || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 8051d481c439b..0ac8a9055a432 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o obj-$(CONFIG_IPQ_GCC_9574) += gcc-ipq9574.o +obj-$(CONFIG_IPQ_NSSCC_5424) += nsscc-ipq5424.o obj-$(CONFIG_IPQ_NSSCC_9574) += nsscc-ipq9574.o obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o obj-$(CONFIG_IPQ_NSSCC_QCA8K) += nsscc-qca8k.o @@ -184,6 +185,7 @@ obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o obj-$(CONFIG_SM_VIDEOCC_8350) += videocc-sm8350.o obj-$(CONFIG_SM_VIDEOCC_8450) += videocc-sm8450.o obj-$(CONFIG_SM_VIDEOCC_8550) += videocc-sm8550.o +obj-$(CONFIG_SM_VIDEOCC_8750) += videocc-sm8750.o obj-$(CONFIG_SM_VIDEOCC_MILOS) += videocc-milos.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o diff --git a/drivers/clk/qcom/apss-ipq5424.c b/drivers/clk/qcom/apss-ipq5424.c index 4c67f722e009a..2d622c1fe5d05 100644 --- a/drivers/clk/qcom/apss-ipq5424.c +++ b/drivers/clk/qcom/apss-ipq5424.c @@ -35,13 +35,6 @@ enum { P_L3_PLL, }; -struct apss_clk { - struct notifier_block cpu_clk_notifier; - struct clk_hw *hw; - struct device *dev; - struct clk *l3_clk; -}; - static const struct alpha_pll_config apss_pll_config = { .l = 0x3b, .config_ctl_val = 0x08200920, diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c index cf60e8dd292a9..fb313da7165b8 100644 --- a/drivers/clk/qcom/camcc-sdm845.c +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -1543,6 +1543,7 @@ static struct gdsc bps_gdsc = { .name = "bps_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -1552,6 +1553,7 @@ static struct gdsc ipe_0_gdsc = { .name = "ipe_0_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -1561,6 +1563,7 @@ static struct gdsc ipe_1_gdsc = { .name = "ipe_1_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c index 8aac97d29ce3f..7df12c1311c68 100644 --- a/drivers/clk/qcom/camcc-sm6350.c +++ b/drivers/clk/qcom/camcc-sm6350.c @@ -145,15 +145,11 @@ static struct clk_alpha_pll_postdiv camcc_pll1_out_even = { static const struct alpha_pll_config camcc_pll2_config = { .l = 0x64, .alpha = 0x0, - .post_div_val = 0x3 << 8, - .post_div_mask = 0x3 << 8, - .aux_output_mask = BIT(1), - .main_output_mask = BIT(0), - .early_output_mask = BIT(3), .config_ctl_val = 0x20000800, .config_ctl_hi_val = 0x400003d2, .test_ctl_val = 0x04000400, .test_ctl_hi_val = 0x00004000, + .user_ctl_val = 0x0000030b, }; static struct clk_alpha_pll camcc_pll2 = { @@ -1693,6 +1689,8 @@ static struct clk_branch camcc_sys_tmr_clk = { }, }; +static struct gdsc titan_top_gdsc; + static struct gdsc bps_gdsc = { .gdscr = 0x6004, .en_rest_wait_val = 0x2, @@ -1702,6 +1700,7 @@ static struct gdsc bps_gdsc = { .name = "bps_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, .flags = VOTABLE, }; @@ -1714,6 +1713,7 @@ static struct gdsc ipe_0_gdsc = { .name = "ipe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, .flags = VOTABLE, }; @@ -1726,6 +1726,7 @@ static struct gdsc ife_0_gdsc = { .name = "ife_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, }; static struct gdsc ife_1_gdsc = { @@ -1737,6 +1738,7 @@ static struct gdsc ife_1_gdsc = { .name = "ife_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, }; static struct gdsc ife_2_gdsc = { @@ -1748,6 +1750,7 @@ static struct gdsc ife_2_gdsc = { .name = "ife_2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, }; static struct gdsc titan_top_gdsc = { diff --git a/drivers/clk/qcom/camcc-sm7150.c b/drivers/clk/qcom/camcc-sm7150.c index 4a3baf5d8e858..ee963ed341c39 100644 --- a/drivers/clk/qcom/camcc-sm7150.c +++ b/drivers/clk/qcom/camcc-sm7150.c @@ -139,13 +139,9 @@ static struct clk_fixed_factor camcc_pll1_out_even = { /* 1920MHz configuration */ static const struct alpha_pll_config camcc_pll2_config = { .l = 0x64, - .post_div_val = 0x3 << 8, - .post_div_mask = 0x3 << 8, - .early_output_mask = BIT(3), - .aux_output_mask = BIT(1), - .main_output_mask = BIT(0), .config_ctl_hi_val = 0x400003d6, .config_ctl_val = 0x20000954, + .user_ctl_val = 0x0000030b, }; static struct clk_alpha_pll camcc_pll2 = { @@ -1846,6 +1842,7 @@ static struct gdsc camcc_bps_gdsc = { .name = "camcc_bps_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &camcc_titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -1875,6 +1872,7 @@ static struct gdsc camcc_ipe_0_gdsc = { .name = "camcc_ipe_0_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &camcc_titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -1884,6 +1882,7 @@ static struct gdsc camcc_ipe_1_gdsc = { .name = "camcc_ipe_1_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &camcc_titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -1896,7 +1895,7 @@ static struct gdsc camcc_titan_top_gdsc = { .pwrsts = PWRSTS_OFF_ON, }; -struct clk_hw *camcc_sm7150_hws[] = { +static struct clk_hw *camcc_sm7150_hws[] = { [CAMCC_PLL0_OUT_EVEN] = &camcc_pll0_out_even.hw, [CAMCC_PLL0_OUT_ODD] = &camcc_pll0_out_odd.hw, [CAMCC_PLL1_OUT_EVEN] = &camcc_pll1_out_even.hw, diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c index 6da89c49ba3d8..c95a00628630e 100644 --- a/drivers/clk/qcom/camcc-sm8250.c +++ b/drivers/clk/qcom/camcc-sm8250.c @@ -2213,6 +2213,7 @@ static struct gdsc bps_gdsc = { .name = "bps_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -2222,6 +2223,7 @@ static struct gdsc ipe_0_gdsc = { .name = "ipe_0_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -2231,6 +2233,7 @@ static struct gdsc sbi_gdsc = { .name = "sbi_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; diff --git a/drivers/clk/qcom/camcc-sm8450.c b/drivers/clk/qcom/camcc-sm8450.c index 4dd8be8cc9881..ef8cf54d0eed6 100644 --- a/drivers/clk/qcom/camcc-sm8450.c +++ b/drivers/clk/qcom/camcc-sm8450.c @@ -2935,6 +2935,7 @@ static struct gdsc bps_gdsc = { .name = "bps_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -2944,6 +2945,7 @@ static struct gdsc ipe_0_gdsc = { .name = "ipe_0_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -2953,6 +2955,7 @@ static struct gdsc sbi_gdsc = { .name = "sbi_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; diff --git a/drivers/clk/qcom/camcc-sm8550.c b/drivers/clk/qcom/camcc-sm8550.c index 63aed9e4c362d..b8ece8a57a8a9 100644 --- a/drivers/clk/qcom/camcc-sm8550.c +++ b/drivers/clk/qcom/camcc-sm8550.c @@ -3204,6 +3204,8 @@ static struct clk_branch cam_cc_sfe_1_fast_ahb_clk = { }, }; +static struct gdsc cam_cc_titan_top_gdsc; + static struct gdsc cam_cc_bps_gdsc = { .gdscr = 0x10004, .en_rest_wait_val = 0x2, @@ -3213,6 +3215,7 @@ static struct gdsc cam_cc_bps_gdsc = { .name = "cam_cc_bps_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3225,6 +3228,7 @@ static struct gdsc cam_cc_ife_0_gdsc = { .name = "cam_cc_ife_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3237,6 +3241,7 @@ static struct gdsc cam_cc_ife_1_gdsc = { .name = "cam_cc_ife_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3249,6 +3254,7 @@ static struct gdsc cam_cc_ife_2_gdsc = { .name = "cam_cc_ife_2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3261,6 +3267,7 @@ static struct gdsc cam_cc_ipe_0_gdsc = { .name = "cam_cc_ipe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3273,6 +3280,7 @@ static struct gdsc cam_cc_sbi_gdsc = { .name = "cam_cc_sbi_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3285,6 +3293,7 @@ static struct gdsc cam_cc_sfe_0_gdsc = { .name = "cam_cc_sfe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3297,6 +3306,7 @@ static struct gdsc cam_cc_sfe_1_gdsc = { .name = "cam_cc_sfe_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index 0f10090d4ae68..444e7d8648d42 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c @@ -142,8 +142,8 @@ static int clk_branch2_mem_enable(struct clk_hw *hw) u32 val; int ret; - regmap_update_bits(branch.clkr.regmap, mem_br->mem_enable_reg, - mem_br->mem_enable_ack_mask, mem_br->mem_enable_ack_mask); + regmap_assign_bits(branch.clkr.regmap, mem_br->mem_enable_reg, + mem_br->mem_enable_mask, !mem_br->mem_enable_invert); ret = regmap_read_poll_timeout(branch.clkr.regmap, mem_br->mem_ack_reg, val, val & mem_br->mem_enable_ack_mask, 0, 200); @@ -159,8 +159,8 @@ static void clk_branch2_mem_disable(struct clk_hw *hw) { struct clk_mem_branch *mem_br = to_clk_mem_branch(hw); - regmap_update_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg, - mem_br->mem_enable_ack_mask, 0); + regmap_assign_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg, + mem_br->mem_enable_mask, mem_br->mem_enable_invert); return clk_branch2_disable(hw); } diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h index 292756435f536..6bc2ba2b53505 100644 --- a/drivers/clk/qcom/clk-branch.h +++ b/drivers/clk/qcom/clk-branch.h @@ -44,6 +44,8 @@ struct clk_branch { * @mem_enable_reg: branch clock memory gating register * @mem_ack_reg: branch clock memory ack register * @mem_enable_ack_mask: branch clock memory enable and ack field in @mem_ack_reg + * @mem_enable_mask: branch clock memory enable mask + * @mem_enable_invert: branch clock memory enable and disable has invert logic * @branch: branch clock gating handle * * Clock which can gate its memories. @@ -52,6 +54,8 @@ struct clk_mem_branch { u32 mem_enable_reg; u32 mem_ack_reg; u32 mem_enable_ack_mask; + u32 mem_enable_mask; + bool mem_enable_invert; struct clk_branch branch; }; diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 63c38cb47bc45..1a98b3a0c528c 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -855,6 +855,7 @@ static struct clk_hw *qcs615_rpmh_clocks[] = { [RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw, [RPMH_RF_CLK2] = &clk_rpmh_rf_clk2_a.hw, [RPMH_RF_CLK2_A] = &clk_rpmh_rf_clk2_a_ao.hw, + [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, }; static const struct clk_rpmh_desc clk_rpmh_qcs615 = { diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c index b0bd163a449cc..5b1d8f86515f2 100644 --- a/drivers/clk/qcom/dispcc-sm6350.c +++ b/drivers/clk/qcom/dispcc-sm6350.c @@ -679,6 +679,11 @@ static struct clk_branch disp_cc_xo_clk = { }, }; +static const struct qcom_reset_map disp_cc_sm6350_resets[] = { + [DISP_CC_MDSS_CORE_BCR] = { 0x1000 }, + [DISP_CC_MDSS_RSCC_BCR] = { 0x2000 }, +}; + static struct gdsc mdss_gdsc = { .gdscr = 0x1004, .en_rest_wait_val = 0x2, @@ -746,6 +751,8 @@ static const struct qcom_cc_desc disp_cc_sm6350_desc = { .num_clks = ARRAY_SIZE(disp_cc_sm6350_clocks), .gdscs = disp_cc_sm6350_gdscs, .num_gdscs = ARRAY_SIZE(disp_cc_sm6350_gdscs), + .resets = disp_cc_sm6350_resets, + .num_resets = ARRAY_SIZE(disp_cc_sm6350_resets), }; static const struct of_device_id disp_cc_sm6350_match_table[] = { diff --git a/drivers/clk/qcom/dispcc-sm7150.c b/drivers/clk/qcom/dispcc-sm7150.c index bdfff246ed3fe..811d380a8e9f9 100644 --- a/drivers/clk/qcom/dispcc-sm7150.c +++ b/drivers/clk/qcom/dispcc-sm7150.c @@ -20,6 +20,7 @@ #include "clk-regmap-divider.h" #include "common.h" #include "gdsc.h" +#include "reset.h" enum { DT_BI_TCXO, @@ -356,7 +357,7 @@ static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = { .name = "dispcc_mdss_pclk0_clk_src", .parent_data = dispcc_parent_data_4, .num_parents = ARRAY_SIZE(dispcc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, .ops = &clk_pixel_ops, }, }; @@ -951,6 +952,10 @@ static struct gdsc *dispcc_sm7150_gdscs[] = { [MDSS_GDSC] = &mdss_gdsc, }; +static const struct qcom_reset_map dispcc_sm7150_resets[] = { + [DISPCC_MDSS_CORE_BCR] = { 0x2000 }, +}; + static const struct regmap_config dispcc_sm7150_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -965,6 +970,8 @@ static const struct qcom_cc_desc dispcc_sm7150_desc = { .num_clks = ARRAY_SIZE(dispcc_sm7150_clocks), .gdscs = dispcc_sm7150_gdscs, .num_gdscs = ARRAY_SIZE(dispcc_sm7150_gdscs), + .resets = dispcc_sm7150_resets, + .num_resets = ARRAY_SIZE(dispcc_sm7150_resets), }; static const struct of_device_id dispcc_sm7150_match_table[] = { diff --git a/drivers/clk/qcom/dispcc-x1e80100.c b/drivers/clk/qcom/dispcc-x1e80100.c index 40069eba41f24..aa7fd43969f9c 100644 --- a/drivers/clk/qcom/dispcc-x1e80100.c +++ b/drivers/clk/qcom/dispcc-x1e80100.c @@ -1618,6 +1618,9 @@ static struct clk_regmap *disp_cc_x1e80100_clocks[] = { static const struct qcom_reset_map disp_cc_x1e80100_resets[] = { [DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, + [DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK_ARES] = { .reg = 0x8044, .bit = 2 }, + [DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK_ARES] = { .reg = 0x8068, .bit = 2 }, + [DISP_CC_MDSS_DPTX2_USB_ROUTER_LINK_INTF_CLK_ARES] = { .reg = 0x8088, .bit = 2 }, [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, }; diff --git a/drivers/clk/qcom/ecpricc-qdu1000.c b/drivers/clk/qcom/ecpricc-qdu1000.c index dbc11260479b6..c2a16616ed645 100644 --- a/drivers/clk/qcom/ecpricc-qdu1000.c +++ b/drivers/clk/qcom/ecpricc-qdu1000.c @@ -920,6 +920,7 @@ static struct clk_branch ecpri_cc_eth_100g_c2c1_udp_fifo_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_0_clk = { .mem_enable_reg = 0x8410, .mem_ack_reg = 0x8424, + .mem_enable_mask = BIT(0), .mem_enable_ack_mask = BIT(0), .branch = { .halt_reg = 0x80b4, @@ -943,6 +944,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_1_clk = { .mem_enable_reg = 0x8410, .mem_ack_reg = 0x8424, + .mem_enable_mask = BIT(1), .mem_enable_ack_mask = BIT(1), .branch = { .halt_reg = 0x80bc, @@ -966,6 +968,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_1_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_c2c_hm_macsec_clk = { .mem_enable_reg = 0x8410, .mem_ack_reg = 0x8424, + .mem_enable_mask = BIT(4), .mem_enable_ack_mask = BIT(4), .branch = { .halt_reg = 0x80ac, @@ -989,6 +992,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_c2c_hm_macsec_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_dbg_c2c_hm_ff_0_clk = { .mem_enable_reg = 0x8414, .mem_ack_reg = 0x8428, + .mem_enable_mask = BIT(0), .mem_enable_ack_mask = BIT(0), .branch = { .halt_reg = 0x80d8, @@ -1012,6 +1016,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_dbg_c2c_hm_ff_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_dbg_c2c_hm_ff_1_clk = { .mem_enable_reg = 0x8414, .mem_ack_reg = 0x8428, + .mem_enable_mask = BIT(1), .mem_enable_ack_mask = BIT(1), .branch = { .halt_reg = 0x80e0, @@ -1053,6 +1058,7 @@ static struct clk_branch ecpri_cc_eth_100g_dbg_c2c_udp_fifo_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_0_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(0), .mem_enable_ack_mask = BIT(0), .branch = { .halt_reg = 0x800c, @@ -1076,6 +1082,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_1_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(1), .mem_enable_ack_mask = BIT(1), .branch = { .halt_reg = 0x8014, @@ -1099,6 +1106,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_1_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_2_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(2), .mem_enable_ack_mask = BIT(2), .branch = { .halt_reg = 0x801c, @@ -1122,6 +1130,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_2_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_3_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(3), .mem_enable_ack_mask = BIT(3), .branch = { .halt_reg = 0x8024, @@ -1163,6 +1172,7 @@ static struct clk_branch ecpri_cc_eth_100g_fh_0_udp_fifo_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_0_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(0), .mem_enable_ack_mask = BIT(0), .branch = { .halt_reg = 0x8044, @@ -1186,6 +1196,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_1_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(1), .mem_enable_ack_mask = BIT(1), .branch = { .halt_reg = 0x804c, @@ -1209,6 +1220,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_1_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_2_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(2), .mem_enable_ack_mask = BIT(2), .branch = { .halt_reg = 0x8054, @@ -1232,6 +1244,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_2_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_3_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(3), .mem_enable_ack_mask = BIT(3), .branch = { .halt_reg = 0x805c, @@ -1273,6 +1286,7 @@ static struct clk_branch ecpri_cc_eth_100g_fh_1_udp_fifo_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_0_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(0), .mem_enable_ack_mask = BIT(0), .branch = { .halt_reg = 0x807c, @@ -1296,6 +1310,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_1_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(1), .mem_enable_ack_mask = BIT(1), .branch = { .halt_reg = 0x8084, @@ -1319,6 +1334,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_1_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_2_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(2), .mem_enable_ack_mask = BIT(2), .branch = { .halt_reg = 0x808c, @@ -1342,6 +1358,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_2_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_3_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(3), .mem_enable_ack_mask = BIT(3), .branch = { .halt_reg = 0x8094, @@ -1383,6 +1400,7 @@ static struct clk_branch ecpri_cc_eth_100g_fh_2_udp_fifo_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_0_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(4), .mem_enable_ack_mask = BIT(4), .branch = { .halt_reg = 0x8004, @@ -1406,6 +1424,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_1_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(4), .mem_enable_ack_mask = BIT(4), .branch = { .halt_reg = 0x803c, @@ -1429,6 +1448,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_1_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_2_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(4), .mem_enable_ack_mask = BIT(4), .branch = { .halt_reg = 0x8074, @@ -1452,6 +1472,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_2_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_mac_c2c_hm_ref_clk = { .mem_enable_reg = 0x8410, .mem_ack_reg = 0x8424, + .mem_enable_mask = BIT(5), .mem_enable_ack_mask = BIT(5), .branch = { .halt_reg = 0x80c4, @@ -1475,6 +1496,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_c2c_hm_ref_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_mac_dbg_c2c_hm_ref_clk = { .mem_enable_reg = 0x8414, .mem_ack_reg = 0x8428, + .mem_enable_mask = BIT(5), .mem_enable_ack_mask = BIT(5), .branch = { .halt_reg = 0x80e8, @@ -1498,6 +1520,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_dbg_c2c_hm_ref_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh0_hm_ref_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(5), .mem_enable_ack_mask = BIT(5), .branch = { .halt_reg = 0x802c, @@ -1521,6 +1544,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh0_hm_ref_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh1_hm_ref_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(5), .mem_enable_ack_mask = BIT(5), .branch = { .halt_reg = 0x8064, @@ -1544,6 +1568,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh1_hm_ref_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh2_hm_ref_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(5), .mem_enable_ack_mask = BIT(5), .branch = { .halt_reg = 0x809c, @@ -1603,6 +1628,7 @@ static struct clk_branch ecpri_cc_eth_dbg_noc_axi_clk = { static struct clk_mem_branch ecpri_cc_eth_phy_0_ock_sram_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(6), .mem_enable_ack_mask = BIT(6), .branch = { .halt_reg = 0xd140, @@ -1621,6 +1647,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_0_ock_sram_clk = { static struct clk_mem_branch ecpri_cc_eth_phy_1_ock_sram_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841C, + .mem_enable_mask = BIT(6), .mem_enable_ack_mask = BIT(6), .branch = { .halt_reg = 0xd148, @@ -1639,6 +1666,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_1_ock_sram_clk = { static struct clk_mem_branch ecpri_cc_eth_phy_2_ock_sram_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(6), .mem_enable_ack_mask = BIT(6), .branch = { .halt_reg = 0xd150, @@ -1657,6 +1685,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_2_ock_sram_clk = { static struct clk_mem_branch ecpri_cc_eth_phy_3_ock_sram_clk = { .mem_enable_reg = 0x8410, .mem_ack_reg = 0x8424, + .mem_enable_mask = BIT(6), .mem_enable_ack_mask = BIT(6), .branch = { .halt_reg = 0xd158, @@ -1675,6 +1704,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_3_ock_sram_clk = { static struct clk_mem_branch ecpri_cc_eth_phy_4_ock_sram_clk = { .mem_enable_reg = 0x8414, .mem_ack_reg = 0x8428, + .mem_enable_mask = BIT(6), .mem_enable_ack_mask = BIT(6), .branch = { .halt_reg = 0xd160, diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c index 62059120f9720..deab819576d0e 100644 --- a/drivers/clk/qcom/gcc-glymur.c +++ b/drivers/clk/qcom/gcc-glymur.c @@ -2643,7 +2643,6 @@ static struct clk_rcg2 gcc_usb3_tert_phy_aux_clk_src = { }; static const struct freq_tbl ftbl_gcc_usb4_0_master_clk_src[] = { - F(85714286, P_GCC_GPLL0_OUT_EVEN, 3.5, 0, 0), F(177666750, P_GCC_GPLL8_OUT_MAIN, 4, 0, 0), F(355333500, P_GCC_GPLL8_OUT_MAIN, 2, 0, 0), { } @@ -6760,7 +6759,7 @@ static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { .halt_reg = 0x3f088, - .halt_check = BRANCH_HALT_DELAY, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x3f088, .hwcg_bit = 1, .clkr = { @@ -6816,7 +6815,7 @@ static struct clk_branch gcc_usb3_sec_phy_com_aux_clk = { static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { .halt_reg = 0xe2078, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0xe2078, .hwcg_bit = 1, .clkr = { @@ -6872,7 +6871,7 @@ static struct clk_branch gcc_usb3_tert_phy_com_aux_clk = { static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { .halt_reg = 0xe1078, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0xe1078, .hwcg_bit = 1, .clkr = { @@ -6961,7 +6960,7 @@ static struct clk_branch gcc_usb4_0_master_clk = { static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { .halt_reg = 0x2b0f4, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b0f4, .enable_mask = BIT(0), @@ -6979,7 +6978,7 @@ static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { .halt_reg = 0x2b04c, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x62010, .enable_mask = BIT(11), @@ -7033,7 +7032,7 @@ static struct clk_branch gcc_usb4_0_phy_rx1_clk = { static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = { .halt_reg = 0x2b0bc, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x2b0bc, .hwcg_bit = 1, .clkr = { @@ -7196,7 +7195,7 @@ static struct clk_branch gcc_usb4_1_master_clk = { static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { .halt_reg = 0x2d118, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2d118, .enable_mask = BIT(0), @@ -7214,7 +7213,7 @@ static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { .halt_reg = 0x2d04c, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x62010, .enable_mask = BIT(12), @@ -7268,7 +7267,7 @@ static struct clk_branch gcc_usb4_1_phy_rx1_clk = { static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = { .halt_reg = 0x2d0e0, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x2d0e0, .hwcg_bit = 1, .clkr = { @@ -7431,7 +7430,7 @@ static struct clk_branch gcc_usb4_2_master_clk = { static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { .halt_reg = 0xe00f8, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0xe00f8, .enable_mask = BIT(0), @@ -7449,7 +7448,7 @@ static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { .halt_reg = 0xe004c, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x62010, .enable_mask = BIT(13), @@ -7503,7 +7502,7 @@ static struct clk_branch gcc_usb4_2_phy_rx1_clk = { static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = { .halt_reg = 0xe00c0, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0xe00c0, .hwcg_bit = 1, .clkr = { diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index 3d42f3d85c7a9..35af6ffeeb855 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -79,6 +79,20 @@ static struct clk_fixed_factor gpll0_div2 = { }, }; +static struct clk_alpha_pll_postdiv gpll0_out_aux = { + .offset = 0x20000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll0_out_aux", + .parent_hws = (const struct clk_hw *[]) { + &gpll0.clkr.hw + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + static struct clk_alpha_pll gpll2 = { .offset = 0x21000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_NSS_HUAYRA], @@ -2934,6 +2948,7 @@ static struct clk_regmap *gcc_ipq5424_clocks[] = { [GPLL2] = &gpll2.clkr, [GPLL2_OUT_MAIN] = &gpll2_out_main.clkr, [GPLL4] = &gpll4.clkr, + [GPLL0_OUT_AUX] = &gpll0_out_aux.clkr, }; static const struct qcom_reset_map gcc_ipq5424_resets[] = { @@ -3250,6 +3265,16 @@ static const struct qcom_icc_hws_data icc_ipq5424_hws[] = { { MASTER_ANOC_PCIE3, SLAVE_ANOC_PCIE3, GCC_ANOC_PCIE3_2LANE_M_CLK }, { MASTER_CNOC_PCIE3, SLAVE_CNOC_PCIE3, GCC_CNOC_PCIE3_2LANE_S_CLK }, { MASTER_CNOC_USB, SLAVE_CNOC_USB, GCC_CNOC_USB_CLK }, + { MASTER_NSSNOC_NSSCC, SLAVE_NSSNOC_NSSCC, GCC_NSSNOC_NSSCC_CLK }, + { MASTER_NSSNOC_SNOC_0, SLAVE_NSSNOC_SNOC_0, GCC_NSSNOC_SNOC_CLK }, + { MASTER_NSSNOC_SNOC_1, SLAVE_NSSNOC_SNOC_1, GCC_NSSNOC_SNOC_1_CLK }, + { MASTER_NSSNOC_PCNOC_1, SLAVE_NSSNOC_PCNOC_1, GCC_NSSNOC_PCNOC_1_CLK }, + { MASTER_NSSNOC_QOSGEN_REF, SLAVE_NSSNOC_QOSGEN_REF, GCC_NSSNOC_QOSGEN_REF_CLK }, + { MASTER_NSSNOC_TIMEOUT_REF, SLAVE_NSSNOC_TIMEOUT_REF, GCC_NSSNOC_TIMEOUT_REF_CLK }, + { MASTER_NSSNOC_XO_DCD, SLAVE_NSSNOC_XO_DCD, GCC_NSSNOC_XO_DCD_CLK }, + { MASTER_NSSNOC_ATB, SLAVE_NSSNOC_ATB, GCC_NSSNOC_ATB_CLK }, + { MASTER_CNOC_LPASS_CFG, SLAVE_CNOC_LPASS_CFG, GCC_CNOC_LPASS_CFG_CLK }, + { MASTER_SNOC_LPASS, SLAVE_SNOC_LPASS, GCC_SNOC_LPASS_CLK }, }; static const struct of_device_id gcc_ipq5424_match_table[] = { @@ -3284,6 +3309,7 @@ static const struct qcom_cc_desc gcc_ipq5424_desc = { .num_clk_hws = ARRAY_SIZE(gcc_ipq5424_hws), .icc_hws = icc_ipq5424_hws, .num_icc_hws = ARRAY_SIZE(icc_ipq5424_hws), + .icc_first_node_id = IPQ_APPS_ID, }; static int gcc_ipq5424_probe(struct platform_device *pdev) diff --git a/drivers/clk/qcom/gcc-qcs615.c b/drivers/clk/qcom/gcc-qcs615.c index 9695446bc2a3c..5b3b8dd4f114b 100644 --- a/drivers/clk/qcom/gcc-qcs615.c +++ b/drivers/clk/qcom/gcc-qcs615.c @@ -784,7 +784,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .name = "gcc_sdcc1_apps_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -806,7 +806,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { .name = "gcc_sdcc1_ice_core_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -830,7 +830,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sc8280xp.c b/drivers/clk/qcom/gcc-sc8280xp.c index b683795475e34..2ab111585d7fc 100644 --- a/drivers/clk/qcom/gcc-sc8280xp.c +++ b/drivers/clk/qcom/gcc-sc8280xp.c @@ -2224,7 +2224,6 @@ static struct clk_rcg2 gcc_usb3_sec_phy_aux_clk_src = { }; static const struct freq_tbl ftbl_gcc_usb4_1_master_clk_src[] = { - F(85714286, P_GCC_GPLL0_OUT_EVEN, 3.5, 0, 0), F(175000000, P_GCC_GPLL8_OUT_MAIN, 4, 0, 0), F(350000000, P_GCC_GPLL8_OUT_MAIN, 2, 0, 0), { } diff --git a/drivers/clk/qcom/gcc-sm8750.c b/drivers/clk/qcom/gcc-sm8750.c index 8092dd6b37b56..def86b71a3da5 100644 --- a/drivers/clk/qcom/gcc-sm8750.c +++ b/drivers/clk/qcom/gcc-sm8750.c @@ -1012,6 +1012,7 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = { static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { F(400000, P_BI_TCXO, 12, 1, 4), F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0), F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0), diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index 301fc9fc32d8e..b63c8abdd2fc2 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -32,6 +32,33 @@ enum { DT_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE, DT_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE, DT_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE, + DT_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, + DT_QUSB4PHY_0_GCC_USB4_RX0_CLK, + DT_QUSB4PHY_0_GCC_USB4_RX1_CLK, + DT_QUSB4PHY_1_GCC_USB4_RX0_CLK, + DT_QUSB4PHY_1_GCC_USB4_RX1_CLK, + DT_QUSB4PHY_2_GCC_USB4_RX0_CLK, + DT_QUSB4PHY_2_GCC_USB4_RX1_CLK, + DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, + DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, + DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, + DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, }; enum { @@ -42,10 +69,40 @@ enum { P_GCC_GPLL7_OUT_MAIN, P_GCC_GPLL8_OUT_MAIN, P_GCC_GPLL9_OUT_MAIN, + P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, + P_GCC_USB3_SEC_PHY_PIPE_CLK_SRC, + P_GCC_USB3_TERT_PHY_PIPE_CLK_SRC, + P_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, + P_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, + P_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, + P_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, + P_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, + P_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC, + P_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC, + P_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, + P_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, + P_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, + P_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, + P_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, + P_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, + P_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, + P_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, + P_QUSB4PHY_0_GCC_USB4_RX0_CLK, + P_QUSB4PHY_0_GCC_USB4_RX1_CLK, + P_QUSB4PHY_1_GCC_USB4_RX0_CLK, + P_QUSB4PHY_1_GCC_USB4_RX1_CLK, + P_QUSB4PHY_2_GCC_USB4_RX0_CLK, + P_QUSB4PHY_2_GCC_USB4_RX1_CLK, P_SLEEP_CLK, P_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE_CLK, P_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE_CLK, P_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE_CLK, + P_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, + P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + P_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, + P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, + P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, }; static struct clk_alpha_pll gcc_gpll0 = { @@ -320,6 +377,342 @@ static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { { } }; +static const struct clk_parent_data gcc_parent_data_13[] = { + { .index = DT_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_14[] = { + { .index = DT_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_15[] = { + { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_16[] = { + { .index = DT_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_17[] = { + { .index = DT_QUSB4PHY_0_GCC_USB4_RX0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_18[] = { + { .index = DT_QUSB4PHY_0_GCC_USB4_RX1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_19[] = { + { .index = DT_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_20[] = { + { .index = DT_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_21[] = { + { .index = DT_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_22[] = { + { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_23[] = { + { .index = DT_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_24[] = { + { .index = DT_QUSB4PHY_1_GCC_USB4_RX0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_25[] = { + { .index = DT_QUSB4PHY_1_GCC_USB4_RX1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_26[] = { + { .index = DT_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_27[] = { + { .index = DT_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_28[] = { + { .index = DT_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_29[] = { + { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_30[] = { + { .index = DT_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_31[] = { + { .index = DT_QUSB4PHY_2_GCC_USB4_RX0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_32[] = { + { .index = DT_QUSB4PHY_2_GCC_USB4_RX1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_33[] = { + { .index = DT_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp0_clk_src = { + .reg = 0x9f06c, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_dp0_clk_src", + .parent_data = gcc_parent_data_13, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp1_clk_src = { + .reg = 0x9f114, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_dp1_clk_src", + .parent_data = gcc_parent_data_14, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_p2rr2p_pipe_clk_src = { + .reg = 0x9f0d4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_p2rr2p_pipe_clk_src", + .parent_data = gcc_parent_data_15, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_pcie_pipe_mux_clk_src = { + .reg = 0x9f104, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_pcie_pipe_mux_clk_src", + .parent_data = gcc_parent_data_16, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_rx0_clk_src = { + .reg = 0x9f0ac, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx0_clk_src", + .parent_data = gcc_parent_data_17, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_rx1_clk_src = { + .reg = 0x9f0bc, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx1_clk_src", + .parent_data = gcc_parent_data_18, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_sys_clk_src = { + .reg = 0x9f0e4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_sys_clk_src", + .parent_data = gcc_parent_data_19, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_dp0_clk_src = { + .reg = 0x2b06c, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_dp0_clk_src", + .parent_data = gcc_parent_data_20, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_dp1_clk_src = { + .reg = 0x2b114, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_dp1_clk_src", + .parent_data = gcc_parent_data_21, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_p2rr2p_pipe_clk_src = { + .reg = 0x2b0d4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_p2rr2p_pipe_clk_src", + .parent_data = gcc_parent_data_22, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_pcie_pipe_mux_clk_src = { + .reg = 0x2b104, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_pcie_pipe_mux_clk_src", + .parent_data = gcc_parent_data_23, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_rx0_clk_src = { + .reg = 0x2b0ac, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx0_clk_src", + .parent_data = gcc_parent_data_24, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_rx1_clk_src = { + .reg = 0x2b0bc, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx1_clk_src", + .parent_data = gcc_parent_data_25, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_sys_clk_src = { + .reg = 0x2b0e4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_sys_clk_src", + .parent_data = gcc_parent_data_26, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_dp0_clk_src = { + .reg = 0x1106c, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_dp0_clk_src", + .parent_data = gcc_parent_data_27, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_dp1_clk_src = { + .reg = 0x11114, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_dp1_clk_src", + .parent_data = gcc_parent_data_28, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_p2rr2p_pipe_clk_src = { + .reg = 0x110d4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_p2rr2p_pipe_clk_src", + .parent_data = gcc_parent_data_29, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_pcie_pipe_mux_clk_src = { + .reg = 0x11104, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_pcie_pipe_mux_clk_src", + .parent_data = gcc_parent_data_30, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_rx0_clk_src = { + .reg = 0x110ac, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx0_clk_src", + .parent_data = gcc_parent_data_31, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_rx1_clk_src = { + .reg = 0x110bc, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx1_clk_src", + .parent_data = gcc_parent_data_32, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_sys_clk_src = { + .reg = 0x110e4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_sys_clk_src", + .parent_data = gcc_parent_data_33, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + static struct clk_rcg2 gcc_gp1_clk_src = { .cmd_rcgr = 0x64004, .mnd_width = 16, @@ -1456,7 +1849,6 @@ static struct clk_rcg2 gcc_usb3_tert_phy_aux_clk_src = { }; static const struct freq_tbl ftbl_gcc_usb4_0_master_clk_src[] = { - F(85714286, P_GCC_GPLL0_OUT_EVEN, 3.5, 0, 0), F(175000000, P_GCC_GPLL8_OUT_MAIN, 4, 0, 0), F(350000000, P_GCC_GPLL8_OUT_MAIN, 2, 0, 0), { } @@ -2790,6 +3182,11 @@ static struct clk_branch gcc_pcie_0_pipe_clk = { .enable_mask = BIT(25), .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_0_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -2879,6 +3276,11 @@ static struct clk_branch gcc_pcie_1_pipe_clk = { .enable_mask = BIT(30), .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_1_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -2968,6 +3370,11 @@ static struct clk_branch gcc_pcie_2_pipe_clk = { .enable_mask = BIT(23), .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_2_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5156,6 +5563,33 @@ static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { }, }; +static const struct parent_map gcc_parent_map_34[] = { + { P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, 0 }, + { P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, + { P_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_34[] = { + { .hw = &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw }, + { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, + { .index = DT_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC }, +}; + +static struct clk_regmap_mux gcc_usb34_prim_phy_pipe_clk_src = { + .reg = 0x39070, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_34, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb34_prim_phy_pipe_clk_src", + .parent_data = gcc_parent_data_34, + .num_parents = ARRAY_SIZE(gcc_parent_data_34), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { .halt_reg = 0x39068, .halt_check = BRANCH_HALT_SKIP, @@ -5167,7 +5601,7 @@ static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { .hw.init = &(const struct clk_init_data) { .name = "gcc_usb3_prim_phy_pipe_clk", .parent_hws = (const struct clk_hw*[]) { - &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw, + &gcc_usb34_prim_phy_pipe_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -5227,6 +5661,33 @@ static struct clk_regmap_mux gcc_usb3_sec_phy_pipe_clk_src = { }, }; +static const struct parent_map gcc_parent_map_35[] = { + { P_GCC_USB3_SEC_PHY_PIPE_CLK_SRC, 0 }, + { P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, + { P_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_35[] = { + { .hw = &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw }, + { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, + { .index = DT_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC }, +}; + +static struct clk_regmap_mux gcc_usb34_sec_phy_pipe_clk_src = { + .reg = 0xa1070, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_35, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb34_sec_phy_pipe_clk_src", + .parent_data = gcc_parent_data_35, + .num_parents = ARRAY_SIZE(gcc_parent_data_35), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { .halt_reg = 0xa1068, .halt_check = BRANCH_HALT_SKIP, @@ -5238,7 +5699,7 @@ static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { .hw.init = &(const struct clk_init_data) { .name = "gcc_usb3_sec_phy_pipe_clk", .parent_hws = (const struct clk_hw*[]) { - &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw, + &gcc_usb34_sec_phy_pipe_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -5298,6 +5759,33 @@ static struct clk_regmap_mux gcc_usb3_tert_phy_pipe_clk_src = { }, }; +static const struct parent_map gcc_parent_map_36[] = { + { P_GCC_USB3_TERT_PHY_PIPE_CLK_SRC, 0 }, + { P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, + { P_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_36[] = { + { .hw = &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw }, + { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, + { .index = DT_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC }, +}; + +static struct clk_regmap_mux gcc_usb34_tert_phy_pipe_clk_src = { + .reg = 0xa2070, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_36, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb34_tert_phy_pipe_clk_src", + .parent_data = gcc_parent_data_36, + .num_parents = ARRAY_SIZE(gcc_parent_data_36), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { .halt_reg = 0xa2068, .halt_check = BRANCH_HALT_SKIP, @@ -5309,7 +5797,7 @@ static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { .hw.init = &(const struct clk_init_data) { .name = "gcc_usb3_tert_phy_pipe_clk", .parent_hws = (const struct clk_hw*[]) { - &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw, + &gcc_usb34_tert_phy_pipe_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -5335,12 +5823,17 @@ static struct clk_branch gcc_usb4_0_cfg_ahb_clk = { static struct clk_branch gcc_usb4_0_dp0_clk = { .halt_reg = 0x9f060, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f060, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_dp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_dp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5348,12 +5841,17 @@ static struct clk_branch gcc_usb4_0_dp0_clk = { static struct clk_branch gcc_usb4_0_dp1_clk = { .halt_reg = 0x9f108, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f108, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_dp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_dp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5385,6 +5883,11 @@ static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_phy_p2rr2p_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_p2rr2p_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5398,6 +5901,11 @@ static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { .enable_mask = BIT(19), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_phy_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5405,12 +5913,17 @@ static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { static struct clk_branch gcc_usb4_0_phy_rx0_clk = { .halt_reg = 0x9f0b0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f0b0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_phy_rx0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_rx0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5418,12 +5931,17 @@ static struct clk_branch gcc_usb4_0_phy_rx0_clk = { static struct clk_branch gcc_usb4_0_phy_rx1_clk = { .halt_reg = 0x9f0c0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f0c0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_phy_rx1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_rx1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5439,6 +5957,11 @@ static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_phy_usb_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5470,6 +5993,11 @@ static struct clk_branch gcc_usb4_0_sys_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_sys_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5512,12 +6040,17 @@ static struct clk_branch gcc_usb4_1_cfg_ahb_clk = { static struct clk_branch gcc_usb4_1_dp0_clk = { .halt_reg = 0x2b060, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b060, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_dp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_dp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5525,12 +6058,17 @@ static struct clk_branch gcc_usb4_1_dp0_clk = { static struct clk_branch gcc_usb4_1_dp1_clk = { .halt_reg = 0x2b108, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b108, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_dp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_dp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5562,6 +6100,11 @@ static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_phy_p2rr2p_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_p2rr2p_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5575,6 +6118,11 @@ static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_phy_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5582,12 +6130,17 @@ static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { static struct clk_branch gcc_usb4_1_phy_rx0_clk = { .halt_reg = 0x2b0b0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b0b0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_phy_rx0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_rx0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5595,12 +6148,17 @@ static struct clk_branch gcc_usb4_1_phy_rx0_clk = { static struct clk_branch gcc_usb4_1_phy_rx1_clk = { .halt_reg = 0x2b0c0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b0c0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_phy_rx1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_rx1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5616,6 +6174,11 @@ static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_phy_usb_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_sec_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5647,6 +6210,11 @@ static struct clk_branch gcc_usb4_1_sys_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_sys_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5689,12 +6257,17 @@ static struct clk_branch gcc_usb4_2_cfg_ahb_clk = { static struct clk_branch gcc_usb4_2_dp0_clk = { .halt_reg = 0x11060, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x11060, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_dp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_dp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5702,12 +6275,17 @@ static struct clk_branch gcc_usb4_2_dp0_clk = { static struct clk_branch gcc_usb4_2_dp1_clk = { .halt_reg = 0x11108, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x11108, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_dp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_dp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5739,6 +6317,11 @@ static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_phy_p2rr2p_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_p2rr2p_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5752,6 +6335,11 @@ static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { .enable_mask = BIT(1), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_phy_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5759,12 +6347,17 @@ static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { static struct clk_branch gcc_usb4_2_phy_rx0_clk = { .halt_reg = 0x110b0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x110b0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_phy_rx0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_rx0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5772,12 +6365,17 @@ static struct clk_branch gcc_usb4_2_phy_rx0_clk = { static struct clk_branch gcc_usb4_2_phy_rx1_clk = { .halt_reg = 0x110c0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x110c0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_phy_rx1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_rx1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5793,6 +6391,11 @@ static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_phy_usb_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_tert_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -6483,6 +7086,9 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB30_TERT_MOCK_UTMI_CLK_SRC] = &gcc_usb30_tert_mock_utmi_clk_src.clkr, [GCC_USB30_TERT_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_tert_mock_utmi_postdiv_clk_src.clkr, [GCC_USB30_TERT_SLEEP_CLK] = &gcc_usb30_tert_sleep_clk.clkr, + [GCC_USB34_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb34_prim_phy_pipe_clk_src.clkr, + [GCC_USB34_SEC_PHY_PIPE_CLK_SRC] = &gcc_usb34_sec_phy_pipe_clk_src.clkr, + [GCC_USB34_TERT_PHY_PIPE_CLK_SRC] = &gcc_usb34_tert_phy_pipe_clk_src.clkr, [GCC_USB3_MP_PHY_AUX_CLK] = &gcc_usb3_mp_phy_aux_clk.clkr, [GCC_USB3_MP_PHY_AUX_CLK_SRC] = &gcc_usb3_mp_phy_aux_clk_src.clkr, [GCC_USB3_MP_PHY_COM_AUX_CLK] = &gcc_usb3_mp_phy_com_aux_clk.clkr, @@ -6508,11 +7114,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB4_0_DP1_CLK] = &gcc_usb4_0_dp1_clk.clkr, [GCC_USB4_0_MASTER_CLK] = &gcc_usb4_0_master_clk.clkr, [GCC_USB4_0_MASTER_CLK_SRC] = &gcc_usb4_0_master_clk_src.clkr, + [GCC_USB4_0_PHY_DP0_CLK_SRC] = &gcc_usb4_0_phy_dp0_clk_src.clkr, + [GCC_USB4_0_PHY_DP1_CLK_SRC] = &gcc_usb4_0_phy_dp1_clk_src.clkr, [GCC_USB4_0_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_0_phy_p2rr2p_pipe_clk.clkr, + [GCC_USB4_0_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_0_phy_p2rr2p_pipe_clk_src.clkr, [GCC_USB4_0_PHY_PCIE_PIPE_CLK] = &gcc_usb4_0_phy_pcie_pipe_clk.clkr, [GCC_USB4_0_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_0_phy_pcie_pipe_clk_src.clkr, + [GCC_USB4_0_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr, [GCC_USB4_0_PHY_RX0_CLK] = &gcc_usb4_0_phy_rx0_clk.clkr, + [GCC_USB4_0_PHY_RX0_CLK_SRC] = &gcc_usb4_0_phy_rx0_clk_src.clkr, [GCC_USB4_0_PHY_RX1_CLK] = &gcc_usb4_0_phy_rx1_clk.clkr, + [GCC_USB4_0_PHY_RX1_CLK_SRC] = &gcc_usb4_0_phy_rx1_clk_src.clkr, + [GCC_USB4_0_PHY_SYS_CLK_SRC] = &gcc_usb4_0_phy_sys_clk_src.clkr, [GCC_USB4_0_PHY_USB_PIPE_CLK] = &gcc_usb4_0_phy_usb_pipe_clk.clkr, [GCC_USB4_0_SB_IF_CLK] = &gcc_usb4_0_sb_if_clk.clkr, [GCC_USB4_0_SB_IF_CLK_SRC] = &gcc_usb4_0_sb_if_clk_src.clkr, @@ -6524,11 +7137,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB4_1_DP1_CLK] = &gcc_usb4_1_dp1_clk.clkr, [GCC_USB4_1_MASTER_CLK] = &gcc_usb4_1_master_clk.clkr, [GCC_USB4_1_MASTER_CLK_SRC] = &gcc_usb4_1_master_clk_src.clkr, + [GCC_USB4_1_PHY_DP0_CLK_SRC] = &gcc_usb4_1_phy_dp0_clk_src.clkr, + [GCC_USB4_1_PHY_DP1_CLK_SRC] = &gcc_usb4_1_phy_dp1_clk_src.clkr, [GCC_USB4_1_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_1_phy_p2rr2p_pipe_clk.clkr, + [GCC_USB4_1_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_1_phy_p2rr2p_pipe_clk_src.clkr, [GCC_USB4_1_PHY_PCIE_PIPE_CLK] = &gcc_usb4_1_phy_pcie_pipe_clk.clkr, [GCC_USB4_1_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_1_phy_pcie_pipe_clk_src.clkr, + [GCC_USB4_1_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr, [GCC_USB4_1_PHY_RX0_CLK] = &gcc_usb4_1_phy_rx0_clk.clkr, + [GCC_USB4_1_PHY_RX0_CLK_SRC] = &gcc_usb4_1_phy_rx0_clk_src.clkr, [GCC_USB4_1_PHY_RX1_CLK] = &gcc_usb4_1_phy_rx1_clk.clkr, + [GCC_USB4_1_PHY_RX1_CLK_SRC] = &gcc_usb4_1_phy_rx1_clk_src.clkr, + [GCC_USB4_1_PHY_SYS_CLK_SRC] = &gcc_usb4_1_phy_sys_clk_src.clkr, [GCC_USB4_1_PHY_USB_PIPE_CLK] = &gcc_usb4_1_phy_usb_pipe_clk.clkr, [GCC_USB4_1_SB_IF_CLK] = &gcc_usb4_1_sb_if_clk.clkr, [GCC_USB4_1_SB_IF_CLK_SRC] = &gcc_usb4_1_sb_if_clk_src.clkr, @@ -6540,11 +7160,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB4_2_DP1_CLK] = &gcc_usb4_2_dp1_clk.clkr, [GCC_USB4_2_MASTER_CLK] = &gcc_usb4_2_master_clk.clkr, [GCC_USB4_2_MASTER_CLK_SRC] = &gcc_usb4_2_master_clk_src.clkr, + [GCC_USB4_2_PHY_DP0_CLK_SRC] = &gcc_usb4_2_phy_dp0_clk_src.clkr, + [GCC_USB4_2_PHY_DP1_CLK_SRC] = &gcc_usb4_2_phy_dp1_clk_src.clkr, [GCC_USB4_2_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_2_phy_p2rr2p_pipe_clk.clkr, + [GCC_USB4_2_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_2_phy_p2rr2p_pipe_clk_src.clkr, [GCC_USB4_2_PHY_PCIE_PIPE_CLK] = &gcc_usb4_2_phy_pcie_pipe_clk.clkr, [GCC_USB4_2_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_2_phy_pcie_pipe_clk_src.clkr, + [GCC_USB4_2_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr, [GCC_USB4_2_PHY_RX0_CLK] = &gcc_usb4_2_phy_rx0_clk.clkr, + [GCC_USB4_2_PHY_RX0_CLK_SRC] = &gcc_usb4_2_phy_rx0_clk_src.clkr, [GCC_USB4_2_PHY_RX1_CLK] = &gcc_usb4_2_phy_rx1_clk.clkr, + [GCC_USB4_2_PHY_RX1_CLK_SRC] = &gcc_usb4_2_phy_rx1_clk_src.clkr, + [GCC_USB4_2_PHY_SYS_CLK_SRC] = &gcc_usb4_2_phy_sys_clk_src.clkr, [GCC_USB4_2_PHY_USB_PIPE_CLK] = &gcc_usb4_2_phy_usb_pipe_clk.clkr, [GCC_USB4_2_SB_IF_CLK] = &gcc_usb4_2_sb_if_clk.clkr, [GCC_USB4_2_SB_IF_CLK_SRC] = &gcc_usb4_2_sb_if_clk_src.clkr, @@ -6660,16 +7287,52 @@ static const struct qcom_reset_map gcc_x1e80100_resets[] = { [GCC_USB3_UNIPHY_MP0_BCR] = { 0x19000 }, [GCC_USB3_UNIPHY_MP1_BCR] = { 0x54000 }, [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, + [GCC_USB4PHY_PHY_PRIM_BCR] = { 0x5000c }, [GCC_USB3PHY_PHY_SEC_BCR] = { 0x2a004 }, + [GCC_USB4PHY_PHY_SEC_BCR] = { 0x2a00c }, [GCC_USB3PHY_PHY_TERT_BCR] = { 0xa3004 }, + [GCC_USB4PHY_PHY_TERT_BCR] = { 0xa300c }, [GCC_USB3UNIPHY_PHY_MP0_BCR] = { 0x19004 }, [GCC_USB3UNIPHY_PHY_MP1_BCR] = { 0x54004 }, [GCC_USB4_0_BCR] = { 0x9f000 }, [GCC_USB4_0_DP0_PHY_PRIM_BCR] = { 0x50010 }, - [GCC_USB4_1_DP0_PHY_SEC_BCR] = { 0x2a010 }, - [GCC_USB4_2_DP0_PHY_TERT_BCR] = { 0xa3010 }, + [GCC_USB4_0_MISC_USB4_SYS_BCR] = { .reg = 0xad0f8, .bit = 0 }, + [GCC_USB4_0_MISC_RX_CLK_0_BCR] = { .reg = 0xad0f8, .bit = 1 }, + [GCC_USB4_0_MISC_RX_CLK_1_BCR] = { .reg = 0xad0f8, .bit = 2 }, + [GCC_USB4_0_MISC_USB_PIPE_BCR] = { .reg = 0xad0f8, .bit = 3 }, + [GCC_USB4_0_MISC_PCIE_PIPE_BCR] = { .reg = 0xad0f8, .bit = 4 }, + [GCC_USB4_0_MISC_TMU_BCR] = { .reg = 0xad0f8, .bit = 5 }, + [GCC_USB4_0_MISC_SB_IF_BCR] = { .reg = 0xad0f8, .bit = 6 }, + [GCC_USB4_0_MISC_HIA_MSTR_BCR] = { .reg = 0xad0f8, .bit = 7 }, + [GCC_USB4_0_MISC_AHB_BCR] = { .reg = 0xad0f8, .bit = 8 }, + [GCC_USB4_0_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xad0f8, .bit = 9 }, + [GCC_USB4_0_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xad0f8, .bit = 10 }, [GCC_USB4_1_BCR] = { 0x2b000 }, + [GCC_USB4_1_DP0_PHY_SEC_BCR] = { 0x2a010 }, + [GCC_USB4_1_MISC_USB4_SYS_BCR] = { .reg = 0xae0f8, .bit = 0 }, + [GCC_USB4_1_MISC_RX_CLK_0_BCR] = { .reg = 0xae0f8, .bit = 1 }, + [GCC_USB4_1_MISC_RX_CLK_1_BCR] = { .reg = 0xae0f8, .bit = 2 }, + [GCC_USB4_1_MISC_USB_PIPE_BCR] = { .reg = 0xae0f8, .bit = 3 }, + [GCC_USB4_1_MISC_PCIE_PIPE_BCR] = { .reg = 0xae0f8, .bit = 4 }, + [GCC_USB4_1_MISC_TMU_BCR] = { .reg = 0xae0f8, .bit = 5 }, + [GCC_USB4_1_MISC_SB_IF_BCR] = { .reg = 0xae0f8, .bit = 6 }, + [GCC_USB4_1_MISC_HIA_MSTR_BCR] = { .reg = 0xae0f8, .bit = 7 }, + [GCC_USB4_1_MISC_AHB_BCR] = { .reg = 0xae0f8, .bit = 8 }, + [GCC_USB4_1_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xae0f8, .bit = 9 }, + [GCC_USB4_1_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xae0f8, .bit = 10 }, [GCC_USB4_2_BCR] = { 0x11000 }, + [GCC_USB4_2_DP0_PHY_TERT_BCR] = { 0xa3010 }, + [GCC_USB4_2_MISC_USB4_SYS_BCR] = { .reg = 0xaf0f8, .bit = 0 }, + [GCC_USB4_2_MISC_RX_CLK_0_BCR] = { .reg = 0xaf0f8, .bit = 1 }, + [GCC_USB4_2_MISC_RX_CLK_1_BCR] = { .reg = 0xaf0f8, .bit = 2 }, + [GCC_USB4_2_MISC_USB_PIPE_BCR] = { .reg = 0xaf0f8, .bit = 3 }, + [GCC_USB4_2_MISC_PCIE_PIPE_BCR] = { .reg = 0xaf0f8, .bit = 4 }, + [GCC_USB4_2_MISC_TMU_BCR] = { .reg = 0xaf0f8, .bit = 5 }, + [GCC_USB4_2_MISC_SB_IF_BCR] = { .reg = 0xaf0f8, .bit = 6 }, + [GCC_USB4_2_MISC_HIA_MSTR_BCR] = { .reg = 0xaf0f8, .bit = 7 }, + [GCC_USB4_2_MISC_AHB_BCR] = { .reg = 0xaf0f8, .bit = 8 }, + [GCC_USB4_2_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xaf0f8, .bit = 9 }, + [GCC_USB4_2_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xaf0f8, .bit = 10 }, [GCC_USB_0_PHY_BCR] = { 0x50020 }, [GCC_USB_1_PHY_BCR] = { 0x2a020 }, [GCC_USB_2_PHY_BCR] = { 0xa3020 }, diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index b723c536dfb6c..dbd3f561dc6d0 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -2781,6 +2781,7 @@ static struct gdsc *mmcc_sdm660_gdscs[] = { }; static const struct qcom_reset_map mmcc_660_resets[] = { + [MDSS_BCR] = { 0x2300 }, [CAMSS_MICRO_BCR] = { 0x3490 }, }; diff --git a/drivers/clk/qcom/nsscc-ipq5424.c b/drivers/clk/qcom/nsscc-ipq5424.c new file mode 100644 index 0000000000000..5893c71461800 --- /dev/null +++ b/drivers/clk/qcom/nsscc-ipq5424.c @@ -0,0 +1,1340 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "reset.h" + +/* Need to match the order of clocks in DT binding */ +enum { + DT_CMN_PLL_XO_CLK, + DT_CMN_PLL_NSS_300M_CLK, + DT_CMN_PLL_NSS_375M_CLK, + DT_GCC_GPLL0_OUT_AUX, + DT_UNIPHY0_NSS_RX_CLK, + DT_UNIPHY0_NSS_TX_CLK, + DT_UNIPHY1_NSS_RX_CLK, + DT_UNIPHY1_NSS_TX_CLK, + DT_UNIPHY2_NSS_RX_CLK, + DT_UNIPHY2_NSS_TX_CLK, +}; + +enum { + P_CMN_PLL_XO_CLK, + P_CMN_PLL_NSS_300M_CLK, + P_CMN_PLL_NSS_375M_CLK, + P_GCC_GPLL0_OUT_AUX, + P_UNIPHY0_NSS_RX_CLK, + P_UNIPHY0_NSS_TX_CLK, + P_UNIPHY1_NSS_RX_CLK, + P_UNIPHY1_NSS_TX_CLK, + P_UNIPHY2_NSS_RX_CLK, + P_UNIPHY2_NSS_TX_CLK, +}; + +static const struct parent_map nss_cc_parent_map_0[] = { + { P_CMN_PLL_XO_CLK, 0 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_CMN_PLL_NSS_300M_CLK, 5 }, + { P_CMN_PLL_NSS_375M_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_0[] = { + { .index = DT_CMN_PLL_XO_CLK }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_CMN_PLL_NSS_300M_CLK }, + { .index = DT_CMN_PLL_NSS_375M_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_1[] = { + { P_CMN_PLL_XO_CLK, 0 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_UNIPHY0_NSS_RX_CLK, 3 }, + { P_UNIPHY0_NSS_TX_CLK, 4 }, + { P_CMN_PLL_NSS_300M_CLK, 5 }, + { P_CMN_PLL_NSS_375M_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_1[] = { + { .index = DT_CMN_PLL_XO_CLK }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_UNIPHY0_NSS_RX_CLK }, + { .index = DT_UNIPHY0_NSS_TX_CLK }, + { .index = DT_CMN_PLL_NSS_300M_CLK }, + { .index = DT_CMN_PLL_NSS_375M_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_2[] = { + { P_CMN_PLL_XO_CLK, 0 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_UNIPHY1_NSS_RX_CLK, 3 }, + { P_UNIPHY1_NSS_TX_CLK, 4 }, + { P_CMN_PLL_NSS_300M_CLK, 5 }, + { P_CMN_PLL_NSS_375M_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_2[] = { + { .index = DT_CMN_PLL_XO_CLK }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_UNIPHY1_NSS_RX_CLK }, + { .index = DT_UNIPHY1_NSS_TX_CLK }, + { .index = DT_CMN_PLL_NSS_300M_CLK }, + { .index = DT_CMN_PLL_NSS_375M_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_3[] = { + { P_CMN_PLL_XO_CLK, 0 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_UNIPHY2_NSS_RX_CLK, 3 }, + { P_UNIPHY2_NSS_TX_CLK, 4 }, + { P_CMN_PLL_NSS_300M_CLK, 5 }, + { P_CMN_PLL_NSS_375M_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_3[] = { + { .index = DT_CMN_PLL_XO_CLK }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_UNIPHY2_NSS_RX_CLK }, + { .index = DT_UNIPHY2_NSS_TX_CLK }, + { .index = DT_CMN_PLL_NSS_300M_CLK }, + { .index = DT_CMN_PLL_NSS_375M_CLK }, +}; + +static const struct freq_tbl ftbl_nss_cc_ce_clk_src[] = { + F(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + F(375000000, P_CMN_PLL_NSS_375M_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_ce_clk_src = { + .cmd_rcgr = 0x5e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_0, + .freq_tbl = ftbl_nss_cc_ce_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ce_clk_src", + .parent_data = nss_cc_parent_data_0, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_cc_cfg_clk_src[] = { + F(100000000, P_GCC_GPLL0_OUT_AUX, 8, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_cfg_clk_src = { + .cmd_rcgr = 0x6a8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_0, + .freq_tbl = ftbl_nss_cc_cfg_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_cfg_clk_src", + .parent_data = nss_cc_parent_data_0, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_cc_eip_bfdcd_clk_src[] = { + F(300000000, P_CMN_PLL_NSS_300M_CLK, 1, 0, 0), + F(375000000, P_CMN_PLL_NSS_375M_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_eip_bfdcd_clk_src = { + .cmd_rcgr = 0x644, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_0, + .freq_tbl = ftbl_nss_cc_eip_bfdcd_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_eip_bfdcd_clk_src", + .parent_data = nss_cc_parent_data_0, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port1_rx_clk_src_25[] = { + C(P_UNIPHY0_NSS_RX_CLK, 12.5, 0, 0), + C(P_UNIPHY0_NSS_RX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port1_rx_clk_src_125[] = { + C(P_UNIPHY0_NSS_RX_CLK, 2.5, 0, 0), + C(P_UNIPHY0_NSS_RX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port1_rx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port1_rx_clk_src_25), + FMS(78125000, P_UNIPHY0_NSS_RX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port1_rx_clk_src_125), + FMS(156250000, P_UNIPHY0_NSS_RX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY0_NSS_RX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port1_rx_clk_src = { + .cmd_rcgr = 0x4b4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_1, + .freq_multi_tbl = ftbl_nss_cc_port1_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port1_rx_clk_src", + .parent_data = nss_cc_parent_data_1, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_1), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port1_tx_clk_src_25[] = { + C(P_UNIPHY0_NSS_TX_CLK, 12.5, 0, 0), + C(P_UNIPHY0_NSS_TX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port1_tx_clk_src_125[] = { + C(P_UNIPHY0_NSS_TX_CLK, 2.5, 0, 0), + C(P_UNIPHY0_NSS_TX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port1_tx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port1_tx_clk_src_25), + FMS(78125000, P_UNIPHY0_NSS_TX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port1_tx_clk_src_125), + FMS(156250000, P_UNIPHY0_NSS_TX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY0_NSS_TX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port1_tx_clk_src = { + .cmd_rcgr = 0x4c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_1, + .freq_multi_tbl = ftbl_nss_cc_port1_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port1_tx_clk_src", + .parent_data = nss_cc_parent_data_1, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_1), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port2_rx_clk_src_25[] = { + C(P_UNIPHY1_NSS_RX_CLK, 12.5, 0, 0), + C(P_UNIPHY1_NSS_RX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port2_rx_clk_src_125[] = { + C(P_UNIPHY1_NSS_RX_CLK, 2.5, 0, 0), + C(P_UNIPHY1_NSS_RX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port2_rx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port2_rx_clk_src_25), + FMS(78125000, P_UNIPHY1_NSS_RX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port2_rx_clk_src_125), + FMS(156250000, P_UNIPHY1_NSS_RX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY1_NSS_RX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port2_rx_clk_src = { + .cmd_rcgr = 0x4cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_2, + .freq_multi_tbl = ftbl_nss_cc_port2_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port2_rx_clk_src", + .parent_data = nss_cc_parent_data_2, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_2), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port2_tx_clk_src_25[] = { + C(P_UNIPHY1_NSS_TX_CLK, 12.5, 0, 0), + C(P_UNIPHY1_NSS_TX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port2_tx_clk_src_125[] = { + C(P_UNIPHY1_NSS_TX_CLK, 2.5, 0, 0), + C(P_UNIPHY1_NSS_TX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port2_tx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port2_tx_clk_src_25), + FMS(78125000, P_UNIPHY1_NSS_TX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port2_tx_clk_src_125), + FMS(156250000, P_UNIPHY1_NSS_TX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY1_NSS_TX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port2_tx_clk_src = { + .cmd_rcgr = 0x4d8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_2, + .freq_multi_tbl = ftbl_nss_cc_port2_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port2_tx_clk_src", + .parent_data = nss_cc_parent_data_2, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_2), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port3_rx_clk_src_25[] = { + C(P_UNIPHY2_NSS_RX_CLK, 12.5, 0, 0), + C(P_UNIPHY2_NSS_RX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port3_rx_clk_src_125[] = { + C(P_UNIPHY2_NSS_RX_CLK, 2.5, 0, 0), + C(P_UNIPHY2_NSS_RX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port3_rx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port3_rx_clk_src_25), + FMS(78125000, P_UNIPHY2_NSS_RX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port3_rx_clk_src_125), + FMS(156250000, P_UNIPHY2_NSS_RX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY2_NSS_RX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port3_rx_clk_src = { + .cmd_rcgr = 0x4e4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_3, + .freq_multi_tbl = ftbl_nss_cc_port3_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port3_rx_clk_src", + .parent_data = nss_cc_parent_data_3, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_3), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port3_tx_clk_src_25[] = { + C(P_UNIPHY2_NSS_TX_CLK, 12.5, 0, 0), + C(P_UNIPHY2_NSS_TX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port3_tx_clk_src_125[] = { + C(P_UNIPHY2_NSS_TX_CLK, 2.5, 0, 0), + C(P_UNIPHY2_NSS_TX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port3_tx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port3_tx_clk_src_25), + FMS(78125000, P_UNIPHY2_NSS_TX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port3_tx_clk_src_125), + FMS(156250000, P_UNIPHY2_NSS_TX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY2_NSS_TX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port3_tx_clk_src = { + .cmd_rcgr = 0x4f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_3, + .freq_multi_tbl = ftbl_nss_cc_port3_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port3_tx_clk_src", + .parent_data = nss_cc_parent_data_3, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_3), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_ppe_clk_src = { + .cmd_rcgr = 0x3ec, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_0, + .freq_tbl = ftbl_nss_cc_ce_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_clk_src", + .parent_data = nss_cc_parent_data_0, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port1_rx_div_clk_src = { + .reg = 0x4bc, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_rx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port1_tx_div_clk_src = { + .reg = 0x4c8, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_tx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port2_rx_div_clk_src = { + .reg = 0x4d4, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_rx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port2_tx_div_clk_src = { + .reg = 0x4e0, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_tx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port3_rx_div_clk_src = { + .reg = 0x4ec, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_rx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port3_tx_div_clk_src = { + .reg = 0x4f8, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_tx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac0_ptp_ref_div_clk_src = { + .reg = 0x3f4, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac0_ptp_ref_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac1_ptp_ref_div_clk_src = { + .reg = 0x3f8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac1_ptp_ref_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac2_ptp_ref_div_clk_src = { + .reg = 0x3fc, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac2_ptp_ref_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch nss_cc_ce_apb_clk = { + .halt_reg = 0x5e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ce_apb_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ce_axi_clk = { + .halt_reg = 0x5ec, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5ec, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ce_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_debug_clk = { + .halt_reg = 0x70c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x70c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_debug_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_eip_clk = { + .halt_reg = 0x658, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x658, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_eip_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_eip_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nss_csr_clk = { + .halt_reg = 0x6b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nss_csr_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ce_apb_clk = { + .halt_reg = 0x5f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_ce_apb_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ce_axi_clk = { + .halt_reg = 0x5f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_ce_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_eip_clk = { + .halt_reg = 0x660, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x660, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_eip_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_eip_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_nss_csr_clk = { + .halt_reg = 0x6b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_nss_csr_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ppe_cfg_clk = { + .halt_reg = 0x444, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x444, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_ppe_cfg_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ppe_clk = { + .halt_reg = 0x440, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x440, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_ppe_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port1_mac_clk = { + .halt_reg = 0x428, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x428, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port1_mac_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port1_rx_clk = { + .halt_reg = 0x4fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port1_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port1_tx_clk = { + .halt_reg = 0x504, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x504, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port1_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port2_mac_clk = { + .halt_reg = 0x430, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x430, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port2_mac_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port2_rx_clk = { + .halt_reg = 0x50c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x50c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port2_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port2_tx_clk = { + .halt_reg = 0x514, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x514, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port2_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port3_mac_clk = { + .halt_reg = 0x438, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x438, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port3_mac_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port3_rx_clk = { + .halt_reg = 0x51c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port3_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port3_tx_clk = { + .halt_reg = 0x524, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x524, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port3_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_edma_cfg_clk = { + .halt_reg = 0x424, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x424, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_edma_cfg_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_edma_clk = { + .halt_reg = 0x41c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x41c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_edma_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_btq_clk = { + .halt_reg = 0x408, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x408, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_switch_btq_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_cfg_clk = { + .halt_reg = 0x418, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x418, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_switch_cfg_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_clk = { + .halt_reg = 0x410, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x410, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_switch_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_ipe_clk = { + .halt_reg = 0x400, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x400, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_switch_ipe_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port1_rx_clk = { + .halt_reg = 0x57c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x57c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port1_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port1_tx_clk = { + .halt_reg = 0x580, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x580, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port1_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port2_rx_clk = { + .halt_reg = 0x584, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x584, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port2_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port2_tx_clk = { + .halt_reg = 0x588, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x588, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port2_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port3_rx_clk = { + .halt_reg = 0x58c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port3_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port3_tx_clk = { + .halt_reg = 0x590, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x590, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port3_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac0_ptp_ref_clk = { + .halt_reg = 0x448, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x448, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_xgmac0_ptp_ref_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_xgmac0_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac1_ptp_ref_clk = { + .halt_reg = 0x44c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x44c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_xgmac1_ptp_ref_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_xgmac1_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac2_ptp_ref_clk = { + .halt_reg = 0x450, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x450, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_xgmac2_ptp_ref_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_xgmac2_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *nss_cc_ipq5424_clocks[] = { + [NSS_CC_CE_APB_CLK] = &nss_cc_ce_apb_clk.clkr, + [NSS_CC_CE_AXI_CLK] = &nss_cc_ce_axi_clk.clkr, + [NSS_CC_CE_CLK_SRC] = &nss_cc_ce_clk_src.clkr, + [NSS_CC_CFG_CLK_SRC] = &nss_cc_cfg_clk_src.clkr, + [NSS_CC_DEBUG_CLK] = &nss_cc_debug_clk.clkr, + [NSS_CC_EIP_BFDCD_CLK_SRC] = &nss_cc_eip_bfdcd_clk_src.clkr, + [NSS_CC_EIP_CLK] = &nss_cc_eip_clk.clkr, + [NSS_CC_NSS_CSR_CLK] = &nss_cc_nss_csr_clk.clkr, + [NSS_CC_NSSNOC_CE_APB_CLK] = &nss_cc_nssnoc_ce_apb_clk.clkr, + [NSS_CC_NSSNOC_CE_AXI_CLK] = &nss_cc_nssnoc_ce_axi_clk.clkr, + [NSS_CC_NSSNOC_EIP_CLK] = &nss_cc_nssnoc_eip_clk.clkr, + [NSS_CC_NSSNOC_NSS_CSR_CLK] = &nss_cc_nssnoc_nss_csr_clk.clkr, + [NSS_CC_NSSNOC_PPE_CFG_CLK] = &nss_cc_nssnoc_ppe_cfg_clk.clkr, + [NSS_CC_NSSNOC_PPE_CLK] = &nss_cc_nssnoc_ppe_clk.clkr, + [NSS_CC_PORT1_MAC_CLK] = &nss_cc_port1_mac_clk.clkr, + [NSS_CC_PORT1_RX_CLK] = &nss_cc_port1_rx_clk.clkr, + [NSS_CC_PORT1_RX_CLK_SRC] = &nss_cc_port1_rx_clk_src.clkr, + [NSS_CC_PORT1_RX_DIV_CLK_SRC] = &nss_cc_port1_rx_div_clk_src.clkr, + [NSS_CC_PORT1_TX_CLK] = &nss_cc_port1_tx_clk.clkr, + [NSS_CC_PORT1_TX_CLK_SRC] = &nss_cc_port1_tx_clk_src.clkr, + [NSS_CC_PORT1_TX_DIV_CLK_SRC] = &nss_cc_port1_tx_div_clk_src.clkr, + [NSS_CC_PORT2_MAC_CLK] = &nss_cc_port2_mac_clk.clkr, + [NSS_CC_PORT2_RX_CLK] = &nss_cc_port2_rx_clk.clkr, + [NSS_CC_PORT2_RX_CLK_SRC] = &nss_cc_port2_rx_clk_src.clkr, + [NSS_CC_PORT2_RX_DIV_CLK_SRC] = &nss_cc_port2_rx_div_clk_src.clkr, + [NSS_CC_PORT2_TX_CLK] = &nss_cc_port2_tx_clk.clkr, + [NSS_CC_PORT2_TX_CLK_SRC] = &nss_cc_port2_tx_clk_src.clkr, + [NSS_CC_PORT2_TX_DIV_CLK_SRC] = &nss_cc_port2_tx_div_clk_src.clkr, + [NSS_CC_PORT3_MAC_CLK] = &nss_cc_port3_mac_clk.clkr, + [NSS_CC_PORT3_RX_CLK] = &nss_cc_port3_rx_clk.clkr, + [NSS_CC_PORT3_RX_CLK_SRC] = &nss_cc_port3_rx_clk_src.clkr, + [NSS_CC_PORT3_RX_DIV_CLK_SRC] = &nss_cc_port3_rx_div_clk_src.clkr, + [NSS_CC_PORT3_TX_CLK] = &nss_cc_port3_tx_clk.clkr, + [NSS_CC_PORT3_TX_CLK_SRC] = &nss_cc_port3_tx_clk_src.clkr, + [NSS_CC_PORT3_TX_DIV_CLK_SRC] = &nss_cc_port3_tx_div_clk_src.clkr, + [NSS_CC_PPE_CLK_SRC] = &nss_cc_ppe_clk_src.clkr, + [NSS_CC_PPE_EDMA_CFG_CLK] = &nss_cc_ppe_edma_cfg_clk.clkr, + [NSS_CC_PPE_EDMA_CLK] = &nss_cc_ppe_edma_clk.clkr, + [NSS_CC_PPE_SWITCH_BTQ_CLK] = &nss_cc_ppe_switch_btq_clk.clkr, + [NSS_CC_PPE_SWITCH_CFG_CLK] = &nss_cc_ppe_switch_cfg_clk.clkr, + [NSS_CC_PPE_SWITCH_CLK] = &nss_cc_ppe_switch_clk.clkr, + [NSS_CC_PPE_SWITCH_IPE_CLK] = &nss_cc_ppe_switch_ipe_clk.clkr, + [NSS_CC_UNIPHY_PORT1_RX_CLK] = &nss_cc_uniphy_port1_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT1_TX_CLK] = &nss_cc_uniphy_port1_tx_clk.clkr, + [NSS_CC_UNIPHY_PORT2_RX_CLK] = &nss_cc_uniphy_port2_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT2_TX_CLK] = &nss_cc_uniphy_port2_tx_clk.clkr, + [NSS_CC_UNIPHY_PORT3_RX_CLK] = &nss_cc_uniphy_port3_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT3_TX_CLK] = &nss_cc_uniphy_port3_tx_clk.clkr, + [NSS_CC_XGMAC0_PTP_REF_CLK] = &nss_cc_xgmac0_ptp_ref_clk.clkr, + [NSS_CC_XGMAC0_PTP_REF_DIV_CLK_SRC] = &nss_cc_xgmac0_ptp_ref_div_clk_src.clkr, + [NSS_CC_XGMAC1_PTP_REF_CLK] = &nss_cc_xgmac1_ptp_ref_clk.clkr, + [NSS_CC_XGMAC1_PTP_REF_DIV_CLK_SRC] = &nss_cc_xgmac1_ptp_ref_div_clk_src.clkr, + [NSS_CC_XGMAC2_PTP_REF_CLK] = &nss_cc_xgmac2_ptp_ref_clk.clkr, + [NSS_CC_XGMAC2_PTP_REF_DIV_CLK_SRC] = &nss_cc_xgmac2_ptp_ref_div_clk_src.clkr, +}; + +static const struct qcom_reset_map nss_cc_ipq5424_resets[] = { + [NSS_CC_CE_APB_CLK_ARES] = { 0x5e8, 2 }, + [NSS_CC_CE_AXI_CLK_ARES] = { 0x5ec, 2 }, + [NSS_CC_DEBUG_CLK_ARES] = { 0x70c, 2 }, + [NSS_CC_EIP_CLK_ARES] = { 0x658, 2 }, + [NSS_CC_NSS_CSR_CLK_ARES] = { 0x6b0, 2 }, + [NSS_CC_NSSNOC_CE_APB_CLK_ARES] = { 0x5f4, 2 }, + [NSS_CC_NSSNOC_CE_AXI_CLK_ARES] = { 0x5f8, 2 }, + [NSS_CC_NSSNOC_EIP_CLK_ARES] = { 0x660, 2 }, + [NSS_CC_NSSNOC_NSS_CSR_CLK_ARES] = { 0x6b4, 2 }, + [NSS_CC_NSSNOC_PPE_CLK_ARES] = { 0x440, 2 }, + [NSS_CC_NSSNOC_PPE_CFG_CLK_ARES] = { 0x444, 2 }, + [NSS_CC_PORT1_MAC_CLK_ARES] = { 0x428, 2 }, + [NSS_CC_PORT1_RX_CLK_ARES] = { 0x4fc, 2 }, + [NSS_CC_PORT1_TX_CLK_ARES] = { 0x504, 2 }, + [NSS_CC_PORT2_MAC_CLK_ARES] = { 0x430, 2 }, + [NSS_CC_PORT2_RX_CLK_ARES] = { 0x50c, 2 }, + [NSS_CC_PORT2_TX_CLK_ARES] = { 0x514, 2 }, + [NSS_CC_PORT3_MAC_CLK_ARES] = { 0x438, 2 }, + [NSS_CC_PORT3_RX_CLK_ARES] = { 0x51c, 2 }, + [NSS_CC_PORT3_TX_CLK_ARES] = { 0x524, 2 }, + [NSS_CC_PPE_BCR] = { 0x3e8 }, + [NSS_CC_PPE_EDMA_CLK_ARES] = { 0x41c, 2 }, + [NSS_CC_PPE_EDMA_CFG_CLK_ARES] = { 0x424, 2 }, + [NSS_CC_PPE_SWITCH_BTQ_CLK_ARES] = { 0x408, 2 }, + [NSS_CC_PPE_SWITCH_CLK_ARES] = { 0x410, 2 }, + [NSS_CC_PPE_SWITCH_CFG_CLK_ARES] = { 0x418, 2 }, + [NSS_CC_PPE_SWITCH_IPE_CLK_ARES] = { 0x400, 2 }, + [NSS_CC_UNIPHY_PORT1_RX_CLK_ARES] = { 0x57c, 2 }, + [NSS_CC_UNIPHY_PORT1_TX_CLK_ARES] = { 0x580, 2 }, + [NSS_CC_UNIPHY_PORT2_RX_CLK_ARES] = { 0x584, 2 }, + [NSS_CC_UNIPHY_PORT2_TX_CLK_ARES] = { 0x588, 2 }, + [NSS_CC_UNIPHY_PORT3_RX_CLK_ARES] = { 0x58c, 2 }, + [NSS_CC_UNIPHY_PORT3_TX_CLK_ARES] = { 0x590, 2 }, + [NSS_CC_XGMAC0_PTP_REF_CLK_ARES] = { 0x448, 2 }, + [NSS_CC_XGMAC1_PTP_REF_CLK_ARES] = { 0x44c, 2 }, + [NSS_CC_XGMAC2_PTP_REF_CLK_ARES] = { 0x450, 2 }, +}; + +static const struct regmap_config nss_cc_ipq5424_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x800, + .fast_io = true, +}; + +static const struct qcom_icc_hws_data icc_ipq5424_nss_hws[] = { + { MASTER_NSSNOC_PPE, SLAVE_NSSNOC_PPE, NSS_CC_NSSNOC_PPE_CLK }, + { MASTER_NSSNOC_PPE_CFG, SLAVE_NSSNOC_PPE_CFG, NSS_CC_NSSNOC_PPE_CFG_CLK }, + { MASTER_NSSNOC_NSS_CSR, SLAVE_NSSNOC_NSS_CSR, NSS_CC_NSSNOC_NSS_CSR_CLK }, + { MASTER_NSSNOC_CE_AXI, SLAVE_NSSNOC_CE_AXI, NSS_CC_NSSNOC_CE_AXI_CLK}, + { MASTER_NSSNOC_CE_APB, SLAVE_NSSNOC_CE_APB, NSS_CC_NSSNOC_CE_APB_CLK}, + { MASTER_NSSNOC_EIP, SLAVE_NSSNOC_EIP, NSS_CC_NSSNOC_EIP_CLK}, +}; + +#define IPQ_NSSCC_ID (5424 * 2) /* some unique value */ + +static const struct qcom_cc_desc nss_cc_ipq5424_desc = { + .config = &nss_cc_ipq5424_regmap_config, + .clks = nss_cc_ipq5424_clocks, + .num_clks = ARRAY_SIZE(nss_cc_ipq5424_clocks), + .resets = nss_cc_ipq5424_resets, + .num_resets = ARRAY_SIZE(nss_cc_ipq5424_resets), + .icc_hws = icc_ipq5424_nss_hws, + .num_icc_hws = ARRAY_SIZE(icc_ipq5424_nss_hws), + .icc_first_node_id = IPQ_NSSCC_ID, +}; + +static const struct dev_pm_ops nss_cc_ipq5424_pm_ops = { + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) +}; + +static const struct of_device_id nss_cc_ipq5424_match_table[] = { + { .compatible = "qcom,ipq5424-nsscc" }, + { } +}; +MODULE_DEVICE_TABLE(of, nss_cc_ipq5424_match_table); + +static int nss_cc_ipq5424_probe(struct platform_device *pdev) +{ + int ret; + + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to enable runtime PM\n"); + + ret = devm_pm_clk_create(&pdev->dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to create PM clock\n"); + + ret = pm_clk_add(&pdev->dev, "bus"); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to add bus clock\n"); + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to resume\n"); + + ret = qcom_cc_probe(pdev, &nss_cc_ipq5424_desc); + pm_runtime_put(&pdev->dev); + + return ret; +} + +static struct platform_driver nss_cc_ipq5424_driver = { + .probe = nss_cc_ipq5424_probe, + .driver = { + .name = "qcom,ipq5424-nsscc", + .of_match_table = nss_cc_ipq5424_match_table, + .pm = &nss_cc_ipq5424_pm_ops, + .sync_state = icc_sync_state, + }, +}; +module_platform_driver(nss_cc_ipq5424_driver); + +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. NSSCC IPQ5424 Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/tcsrcc-glymur.c b/drivers/clk/qcom/tcsrcc-glymur.c index c1f8b6d10b7fd..215bc2ac548da 100644 --- a/drivers/clk/qcom/tcsrcc-glymur.c +++ b/drivers/clk/qcom/tcsrcc-glymur.c @@ -28,10 +28,10 @@ enum { }; static struct clk_branch tcsr_edp_clkref_en = { - .halt_reg = 0x1c, + .halt_reg = 0x60, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x1c, + .enable_reg = 0x60, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_edp_clkref_en", @@ -45,10 +45,10 @@ static struct clk_branch tcsr_edp_clkref_en = { }; static struct clk_branch tcsr_pcie_1_clkref_en = { - .halt_reg = 0x4, + .halt_reg = 0x48, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x4, + .enable_reg = 0x48, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_pcie_1_clkref_en", @@ -62,10 +62,10 @@ static struct clk_branch tcsr_pcie_1_clkref_en = { }; static struct clk_branch tcsr_pcie_2_clkref_en = { - .halt_reg = 0x8, + .halt_reg = 0x4c, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x8, + .enable_reg = 0x4c, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_pcie_2_clkref_en", @@ -79,10 +79,10 @@ static struct clk_branch tcsr_pcie_2_clkref_en = { }; static struct clk_branch tcsr_pcie_3_clkref_en = { - .halt_reg = 0x10, + .halt_reg = 0x54, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x10, + .enable_reg = 0x54, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_pcie_3_clkref_en", @@ -96,10 +96,10 @@ static struct clk_branch tcsr_pcie_3_clkref_en = { }; static struct clk_branch tcsr_pcie_4_clkref_en = { - .halt_reg = 0x14, + .halt_reg = 0x58, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x14, + .enable_reg = 0x58, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_pcie_4_clkref_en", @@ -113,10 +113,10 @@ static struct clk_branch tcsr_pcie_4_clkref_en = { }; static struct clk_branch tcsr_usb2_1_clkref_en = { - .halt_reg = 0x28, + .halt_reg = 0x6c, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x28, + .enable_reg = 0x6c, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb2_1_clkref_en", @@ -130,10 +130,10 @@ static struct clk_branch tcsr_usb2_1_clkref_en = { }; static struct clk_branch tcsr_usb2_2_clkref_en = { - .halt_reg = 0x2c, + .halt_reg = 0x70, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x2c, + .enable_reg = 0x70, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb2_2_clkref_en", @@ -147,10 +147,10 @@ static struct clk_branch tcsr_usb2_2_clkref_en = { }; static struct clk_branch tcsr_usb2_3_clkref_en = { - .halt_reg = 0x30, + .halt_reg = 0x74, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x30, + .enable_reg = 0x74, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb2_3_clkref_en", @@ -164,10 +164,10 @@ static struct clk_branch tcsr_usb2_3_clkref_en = { }; static struct clk_branch tcsr_usb2_4_clkref_en = { - .halt_reg = 0x44, + .halt_reg = 0x88, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x44, + .enable_reg = 0x88, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb2_4_clkref_en", @@ -181,10 +181,10 @@ static struct clk_branch tcsr_usb2_4_clkref_en = { }; static struct clk_branch tcsr_usb3_0_clkref_en = { - .halt_reg = 0x20, + .halt_reg = 0x64, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x20, + .enable_reg = 0x64, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb3_0_clkref_en", @@ -198,10 +198,10 @@ static struct clk_branch tcsr_usb3_0_clkref_en = { }; static struct clk_branch tcsr_usb3_1_clkref_en = { - .halt_reg = 0x24, + .halt_reg = 0x68, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x24, + .enable_reg = 0x68, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb3_1_clkref_en", @@ -215,10 +215,10 @@ static struct clk_branch tcsr_usb3_1_clkref_en = { }; static struct clk_branch tcsr_usb4_1_clkref_en = { - .halt_reg = 0x0, + .halt_reg = 0x44, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x0, + .enable_reg = 0x44, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb4_1_clkref_en", @@ -232,10 +232,10 @@ static struct clk_branch tcsr_usb4_1_clkref_en = { }; static struct clk_branch tcsr_usb4_2_clkref_en = { - .halt_reg = 0x18, + .halt_reg = 0x5c, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x18, + .enable_reg = 0x5c, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb4_2_clkref_en", @@ -268,7 +268,7 @@ static const struct regmap_config tcsr_cc_glymur_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = 0x44, + .max_register = 0x94, .fast_io = true, }; diff --git a/drivers/clk/qcom/videocc-sm8750.c b/drivers/clk/qcom/videocc-sm8750.c new file mode 100644 index 0000000000000..0acf3104d702b --- /dev/null +++ b/drivers/clk/qcom/videocc-sm8750.c @@ -0,0 +1,463 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_SLEEP_CLK, + P_VIDEO_CC_PLL0_OUT_MAIN, +}; + +static const struct pll_vco taycan_elu_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +static const struct alpha_pll_config video_cc_pll0_config = { + .l = 0x25, + .alpha = 0x8000, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll0 = { + .offset = 0x0, + .config = &video_cc_pll0_config, + .vco_table = taycan_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_0_ao[] = { + { .index = DT_BI_TCXO_AO }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll0.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2_ao[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_ahb_clk_src = { + .cmd_rcgr = 0x8018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_ahb_clk_src", + .parent_data = video_cc_parent_data_0_ao, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { + F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1260000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1710000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1890000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_mvs0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_sleep_clk_src = { + .cmd_rcgr = 0x80e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_sleep_clk_src", + .parent_data = video_cc_parent_data_2_ao, + .num_parents = ARRAY_SIZE(video_cc_parent_data_2_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x80bc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_xo_clk_src", + .parent_data = video_cc_parent_data_0_ao, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs0_div_clk_src = { + .reg = 0x809c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = { + .reg = 0x8060, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_div2_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch video_cc_mvs0_clk = { + .halt_reg = 0x807c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x807c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x807c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_mem_branch video_cc_mvs0_freerun_clk = { + .mem_enable_reg = 0x8090, + .mem_ack_reg = 0x8090, + .mem_enable_mask = BIT(3), + .mem_enable_ack_mask = GENMASK(11, 10), + .mem_enable_invert = true, + .branch = { + .halt_reg = 0x808c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x808c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_mem_ops, + }, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_shift_clk = { + .halt_reg = 0x80d8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80d8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_clk = { + .halt_reg = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_div2_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_freerun_clk = { + .halt_reg = 0x805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_div2_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_shift_clk = { + .halt_reg = 0x80dc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80dc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc video_cc_mvs0c_gdsc = { + .gdscr = 0x8034, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0c_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_gdsc = { + .gdscr = 0x8068, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mvs0c_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct clk_regmap *video_cc_sm8750_clocks[] = { + [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, + [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, + [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, + [VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr, + [VIDEO_CC_MVS0_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.branch.clkr, + [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, + [VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr, + [VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr, + [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, + [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, + [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr, + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, +}; + +static struct gdsc *video_cc_sm8750_gdscs[] = { + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, +}; + +static const struct qcom_reset_map video_cc_sm8750_resets[] = { + [VIDEO_CC_INTERFACE_BCR] = { 0x80a0 }, + [VIDEO_CC_MVS0_BCR] = { 0x8064 }, + [VIDEO_CC_MVS0C_CLK_ARES] = { 0x804c, 2 }, + [VIDEO_CC_MVS0C_BCR] = { 0x8030 }, + [VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x808c, 2 }, + [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x805c, 2 }, + [VIDEO_CC_XO_CLK_ARES] = { 0x80d4, 2 }, +}; + +static const struct regmap_config video_cc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9f4c, + .fast_io = true, +}; + +static struct clk_alpha_pll *video_cc_sm8750_plls[] = { + &video_cc_pll0, +}; + +static u32 video_cc_sm8750_critical_cbcrs[] = { + 0x80a4, /* VIDEO_CC_AHB_CLK */ + 0x80f8, /* VIDEO_CC_SLEEP_CLK */ + 0x80d4, /* VIDEO_CC_XO_CLK */ +}; + +static void clk_sm8750_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Update DLY_ACCU_RED_SHIFTER_DONE to 0xF for mvs0, mvs0c */ + regmap_update_bits(regmap, 0x8074, GENMASK(25, 21), GENMASK(25, 21)); + regmap_update_bits(regmap, 0x8040, GENMASK(25, 21), GENMASK(25, 21)); + + regmap_update_bits(regmap, 0x9f24, BIT(0), BIT(0)); +} + +static struct qcom_cc_driver_data video_cc_sm8750_driver_data = { + .alpha_plls = video_cc_sm8750_plls, + .num_alpha_plls = ARRAY_SIZE(video_cc_sm8750_plls), + .clk_cbcrs = video_cc_sm8750_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_sm8750_critical_cbcrs), + .clk_regs_configure = clk_sm8750_regs_configure, +}; + +static struct qcom_cc_desc video_cc_sm8750_desc = { + .config = &video_cc_sm8750_regmap_config, + .clks = video_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(video_cc_sm8750_clocks), + .resets = video_cc_sm8750_resets, + .num_resets = ARRAY_SIZE(video_cc_sm8750_resets), + .gdscs = video_cc_sm8750_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_sm8750_gdscs), + .use_rpm = true, + .driver_data = &video_cc_sm8750_driver_data, +}; + +static const struct of_device_id video_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_sm8750_match_table); + +static int video_cc_sm8750_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &video_cc_sm8750_desc); +} + +static struct platform_driver video_cc_sm8750_driver = { + .probe = video_cc_sm8750_probe, + .driver = { + .name = "video_cc-sm8750", + .of_match_table = video_cc_sm8750_match_table, + }, +}; + +static int __init video_cc_sm8750_init(void) +{ + return platform_driver_register(&video_cc_sm8750_driver); +} +subsys_initcall(video_cc_sm8750_init); + +static void __exit video_cc_sm8750_exit(void) +{ + platform_driver_unregister(&video_cc_sm8750_driver); +} +module_exit(video_cc_sm8750_exit); + +MODULE_DESCRIPTION("QTI VIDEO_CC SM8750 Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index 3abd6e5400ade..f7b827b5e9b2d 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -7,6 +7,7 @@ * Contact: Laurent Pinchart */ +#include #include #include #include @@ -171,8 +172,7 @@ static u8 cpg_div6_clock_get_parent(struct clk_hw *hw) if (clock->src_mask == 0) return 0; - hw_index = (readl(clock->reg) & clock->src_mask) >> - __ffs(clock->src_mask); + hw_index = field_get(clock->src_mask, readl(clock->reg)); for (i = 0; i < clk_hw_get_num_parents(hw); i++) { if (clock->parents[i] == hw_index) return i; @@ -191,7 +191,7 @@ static int cpg_div6_clock_set_parent(struct clk_hw *hw, u8 index) if (index >= clk_hw_get_num_parents(hw)) return -EINVAL; - src = clock->parents[index] << __ffs(clock->src_mask); + src = field_prep(clock->src_mask, clock->parents[index]); writel((readl(clock->reg) & ~clock->src_mask) | src, clock->reg); return 0; } diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index 1be7b9592aa62..d67dff05d9f4a 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -26,7 +26,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R8A779A0_CLK_OSC, + LAST_DT_CORE_CLK = R8A779A0_CLK_ZG, /* External Input Clocks */ CLK_EXTAL, @@ -39,6 +39,7 @@ enum clk_ids { CLK_PLL21, CLK_PLL30, CLK_PLL31, + CLK_PLL4, CLK_PLL5, CLK_PLL1_DIV2, CLK_PLL20_DIV2, @@ -65,6 +66,7 @@ enum clk_ids { #define CPG_PLL21CR 0x0838 /* PLL21 Control Register */ #define CPG_PLL30CR 0x083c /* PLL30 Control Register */ #define CPG_PLL31CR 0x0840 /* PLL31 Control Register */ +#define CPG_PLL4CR 0x0844 /* PLL4 Control Register */ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { /* External Clock Inputs */ @@ -79,6 +81,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { DEF_PLL(".pll21", CLK_PLL21, CPG_PLL21CR), DEF_PLL(".pll30", CLK_PLL30, CPG_PLL30CR), DEF_PLL(".pll31", CLK_PLL31, CPG_PLL31CR), + DEF_PLL(".pll4", CLK_PLL4, CPG_PLL4CR), DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), DEF_FIXED(".pll20_div2", CLK_PLL20_DIV2, CLK_PLL20, 2, 1), @@ -98,6 +101,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { /* Core Clock Outputs */ DEF_GEN4_Z("z0", R8A779A0_CLK_Z0, CLK_TYPE_GEN4_Z, CLK_PLL20, 2, 0), DEF_GEN4_Z("z1", R8A779A0_CLK_Z1, CLK_TYPE_GEN4_Z, CLK_PLL21, 2, 8), + DEF_GEN4_Z("zg", R8A779A0_CLK_ZG, CLK_TYPE_GEN4_Z, CLK_PLL4, 2, 88), DEF_FIXED("zx", R8A779A0_CLK_ZX, CLK_PLL20_DIV2, 2, 1), DEF_FIXED("s1d1", R8A779A0_CLK_S1D1, CLK_S1, 1, 1), DEF_FIXED("s1d2", R8A779A0_CLK_S1D2, CLK_S1, 2, 1), @@ -138,6 +142,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { }; static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { + DEF_MOD("3dge", 0, R8A779A0_CLK_ZG), DEF_MOD("isp0", 16, R8A779A0_CLK_S1D1), DEF_MOD("isp1", 17, R8A779A0_CLK_S1D1), DEF_MOD("isp2", 18, R8A779A0_CLK_S1D1), diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index dcda19318b2a9..0f5c91b5dfa99 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -1333,9 +1333,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) if (IS_ERR(mclk)) return PTR_ERR(mclk); - clocks->reg = of_iomap(np, 0); - if (WARN_ON(!clocks->reg)) - return -ENOMEM; + clocks->reg = devm_of_iomap(dev, np, 0, NULL); + if (IS_ERR(clocks->reg)) + return PTR_ERR(clocks->reg); r9a06g032_init_h2mode(clocks); diff --git a/drivers/clk/renesas/r9a09g047-cpg.c b/drivers/clk/renesas/r9a09g047-cpg.c index ef115f9ec0e64..1e9896742a062 100644 --- a/drivers/clk/renesas/r9a09g047-cpg.c +++ b/drivers/clk/renesas/r9a09g047-cpg.c @@ -16,7 +16,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G047_USB3_0_CLKCORE, + LAST_DT_CORE_CLK = R9A09G047_USB2_0_CLK_CORE1, /* External Input Clocks */ CLK_AUDIO_EXTAL, @@ -44,6 +44,9 @@ enum clk_ids { CLK_PLLCLN_DIV8, CLK_PLLCLN_DIV16, CLK_PLLCLN_DIV20, + CLK_PLLCLN_DIV64, + CLK_PLLCLN_DIV256, + CLK_PLLCLN_DIV1024, CLK_PLLDTY_ACPU, CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU_DIV4, @@ -142,6 +145,9 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8), DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16), DEF_FIXED(".pllcln_div20", CLK_PLLCLN_DIV20, CLK_PLLCLN, 1, 20), + DEF_FIXED(".pllcln_div64", CLK_PLLCLN_DIV64, CLK_PLLCLN, 1, 64), + DEF_FIXED(".pllcln_div256", CLK_PLLCLN_DIV256, CLK_PLLCLN, 1, 256), + DEF_FIXED(".pllcln_div1024", CLK_PLLCLN_DIV1024, CLK_PLLCLN, 1, 1024), DEF_DDIV(".plldty_acpu", CLK_PLLDTY_ACPU, CLK_PLLDTY, CDDIV0_DIVCTL2, dtable_2_64), DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2), @@ -177,6 +183,8 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { CDDIV1_DIVCTL3, dtable_1_8), DEF_FIXED("iotop_0_shclk", R9A09G047_IOTOP_0_SHCLK, CLK_PLLCM33_DIV16, 1, 1), DEF_FIXED("spi_clk_spi", R9A09G047_SPI_CLK_SPI, CLK_PLLCM33_XSPI, 1, 2), + DEF_FIXED("usb2_0_clk_core0", R9A09G047_USB2_0_CLK_CORE0, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb2_0_clk_core1", R9A09G047_USB2_0_CLK_CORE1, CLK_QEXTAL, 1, 1), DEF_FIXED("gbeth_0_clk_ptp_ref_i", R9A09G047_GBETH_0_CLK_PTP_REF_I, CLK_PLLETH_DIV_125_FIX, 1, 1), DEF_FIXED("gbeth_1_clk_ptp_ref_i", R9A09G047_GBETH_1_CLK_PTP_REF_I, @@ -216,6 +224,106 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = { BUS_MSTOP(5, BIT(13))), DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18, BUS_MSTOP(5, BIT(13))), + DEF_MOD("rsci0_pclk", CLK_PLLCLN_DIV16, 5, 13, 2, 29, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_tclk", CLK_PLLCLN_DIV16, 5, 14, 2, 30, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps3_n", CLK_PLLCLN_DIV1024, 5, 15, 2, 31, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 0, 3, 0, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 1, 3, 1, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci1_pclk", CLK_PLLCLN_DIV16, 6, 2, 3, 2, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_tclk", CLK_PLLCLN_DIV16, 6, 3, 3, 3, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 4, 3, 4, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 5, 3, 5, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 6, 3, 6, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci2_pclk", CLK_PLLCLN_DIV16, 6, 7, 3, 7, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_tclk", CLK_PLLCLN_DIV16, 6, 8, 3, 8, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 9, 3, 9, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 10, 3, 10, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 11, 3, 11, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci3_pclk", CLK_PLLCLN_DIV16, 6, 12, 3, 12, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_tclk", CLK_PLLCLN_DIV16, 6, 13, 3, 13, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 14, 3, 14, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 15, 3, 15, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 0, 3, 16, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci4_pclk", CLK_PLLCLN_DIV16, 7, 1, 3, 17, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_tclk", CLK_PLLCLN_DIV16, 7, 2, 3, 18, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 3, 3, 19, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 4, 3, 20, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 5, 3, 21, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci5_pclk", CLK_PLLCLN_DIV16, 7, 6, 3, 22, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_tclk", CLK_PLLCLN_DIV16, 7, 7, 3, 23, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 8, 3, 24, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 9, 3, 25, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 10, 3, 26, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci6_pclk", CLK_PLLCLN_DIV16, 7, 11, 3, 27, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_tclk", CLK_PLLCLN_DIV16, 7, 12, 3, 28, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 13, 3, 29, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 14, 3, 30, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 15, 3, 31, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci7_pclk", CLK_PLLCLN_DIV16, 8, 0, 4, 0, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_tclk", CLK_PLLCLN_DIV16, 8, 1, 4, 1, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 2, 4, 2, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 3, 4, 3, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 4, 4, 4, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci8_pclk", CLK_PLLCLN_DIV16, 8, 5, 4, 5, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_tclk", CLK_PLLCLN_DIV16, 8, 6, 4, 6, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 7, 4, 7, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 8, 4, 8, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 9, 4, 9, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci9_pclk", CLK_PLLCLN_DIV16, 8, 10, 4, 10, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_tclk", CLK_PLLCLN_DIV16, 8, 11, 4, 11, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 12, 4, 12, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 13, 4, 13, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 14, 4, 14, + BUS_MSTOP(11, BIT(12))), DEF_MOD("scif_0_clk_pck", CLK_PLLCM33_DIV16, 8, 15, 4, 15, BUS_MSTOP(3, BIT(14))), DEF_MOD("i3c_0_pclkrw", CLK_PLLCLN_DIV16, 9, 0, 4, 16, @@ -282,6 +390,16 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = { BUS_MSTOP(7, BIT(12))), DEF_MOD("usb3_0_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 0, 5, 16, BUS_MSTOP(7, BIT(14))), + DEF_MOD("usb2_0_u2h0_hclk", CLK_PLLDTY_DIV8, 11, 3, 5, 19, + BUS_MSTOP(7, BIT(7))), + DEF_MOD("usb2_0_u2h1_hclk", CLK_PLLDTY_DIV8, 11, 4, 5, 20, + BUS_MSTOP(7, BIT(8))), + DEF_MOD("usb2_0_u2p_exr_cpuclk", CLK_PLLDTY_ACPU_DIV4, 11, 5, 5, 21, + BUS_MSTOP(7, BIT(9))), + DEF_MOD("usb2_0_pclk_usbtst0", CLK_PLLDTY_ACPU_DIV4, 11, 6, 5, 22, + BUS_MSTOP(7, BIT(10))), + DEF_MOD("usb2_0_pclk_usbtst1", CLK_PLLDTY_ACPU_DIV4, 11, 7, 5, 23, + BUS_MSTOP(7, BIT(11))), DEF_MOD_MUX_EXTERNAL("gbeth_0_clk_tx_i", CLK_SMUX2_GBE0_TXCLK, 11, 8, 5, 24, BUS_MSTOP(8, BIT(5)), 1), DEF_MOD_MUX_EXTERNAL("gbeth_0_clk_rx_i", CLK_SMUX2_GBE0_RXCLK, 11, 9, 5, 25, @@ -339,6 +457,26 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = { DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */ DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ + DEF_RST(8, 1, 3, 18), /* RSCI0_PRESETN */ + DEF_RST(8, 2, 3, 19), /* RSCI0_TRESETN */ + DEF_RST(8, 3, 3, 20), /* RSCI1_PRESETN */ + DEF_RST(8, 4, 3, 21), /* RSCI1_TRESETN */ + DEF_RST(8, 5, 3, 22), /* RSCI2_PRESETN */ + DEF_RST(8, 6, 3, 23), /* RSCI2_TRESETN */ + DEF_RST(8, 7, 3, 24), /* RSCI3_PRESETN */ + DEF_RST(8, 8, 3, 25), /* RSCI3_TRESETN */ + DEF_RST(8, 9, 3, 26), /* RSCI4_PRESETN */ + DEF_RST(8, 10, 3, 27), /* RSCI4_TRESETN */ + DEF_RST(8, 11, 3, 28), /* RSCI5_PRESETN */ + DEF_RST(8, 12, 3, 29), /* RSCI5_TRESETN */ + DEF_RST(8, 13, 3, 30), /* RSCI6_PRESETN */ + DEF_RST(8, 14, 3, 31), /* RSCI6_TRESETN */ + DEF_RST(8, 15, 4, 0), /* RSCI7_PRESETN */ + DEF_RST(9, 0, 4, 1), /* RSCI7_TRESETN */ + DEF_RST(9, 1, 4, 2), /* RSCI8_PRESETN */ + DEF_RST(9, 2, 4, 3), /* RSCI8_TRESETN */ + DEF_RST(9, 3, 4, 4), /* RSCI9_PRESETN */ + DEF_RST(9, 4, 4, 5), /* RSCI9_TRESETN */ DEF_RST(9, 5, 4, 6), /* SCIF_0_RST_SYSTEM_N */ DEF_RST(9, 6, 4, 7), /* I3C_0_PRESETN */ DEF_RST(9, 7, 4, 8), /* I3C_0_TRESETN */ @@ -359,6 +497,10 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = { DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */ DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */ DEF_RST(10, 10, 4, 27), /* USB3_0_ARESETN */ + DEF_RST(10, 12, 4, 29), /* USB2_0_U2H0_HRESETN */ + DEF_RST(10, 13, 4, 30), /* USB2_0_U2H1_HRESETN */ + DEF_RST(10, 14, 4, 31), /* USB2_0_U2P_EXL_SYSRST */ + DEF_RST(10, 15, 5, 0), /* USB2_0_PRESETN */ DEF_RST(11, 0, 5, 1), /* GBETH_0_ARESETN_I */ DEF_RST(11, 1, 5, 2), /* GBETH_1_ARESETN_I */ DEF_RST(12, 5, 5, 22), /* CRU_0_PRESETN */ diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index 55f056359dd77..f48a082e65d77 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -16,7 +17,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G056_SPI_CLK_SPI, + LAST_DT_CORE_CLK = R9A09G056_USB3_0_CLKCORE, /* External Input Clocks */ CLK_AUDIO_EXTAL, @@ -28,7 +29,9 @@ enum clk_ids { CLK_PLLCLN, CLK_PLLDTY, CLK_PLLCA55, + CLK_PLLVDO, CLK_PLLETH, + CLK_PLLDSI, CLK_PLLGPU, /* Internal Core Clocks */ @@ -47,6 +50,10 @@ enum clk_ids { CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_DIV8, + CLK_PLLDTY_DIV16, + CLK_PLLVDO_CRU0, + CLK_PLLVDO_CRU1, + CLK_PLLVDO_ISP, CLK_PLLETH_DIV_250_FIX, CLK_PLLETH_DIV_125_FIX, CLK_CSDIV_PLLETH_GBE0, @@ -55,6 +62,9 @@ enum clk_ids { CLK_SMUX2_GBE0_RXCLK, CLK_SMUX2_GBE1_TXCLK, CLK_SMUX2_GBE1_RXCLK, + CLK_CDIV4_PLLETH_LPCLK, + CLK_PLLETH_LPCLK_GEAR, + CLK_PLLDSI_GEAR, CLK_PLLGPU_GEAR, /* Module Clocks */ @@ -69,6 +79,12 @@ static const struct clk_div_table dtable_1_8[] = { {0, 0}, }; +static const struct clk_div_table dtable_2_4[] = { + {0, 2}, + {1, 4}, + {0, 0}, +}; + static const struct clk_div_table dtable_2_16[] = { {0, 2}, {1, 4}, @@ -77,6 +93,26 @@ static const struct clk_div_table dtable_2_16[] = { {0, 0}, }; +static const struct clk_div_table dtable_2_32[] = { + {0, 2}, + {1, 4}, + {2, 6}, + {3, 8}, + {4, 10}, + {5, 12}, + {6, 14}, + {7, 16}, + {8, 18}, + {9, 20}, + {10, 22}, + {11, 24}, + {12, 26}, + {13, 28}, + {14, 30}, + {15, 32}, + {0, 0}, +}; + static const struct clk_div_table dtable_2_64[] = { {0, 2}, {1, 4}, @@ -93,6 +129,17 @@ static const struct clk_div_table dtable_2_100[] = { {0, 0}, }; +static const struct clk_div_table dtable_16_128[] = { + {0, 16}, + {1, 32}, + {2, 64}, + {3, 128}, + {0, 0}, +}; + +RZV2H_CPG_PLL_DSI_LIMITS(rzv2n_cpg_pll_dsi_limits); +#define PLLDSI PLL_PACK_LIMITS(0xc0, 1, 0, &rzv2n_cpg_pll_dsi_limits) + /* Mux clock tables */ static const char * const smux2_gbe0_rxclk[] = { ".plleth_gbe0", "et0_rxclk" }; static const char * const smux2_gbe0_txclk[] = { ".plleth_gbe0", "et0_txclk" }; @@ -112,7 +159,9 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".pllcln", CLK_PLLCLN, CLK_QEXTAL, 200, 3), DEF_FIXED(".plldty", CLK_PLLDTY, CLK_QEXTAL, 200, 3), DEF_PLL(".pllca55", CLK_PLLCA55, CLK_QEXTAL, PLLCA55), + DEF_FIXED(".pllvdo", CLK_PLLVDO, CLK_QEXTAL, 105, 2), DEF_FIXED(".plleth", CLK_PLLETH, CLK_QEXTAL, 125, 3), + DEF_PLLDSI(".plldsi", CLK_PLLDSI, CLK_QEXTAL, PLLDSI), DEF_PLL(".pllgpu", CLK_PLLGPU, CLK_QEXTAL, PLLGPU), /* Internal Core Clocks */ @@ -134,6 +183,11 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2), DEF_FIXED(".plldty_acpu_div4", CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_ACPU, 1, 4), DEF_FIXED(".plldty_div8", CLK_PLLDTY_DIV8, CLK_PLLDTY, 1, 8), + DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16), + + DEF_DDIV(".pllvdo_cru0", CLK_PLLVDO_CRU0, CLK_PLLVDO, CDDIV3_DIVCTL3, dtable_2_4), + DEF_DDIV(".pllvdo_cru1", CLK_PLLVDO_CRU1, CLK_PLLVDO, CDDIV4_DIVCTL0, dtable_2_4), + DEF_DDIV(".pllvdo_isp", CLK_PLLVDO_ISP, CLK_PLLVDO, CDDIV2_DIVCTL3, dtable_2_64), DEF_FIXED(".plleth_250_fix", CLK_PLLETH_DIV_250_FIX, CLK_PLLETH, 1, 4), DEF_FIXED(".plleth_125_fix", CLK_PLLETH_DIV_125_FIX, CLK_PLLETH_DIV_250_FIX, 1, 2), @@ -145,6 +199,12 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_SMUX(".smux2_gbe0_rxclk", CLK_SMUX2_GBE0_RXCLK, SSEL0_SELCTL3, smux2_gbe0_rxclk), DEF_SMUX(".smux2_gbe1_txclk", CLK_SMUX2_GBE1_TXCLK, SSEL1_SELCTL0, smux2_gbe1_txclk), DEF_SMUX(".smux2_gbe1_rxclk", CLK_SMUX2_GBE1_RXCLK, SSEL1_SELCTL1, smux2_gbe1_rxclk), + DEF_FIXED(".cdiv4_plleth_lpclk", CLK_CDIV4_PLLETH_LPCLK, CLK_PLLETH, 1, 4), + DEF_CSDIV(".plleth_lpclk_gear", CLK_PLLETH_LPCLK_GEAR, CLK_CDIV4_PLLETH_LPCLK, + CSDIV0_DIVCTL2, dtable_16_128), + + DEF_PLLDSI_DIV(".plldsi_gear", CLK_PLLDSI_GEAR, CLK_PLLDSI, + CSDIV1_DIVCTL2, dtable_2_32), DEF_DDIV(".pllgpu_gear", CLK_PLLGPU_GEAR, CLK_PLLGPU, CDDIV3_DIVCTL1, dtable_2_64), @@ -166,6 +226,8 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { CLK_PLLETH_DIV_125_FIX, 1, 1), DEF_FIXED_MOD_STATUS("spi_clk_spi", R9A09G056_SPI_CLK_SPI, CLK_PLLCM33_XSPI, 1, 2, FIXED_MOD_CONF_XSPI), + DEF_FIXED("usb3_0_ref_alt_clk_p", R9A09G056_USB3_0_REF_ALT_CLK_P, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb3_0_core_clk", R9A09G056_USB3_0_CLKCORE, CLK_QEXTAL, 1, 1), }; static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { @@ -259,6 +321,10 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(8, BIT(4))), DEF_MOD("sdhi_2_aclk", CLK_PLLDTY_ACPU_DIV4, 10, 14, 5, 14, BUS_MSTOP(8, BIT(4))), + DEF_MOD("usb3_0_aclk", CLK_PLLDTY_DIV8, 10, 15, 5, 15, + BUS_MSTOP(7, BIT(12))), + DEF_MOD("usb3_0_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 0, 5, 16, + BUS_MSTOP(7, BIT(14))), DEF_MOD("usb2_0_u2h0_hclk", CLK_PLLDTY_DIV8, 11, 3, 5, 19, BUS_MSTOP(7, BIT(7))), DEF_MOD("usb2_0_u2p_exr_cpuclk", CLK_PLLDTY_ACPU_DIV4, 11, 5, 5, 21, @@ -289,6 +355,42 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(8, BIT(6))), DEF_MOD("gbeth_1_aclk_i", CLK_PLLDTY_DIV8, 12, 3, 6, 3, BUS_MSTOP(8, BIT(6))), + DEF_MOD("cru_0_aclk", CLK_PLLDTY_ACPU_DIV2, 13, 2, 6, 18, + BUS_MSTOP(9, BIT(4))), + DEF_MOD_NO_PM("cru_0_vclk", CLK_PLLVDO_CRU0, 13, 3, 6, 19, + BUS_MSTOP(9, BIT(4))), + DEF_MOD("cru_0_pclk", CLK_PLLDTY_DIV16, 13, 4, 6, 20, + BUS_MSTOP(9, BIT(4))), + DEF_MOD("cru_1_aclk", CLK_PLLDTY_ACPU_DIV2, 13, 5, 6, 21, + BUS_MSTOP(9, BIT(5))), + DEF_MOD_NO_PM("cru_1_vclk", CLK_PLLVDO_CRU1, 13, 6, 6, 22, + BUS_MSTOP(9, BIT(5))), + DEF_MOD("cru_1_pclk", CLK_PLLDTY_DIV16, 13, 7, 6, 23, + BUS_MSTOP(9, BIT(5))), + DEF_MOD("isp_0_reg_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 2, 7, 2, + BUS_MSTOP(9, BIT(8))), + DEF_MOD("isp_0_pclk", CLK_PLLDTY_DIV16, 14, 3, 7, 3, + BUS_MSTOP(9, BIT(8))), + DEF_MOD("isp_0_vin_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 4, 7, 4, + BUS_MSTOP(9, BIT(9))), + DEF_MOD("isp_0_isp_sclk", CLK_PLLVDO_ISP, 14, 5, 7, 5, + BUS_MSTOP(9, BIT(9))), + DEF_MOD("dsi_0_pclk", CLK_PLLDTY_DIV16, 14, 8, 7, 8, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 9, 7, 9, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_vclk1", CLK_PLLDSI_GEAR, 14, 10, 7, 10, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_lpclk", CLK_PLLETH_LPCLK_GEAR, 14, 11, 7, 11, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_pllref_clk", CLK_QEXTAL, 14, 12, 7, 12, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("lcdc_0_clk_a", CLK_PLLDTY_ACPU_DIV2, 14, 13, 7, 13, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), + DEF_MOD("lcdc_0_clk_p", CLK_PLLDTY_DIV16, 14, 14, 7, 14, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), + DEF_MOD("lcdc_0_clk_d", CLK_PLLDSI_GEAR, 14, 15, 7, 15, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), DEF_MOD("gpu_0_clk", CLK_PLLGPU_GEAR, 15, 0, 7, 16, BUS_MSTOP(3, BIT(4))), DEF_MOD("gpu_0_axi_clk", CLK_PLLDTY_ACPU_DIV2, 15, 1, 7, 17, @@ -330,11 +432,25 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */ DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */ DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */ + DEF_RST(10, 10, 4, 27), /* USB3_0_ARESETN */ DEF_RST(10, 12, 4, 29), /* USB2_0_U2H0_HRESETN */ DEF_RST(10, 14, 4, 31), /* USB2_0_U2P_EXL_SYSRST */ DEF_RST(10, 15, 5, 0), /* USB2_0_PRESETN */ DEF_RST(11, 0, 5, 1), /* GBETH_0_ARESETN_I */ DEF_RST(11, 1, 5, 2), /* GBETH_1_ARESETN_I */ + DEF_RST(12, 5, 5, 22), /* CRU_0_PRESETN */ + DEF_RST(12, 6, 5, 23), /* CRU_0_ARESETN */ + DEF_RST(12, 7, 5, 24), /* CRU_0_S_RESETN */ + DEF_RST(12, 8, 5, 25), /* CRU_1_PRESETN */ + DEF_RST(12, 9, 5, 26), /* CRU_1_ARESETN */ + DEF_RST(12, 10, 5, 27), /* CRU_1_S_RESETN */ + DEF_RST(13, 1, 6, 2), /* ISP_0_VIN_ARESETN */ + DEF_RST(13, 2, 6, 3), /* ISP_0_REG_ARESETN */ + DEF_RST(13, 3, 6, 4), /* ISP_0_ISP_SRESETN */ + DEF_RST(13, 4, 6, 5), /* ISP_0_PRESETN */ + DEF_RST(13, 7, 6, 8), /* DSI_0_PRESETN */ + DEF_RST(13, 8, 6, 9), /* DSI_0_ARESETN */ + DEF_RST(13, 12, 6, 13), /* LCDC_0_RESET_N */ DEF_RST(13, 13, 6, 14), /* GPU_0_RESETN */ DEF_RST(13, 14, 6, 15), /* GPU_0_AXI_RESETN */ DEF_RST(13, 15, 6, 16), /* GPU_0_ACE_RESETN */ diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c index 6389c4b6a5231..400d9e94f2e9f 100644 --- a/drivers/clk/renesas/r9a09g057-cpg.c +++ b/drivers/clk/renesas/r9a09g057-cpg.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -16,7 +17,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G057_SPI_CLK_SPI, + LAST_DT_CORE_CLK = R9A09G057_USB3_1_CLKCORE, /* External Input Clocks */ CLK_AUDIO_EXTAL, @@ -30,6 +31,7 @@ enum clk_ids { CLK_PLLCA55, CLK_PLLVDO, CLK_PLLETH, + CLK_PLLDSI, CLK_PLLGPU, /* Internal Core Clocks */ @@ -55,6 +57,7 @@ enum clk_ids { CLK_PLLVDO_CRU1, CLK_PLLVDO_CRU2, CLK_PLLVDO_CRU3, + CLK_PLLVDO_ISP, CLK_PLLETH_DIV_250_FIX, CLK_PLLETH_DIV_125_FIX, CLK_CSDIV_PLLETH_GBE0, @@ -63,6 +66,9 @@ enum clk_ids { CLK_SMUX2_GBE0_RXCLK, CLK_SMUX2_GBE1_TXCLK, CLK_SMUX2_GBE1_RXCLK, + CLK_CDIV4_PLLETH_LPCLK, + CLK_PLLETH_LPCLK_GEAR, + CLK_PLLDSI_GEAR, CLK_PLLGPU_GEAR, /* Module Clocks */ @@ -91,6 +97,26 @@ static const struct clk_div_table dtable_2_16[] = { {0, 0}, }; +static const struct clk_div_table dtable_2_32[] = { + {0, 2}, + {1, 4}, + {2, 6}, + {3, 8}, + {4, 10}, + {5, 12}, + {6, 14}, + {7, 16}, + {8, 18}, + {9, 20}, + {10, 22}, + {11, 24}, + {12, 26}, + {13, 28}, + {14, 30}, + {15, 32}, + {0, 0}, +}; + static const struct clk_div_table dtable_2_64[] = { {0, 2}, {1, 4}, @@ -107,6 +133,17 @@ static const struct clk_div_table dtable_2_100[] = { {0, 0}, }; +static const struct clk_div_table dtable_16_128[] = { + {0, 16}, + {1, 32}, + {2, 64}, + {3, 128}, + {0, 0}, +}; + +RZV2H_CPG_PLL_DSI_LIMITS(rzv2h_cpg_pll_dsi_limits); +#define PLLDSI PLL_PACK_LIMITS(0xc0, 1, 0, &rzv2h_cpg_pll_dsi_limits) + /* Mux clock tables */ static const char * const smux2_gbe0_rxclk[] = { ".plleth_gbe0", "et0_rxclk" }; static const char * const smux2_gbe0_txclk[] = { ".plleth_gbe0", "et0_txclk" }; @@ -128,6 +165,7 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { DEF_PLL(".pllca55", CLK_PLLCA55, CLK_QEXTAL, PLLCA55), DEF_FIXED(".pllvdo", CLK_PLLVDO, CLK_QEXTAL, 105, 2), DEF_FIXED(".plleth", CLK_PLLETH, CLK_QEXTAL, 125, 3), + DEF_PLLDSI(".plldsi", CLK_PLLDSI, CLK_QEXTAL, PLLDSI), DEF_PLL(".pllgpu", CLK_PLLGPU, CLK_QEXTAL, PLLGPU), /* Internal Core Clocks */ @@ -157,6 +195,7 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { DEF_DDIV(".pllvdo_cru1", CLK_PLLVDO_CRU1, CLK_PLLVDO, CDDIV4_DIVCTL0, dtable_2_4), DEF_DDIV(".pllvdo_cru2", CLK_PLLVDO_CRU2, CLK_PLLVDO, CDDIV4_DIVCTL1, dtable_2_4), DEF_DDIV(".pllvdo_cru3", CLK_PLLVDO_CRU3, CLK_PLLVDO, CDDIV4_DIVCTL2, dtable_2_4), + DEF_DDIV(".pllvdo_isp", CLK_PLLVDO_ISP, CLK_PLLVDO, CDDIV2_DIVCTL3, dtable_2_64), DEF_FIXED(".plleth_250_fix", CLK_PLLETH_DIV_250_FIX, CLK_PLLETH, 1, 4), DEF_FIXED(".plleth_125_fix", CLK_PLLETH_DIV_125_FIX, CLK_PLLETH_DIV_250_FIX, 1, 2), @@ -168,6 +207,12 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { DEF_SMUX(".smux2_gbe0_rxclk", CLK_SMUX2_GBE0_RXCLK, SSEL0_SELCTL3, smux2_gbe0_rxclk), DEF_SMUX(".smux2_gbe1_txclk", CLK_SMUX2_GBE1_TXCLK, SSEL1_SELCTL0, smux2_gbe1_txclk), DEF_SMUX(".smux2_gbe1_rxclk", CLK_SMUX2_GBE1_RXCLK, SSEL1_SELCTL1, smux2_gbe1_rxclk), + DEF_FIXED(".cdiv4_plleth_lpclk", CLK_CDIV4_PLLETH_LPCLK, CLK_PLLETH, 1, 4), + DEF_CSDIV(".plleth_lpclk_gear", CLK_PLLETH_LPCLK_GEAR, CLK_CDIV4_PLLETH_LPCLK, + CSDIV0_DIVCTL2, dtable_16_128), + + DEF_PLLDSI_DIV(".plldsi_gear", CLK_PLLDSI_GEAR, CLK_PLLDSI, + CSDIV1_DIVCTL2, dtable_2_32), DEF_DDIV(".pllgpu_gear", CLK_PLLGPU_GEAR, CLK_PLLGPU, CDDIV3_DIVCTL1, dtable_2_64), @@ -190,6 +235,10 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { CLK_PLLETH_DIV_125_FIX, 1, 1), DEF_FIXED_MOD_STATUS("spi_clk_spi", R9A09G057_SPI_CLK_SPI, CLK_PLLCM33_XSPI, 1, 2, FIXED_MOD_CONF_XSPI), + DEF_FIXED("usb3_0_ref_alt_clk_p", R9A09G057_USB3_0_REF_ALT_CLK_P, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb3_0_core_clk", R9A09G057_USB3_0_CLKCORE, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb3_1_ref_alt_clk_p", R9A09G057_USB3_1_REF_ALT_CLK_P, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb3_1_core_clk", R9A09G057_USB3_1_CLKCORE, CLK_QEXTAL, 1, 1), }; static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { @@ -239,6 +288,8 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(5, BIT(13))), DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18, BUS_MSTOP(5, BIT(13))), + DEF_MOD("rtc_0_clk_rtc", CLK_PLLCM33_DIV16, 5, 3, 2, 19, + BUS_MSTOP(3, BIT(11) | BIT(12))), DEF_MOD("rspi_0_pclk", CLK_PLLCLN_DIV8, 5, 4, 2, 20, BUS_MSTOP(11, BIT(0))), DEF_MOD("rspi_0_pclk_sfr", CLK_PLLCLN_DIV8, 5, 5, 2, 21, @@ -313,6 +364,14 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(8, BIT(4))), DEF_MOD("sdhi_2_aclk", CLK_PLLDTY_ACPU_DIV4, 10, 14, 5, 14, BUS_MSTOP(8, BIT(4))), + DEF_MOD("usb3_0_aclk", CLK_PLLDTY_DIV8, 10, 15, 5, 15, + BUS_MSTOP(7, BIT(12))), + DEF_MOD("usb3_0_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 0, 5, 16, + BUS_MSTOP(7, BIT(14))), + DEF_MOD("usb3_1_aclk", CLK_PLLDTY_DIV8, 11, 1, 5, 17, + BUS_MSTOP(7, BIT(13))), + DEF_MOD("usb3_1_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 2, 5, 18, + BUS_MSTOP(7, BIT(15))), DEF_MOD("usb2_0_u2h0_hclk", CLK_PLLDTY_DIV8, 11, 3, 5, 19, BUS_MSTOP(7, BIT(7))), DEF_MOD("usb2_0_u2h1_hclk", CLK_PLLDTY_DIV8, 11, 4, 5, 20, @@ -371,12 +430,40 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(9, BIT(7))), DEF_MOD("cru_3_pclk", CLK_PLLDTY_DIV16, 13, 13, 6, 29, BUS_MSTOP(9, BIT(7))), + DEF_MOD("isp_0_reg_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 2, 7, 2, + BUS_MSTOP(9, BIT(8))), + DEF_MOD("isp_0_pclk", CLK_PLLDTY_DIV16, 14, 3, 7, 3, + BUS_MSTOP(9, BIT(8))), + DEF_MOD("isp_0_vin_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 4, 7, 4, + BUS_MSTOP(9, BIT(9))), + DEF_MOD("isp_0_isp_sclk", CLK_PLLVDO_ISP, 14, 5, 7, 5, + BUS_MSTOP(9, BIT(9))), + DEF_MOD("dsi_0_pclk", CLK_PLLDTY_DIV16, 14, 8, 7, 8, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 9, 7, 9, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_vclk1", CLK_PLLDSI_GEAR, 14, 10, 7, 10, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_lpclk", CLK_PLLETH_LPCLK_GEAR, 14, 11, 7, 11, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_pllref_clk", CLK_QEXTAL, 14, 12, 7, 12, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("lcdc_0_clk_a", CLK_PLLDTY_ACPU_DIV2, 14, 13, 7, 13, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), + DEF_MOD("lcdc_0_clk_p", CLK_PLLDTY_DIV16, 14, 14, 7, 14, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), + DEF_MOD("lcdc_0_clk_d", CLK_PLLDSI_GEAR, 14, 15, 7, 15, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), DEF_MOD("gpu_0_clk", CLK_PLLGPU_GEAR, 15, 0, 7, 16, BUS_MSTOP(3, BIT(4))), DEF_MOD("gpu_0_axi_clk", CLK_PLLDTY_ACPU_DIV2, 15, 1, 7, 17, BUS_MSTOP(3, BIT(4))), DEF_MOD("gpu_0_ace_clk", CLK_PLLDTY_ACPU_DIV2, 15, 2, 7, 18, BUS_MSTOP(3, BIT(4))), + DEF_MOD("tsu_0_pclk", CLK_QEXTAL, 16, 9, 8, 9, + BUS_MSTOP(5, BIT(2))), + DEF_MOD("tsu_1_pclk", CLK_QEXTAL, 16, 10, 8, 10, + BUS_MSTOP(2, BIT(15))), }; static const struct rzv2h_reset r9a09g057_resets[] __initconst = { @@ -401,6 +488,8 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */ DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ + DEF_RST(7, 9, 3, 10), /* RTC_0_RST_RTC */ + DEF_RST(7, 10, 3, 11), /* RTC_0_RST_RTC_V */ DEF_RST(7, 11, 3, 12), /* RSPI_0_PRESETN */ DEF_RST(7, 12, 3, 13), /* RSPI_0_TRESETN */ DEF_RST(7, 13, 3, 14), /* RSPI_1_PRESETN */ @@ -424,6 +513,8 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */ DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */ DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */ + DEF_RST(10, 10, 4, 27), /* USB3_0_ARESETN */ + DEF_RST(10, 11, 4, 28), /* USB3_1_ARESETN */ DEF_RST(10, 12, 4, 29), /* USB2_0_U2H0_HRESETN */ DEF_RST(10, 13, 4, 30), /* USB2_0_U2H1_HRESETN */ DEF_RST(10, 14, 4, 31), /* USB2_0_U2P_EXL_SYSRST */ @@ -442,9 +533,18 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(12, 14, 5, 31), /* CRU_3_PRESETN */ DEF_RST(12, 15, 6, 0), /* CRU_3_ARESETN */ DEF_RST(13, 0, 6, 1), /* CRU_3_S_RESETN */ + DEF_RST(13, 1, 6, 2), /* ISP_0_VIN_ARESETN */ + DEF_RST(13, 2, 6, 3), /* ISP_0_REG_ARESETN */ + DEF_RST(13, 3, 6, 4), /* ISP_0_ISP_SRESETN */ + DEF_RST(13, 4, 6, 5), /* ISP_0_PRESETN */ + DEF_RST(13, 7, 6, 8), /* DSI_0_PRESETN */ + DEF_RST(13, 8, 6, 9), /* DSI_0_ARESETN */ + DEF_RST(13, 12, 6, 13), /* LCDC_0_RESET_N */ DEF_RST(13, 13, 6, 14), /* GPU_0_RESETN */ DEF_RST(13, 14, 6, 15), /* GPU_0_AXI_RESETN */ DEF_RST(13, 15, 6, 16), /* GPU_0_ACE_RESETN */ + DEF_RST(15, 7, 7, 8), /* TSU_0_PRESETN */ + DEF_RST(15, 8, 7, 9), /* TSU_1_PRESETN */ }; const struct rzv2h_cpg_info r9a09g057_cpg_info __initconst = { diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index af3ef6d58c87c..fb6cc94d08a11 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -46,8 +46,12 @@ #define DIVCA55C2 CONF_PACK(SCKCR2, 10, 1) #define DIVCA55C3 CONF_PACK(SCKCR2, 11, 1) #define DIVCA55S CONF_PACK(SCKCR2, 12, 1) +#define DIVSPI3ASYNC CONF_PACK(SCKCR2, 16, 2) #define DIVSCI5ASYNC CONF_PACK(SCKCR2, 18, 2) +#define DIVSPI0ASYNC CONF_PACK(SCKCR3, 0, 2) +#define DIVSPI1ASYNC CONF_PACK(SCKCR3, 2, 2) +#define DIVSPI2ASYNC CONF_PACK(SCKCR3, 4, 2) #define DIVSCI0ASYNC CONF_PACK(SCKCR3, 6, 2) #define DIVSCI1ASYNC CONF_PACK(SCKCR3, 8, 2) #define DIVSCI2ASYNC CONF_PACK(SCKCR3, 10, 2) @@ -56,7 +60,6 @@ #define SEL_PLL CONF_PACK(SCKCR, 22, 1) - enum rzt2h_clk_types { CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */ CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */ @@ -94,6 +97,10 @@ enum clk_ids { CLK_SCI3ASYNC, CLK_SCI4ASYNC, CLK_SCI5ASYNC, + CLK_SPI0ASYNC, + CLK_SPI1ASYNC, + CLK_SPI2ASYNC, + CLK_SPI3ASYNC, /* Module Clocks */ MOD_CLK_BASE, @@ -154,6 +161,15 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { DEF_DIV(".sci5async", CLK_SCI5ASYNC, CLK_PLL4D1, DIVSCI5ASYNC, dtable_24_25_30_32), + DEF_DIV(".spi0async", CLK_SPI0ASYNC, CLK_PLL4D1, DIVSPI0ASYNC, + dtable_24_25_30_32), + DEF_DIV(".spi1async", CLK_SPI1ASYNC, CLK_PLL4D1, DIVSPI1ASYNC, + dtable_24_25_30_32), + DEF_DIV(".spi2async", CLK_SPI2ASYNC, CLK_PLL4D1, DIVSPI2ASYNC, + dtable_24_25_30_32), + DEF_DIV(".spi3async", CLK_SPI3ASYNC, CLK_PLL4D1, DIVSPI3ASYNC, + dtable_24_25_30_32), + /* Core output clk */ DEF_DIV("CA55C0", R9A09G077_CLK_CA55C0, CLK_SEL_CLK_PLL0, DIVCA55C0, dtable_1_2), @@ -188,6 +204,13 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("sci4fck", 12, CLK_SCI4ASYNC), DEF_MOD("iic0", 100, R9A09G077_CLK_PCLKL), DEF_MOD("iic1", 101, R9A09G077_CLK_PCLKL), + DEF_MOD("spi0", 104, CLK_SPI0ASYNC), + DEF_MOD("spi1", 105, CLK_SPI1ASYNC), + DEF_MOD("spi2", 106, CLK_SPI2ASYNC), + DEF_MOD("adc0", 206, R9A09G077_CLK_PCLKH), + DEF_MOD("adc1", 207, R9A09G077_CLK_PCLKH), + DEF_MOD("adc2", 225, R9A09G077_CLK_PCLKM), + DEF_MOD("tsu", 307, R9A09G077_CLK_PCLKL), DEF_MOD("gmac0", 400, R9A09G077_CLK_PCLKM), DEF_MOD("ethsw", 401, R9A09G077_CLK_PCLKM), DEF_MOD("ethss", 403, R9A09G077_CLK_PCLKM), @@ -196,6 +219,7 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("gmac2", 417, R9A09G077_CLK_PCLKAM), DEF_MOD("sci5fck", 600, CLK_SCI5ASYNC), DEF_MOD("iic2", 601, R9A09G077_CLK_PCLKL), + DEF_MOD("spi3", 602, CLK_SPI3ASYNC), DEF_MOD("sdhi0", 1212, R9A09G077_CLK_PCLKAM), DEF_MOD("sdhi1", 1213, R9A09G077_CLK_PCLKAM), }; @@ -216,27 +240,28 @@ r9a09g077_cpg_div_clk_register(struct device *dev, parent_name = __clk_get_name(parent); if (core->dtable) - clk_hw = clk_hw_register_divider_table(dev, core->name, - parent_name, 0, - addr, - GET_SHIFT(core->conf), - GET_WIDTH(core->conf), - core->flag, - core->dtable, - &pub->rmw_lock); + clk_hw = devm_clk_hw_register_divider_table(dev, core->name, + parent_name, + CLK_SET_RATE_PARENT, + addr, + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, + core->dtable, + &pub->rmw_lock); else - clk_hw = clk_hw_register_divider(dev, core->name, - parent_name, 0, - addr, - GET_SHIFT(core->conf), - GET_WIDTH(core->conf), - core->flag, &pub->rmw_lock); + clk_hw = devm_clk_hw_register_divider(dev, core->name, + parent_name, + CLK_SET_RATE_PARENT, + addr, + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, &pub->rmw_lock); if (IS_ERR(clk_hw)) return ERR_CAST(clk_hw); return clk_hw->clk; - } static struct clk * __init diff --git a/drivers/clk/renesas/rcar-cpg-lib.c b/drivers/clk/renesas/rcar-cpg-lib.c index a45f8e7e9ab67..7b271de7037a1 100644 --- a/drivers/clk/renesas/rcar-cpg-lib.c +++ b/drivers/clk/renesas/rcar-cpg-lib.c @@ -35,7 +35,7 @@ void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set) val |= set; writel(val, reg); spin_unlock_irqrestore(&cpg_lock, flags); -}; +} static int cpg_simple_notifier_call(struct notifier_block *nb, unsigned long action, void *data) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 10ae20489df9a..b954278ddd9d8 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -54,10 +54,8 @@ static unsigned long cpg_pll_clk_recalc_rate(struct clk_hw *hw, { struct cpg_pll_clk *pll_clk = to_pll_clk(hw); unsigned int mult; - u32 val; - val = readl(pll_clk->pllcr_reg) & CPG_PLLnCR_STC_MASK; - mult = (val >> __ffs(CPG_PLLnCR_STC_MASK)) + 1; + mult = FIELD_GET(CPG_PLLnCR_STC_MASK, readl(pll_clk->pllcr_reg)) + 1; return parent_rate * mult * pll_clk->fixed_mult; } @@ -94,7 +92,7 @@ static int cpg_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, val = readl(pll_clk->pllcr_reg); val &= ~CPG_PLLnCR_STC_MASK; - val |= (mult - 1) << __ffs(CPG_PLLnCR_STC_MASK); + val |= FIELD_PREP(CPG_PLLnCR_STC_MASK, mult - 1); writel(val, pll_clk->pllcr_reg); for (i = 1000; i; i--) { @@ -176,11 +174,7 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct cpg_z_clk *zclk = to_z_clk(hw); - unsigned int mult; - u32 val; - - val = readl(zclk->reg) & zclk->mask; - mult = 32 - (val >> __ffs(zclk->mask)); + unsigned int mult = 32 - field_get(zclk->mask, readl(zclk->reg)); return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, 32 * zclk->fixed_div); @@ -231,7 +225,8 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) return -EBUSY; - cpg_reg_modify(zclk->reg, zclk->mask, (32 - mult) << __ffs(zclk->mask)); + cpg_reg_modify(zclk->reg, zclk->mask, + field_prep(zclk->mask, 32 - mult)); /* * Set KICK bit in FRQCRB to update hardware setting and wait for diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c index fb9a876aaba5c..ac2b5afec46df 100644 --- a/drivers/clk/renesas/rcar-gen4-cpg.c +++ b/drivers/clk/renesas/rcar-gen4-cpg.c @@ -257,7 +257,7 @@ static struct clk * __init cpg_pll_clk_register(const char *name, } /* - * Z0 Clock & Z1 Clock + * Z0, Z1 and ZG Clock */ #define CPG_FRQCRB 0x00000804 #define CPG_FRQCRB_KICK BIT(31) @@ -279,11 +279,7 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct cpg_z_clk *zclk = to_z_clk(hw); - unsigned int mult; - u32 val; - - val = readl(zclk->reg) & zclk->mask; - mult = 32 - (val >> __ffs(zclk->mask)); + unsigned int mult = 32 - field_get(zclk->mask, readl(zclk->reg)); return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, 32 * zclk->fixed_div); @@ -334,7 +330,8 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) return -EBUSY; - cpg_reg_modify(zclk->reg, zclk->mask, (32 - mult) << __ffs(zclk->mask)); + cpg_reg_modify(zclk->reg, zclk->mask, + field_prep(zclk->mask, 32 - mult)); /* * Set KICK bit in FRQCRB to update hardware setting and wait for @@ -389,9 +386,14 @@ static struct clk * __init cpg_z_clk_register(const char *name, if (offset < 32) { zclk->reg = reg + CPG_FRQCRC0; - } else { + } else if (offset < 64) { zclk->reg = reg + CPG_FRQCRC1; offset -= 32; + } else if (offset < 96) { + zclk->reg = reg + CPG_FRQCRB; + offset -= 64; + } else { + return ERR_PTR(-EINVAL); } zclk->kick_reg = reg + CPG_FRQCRB; zclk->hw.init = &init; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index de1cf7ba45b78..7f9b7aa397906 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -40,8 +40,10 @@ #define WARN_DEBUG(x) do { } while (0) #endif +#define RZT2H_RESET_REG_READ_COUNT 7 + /* - * Module Standby and Software Reset register offets. + * Module Standby and Software Reset register offsets. * * If the registers exist, these are valid for SH-Mobile, R-Mobile, * R-Car Gen2, R-Car Gen3, and RZ/G1. @@ -137,6 +139,22 @@ static const u16 srcr_for_gen4[] = { 0x2C60, 0x2C64, 0x2C68, 0x2C6C, 0x2C70, 0x2C74, }; +static const u16 mrcr_for_rzt2h[] = { + 0x240, /* MRCTLA */ + 0x244, /* Reserved */ + 0x248, /* Reserved */ + 0x24C, /* Reserved */ + 0x250, /* MRCTLE */ + 0x254, /* Reserved */ + 0x258, /* Reserved */ + 0x25C, /* Reserved */ + 0x260, /* MRCTLI */ + 0x264, /* Reserved */ + 0x268, /* Reserved */ + 0x26C, /* Reserved */ + 0x270, /* MRCTLM */ +}; + /* * Software Reset Clearing Register offsets */ @@ -290,9 +308,20 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); - if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A || - priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) + if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A) + return 0; + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { + /* + * For the RZ/T2H case, it is necessary to perform a read-back after + * accessing the MSTPCRm register and to dummy-read any register of + * the IP at least seven times. Instead of memory-mapping the IP + * register, we simply add a delay after the read operation. + */ + cpg_rzt2h_mstp_read(hw, priv->control_regs[reg]); + udelay(10); return 0; + } error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg], value, !(value & bitmask), 0, 10); @@ -451,7 +480,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, break; } - if (IS_ERR_OR_NULL(clk)) + if (IS_ERR(clk)) goto fail; dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); @@ -676,64 +705,133 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, #define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev) -static int cpg_mssr_reset(struct reset_controller_dev *rcdev, - unsigned long id) +static int cpg_mssr_reset_operate(struct reset_controller_dev *rcdev, + const char *func, bool set, unsigned long id) { struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); unsigned int reg = id / 32; unsigned int bit = id % 32; + const u16 off = set ? priv->reset_regs[reg] : priv->reset_clear_regs[reg]; u32 bitmask = BIT(bit); - dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); + if (func) + dev_dbg(priv->dev, "%s %u%02u\n", func, reg, bit); + + writel(bitmask, priv->pub.base0 + off); + readl(priv->pub.base0 + off); + barrier_data(priv->pub.base0 + off); + + return 0; +} + +static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); /* Reset module */ - writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); + cpg_mssr_reset_operate(rcdev, "reset", true, id); - /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ - udelay(35); + /* + * On R-Car Gen4, delay after SRCR has been written is 1ms. + * On older SoCs, delay after SRCR has been written is 35us + * (one cycle of the RCLK clock @ ca. 32 kHz). + */ + if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) + usleep_range(1000, 2000); + else + usleep_range(35, 1000); /* Release module from reset state */ - writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); - - return 0; + return cpg_mssr_reset_operate(rcdev, NULL, false, id); } static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) +{ + return cpg_mssr_reset_operate(rcdev, "assert", true, id); +} + +static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return cpg_mssr_reset_operate(rcdev, "deassert", false, id); +} + +static int cpg_mssr_status(struct reset_controller_dev *rcdev, + unsigned long id) { struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); unsigned int reg = id / 32; unsigned int bit = id % 32; u32 bitmask = BIT(bit); - dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); - - writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); - return 0; + return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask); } -static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, - unsigned long id) +static int cpg_mrcr_set_reset_state(struct reset_controller_dev *rcdev, + unsigned long id, bool set) { struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); unsigned int reg = id / 32; unsigned int bit = id % 32; u32 bitmask = BIT(bit); + void __iomem *reg_addr; + unsigned long flags; + unsigned int i; + u32 val; + + dev_dbg(priv->dev, "%s %u%02u\n", set ? "assert" : "deassert", reg, bit); + + spin_lock_irqsave(&priv->pub.rmw_lock, flags); + + reg_addr = priv->pub.base0 + priv->reset_regs[reg]; + /* Read current value and modify */ + val = readl(reg_addr); + if (set) + val |= bitmask; + else + val &= ~bitmask; + writel(val, reg_addr); - dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); + /* + * For secure processing after release from a module reset, one must + * perform multiple dummy reads of the same register. + */ + for (i = 0; !set && i < RZT2H_RESET_REG_READ_COUNT; i++) + readl(reg_addr); + + /* Verify the operation */ + val = readl(reg_addr); + if (set == !(bitmask & val)) { + dev_err(priv->dev, "Reset register %u%02u operation failed\n", reg, bit); + spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); + return -EIO; + } + + spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); - writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); return 0; } -static int cpg_mssr_status(struct reset_controller_dev *rcdev, - unsigned long id) +static int cpg_mrcr_reset(struct reset_controller_dev *rcdev, unsigned long id) { - struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); - unsigned int reg = id / 32; - unsigned int bit = id % 32; - u32 bitmask = BIT(bit); + int ret; - return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask); + ret = cpg_mrcr_set_reset_state(rcdev, id, true); + if (ret) + return ret; + + return cpg_mrcr_set_reset_state(rcdev, id, false); +} + +static int cpg_mrcr_assert(struct reset_controller_dev *rcdev, unsigned long id) +{ + return cpg_mrcr_set_reset_state(rcdev, id, true); +} + +static int cpg_mrcr_deassert(struct reset_controller_dev *rcdev, unsigned long id) +{ + return cpg_mrcr_set_reset_state(rcdev, id, false); } static const struct reset_control_ops cpg_mssr_reset_ops = { @@ -743,6 +841,13 @@ static const struct reset_control_ops cpg_mssr_reset_ops = { .status = cpg_mssr_status, }; +static const struct reset_control_ops cpg_mrcr_reset_ops = { + .reset = cpg_mrcr_reset, + .assert = cpg_mrcr_assert, + .deassert = cpg_mrcr_deassert, + .status = cpg_mssr_status, +}; + static int cpg_mssr_reset_xlate(struct reset_controller_dev *rcdev, const struct of_phandle_args *reset_spec) { @@ -760,11 +865,23 @@ static int cpg_mssr_reset_xlate(struct reset_controller_dev *rcdev, static int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv) { - priv->rcdev.ops = &cpg_mssr_reset_ops; + /* + * RZ/T2H (and family) has the Module Reset Control Registers + * which allows control resets of certain modules. + * The number of resets is not equal to the number of module clocks. + */ + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { + priv->rcdev.ops = &cpg_mrcr_reset_ops; + priv->rcdev.nr_resets = ARRAY_SIZE(mrcr_for_rzt2h) * 32; + } else { + priv->rcdev.ops = &cpg_mssr_reset_ops; + priv->rcdev.nr_resets = priv->num_mod_clks; + } + priv->rcdev.of_node = priv->dev->of_node; priv->rcdev.of_reset_n_cells = 1; priv->rcdev.of_xlate = cpg_mssr_reset_xlate; - priv->rcdev.nr_resets = priv->num_mod_clks; + return devm_reset_controller_register(priv->dev, &priv->rcdev); } @@ -1169,6 +1286,7 @@ static int __init cpg_mssr_common_init(struct device *dev, priv->control_regs = stbcr; } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { priv->control_regs = mstpcr_for_rzt2h; + priv->reset_regs = mrcr_for_rzt2h; } else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) { priv->status_regs = mstpsr_for_gen4; priv->control_regs = mstpcr_for_gen4; @@ -1265,8 +1383,7 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) goto reserve_exit; /* Reset Controller not supported for Standby Control SoCs */ - if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A || - priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) goto reserve_exit; error = cpg_mssr_reset_controller_register(priv); diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 07909e80bae24..64d1ef6e4c943 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -1177,7 +1177,7 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, goto fail; } - if (IS_ERR_OR_NULL(clk)) + if (IS_ERR(clk)) goto fail; dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index 2197d1d2453a3..3f6299b9fec05 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -14,9 +14,14 @@ #include #include #include +#include #include #include #include +#include +#include +#include +#include #include #include #include @@ -26,6 +31,7 @@ #include #include #include +#include #include @@ -47,13 +53,15 @@ #define CPG_PLL_STBY(x) ((x)) #define CPG_PLL_STBY_RESETB BIT(0) +#define CPG_PLL_STBY_SSC_EN BIT(2) #define CPG_PLL_STBY_RESETB_WEN BIT(16) +#define CPG_PLL_STBY_SSC_EN_WEN BIT(18) #define CPG_PLL_CLK1(x) ((x) + 0x004) -#define CPG_PLL_CLK1_KDIV(x) ((s16)FIELD_GET(GENMASK(31, 16), (x))) -#define CPG_PLL_CLK1_MDIV(x) FIELD_GET(GENMASK(15, 6), (x)) -#define CPG_PLL_CLK1_PDIV(x) FIELD_GET(GENMASK(5, 0), (x)) +#define CPG_PLL_CLK1_KDIV GENMASK(31, 16) +#define CPG_PLL_CLK1_MDIV GENMASK(15, 6) +#define CPG_PLL_CLK1_PDIV GENMASK(5, 0) #define CPG_PLL_CLK2(x) ((x) + 0x008) -#define CPG_PLL_CLK2_SDIV(x) FIELD_GET(GENMASK(2, 0), (x)) +#define CPG_PLL_CLK2_SDIV GENMASK(2, 0) #define CPG_PLL_MON(x) ((x) + 0x010) #define CPG_PLL_MON_RESETB BIT(0) #define CPG_PLL_MON_LOCK BIT(4) @@ -65,6 +73,22 @@ #define CPG_CLKSTATUS0 (0x700) +/* On RZ/G3E SoC we have two DSI PLLs */ +#define MAX_CPG_DSI_PLL 2 + +/** + * struct rzv2h_pll_dsi_info - PLL DSI information, holds the limits and parameters + * + * @pll_dsi_limits: PLL DSI parameters limits + * @pll_dsi_parameters: Calculated PLL DSI parameters + * @req_pll_dsi_rate: Requested PLL DSI rate + */ +struct rzv2h_pll_dsi_info { + const struct rzv2h_pll_limits *pll_dsi_limits; + struct rzv2h_pll_div_pars pll_dsi_parameters; + unsigned long req_pll_dsi_rate; +}; + /** * struct rzv2h_cpg_priv - Clock Pulse Generator Private Data * @@ -80,6 +104,7 @@ * @ff_mod_status_ops: Fixed Factor Module Status Clock operations * @mstop_count: Array of mstop values * @rcdev: Reset controller entity + * @pll_dsi_info: Array of PLL DSI information, holds the limits and parameters */ struct rzv2h_cpg_priv { struct device *dev; @@ -98,6 +123,8 @@ struct rzv2h_cpg_priv { atomic_t *mstop_count; struct reset_controller_dev rcdev; + + struct rzv2h_pll_dsi_info pll_dsi_info[MAX_CPG_DSI_PLL]; }; #define rcdev_to_priv(x) container_of(x, struct rzv2h_cpg_priv, rcdev) @@ -168,6 +195,460 @@ struct rzv2h_ff_mod_status_clk { #define to_rzv2h_ff_mod_status_clk(_hw) \ container_of(_hw, struct rzv2h_ff_mod_status_clk, fix.hw) +/** + * struct rzv2h_plldsi_div_clk - PLL DSI DDIV clock + * + * @dtable: divider table + * @priv: CPG private data + * @hw: divider clk + * @ddiv: divider configuration + */ +struct rzv2h_plldsi_div_clk { + const struct clk_div_table *dtable; + struct rzv2h_cpg_priv *priv; + struct clk_hw hw; + struct ddiv ddiv; +}; + +#define to_plldsi_div_clk(_hw) \ + container_of(_hw, struct rzv2h_plldsi_div_clk, hw) + +#define RZ_V2H_OSC_CLK_IN_MEGA (24 * MEGA) +#define RZV2H_MAX_DIV_TABLES (16) + +/** + * rzv2h_get_pll_pars - Finds the best combination of PLL parameters + * for a given frequency. + * + * @limits: Pointer to the structure containing the limits for the PLL parameters + * @pars: Pointer to the structure where the best calculated PLL parameters values + * will be stored + * @freq_millihz: Target output frequency in millihertz + * + * This function calculates the best set of PLL parameters (M, K, P, S) to achieve + * the desired frequency. + * There is no direct formula to calculate the PLL parameters, as it's an open + * system of equations, therefore this function uses an iterative approach to + * determine the best solution. The best solution is one that minimizes the error + * (desired frequency - actual frequency). + * + * Return: true if a valid set of parameters values is found, false otherwise. + */ +bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_pars *pars, u64 freq_millihz) +{ + u64 fout_min_millihz = mul_u32_u32(limits->fout.min, MILLI); + u64 fout_max_millihz = mul_u32_u32(limits->fout.max, MILLI); + struct rzv2h_pll_pars p, best; + + if (freq_millihz > fout_max_millihz || + freq_millihz < fout_min_millihz) + return false; + + /* Initialize best error to maximum possible value */ + best.error_millihz = S64_MAX; + + for (p.p = limits->p.min; p.p <= limits->p.max; p.p++) { + u32 fref = RZ_V2H_OSC_CLK_IN_MEGA / p.p; + u16 divider; + + for (divider = 1 << limits->s.min, p.s = limits->s.min; + p.s <= limits->s.max; p.s++, divider <<= 1) { + for (p.m = limits->m.min; p.m <= limits->m.max; p.m++) { + u64 output_m, output_k_range; + s64 pll_k, output_k; + u64 fvco, output; + + /* + * The frequency generated by the PLL + divider + * is calculated as follows: + * + * With: + * Freq = Ffout = Ffvco / 2^(pll_s) + * Ffvco = (pll_m + (pll_k / 65536)) * Ffref + * Ffref = 24MHz / pll_p + * + * Freq can also be rewritten as: + * Freq = Ffvco / 2^(pll_s) + * = ((pll_m + (pll_k / 65536)) * Ffref) / 2^(pll_s) + * = (pll_m * Ffref) / 2^(pll_s) + ((pll_k / 65536) * Ffref) / 2^(pll_s) + * = output_m + output_k + * + * Every parameter has been determined at this + * point, but pll_k. + * + * Considering that: + * limits->k.min <= pll_k <= limits->k.max + * Then: + * -0.5 <= (pll_k / 65536) < 0.5 + * Therefore: + * -Ffref / (2 * 2^(pll_s)) <= output_k < Ffref / (2 * 2^(pll_s)) + */ + + /* Compute output M component (in mHz) */ + output_m = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(p.m, fref) * MILLI, + divider); + /* Compute range for output K (in mHz) */ + output_k_range = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(fref, MILLI), + 2 * divider); + /* + * No point in continuing if we can't achieve + * the desired frequency + */ + if (freq_millihz < (output_m - output_k_range) || + freq_millihz >= (output_m + output_k_range)) { + continue; + } + + /* + * Compute the K component + * + * Since: + * Freq = output_m + output_k + * Then: + * output_k = Freq - output_m + * = ((pll_k / 65536) * Ffref) / 2^(pll_s) + * Therefore: + * pll_k = (output_k * 65536 * 2^(pll_s)) / Ffref + */ + output_k = freq_millihz - output_m; + pll_k = div_s64(output_k * 65536ULL * divider, + fref); + pll_k = DIV_S64_ROUND_CLOSEST(pll_k, MILLI); + + /* Validate K value within allowed limits */ + if (pll_k < limits->k.min || + pll_k > limits->k.max) + continue; + + p.k = pll_k; + + /* Compute (Ffvco * 65536) */ + fvco = mul_u32_u32(p.m * 65536 + p.k, fref); + if (fvco < mul_u32_u32(limits->fvco.min, 65536) || + fvco > mul_u32_u32(limits->fvco.max, 65536)) + continue; + + /* PLL_M component of (output * 65536 * PLL_P) */ + output = mul_u32_u32(p.m * 65536, RZ_V2H_OSC_CLK_IN_MEGA); + /* PLL_K component of (output * 65536 * PLL_P) */ + output += p.k * RZ_V2H_OSC_CLK_IN_MEGA; + /* Make it in mHz */ + output *= MILLI; + output = DIV_U64_ROUND_CLOSEST(output, 65536 * p.p * divider); + + /* Check output frequency against limits */ + if (output < fout_min_millihz || + output > fout_max_millihz) + continue; + + p.error_millihz = freq_millihz - output; + p.freq_millihz = output; + + /* If an exact match is found, return immediately */ + if (p.error_millihz == 0) { + *pars = p; + return true; + } + + /* Update best match if error is smaller */ + if (abs(best.error_millihz) > abs(p.error_millihz)) + best = p; + } + } + } + + /* If no valid parameters were found, return false */ + if (best.error_millihz == S64_MAX) + return false; + + *pars = best; + return true; +} +EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_pars, "RZV2H_CPG"); + +/* + * rzv2h_get_pll_divs_pars - Finds the best combination of PLL parameters + * and divider value for a given frequency. + * + * @limits: Pointer to the structure containing the limits for the PLL parameters + * @pars: Pointer to the structure where the best calculated PLL parameters and + * divider values will be stored + * @table: Pointer to the array of valid divider values + * @table_size: Size of the divider values array + * @freq_millihz: Target output frequency in millihertz + * + * This function calculates the best set of PLL parameters (M, K, P, S) and divider + * value to achieve the desired frequency. See rzv2h_get_pll_pars() for more details + * on how the PLL parameters are calculated. + * + * freq_millihz is the desired frequency generated by the PLL followed by a + * a gear. + */ +bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_div_pars *pars, + const u8 *table, u8 table_size, u64 freq_millihz) +{ + struct rzv2h_pll_div_pars p, best; + + best.div.error_millihz = S64_MAX; + p.div.error_millihz = S64_MAX; + for (unsigned int i = 0; i < table_size; i++) { + if (!rzv2h_get_pll_pars(limits, &p.pll, freq_millihz * table[i])) + continue; + + p.div.divider_value = table[i]; + p.div.freq_millihz = DIV_U64_ROUND_CLOSEST(p.pll.freq_millihz, table[i]); + p.div.error_millihz = freq_millihz - p.div.freq_millihz; + + if (p.div.error_millihz == 0) { + *pars = p; + return true; + } + + if (abs(best.div.error_millihz) > abs(p.div.error_millihz)) + best = p; + } + + if (best.div.error_millihz == S64_MAX) + return false; + + *pars = best; + return true; +} +EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_divs_pars, "RZV2H_CPG"); + +static unsigned long rzv2h_cpg_plldsi_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw); + struct rzv2h_cpg_priv *priv = dsi_div->priv; + struct ddiv ddiv = dsi_div->ddiv; + u32 div; + + div = readl(priv->base + ddiv.offset); + div >>= ddiv.shift; + div &= clk_div_mask(ddiv.width); + div = dsi_div->dtable[div].div; + + return DIV_ROUND_CLOSEST_ULL(parent_rate, div); +} + +static int rzv2h_cpg_plldsi_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw); + struct pll_clk *pll_clk = to_pll(clk_hw_get_parent(hw)); + struct rzv2h_cpg_priv *priv = dsi_div->priv; + u8 table[RZV2H_MAX_DIV_TABLES] = { 0 }; + struct rzv2h_pll_div_pars *dsi_params; + struct rzv2h_pll_dsi_info *dsi_info; + const struct clk_div_table *div; + unsigned int i = 0; + u64 rate_millihz; + + dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance]; + dsi_params = &dsi_info->pll_dsi_parameters; + + rate_millihz = mul_u32_u32(req->rate, MILLI); + if (rate_millihz == dsi_params->div.error_millihz + dsi_params->div.freq_millihz) + goto exit_determine_rate; + + for (div = dsi_div->dtable; div->div; div++) { + if (i >= RZV2H_MAX_DIV_TABLES) + return -EINVAL; + table[i++] = div->div; + } + + if (!rzv2h_get_pll_divs_pars(dsi_info->pll_dsi_limits, dsi_params, table, i, + rate_millihz)) { + dev_err(priv->dev, "failed to determine rate for req->rate: %lu\n", + req->rate); + return -EINVAL; + } + +exit_determine_rate: + req->rate = DIV_ROUND_CLOSEST_ULL(dsi_params->div.freq_millihz, MILLI); + req->best_parent_rate = req->rate * dsi_params->div.divider_value; + dsi_info->req_pll_dsi_rate = req->best_parent_rate; + + return 0; +} + +static int rzv2h_cpg_plldsi_div_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw); + struct pll_clk *pll_clk = to_pll(clk_hw_get_parent(hw)); + struct rzv2h_cpg_priv *priv = dsi_div->priv; + struct rzv2h_pll_div_pars *dsi_params; + struct rzv2h_pll_dsi_info *dsi_info; + struct ddiv ddiv = dsi_div->ddiv; + const struct clk_div_table *clkt; + bool divider_found = false; + u32 val, shift; + + dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance]; + dsi_params = &dsi_info->pll_dsi_parameters; + + for (clkt = dsi_div->dtable; clkt->div; clkt++) { + if (clkt->div == dsi_params->div.divider_value) { + divider_found = true; + break; + } + } + + if (!divider_found) + return -EINVAL; + + shift = ddiv.shift; + val = readl(priv->base + ddiv.offset) | DDIV_DIVCTL_WEN(shift); + val &= ~(clk_div_mask(ddiv.width) << shift); + val |= clkt->val << shift; + writel(val, priv->base + ddiv.offset); + + return 0; +} + +static const struct clk_ops rzv2h_cpg_plldsi_div_ops = { + .recalc_rate = rzv2h_cpg_plldsi_div_recalc_rate, + .determine_rate = rzv2h_cpg_plldsi_div_determine_rate, + .set_rate = rzv2h_cpg_plldsi_div_set_rate, +}; + +static struct clk * __init +rzv2h_cpg_plldsi_div_clk_register(const struct cpg_core_clk *core, + struct rzv2h_cpg_priv *priv) +{ + struct rzv2h_plldsi_div_clk *clk_hw_data; + struct clk **clks = priv->clks; + struct clk_init_data init; + const struct clk *parent; + const char *parent_name; + struct clk_hw *clk_hw; + int ret; + + parent = clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); + if (!clk_hw_data) + return ERR_PTR(-ENOMEM); + + clk_hw_data->priv = priv; + clk_hw_data->ddiv = core->cfg.ddiv; + clk_hw_data->dtable = core->dtable; + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = &rzv2h_cpg_plldsi_div_ops; + init.flags = core->flag; + init.parent_names = &parent_name; + init.num_parents = 1; + + clk_hw = &clk_hw_data->hw; + clk_hw->init = &init; + + ret = devm_clk_hw_register(priv->dev, clk_hw); + if (ret) + return ERR_PTR(ret); + + return clk_hw->clk; +} + +static int rzv2h_cpg_plldsi_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzv2h_cpg_priv *priv = pll_clk->priv; + struct rzv2h_pll_dsi_info *dsi_info; + u64 rate_millihz; + + dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance]; + /* check if the divider has already invoked the algorithm */ + if (req->rate == dsi_info->req_pll_dsi_rate) + return 0; + + /* If the req->rate doesn't match we do the calculation assuming there is no divider */ + rate_millihz = mul_u32_u32(req->rate, MILLI); + if (!rzv2h_get_pll_pars(dsi_info->pll_dsi_limits, + &dsi_info->pll_dsi_parameters.pll, rate_millihz)) { + dev_err(priv->dev, + "failed to determine rate for req->rate: %lu\n", + req->rate); + return -EINVAL; + } + + req->rate = DIV_ROUND_CLOSEST_ULL(dsi_info->pll_dsi_parameters.pll.freq_millihz, MILLI); + dsi_info->req_pll_dsi_rate = req->rate; + + return 0; +} + +static int rzv2h_cpg_pll_set_rate(struct pll_clk *pll_clk, + struct rzv2h_pll_pars *params, + bool ssc_disable) +{ + struct rzv2h_cpg_priv *priv = pll_clk->priv; + u16 offset = pll_clk->pll.offset; + u32 val; + int ret; + + /* Put PLL into standby mode */ + writel(CPG_PLL_STBY_RESETB_WEN, priv->base + CPG_PLL_STBY(offset)); + ret = readl_poll_timeout_atomic(priv->base + CPG_PLL_MON(offset), + val, !(val & CPG_PLL_MON_LOCK), + 100, 2000); + if (ret) { + dev_err(priv->dev, "Failed to put PLLDSI into standby mode"); + return ret; + } + + /* Output clock setting 1 */ + writel(FIELD_PREP(CPG_PLL_CLK1_KDIV, (u16)params->k) | + FIELD_PREP(CPG_PLL_CLK1_MDIV, params->m) | + FIELD_PREP(CPG_PLL_CLK1_PDIV, params->p), + priv->base + CPG_PLL_CLK1(offset)); + + /* Output clock setting 2 */ + val = readl(priv->base + CPG_PLL_CLK2(offset)); + writel((val & ~CPG_PLL_CLK2_SDIV) | FIELD_PREP(CPG_PLL_CLK2_SDIV, params->s), + priv->base + CPG_PLL_CLK2(offset)); + + /* Put PLL to normal mode */ + if (ssc_disable) + val = CPG_PLL_STBY_SSC_EN_WEN; + else + val = CPG_PLL_STBY_SSC_EN_WEN | CPG_PLL_STBY_SSC_EN; + writel(val | CPG_PLL_STBY_RESETB_WEN | CPG_PLL_STBY_RESETB, + priv->base + CPG_PLL_STBY(offset)); + + /* PLL normal mode transition, output clock stability check */ + ret = readl_poll_timeout_atomic(priv->base + CPG_PLL_MON(offset), + val, (val & CPG_PLL_MON_LOCK), + 100, 2000); + if (ret) { + dev_err(priv->dev, "Failed to put PLLDSI into normal mode"); + return ret; + } + + return 0; +} + +static int rzv2h_cpg_plldsi_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzv2h_pll_dsi_info *dsi_info; + struct rzv2h_cpg_priv *priv = pll_clk->priv; + + dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance]; + + return rzv2h_cpg_pll_set_rate(pll_clk, &dsi_info->pll_dsi_parameters.pll, true); +} + static int rzv2h_cpg_pll_clk_is_enabled(struct clk_hw *hw) { struct pll_clk *pll_clk = to_pll(hw); @@ -231,12 +712,19 @@ static unsigned long rzv2h_cpg_pll_clk_recalc_rate(struct clk_hw *hw, clk1 = readl(priv->base + CPG_PLL_CLK1(pll.offset)); clk2 = readl(priv->base + CPG_PLL_CLK2(pll.offset)); - rate = mul_u64_u32_shr(parent_rate, (CPG_PLL_CLK1_MDIV(clk1) << 16) + - CPG_PLL_CLK1_KDIV(clk1), 16 + CPG_PLL_CLK2_SDIV(clk2)); + rate = mul_u64_u32_shr(parent_rate, (FIELD_GET(CPG_PLL_CLK1_MDIV, clk1) << 16) + + (s16)FIELD_GET(CPG_PLL_CLK1_KDIV, clk1), + 16 + FIELD_GET(CPG_PLL_CLK2_SDIV, clk2)); - return DIV_ROUND_CLOSEST_ULL(rate, CPG_PLL_CLK1_PDIV(clk1)); + return DIV_ROUND_CLOSEST_ULL(rate, FIELD_GET(CPG_PLL_CLK1_PDIV, clk1)); } +static const struct clk_ops rzv2h_cpg_plldsi_ops = { + .recalc_rate = rzv2h_cpg_pll_clk_recalc_rate, + .determine_rate = rzv2h_cpg_plldsi_determine_rate, + .set_rate = rzv2h_cpg_plldsi_set_rate, +}; + static const struct clk_ops rzv2h_cpg_pll_ops = { .is_enabled = rzv2h_cpg_pll_clk_is_enabled, .enable = rzv2h_cpg_pll_clk_enable, @@ -263,6 +751,10 @@ rzv2h_cpg_pll_clk_register(const struct cpg_core_clk *core, if (!pll_clk) return ERR_PTR(-ENOMEM); + if (core->type == CLK_TYPE_PLLDSI) + priv->pll_dsi_info[core->cfg.pll.instance].pll_dsi_limits = + core->cfg.pll.limits; + parent_name = __clk_get_name(parent); init.name = core->name; init.ops = ops; @@ -587,11 +1079,17 @@ rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core, case CLK_TYPE_SMUX: clk = rzv2h_cpg_mux_clk_register(core, priv); break; + case CLK_TYPE_PLLDSI: + clk = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_plldsi_ops); + break; + case CLK_TYPE_PLLDSI_DIV: + clk = rzv2h_cpg_plldsi_div_clk_register(core, priv); + break; default: goto fail; } - if (IS_ERR_OR_NULL(clk)) + if (IS_ERR(clk)) goto fail; dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h index 840eed25aeda7..dc957bdaf5e97 100644 --- a/drivers/clk/renesas/rzv2h-cpg.h +++ b/drivers/clk/renesas/rzv2h-cpg.h @@ -16,20 +16,28 @@ * * @offset: STBY register offset * @has_clkn: Flag to indicate if CLK1/2 are accessible or not + * @instance: PLL instance number */ struct pll { unsigned int offset:9; unsigned int has_clkn:1; + unsigned int instance:2; + const struct rzv2h_pll_limits *limits; }; -#define PLL_PACK(_offset, _has_clkn) \ +#define PLL_PACK_LIMITS(_offset, _has_clkn, _instance, _limits) \ ((struct pll){ \ .offset = _offset, \ - .has_clkn = _has_clkn \ + .has_clkn = _has_clkn, \ + .instance = _instance, \ + .limits = _limits \ }) -#define PLLCA55 PLL_PACK(0x60, 1) -#define PLLGPU PLL_PACK(0x120, 1) +#define PLL_PACK(_offset, _has_clkn, _instance) \ + PLL_PACK_LIMITS(_offset, _has_clkn, _instance, NULL) + +#define PLLCA55 PLL_PACK(0x60, 1, 0) +#define PLLGPU PLL_PACK(0x120, 1, 0) /** * struct ddiv - Structure for dynamic switching divider @@ -115,9 +123,11 @@ struct fixed_mod_conf { #define CPG_SSEL1 (0x304) #define CPG_CDDIV0 (0x400) #define CPG_CDDIV1 (0x404) +#define CPG_CDDIV2 (0x408) #define CPG_CDDIV3 (0x40C) #define CPG_CDDIV4 (0x410) #define CPG_CSDIV0 (0x500) +#define CPG_CSDIV1 (0x504) #define CDDIV0_DIVCTL1 DDIV_PACK(CPG_CDDIV0, 4, 3, 1) #define CDDIV0_DIVCTL2 DDIV_PACK(CPG_CDDIV0, 8, 3, 2) @@ -125,6 +135,7 @@ struct fixed_mod_conf { #define CDDIV1_DIVCTL1 DDIV_PACK(CPG_CDDIV1, 4, 2, 5) #define CDDIV1_DIVCTL2 DDIV_PACK(CPG_CDDIV1, 8, 2, 6) #define CDDIV1_DIVCTL3 DDIV_PACK(CPG_CDDIV1, 12, 2, 7) +#define CDDIV2_DIVCTL3 DDIV_PACK(CPG_CDDIV2, 12, 3, 11) #define CDDIV3_DIVCTL1 DDIV_PACK(CPG_CDDIV3, 4, 3, 13) #define CDDIV3_DIVCTL2 DDIV_PACK(CPG_CDDIV3, 8, 3, 14) #define CDDIV3_DIVCTL3 DDIV_PACK(CPG_CDDIV3, 12, 1, 15) @@ -134,7 +145,9 @@ struct fixed_mod_conf { #define CSDIV0_DIVCTL0 DDIV_PACK(CPG_CSDIV0, 0, 2, CSDIV_NO_MON) #define CSDIV0_DIVCTL1 DDIV_PACK(CPG_CSDIV0, 4, 2, CSDIV_NO_MON) +#define CSDIV0_DIVCTL2 DDIV_PACK(CPG_CSDIV0, 8, 2, CSDIV_NO_MON) #define CSDIV0_DIVCTL3 DDIV_PACK_NO_RMW(CPG_CSDIV0, 12, 2, CSDIV_NO_MON) +#define CSDIV1_DIVCTL2 DDIV_PACK(CPG_CSDIV1, 8, 4, CSDIV_NO_MON) #define SSEL0_SELCTL2 SMUX_PACK(CPG_SSEL0, 8, 1) #define SSEL0_SELCTL3 SMUX_PACK(CPG_SSEL0, 12, 1) @@ -188,6 +201,8 @@ enum clk_types { CLK_TYPE_PLL, CLK_TYPE_DDIV, /* Dynamic Switching Divider */ CLK_TYPE_SMUX, /* Static Mux */ + CLK_TYPE_PLLDSI, /* PLLDSI */ + CLK_TYPE_PLLDSI_DIV, /* PLLDSI divider */ }; #define DEF_TYPE(_name, _id, _type...) \ @@ -218,6 +233,14 @@ enum clk_types { .num_parents = ARRAY_SIZE(_parent_names), \ .flag = CLK_SET_RATE_PARENT, \ .mux_flags = CLK_MUX_HIWORD_MASK) +#define DEF_PLLDSI(_name, _id, _parent, _pll_packed) \ + DEF_TYPE(_name, _id, CLK_TYPE_PLLDSI, .parent = _parent, .cfg.pll = _pll_packed) +#define DEF_PLLDSI_DIV(_name, _id, _parent, _ddiv_packed, _dtable) \ + DEF_TYPE(_name, _id, CLK_TYPE_PLLDSI_DIV, \ + .cfg.ddiv = _ddiv_packed, \ + .dtable = _dtable, \ + .parent = _parent, \ + .flag = CLK_SET_RATE_PARENT) /** * struct rzv2h_mod_clk - Module Clocks definitions diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig index febb7944f34bb..5cf1e0fd6fb32 100644 --- a/drivers/clk/rockchip/Kconfig +++ b/drivers/clk/rockchip/Kconfig @@ -30,6 +30,13 @@ config CLK_RV1126 help Build the driver for RV1126 Clock Driver. +config CLK_RV1126B + bool "Rockchip RV1126B clock controller support" + depends on ARM64 || COMPILE_TEST + default y + help + Build the driver for RV1126B Clock Driver. + config CLK_RK3036 bool "Rockchip RK3036 clock controller support" depends on ARM || COMPILE_TEST @@ -93,6 +100,13 @@ config CLK_RK3399 help Build the driver for RK3399 Clock Driver. +config CLK_RK3506 + bool "Rockchip RK3506 clock controller support" + depends on ARM || COMPILE_TEST + default y + help + Build the driver for RK3506 Clock Driver. + config CLK_RK3528 bool "Rockchip RK3528 clock controller support" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index c281a9738d9f4..4d8cbb2044c7c 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -20,6 +20,7 @@ clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o obj-$(CONFIG_CLK_PX30) += clk-px30.o obj-$(CONFIG_CLK_RV110X) += clk-rv1108.o obj-$(CONFIG_CLK_RV1126) += clk-rv1126.o +obj-$(CONFIG_CLK_RV1126B) += clk-rv1126b.o rst-rv1126b.o obj-$(CONFIG_CLK_RK3036) += clk-rk3036.o obj-$(CONFIG_CLK_RK312X) += clk-rk3128.o obj-$(CONFIG_CLK_RK3188) += clk-rk3188.o @@ -29,6 +30,7 @@ obj-$(CONFIG_CLK_RK3308) += clk-rk3308.o obj-$(CONFIG_CLK_RK3328) += clk-rk3328.o obj-$(CONFIG_CLK_RK3368) += clk-rk3368.o obj-$(CONFIG_CLK_RK3399) += clk-rk3399.o +obj-$(CONFIG_CLK_RK3506) += clk-rk3506.o rst-rk3506.o obj-$(CONFIG_CLK_RK3528) += clk-rk3528.o rst-rk3528.o obj-$(CONFIG_CLK_RK3562) += clk-rk3562.o rst-rk3562.o obj-$(CONFIG_CLK_RK3568) += clk-rk3568.o diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index dcc9dcb597ae1..6e91a3041a03c 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -396,3 +396,168 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, kfree(cpuclk); return ERR_PTR(ret); } + +static int rockchip_cpuclk_multi_pll_pre_rate_change(struct rockchip_cpuclk *cpuclk, + struct clk_notifier_data *ndata) +{ + unsigned long new_rate = roundup(ndata->new_rate, 1000); + const struct rockchip_cpuclk_rate_table *rate; + unsigned long flags; + + rate = rockchip_get_cpuclk_settings(cpuclk, new_rate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for cpuclk\n", + __func__, new_rate); + return -EINVAL; + } + + if (new_rate > ndata->old_rate) { + spin_lock_irqsave(cpuclk->lock, flags); + rockchip_cpuclk_set_dividers(cpuclk, rate); + spin_unlock_irqrestore(cpuclk->lock, flags); + } + + return 0; +} + +static int rockchip_cpuclk_multi_pll_post_rate_change(struct rockchip_cpuclk *cpuclk, + struct clk_notifier_data *ndata) +{ + unsigned long new_rate = roundup(ndata->new_rate, 1000); + const struct rockchip_cpuclk_rate_table *rate; + unsigned long flags; + + rate = rockchip_get_cpuclk_settings(cpuclk, new_rate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for cpuclk\n", + __func__, new_rate); + return -EINVAL; + } + + if (new_rate < ndata->old_rate) { + spin_lock_irqsave(cpuclk->lock, flags); + rockchip_cpuclk_set_dividers(cpuclk, rate); + spin_unlock_irqrestore(cpuclk->lock, flags); + } + + return 0; +} + +static int rockchip_cpuclk_multi_pll_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct clk_notifier_data *ndata = data; + struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_nb(nb); + int ret = 0; + + pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n", + __func__, event, ndata->old_rate, ndata->new_rate); + if (event == PRE_RATE_CHANGE) + ret = rockchip_cpuclk_multi_pll_pre_rate_change(cpuclk, ndata); + else if (event == POST_RATE_CHANGE) + ret = rockchip_cpuclk_multi_pll_post_rate_change(cpuclk, ndata); + + return notifier_from_errno(ret); +} + +struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name, + const char *const *parent_names, + u8 num_parents, void __iomem *base, + int muxdiv_offset, u8 mux_shift, + u8 mux_width, u8 mux_flags, + int div_offset, u8 div_shift, + u8 div_width, u8 div_flags, + unsigned long flags, spinlock_t *lock, + const struct rockchip_cpuclk_rate_table *rates, + int nrates) +{ + struct rockchip_cpuclk *cpuclk; + struct clk_hw *hw; + struct clk_mux *mux = NULL; + struct clk_divider *div = NULL; + const struct clk_ops *mux_ops = NULL, *div_ops = NULL; + int ret; + + if (num_parents > 1) { + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + mux->reg = base + muxdiv_offset; + mux->shift = mux_shift; + mux->mask = BIT(mux_width) - 1; + mux->flags = mux_flags; + mux->lock = lock; + mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops + : &clk_mux_ops; + } + + if (div_width > 0) { + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) { + ret = -ENOMEM; + goto free_mux; + } + + div->flags = div_flags; + if (div_offset) + div->reg = base + div_offset; + else + div->reg = base + muxdiv_offset; + div->shift = div_shift; + div->width = div_width; + div->lock = lock; + div_ops = (div_flags & CLK_DIVIDER_READ_ONLY) + ? &clk_divider_ro_ops + : &clk_divider_ops; + } + + hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, + mux ? &mux->hw : NULL, mux_ops, + div ? &div->hw : NULL, div_ops, + NULL, NULL, flags); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto free_div; + } + + cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); + if (!cpuclk) { + ret = -ENOMEM; + goto unregister_clk; + } + + cpuclk->reg_base = base; + cpuclk->lock = lock; + cpuclk->clk_nb.notifier_call = rockchip_cpuclk_multi_pll_notifier_cb; + ret = clk_notifier_register(hw->clk, &cpuclk->clk_nb); + if (ret) { + pr_err("%s: failed to register clock notifier for %s\n", + __func__, name); + goto free_cpuclk; + } + + if (nrates > 0) { + cpuclk->rate_count = nrates; + cpuclk->rate_table = kmemdup(rates, + sizeof(*rates) * nrates, + GFP_KERNEL); + if (!cpuclk->rate_table) { + ret = -ENOMEM; + goto free_cpuclk; + } + } + + return hw->clk; + +free_cpuclk: + kfree(cpuclk); +unregister_clk: + clk_hw_unregister_composite(hw); +free_div: + kfree(div); +free_mux: + kfree(mux); + + return ERR_PTR(ret); +} diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 0a1e017df7c66..9cf3e1e43b781 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -871,7 +871,7 @@ static const int rk3288_saved_cru_reg_ids[] = { static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)]; -static int rk3288_clk_suspend(void) +static int rk3288_clk_suspend(void *data) { int i, reg_id; @@ -906,7 +906,7 @@ static int rk3288_clk_suspend(void) return 0; } -static void rk3288_clk_resume(void) +static void rk3288_clk_resume(void *data) { int i, reg_id; @@ -923,11 +923,15 @@ static void rk3288_clk_shutdown(void) writel_relaxed(0xf3030000, rk3288_cru_base + RK3288_MODE_CON); } -static struct syscore_ops rk3288_clk_syscore_ops = { +static const struct syscore_ops rk3288_clk_syscore_ops = { .suspend = rk3288_clk_suspend, .resume = rk3288_clk_resume, }; +static struct syscore rk3288_clk_syscore = { + .ops = &rk3288_clk_syscore_ops, +}; + static void __init rk3288_common_init(struct device_node *np, enum rk3288_variant soc) { @@ -976,7 +980,7 @@ static void __init rk3288_common_init(struct device_node *np, rockchip_register_restart_notifier(ctx, RK3288_GLB_SRST_FST, rk3288_clk_shutdown); - register_syscore_ops(&rk3288_clk_syscore_ops); + register_syscore(&rk3288_clk_syscore); rockchip_clk_of_add_provider(np, ctx); } diff --git a/drivers/clk/rockchip/clk-rk3506.c b/drivers/clk/rockchip/clk-rk3506.c new file mode 100644 index 0000000000000..dd59bd60382ef --- /dev/null +++ b/drivers/clk/rockchip/clk-rk3506.c @@ -0,0 +1,869 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd. + * Author: Finley Xiao + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define PVTPLL_SRC_SEL_PVTPLL (BIT(7) | BIT(23)) + +enum rk3506_plls { + gpll, v0pll, v1pll, +}; + +/* + * [FRAC PLL]: GPLL, V0PLL, V1PLL + * - VCO Frequency: 950MHz to 3800MHZ + * - Output Frequency: 19MHz to 3800MHZ + * - refdiv: 1 to 63 (Int Mode), 1 to 2 (Frac Mode) + * - fbdiv: 16 to 3800 (Int Mode), 20 to 380 (Frac Mode) + * - post1div: 1 to 7 + * - post2div: 1 to 7 + */ +static struct rockchip_pll_rate_table rk3506_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0), + RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0), + RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0), + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), + RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0), + RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0), + RK3036_PLL_RATE(1350000000, 4, 225, 1, 1, 1, 0), + RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0), + RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137), + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 3, 125, 1, 1, 1, 0), + RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355), + RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127), + RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0), + RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), + RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185), + RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), + RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0), + RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0), + RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), + RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0), + RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), + RK3036_PLL_RATE(96000000, 1, 48, 6, 2, 1, 0), + { /* sentinel */ }, +}; + +#define RK3506_DIV_ACLK_CORE_MASK 0xf +#define RK3506_DIV_ACLK_CORE_SHIFT 9 +#define RK3506_DIV_PCLK_CORE_MASK 0xf +#define RK3506_DIV_PCLK_CORE_SHIFT 0 + +#define RK3506_CLKSEL15(_aclk_core_div) \ +{ \ + .reg = RK3506_CLKSEL_CON(15), \ + .val = HIWORD_UPDATE(_aclk_core_div, RK3506_DIV_ACLK_CORE_MASK, \ + RK3506_DIV_ACLK_CORE_SHIFT), \ +} + +#define RK3506_CLKSEL16(_pclk_core_div) \ +{ \ + .reg = RK3506_CLKSEL_CON(16), \ + .val = HIWORD_UPDATE(_pclk_core_div, RK3506_DIV_PCLK_CORE_MASK, \ + RK3506_DIV_PCLK_CORE_SHIFT), \ +} + +/* SIGN-OFF: aclk_core: 500M, pclk_core: 125M, */ +#define RK3506_CPUCLK_RATE(_prate, _aclk_core_div, _pclk_core_div) \ +{ \ + .prate = _prate, \ + .divs = { \ + RK3506_CLKSEL15(_aclk_core_div), \ + RK3506_CLKSEL16(_pclk_core_div), \ + }, \ +} + +static struct rockchip_cpuclk_rate_table rk3506_cpuclk_rates[] __initdata = { + RK3506_CPUCLK_RATE(1608000000, 3, 12), + RK3506_CPUCLK_RATE(1512000000, 3, 12), + RK3506_CPUCLK_RATE(1416000000, 2, 11), + RK3506_CPUCLK_RATE(1296000000, 2, 10), + RK3506_CPUCLK_RATE(1200000000, 2, 9), + RK3506_CPUCLK_RATE(1179648000, 2, 9), + RK3506_CPUCLK_RATE(1008000000, 1, 7), + RK3506_CPUCLK_RATE(903168000, 1, 7), + RK3506_CPUCLK_RATE(800000000, 1, 6), + RK3506_CPUCLK_RATE(750000000, 1, 5), + RK3506_CPUCLK_RATE(589824000, 1, 4), + RK3506_CPUCLK_RATE(400000000, 1, 3), + RK3506_CPUCLK_RATE(200000000, 1, 1), +}; + +PNAME(mux_pll_p) = { "xin24m" }; +PNAME(gpll_v0pll_v1pll_parents_p) = { "gpll", "v0pll", "v1pll" }; +PNAME(gpll_v0pll_v1pll_g_parents_p) = { "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" }; +PNAME(gpll_v0pll_v1pll_div_parents_p) = { "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" }; +PNAME(xin24m_gpll_v0pll_v1pll_g_parents_p) = { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" }; +PNAME(xin24m_g_gpll_v0pll_v1pll_g_parents_p) = { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" }; +PNAME(xin24m_g_gpll_v0pll_v1pll_div_parents_p) = { "xin24m_gate", "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" }; +PNAME(xin24m_400k_32k_parents_p) = { "xin24m", "clk_rc", "clk_32k" }; +PNAME(clk_frac_uart_matrix0_mux_parents_p) = { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" }; +PNAME(clk_timer0_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai0_mclk_in", "sai0_sclk_in" }; +PNAME(clk_timer1_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai1_mclk_in", "sai1_sclk_in" }; +PNAME(clk_timer2_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai2_mclk_in", "sai2_sclk_in" }; +PNAME(clk_timer3_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai3_mclk_in", "sai3_sclk_in" }; +PNAME(clk_timer4_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc0" }; +PNAME(clk_timer5_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc1" }; +PNAME(sclk_uart_parents_p) = { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_frac_uart_matrix0", "clk_frac_uart_matrix1", + "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" }; +PNAME(clk_mac_ptp_root_parents_p) = { "gpll", "v0pll", "v1pll" }; +PNAME(clk_pwm_parents_p) = { "clk_rc", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "sai0_sclk_in", "sai1_sclk_in", + "sai2_sclk_in", "sai3_sclk_in", "mclk_asrc0", "mclk_asrc1" }; +PNAME(clk_can_parents_p) = { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate", "clk_frac_voice_matrix1", + "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" }; +PNAME(clk_pdm_parents_p) = { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2", + "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1", + "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "clk_gpll_div" }; +PNAME(mclk_sai_asrc_parents_p) = { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2", + "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1", + "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in" }; +PNAME(lrck_asrc_parents_p) = { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", "mclk_spdiftx", "clk_spdifrx_to_asrc", "clkout_pdm", + "sai0_fs", "sai1_fs", "sai2_fs", "sai3_fs", "sai4_fs" }; +PNAME(cclk_src_sdmmc_parents_p) = { "xin24m_gate", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" }; +PNAME(dclk_vop_parents_p) = { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate", "dummy_vop_dclk", + "dummy_vop_dclk", "dummy_vop_dclk", "dummy_vop_dclk" }; +PNAME(dbclk_gpio0_parents_p) = { "xin24m", "clk_rc", "clk_32k_pmu" }; +PNAME(clk_pmu_hp_timer_parents_p) = { "xin24m", "gpll_div_100m", "clk_core_pvtpll" }; +PNAME(clk_ref_out_parents_p) = { "xin24m", "gpll", "v0pll", "v1pll" }; +PNAME(clk_32k_frac_parents_p) = { "xin24m", "v0pll", "v1pll", "clk_rc" }; +PNAME(clk_32k_parents_p) = { "xin32k", "clk_32k_rc", "clk_32k_frac" }; +PNAME(clk_ref_phy_pmu_mux_parents_p) = { "xin24m", "clk_ref_phy_pll" }; +PNAME(clk_vpll_ref_parents_p) = { "xin24m", "clk_pll_ref_io" }; +PNAME(mux_armclk_p) = { "armclk_pll", "clk_core_pvtpll" }; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_pll_clock rk3506_pll_clks[] __initdata = { + [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p, + CLK_IS_CRITICAL, RK3506_PLL_CON(0), + RK3506_MODE_CON, 0, 2, 0, rk3506_pll_rates), + [v0pll] = PLL(pll_rk3328, PLL_V0PLL, "v0pll", mux_pll_p, + CLK_IS_CRITICAL, RK3506_PLL_CON(8), + RK3506_MODE_CON, 2, 0, 0, rk3506_pll_rates), + [v1pll] = PLL(pll_rk3328, PLL_V1PLL, "v1pll", mux_pll_p, + CLK_IS_CRITICAL, RK3506_PLL_CON(16), + RK3506_MODE_CON, 4, 1, 0, rk3506_pll_rates), +}; + +static struct rockchip_clk_branch rk3506_armclk __initdata = + MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + RK3506_CLKSEL_CON(15), 8, 1, MFLAGS); + +static struct rockchip_clk_branch rk3506_clk_branches[] __initdata = { + /* + * CRU Clock-Architecture + */ + /* top */ + GATE(XIN24M_GATE, "xin24m_gate", "xin24m", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(0), 1, GFLAGS), + GATE(CLK_GPLL_GATE, "clk_gpll_gate", "gpll", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(0), 2, GFLAGS), + GATE(CLK_V0PLL_GATE, "clk_v0pll_gate", "v0pll", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(0), 3, GFLAGS), + GATE(CLK_V1PLL_GATE, "clk_v1pll_gate", "v1pll", 0, + RK3506_CLKGATE_CON(0), 4, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV, "clk_gpll_div", "clk_gpll_gate", CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(0), 6, 4, DFLAGS, + RK3506_CLKGATE_CON(0), 5, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV_100M, "clk_gpll_div_100m", "clk_gpll_div", 0, + RK3506_CLKSEL_CON(0), 10, 4, DFLAGS, + RK3506_CLKGATE_CON(0), 6, GFLAGS), + COMPOSITE_NOMUX(CLK_V0PLL_DIV, "clk_v0pll_div", "clk_v0pll_gate", CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(1), 0, 4, DFLAGS, + RK3506_CLKGATE_CON(0), 7, GFLAGS), + COMPOSITE_NOMUX(CLK_V1PLL_DIV, "clk_v1pll_div", "clk_v1pll_gate", 0, + RK3506_CLKSEL_CON(1), 4, 4, DFLAGS, + RK3506_CLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX0, "clk_int_voice_matrix0", "clk_v0pll_gate", 0, + RK3506_CLKSEL_CON(1), 8, 5, DFLAGS, + RK3506_CLKGATE_CON(0), 9, GFLAGS), + COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX1, "clk_int_voice_matrix1", "clk_v1pll_gate", 0, + RK3506_CLKSEL_CON(2), 0, 5, DFLAGS, + RK3506_CLKGATE_CON(0), 10, GFLAGS), + COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX2, "clk_int_voice_matrix2", "clk_v0pll_gate", 0, + RK3506_CLKSEL_CON(2), 5, 5, DFLAGS, + RK3506_CLKGATE_CON(0), 11, GFLAGS), + MUX(CLK_FRAC_UART_MATRIX0_MUX, "clk_frac_uart_matrix0_mux", clk_frac_uart_matrix0_mux_parents_p, 0, + RK3506_CLKSEL_CON(3), 9, 2, MFLAGS), + MUX(CLK_FRAC_UART_MATRIX1_MUX, "clk_frac_uart_matrix1_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(3), 11, 2, MFLAGS), + MUX(CLK_FRAC_VOICE_MATRIX0_MUX, "clk_frac_voice_matrix0_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(3), 13, 2, MFLAGS), + MUX(CLK_FRAC_VOICE_MATRIX1_MUX, "clk_frac_voice_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(4), 0, 2, MFLAGS), + MUX(CLK_FRAC_COMMON_MATRIX0_MUX, "clk_frac_common_matrix0_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(4), 2, 2, MFLAGS), + MUX(CLK_FRAC_COMMON_MATRIX1_MUX, "clk_frac_common_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(4), 4, 2, MFLAGS), + MUX(CLK_FRAC_COMMON_MATRIX2_MUX, "clk_frac_common_matrix2_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(4), 6, 2, MFLAGS), + COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX0, "clk_frac_uart_matrix0", "clk_frac_uart_matrix0_mux", 0, + RK3506_CLKSEL_CON(5), 0, + RK3506_CLKGATE_CON(0), 13, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX1, "clk_frac_uart_matrix1", "clk_frac_uart_matrix1_mux", 0, + RK3506_CLKSEL_CON(6), 0, + RK3506_CLKGATE_CON(0), 14, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX0, "clk_frac_voice_matrix0", "clk_frac_voice_matrix0_mux", 0, + RK3506_CLKSEL_CON(7), 0, + RK3506_CLKGATE_CON(0), 15, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX1, "clk_frac_voice_matrix1", "clk_frac_voice_matrix1_mux", 0, + RK3506_CLKSEL_CON(9), 0, + RK3506_CLKGATE_CON(1), 0, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX0, "clk_frac_common_matrix0", "clk_frac_common_matrix0_mux", 0, + RK3506_CLKSEL_CON(11), 0, + RK3506_CLKGATE_CON(1), 1, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX1, "clk_frac_common_matrix1", "clk_frac_common_matrix1_mux", 0, + RK3506_CLKSEL_CON(12), 0, + RK3506_CLKGATE_CON(1), 2, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX2, "clk_frac_common_matrix2", "clk_frac_common_matrix2_mux", 0, + RK3506_CLKSEL_CON(13), 0, + RK3506_CLKGATE_CON(1), 3, GFLAGS), + GATE(CLK_REF_USBPHY_TOP, "clk_ref_usbphy_top", "xin24m", 0, + RK3506_CLKGATE_CON(1), 4, GFLAGS), + GATE(CLK_REF_DPHY_TOP, "clk_ref_dphy_top", "xin24m", 0, + RK3506_CLKGATE_CON(1), 5, GFLAGS), + + /* core */ + COMPOSITE_NOGATE(0, "armclk_pll", gpll_v0pll_v1pll_parents_p, CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(15), 5, 2, MFLAGS, 0, 5, DFLAGS), + COMPOSITE_NOMUX(ACLK_CORE_ROOT, "aclk_core_root", "armclk", CLK_IGNORE_UNUSED, + RK3506_CLKSEL_CON(15), 9, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3506_CLKGATE_CON(2), 11, GFLAGS), + COMPOSITE_NOMUX(PCLK_CORE_ROOT, "pclk_core_root", "armclk", CLK_IGNORE_UNUSED, + RK3506_CLKSEL_CON(16), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3506_CLKGATE_CON(2), 12, GFLAGS), + GATE(PCLK_DBG, "pclk_dbg", "pclk_core_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(3), 1, GFLAGS), + GATE(PCLK_CORE_GRF, "pclk_core_grf", "pclk_core_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(3), 4, GFLAGS), + GATE(PCLK_CORE_CRU, "pclk_core_cru", "pclk_core_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(3), 5, GFLAGS), + GATE(CLK_CORE_EMA_DETECT, "clk_core_ema_detect", "xin24m_gate", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(3), 6, GFLAGS), + GATE(PCLK_GPIO1, "pclk_gpio1", "aclk_core_root", 0, + RK3506_CLKGATE_CON(3), 8, GFLAGS), + GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m_gate", 0, + RK3506_CLKGATE_CON(3), 9, GFLAGS), + + /* core peri */ + COMPOSITE(ACLK_CORE_PERI_ROOT, "aclk_core_peri_root", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(18), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(4), 0, GFLAGS), + GATE(HCLK_CORE_PERI_ROOT, "hclk_core_peri_root", "aclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 1, GFLAGS), + GATE(PCLK_CORE_PERI_ROOT, "pclk_core_peri_root", "aclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 2, GFLAGS), + COMPOSITE(CLK_DSMC, "clk_dsmc", xin24m_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(18), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(4), 4, GFLAGS), + GATE(ACLK_DSMC, "aclk_dsmc", "aclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 5, GFLAGS), + GATE(PCLK_DSMC, "pclk_dsmc", "pclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 6, GFLAGS), + COMPOSITE(CLK_FLEXBUS_TX, "clk_flexbus_tx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(19), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(4), 7, GFLAGS), + COMPOSITE(CLK_FLEXBUS_RX, "clk_flexbus_rx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(19), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(4), 8, GFLAGS), + GATE(ACLK_FLEXBUS, "aclk_flexbus", "aclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 9, GFLAGS), + GATE(HCLK_FLEXBUS, "hclk_flexbus", "hclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 10, GFLAGS), + GATE(ACLK_DSMC_SLV, "aclk_dsmc_slv", "aclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 11, GFLAGS), + GATE(HCLK_DSMC_SLV, "hclk_dsmc_slv", "hclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 12, GFLAGS), + + /* bus */ + COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(21), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(5), 0, GFLAGS), + COMPOSITE(HCLK_BUS_ROOT, "hclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(21), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(5), 1, GFLAGS), + COMPOSITE(PCLK_BUS_ROOT, "pclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(5), 2, GFLAGS), + GATE(ACLK_SYSRAM, "aclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(5), 6, GFLAGS), + GATE(HCLK_SYSRAM, "hclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(5), 7, GFLAGS), + GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0, + RK3506_CLKGATE_CON(5), 8, GFLAGS), + GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0, + RK3506_CLKGATE_CON(5), 9, GFLAGS), + GATE(HCLK_M0, "hclk_m0", "aclk_bus_root", 0, + RK3506_CLKGATE_CON(5), 10, GFLAGS), + GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_bus_root", 0, + RK3506_CLKGATE_CON(5), 14, GFLAGS), + GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(5), 15, GFLAGS), + GATE(HCLK_RNG, "hclk_rng", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 0, GFLAGS), + GATE(PCLK_BUS_GRF, "pclk_bus_grf", "pclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(6), 1, GFLAGS), + GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 2, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH0, "clk_timer0_ch0", clk_timer0_parents_p, 0, + RK3506_CLKSEL_CON(22), 7, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 3, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH1, "clk_timer0_ch1", clk_timer1_parents_p, 0, + RK3506_CLKSEL_CON(22), 10, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 4, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH2, "clk_timer0_ch2", clk_timer2_parents_p, 0, + RK3506_CLKSEL_CON(22), 13, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 5, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH3, "clk_timer0_ch3", clk_timer3_parents_p, 0, + RK3506_CLKSEL_CON(23), 0, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 6, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH4, "clk_timer0_ch4", clk_timer4_parents_p, 0, + RK3506_CLKSEL_CON(23), 3, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 7, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH5, "clk_timer0_ch5", clk_timer5_parents_p, 0, + RK3506_CLKSEL_CON(23), 6, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 8, GFLAGS), + GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 9, GFLAGS), + GATE(TCLK_WDT0, "tclk_wdt0", "xin24m_gate", 0, + RK3506_CLKGATE_CON(6), 10, GFLAGS), + GATE(PCLK_WDT1, "pclk_wdt1", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 11, GFLAGS), + GATE(TCLK_WDT1, "tclk_wdt1", "xin24m_gate", 0, + RK3506_CLKGATE_CON(6), 12, GFLAGS), + GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 13, GFLAGS), + GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 14, GFLAGS), + GATE(PCLK_SPINLOCK, "pclk_spinlock", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 15, GFLAGS), + GATE(PCLK_DDRC, "pclk_ddrc", "pclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(7), 0, GFLAGS), + GATE(HCLK_DDRPHY, "hclk_ddrphy", "hclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(7), 1, GFLAGS), + GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(7), 2, GFLAGS), + GATE(CLK_DDRMON_OSC, "clk_ddrmon_osc", "xin24m_gate", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(7), 3, GFLAGS), + GATE(PCLK_STDBY, "pclk_stdby", "pclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(7), 4, GFLAGS), + GATE(HCLK_USBOTG0, "hclk_usbotg0", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(7), 5, GFLAGS), + GATE(HCLK_USBOTG0_PMU, "hclk_usbotg0_pmu", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(7), 6, GFLAGS), + GATE(CLK_USBOTG0_ADP, "clk_usbotg0_adp", "clk_32k", 0, + RK3506_CLKGATE_CON(7), 7, GFLAGS), + GATE(HCLK_USBOTG1, "hclk_usbotg1", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(7), 8, GFLAGS), + GATE(HCLK_USBOTG1_PMU, "hclk_usbotg1_pmu", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(7), 9, GFLAGS), + GATE(CLK_USBOTG1_ADP, "clk_usbotg1_adp", "clk_32k", 0, + RK3506_CLKGATE_CON(7), 10, GFLAGS), + GATE(PCLK_USBPHY, "pclk_usbphy", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(7), 11, GFLAGS), + GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(8), 0, GFLAGS), + GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(8), 1, GFLAGS), + COMPOSITE_NOMUX(STCLK_M0, "stclk_m0", "xin24m_gate", 0, + RK3506_CLKSEL_CON(23), 9, 6, DFLAGS, + RK3506_CLKGATE_CON(8), 2, GFLAGS), + COMPOSITE(CLK_DDRPHY, "clk_ddrphy", gpll_v0pll_v1pll_parents_p, CLK_IGNORE_UNUSED, + RK3506_PMU_CLKSEL_CON(4), 4, 2, MFLAGS, 0, 4, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 10, GFLAGS), + FACTOR(CLK_DDRC_SRC, "clk_ddrc_src", "clk_ddrphy", 0, 1, 4), + GATE(ACLK_DDRC_0, "aclk_ddrc_0", "clk_ddrc_src", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(10), 0, GFLAGS), + GATE(ACLK_DDRC_1, "aclk_ddrc_1", "clk_ddrc_src", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(10), 1, GFLAGS), + GATE(CLK_DDRC, "clk_ddrc", "clk_ddrc_src", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(10), 3, GFLAGS), + GATE(CLK_DDRMON, "clk_ddrmon", "clk_ddrc_src", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(10), 4, GFLAGS), + + /* ls peri */ + COMPOSITE(HCLK_LSPERI_ROOT, "hclk_lsperi_root", gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(29), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 0, GFLAGS), + GATE(PCLK_LSPERI_ROOT, "pclk_lsperi_root", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 1, GFLAGS), + GATE(PCLK_UART0, "pclk_uart0", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 4, GFLAGS), + GATE(PCLK_UART1, "pclk_uart1", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 5, GFLAGS), + GATE(PCLK_UART2, "pclk_uart2", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 6, GFLAGS), + GATE(PCLK_UART3, "pclk_uart3", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 7, GFLAGS), + GATE(PCLK_UART4, "pclk_uart4", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 8, GFLAGS), + COMPOSITE(SCLK_UART0, "sclk_uart0", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(29), 12, 3, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 9, GFLAGS), + COMPOSITE(SCLK_UART1, "sclk_uart1", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(30), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 10, GFLAGS), + COMPOSITE(SCLK_UART2, "sclk_uart2", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(30), 13, 3, MFLAGS, 8, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 11, GFLAGS), + COMPOSITE(SCLK_UART3, "sclk_uart3", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(31), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 12, GFLAGS), + COMPOSITE(SCLK_UART4, "sclk_uart4", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(31), 13, 3, MFLAGS, 8, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 13, GFLAGS), + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 14, GFLAGS), + COMPOSITE(CLK_I2C0, "clk_i2c0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(32), 4, 2, MFLAGS, 0, 4, DFLAGS, + RK3506_CLKGATE_CON(11), 15, GFLAGS), + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 0, GFLAGS), + COMPOSITE(CLK_I2C1, "clk_i2c1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(32), 10, 2, MFLAGS, 6, 4, DFLAGS, + RK3506_CLKGATE_CON(12), 1, GFLAGS), + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 2, GFLAGS), + COMPOSITE(CLK_I2C2, "clk_i2c2", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(33), 4, 2, MFLAGS, 0, 4, DFLAGS, + RK3506_CLKGATE_CON(12), 3, GFLAGS), + GATE(PCLK_PWM1, "pclk_pwm1", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 4, GFLAGS), + COMPOSITE(CLK_PWM1, "clk_pwm1", gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(33), 10, 2, MFLAGS, 6, 4, DFLAGS, + RK3506_CLKGATE_CON(12), 5, GFLAGS), + GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0, + RK3506_CLKGATE_CON(12), 6, GFLAGS), + GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_rc", 0, + RK3506_CLKGATE_CON(12), 7, GFLAGS), + COMPOSITE_NODIV(CLK_FREQ_PWM1, "clk_freq_pwm1", clk_pwm_parents_p, 0, + RK3506_CLKSEL_CON(33), 12, 4, MFLAGS, + RK3506_CLKGATE_CON(12), 8, GFLAGS), + COMPOSITE_NODIV(CLK_COUNTER_PWM1, "clk_counter_pwm1", clk_pwm_parents_p, 0, + RK3506_CLKSEL_CON(34), 0, 4, MFLAGS, + RK3506_CLKGATE_CON(12), 9, GFLAGS), + GATE(PCLK_SPI0, "pclk_spi0", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 10, GFLAGS), + COMPOSITE(CLK_SPI0, "clk_spi0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(34), 8, 2, MFLAGS, 4, 4, DFLAGS, + RK3506_CLKGATE_CON(12), 11, GFLAGS), + GATE(PCLK_SPI1, "pclk_spi1", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 12, GFLAGS), + COMPOSITE(CLK_SPI1, "clk_spi1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(34), 14, 2, MFLAGS, 10, 4, DFLAGS, + RK3506_CLKGATE_CON(12), 13, GFLAGS), + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 14, GFLAGS), + COMPOSITE_NODIV(DBCLK_GPIO2, "dbclk_gpio2", xin24m_400k_32k_parents_p, 0, + RK3506_CLKSEL_CON(35), 0, 2, MFLAGS, + RK3506_CLKGATE_CON(12), 15, GFLAGS), + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 0, GFLAGS), + COMPOSITE_NODIV(DBCLK_GPIO3, "dbclk_gpio3", xin24m_400k_32k_parents_p, 0, + RK3506_CLKSEL_CON(35), 2, 2, MFLAGS, + RK3506_CLKGATE_CON(13), 1, GFLAGS), + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 2, GFLAGS), + COMPOSITE_NODIV(DBCLK_GPIO4, "dbclk_gpio4", xin24m_400k_32k_parents_p, 0, + RK3506_CLKSEL_CON(35), 4, 2, MFLAGS, + RK3506_CLKGATE_CON(13), 3, GFLAGS), + GATE(HCLK_CAN0, "hclk_can0", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 4, GFLAGS), + COMPOSITE(CLK_CAN0, "clk_can0", clk_can_parents_p, 0, + RK3506_CLKSEL_CON(35), 11, 3, MFLAGS, 6, 5, DFLAGS, + RK3506_CLKGATE_CON(13), 5, GFLAGS), + GATE(HCLK_CAN1, "hclk_can1", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 6, GFLAGS), + COMPOSITE(CLK_CAN1, "clk_can1", clk_can_parents_p, 0, + RK3506_CLKSEL_CON(36), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(13), 7, GFLAGS), + GATE(HCLK_PDM, "hclk_pdm", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 8, GFLAGS), + COMPOSITE(MCLK_PDM, "mclk_pdm", clk_pdm_parents_p, 0, + RK3506_CLKSEL_CON(37), 5, 4, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(13), 9, GFLAGS), + COMPOSITE(CLKOUT_PDM, "clkout_pdm", clk_pdm_parents_p, 0, + RK3506_CLKSEL_CON(38), 10, 4, MFLAGS, 0, 10, DFLAGS, + RK3506_CLKGATE_CON(13), 10, GFLAGS), + COMPOSITE(MCLK_SPDIFTX, "mclk_spdiftx", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(39), 5, 4, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(13), 11, GFLAGS), + GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 12, GFLAGS), + GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 13, GFLAGS), + COMPOSITE(MCLK_SPDIFRX, "mclk_spdifrx", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(39), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3506_CLKGATE_CON(13), 14, GFLAGS), + COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(40), 8, 4, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(13), 15, GFLAGS), + GATE(HCLK_SAI0, "hclk_sai0", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(14), 0, GFLAGS), + GATE(MCLK_OUT_SAI0, "mclk_out_sai0", "mclk_sai0", 0, + RK3506_CLKGATE_CON(14), 1, GFLAGS), + COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(41), 8, 4, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(14), 2, GFLAGS), + GATE(HCLK_SAI1, "hclk_sai1", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(14), 3, GFLAGS), + GATE(MCLK_OUT_SAI1, "mclk_out_sai1", "mclk_sai1", 0, + RK3506_CLKGATE_CON(14), 4, GFLAGS), + GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(14), 5, GFLAGS), + COMPOSITE(CLK_ASRC0, "clk_asrc0", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(42), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(14), 6, GFLAGS), + GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(14), 7, GFLAGS), + COMPOSITE(CLK_ASRC1, "clk_asrc1", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(42), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(14), 8, GFLAGS), + GATE(PCLK_CRU, "pclk_cru", "pclk_lsperi_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(14), 9, GFLAGS), + GATE(PCLK_PMU_ROOT, "pclk_pmu_root", "pclk_lsperi_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(14), 10, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(46), 0, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 0, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(46), 4, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 1, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(46), 8, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 2, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(46), 12, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 3, GFLAGS), + COMPOSITE_NODIV(LRCK_ASRC0_SRC, "lrck_asrc0_src", lrck_asrc_parents_p, 0, + RK3506_CLKSEL_CON(47), 0, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 4, GFLAGS), + COMPOSITE_NODIV(LRCK_ASRC0_DST, "lrck_asrc0_dst", lrck_asrc_parents_p, 0, + RK3506_CLKSEL_CON(47), 4, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 5, GFLAGS), + COMPOSITE_NODIV(LRCK_ASRC1_SRC, "lrck_asrc1_src", lrck_asrc_parents_p, 0, + RK3506_CLKSEL_CON(47), 8, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 6, GFLAGS), + COMPOSITE_NODIV(LRCK_ASRC1_DST, "lrck_asrc1_dst", lrck_asrc_parents_p, 0, + RK3506_CLKSEL_CON(47), 12, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 7, GFLAGS), + + /* hs peri */ + COMPOSITE(ACLK_HSPERI_ROOT, "aclk_hsperi_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(49), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(17), 0, GFLAGS), + GATE(HCLK_HSPERI_ROOT, "hclk_hsperi_root", "aclk_hsperi_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(17), 1, GFLAGS), + GATE(PCLK_HSPERI_ROOT, "pclk_hsperi_root", "hclk_hsperi_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(17), 2, GFLAGS), + COMPOSITE(CCLK_SRC_SDMMC, "cclk_src_sdmmc", cclk_src_sdmmc_parents_p, 0, + RK3506_CLKSEL_CON(49), 13, 2, MFLAGS, 7, 6, DFLAGS, + RK3506_CLKGATE_CON(17), 6, GFLAGS), + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 7, GFLAGS), + GATE(HCLK_FSPI, "hclk_fspi", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 8, GFLAGS), + COMPOSITE(SCLK_FSPI, "sclk_fspi", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(50), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(17), 9, GFLAGS), + GATE(PCLK_SPI2, "pclk_spi2", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 10, GFLAGS), + GATE(ACLK_MAC0, "aclk_mac0", "aclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 11, GFLAGS), + GATE(ACLK_MAC1, "aclk_mac1", "aclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 12, GFLAGS), + GATE(PCLK_MAC0, "pclk_mac0", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 13, GFLAGS), + GATE(PCLK_MAC1, "pclk_mac1", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 14, GFLAGS), + COMPOSITE_NOMUX(CLK_MAC_ROOT, "clk_mac_root", "gpll", 0, + RK3506_CLKSEL_CON(50), 7, 5, DFLAGS, + RK3506_CLKGATE_CON(17), 15, GFLAGS), + GATE(CLK_MAC0, "clk_mac0", "clk_mac_root", 0, + RK3506_CLKGATE_CON(18), 0, GFLAGS), + GATE(CLK_MAC1, "clk_mac1", "clk_mac_root", 0, + RK3506_CLKGATE_CON(18), 1, GFLAGS), + COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(51), 8, 4, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(18), 2, GFLAGS), + GATE(HCLK_SAI2, "hclk_sai2", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(18), 3, GFLAGS), + GATE(MCLK_OUT_SAI2, "mclk_out_sai2", "mclk_sai2", 0, + RK3506_CLKGATE_CON(18), 4, GFLAGS), + COMPOSITE(MCLK_SAI3_SRC, "mclk_sai3_src", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(52), 8, 4, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(18), 5, GFLAGS), + GATE(HCLK_SAI3, "hclk_sai3", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(18), 6, GFLAGS), + GATE(MCLK_SAI3, "mclk_sai3", "mclk_sai3_src", 0, + RK3506_CLKGATE_CON(18), 7, GFLAGS), + GATE(MCLK_OUT_SAI3, "mclk_out_sai3", "mclk_sai3_src", 0, + RK3506_CLKGATE_CON(18), 8, GFLAGS), + COMPOSITE(MCLK_SAI4_SRC, "mclk_sai4_src", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(53), 8, 4, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(18), 9, GFLAGS), + GATE(HCLK_SAI4, "hclk_sai4", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(18), 10, GFLAGS), + GATE(MCLK_SAI4, "mclk_sai4", "mclk_sai4_src", 0, + RK3506_CLKGATE_CON(18), 11, GFLAGS), + GATE(HCLK_DSM, "hclk_dsm", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(18), 12, GFLAGS), + GATE(MCLK_DSM, "mclk_dsm", "mclk_sai3_src", 0, + RK3506_CLKGATE_CON(18), 13, GFLAGS), + GATE(PCLK_AUDIO_ADC, "pclk_audio_adc", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(18), 14, GFLAGS), + GATE(MCLK_AUDIO_ADC, "mclk_audio_adc", "mclk_sai4_src", 0, + RK3506_CLKGATE_CON(18), 15, GFLAGS), + FACTOR(MCLK_AUDIO_ADC_DIV4, "mclk_audio_adc_div4", "mclk_audio_adc", 0, 1, 4), + GATE(PCLK_SARADC, "pclk_saradc", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(19), 0, GFLAGS), + COMPOSITE(CLK_SARADC, "clk_saradc", xin24m_400k_32k_parents_p, 0, + RK3506_CLKSEL_CON(54), 4, 2, MFLAGS, 0, 4, DFLAGS, + RK3506_CLKGATE_CON(19), 1, GFLAGS), + GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(19), 3, GFLAGS), + GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m_gate", 0, + RK3506_CLKGATE_CON(19), 4, GFLAGS), + FACTOR(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "clk_sbpi_otpc_ns", 0, 1, 2), + GATE(PCLK_UART5, "pclk_uart5", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(19), 6, GFLAGS), + COMPOSITE(SCLK_UART5, "sclk_uart5", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(54), 11, 3, MFLAGS, 6, 5, DFLAGS, + RK3506_CLKGATE_CON(19), 7, GFLAGS), + GATE(PCLK_GPIO234_IOC, "pclk_gpio234_ioc", "pclk_hsperi_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(19), 8, GFLAGS), + COMPOSITE(CLK_MAC_PTP_ROOT, "clk_mac_ptp_root", clk_mac_ptp_root_parents_p, 0, + RK3506_CLKSEL_CON(55), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(19), 9, GFLAGS), + GATE(CLK_MAC0_PTP, "clk_mac0_ptp", "clk_mac_ptp_root", 0, + RK3506_CLKGATE_CON(19), 10, GFLAGS), + GATE(CLK_MAC1_PTP, "clk_mac1_ptp", "clk_mac_ptp_root", 0, + RK3506_CLKGATE_CON(19), 11, GFLAGS), + COMPOSITE(ACLK_VIO_ROOT, "aclk_vio_root", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(58), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(21), 0, GFLAGS), + COMPOSITE(HCLK_VIO_ROOT, "hclk_vio_root", gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(58), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(21), 1, GFLAGS), + GATE(PCLK_VIO_ROOT, "pclk_vio_root", "hclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 2, GFLAGS), + GATE(HCLK_RGA, "hclk_rga", "hclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 6, GFLAGS), + GATE(ACLK_RGA, "aclk_rga", "aclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 7, GFLAGS), + COMPOSITE(CLK_CORE_RGA, "clk_core_rga", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(59), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(21), 8, GFLAGS), + GATE(ACLK_VOP, "aclk_vop", "aclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 9, GFLAGS), + GATE(HCLK_VOP, "hclk_vop", "hclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 10, GFLAGS), + COMPOSITE(DCLK_VOP, "dclk_vop", dclk_vop_parents_p, 0, + RK3506_CLKSEL_CON(60), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(21), 11, GFLAGS), + GATE(PCLK_DPHY, "pclk_dphy", "pclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 12, GFLAGS), + GATE(PCLK_DSI_HOST, "pclk_dsi_host", "pclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 13, GFLAGS), + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 14, GFLAGS), + COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m_gate", 0, + RK3506_CLKSEL_CON(61), 0, 8, DFLAGS, + RK3506_CLKGATE_CON(21), 15, GFLAGS), + COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m_gate", 0, + RK3506_CLKSEL_CON(61), 8, 3, DFLAGS, + RK3506_CLKGATE_CON(22), 0, GFLAGS), + GATE(PCLK_GPIO1_IOC, "pclk_gpio1_ioc", "pclk_vio_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(22), 1, GFLAGS), + + /* pmu */ + GATE(CLK_PMU, "clk_pmu", "xin24m", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 1, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_root", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 2, GFLAGS), + GATE(PCLK_PMU_CRU, "pclk_pmu_cru", "pclk_pmu_root", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 4, GFLAGS), + GATE(PCLK_PMU_GRF, "pclk_pmu_grf", "pclk_pmu_root", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 5, GFLAGS), + GATE(PCLK_GPIO0_IOC, "pclk_gpio0_ioc", "pclk_pmu_root", CLK_IS_CRITICAL, + RK3506_PMU_CLKGATE_CON(0), 7, GFLAGS), + GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu_root", 0, + RK3506_PMU_CLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", dbclk_gpio0_parents_p, 0, + RK3506_PMU_CLKSEL_CON(0), 0, 2, MFLAGS, + RK3506_PMU_CLKGATE_CON(0), 9, GFLAGS), + GATE(PCLK_GPIO1_SHADOW, "pclk_gpio1_shadow", "pclk_pmu_root", 0, + RK3506_PMU_CLKGATE_CON(0), 10, GFLAGS), + COMPOSITE_NODIV(DBCLK_GPIO1_SHADOW, "dbclk_gpio1_shadow", dbclk_gpio0_parents_p, 0, + RK3506_PMU_CLKSEL_CON(0), 2, 2, MFLAGS, + RK3506_PMU_CLKGATE_CON(0), 11, GFLAGS), + GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "pclk_pmu_root", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 12, GFLAGS), + MUX(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", clk_pmu_hp_timer_parents_p, CLK_IGNORE_UNUSED, + RK3506_PMU_CLKSEL_CON(0), 4, 2, MFLAGS), + GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pmu_root", 0, + RK3506_PMU_CLKGATE_CON(0), 15, GFLAGS), + COMPOSITE_NOMUX(CLK_PWM0, "clk_pwm0", "clk_gpll_div_100m", 0, + RK3506_PMU_CLKSEL_CON(0), 6, 4, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 0, GFLAGS), + GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0, + RK3506_PMU_CLKGATE_CON(1), 1, GFLAGS), + GATE(CLK_RC_PWM0, "clk_rc_pwm0", "clk_rc", 0, + RK3506_PMU_CLKGATE_CON(1), 2, GFLAGS), + COMPOSITE_NOMUX(CLK_MAC_OUT, "clk_mac_out", "gpll", 0, + RK3506_PMU_CLKSEL_CON(0), 10, 6, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 3, GFLAGS), + COMPOSITE(CLK_REF_OUT0, "clk_ref_out0", clk_ref_out_parents_p, 0, + RK3506_PMU_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 4, GFLAGS), + COMPOSITE(CLK_REF_OUT1, "clk_ref_out1", clk_ref_out_parents_p, 0, + RK3506_PMU_CLKSEL_CON(1), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 5, GFLAGS), + MUX(CLK_32K_FRAC_MUX, "clk_32k_frac_mux", clk_32k_frac_parents_p, 0, + RK3506_PMU_CLKSEL_CON(3), 0, 2, MFLAGS), + COMPOSITE_FRAC(CLK_32K_FRAC, "clk_32k_frac", "clk_32k_frac_mux", 0, + RK3506_PMU_CLKSEL_CON(2), 0, + RK3506_PMU_CLKGATE_CON(1), 6, GFLAGS), + COMPOSITE_NOMUX(CLK_32K_RC, "clk_32k_rc", "clk_rc", CLK_IS_CRITICAL, + RK3506_PMU_CLKSEL_CON(3), 2, 5, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 7, GFLAGS), + COMPOSITE_NODIV(CLK_32K, "clk_32k", clk_32k_parents_p, CLK_IS_CRITICAL, + RK3506_PMU_CLKSEL_CON(3), 7, 2, MFLAGS, + RK3506_PMU_CLKGATE_CON(1), 8, GFLAGS), + COMPOSITE_NODIV(CLK_32K_PMU, "clk_32k_pmu", clk_32k_parents_p, CLK_IS_CRITICAL, + RK3506_PMU_CLKSEL_CON(3), 9, 2, MFLAGS, + RK3506_PMU_CLKGATE_CON(1), 9, GFLAGS), + GATE(CLK_PMU_32K, "clk_pmu_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 3, GFLAGS), + GATE(CLK_PMU_HP_TIMER_32K, "clk_pmu_hp_timer_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 14, GFLAGS), + GATE(PCLK_TOUCH_KEY, "pclk_touch_key", "pclk_pmu_root", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(1), 12, GFLAGS), + GATE(CLK_TOUCH_KEY, "clk_touch_key", "xin24m", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(1), 13, GFLAGS), + COMPOSITE(CLK_REF_PHY_PLL, "clk_ref_phy_pll", gpll_v0pll_v1pll_parents_p, 0, + RK3506_PMU_CLKSEL_CON(4), 13, 2, MFLAGS, 6, 7, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 14, GFLAGS), + MUX(CLK_REF_PHY_PMU_MUX, "clk_ref_phy_pmu_mux", clk_ref_phy_pmu_mux_parents_p, 0, + RK3506_PMU_CLKSEL_CON(4), 15, 1, MFLAGS), + GATE(CLK_WIFI_OUT, "clk_wifi_out", "xin24m", 0, + RK3506_PMU_CLKGATE_CON(2), 0, GFLAGS), + MUX(CLK_V0PLL_REF, "clk_v0pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED, + RK3506_PMU_CLKSEL_CON(6), 0, 1, MFLAGS), + MUX(CLK_V1PLL_REF, "clk_v1pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED, + RK3506_PMU_CLKSEL_CON(6), 1, 1, MFLAGS), + + /* secure ns */ + GATE(CLK_CORE_CRYPTO_NS, "clk_core_crypto_ns", "clk_core_crypto", 0, + RK3506_CLKGATE_CON(5), 12, GFLAGS), + GATE(CLK_PKA_CRYPTO_NS, "clk_pka_crypto_ns", "clk_pka_crypto", 0, + RK3506_CLKGATE_CON(5), 13, GFLAGS), + + /* io */ + GATE(CLK_SPI2, "clk_spi2", "clk_spi2_io", 0, + RK3506_CLKGATE_CON(20), 0, GFLAGS), +}; + +static void __init rk3506_clk_init(struct device_node *np) +{ + struct rockchip_clk_provider *ctx; + unsigned long clk_nr_clks; + void __iomem *reg_base; + + clk_nr_clks = rockchip_clk_find_max_clk_id(rk3506_clk_branches, + ARRAY_SIZE(rk3506_clk_branches)) + 1; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: could not map cru region\n", __func__); + return; + } + + ctx = rockchip_clk_init(np, reg_base, clk_nr_clks); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); + return; + } + + rockchip_clk_register_plls(ctx, rk3506_pll_clks, + ARRAY_SIZE(rk3506_pll_clks), + 0); + + rockchip_clk_register_armclk_multi_pll(ctx, &rk3506_armclk, + rk3506_cpuclk_rates, + ARRAY_SIZE(rk3506_cpuclk_rates)); + + rockchip_clk_register_branches(ctx, rk3506_clk_branches, + ARRAY_SIZE(rk3506_clk_branches)); + + rk3506_rst_init(np, reg_base); + + rockchip_register_restart_notifier(ctx, RK3506_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); + + /* pvtpll src init */ + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RK3506_CLKSEL_CON(15)); +} + +CLK_OF_DECLARE(rk3506_cru, "rockchip,rk3506-cru", rk3506_clk_init); + +struct clk_rk3506_inits { + void (*inits)(struct device_node *np); +}; + +static const struct clk_rk3506_inits clk_rk3506_cru_init = { + .inits = rk3506_clk_init, +}; + +static const struct of_device_id clk_rk3506_match_table[] = { + { + .compatible = "rockchip,rk3506-cru", + .data = &clk_rk3506_cru_init, + }, + { } +}; + +static int clk_rk3506_probe(struct platform_device *pdev) +{ + const struct clk_rk3506_inits *init_data; + struct device *dev = &pdev->dev; + + init_data = device_get_match_data(dev); + if (!init_data) + return -EINVAL; + + if (init_data->inits) + init_data->inits(dev->of_node); + + return 0; +} + +static struct platform_driver clk_rk3506_driver = { + .probe = clk_rk3506_probe, + .driver = { + .name = "clk-rk3506", + .of_match_table = clk_rk3506_match_table, + .suppress_bind_attrs = true, + }, +}; +builtin_platform_driver_probe(clk_rk3506_driver, clk_rk3506_probe); diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c index 97d279399ae84..74eabf9b2ae2e 100644 --- a/drivers/clk/rockchip/clk-rk3568.c +++ b/drivers/clk/rockchip/clk-rk3568.c @@ -1652,6 +1652,7 @@ CLK_OF_DECLARE(rk3568_cru_pmu, "rockchip,rk3568-pmucru", rk3568_pmu_clk_init); static void __init rk3568_clk_init(struct device_node *np) { struct rockchip_clk_provider *ctx; + unsigned long clk_nr_clks; void __iomem *reg_base; reg_base = of_iomap(np, 0); @@ -1660,7 +1661,9 @@ static void __init rk3568_clk_init(struct device_node *np) return; } - ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + clk_nr_clks = rockchip_clk_find_max_clk_id(rk3568_clk_branches, + ARRAY_SIZE(rk3568_clk_branches)) + 1; + ctx = rockchip_clk_init(np, reg_base, clk_nr_clks); if (IS_ERR(ctx)) { pr_err("%s: rockchip clk init failed\n", __func__); iounmap(reg_base); diff --git a/drivers/clk/rockchip/clk-rv1126b.c b/drivers/clk/rockchip/clk-rv1126b.c new file mode 100644 index 0000000000000..3e27bfc14854f --- /dev/null +++ b/drivers/clk/rockchip/clk-rv1126b.c @@ -0,0 +1,1117 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + * Author: Elaine Zhang + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define RV1126B_FRAC_MAX_PRATE 1200000000 + +#define PVTPLL_SRC_SEL_PVTPLL (BIT(0) | BIT(16)) + +enum rv1126b_plls { + gpll, cpll, aupll, dpll +}; + +static struct rockchip_pll_rate_table rv1126b_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137), + RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0), + RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355), + RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127), + RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185), + { /* sentinel */ }, +}; + +#define RV1126B_DIV_ACLK_CORE_MASK 0x1f +#define RV1126B_DIV_ACLK_CORE_SHIFT 0 +#define RV1126B_DIV_PCLK_CORE_MASK 0x1f +#define RV1126B_DIV_PCLK_CORE_SHIFT 8 +#define RV1126B_CORE_SEL_MASK 0x1 +#define RV1126B_CORE_SEL_SHIFT 1 + +#define RV1126B_CLKSEL0(_aclk_core) \ +{ \ + .reg = RV1126B_CORECLKSEL_CON(2), \ + .val = HIWORD_UPDATE(_aclk_core - 1, RV1126B_DIV_ACLK_CORE_MASK, \ + RV1126B_DIV_ACLK_CORE_SHIFT), \ +} + +#define RV1126B_CLKSEL1(_pclk_dbg) \ +{ \ + .reg = RV1126B_CORECLKSEL_CON(2), \ + .val = HIWORD_UPDATE(_pclk_dbg - 1, RV1126B_DIV_PCLK_CORE_MASK, \ + RV1126B_DIV_PCLK_CORE_SHIFT), \ +} + +#define RV1126B_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg) \ +{ \ + .prate = _prate, \ + .divs = { \ + RV1126B_CLKSEL0(_aclk_core), \ + RV1126B_CLKSEL1(_pclk_dbg), \ + }, \ +} + +static struct rockchip_cpuclk_rate_table rv1126b_cpuclk_rates[] __initdata = { + RV1126B_CPUCLK_RATE(1608000000, 4, 10), + RV1126B_CPUCLK_RATE(1512000000, 4, 10), + RV1126B_CPUCLK_RATE(1416000000, 4, 10), + RV1126B_CPUCLK_RATE(1296000000, 3, 10), + RV1126B_CPUCLK_RATE(1200000000, 3, 10), + RV1126B_CPUCLK_RATE(1188000000, 3, 8), + RV1126B_CPUCLK_RATE(1104000000, 2, 8), + RV1126B_CPUCLK_RATE(1008000000, 2, 8), + RV1126B_CPUCLK_RATE(816000000, 2, 6), + RV1126B_CPUCLK_RATE(600000000, 2, 4), + RV1126B_CPUCLK_RATE(594000000, 2, 4), + RV1126B_CPUCLK_RATE(408000000, 1, 3), + RV1126B_CPUCLK_RATE(396000000, 1, 3), +}; + +PNAME(mux_pll_p) = { "xin24m" }; +PNAME(mux_gpll_cpll_p) = { "gpll", "cpll" }; +PNAME(mux_gpll_aupll_p) = { "gpll", "aupll" }; +PNAME(mux_gpll_aupll_cpll_p) = { "gpll", "aupll", "cpll" }; +PNAME(mux_gpll_cpll_24m_p) = { "gpll", "cpll", "xin24m" }; +PNAME(mux_cpll_24m_p) = { "cpll", "xin24m" }; +PNAME(mux_24m_gpll_aupll_cpll_p) = { "xin24m", "gpll", "aupll", "cpll" }; +PNAME(mux_24m_gpll_cpll_p) = { "xin24m", "gpll", "cpll" }; +PNAME(mux_24m_gpll_aupll_p) = { "xin24m", "gpll", "aupll" }; +PNAME(mux_sclk_uart_src_p) = { "xin24m", "clk_cm_frac0", "clk_cm_frac1", + "clk_cm_frac2", "clk_uart_frac0", "clk_uart_frac1" }; +PNAME(mclk_sai0_src_p) = { "xin24m", "clk_cm_frac0", "clk_cm_frac1", + "clk_cm_frac2", "clk_audio_frac0", "clk_audio_frac1", + "clk_audio_int0", "clk_audio_int1", + "mclk_sai0_from_io" }; +PNAME(mclk_sai1_src_p) = { "xin24m", "clk_cm_frac0", "clk_cm_frac1", + "clk_cm_frac2", "clk_audio_frac0", "clk_audio_frac1", + "clk_audio_int0", "clk_audio_int1", + "mclk_sai1_from_io" }; +PNAME(mclk_sai2_src_p) = { "xin24m", "clk_cm_frac0", "clk_cm_frac1", + "clk_cm_frac2", "clk_audio_frac0", "clk_audio_frac1", + "clk_audio_int0", "clk_audio_int1", + "mclk_sai2_from_io" }; +PNAME(mux_sai_src_p) = { "xin24m", "clk_cm_frac0", "clk_cm_frac1", + "clk_cm_frac2", "clk_audio_frac0", "clk_audio_frac1", + "clk_audio_int0", "clk_audio_int1", "mclk_sai0_from_io", + "mclk_sai1_from_io", "mclk_sai2_from_io"}; +PNAME(mux_100m_24m_p) = { "clk_cpll_div10", "xin24m" }; +PNAME(mux_200m_24m_p) = { "clk_gpll_div6", "xin24m" }; +PNAME(mux_500m_400m_200m_p) = { "clk_cpll_div2", "clk_gpll_div3", "clk_gpll_div6" }; +PNAME(mux_300m_200m_p) = { "clk_gpll_div4", "clk_gpll_div6" }; +PNAME(mux_500m_400m_300m_p) = { "clk_cpll_div2", "clk_gpll_div3", "clk_gpll_div4" }; +PNAME(mux_333m_200m_p) = { "clk_cpll_div3", "clk_gpll_div6" }; +PNAME(mux_600m_400m_200m_p) = { "clk_gpll_div2", "clk_gpll_div3", "clk_gpll_div6" }; +PNAME(mux_400m_300m_200m_p) = { "clk_gpll_div3", "clk_gpll_div4", "clk_gpll_div6" }; +PNAME(mux_200m_100m_p) = { "clk_gpll_div6", "clk_cpll_div10" }; +PNAME(mux_200m_100m_50m_24m_p) = { "clk_gpll_div6", "clk_cpll_div10", "clk_cpll_div20", + "xin24m" }; +PNAME(mux_600m_24m_p) = { "clk_gpll_div2", "xin24m" }; +PNAME(mux_armclk_p) = { "clk_core_pll", "clk_core_pvtpll" }; +PNAME(aclk_npu_root_p) = { "clk_npu_pll", "clk_npu_pvtpll" }; +PNAME(clk_saradc0_p) = { "clk_saradc0_src", "clk_saradc0_rcosc_io" }; +PNAME(clk_core_vepu_p) = { "clk_vepu_pll", "clk_vepu_pvtpll" }; +PNAME(clk_core_fec_p) = { "clk_core_fec_src", "clk_vcp_pvtpll" }; +PNAME(clk_core_aisp_p) = { "clk_aisp_pll", "clk_vcp_pvtpll" }; +PNAME(clk_core_isp_root_p) = { "clk_isp_pll", "clk_isp_pvtpll" }; +PNAME(clk_gmac_ptp_ref_p) = { "clk_gmac_ptp_ref_src", "clk_gmac_ptp_from_io" }; +PNAME(clk_saradc1_p) = { "clk_saradc1_src", "clk_saradc1_rcosc_io" }; +PNAME(clk_saradc2_p) = { "clk_saradc2_src", "clk_saradc2_rcosc_io" }; +PNAME(clk_rcosc_src_p) = { "xin24m", "clk_rcosc", "clk_rcosc_div2", + "clk_rcosc_div3", "clk_rcosc_div4" }; +PNAME(busclk_pmu_mux_p) = { "clk_cpll_div10", "clk_rcosc_src" }; +PNAME(clk_xin_rc_div_p) = { "xin24m", "clk_rcosc_src" }; +PNAME(clk_32k_p) = { "clk_xin_rc_div", "clk_32k_rtc", "clk_32k_io" }; +PNAME(mux_24m_32k_p) = { "xin24m", "clk_32k" }; +PNAME(mux_24m_rcosc_buspmu_p) = { "xin24m", "clk_rcosc_src", "busclk_pmu_src" }; +PNAME(mux_24m_rcosc_buspmu_32k_p) = { "xin24m", "clk_rcosc_src", "busclk_pmu_src", + "clk_32k" }; +PNAME(sclk_uart0_p) = { "sclk_uart0_src", "xin24m", "clk_rcosc_src" }; +PNAME(clk_osc_rcosc_ctrl_p) = { "clk_rcosc_src", "clk_testout_out" }; +PNAME(lrck_src_asrc_p) = { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", + "fs_inter_from_sai0", "fs_inter_from_sai1", + "fs_inter_from_sai2", "clkout_pdm"}; +PNAME(clk_ref_pipephy_p) = { "clk_ref_pipephy_cpll_src", "xin24m" }; +PNAME(clk_timer0_parents_p) = { "clk_timer_root", "mclk_sai0_from_io", + "sclk_sai0_from_io" }; +PNAME(clk_timer1_parents_p) = { "clk_timer_root", "mclk_sai1_from_io", + "sclk_sai1_from_io" }; +PNAME(clk_timer2_parents_p) = { "clk_timer_root", "mclk_sai2_from_io", + "sclk_sai2_from_io" }; +PNAME(clk_timer3_parents_p) = { "clk_timer_root", "mclk_asrc0", "mclk_asrc1" }; +PNAME(clk_timer4_parents_p) = { "clk_timer_root", "mclk_asrc2", "mclk_asrc3" }; +PNAME(clk_macphy_p) = { "xin24m", "clk_cpll_div20" }; +PNAME(clk_cpll_div10_p) = { "gpll", "clk_aisp_pll_src" }; + +static struct rockchip_pll_clock rv1126b_pll_clks[] __initdata = { + [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p, + CLK_IS_CRITICAL, RV1126B_PLL_CON(8), + RV1126B_MODE_CON, 2, 10, 0, rv1126b_pll_rates), + [aupll] = PLL(pll_rk3328, PLL_AUPLL, "aupll", mux_pll_p, + CLK_IS_CRITICAL, RV1126B_PLL_CON(0), + RV1126B_MODE_CON, 0, 10, 0, rv1126b_pll_rates), + [cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p, + CLK_IS_CRITICAL, RV1126B_PERIPLL_CON(0), + RV1126B_MODE_CON, 4, 10, 0, rv1126b_pll_rates), + [dpll] = PLL(pll_rk3328, 0, "dpll", mux_pll_p, + CLK_IS_CRITICAL, RV1126B_SUBDDRPLL_CON(0), + RV1126B_MODE_CON, 2, 10, 0, rv1126b_pll_rates), +}; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_clk_branch rv1126b_rcdiv_pmu_fracmux __initdata = + MUX(CLK_32K, "clk_32k", clk_32k_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + RV1126B_PMUCLKSEL_CON(2), 1, 2, MFLAGS); + +static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = { + + FACTOR(0, "clk_rcosc_div2", "clk_rcosc", 0, 1, 2), + FACTOR(0, "clk_rcosc_div3", "clk_rcosc", 0, 1, 3), + FACTOR(0, "clk_rcosc_div4", "clk_rcosc", 0, 1, 4), + + /* Clock Definition */ + COMPOSITE_NODIV(CLK_AISP_PLL_SRC, "clk_aisp_pll_src", mux_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(62), 4, 2, MFLAGS, + RV1126B_CLKGATE_CON(5), 4, GFLAGS), + DIV(CLK_AISP_PLL, "clk_aisp_pll", "clk_aisp_pll_src", 0, + RV1126B_CLKSEL_CON(62), 0, 3, DFLAGS), + + COMPOSITE(CLK_CPLL_DIV10, "clk_cpll_div10", clk_cpll_div10_p, 0, + RV1126B_CLKSEL_CON(1), 15, 1, MFLAGS, 5, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 1, GFLAGS), + COMPOSITE_NOMUX(CLK_CPLL_DIV20, "clk_cpll_div20", "cpll", 0, + RV1126B_CLKSEL_CON(1), 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NOMUX(CLK_CPLL_DIV8, "clk_cpll_div8", "cpll", 0, + RV1126B_CLKSEL_CON(1), 10, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 2, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV8, "clk_gpll_div8", "gpll", 0, + RV1126B_CLKSEL_CON(2), 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 3, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV6, "clk_gpll_div6", "gpll", 0, + RV1126B_CLKSEL_CON(2), 5, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 4, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV4, "clk_gpll_div4", "gpll", 0, + RV1126B_CLKSEL_CON(2), 10, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 5, GFLAGS), + COMPOSITE_NOMUX(CLK_CPLL_DIV3, "clk_cpll_div3", "cpll", 0, + RV1126B_CLKSEL_CON(3), 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 6, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV3, "clk_gpll_div3", "gpll", 0, + RV1126B_CLKSEL_CON(3), 5, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 7, GFLAGS), + COMPOSITE_NOMUX(CLK_CPLL_DIV2, "clk_cpll_div2", "cpll", 0, + RV1126B_CLKSEL_CON(3), 10, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV2, "clk_gpll_div2", "gpll", 0, + RV1126B_CLKSEL_CON(4), 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 9, GFLAGS), + MUX(CLK_CM_FRAC0_SRC, "clk_cm_frac0_src", mux_24m_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(10), 0, 2, MFLAGS), + COMPOSITE_FRAC(CLK_CM_FRAC0, "clk_cm_frac0", "clk_cm_frac0_src", 0, + RV1126B_CLKSEL_CON(25), 0, + RV1126B_CLKGATE_CON(1), 0, GFLAGS), + MUX(CLK_CM_FRAC1_SRC, "clk_cm_frac1_src", mux_24m_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(10), 2, 2, MFLAGS), + COMPOSITE_FRAC(CLK_CM_FRAC1, "clk_cm_frac1", "clk_cm_frac1_src", 0, + RV1126B_CLKSEL_CON(26), 0, + RV1126B_CLKGATE_CON(1), 1, GFLAGS), + MUX(CLK_CM_FRAC2_SRC, "clk_cm_frac2_src", mux_24m_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(10), 4, 2, MFLAGS), + COMPOSITE_FRAC(CLK_CM_FRAC2, "clk_cm_frac2", "clk_cm_frac2_src", 0, + RV1126B_CLKSEL_CON(27), 0, + RV1126B_CLKGATE_CON(1), 2, GFLAGS), + MUX(CLK_UART_FRAC0_SRC, "clk_uart_frac0_src", mux_24m_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(10), 6, 2, MFLAGS), + COMPOSITE_FRAC(CLK_UART_FRAC0, "clk_uart_frac0", "clk_uart_frac0_src", 0, + RV1126B_CLKSEL_CON(28), 0, + RV1126B_CLKGATE_CON(1), 3, GFLAGS), + MUX(CLK_UART_FRAC1_SRC, "clk_uart_frac1_src", mux_24m_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(10), 8, 2, MFLAGS), + COMPOSITE_FRAC(CLK_UART_FRAC1, "clk_uart_frac1", "clk_uart_frac1_src", 0, + RV1126B_CLKSEL_CON(29), 0, + RV1126B_CLKGATE_CON(1), 4, GFLAGS), + MUX(CLK_AUDIO_FRAC0_SRC, "clk_audio_frac0_src", mux_24m_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(10), 10, 2, MFLAGS), + COMPOSITE_FRAC(CLK_AUDIO_FRAC0, "clk_audio_frac0", "clk_audio_frac0_src", 0, + RV1126B_CLKSEL_CON(30), 0, + RV1126B_CLKGATE_CON(1), 5, GFLAGS), + MUX(CLK_AUDIO_FRAC1_SRC, "clk_audio_frac1_src", mux_24m_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(10), 12, 2, MFLAGS), + COMPOSITE_FRAC(CLK_AUDIO_FRAC1, "clk_audio_frac1", "clk_audio_frac1_src", 0, + RV1126B_CLKSEL_CON(31), 0, + RV1126B_CLKGATE_CON(1), 6, GFLAGS), + COMPOSITE(CLK_AUDIO_INT0, "clk_audio_int0", mux_24m_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 7, GFLAGS), + COMPOSITE(CLK_AUDIO_INT1, "clk_audio_int1", mux_24m_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 8, GFLAGS), + COMPOSITE(SCLK_UART0_SRC, "sclk_uart0_src", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(12), 5, 3, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 9, GFLAGS), + COMPOSITE(SCLK_UART1, "sclk_uart1", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(12), 13, 3, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 10, GFLAGS), + COMPOSITE(SCLK_UART2, "sclk_uart2", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(13), 5, 3, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 11, GFLAGS), + COMPOSITE(SCLK_UART3, "sclk_uart3", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(13), 13, 3, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 12, GFLAGS), + COMPOSITE(SCLK_UART4, "sclk_uart4", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(14), 5, 3, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 13, GFLAGS), + COMPOSITE(SCLK_UART5, "sclk_uart5", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(14), 13, 3, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 14, GFLAGS), + COMPOSITE(SCLK_UART6, "sclk_uart6", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(15), 5, 3, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(2), 0, GFLAGS), + COMPOSITE(SCLK_UART7, "sclk_uart7", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(15), 13, 3, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(2), 1, GFLAGS), + COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai0_src_p, 0, + RV1126B_CLKSEL_CON(16), 8, 4, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(2), 2, GFLAGS), + COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai1_src_p, 0, + RV1126B_CLKSEL_CON(17), 8, 4, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(2), 3, GFLAGS), + COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai2_src_p, 0, + RV1126B_CLKSEL_CON(18), 8, 4, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(2), 4, GFLAGS), + COMPOSITE(MCLK_PDM, "mclk_pdm", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(19), 6, 4, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(2), 5, GFLAGS), + COMPOSITE_NOGATE(0, "clkout_pdm_src", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(20), 8, 4, MFLAGS, 0, 8, DFLAGS), + GATE(CLKOUT_PDM, "clkout_pdm", "clkout_pdm_src", 0, + RV1126B_CLKGATE_CON(2), 6, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(16), 12, 4, MFLAGS, + RV1126B_CLKGATE_CON(2), 7, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(17), 12, 4, MFLAGS, + RV1126B_CLKGATE_CON(2), 8, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(18), 12, 4, MFLAGS, + RV1126B_CLKGATE_CON(2), 9, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(19), 12, 4, MFLAGS, + RV1126B_CLKGATE_CON(2), 10, GFLAGS), + COMPOSITE(CLK_ASRC0, "clk_asrc0", mux_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(21), 6, 1, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(2), 11, GFLAGS), + COMPOSITE(CLK_ASRC1, "clk_asrc1", mux_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(21), 14, 1, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(2), 12, GFLAGS), + COMPOSITE_NOMUX(CLK_CORE_PLL, "clk_core_pll", "gpll", CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(60), 0, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 0, GFLAGS), + COMPOSITE_NOMUX(CLK_NPU_PLL, "clk_npu_pll", "gpll", CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(60), 6, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 1, GFLAGS), + COMPOSITE(CLK_VEPU_PLL, "clk_vepu_pll", mux_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(61), 4, 2, MFLAGS, 0, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 2, GFLAGS), + COMPOSITE(CLK_ISP_PLL, "clk_isp_pll", mux_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(61), 10, 2, MFLAGS, 6, 4, DFLAGS, + RV1126B_CLKGATE_CON(5), 3, GFLAGS), + COMPOSITE(CLK_SARADC0_SRC, "clk_saradc0_src", mux_200m_24m_p, 0, + RV1126B_CLKSEL_CON(63), 12, 1, MFLAGS, 0, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 6, GFLAGS), + COMPOSITE(CLK_SARADC1_SRC, "clk_saradc1_src", mux_200m_24m_p, 0, + RV1126B_CLKSEL_CON(63), 13, 1, MFLAGS, 4, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 7, GFLAGS), + COMPOSITE(CLK_SARADC2_SRC, "clk_saradc2_src", mux_200m_24m_p, 0, + RV1126B_CLKSEL_CON(63), 14, 1, MFLAGS, 8, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 8, GFLAGS), + GATE(HCLK_RKNN, "hclk_rknn", "clk_gpll_div8", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(5), 10, GFLAGS), + GATE(PCLK_NPU_ROOT, "pclk_npu_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(5), 11, GFLAGS), + COMPOSITE_NODIV(ACLK_VEPU_ROOT, "aclk_vepu_root", mux_500m_400m_200m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(40), 0, 2, MFLAGS, + RV1126B_CLKGATE_CON(5), 12, GFLAGS), + GATE(HCLK_VEPU_ROOT, "hclk_vepu_root", "clk_gpll_div8", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(5), 13, GFLAGS), + GATE(PCLK_VEPU_ROOT, "pclk_vepu_root", "clk_cpll_div10", 0, + RV1126B_CLKGATE_CON(5), 14, GFLAGS), + COMPOSITE(CLK_CORE_RGA_SRC, "clk_core_rga_src", mux_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(40), 5, 1, MFLAGS, 2, 3, DFLAGS, + RV1126B_CLKGATE_CON(6), 0, GFLAGS), + COMPOSITE_NODIV(ACLK_GMAC_ROOT, "aclk_gmac_root", mux_300m_200m_p, 0, + RV1126B_CLKSEL_CON(40), 6, 1, MFLAGS, + RV1126B_CLKGATE_CON(6), 1, GFLAGS), + COMPOSITE_NODIV(ACLK_VI_ROOT, "aclk_vi_root", mux_500m_400m_300m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(40), 7, 2, MFLAGS, + RV1126B_CLKGATE_CON(6), 2, GFLAGS), + GATE(HCLK_VI_ROOT, "hclk_vi_root", "clk_gpll_div8", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(6), 3, GFLAGS), + GATE(PCLK_VI_ROOT, "pclk_vi_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(6), 4, GFLAGS), + COMPOSITE_NODIV(DCLK_VICAP_ROOT, "dclk_vicap_root", mux_333m_200m_p, 0, + RV1126B_CLKSEL_CON(42), 5, 1, MFLAGS, + RV1126B_CLKGATE_CON(6), 5, GFLAGS), + COMPOSITE(CLK_SYS_DSMC_ROOT, "clk_sys_dsmc_root", mux_24m_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(40), 14, 2, MFLAGS, 9, 5, DFLAGS, + RV1126B_CLKGATE_CON(6), 6, GFLAGS), + COMPOSITE(ACLK_VDO_ROOT, "aclk_vdo_root", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(42), 4, 1, MFLAGS, 0, 4, DFLAGS, + RV1126B_CLKGATE_CON(6), 7, GFLAGS), + COMPOSITE(ACLK_RKVDEC_ROOT, "aclk_rkvdec_root", mux_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(42), 10, 1, MFLAGS, 6, 4, DFLAGS, + RV1126B_CLKGATE_CON(6), 8, GFLAGS), + GATE(HCLK_VDO_ROOT, "hclk_vdo_root", "clk_gpll_div8", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(6), 9, GFLAGS), + GATE(PCLK_VDO_ROOT, "pclk_vdo_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(6), 10, GFLAGS), + COMPOSITE(DCLK_VOP, "dclk_vop", mux_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(43), 8, 1, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(6), 12, GFLAGS), + COMPOSITE(DCLK_OOC_SRC, "dclk_ooc_src", mux_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(62), 7, 1, MFLAGS, 8, 8, DFLAGS, + RV1126B_CLKGATE_CON(6), 13, GFLAGS), + GATE(DCLK_DECOM_SRC, "dclk_decom_src", "clk_gpll_div3", 0, + RV1126B_CLKGATE_CON(6), 14, GFLAGS), + GATE(PCLK_DDR_ROOT, "pclk_ddr_root", "clk_cpll_div10", 0, + RV1126B_CLKGATE_CON(7), 0, GFLAGS), + COMPOSITE(ACLK_SYSMEM, "aclk_sysmem", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(44), 3, 1, MFLAGS, 0, 3, DFLAGS, + RV1126B_CLKGATE_CON(7), 1, GFLAGS), + COMPOSITE_NODIV(ACLK_TOP_ROOT, "aclk_top_root", mux_600m_400m_200m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(44), 6, 2, MFLAGS, + RV1126B_CLKGATE_CON(7), 3, GFLAGS), + COMPOSITE_NODIV(ACLK_BUS_ROOT, "aclk_bus_root", mux_400m_300m_200m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(44), 8, 2, MFLAGS, + RV1126B_CLKGATE_CON(7), 4, GFLAGS), + COMPOSITE_NODIV(HCLK_BUS_ROOT, "hclk_bus_root", mux_200m_100m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(44), 10, 1, MFLAGS, + RV1126B_CLKGATE_CON(7), 5, GFLAGS), + GATE(PCLK_BUS_ROOT, "pclk_bus_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(7), 6, GFLAGS), + COMPOSITE(CCLK_SDMMC0, "cclk_sdmmc0", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(45), 8, 2, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(7), 7, GFLAGS), + COMPOSITE(CCLK_SDMMC1, "cclk_sdmmc1", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(46), 8, 2, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(7), 8, GFLAGS), + COMPOSITE(CCLK_EMMC, "cclk_emmc", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(47), 8, 2, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(7), 9, GFLAGS), + COMPOSITE(SCLK_2X_FSPI0, "sclk_2x_fspi0", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(48), 8, 2, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(7), 10, GFLAGS), + COMPOSITE(CLK_GMAC_PTP_REF_SRC, "clk_gmac_ptp_ref_src", mux_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(45), 10, 1, MFLAGS, 11, 5, DFLAGS, + RV1126B_CLKGATE_CON(7), 11, GFLAGS), + GATE(CLK_GMAC_125M, "clk_gmac_125m", "clk_cpll_div8", 0, + RV1126B_CLKGATE_CON(7), 12, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER_ROOT, "clk_timer_root", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(46), 11, 1, MFLAGS, + RV1126B_CLKGATE_CON(7), 13, GFLAGS), + COMPOSITE_NODIV(TCLK_WDT_NS_SRC, "tclk_wdt_ns_src", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(46), 12, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 0, GFLAGS), + COMPOSITE_NODIV(TCLK_WDT_S_SRC, "tclk_wdt_s_src", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(46), 13, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 1, GFLAGS), + COMPOSITE_NODIV(TCLK_WDT_HPMCU, "tclk_wdt_hpmcu", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(46), 14, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 2, GFLAGS), + COMPOSITE(CLK_CAN0, "clk_can0", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(49), 6, 2, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(8), 4, GFLAGS), + COMPOSITE(CLK_CAN1, "clk_can1", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(49), 14, 2, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(8), 5, GFLAGS), + COMPOSITE_NODIV(PCLK_PERI_ROOT, "pclk_peri_root", mux_100m_24m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(47), 12, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 6, GFLAGS), + COMPOSITE_NODIV(ACLK_PERI_ROOT, "aclk_peri_root", mux_200m_24m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(47), 13, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 7, GFLAGS), + COMPOSITE_NODIV(CLK_I2C_BUS_SRC, "clk_i2c_bus_src", mux_200m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 1, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 9, GFLAGS), + COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_100m_50m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 2, 2, MFLAGS, + RV1126B_CLKGATE_CON(8), 10, GFLAGS), + COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_100m_50m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 4, 2, MFLAGS, + RV1126B_CLKGATE_CON(8), 11, GFLAGS), + GATE(BUSCLK_PMU_SRC, "busclk_pmu_src", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(8), 12, GFLAGS), + COMPOSITE_NODIV(CLK_PWM0, "clk_pwm0", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 8, 1, MFLAGS, + RV1126B_CLKGATE_CON(9), 0, GFLAGS), + COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 10, 1, MFLAGS, + RV1126B_CLKGATE_CON(9), 2, GFLAGS), + COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 11, 1, MFLAGS, + RV1126B_CLKGATE_CON(9), 3, GFLAGS), + COMPOSITE_NODIV(CLK_PKA_RKCE_SRC, "clk_pka_rkce_src", mux_300m_200m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(50), 12, 1, MFLAGS, + RV1126B_CLKGATE_CON(9), 4, GFLAGS), + COMPOSITE_NODIV(ACLK_RKCE_SRC, "aclk_rkce_src", mux_200m_24m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(50), 13, 1, MFLAGS, + RV1126B_CLKGATE_CON(9), 5, GFLAGS), + COMPOSITE_NODIV(ACLK_VCP_ROOT, "aclk_vcp_root", mux_500m_400m_200m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(48), 12, 2, MFLAGS, + RV1126B_CLKGATE_CON(9), 6, GFLAGS), + GATE(HCLK_VCP_ROOT, "hclk_vcp_root", "clk_gpll_div8", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(9), 7, GFLAGS), + GATE(PCLK_VCP_ROOT, "pclk_vcp_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(9), 8, GFLAGS), + COMPOSITE(CLK_CORE_FEC_SRC, "clk_core_fec_src", mux_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(51), 3, 1, MFLAGS, 0, 3, DFLAGS, + RV1126B_CLKGATE_CON(9), 9, GFLAGS), + GATE(CLK_50M_GMAC_IOBUF_VI, "clk_50m_gmac_iobuf_vi", "clk_cpll_div20", 0, + RV1126B_CLKGATE_CON(9), 11, GFLAGS), + GATE(PCLK_TOP_ROOT, "pclk_top_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(15), 0, GFLAGS), + COMPOSITE(CLK_MIPI0_OUT2IO, "clk_mipi0_out2io", mux_600m_24m_p, 0, + RV1126B_CLKSEL_CON(67), 11, 1, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(15), 3, GFLAGS), + COMPOSITE(CLK_MIPI1_OUT2IO, "clk_mipi1_out2io", mux_600m_24m_p, 0, + RV1126B_CLKSEL_CON(67), 12, 1, MFLAGS, 6, 5, DFLAGS, + RV1126B_CLKGATE_CON(15), 4, GFLAGS), + COMPOSITE(CLK_MIPI2_OUT2IO, "clk_mipi2_out2io", mux_600m_24m_p, 0, + RV1126B_CLKSEL_CON(68), 11, 1, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(15), 5, GFLAGS), + COMPOSITE(CLK_MIPI3_OUT2IO, "clk_mipi3_out2io", mux_600m_24m_p, 0, + RV1126B_CLKSEL_CON(68), 12, 1, MFLAGS, 6, 5, DFLAGS, + RV1126B_CLKGATE_CON(15), 6, GFLAGS), + COMPOSITE(CLK_CIF_OUT2IO, "clk_cif_out2io", mux_600m_24m_p, 0, + RV1126B_CLKSEL_CON(69), 5, 1, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(15), 7, GFLAGS), + COMPOSITE(CLK_MAC_OUT2IO, "clk_mac_out2io", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(69), 6, 2, MFLAGS, 8, 7, DFLAGS, + RV1126B_CLKGATE_CON(15), 8, GFLAGS), + COMPOSITE_NOMUX(MCLK_SAI0_OUT2IO, "mclk_sai0_out2io", "mclk_sai0", CLK_SET_RATE_PARENT, + RV1126B_CLKSEL_CON(70), 0, 4, DFLAGS, + RV1126B_CLKGATE_CON(15), 9, GFLAGS), + COMPOSITE_NOMUX(MCLK_SAI1_OUT2IO, "mclk_sai1_out2io", "mclk_sai1", CLK_SET_RATE_PARENT, + RV1126B_CLKSEL_CON(70), 5, 4, DFLAGS, + RV1126B_CLKGATE_CON(15), 10, GFLAGS), + COMPOSITE_NOMUX(MCLK_SAI2_OUT2IO, "mclk_sai2_out2io", "mclk_sai2", CLK_SET_RATE_PARENT, + RV1126B_CLKSEL_CON(70), 10, 4, DFLAGS, + RV1126B_CLKGATE_CON(15), 11, GFLAGS), + + /* pd _npu */ + MUX(ACLK_RKNN, "aclk_rknn", aclk_npu_root_p, CLK_SET_RATE_PARENT, + RV1126B_NPUCLKSEL_CON(0), 1, 1, MFLAGS), + + /* pd_vepu */ + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_vepu_root", 0, + RV1126B_VEPUCLKGATE_CON(0), 7, GFLAGS), + GATE(DBCLK_GPIO3, "dbclk_gpio3", "xin24m", 0, + RV1126B_VEPUCLKGATE_CON(0), 8, GFLAGS), + GATE(PCLK_IOC_VCCIO3, "pclk_ioc_vccio3", "pclk_vepu_root", CLK_IS_CRITICAL, + RV1126B_VEPUCLKGATE_CON(0), 9, GFLAGS), + GATE(PCLK_SARADC0, "pclk_saradc0", "pclk_vepu_root", 0, + RV1126B_VEPUCLKGATE_CON(0), 10, GFLAGS), + MUX(CLK_SARADC0, "clk_saradc0", clk_saradc0_p, CLK_SET_RATE_PARENT, + RV1126B_VEPUCLKSEL_CON(0), 2, 1, MFLAGS), + GATE(HCLK_SDMMC1, "hclk_sdmmc1", "hclk_vepu_root", 0, + RV1126B_VEPUCLKGATE_CON(0), 12, GFLAGS), + GATE(HCLK_VEPU, "hclk_vepu", "hclk_vepu_root", 0, + RV1126B_VEPUCLKGATE_CON(1), 1, GFLAGS), + GATE(ACLK_VEPU, "aclk_vepu", "aclk_vepu_root", 0, + RV1126B_VEPUCLKGATE_CON(1), 2, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_VEPU, "clk_core_vepu", clk_core_vepu_p, CLK_SET_RATE_PARENT, + RV1126B_VEPUCLKSEL_CON(0), 1, 1, MFLAGS, + RV1126B_VEPUCLKGATE_CON(1), 3, GFLAGS), + + /* pd_vcp */ + GATE(HCLK_FEC, "hclk_fec", "hclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(1), 0, GFLAGS), + GATE(ACLK_FEC, "aclk_fec", "aclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(1), 1, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_FEC, "clk_core_fec", clk_core_fec_p, CLK_SET_RATE_PARENT, + RV1126B_VCPCLKSEL_CON(0), 13, 1, MFLAGS, + RV1126B_VCPCLKGATE_CON(1), 2, GFLAGS), + GATE(HCLK_AVSP, "hclk_avsp", "hclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(1), 3, GFLAGS), + GATE(ACLK_AVSP, "aclk_avsp", "aclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(1), 4, GFLAGS), + GATE(HCLK_AISP, "hclk_aisp", "hclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(0), 11, GFLAGS), + GATE(ACLK_AISP, "aclk_aisp", "aclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(0), 12, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_AISP, "clk_core_aisp", clk_core_aisp_p, CLK_SET_RATE_PARENT, + RV1126B_VCPCLKSEL_CON(0), 15, 1, MFLAGS, + RV1126B_VCPCLKGATE_CON(0), 13, GFLAGS), + + /* pd_vi */ + MUX(CLK_CORE_ISP_ROOT, "clk_core_isp_root", clk_core_isp_root_p, CLK_SET_RATE_PARENT, + RV1126B_VICLKSEL_CON(0), 1, 1, MFLAGS), + GATE(PCLK_DSMC, "pclk_dsmc", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(0), 8, GFLAGS), + GATE(ACLK_DSMC, "aclk_dsmc", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(0), 9, GFLAGS), + GATE(HCLK_CAN0, "hclk_can0", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(0), 10, GFLAGS), + GATE(HCLK_CAN1, "hclk_can1", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(0), 11, GFLAGS), + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(1), 0, GFLAGS), + GATE(DBCLK_GPIO2, "dbclk_gpio2", "xin24m", 0, + RV1126B_VICLKGATE_CON(1), 1, GFLAGS), + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(1), 2, GFLAGS), + GATE(DBCLK_GPIO4, "dbclk_gpio4", "xin24m", 0, + RV1126B_VICLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(1), 4, GFLAGS), + GATE(DBCLK_GPIO5, "dbclk_gpio5", "xin24m", 0, + RV1126B_VICLKGATE_CON(1), 5, GFLAGS), + GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(1), 6, GFLAGS), + GATE(DBCLK_GPIO6, "dbclk_gpio6", "xin24m", 0, + RV1126B_VICLKGATE_CON(1), 7, GFLAGS), + GATE(PCLK_GPIO7, "pclk_gpio7", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(1), 8, GFLAGS), + GATE(DBCLK_GPIO7, "dbclk_gpio7", "xin24m", 0, + RV1126B_VICLKGATE_CON(1), 9, GFLAGS), + GATE(PCLK_IOC_VCCIO2, "pclk_ioc_vccio2", "pclk_vi_root", CLK_IS_CRITICAL, + RV1126B_VICLKGATE_CON(1), 10, GFLAGS), + GATE(PCLK_IOC_VCCIO4, "pclk_ioc_vccio4", "pclk_vi_root", CLK_IS_CRITICAL, + RV1126B_VICLKGATE_CON(1), 11, GFLAGS), + GATE(PCLK_IOC_VCCIO5, "pclk_ioc_vccio5", "pclk_vi_root", CLK_IS_CRITICAL, + RV1126B_VICLKGATE_CON(1), 12, GFLAGS), + GATE(PCLK_IOC_VCCIO6, "pclk_ioc_vccio6", "pclk_vi_root", CLK_IS_CRITICAL, + RV1126B_VICLKGATE_CON(1), 13, GFLAGS), + GATE(PCLK_IOC_VCCIO7, "pclk_ioc_vccio7", "pclk_vi_root", CLK_IS_CRITICAL, + RV1126B_VICLKGATE_CON(1), 14, GFLAGS), + GATE(HCLK_ISP, "hclk_isp", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 0, GFLAGS), + GATE(ACLK_ISP, "aclk_isp", "aclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 1, GFLAGS), + GATE(CLK_CORE_ISP, "clk_core_isp", "clk_core_isp_root", 0, + RV1126B_VICLKGATE_CON(2), 2, GFLAGS), + GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 3, GFLAGS), + GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 4, GFLAGS), + GATE(DCLK_VICAP, "dclk_vicap", "dclk_vicap_root", 0, + RV1126B_VICLKGATE_CON(2), 5, GFLAGS), + GATE(ISP0CLK_VICAP, "isp0clk_vicap", "clk_core_isp_root", 0, + RV1126B_VICLKGATE_CON(2), 6, GFLAGS), + GATE(HCLK_VPSS, "hclk_vpss", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 7, GFLAGS), + GATE(ACLK_VPSS, "aclk_vpss", "aclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 8, GFLAGS), + GATE(CLK_CORE_VPSS, "clk_core_vpss", "clk_core_isp_root", 0, + RV1126B_VICLKGATE_CON(2), 9, GFLAGS), + GATE(HCLK_VPSL, "hclk_vpsl", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 10, GFLAGS), + GATE(ACLK_VPSL, "aclk_vpsl", "aclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 11, GFLAGS), + GATE(CLK_CORE_VPSL, "clk_core_vpsl", "clk_core_isp_root", 0, + RV1126B_VICLKGATE_CON(2), 12, GFLAGS), + GATE(PCLK_CSI2HOST0, "pclk_csi2host0", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 0, GFLAGS), + GATE(DCLK_CSI2HOST0, "dclk_csi2host0", "dclk_vicap_root", 0, + RV1126B_VICLKGATE_CON(3), 1, GFLAGS), + GATE(PCLK_CSI2HOST1, "pclk_csi2host1", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 2, GFLAGS), + GATE(DCLK_CSI2HOST1, "dclk_csi2host1", "dclk_vicap_root", 0, + RV1126B_VICLKGATE_CON(3), 3, GFLAGS), + GATE(PCLK_CSI2HOST2, "pclk_csi2host2", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 4, GFLAGS), + GATE(DCLK_CSI2HOST2, "dclk_csi2host2", "dclk_vicap_root", 0, + RV1126B_VICLKGATE_CON(3), 5, GFLAGS), + GATE(PCLK_CSI2HOST3, "pclk_csi2host3", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 6, GFLAGS), + GATE(DCLK_CSI2HOST3, "dclk_csi2host3", "dclk_vicap_root", 0, + RV1126B_VICLKGATE_CON(3), 7, GFLAGS), + GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 8, GFLAGS), + GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_root", 0, + RV1126B_VICLKGATE_CON(3), 9, GFLAGS), + GATE(PCLK_GMAC, "pclk_gmac", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 10, GFLAGS), + MUX(CLK_GMAC_PTP_REF, "clk_gmac_ptp_ref", clk_gmac_ptp_ref_p, CLK_SET_RATE_PARENT, + RV1126B_VICLKSEL_CON(0), 14, 1, MFLAGS), + GATE(PCLK_CSIPHY0, "pclk_csiphy0", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 11, GFLAGS), + GATE(PCLK_CSIPHY1, "pclk_csiphy1", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 12, GFLAGS), + GATE(PCLK_MACPHY, "pclk_macphy", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 13, GFLAGS), + GATE(PCLK_SARADC1, "pclk_saradc1", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(4), 0, GFLAGS), + MUX(CLK_SARADC1, "clk_saradc1", clk_saradc1_p, CLK_SET_RATE_PARENT, + RV1126B_VICLKSEL_CON(0), 2, 1, MFLAGS), + GATE(PCLK_SARADC2, "pclk_saradc2", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(4), 2, GFLAGS), + MUX(CLK_SARADC2, "clk_saradc2", clk_saradc2_p, CLK_SET_RATE_PARENT, + RV1126B_VICLKSEL_CON(0), 3, 1, MFLAGS), + COMPOSITE_NODIV(CLK_MACPHY, "clk_macphy", clk_macphy_p, 0, + RV1126B_VICLKSEL_CON(1), 1, 1, MFLAGS, + RV1126B_VICLKGATE_CON(0), 12, GFLAGS), + + /* pd_vdo */ + GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_root", 0, + RV1126B_VDOCLKGATE_CON(0), 7, GFLAGS), + GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(0), 8, GFLAGS), + GATE(CLK_HEVC_CA_RKVDEC, "clk_hevc_ca_rkvdec", "aclk_rkvdec_root", 0, + RV1126B_VDOCLKGATE_CON(0), 9, GFLAGS), + GATE(ACLK_VOP, "aclk_vop", "aclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(0), 10, GFLAGS), + GATE(HCLK_VOP, "hclk_vop", "hclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(0), 11, GFLAGS), + GATE(ACLK_OOC, "aclk_ooc", "aclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(0), 13, GFLAGS), + GATE(HCLK_OOC, "hclk_ooc", "hclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(0), 14, GFLAGS), + GATE(HCLK_RKJPEG, "hclk_rkjpeg", "hclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 3, GFLAGS), + GATE(ACLK_RKJPEG, "aclk_rkjpeg", "aclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 4, GFLAGS), + GATE(ACLK_RKMMU_DECOM, "aclk_rkmmu_decom", "aclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 5, GFLAGS), + GATE(HCLK_RKMMU_DECOM, "hclk_rkmmu_decom", "hclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 6, GFLAGS), + GATE(DCLK_DECOM, "dclk_decom", "dclk_decom_src", 0, + RV1126B_VDOCLKGATE_CON(1), 8, GFLAGS), + GATE(ACLK_DECOM, "aclk_decom", "aclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 9, GFLAGS), + GATE(PCLK_DECOM, "pclk_decom", "pclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 10, GFLAGS), + GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 12, GFLAGS), + GATE(PCLK_DSIPHY, "pclk_dsiphy", "pclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 13, GFLAGS), + + /* pd_ddr */ + GATE(PCLK_DDRC, "pclk_ddrc", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1126B_DDRCLKGATE_CON(0), 2, GFLAGS), + GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1126B_DDRCLKGATE_CON(0), 3, GFLAGS), + GATE(CLK_TIMER_DDRMON, "clk_timer_ddrmon", "xin24m", 0, + RV1126B_DDRCLKGATE_CON(0), 4, GFLAGS), + GATE(PCLK_DFICTRL, "pclk_dfictrl", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1126B_DDRCLKGATE_CON(0), 5, GFLAGS), + GATE(PCLK_DDRPHY, "pclk_ddrphy", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1126B_DDRCLKGATE_CON(0), 8, GFLAGS), + GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1126B_DDRCLKGATE_CON(0), 9, GFLAGS), + + /* pd_pmu*/ + COMPOSITE_NODIV(CLK_RCOSC_SRC, "clk_rcosc_src", clk_rcosc_src_p, 0, + RV1126B_PMUCLKSEL_CON(1), 0, 3, MFLAGS, + RV1126B_PMUCLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NOGATE(BUSCLK_PMU_MUX, "busclk_pmu_mux", busclk_pmu_mux_p, 0, + RV1126B_PMUCLKSEL_CON(1), 3, 1, MFLAGS, 4, 2, DFLAGS), + GATE(BUSCLK_PMU_ROOT, "busclk_pmu_root", "busclk_pmu_mux", 0, + RV1126B_PMUCLKGATE_CON(0), 1, GFLAGS), + GATE(BUSCLK_PMU1_ROOT, "busclk_pmu1_root", "busclk_pmu_mux", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(3), 11, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(0), 6, GFLAGS), + MUX(0, "xin_rc_src", clk_xin_rc_div_p, 0, + RV1126B_PMUCLKSEL_CON(2), 0, 1, MFLAGS), + COMPOSITE_FRACMUX_NOGATE(CLK_XIN_RC_DIV, "clk_xin_rc_div", "xin_rc_src", CLK_SET_RATE_PARENT, + RV1126B_PMUCLKSEL_CON(8), 0, + &rv1126b_rcdiv_pmu_fracmux), + GATE(PCLK_PMU_GPIO0, "pclk_pmu_gpio0", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(0), 7, GFLAGS), + COMPOSITE_NODIV(DBCLK_PMU_GPIO0, "dbclk_pmu_gpio0", mux_24m_32k_p, 0, + RV1126B_PMUCLKSEL_CON(2), 4, 1, MFLAGS, + RV1126B_PMUCLKGATE_CON(0), 8, GFLAGS), + GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(0), 10, GFLAGS), + COMPOSITE(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", mux_cpll_24m_p, CLK_IS_CRITICAL, + RV1126B_PMUCLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS, + RV1126B_PMUCLKGATE_CON(0), 11, GFLAGS), + GATE(CLK_PMU_32K_HP_TIMER, "clk_pmu_32k_hp_timer", "clk_32k", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(0), 13, GFLAGS), + GATE(PCLK_PWM1, "pclk_pwm1", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(1), 0, GFLAGS), + COMPOSITE(CLK_PWM1, "clk_pwm1", mux_24m_rcosc_buspmu_p, 0, + RV1126B_PMUCLKSEL_CON(2), 8, 2, MFLAGS, 6, 2, DFLAGS, + RV1126B_PMUCLKGATE_CON(1), 1, GFLAGS), + GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0, + RV1126B_PMUCLKGATE_CON(1), 2, GFLAGS), + GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_32k", 0, + RV1126B_PMUCLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_I2C2, "pclk_i2c2", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(1), 6, GFLAGS), + COMPOSITE(CLK_I2C2, "clk_i2c2", mux_24m_rcosc_buspmu_p, 0, + RV1126B_PMUCLKSEL_CON(2), 14, 2, MFLAGS, 12, 2, DFLAGS, + RV1126B_PMUCLKGATE_CON(1), 7, GFLAGS), + GATE(PCLK_UART0, "pclk_uart0", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(1), 8, GFLAGS), + COMPOSITE_NODIV(SCLK_UART0, "sclk_uart0", sclk_uart0_p, CLK_SET_RATE_PARENT, + RV1126B_PMUCLKSEL_CON(3), 0, 2, MFLAGS, + RV1126B_PMUCLKGATE_CON(1), 11, GFLAGS), + GATE(PCLK_RCOSC_CTRL, "pclk_rcosc_ctrl", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(2), 0, GFLAGS), + COMPOSITE_NODIV(CLK_OSC_RCOSC_CTRL, "clk_osc_rcosc_ctrl", clk_osc_rcosc_ctrl_p, CLK_IS_CRITICAL, + RV1126B_PMUCLKSEL_CON(3), 2, 1, MFLAGS, + RV1126B_PMUCLKGATE_CON(2), 1, GFLAGS), + GATE(CLK_REF_RCOSC_CTRL, "clk_ref_rcosc_ctrl", "xin24m", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(2), 2, GFLAGS), + GATE(PCLK_IOC_PMUIO0, "pclk_ioc_pmuio0", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(2), 3, GFLAGS), + GATE(CLK_REFOUT, "clk_refout", "xin24m", 0, + RV1126B_PMUCLKGATE_CON(2), 6, GFLAGS), + GATE(CLK_PREROLL, "clk_preroll", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(2), 7, GFLAGS), + GATE(CLK_PREROLL_32K, "clk_preroll_32k", "clk_32k", 0, + RV1126B_PMUCLKGATE_CON(2), 8, GFLAGS), + GATE(HCLK_PMU_SRAM, "hclk_pmu_sram", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(2), 9, GFLAGS), + GATE(PCLK_WDT_LPMCU, "pclk_wdt_lpmcu", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(3), 0, GFLAGS), + COMPOSITE_NODIV(TCLK_WDT_LPMCU, "tclk_wdt_lpmcu", mux_24m_rcosc_buspmu_32k_p, 0, + RV1126B_PMUCLKSEL_CON(3), 6, 2, MFLAGS, + RV1126B_PMUCLKGATE_CON(3), 1, GFLAGS), + GATE(CLK_LPMCU, "clk_lpmcu", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(3), 2, GFLAGS), + GATE(CLK_LPMCU_RTC, "clk_lpmcu_rtc", "xin24m", 0, + RV1126B_PMUCLKGATE_CON(3), 3, GFLAGS), + GATE(PCLK_LPMCU_MAILBOX, "pclk_lpmcu_mailbox", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(3), 4, GFLAGS), + + /* pd_pmu1 */ + GATE(PCLK_SPI2AHB, "pclk_spi2ahb", "busclk_pmu_root", 0, + RV1126B_PMU1CLKGATE_CON(0), 0, GFLAGS), + GATE(HCLK_SPI2AHB, "hclk_spi2ahb", "busclk_pmu_root", 0, + RV1126B_PMU1CLKGATE_CON(0), 1, GFLAGS), + GATE(HCLK_FSPI1, "hclk_fspi1", "busclk_pmu_root", 0, + RV1126B_PMU1CLKGATE_CON(0), 2, GFLAGS), + GATE(HCLK_XIP_FSPI1, "hclk_xip_fspi1", "busclk_pmu_root", 0, + RV1126B_PMU1CLKGATE_CON(0), 3, GFLAGS), + COMPOSITE(SCLK_1X_FSPI1, "sclk_1x_fspi1", mux_24m_rcosc_buspmu_p, 0, + RV1126B_PMU1CLKSEL_CON(0), 0, 2, MFLAGS, 2, 3, DFLAGS, + RV1126B_PMU1CLKGATE_CON(0), 4, GFLAGS), + GATE(PCLK_IOC_PMUIO1, "pclk_ioc_pmuio1", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMU1CLKGATE_CON(0), 5, GFLAGS), + GATE(PCLK_AUDIO_ADC_PMU, "pclk_audio_adc_pmu", "busclk_pmu_root", 0, + RV1126B_PMU1CLKGATE_CON(0), 8, GFLAGS), + + COMPOSITE(MCLK_LPSAI, "mclk_lpsai", mux_24m_rcosc_buspmu_p, 0, + RV1126B_PMU1CLKSEL_CON(0), 6, 2, MFLAGS, 8, 5, DFLAGS, + RV1126B_PMU1CLKGATE_CON(1), 3, GFLAGS), + GATE(MCLK_AUDIO_ADC_PMU, "mclk_audio_adc_pmu", "mclk_lpsai", CLK_IS_CRITICAL, + RV1126B_PMU1CLKGATE_CON(0), 9, GFLAGS), + FACTOR(MCLK_AUDIO_ADC_DIV4_PMU, "mclk_audio_adc_div4_pmu", "mclk_audio_adc_pmu", 0, 1, 4), + + /* pd_bus */ + GATE(ACLK_GIC400, "aclk_gic400", "hclk_bus_root", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(0), 8, GFLAGS), + GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(0), 10, GFLAGS), + GATE(TCLK_WDT_NS, "tclk_wdt_ns", "tclk_wdt_ns_src", 0, + RV1126B_BUSCLKGATE_CON(0), 11, GFLAGS), + GATE(PCLK_WDT_HPMCU, "pclk_wdt_hpmcu", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 0, GFLAGS), + GATE(HCLK_CACHE, "hclk_cache", "aclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 2, GFLAGS), + GATE(PCLK_HPMCU_MAILBOX, "pclk_hpmcu_mailbox", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_HPMCU_INTMUX, "pclk_hpmcu_intmux", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 4, GFLAGS), + GATE(CLK_HPMCU, "clk_hpmcu", "aclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 5, GFLAGS), + GATE(CLK_HPMCU_RTC, "clk_hpmcu_rtc", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(1), 10, GFLAGS), + GATE(PCLK_RKDMA, "pclk_rkdma", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 11, GFLAGS), + GATE(ACLK_RKDMA, "aclk_rkdma", "aclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 12, GFLAGS), + GATE(PCLK_DCF, "pclk_dcf", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 0, GFLAGS), + GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 1, GFLAGS), + GATE(HCLK_RGA, "hclk_rga", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 2, GFLAGS), + GATE(ACLK_RGA, "aclk_rga", "aclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 3, GFLAGS), + GATE(CLK_CORE_RGA, "clk_core_rga", "clk_core_rga_src", 0, + RV1126B_BUSCLKGATE_CON(2), 4, GFLAGS), + GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 5, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0, "clk_timer0", clk_timer0_parents_p, 0, + RV1126B_BUSCLKSEL_CON(2), 0, 2, MFLAGS, + RV1126B_BUSCLKGATE_CON(2), 6, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER1, "clk_timer1", clk_timer1_parents_p, 0, + RV1126B_BUSCLKSEL_CON(2), 2, 2, MFLAGS, + RV1126B_BUSCLKGATE_CON(2), 7, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER2, "clk_timer2", clk_timer2_parents_p, 0, + RV1126B_BUSCLKSEL_CON(2), 4, 2, MFLAGS, + RV1126B_BUSCLKGATE_CON(2), 8, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER3, "clk_timer3", clk_timer3_parents_p, 0, + RV1126B_BUSCLKSEL_CON(2), 6, 2, MFLAGS, + RV1126B_BUSCLKGATE_CON(2), 9, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER4, "clk_timer4", clk_timer4_parents_p, 0, + RV1126B_BUSCLKSEL_CON(2), 8, 2, MFLAGS, + RV1126B_BUSCLKGATE_CON(2), 10, GFLAGS), + GATE(HCLK_RKRNG_S_NS, "hclk_rkrng_s_ns", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 14, GFLAGS), + GATE(HCLK_RKRNG_NS, "hclk_rkrng_ns", "hclk_rkrng_s_ns", 0, + RV1126B_BUSCLKGATE_CON(2), 15, GFLAGS), + GATE(CLK_TIMER5, "clk_timer5", "clk_timer_root", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(2), 11, GFLAGS), + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 0, GFLAGS), + GATE(CLK_I2C0, "clk_i2c0", "clk_i2c_bus_src", 0, + RV1126B_BUSCLKGATE_CON(3), 1, GFLAGS), + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 2, GFLAGS), + GATE(CLK_I2C1, "clk_i2c1", "clk_i2c_bus_src", 0, + RV1126B_BUSCLKGATE_CON(3), 3, GFLAGS), + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 4, GFLAGS), + GATE(CLK_I2C3, "clk_i2c3", "clk_i2c_bus_src", 0, + RV1126B_BUSCLKGATE_CON(3), 5, GFLAGS), + GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 6, GFLAGS), + GATE(CLK_I2C4, "clk_i2c4", "clk_i2c_bus_src", 0, + RV1126B_BUSCLKGATE_CON(3), 7, GFLAGS), + GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 8, GFLAGS), + GATE(CLK_I2C5, "clk_i2c5", "clk_i2c_bus_src", 0, + RV1126B_BUSCLKGATE_CON(3), 9, GFLAGS), + GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 10, GFLAGS), + GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 12, GFLAGS), + GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 0, GFLAGS), + GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 1, GFLAGS), + GATE(CLK_RC_PWM0, "clk_rc_pwm0", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 2, GFLAGS), + GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 3, GFLAGS), + GATE(CLK_OSC_PWM2, "clk_osc_pwm2", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 4, GFLAGS), + GATE(CLK_RC_PWM2, "clk_rc_pwm2", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 5, GFLAGS), + GATE(PCLK_PWM3, "pclk_pwm3", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 6, GFLAGS), + GATE(CLK_OSC_PWM3, "clk_osc_pwm3", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 7, GFLAGS), + GATE(CLK_RC_PWM3, "clk_rc_pwm3", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 8, GFLAGS), + GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 9, GFLAGS), + GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 10, GFLAGS), + GATE(PCLK_UART3, "pclk_uart3", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 11, GFLAGS), + GATE(PCLK_UART4, "pclk_uart4", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 12, GFLAGS), + GATE(PCLK_UART5, "pclk_uart5", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 13, GFLAGS), + GATE(PCLK_UART6, "pclk_uart6", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 14, GFLAGS), + GATE(PCLK_UART7, "pclk_uart7", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 15, GFLAGS), + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_root", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(5), 0, GFLAGS), + GATE(CLK_TSADC, "clk_tsadc", "xin24m", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(5), 1, GFLAGS), + GATE(HCLK_SAI0, "hclk_sai0", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 2, GFLAGS), + GATE(HCLK_SAI1, "hclk_sai1", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 4, GFLAGS), + GATE(HCLK_SAI2, "hclk_sai2", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 6, GFLAGS), + GATE(HCLK_RKDSM, "hclk_rkdsm", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 8, GFLAGS), + GATE(MCLK_RKDSM, "mclk_rkdsm", "mclk_sai2", 0, + RV1126B_BUSCLKGATE_CON(5), 9, GFLAGS), + GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 10, GFLAGS), + GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 11, GFLAGS), + GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 12, GFLAGS), + GATE(PCLK_AUDIO_ADC_BUS, "pclk_audio_adc_bus", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 13, GFLAGS), + GATE(MCLK_AUDIO_ADC_BUS, "mclk_audio_adc_bus", "mclk_sai2", 0, + RV1126B_BUSCLKGATE_CON(5), 14, GFLAGS), + FACTOR(MCLK_AUDIO_ADC_DIV4_BUS, "mclk_audio_adc_div4_bus", "mclk_audio_adc_bus", 0, 1, 4), + GATE(PCLK_RKCE, "pclk_rkce", "pclk_bus_root", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(6), 0, GFLAGS), + GATE(HCLK_NS_RKCE, "hclk_ns_rkce", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(6), 1, GFLAGS), + GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(6), 2, GFLAGS), + GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(6), 3, GFLAGS), + COMPOSITE_NOMUX(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "xin24m", 0, + RV1126B_BUSCLKSEL_CON(2), 12, 3, DFLAGS, + RV1126B_BUSCLKGATE_CON(6), 4, GFLAGS), + GATE(PCLK_OTP_MASK, "pclk_otp_mask", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(6), 6, GFLAGS), + GATE(CLK_TSADC_PHYCTRL, "clk_tsadc_phyctrl", "xin24m", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(6), 8, GFLAGS), + MUX(LRCK_SRC_ASRC0, "lrck_src_asrc0", lrck_src_asrc_p, 0, + RV1126B_BUSCLKSEL_CON(3), 0, 3, MFLAGS), + MUX(LRCK_DST_ASRC0, "lrck_dst_asrc0", lrck_src_asrc_p, 0, + RV1126B_BUSCLKSEL_CON(3), 4, 3, MFLAGS), + MUX(LRCK_SRC_ASRC1, "lrck_src_asrc1", lrck_src_asrc_p, 0, + RV1126B_BUSCLKSEL_CON(3), 8, 3, MFLAGS), + MUX(LRCK_DST_ASRC1, "lrck_dst_asrc1", lrck_src_asrc_p, 0, + RV1126B_BUSCLKSEL_CON(3), 12, 3, MFLAGS), + GATE(ACLK_NSRKCE, "aclk_nsrkce", "aclk_rkce_src", 0, + RV1126B_BUSCLKGATE_CON(2), 12, GFLAGS), + GATE(CLK_PKA_NSRKCE, "clk_pka_nsrkce", "clk_pka_rkce_src", 0, + RV1126B_BUSCLKGATE_CON(2), 13, GFLAGS), + + /* pd_peri */ + DIV(PCLK_RTC_ROOT, "pclk_rtc_root", "pclk_peri_root", 0, + RV1126B_PERICLKSEL_CON(0), 0, 2, DFLAGS), + GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(0), 5, GFLAGS), + GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m", 0, + RV1126B_PERICLKGATE_CON(0), 6, GFLAGS), + GATE(PCLK_IOC_VCCIO1, "pclk_ioc_vccio1", "pclk_peri_root", CLK_IS_CRITICAL, + RV1126B_PERICLKGATE_CON(0), 7, GFLAGS), + GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(0), 8, GFLAGS), + GATE(CLK_REF_USB3OTG, "clk_ref_usb3otg", "xin24m", 0, + RV1126B_PERICLKGATE_CON(0), 9, GFLAGS), + GATE(CLK_SUSPEND_USB3OTG, "clk_suspend_usb3otg", "xin24m", 0, + RV1126B_PERICLKGATE_CON(0), 10, GFLAGS), + GATE(HCLK_USB2HOST, "hclk_usb2host", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(0), 11, GFLAGS), + GATE(HCLK_ARB_USB2HOST, "hclk_arb_usb2host", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(0), 12, GFLAGS), + GATE(PCLK_RTC_TEST, "pclk_rtc_test", "pclk_rtc_root", 0, + RV1126B_PERICLKGATE_CON(0), 13, GFLAGS), + GATE(HCLK_EMMC, "hclk_emmc", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(1), 0, GFLAGS), + GATE(HCLK_FSPI0, "hclk_fspi0", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(1), 1, GFLAGS), + GATE(HCLK_XIP_FSPI0, "hclk_xip_fspi0", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(1), 2, GFLAGS), + GATE(PCLK_PIPEPHY, "pclk_pipephy", "pclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(1), 8, GFLAGS), + GATE(PCLK_USB2PHY, "pclk_usb2phy", "pclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(1), 10, GFLAGS), + COMPOSITE_NOMUX(CLK_REF_PIPEPHY_CPLL_SRC, "clk_ref_pipephy_cpll_src", "cpll", 0, + RV1126B_PERICLKSEL_CON(1), 0, 6, DFLAGS, + RV1126B_PERICLKGATE_CON(1), 14, GFLAGS), + MUX(CLK_REF_PIPEPHY, "clk_ref_pipephy", clk_ref_pipephy_p, 0, + RV1126B_PERICLKSEL_CON(1), 12, 1, MFLAGS), +}; + +static struct rockchip_clk_branch rv1126b_armclk __initdata = + MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + RV1126B_CORECLKSEL_CON(0), 1, 1, MFLAGS); + +static void __init rv1126b_clk_init(struct device_node *np) +{ + struct rockchip_clk_provider *ctx; + void __iomem *reg_base; + unsigned long clk_nr_clks; + + clk_nr_clks = rockchip_clk_find_max_clk_id(rv1126b_clk_branches, + ARRAY_SIZE(rv1126b_clk_branches)) + 1; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: could not map cru region\n", __func__); + return; + } + + ctx = rockchip_clk_init(np, reg_base, clk_nr_clks); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); + return; + } + + rockchip_clk_register_plls(ctx, rv1126b_pll_clks, + ARRAY_SIZE(rv1126b_pll_clks), + 0); + + rockchip_clk_register_branches(ctx, rv1126b_clk_branches, + ARRAY_SIZE(rv1126b_clk_branches)); + + rockchip_clk_register_armclk_multi_pll(ctx, &rv1126b_armclk, + rv1126b_cpuclk_rates, + ARRAY_SIZE(rv1126b_cpuclk_rates)); + + rv1126b_rst_init(np, reg_base); + + rockchip_register_restart_notifier(ctx, RV1126B_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); + + /* pvtpll src init */ + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_CORECLKSEL_CON(0)); + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_NPUCLKSEL_CON(0)); + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VICLKSEL_CON(0)); + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VEPUCLKSEL_CON(0)); + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VCPCLKSEL_CON(0)); +} + +CLK_OF_DECLARE(rv1126b_cru, "rockchip,rv1126b-cru", rv1126b_clk_init); + +struct clk_rv1126b_inits { + void (*inits)(struct device_node *np); +}; + +static const struct clk_rv1126b_inits clk_rv1126b_init = { + .inits = rv1126b_clk_init, +}; + +static const struct of_device_id clk_rv1126b_match_table[] = { + { + .compatible = "rockchip,rv1126b-cru", + .data = &clk_rv1126b_init, + }, + { } +}; + +static int clk_rv1126b_probe(struct platform_device *pdev) +{ + const struct clk_rv1126b_inits *init_data; + struct device *dev = &pdev->dev; + + init_data = device_get_match_data(dev); + if (!init_data) + return -EINVAL; + + if (init_data->inits) + init_data->inits(dev->of_node); + + return 0; +} + +static struct platform_driver clk_rv1126b_driver = { + .probe = clk_rv1126b_probe, + .driver = { + .name = "clk-rv1126b", + .of_match_table = clk_rv1126b_match_table, + .suppress_bind_attrs = true, + }, +}; +builtin_platform_driver_probe(clk_rv1126b_driver, clk_rv1126b_probe); diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 19caf26c991bd..2601df3b1066b 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -722,6 +722,30 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, } EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk); +void rockchip_clk_register_armclk_multi_pll(struct rockchip_clk_provider *ctx, + struct rockchip_clk_branch *list, + const struct rockchip_cpuclk_rate_table *rates, + int nrates) +{ + struct clk *clk; + + clk = rockchip_clk_register_cpuclk_multi_pll(list->name, list->parent_names, + list->num_parents, ctx->reg_base, + list->muxdiv_offset, list->mux_shift, + list->mux_width, list->mux_flags, + list->div_offset, list->div_shift, + list->div_width, list->div_flags, + list->flags, &ctx->lock, rates, nrates); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s: %ld\n", + __func__, list->name, PTR_ERR(clk)); + return; + } + + rockchip_clk_set_lookup(ctx, clk, list->id); +} +EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk_multi_pll); + void rockchip_clk_protect_critical(const char *const clocks[], int nclocks) { diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 7c5e74c7a2e21..b2fff1d13a4ab 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -99,6 +99,73 @@ struct clk; #define RV1126_EMMC_CON0 0x450 #define RV1126_EMMC_CON1 0x454 +#define RV1126B_TOPCRU_BASE 0x0 +#define RV1126B_BUSCRU_BASE 0x10000 +#define RV1126B_PERICRU_BASE 0x20000 +#define RV1126B_CORECRU_BASE 0x30000 +#define RV1126B_PMUCRU_BASE 0x40000 +#define RV1126B_PMU1CRU_BASE 0x50000 +#define RV1126B_DDRCRU_BASE 0x60000 +#define RV1126B_SUBDDRCRU_BASE 0x68000 +#define RV1126B_VICRU_BASE 0x70000 +#define RV1126B_VEPUCRU_BASE 0x80000 +#define RV1126B_NPUCRU_BASE 0x90000 +#define RV1126B_VDOCRU_BASE 0xA0000 +#define RV1126B_VCPCRU_BASE 0xB0000 + +#define RV1126B_PLL_CON(x) ((x) * 0x4 + RV1126B_TOPCRU_BASE) +#define RV1126B_MODE_CON (0x280 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_TOPCRU_BASE) +#define RV1126B_SOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_TOPCRU_BASE) +#define RV1126B_GLB_SRST_FST (0xc08 + RV1126B_TOPCRU_BASE) +#define RV1126B_GLB_SRST_SND (0xc0c + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_CM_FRAC0_DIV_H (0xcc0 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_CM_FRAC1_DIV_H (0xcc4 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_CM_FRAC2_DIV_H (0xcc8 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_UART_FRAC0_DIV_H (0xccc + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_UART_FRAC1_DIV_H (0xcd0 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_AUDIO_FRAC0_DIV_H (0xcd4 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_AUDIO_FRAC1_DIV_H (0xcd8 + RV1126B_TOPCRU_BASE) +#define RV1126B_BUSCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_BUSCRU_BASE) +#define RV1126B_BUSCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_BUSCRU_BASE) +#define RV1126B_BUSSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_BUSCRU_BASE) +#define RV1126B_PERIPLL_CON(x) ((x) * 0x4 + RV1126B_PERICRU_BASE) +#define RV1126B_PERICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_PERICRU_BASE) +#define RV1126B_PERICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_PERICRU_BASE) +#define RV1126B_PERISOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_PERICRU_BASE) +#define RV1126B_CORECLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_CORECRU_BASE) +#define RV1126B_CORECLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_CORECRU_BASE) +#define RV1126B_CORESOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_CORECRU_BASE) +#define RV1126B_PMUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_PMUCRU_BASE) +#define RV1126B_PMUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_PMUCRU_BASE) +#define RV1126B_PMUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_PMUCRU_BASE) +#define RV1126B_PMU1CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_PMU1CRU_BASE) +#define RV1126B_PMU1CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_PMU1CRU_BASE) +#define RV1126B_PMU1SOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_PMU1CRU_BASE) +#define RV1126B_DDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_DDRCRU_BASE) +#define RV1126B_DDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_DDRCRU_BASE) +#define RV1126B_DDRSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_DDRCRU_BASE) +#define RV1126B_SUBDDRPLL_CON(x) ((x) * 0x4 + RV1126B_SUBDDRCRU_BASE) +#define RV1126B_SUBDDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_SUBDDRCRU_BASE) +#define RV1126B_SUBDDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_SUBDDRCRU_BASE) +#define RV1126B_SUBDDRSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_SUBDDRCRU_BASE) +#define RV1126B_VICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VICRU_BASE) +#define RV1126B_VICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VICRU_BASE) +#define RV1126B_VISOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VICRU_BASE) +#define RV1126B_VEPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VEPUCRU_BASE) +#define RV1126B_VEPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VEPUCRU_BASE) +#define RV1126B_VEPUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VEPUCRU_BASE) +#define RV1126B_NPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_NPUCRU_BASE) +#define RV1126B_NPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_NPUCRU_BASE) +#define RV1126B_NPUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_NPUCRU_BASE) +#define RV1126B_VDOCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VDOCRU_BASE) +#define RV1126B_VDOCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VDOCRU_BASE) +#define RV1126B_VDOSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VDOCRU_BASE) +#define RV1126B_VCPCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VCPCRU_BASE) +#define RV1126B_VCPCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VCPCRU_BASE) +#define RV1126B_VCPSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VCPCRU_BASE) + #define RK2928_PLL_CON(x) ((x) * 0x4) #define RK2928_MODE_CON 0x40 #define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44) @@ -208,6 +275,18 @@ struct clk; #define RK3399_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x100) #define RK3399_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x110) +#define RK3506_PMU_CRU_BASE 0x10000 +#define RK3506_PLL_CON(x) ((x) * 0x4 + RK3506_PMU_CRU_BASE) +#define RK3506_CLKSEL_CON(x) ((x) * 0x4 + 0x300) +#define RK3506_CLKGATE_CON(x) ((x) * 0x4 + 0x800) +#define RK3506_SOFTRST_CON(x) ((x) * 0x4 + 0xa00) +#define RK3506_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3506_PMU_CRU_BASE) +#define RK3506_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RK3506_PMU_CRU_BASE) +#define RK3506_MODE_CON 0x280 +#define RK3506_GLB_CNT_TH 0xc00 +#define RK3506_GLB_SRST_FST 0xc08 +#define RK3506_GLB_SRST_SND 0xc0c + #define RK3528_PMU_CRU_BASE 0x10000 #define RK3528_PCIE_CRU_BASE 0x20000 #define RK3528_DDRPHY_CRU_BASE 0x28000 @@ -622,6 +701,17 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, const struct rockchip_cpuclk_rate_table *rates, int nrates, void __iomem *reg_base, spinlock_t *lock); +struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name, + const char *const *parent_names, + u8 num_parents, void __iomem *base, + int muxdiv_offset, u8 mux_shift, + u8 mux_width, u8 mux_flags, + int div_offset, u8 div_shift, + u8 div_width, u8 div_flags, + unsigned long flags, spinlock_t *lock, + const struct rockchip_cpuclk_rate_table *rates, + int nrates); + struct clk *rockchip_clk_register_mmc(const char *name, const char *const *parent_names, u8 num_parents, void __iomem *reg, @@ -1208,6 +1298,10 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, const struct rockchip_cpuclk_reg_data *reg_data, const struct rockchip_cpuclk_rate_table *rates, int nrates); +void rockchip_clk_register_armclk_multi_pll(struct rockchip_clk_provider *ctx, + struct rockchip_clk_branch *list, + const struct rockchip_cpuclk_rate_table *rates, + int nrates); void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, unsigned int reg, void (*cb)(void)); @@ -1246,6 +1340,8 @@ static inline void rockchip_register_softrst(struct device_node *np, return rockchip_register_softrst_lut(np, NULL, num_regs, base, flags); } +void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base); +void rk3506_rst_init(struct device_node *np, void __iomem *reg_base); void rk3528_rst_init(struct device_node *np, void __iomem *reg_base); void rk3562_rst_init(struct device_node *np, void __iomem *reg_base); void rk3576_rst_init(struct device_node *np, void __iomem *reg_base); diff --git a/drivers/clk/rockchip/rst-rk3506.c b/drivers/clk/rockchip/rst-rk3506.c new file mode 100644 index 0000000000000..c3abde60f3c6b --- /dev/null +++ b/drivers/clk/rockchip/rst-rk3506.c @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + * Author: Finley Xiao + */ + +#include +#include +#include +#include "clk.h" + +/* 0xFF9A0000 + 0x0A00 */ +#define RK3506_CRU_RESET_OFFSET(id, reg, bit) [id] = (0 + reg * 16 + bit) + +/* mapping table for reset ID to register offset */ +static const int rk3506_register_offset[] = { + /* CRU-->SOFTRST_CON00 */ + RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET0_AC, 0, 0), + RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET1_AC, 0, 1), + RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET2_AC, 0, 2), + RK3506_CRU_RESET_OFFSET(SRST_NCORESET0_AC, 0, 4), + RK3506_CRU_RESET_OFFSET(SRST_NCORESET1_AC, 0, 5), + RK3506_CRU_RESET_OFFSET(SRST_NCORESET2_AC, 0, 6), + RK3506_CRU_RESET_OFFSET(SRST_NL2RESET_AC, 0, 8), + RK3506_CRU_RESET_OFFSET(SRST_A_CORE_BIU_AC, 0, 9), + RK3506_CRU_RESET_OFFSET(SRST_H_M0_AC, 0, 10), + + /* CRU-->SOFTRST_CON02 */ + RK3506_CRU_RESET_OFFSET(SRST_NDBGRESET, 2, 10), + RK3506_CRU_RESET_OFFSET(SRST_P_CORE_BIU, 2, 14), + RK3506_CRU_RESET_OFFSET(SRST_PMU, 2, 15), + + /* CRU-->SOFTRST_CON03 */ + RK3506_CRU_RESET_OFFSET(SRST_P_DBG, 3, 1), + RK3506_CRU_RESET_OFFSET(SRST_POT_DBG, 3, 2), + RK3506_CRU_RESET_OFFSET(SRST_P_CORE_GRF, 3, 4), + RK3506_CRU_RESET_OFFSET(SRST_CORE_EMA_DETECT, 3, 6), + RK3506_CRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 3, 7), + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1, 3, 8), + RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO1, 3, 9), + + /* CRU-->SOFTRST_CON04 */ + RK3506_CRU_RESET_OFFSET(SRST_A_CORE_PERI_BIU, 4, 3), + RK3506_CRU_RESET_OFFSET(SRST_A_DSMC, 4, 5), + RK3506_CRU_RESET_OFFSET(SRST_P_DSMC, 4, 6), + RK3506_CRU_RESET_OFFSET(SRST_FLEXBUS, 4, 7), + RK3506_CRU_RESET_OFFSET(SRST_A_FLEXBUS, 4, 9), + RK3506_CRU_RESET_OFFSET(SRST_H_FLEXBUS, 4, 10), + RK3506_CRU_RESET_OFFSET(SRST_A_DSMC_SLV, 4, 11), + RK3506_CRU_RESET_OFFSET(SRST_H_DSMC_SLV, 4, 12), + RK3506_CRU_RESET_OFFSET(SRST_DSMC_SLV, 4, 13), + + /* CRU-->SOFTRST_CON05 */ + RK3506_CRU_RESET_OFFSET(SRST_A_BUS_BIU, 5, 3), + RK3506_CRU_RESET_OFFSET(SRST_H_BUS_BIU, 5, 4), + RK3506_CRU_RESET_OFFSET(SRST_P_BUS_BIU, 5, 5), + RK3506_CRU_RESET_OFFSET(SRST_A_SYSRAM, 5, 6), + RK3506_CRU_RESET_OFFSET(SRST_H_SYSRAM, 5, 7), + RK3506_CRU_RESET_OFFSET(SRST_A_DMAC0, 5, 8), + RK3506_CRU_RESET_OFFSET(SRST_A_DMAC1, 5, 9), + RK3506_CRU_RESET_OFFSET(SRST_H_M0, 5, 10), + RK3506_CRU_RESET_OFFSET(SRST_M0_JTAG, 5, 11), + RK3506_CRU_RESET_OFFSET(SRST_H_CRYPTO, 5, 15), + + /* CRU-->SOFTRST_CON06 */ + RK3506_CRU_RESET_OFFSET(SRST_H_RNG, 6, 0), + RK3506_CRU_RESET_OFFSET(SRST_P_BUS_GRF, 6, 1), + RK3506_CRU_RESET_OFFSET(SRST_P_TIMER0, 6, 2), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH0, 6, 3), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH1, 6, 4), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH2, 6, 5), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH3, 6, 6), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH4, 6, 7), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH5, 6, 8), + RK3506_CRU_RESET_OFFSET(SRST_P_WDT0, 6, 9), + RK3506_CRU_RESET_OFFSET(SRST_T_WDT0, 6, 10), + RK3506_CRU_RESET_OFFSET(SRST_P_WDT1, 6, 11), + RK3506_CRU_RESET_OFFSET(SRST_T_WDT1, 6, 12), + RK3506_CRU_RESET_OFFSET(SRST_P_MAILBOX, 6, 13), + RK3506_CRU_RESET_OFFSET(SRST_P_INTMUX, 6, 14), + RK3506_CRU_RESET_OFFSET(SRST_P_SPINLOCK, 6, 15), + + /* CRU-->SOFTRST_CON07 */ + RK3506_CRU_RESET_OFFSET(SRST_P_DDRC, 7, 0), + RK3506_CRU_RESET_OFFSET(SRST_H_DDRPHY, 7, 1), + RK3506_CRU_RESET_OFFSET(SRST_P_DDRMON, 7, 2), + RK3506_CRU_RESET_OFFSET(SRST_DDRMON_OSC, 7, 3), + RK3506_CRU_RESET_OFFSET(SRST_P_DDR_LPC, 7, 4), + RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG0, 7, 5), + RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_ADP, 7, 7), + RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG1, 7, 8), + RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_ADP, 7, 10), + RK3506_CRU_RESET_OFFSET(SRST_P_USBPHY, 7, 11), + RK3506_CRU_RESET_OFFSET(SRST_USBPHY_POR, 7, 12), + RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG0, 7, 13), + RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG1, 7, 14), + + /* CRU-->SOFTRST_CON08 */ + RK3506_CRU_RESET_OFFSET(SRST_A_DMA2DDR, 8, 0), + RK3506_CRU_RESET_OFFSET(SRST_P_DMA2DDR, 8, 1), + + /* CRU-->SOFTRST_CON09 */ + RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_UTMI, 9, 0), + RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_UTMI, 9, 1), + + /* CRU-->SOFTRST_CON10 */ + RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_0, 10, 0), + RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_1, 10, 1), + RK3506_CRU_RESET_OFFSET(SRST_A_DDR_BIU, 10, 2), + RK3506_CRU_RESET_OFFSET(SRST_DDRC, 10, 3), + RK3506_CRU_RESET_OFFSET(SRST_DDRMON, 10, 4), + + /* CRU-->SOFTRST_CON11 */ + RK3506_CRU_RESET_OFFSET(SRST_H_LSPERI_BIU, 11, 2), + RK3506_CRU_RESET_OFFSET(SRST_P_UART0, 11, 4), + RK3506_CRU_RESET_OFFSET(SRST_P_UART1, 11, 5), + RK3506_CRU_RESET_OFFSET(SRST_P_UART2, 11, 6), + RK3506_CRU_RESET_OFFSET(SRST_P_UART3, 11, 7), + RK3506_CRU_RESET_OFFSET(SRST_P_UART4, 11, 8), + RK3506_CRU_RESET_OFFSET(SRST_UART0, 11, 9), + RK3506_CRU_RESET_OFFSET(SRST_UART1, 11, 10), + RK3506_CRU_RESET_OFFSET(SRST_UART2, 11, 11), + RK3506_CRU_RESET_OFFSET(SRST_UART3, 11, 12), + RK3506_CRU_RESET_OFFSET(SRST_UART4, 11, 13), + RK3506_CRU_RESET_OFFSET(SRST_P_I2C0, 11, 14), + RK3506_CRU_RESET_OFFSET(SRST_I2C0, 11, 15), + + /* CRU-->SOFTRST_CON12 */ + RK3506_CRU_RESET_OFFSET(SRST_P_I2C1, 12, 0), + RK3506_CRU_RESET_OFFSET(SRST_I2C1, 12, 1), + RK3506_CRU_RESET_OFFSET(SRST_P_I2C2, 12, 2), + RK3506_CRU_RESET_OFFSET(SRST_I2C2, 12, 3), + RK3506_CRU_RESET_OFFSET(SRST_P_PWM1, 12, 4), + RK3506_CRU_RESET_OFFSET(SRST_PWM1, 12, 5), + RK3506_CRU_RESET_OFFSET(SRST_P_SPI0, 12, 10), + RK3506_CRU_RESET_OFFSET(SRST_SPI0, 12, 11), + RK3506_CRU_RESET_OFFSET(SRST_P_SPI1, 12, 12), + RK3506_CRU_RESET_OFFSET(SRST_SPI1, 12, 13), + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO2, 12, 14), + RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO2, 12, 15), + + /* CRU-->SOFTRST_CON13 */ + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO3, 13, 0), + RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO3, 13, 1), + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO4, 13, 2), + RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO4, 13, 3), + RK3506_CRU_RESET_OFFSET(SRST_H_CAN0, 13, 4), + RK3506_CRU_RESET_OFFSET(SRST_CAN0, 13, 5), + RK3506_CRU_RESET_OFFSET(SRST_H_CAN1, 13, 6), + RK3506_CRU_RESET_OFFSET(SRST_CAN1, 13, 7), + RK3506_CRU_RESET_OFFSET(SRST_H_PDM, 13, 8), + RK3506_CRU_RESET_OFFSET(SRST_M_PDM, 13, 9), + RK3506_CRU_RESET_OFFSET(SRST_PDM, 13, 10), + RK3506_CRU_RESET_OFFSET(SRST_SPDIFTX, 13, 11), + RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFTX, 13, 12), + RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFRX, 13, 13), + RK3506_CRU_RESET_OFFSET(SRST_SPDIFRX, 13, 14), + RK3506_CRU_RESET_OFFSET(SRST_M_SAI0, 13, 15), + + /* CRU-->SOFTRST_CON14 */ + RK3506_CRU_RESET_OFFSET(SRST_H_SAI0, 14, 0), + RK3506_CRU_RESET_OFFSET(SRST_M_SAI1, 14, 2), + RK3506_CRU_RESET_OFFSET(SRST_H_SAI1, 14, 3), + RK3506_CRU_RESET_OFFSET(SRST_H_ASRC0, 14, 5), + RK3506_CRU_RESET_OFFSET(SRST_ASRC0, 14, 6), + RK3506_CRU_RESET_OFFSET(SRST_H_ASRC1, 14, 7), + RK3506_CRU_RESET_OFFSET(SRST_ASRC1, 14, 8), + + /* CRU-->SOFTRST_CON17 */ + RK3506_CRU_RESET_OFFSET(SRST_H_HSPERI_BIU, 17, 4), + RK3506_CRU_RESET_OFFSET(SRST_H_SDMMC, 17, 7), + RK3506_CRU_RESET_OFFSET(SRST_H_FSPI, 17, 8), + RK3506_CRU_RESET_OFFSET(SRST_S_FSPI, 17, 9), + RK3506_CRU_RESET_OFFSET(SRST_P_SPI2, 17, 10), + RK3506_CRU_RESET_OFFSET(SRST_A_MAC0, 17, 11), + RK3506_CRU_RESET_OFFSET(SRST_A_MAC1, 17, 12), + + /* CRU-->SOFTRST_CON18 */ + RK3506_CRU_RESET_OFFSET(SRST_M_SAI2, 18, 2), + RK3506_CRU_RESET_OFFSET(SRST_H_SAI2, 18, 3), + RK3506_CRU_RESET_OFFSET(SRST_H_SAI3, 18, 6), + RK3506_CRU_RESET_OFFSET(SRST_M_SAI3, 18, 7), + RK3506_CRU_RESET_OFFSET(SRST_H_SAI4, 18, 10), + RK3506_CRU_RESET_OFFSET(SRST_M_SAI4, 18, 11), + RK3506_CRU_RESET_OFFSET(SRST_H_DSM, 18, 12), + RK3506_CRU_RESET_OFFSET(SRST_M_DSM, 18, 13), + RK3506_CRU_RESET_OFFSET(SRST_P_AUDIO_ADC, 18, 14), + RK3506_CRU_RESET_OFFSET(SRST_M_AUDIO_ADC, 18, 15), + + /* CRU-->SOFTRST_CON19 */ + RK3506_CRU_RESET_OFFSET(SRST_P_SARADC, 19, 0), + RK3506_CRU_RESET_OFFSET(SRST_SARADC, 19, 1), + RK3506_CRU_RESET_OFFSET(SRST_SARADC_PHY, 19, 2), + RK3506_CRU_RESET_OFFSET(SRST_P_OTPC_NS, 19, 3), + RK3506_CRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 19, 4), + RK3506_CRU_RESET_OFFSET(SRST_USER_OTPC_NS, 19, 5), + RK3506_CRU_RESET_OFFSET(SRST_P_UART5, 19, 6), + RK3506_CRU_RESET_OFFSET(SRST_UART5, 19, 7), + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO234_IOC, 19, 8), + + /* CRU-->SOFTRST_CON21 */ + RK3506_CRU_RESET_OFFSET(SRST_A_VIO_BIU, 21, 3), + RK3506_CRU_RESET_OFFSET(SRST_H_VIO_BIU, 21, 4), + RK3506_CRU_RESET_OFFSET(SRST_H_RGA, 21, 6), + RK3506_CRU_RESET_OFFSET(SRST_A_RGA, 21, 7), + RK3506_CRU_RESET_OFFSET(SRST_CORE_RGA, 21, 8), + RK3506_CRU_RESET_OFFSET(SRST_A_VOP, 21, 9), + RK3506_CRU_RESET_OFFSET(SRST_H_VOP, 21, 10), + RK3506_CRU_RESET_OFFSET(SRST_VOP, 21, 11), + RK3506_CRU_RESET_OFFSET(SRST_P_DPHY, 21, 12), + RK3506_CRU_RESET_OFFSET(SRST_P_DSI_HOST, 21, 13), + RK3506_CRU_RESET_OFFSET(SRST_P_TSADC, 21, 14), + RK3506_CRU_RESET_OFFSET(SRST_TSADC, 21, 15), + + /* CRU-->SOFTRST_CON22 */ + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1_IOC, 22, 1), +}; + +void rk3506_rst_init(struct device_node *np, void __iomem *reg_base) +{ + rockchip_register_softrst_lut(np, + rk3506_register_offset, + ARRAY_SIZE(rk3506_register_offset), + reg_base + RK3506_SOFTRST_CON(0), + ROCKCHIP_SOFTRST_HIWORD_MASK); +} diff --git a/drivers/clk/rockchip/rst-rv1126b.c b/drivers/clk/rockchip/rst-rv1126b.c new file mode 100644 index 0000000000000..c75b0d885ca23 --- /dev/null +++ b/drivers/clk/rockchip/rst-rv1126b.c @@ -0,0 +1,443 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + * Author: Elaine Zhang + */ + +#include +#include +#include +#include "clk.h" + +/* 0x20000000 + 0x0A00 */ +#define TOPCRU_RESET_OFFSET(id, reg, bit) [id] = (0x0 * 4 + reg * 16 + bit) +/* 0x20010000 + 0x0A00 */ +#define BUSCRU_RESET_OFFSET(id, reg, bit) [id] = (0x10000 * 4 + reg * 16 + bit) +/* 0x20020000 + 0x0A00 */ +#define PERICRU_RESET_OFFSET(id, reg, bit) [id] = (0x20000 * 4 + reg * 16 + bit) +/* 0x20030000 + 0x0A00 */ +#define CORECRU_RESET_OFFSET(id, reg, bit) [id] = (0x30000 * 4 + reg * 16 + bit) +/* 0x20040000 + 0x0A00 */ +#define PMUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x40000 * 4 + reg * 16 + bit) +/* 0x20050000 + 0x0A00 */ +#define PMU1CRU_RESET_OFFSET(id, reg, bit) [id] = (0x50000 * 4 + reg * 16 + bit) +/* 0x20060000 + 0x0A00 */ +#define DDRCRU_RESET_OFFSET(id, reg, bit) [id] = (0x60000 * 4 + reg * 16 + bit) +/* 0x20068000 + 0x0A00 */ +#define SUBDDRCRU_RESET_OFFSET(id, reg, bit) [id] = (0x68000 * 4 + reg * 16 + bit) +/* 0x20070000 + 0x0A00 */ +#define VICRU_RESET_OFFSET(id, reg, bit) [id] = (0x70000 * 4 + reg * 16 + bit) +/* 0x20080000 + 0x0A00 */ +#define VEPUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x80000 * 4 + reg * 16 + bit) +/* 0x20090000 + 0x0A00 */ +#define NPUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x90000 * 4 + reg * 16 + bit) +/* 0x200A0000 + 0x0A00 */ +#define VDOCRU_RESET_OFFSET(id, reg, bit) [id] = (0xA0000 * 4 + reg * 16 + bit) +/* 0x200B0000 + 0x0A00 */ +#define VCPCRU_RESET_OFFSET(id, reg, bit) [id] = (0xB0000 * 4 + reg * 16 + bit) + +/* =================mapping table for reset ID to register offset================== */ +static const int rv1126b_register_offset[] = { + /* TOPCRU-->SOFTRST_CON00 */ + + /* TOPCRU-->SOFTRST_CON15 */ + TOPCRU_RESET_OFFSET(SRST_P_CRU, 15, 1), + TOPCRU_RESET_OFFSET(SRST_P_CRU_BIU, 15, 2), + + /* BUSCRU-->SOFTRST_CON00 */ + BUSCRU_RESET_OFFSET(SRST_A_TOP_BIU, 0, 0), + BUSCRU_RESET_OFFSET(SRST_A_RKCE_BIU, 0, 1), + BUSCRU_RESET_OFFSET(SRST_A_BUS_BIU, 0, 2), + BUSCRU_RESET_OFFSET(SRST_H_BUS_BIU, 0, 3), + BUSCRU_RESET_OFFSET(SRST_P_BUS_BIU, 0, 4), + BUSCRU_RESET_OFFSET(SRST_P_CRU_BUS, 0, 5), + BUSCRU_RESET_OFFSET(SRST_P_SYS_GRF, 0, 6), + BUSCRU_RESET_OFFSET(SRST_H_BOOTROM, 0, 7), + BUSCRU_RESET_OFFSET(SRST_A_GIC400, 0, 8), + BUSCRU_RESET_OFFSET(SRST_A_SPINLOCK, 0, 9), + BUSCRU_RESET_OFFSET(SRST_P_WDT_NS, 0, 10), + BUSCRU_RESET_OFFSET(SRST_T_WDT_NS, 0, 11), + + /* BUSCRU-->SOFTRST_CON01 */ + BUSCRU_RESET_OFFSET(SRST_P_WDT_HPMCU, 1, 0), + BUSCRU_RESET_OFFSET(SRST_T_WDT_HPMCU, 1, 1), + BUSCRU_RESET_OFFSET(SRST_H_CACHE, 1, 2), + BUSCRU_RESET_OFFSET(SRST_P_HPMCU_MAILBOX, 1, 3), + BUSCRU_RESET_OFFSET(SRST_P_HPMCU_INTMUX, 1, 4), + BUSCRU_RESET_OFFSET(SRST_HPMCU_FULL_CLUSTER, 1, 5), + BUSCRU_RESET_OFFSET(SRST_HPMCU_PWUP, 1, 6), + BUSCRU_RESET_OFFSET(SRST_HPMCU_ONLY_CORE, 1, 7), + BUSCRU_RESET_OFFSET(SRST_T_HPMCU_JTAG, 1, 8), + BUSCRU_RESET_OFFSET(SRST_P_RKDMA, 1, 11), + BUSCRU_RESET_OFFSET(SRST_A_RKDMA, 1, 12), + + /* BUSCRU-->SOFTRST_CON02 */ + BUSCRU_RESET_OFFSET(SRST_P_DCF, 2, 0), + BUSCRU_RESET_OFFSET(SRST_A_DCF, 2, 1), + BUSCRU_RESET_OFFSET(SRST_H_RGA, 2, 2), + BUSCRU_RESET_OFFSET(SRST_A_RGA, 2, 3), + BUSCRU_RESET_OFFSET(SRST_CORE_RGA, 2, 4), + BUSCRU_RESET_OFFSET(SRST_P_TIMER, 2, 5), + BUSCRU_RESET_OFFSET(SRST_TIMER0, 2, 6), + BUSCRU_RESET_OFFSET(SRST_TIMER1, 2, 7), + BUSCRU_RESET_OFFSET(SRST_TIMER2, 2, 8), + BUSCRU_RESET_OFFSET(SRST_TIMER3, 2, 9), + BUSCRU_RESET_OFFSET(SRST_TIMER4, 2, 10), + BUSCRU_RESET_OFFSET(SRST_TIMER5, 2, 11), + BUSCRU_RESET_OFFSET(SRST_A_RKCE, 2, 12), + BUSCRU_RESET_OFFSET(SRST_PKA_RKCE, 2, 13), + BUSCRU_RESET_OFFSET(SRST_H_RKRNG_S, 2, 14), + BUSCRU_RESET_OFFSET(SRST_H_RKRNG_NS, 2, 15), + + /* BUSCRU-->SOFTRST_CON03 */ + BUSCRU_RESET_OFFSET(SRST_P_I2C0, 3, 0), + BUSCRU_RESET_OFFSET(SRST_I2C0, 3, 1), + BUSCRU_RESET_OFFSET(SRST_P_I2C1, 3, 2), + BUSCRU_RESET_OFFSET(SRST_I2C1, 3, 3), + BUSCRU_RESET_OFFSET(SRST_P_I2C3, 3, 4), + BUSCRU_RESET_OFFSET(SRST_I2C3, 3, 5), + BUSCRU_RESET_OFFSET(SRST_P_I2C4, 3, 6), + BUSCRU_RESET_OFFSET(SRST_I2C4, 3, 7), + BUSCRU_RESET_OFFSET(SRST_P_I2C5, 3, 8), + BUSCRU_RESET_OFFSET(SRST_I2C5, 3, 9), + BUSCRU_RESET_OFFSET(SRST_P_SPI0, 3, 10), + BUSCRU_RESET_OFFSET(SRST_SPI0, 3, 11), + BUSCRU_RESET_OFFSET(SRST_P_SPI1, 3, 12), + BUSCRU_RESET_OFFSET(SRST_SPI1, 3, 13), + + /* BUSCRU-->SOFTRST_CON04 */ + BUSCRU_RESET_OFFSET(SRST_P_PWM0, 4, 0), + BUSCRU_RESET_OFFSET(SRST_PWM0, 4, 1), + BUSCRU_RESET_OFFSET(SRST_P_PWM2, 4, 4), + BUSCRU_RESET_OFFSET(SRST_PWM2, 4, 5), + BUSCRU_RESET_OFFSET(SRST_P_PWM3, 4, 8), + BUSCRU_RESET_OFFSET(SRST_PWM3, 4, 9), + + /* BUSCRU-->SOFTRST_CON05 */ + BUSCRU_RESET_OFFSET(SRST_P_UART1, 5, 0), + BUSCRU_RESET_OFFSET(SRST_S_UART1, 5, 1), + BUSCRU_RESET_OFFSET(SRST_P_UART2, 5, 2), + BUSCRU_RESET_OFFSET(SRST_S_UART2, 5, 3), + BUSCRU_RESET_OFFSET(SRST_P_UART3, 5, 4), + BUSCRU_RESET_OFFSET(SRST_S_UART3, 5, 5), + BUSCRU_RESET_OFFSET(SRST_P_UART4, 5, 6), + BUSCRU_RESET_OFFSET(SRST_S_UART4, 5, 7), + BUSCRU_RESET_OFFSET(SRST_P_UART5, 5, 8), + BUSCRU_RESET_OFFSET(SRST_S_UART5, 5, 9), + BUSCRU_RESET_OFFSET(SRST_P_UART6, 5, 10), + BUSCRU_RESET_OFFSET(SRST_S_UART6, 5, 11), + BUSCRU_RESET_OFFSET(SRST_P_UART7, 5, 12), + BUSCRU_RESET_OFFSET(SRST_S_UART7, 5, 13), + + /* BUSCRU-->SOFTRST_CON06 */ + BUSCRU_RESET_OFFSET(SRST_P_TSADC, 6, 0), + BUSCRU_RESET_OFFSET(SRST_TSADC, 6, 1), + BUSCRU_RESET_OFFSET(SRST_H_SAI0, 6, 2), + BUSCRU_RESET_OFFSET(SRST_M_SAI0, 6, 3), + BUSCRU_RESET_OFFSET(SRST_H_SAI1, 6, 4), + BUSCRU_RESET_OFFSET(SRST_M_SAI1, 6, 5), + BUSCRU_RESET_OFFSET(SRST_H_SAI2, 6, 6), + BUSCRU_RESET_OFFSET(SRST_M_SAI2, 6, 7), + BUSCRU_RESET_OFFSET(SRST_H_RKDSM, 6, 8), + BUSCRU_RESET_OFFSET(SRST_M_RKDSM, 6, 9), + BUSCRU_RESET_OFFSET(SRST_H_PDM, 6, 10), + BUSCRU_RESET_OFFSET(SRST_M_PDM, 6, 11), + BUSCRU_RESET_OFFSET(SRST_PDM, 6, 12), + + /* BUSCRU-->SOFTRST_CON07 */ + BUSCRU_RESET_OFFSET(SRST_H_ASRC0, 7, 0), + BUSCRU_RESET_OFFSET(SRST_ASRC0, 7, 1), + BUSCRU_RESET_OFFSET(SRST_H_ASRC1, 7, 2), + BUSCRU_RESET_OFFSET(SRST_ASRC1, 7, 3), + BUSCRU_RESET_OFFSET(SRST_P_AUDIO_ADC_BUS, 7, 4), + BUSCRU_RESET_OFFSET(SRST_M_AUDIO_ADC_BUS, 7, 5), + BUSCRU_RESET_OFFSET(SRST_P_RKCE, 7, 6), + BUSCRU_RESET_OFFSET(SRST_H_NS_RKCE, 7, 7), + BUSCRU_RESET_OFFSET(SRST_P_OTPC_NS, 7, 8), + BUSCRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 7, 9), + BUSCRU_RESET_OFFSET(SRST_USER_OTPC_NS, 7, 10), + BUSCRU_RESET_OFFSET(SRST_OTPC_ARB, 7, 11), + BUSCRU_RESET_OFFSET(SRST_P_OTP_MASK, 7, 12), + + /* PERICRU-->SOFTRST_CON00 */ + PERICRU_RESET_OFFSET(SRST_A_PERI_BIU, 0, 0), + PERICRU_RESET_OFFSET(SRST_P_PERI_BIU, 0, 1), + PERICRU_RESET_OFFSET(SRST_P_RTC_BIU, 0, 2), + PERICRU_RESET_OFFSET(SRST_P_CRU_PERI, 0, 3), + PERICRU_RESET_OFFSET(SRST_P_PERI_GRF, 0, 4), + PERICRU_RESET_OFFSET(SRST_P_GPIO1, 0, 5), + PERICRU_RESET_OFFSET(SRST_DB_GPIO1, 0, 6), + PERICRU_RESET_OFFSET(SRST_P_IOC_VCCIO1, 0, 7), + PERICRU_RESET_OFFSET(SRST_A_USB3OTG, 0, 8), + PERICRU_RESET_OFFSET(SRST_H_USB2HOST, 0, 11), + PERICRU_RESET_OFFSET(SRST_H_ARB_USB2HOST, 0, 12), + PERICRU_RESET_OFFSET(SRST_P_RTC_TEST, 0, 13), + + /* PERICRU-->SOFTRST_CON01 */ + PERICRU_RESET_OFFSET(SRST_H_EMMC, 1, 0), + PERICRU_RESET_OFFSET(SRST_H_FSPI0, 1, 1), + PERICRU_RESET_OFFSET(SRST_H_XIP_FSPI0, 1, 2), + PERICRU_RESET_OFFSET(SRST_S_2X_FSPI0, 1, 3), + PERICRU_RESET_OFFSET(SRST_UTMI_USB2HOST, 1, 5), + PERICRU_RESET_OFFSET(SRST_REF_PIPEPHY, 1, 7), + PERICRU_RESET_OFFSET(SRST_P_PIPEPHY, 1, 8), + PERICRU_RESET_OFFSET(SRST_P_PIPEPHY_GRF, 1, 9), + PERICRU_RESET_OFFSET(SRST_P_USB2PHY, 1, 10), + PERICRU_RESET_OFFSET(SRST_POR_USB2PHY, 1, 11), + PERICRU_RESET_OFFSET(SRST_OTG_USB2PHY, 1, 12), + PERICRU_RESET_OFFSET(SRST_HOST_USB2PHY, 1, 13), + + /* CORECRU-->SOFTRST_CON00 */ + CORECRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 0, 0), + CORECRU_RESET_OFFSET(SRST_NCOREPORESET0, 0, 1), + CORECRU_RESET_OFFSET(SRST_NCORESET0, 0, 2), + CORECRU_RESET_OFFSET(SRST_NCOREPORESET1, 0, 3), + CORECRU_RESET_OFFSET(SRST_NCORESET1, 0, 4), + CORECRU_RESET_OFFSET(SRST_NCOREPORESET2, 0, 5), + CORECRU_RESET_OFFSET(SRST_NCORESET2, 0, 6), + CORECRU_RESET_OFFSET(SRST_NCOREPORESET3, 0, 7), + CORECRU_RESET_OFFSET(SRST_NCORESET3, 0, 8), + CORECRU_RESET_OFFSET(SRST_NDBGRESET, 0, 9), + CORECRU_RESET_OFFSET(SRST_NL2RESET, 0, 10), + + /* CORECRU-->SOFTRST_CON01 */ + CORECRU_RESET_OFFSET(SRST_A_CORE_BIU, 1, 0), + CORECRU_RESET_OFFSET(SRST_P_CORE_BIU, 1, 1), + CORECRU_RESET_OFFSET(SRST_H_CORE_BIU, 1, 2), + CORECRU_RESET_OFFSET(SRST_P_DBG, 1, 3), + CORECRU_RESET_OFFSET(SRST_POT_DBG, 1, 4), + CORECRU_RESET_OFFSET(SRST_NT_DBG, 1, 5), + CORECRU_RESET_OFFSET(SRST_P_CORE_PVTPLL, 1, 6), + CORECRU_RESET_OFFSET(SRST_P_CRU_CORE, 1, 7), + CORECRU_RESET_OFFSET(SRST_P_CORE_GRF, 1, 8), + CORECRU_RESET_OFFSET(SRST_P_DFT2APB, 1, 10), + + /* PMUCRU-->SOFTRST_CON00 */ + PMUCRU_RESET_OFFSET(SRST_H_PMU_BIU, 0, 0), + PMUCRU_RESET_OFFSET(SRST_P_PMU_GPIO0, 0, 7), + PMUCRU_RESET_OFFSET(SRST_DB_PMU_GPIO0, 0, 8), + PMUCRU_RESET_OFFSET(SRST_P_PMU_HP_TIMER, 0, 10), + PMUCRU_RESET_OFFSET(SRST_PMU_HP_TIMER, 0, 11), + PMUCRU_RESET_OFFSET(SRST_PMU_32K_HP_TIMER, 0, 12), + + /* PMUCRU-->SOFTRST_CON01 */ + PMUCRU_RESET_OFFSET(SRST_P_PWM1, 1, 0), + PMUCRU_RESET_OFFSET(SRST_PWM1, 1, 1), + PMUCRU_RESET_OFFSET(SRST_P_I2C2, 1, 2), + PMUCRU_RESET_OFFSET(SRST_I2C2, 1, 3), + PMUCRU_RESET_OFFSET(SRST_P_UART0, 1, 4), + PMUCRU_RESET_OFFSET(SRST_S_UART0, 1, 5), + + /* PMUCRU-->SOFTRST_CON02 */ + PMUCRU_RESET_OFFSET(SRST_P_RCOSC_CTRL, 2, 0), + PMUCRU_RESET_OFFSET(SRST_REF_RCOSC_CTRL, 2, 2), + PMUCRU_RESET_OFFSET(SRST_P_IOC_PMUIO0, 2, 3), + PMUCRU_RESET_OFFSET(SRST_P_CRU_PMU, 2, 4), + PMUCRU_RESET_OFFSET(SRST_P_PMU_GRF, 2, 5), + PMUCRU_RESET_OFFSET(SRST_PREROLL, 2, 7), + PMUCRU_RESET_OFFSET(SRST_PREROLL_32K, 2, 8), + PMUCRU_RESET_OFFSET(SRST_H_PMU_SRAM, 2, 9), + + /* PMUCRU-->SOFTRST_CON03 */ + PMUCRU_RESET_OFFSET(SRST_P_WDT_LPMCU, 3, 0), + PMUCRU_RESET_OFFSET(SRST_T_WDT_LPMCU, 3, 1), + PMUCRU_RESET_OFFSET(SRST_LPMCU_FULL_CLUSTER, 3, 2), + PMUCRU_RESET_OFFSET(SRST_LPMCU_PWUP, 3, 3), + PMUCRU_RESET_OFFSET(SRST_LPMCU_ONLY_CORE, 3, 4), + PMUCRU_RESET_OFFSET(SRST_T_LPMCU_JTAG, 3, 5), + PMUCRU_RESET_OFFSET(SRST_P_LPMCU_MAILBOX, 3, 6), + + /* PMU1CRU-->SOFTRST_CON00 */ + PMU1CRU_RESET_OFFSET(SRST_P_SPI2AHB, 0, 0), + PMU1CRU_RESET_OFFSET(SRST_H_SPI2AHB, 0, 1), + PMU1CRU_RESET_OFFSET(SRST_H_FSPI1, 0, 2), + PMU1CRU_RESET_OFFSET(SRST_H_XIP_FSPI1, 0, 3), + PMU1CRU_RESET_OFFSET(SRST_S_1X_FSPI1, 0, 4), + PMU1CRU_RESET_OFFSET(SRST_P_IOC_PMUIO1, 0, 5), + PMU1CRU_RESET_OFFSET(SRST_P_CRU_PMU1, 0, 6), + PMU1CRU_RESET_OFFSET(SRST_P_AUDIO_ADC_PMU, 0, 7), + PMU1CRU_RESET_OFFSET(SRST_M_AUDIO_ADC_PMU, 0, 8), + PMU1CRU_RESET_OFFSET(SRST_H_PMU1_BIU, 0, 9), + + /* PMU1CRU-->SOFTRST_CON01 */ + PMU1CRU_RESET_OFFSET(SRST_P_LPDMA, 1, 0), + PMU1CRU_RESET_OFFSET(SRST_A_LPDMA, 1, 1), + PMU1CRU_RESET_OFFSET(SRST_H_LPSAI, 1, 2), + PMU1CRU_RESET_OFFSET(SRST_M_LPSAI, 1, 3), + PMU1CRU_RESET_OFFSET(SRST_P_AOA_TDD, 1, 4), + PMU1CRU_RESET_OFFSET(SRST_P_AOA_FE, 1, 5), + PMU1CRU_RESET_OFFSET(SRST_P_AOA_AAD, 1, 6), + PMU1CRU_RESET_OFFSET(SRST_P_AOA_APB, 1, 7), + PMU1CRU_RESET_OFFSET(SRST_P_AOA_SRAM, 1, 8), + + /* DDRCRU-->SOFTRST_CON00 */ + DDRCRU_RESET_OFFSET(SRST_P_DDR_BIU, 0, 1), + DDRCRU_RESET_OFFSET(SRST_P_DDRC, 0, 2), + DDRCRU_RESET_OFFSET(SRST_P_DDRMON, 0, 3), + DDRCRU_RESET_OFFSET(SRST_TIMER_DDRMON, 0, 4), + DDRCRU_RESET_OFFSET(SRST_P_DFICTRL, 0, 5), + DDRCRU_RESET_OFFSET(SRST_P_DDR_GRF, 0, 6), + DDRCRU_RESET_OFFSET(SRST_P_CRU_DDR, 0, 7), + DDRCRU_RESET_OFFSET(SRST_P_DDRPHY, 0, 8), + DDRCRU_RESET_OFFSET(SRST_P_DMA2DDR, 0, 9), + + /* SUBDDRCRU-->SOFTRST_CON00 */ + SUBDDRCRU_RESET_OFFSET(SRST_A_SYSMEM_BIU, 0, 0), + SUBDDRCRU_RESET_OFFSET(SRST_A_SYSMEM, 0, 1), + SUBDDRCRU_RESET_OFFSET(SRST_A_DDR_BIU, 0, 2), + SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH0_CPU, 0, 3), + SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH1_NPU, 0, 4), + SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH2_POE, 0, 5), + SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH3_VI, 0, 6), + SUBDDRCRU_RESET_OFFSET(SRST_CORE_DDRC, 0, 7), + SUBDDRCRU_RESET_OFFSET(SRST_DDRMON, 0, 8), + SUBDDRCRU_RESET_OFFSET(SRST_DFICTRL, 0, 9), + SUBDDRCRU_RESET_OFFSET(SRST_RS, 0, 11), + SUBDDRCRU_RESET_OFFSET(SRST_A_DMA2DDR, 0, 12), + SUBDDRCRU_RESET_OFFSET(SRST_DDRPHY, 0, 13), + + /* VICRU-->SOFTRST_CON00 */ + VICRU_RESET_OFFSET(SRST_REF_PVTPLL_ISP, 0, 0), + VICRU_RESET_OFFSET(SRST_A_GMAC_BIU, 0, 1), + VICRU_RESET_OFFSET(SRST_A_VI_BIU, 0, 2), + VICRU_RESET_OFFSET(SRST_H_VI_BIU, 0, 3), + VICRU_RESET_OFFSET(SRST_P_VI_BIU, 0, 4), + VICRU_RESET_OFFSET(SRST_P_CRU_VI, 0, 5), + VICRU_RESET_OFFSET(SRST_P_VI_GRF, 0, 6), + VICRU_RESET_OFFSET(SRST_P_VI_PVTPLL, 0, 7), + VICRU_RESET_OFFSET(SRST_P_DSMC, 0, 8), + VICRU_RESET_OFFSET(SRST_A_DSMC, 0, 9), + VICRU_RESET_OFFSET(SRST_H_CAN0, 0, 10), + VICRU_RESET_OFFSET(SRST_CAN0, 0, 11), + VICRU_RESET_OFFSET(SRST_H_CAN1, 0, 12), + VICRU_RESET_OFFSET(SRST_CAN1, 0, 13), + + /* VICRU-->SOFTRST_CON01 */ + VICRU_RESET_OFFSET(SRST_P_GPIO2, 1, 0), + VICRU_RESET_OFFSET(SRST_DB_GPIO2, 1, 1), + VICRU_RESET_OFFSET(SRST_P_GPIO4, 1, 2), + VICRU_RESET_OFFSET(SRST_DB_GPIO4, 1, 3), + VICRU_RESET_OFFSET(SRST_P_GPIO5, 1, 4), + VICRU_RESET_OFFSET(SRST_DB_GPIO5, 1, 5), + VICRU_RESET_OFFSET(SRST_P_GPIO6, 1, 6), + VICRU_RESET_OFFSET(SRST_DB_GPIO6, 1, 7), + VICRU_RESET_OFFSET(SRST_P_GPIO7, 1, 8), + VICRU_RESET_OFFSET(SRST_DB_GPIO7, 1, 9), + VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO2, 1, 10), + VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO4, 1, 11), + VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO5, 1, 12), + VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO6, 1, 13), + VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO7, 1, 14), + + /* VICRU-->SOFTRST_CON02 */ + VICRU_RESET_OFFSET(SRST_CORE_ISP, 2, 0), + VICRU_RESET_OFFSET(SRST_H_VICAP, 2, 1), + VICRU_RESET_OFFSET(SRST_A_VICAP, 2, 2), + VICRU_RESET_OFFSET(SRST_D_VICAP, 2, 3), + VICRU_RESET_OFFSET(SRST_ISP0_VICAP, 2, 4), + VICRU_RESET_OFFSET(SRST_CORE_VPSS, 2, 5), + VICRU_RESET_OFFSET(SRST_CORE_VPSL, 2, 6), + VICRU_RESET_OFFSET(SRST_P_CSI2HOST0, 2, 7), + VICRU_RESET_OFFSET(SRST_P_CSI2HOST1, 2, 8), + VICRU_RESET_OFFSET(SRST_P_CSI2HOST2, 2, 9), + VICRU_RESET_OFFSET(SRST_P_CSI2HOST3, 2, 10), + VICRU_RESET_OFFSET(SRST_H_SDMMC0, 2, 11), + VICRU_RESET_OFFSET(SRST_A_GMAC, 2, 12), + VICRU_RESET_OFFSET(SRST_P_CSIPHY0, 2, 13), + VICRU_RESET_OFFSET(SRST_P_CSIPHY1, 2, 14), + + /* VICRU-->SOFTRST_CON03 */ + VICRU_RESET_OFFSET(SRST_P_MACPHY, 3, 0), + VICRU_RESET_OFFSET(SRST_MACPHY, 3, 1), + VICRU_RESET_OFFSET(SRST_P_SARADC1, 3, 2), + VICRU_RESET_OFFSET(SRST_SARADC1, 3, 3), + VICRU_RESET_OFFSET(SRST_P_SARADC2, 3, 5), + VICRU_RESET_OFFSET(SRST_SARADC2, 3, 6), + + /* VEPUCRU-->SOFTRST_CON00 */ + VEPUCRU_RESET_OFFSET(SRST_REF_PVTPLL_VEPU, 0, 0), + VEPUCRU_RESET_OFFSET(SRST_A_VEPU_BIU, 0, 1), + VEPUCRU_RESET_OFFSET(SRST_H_VEPU_BIU, 0, 2), + VEPUCRU_RESET_OFFSET(SRST_P_VEPU_BIU, 0, 3), + VEPUCRU_RESET_OFFSET(SRST_P_CRU_VEPU, 0, 4), + VEPUCRU_RESET_OFFSET(SRST_P_VEPU_GRF, 0, 5), + VEPUCRU_RESET_OFFSET(SRST_P_GPIO3, 0, 7), + VEPUCRU_RESET_OFFSET(SRST_DB_GPIO3, 0, 8), + VEPUCRU_RESET_OFFSET(SRST_P_IOC_VCCIO3, 0, 9), + VEPUCRU_RESET_OFFSET(SRST_P_SARADC0, 0, 10), + VEPUCRU_RESET_OFFSET(SRST_SARADC0, 0, 11), + VEPUCRU_RESET_OFFSET(SRST_H_SDMMC1, 0, 13), + + /* VEPUCRU-->SOFTRST_CON01 */ + VEPUCRU_RESET_OFFSET(SRST_P_VEPU_PVTPLL, 1, 0), + VEPUCRU_RESET_OFFSET(SRST_H_VEPU, 1, 1), + VEPUCRU_RESET_OFFSET(SRST_A_VEPU, 1, 2), + VEPUCRU_RESET_OFFSET(SRST_CORE_VEPU, 1, 3), + + /* NPUCRU-->SOFTRST_CON00 */ + NPUCRU_RESET_OFFSET(SRST_REF_PVTPLL_NPU, 0, 0), + NPUCRU_RESET_OFFSET(SRST_A_NPU_BIU, 0, 2), + NPUCRU_RESET_OFFSET(SRST_H_NPU_BIU, 0, 3), + NPUCRU_RESET_OFFSET(SRST_P_NPU_BIU, 0, 4), + NPUCRU_RESET_OFFSET(SRST_P_CRU_NPU, 0, 5), + NPUCRU_RESET_OFFSET(SRST_P_NPU_GRF, 0, 6), + NPUCRU_RESET_OFFSET(SRST_P_NPU_PVTPLL, 0, 8), + NPUCRU_RESET_OFFSET(SRST_H_RKNN, 0, 9), + NPUCRU_RESET_OFFSET(SRST_A_RKNN, 0, 10), + + /* VDOCRU-->SOFTRST_CON00 */ + VDOCRU_RESET_OFFSET(SRST_A_RKVDEC_BIU, 0, 0), + VDOCRU_RESET_OFFSET(SRST_A_VDO_BIU, 0, 1), + VDOCRU_RESET_OFFSET(SRST_H_VDO_BIU, 0, 3), + VDOCRU_RESET_OFFSET(SRST_P_VDO_BIU, 0, 4), + VDOCRU_RESET_OFFSET(SRST_P_CRU_VDO, 0, 5), + VDOCRU_RESET_OFFSET(SRST_P_VDO_GRF, 0, 6), + VDOCRU_RESET_OFFSET(SRST_A_RKVDEC, 0, 7), + VDOCRU_RESET_OFFSET(SRST_H_RKVDEC, 0, 8), + VDOCRU_RESET_OFFSET(SRST_HEVC_CA_RKVDEC, 0, 9), + VDOCRU_RESET_OFFSET(SRST_A_VOP, 0, 10), + VDOCRU_RESET_OFFSET(SRST_H_VOP, 0, 11), + VDOCRU_RESET_OFFSET(SRST_D_VOP, 0, 12), + VDOCRU_RESET_OFFSET(SRST_A_OOC, 0, 13), + VDOCRU_RESET_OFFSET(SRST_H_OOC, 0, 14), + VDOCRU_RESET_OFFSET(SRST_D_OOC, 0, 15), + + /* VDOCRU-->SOFTRST_CON01 */ + VDOCRU_RESET_OFFSET(SRST_H_RKJPEG, 1, 3), + VDOCRU_RESET_OFFSET(SRST_A_RKJPEG, 1, 4), + VDOCRU_RESET_OFFSET(SRST_A_RKMMU_DECOM, 1, 5), + VDOCRU_RESET_OFFSET(SRST_H_RKMMU_DECOM, 1, 6), + VDOCRU_RESET_OFFSET(SRST_D_DECOM, 1, 8), + VDOCRU_RESET_OFFSET(SRST_A_DECOM, 1, 9), + VDOCRU_RESET_OFFSET(SRST_P_DECOM, 1, 10), + VDOCRU_RESET_OFFSET(SRST_P_MIPI_DSI, 1, 12), + VDOCRU_RESET_OFFSET(SRST_P_DSIPHY, 1, 13), + + /* VCPCRU-->SOFTRST_CON00 */ + VCPCRU_RESET_OFFSET(SRST_REF_PVTPLL_VCP, 0, 0), + VCPCRU_RESET_OFFSET(SRST_A_VCP_BIU, 0, 1), + VCPCRU_RESET_OFFSET(SRST_H_VCP_BIU, 0, 2), + VCPCRU_RESET_OFFSET(SRST_P_VCP_BIU, 0, 3), + VCPCRU_RESET_OFFSET(SRST_P_CRU_VCP, 0, 4), + VCPCRU_RESET_OFFSET(SRST_P_VCP_GRF, 0, 5), + VCPCRU_RESET_OFFSET(SRST_P_VCP_PVTPLL, 0, 7), + VCPCRU_RESET_OFFSET(SRST_A_AISP_BIU, 0, 8), + VCPCRU_RESET_OFFSET(SRST_H_AISP_BIU, 0, 9), + VCPCRU_RESET_OFFSET(SRST_CORE_AISP, 0, 13), + + /* VCPCRU-->SOFTRST_CON01 */ + VCPCRU_RESET_OFFSET(SRST_H_FEC, 1, 0), + VCPCRU_RESET_OFFSET(SRST_A_FEC, 1, 1), + VCPCRU_RESET_OFFSET(SRST_CORE_FEC, 1, 2), + VCPCRU_RESET_OFFSET(SRST_H_AVSP, 1, 3), + VCPCRU_RESET_OFFSET(SRST_A_AVSP, 1, 4), +}; + +void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base) +{ + rockchip_register_softrst_lut(np, + rv1126b_register_offset, + ARRAY_SIZE(rv1126b_register_offset), + reg_base + RV1126B_SOFTRST_CON(0), + ROCKCHIP_SOFTRST_HIWORD_MASK); +} diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig index 76a494e95027a..70a8b82a0136b 100644 --- a/drivers/clk/samsung/Kconfig +++ b/drivers/clk/samsung/Kconfig @@ -95,6 +95,16 @@ config EXYNOS_CLKOUT status of the certains clocks from SoC, but it could also be tied to other devices as an input clock. +config EXYNOS_ACPM_CLK + tristate "Clock driver controlled via ACPM interface" + depends on EXYNOS_ACPM_PROTOCOL || (COMPILE_TEST && !EXYNOS_ACPM_PROTOCOL) + help + This driver provides support for clocks that are controlled by + firmware that implements the ACPM interface. + + This driver uses the ACPM interface to interact with the firmware + providing all the clock controlls. + config TESLA_FSD_COMMON_CLK bool "Tesla FSD clock controller support" if COMPILE_TEST depends on COMMON_CLK_SAMSUNG diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index ef464f434740f..f3657f2e1b98c 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos990.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynosautov9.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynosautov920.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-gs101.o +obj-$(CONFIG_EXYNOS_ACPM_CLK) += clk-acpm.o obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o obj-$(CONFIG_TESLA_FSD_COMMON_CLK) += clk-fsd.o diff --git a/drivers/clk/samsung/clk-acpm.c b/drivers/clk/samsung/clk-acpm.c new file mode 100644 index 0000000000000..b90809ce3f882 --- /dev/null +++ b/drivers/clk/samsung/clk-acpm.c @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Samsung Exynos ACPM protocol based clock driver. + * + * Copyright 2025 Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct acpm_clk { + u32 id; + struct clk_hw hw; + unsigned int mbox_chan_id; + const struct acpm_handle *handle; +}; + +struct acpm_clk_variant { + const char *name; +}; + +struct acpm_clk_driver_data { + const struct acpm_clk_variant *clks; + unsigned int nr_clks; + unsigned int mbox_chan_id; +}; + +#define to_acpm_clk(clk) container_of(clk, struct acpm_clk, hw) + +#define ACPM_CLK(cname) \ + { \ + .name = cname, \ + } + +static const struct acpm_clk_variant gs101_acpm_clks[] = { + ACPM_CLK("mif"), + ACPM_CLK("int"), + ACPM_CLK("cpucl0"), + ACPM_CLK("cpucl1"), + ACPM_CLK("cpucl2"), + ACPM_CLK("g3d"), + ACPM_CLK("g3dl2"), + ACPM_CLK("tpu"), + ACPM_CLK("intcam"), + ACPM_CLK("tnr"), + ACPM_CLK("cam"), + ACPM_CLK("mfc"), + ACPM_CLK("disp"), + ACPM_CLK("bo"), +}; + +static const struct acpm_clk_driver_data acpm_clk_gs101 = { + .clks = gs101_acpm_clks, + .nr_clks = ARRAY_SIZE(gs101_acpm_clks), + .mbox_chan_id = 0, +}; + +static unsigned long acpm_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct acpm_clk *clk = to_acpm_clk(hw); + + return clk->handle->ops.dvfs_ops.get_rate(clk->handle, + clk->mbox_chan_id, clk->id); +} + +static int acpm_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + /* + * We can't figure out what rate it will be, so just return the + * rate back to the caller. acpm_clk_recalc_rate() will be called + * after the rate is set and we'll know what rate the clock is + * running at then. + */ + return 0; +} + +static int acpm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct acpm_clk *clk = to_acpm_clk(hw); + + return clk->handle->ops.dvfs_ops.set_rate(clk->handle, + clk->mbox_chan_id, clk->id, rate); +} + +static const struct clk_ops acpm_clk_ops = { + .recalc_rate = acpm_clk_recalc_rate, + .determine_rate = acpm_clk_determine_rate, + .set_rate = acpm_clk_set_rate, +}; + +static int acpm_clk_register(struct device *dev, struct acpm_clk *aclk, + const char *name) +{ + struct clk_init_data init = {}; + + init.name = name; + init.ops = &acpm_clk_ops; + aclk->hw.init = &init; + + return devm_clk_hw_register(dev, &aclk->hw); +} + +static int acpm_clk_probe(struct platform_device *pdev) +{ + const struct acpm_handle *acpm_handle; + struct clk_hw_onecell_data *clk_data; + struct clk_hw **hws; + struct device *dev = &pdev->dev; + struct acpm_clk *aclks; + unsigned int mbox_chan_id; + int i, err, count; + + acpm_handle = devm_acpm_get_by_node(dev, dev->parent->of_node); + if (IS_ERR(acpm_handle)) + return dev_err_probe(dev, PTR_ERR(acpm_handle), + "Failed to get acpm handle\n"); + + count = acpm_clk_gs101.nr_clks; + mbox_chan_id = acpm_clk_gs101.mbox_chan_id; + + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->num = count; + hws = clk_data->hws; + + aclks = devm_kcalloc(dev, count, sizeof(*aclks), GFP_KERNEL); + if (!aclks) + return -ENOMEM; + + for (i = 0; i < count; i++) { + struct acpm_clk *aclk = &aclks[i]; + + /* + * The code assumes the clock IDs start from zero, + * are sequential and do not have gaps. + */ + aclk->id = i; + aclk->handle = acpm_handle; + aclk->mbox_chan_id = mbox_chan_id; + + hws[i] = &aclk->hw; + + err = acpm_clk_register(dev, aclk, + acpm_clk_gs101.clks[i].name); + if (err) + return dev_err_probe(dev, err, + "Failed to register clock\n"); + } + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + clk_data); +} + +static const struct platform_device_id acpm_clk_id[] = { + { "gs101-acpm-clk" }, + {} +}; +MODULE_DEVICE_TABLE(platform, acpm_clk_id); + +static struct platform_driver acpm_clk_driver = { + .driver = { + .name = "acpm-clocks", + }, + .probe = acpm_clk_probe, + .id_table = acpm_clk_id, +}; +module_platform_driver(acpm_clk_driver); + +MODULE_AUTHOR("Tudor Ambarus "); +MODULE_DESCRIPTION("Samsung Exynos ACPM clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/samsung/clk-exynos-clkout.c b/drivers/clk/samsung/clk-exynos-clkout.c index 5f1a4f5e2e594..5b21025338bd5 100644 --- a/drivers/clk/samsung/clk-exynos-clkout.c +++ b/drivers/clk/samsung/clk-exynos-clkout.c @@ -175,6 +175,7 @@ static int exynos_clkout_probe(struct platform_device *pdev) clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT; clkout->mux.lock = &clkout->slock; + clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; clkout->data.hws[0] = clk_hw_register_composite(NULL, "clkout", parent_names, parent_count, &clkout->mux.hw, &clk_mux_ops, NULL, NULL, &clkout->gate.hw, @@ -185,7 +186,6 @@ static int exynos_clkout_probe(struct platform_device *pdev) goto err_unmap; } - clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; ret = of_clk_add_hw_provider(clkout->np, of_clk_hw_onecell_get, &clkout->data); if (ret) goto err_clk_unreg; diff --git a/drivers/clk/samsung/clk-exynosautov920.c b/drivers/clk/samsung/clk-exynosautov920.c index 572b6ace14acd..b90b73c3518fe 100644 --- a/drivers/clk/samsung/clk-exynosautov920.c +++ b/drivers/clk/samsung/clk-exynosautov920.c @@ -27,6 +27,8 @@ #define CLKS_NR_HSI0 (CLK_DOUT_HSI0_PCIE_APB + 1) #define CLKS_NR_HSI1 (CLK_MOUT_HSI1_USBDRD + 1) #define CLKS_NR_HSI2 (CLK_DOUT_HSI2_ETHERNET_PTP + 1) +#define CLKS_NR_M2M (CLK_DOUT_M2M_NOCP + 1) +#define CLKS_NR_MFC (CLK_DOUT_MFC_NOCP + 1) /* ---- CMU_TOP ------------------------------------------------------------ */ @@ -1821,6 +1823,88 @@ static const struct samsung_cmu_info hsi2_cmu_info __initconst = { .clk_name = "noc", }; +/* ---- CMU_M2M --------------------------------------------------------- */ + +/* Register Offset definitions for CMU_M2M (0x1a800000) */ +#define PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER 0x600 +#define PLL_CON0_MUX_CLKCMU_M2M_NOC_USER 0x610 +#define CLK_CON_DIV_DIV_CLK_M2M_NOCP 0x1800 + +static const unsigned long m2m_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER, + PLL_CON0_MUX_CLKCMU_M2M_NOC_USER, + CLK_CON_DIV_DIV_CLK_M2M_NOCP, +}; + +/* List of parent clocks for Muxes in CMU_M2M */ +PNAME(mout_clkcmu_m2m_noc_user_p) = { "oscclk", "dout_clkcmu_m2m_noc" }; +PNAME(mout_clkcmu_m2m_jpeg_user_p) = { "oscclk", "dout_clkcmu_m2m_jpeg" }; + +static const struct samsung_mux_clock m2m_mux_clks[] __initconst = { + MUX(CLK_MOUT_M2M_JPEG_USER, "mout_clkcmu_m2m_jpeg_user", + mout_clkcmu_m2m_jpeg_user_p, PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER, 4, 1), + MUX(CLK_MOUT_M2M_NOC_USER, "mout_clkcmu_m2m_noc_user", + mout_clkcmu_m2m_noc_user_p, PLL_CON0_MUX_CLKCMU_M2M_NOC_USER, 4, 1), +}; + +static const struct samsung_div_clock m2m_div_clks[] __initconst = { + DIV(CLK_DOUT_M2M_NOCP, "dout_m2m_nocp", + "mout_clkcmu_m2m_noc_user", CLK_CON_DIV_DIV_CLK_M2M_NOCP, + 0, 3), +}; + +static const struct samsung_cmu_info m2m_cmu_info __initconst = { + .mux_clks = m2m_mux_clks, + .nr_mux_clks = ARRAY_SIZE(m2m_mux_clks), + .div_clks = m2m_div_clks, + .nr_div_clks = ARRAY_SIZE(m2m_div_clks), + .nr_clk_ids = CLKS_NR_M2M, + .clk_regs = m2m_clk_regs, + .nr_clk_regs = ARRAY_SIZE(m2m_clk_regs), + .clk_name = "noc", +}; + +/* ---- CMU_MFC --------------------------------------------------------- */ + +/* Register Offset definitions for CMU_MFC (0x19c00000) */ +#define PLL_CON0_MUX_CLKCMU_MFC_MFC_USER 0x600 +#define PLL_CON0_MUX_CLKCMU_MFC_WFD_USER 0x610 +#define CLK_CON_DIV_DIV_CLK_MFC_NOCP 0x1800 + +static const unsigned long mfc_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_MFC_MFC_USER, + PLL_CON0_MUX_CLKCMU_MFC_WFD_USER, + CLK_CON_DIV_DIV_CLK_MFC_NOCP, +}; + +/* List of parent clocks for Muxes in CMU_MFC */ +PNAME(mout_clkcmu_mfc_mfc_user_p) = { "oscclk", "dout_clkcmu_mfc_mfc" }; +PNAME(mout_clkcmu_mfc_wfd_user_p) = { "oscclk", "dout_clkcmu_mfc_wfd" }; + +static const struct samsung_mux_clock mfc_mux_clks[] __initconst = { + MUX(CLK_MOUT_MFC_MFC_USER, "mout_clkcmu_mfc_mfc_user", + mout_clkcmu_mfc_mfc_user_p, PLL_CON0_MUX_CLKCMU_MFC_MFC_USER, 4, 1), + MUX(CLK_MOUT_MFC_WFD_USER, "mout_clkcmu_mfc_wfd_user", + mout_clkcmu_mfc_wfd_user_p, PLL_CON0_MUX_CLKCMU_MFC_WFD_USER, 4, 1), +}; + +static const struct samsung_div_clock mfc_div_clks[] __initconst = { + DIV(CLK_DOUT_MFC_NOCP, "dout_mfc_nocp", + "mout_clkcmu_mfc_mfc_user", CLK_CON_DIV_DIV_CLK_MFC_NOCP, + 0, 3), +}; + +static const struct samsung_cmu_info mfc_cmu_info __initconst = { + .mux_clks = mfc_mux_clks, + .nr_mux_clks = ARRAY_SIZE(mfc_mux_clks), + .div_clks = mfc_div_clks, + .nr_div_clks = ARRAY_SIZE(mfc_div_clks), + .nr_clk_ids = CLKS_NR_MFC, + .clk_regs = mfc_clk_regs, + .nr_clk_regs = ARRAY_SIZE(mfc_clk_regs), + .clk_name = "noc", +}; + static int __init exynosautov920_cmu_probe(struct platform_device *pdev) { const struct samsung_cmu_info *info; @@ -1851,6 +1935,12 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = { }, { .compatible = "samsung,exynosautov920-cmu-hsi2", .data = &hsi2_cmu_info, + }, { + .compatible = "samsung,exynosautov920-cmu-m2m", + .data = &m2m_cmu_info, + }, { + .compatible = "samsung,exynosautov920-cmu-mfc", + .data = &mfc_cmu_info, }, { } }; diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 7bea7be1d7e45..0a8fc9649ae29 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -11,14 +11,12 @@ #include #include #include -#include #include #include #include "clk.h" #include "clk-pll.h" -#define PLL_TIMEOUT_US 20000U -#define PLL_TIMEOUT_LOOPS 1000000U +#define PLL_TIMEOUT_LOOPS 20000U struct samsung_clk_pll { struct clk_hw hw; @@ -71,20 +69,11 @@ static int samsung_pll_determine_rate(struct clk_hw *hw, return 0; } -static bool pll_early_timeout = true; - -static int __init samsung_pll_disable_early_timeout(void) -{ - pll_early_timeout = false; - return 0; -} -arch_initcall(samsung_pll_disable_early_timeout); - /* Wait until the PLL is locked */ static int samsung_pll_lock_wait(struct samsung_clk_pll *pll, unsigned int reg_mask) { - int i, ret; + int ret; u32 val; /* @@ -93,25 +82,15 @@ static int samsung_pll_lock_wait(struct samsung_clk_pll *pll, * initialized, another when the timekeeping is suspended. udelay() also * cannot be used when the clocksource is not running on arm64, since * the current timer is used as cycle counter. So a simple busy loop - * is used here in that special cases. The limit of iterations has been - * derived from experimental measurements of various PLLs on multiple - * Exynos SoC variants. Single register read time was usually in range - * 0.4...1.5 us, never less than 0.4 us. + * is used here. + * The limit of iterations has been derived from experimental + * measurements of various PLLs on multiple Exynos SoC variants. Single + * register read time was usually in range 0.4...1.5 us, never less than + * 0.4 us. */ - if (pll_early_timeout || timekeeping_suspended) { - i = PLL_TIMEOUT_LOOPS; - while (i-- > 0) { - if (readl_relaxed(pll->con_reg) & reg_mask) - return 0; - - cpu_relax(); - } - ret = -ETIMEDOUT; - } else { - ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val, - val & reg_mask, 0, PLL_TIMEOUT_US); - } - + ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val, + val & reg_mask, 0, + PLL_TIMEOUT_LOOPS); if (ret < 0) pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll->hw)); diff --git a/drivers/clk/samsung/clk-s5pv210-audss.c b/drivers/clk/samsung/clk-s5pv210-audss.c index b1fd8fac3a4c0..c9fcb23de183e 100644 --- a/drivers/clk/samsung/clk-s5pv210-audss.c +++ b/drivers/clk/samsung/clk-s5pv210-audss.c @@ -36,7 +36,7 @@ static unsigned long reg_save[][2] = { {ASS_CLK_GATE, 0}, }; -static int s5pv210_audss_clk_suspend(void) +static int s5pv210_audss_clk_suspend(void *data) { int i; @@ -46,7 +46,7 @@ static int s5pv210_audss_clk_suspend(void) return 0; } -static void s5pv210_audss_clk_resume(void) +static void s5pv210_audss_clk_resume(void *data) { int i; @@ -54,10 +54,14 @@ static void s5pv210_audss_clk_resume(void) writel(reg_save[i][1], reg_base + reg_save[i][0]); } -static struct syscore_ops s5pv210_audss_clk_syscore_ops = { +static const struct syscore_ops s5pv210_audss_clk_syscore_ops = { .suspend = s5pv210_audss_clk_suspend, .resume = s5pv210_audss_clk_resume, }; + +static struct syscore s5pv210_audss_clk_syscore = { + .ops = &s5pv210_audss_clk_syscore_ops, +}; #endif /* CONFIG_PM_SLEEP */ /* register s5pv210_audss clocks */ @@ -175,7 +179,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP - register_syscore_ops(&s5pv210_audss_clk_syscore_ops); + register_syscore(&s5pv210_audss_clk_syscore); #endif return 0; diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index dbc9925ca8f46..c149ca6c22172 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -271,7 +271,7 @@ void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx, } #ifdef CONFIG_PM_SLEEP -static int samsung_clk_suspend(void) +static int samsung_clk_suspend(void *data) { struct samsung_clock_reg_cache *reg_cache; @@ -284,7 +284,7 @@ static int samsung_clk_suspend(void) return 0; } -static void samsung_clk_resume(void) +static void samsung_clk_resume(void *data) { struct samsung_clock_reg_cache *reg_cache; @@ -293,11 +293,15 @@ static void samsung_clk_resume(void) reg_cache->rd_num); } -static struct syscore_ops samsung_clk_syscore_ops = { +static const struct syscore_ops samsung_clk_syscore_ops = { .suspend = samsung_clk_suspend, .resume = samsung_clk_resume, }; +static struct syscore samsung_clk_syscore = { + .ops = &samsung_clk_syscore_ops, +}; + void samsung_clk_extended_sleep_init(void __iomem *reg_base, const unsigned long *rdump, unsigned long nr_rdump, @@ -316,7 +320,7 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base, panic("could not allocate register dump storage.\n"); if (list_empty(&clock_reg_cache_list)) - register_syscore_ops(&samsung_clk_syscore_ops); + register_syscore(&samsung_clk_syscore); reg_cache->reg_base = reg_base; reg_cache->rd_num = nr_rdump; diff --git a/drivers/clk/socfpga/Kconfig b/drivers/clk/socfpga/Kconfig index 0cf16b894efb3..d88277e2a8981 100644 --- a/drivers/clk/socfpga/Kconfig +++ b/drivers/clk/socfpga/Kconfig @@ -13,7 +13,7 @@ config CLK_INTEL_SOCFPGA32 default ARM && ARCH_INTEL_SOCFPGA config CLK_INTEL_SOCFPGA64 - bool "Intel Stratix / Agilex / N5X clock controller support" if COMPILE_TEST && (!ARM64 || !ARCH_INTEL_SOCFPGA) + bool "Intel Stratix / Agilex / N5X / Agilex5 clock controller support" if COMPILE_TEST && (!ARM64 || !ARCH_INTEL_SOCFPGA) default ARM64 && ARCH_INTEL_SOCFPGA endif # CLK_INTEL_SOCFPGA diff --git a/drivers/clk/socfpga/Makefile b/drivers/clk/socfpga/Makefile index e8dfce339c915..a1ea2b988eaf4 100644 --- a/drivers/clk/socfpga/Makefile +++ b/drivers/clk/socfpga/Makefile @@ -3,4 +3,4 @@ obj-$(CONFIG_CLK_INTEL_SOCFPGA32) += clk.o clk-gate.o clk-pll.o clk-periph.o \ clk-pll-a10.o clk-periph-a10.o clk-gate-a10.o obj-$(CONFIG_CLK_INTEL_SOCFPGA64) += clk-s10.o \ clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o \ - clk-agilex.o + clk-agilex.o clk-agilex5.o diff --git a/drivers/clk/socfpga/clk-agilex5.c b/drivers/clk/socfpga/clk-agilex5.c new file mode 100644 index 0000000000000..f7f0ad884f645 --- /dev/null +++ b/drivers/clk/socfpga/clk-agilex5.c @@ -0,0 +1,561 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022-2024, Intel Corporation + * Copyright (C) 2025, Altera Corporation + */ +#include +#include +#include +#include +#include +#include "stratix10-clk.h" +#include "clk.h" + +/* External parent clocks come from DT via fw_name */ +static const char * const boot_pll_parents[] = { + "osc1", + "cb-intosc-hs-div2-clk", +}; + +static const char * const main_pll_parents[] = { + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const periph_pll_parents[] = { + "osc1", + "cb-intosc-hs-div2-clk", +}; + +/* Core free muxes */ +static const char * const core0_free_mux[] = { + "main_pll_c1", + "peri_pll_c0", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const core1_free_mux[] = { + "main_pll_c1", + "peri_pll_c0", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const core2_free_mux[] = { + "main_pll_c0", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const core3_free_mux[] = { + "main_pll_c0", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const dsu_free_mux[] = { + "main_pll_c2", + "peri_pll_c0", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const noc_free_mux[] = { + "main_pll_c3", + "peri_pll_c1", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const emac_ptp_free_mux[] = { + "main_pll_c3", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const emaca_free_mux[] = { + "main_pll_c2", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const emacb_free_mux[] = { + "main_pll_c3", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const gpio_db_free_mux[] = { + "main_pll_c3", + "peri_pll_c1", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const psi_ref_free_mux[] = { + "main_pll_c1", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const usb31_free_mux[] = { + "main_pll_c3", + "peri_pll_c2", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const s2f_user0_free_mux[] = { + "main_pll_c1", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const s2f_user1_free_mux[] = { + "main_pll_c1", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +/* Secondary muxes between free_clk and boot_clk */ +static const char * const core0_mux[] = { + "core0_free_clk", + "boot_clk", +}; + +static const char * const core1_mux[] = { + "core1_free_clk", + "boot_clk", +}; + +static const char * const core2_mux[] = { + "core2_free_clk", + "boot_clk", +}; + +static const char * const core3_mux[] = { + "core3_free_clk", + "boot_clk", +}; + +static const char * const dsu_mux[] = { + "dsu_free_clk", + "boot_clk", +}; + +static const char * const noc_mux[] = { + "noc_free_clk", + "boot_clk", +}; + +static const char * const emac_mux[] = { + "emaca_free_clk", + "emacb_free_clk", + "boot_clk", +}; + +static const char * const s2f_user0_mux[] = { + "s2f_user0_free_clk", + "boot_clk", +}; + +static const char * const s2f_user1_mux[] = { + "s2f_user1_free_clk", + "boot_clk", +}; + +static const char * const psi_mux[] = { + "psi_ref_free_clk", + "boot_clk", +}; + +static const char * const gpio_db_mux[] = { + "gpio_db_free_clk", + "boot_clk", +}; + +static const char * const emac_ptp_mux[] = { + "emac_ptp_free_clk", + "boot_clk", +}; + +static const char * const usb31_mux[] = { + "usb31_free_clk", + "boot_clk", +}; + +static const struct agilex5_pll_clock agilex5_pll_clks[] = { + { + .id = AGILEX5_BOOT_CLK, + .name = "boot_clk", + .parent_names = boot_pll_parents, + .num_parents = ARRAY_SIZE(boot_pll_parents), + .flags = 0, + .offset = 0x0, + }, + { + .id = AGILEX5_MAIN_PLL_CLK, + .name = "main_pll", + .parent_names = main_pll_parents, + .num_parents = ARRAY_SIZE(main_pll_parents), + .flags = 0, + .offset = 0x48, + }, + { + .id = AGILEX5_PERIPH_PLL_CLK, + .name = "periph_pll", + .parent_names = periph_pll_parents, + .num_parents = ARRAY_SIZE(periph_pll_parents), + .flags = 0, + .offset = 0x9C, + }, +}; + +/* Main PLL C0, C1, C2, C3 and Peri PLL C0, C1, C2, C3. With ping-pong counter. */ +static const struct stratix10_perip_c_clock agilex5_main_perip_c_clks[] = { + { AGILEX5_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, + 0x5C }, + { AGILEX5_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, + 0x60 }, + { AGILEX5_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, + 0x64 }, + { AGILEX5_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, + 0x68 }, + { AGILEX5_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, + 0xB0 }, + { AGILEX5_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, + 0xB4 }, + { AGILEX5_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, + 0xB8 }, + { AGILEX5_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, + 0xBC }, +}; + +/* Non-SW clock-gated enabled clocks */ +static const struct agilex5_perip_cnt_clock agilex5_main_perip_cnt_clks[] = { + { AGILEX5_CORE0_FREE_CLK, "core0_free_clk", core0_free_mux, + ARRAY_SIZE(core0_free_mux), 0, 0x0100, 0, 0, 0}, + { AGILEX5_CORE1_FREE_CLK, "core1_free_clk", core1_free_mux, + ARRAY_SIZE(core1_free_mux), 0, 0x0104, 0, 0, 0}, + { AGILEX5_CORE2_FREE_CLK, "core2_free_clk", core2_free_mux, + ARRAY_SIZE(core2_free_mux), 0, 0x010C, 0, 0, 0}, + { AGILEX5_CORE3_FREE_CLK, "core3_free_clk", core3_free_mux, + ARRAY_SIZE(core3_free_mux), 0, 0x0110, 0, 0, 0}, + { AGILEX5_DSU_FREE_CLK, "dsu_free_clk", dsu_free_mux, + ARRAY_SIZE(dsu_free_mux), 0, 0xfc, 0, 0, 0}, + { AGILEX5_NOC_FREE_CLK, "noc_free_clk", noc_free_mux, + ARRAY_SIZE(noc_free_mux), 0, 0x40, 0, 0, 0 }, + { AGILEX5_EMAC_A_FREE_CLK, "emaca_free_clk", emaca_free_mux, + ARRAY_SIZE(emaca_free_mux), 0, 0xD4, 0, 0x88, 0 }, + { AGILEX5_EMAC_B_FREE_CLK, "emacb_free_clk", emacb_free_mux, + ARRAY_SIZE(emacb_free_mux), 0, 0xD8, 0, 0x88, 1 }, + { AGILEX5_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", emac_ptp_free_mux, + ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88, 2 }, + { AGILEX5_GPIO_DB_FREE_CLK, "gpio_db_free_clk", gpio_db_free_mux, + ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3 }, + { AGILEX5_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", s2f_user0_free_mux, + ARRAY_SIZE(s2f_user0_free_mux), 0, 0xE8, 0, 0x30, 2 }, + { AGILEX5_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", s2f_user1_free_mux, + ARRAY_SIZE(s2f_user1_free_mux), 0, 0xEC, 0, 0x88, 5 }, + { AGILEX5_PSI_REF_FREE_CLK, "psi_ref_free_clk", psi_ref_free_mux, + ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6 }, + { AGILEX5_USB31_FREE_CLK, "usb31_free_clk", usb31_free_mux, + ARRAY_SIZE(usb31_free_mux), 0, 0xF8, 0, 0x88, 7}, +}; + +static const char * const cs_pdbg_parents[] = { "cs_at_clk" }; +static const char * const usb31_bus_clk_early_parents[] = { "l4_main_clk" }; +static const char * const l4_mp_clk_parent[] = { "l4_mp_clk" }; +static const char * const l4_sp_clk_parent[] = { "l4_sp_clk" }; +static const char * const dfi_clk_parent[] = { "dfi_clk" }; + +/* SW Clock gate enabled clocks */ +static const struct agilex5_gate_clock agilex5_gate_clks[] = { + { AGILEX5_CORE0_CLK, "core0_clk", core0_mux, + ARRAY_SIZE(core0_mux), 0, 0x24, 8, 0, 0, 0, 0x30, 5, 0 }, + { AGILEX5_CORE1_CLK, "core1_clk", core1_mux, + ARRAY_SIZE(core1_mux), 0, 0x24, 9, 0, 0, 0, 0x30, 5, 0 }, + { AGILEX5_CORE2_CLK, "core2_clk", core2_mux, + ARRAY_SIZE(core2_mux), 0, 0x24, 10, 0, 0, 0, 0x30, 6, 0 }, + { AGILEX5_CORE3_CLK, "core3_clk", core3_mux, + ARRAY_SIZE(core3_mux), 0, 0x24, 11, 0, 0, 0, 0x30, 7, 0 }, + { AGILEX5_MPU_CLK, "dsu_clk", dsu_mux, ARRAY_SIZE(dsu_mux), 0, 0, 0, + 0, 0, 0, 0x34, 4, 0 }, + { AGILEX5_MPU_PERIPH_CLK, "mpu_periph_clk", dsu_mux, + ARRAY_SIZE(dsu_mux), 0, 0, 0, 0x44, 20, 2, 0x34, 4, 0 }, + { AGILEX5_MPU_CCU_CLK, "mpu_ccu_clk", dsu_mux, + ARRAY_SIZE(dsu_mux), 0, 0, 0, 0x44, 18, 2, 0x34, 4, 0 }, + { AGILEX5_L4_MAIN_CLK, "l4_main_clk", noc_mux, ARRAY_SIZE(noc_mux), + CLK_IS_CRITICAL, 0x24, 1, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_L4_MP_CLK, "l4_mp_clk", noc_mux, ARRAY_SIZE(noc_mux), 0, + 0x24, 2, 0x44, 4, 2, 0x30, 1, 0 }, + { AGILEX5_L4_SYS_FREE_CLK, "l4_sys_free_clk", noc_mux, + ARRAY_SIZE(noc_mux), 0, 0, 0, 0x44, 2, 2, 0x30, 1, 0 }, + { AGILEX5_L4_SP_CLK, "l4_sp_clk", noc_mux, ARRAY_SIZE(noc_mux), + CLK_IS_CRITICAL, 0x24, 3, 0x44, 6, 2, 0x30, 1, 0 }, + + /* Core sight clocks*/ + { AGILEX5_CS_AT_CLK, "cs_at_clk", noc_mux, ARRAY_SIZE(noc_mux), 0, + 0x24, 4, 0x44, 24, 2, 0x30, 1, 0 }, + { AGILEX5_CS_TRACE_CLK, "cs_trace_clk", noc_mux, + ARRAY_SIZE(noc_mux), 0, 0x24, 4, 0x44, 26, 2, 0x30, 1, 0 }, + { AGILEX5_CS_PDBG_CLK, "cs_pdbg_clk", cs_pdbg_parents, 1, 0, 0x24, 4, + 0x44, 28, 1, 0, 0, 0 }, + + /* Main Peripheral PLL1 Begin */ + { AGILEX5_EMAC0_CLK, "emac0_clk", emac_mux, ARRAY_SIZE(emac_mux), + 0, 0x7C, 0, 0, 0, 0, 0x94, 26, 0 }, + { AGILEX5_EMAC1_CLK, "emac1_clk", emac_mux, ARRAY_SIZE(emac_mux), + 0, 0x7C, 1, 0, 0, 0, 0x94, 27, 0 }, + { AGILEX5_EMAC2_CLK, "emac2_clk", emac_mux, ARRAY_SIZE(emac_mux), + 0, 0x7C, 2, 0, 0, 0, 0x94, 28, 0 }, + { AGILEX5_EMAC_PTP_CLK, "emac_ptp_clk", emac_ptp_mux, + ARRAY_SIZE(emac_ptp_mux), 0, 0x7C, 3, 0, 0, 0, 0x88, 2, 0 }, + { AGILEX5_GPIO_DB_CLK, "gpio_db_clk", gpio_db_mux, + ARRAY_SIZE(gpio_db_mux), 0, 0x7C, 4, 0x98, 0, 16, 0x88, 3, 1 }, + /* Main Peripheral PLL1 End */ + + /* Peripheral clocks */ + { AGILEX5_S2F_USER0_CLK, "s2f_user0_clk", s2f_user0_mux, + ARRAY_SIZE(s2f_user0_mux), 0, 0x24, 6, 0, 0, 0, 0x30, 2, 0 }, + { AGILEX5_S2F_USER1_CLK, "s2f_user1_clk", s2f_user1_mux, + ARRAY_SIZE(s2f_user1_mux), 0, 0x7C, 6, 0, 0, 0, 0x88, 5, 0 }, + { AGILEX5_PSI_REF_CLK, "psi_ref_clk", psi_mux, + ARRAY_SIZE(psi_mux), 0, 0x7C, 7, 0, 0, 0, 0x88, 6, 0 }, + { AGILEX5_USB31_SUSPEND_CLK, "usb31_suspend_clk", usb31_mux, + ARRAY_SIZE(usb31_mux), 0, 0x7C, 25, 0, 0, 0, 0x88, 7, 0 }, + { AGILEX5_USB31_BUS_CLK_EARLY, "usb31_bus_clk_early", usb31_bus_clk_early_parents, + 1, 0, 0x7C, 25, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_USB2OTG_HCLK, "usb2otg_hclk", l4_mp_clk_parent, 1, 0, 0x7C, + 8, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPIM_0_CLK, "spim_0_clk", l4_mp_clk_parent, 1, 0, 0x7C, 9, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPIM_1_CLK, "spim_1_clk", l4_mp_clk_parent, 1, 0, 0x7C, 11, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPIS_0_CLK, "spis_0_clk", l4_sp_clk_parent, 1, 0, 0x7C, 12, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPIS_1_CLK, "spis_1_clk", l4_sp_clk_parent, 1, 0, 0x7C, 13, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_DMA_CORE_CLK, "dma_core_clk", l4_mp_clk_parent, 1, 0, 0x7C, + 14, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_DMA_HS_CLK, "dma_hs_clk", l4_mp_clk_parent, 1, 0, 0x7C, 14, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I3C_0_CORE_CLK, "i3c_0_core_clk", l4_mp_clk_parent, 1, 0, + 0x7C, 18, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I3C_1_CORE_CLK, "i3c_1_core_clk", l4_mp_clk_parent, 1, 0, + 0x7C, 19, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I2C_0_PCLK, "i2c_0_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 15, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I2C_1_PCLK, "i2c_1_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 16, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I2C_EMAC0_PCLK, "i2c_emac0_pclk", l4_sp_clk_parent, 1, 0, + 0x7C, 17, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I2C_EMAC1_PCLK, "i2c_emac1_pclk", l4_sp_clk_parent, 1, 0, + 0x7C, 22, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I2C_EMAC2_PCLK, "i2c_emac2_pclk", l4_sp_clk_parent, 1, 0, + 0x7C, 27, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_UART_0_PCLK, "uart_0_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 20, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_UART_1_PCLK, "uart_1_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 21, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPTIMER_0_PCLK, "sptimer_0_pclk", l4_sp_clk_parent, 1, 0, + 0x7C, 23, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPTIMER_1_PCLK, "sptimer_1_pclk", l4_sp_clk_parent, 1, 0, + 0x7C, 24, 0, 0, 0, 0, 0, 0 }, + + /*NAND, SD/MMC and SoftPHY overall clocking*/ + { AGILEX5_DFI_CLK, "dfi_clk", l4_mp_clk_parent, 1, 0, 0, 0, 0x44, 16, + 2, 0, 0, 0 }, + { AGILEX5_NAND_NF_CLK, "nand_nf_clk", dfi_clk_parent, 1, 0, 0x7C, 10, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_NAND_BCH_CLK, "nand_bch_clk", l4_mp_clk_parent, 1, 0, 0x7C, + 10, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SDMMC_SDPHY_REG_CLK, "sdmmc_sdphy_reg_clk", l4_mp_clk_parent, + 1, 0, 0x7C, 5, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SDMCLK, "sdmclk", dfi_clk_parent, 1, 0, 0x7C, 5, 0, 0, 0, + 0, 0, 0 }, + { AGILEX5_SOFTPHY_REG_PCLK, "softphy_reg_pclk", l4_mp_clk_parent, 1, 0, + 0x7C, 26, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SOFTPHY_PHY_CLK, "softphy_phy_clk", l4_mp_clk_parent, 1, 0, + 0x7C, 26, 0x44, 16, 2, 0, 0, 0 }, + { AGILEX5_SOFTPHY_CTRL_CLK, "softphy_ctrl_clk", dfi_clk_parent, 1, 0, + 0x7C, 26, 0, 0, 0, 0, 0, 0 }, +}; + +static int +agilex5_clk_register_c_perip(const struct stratix10_perip_c_clock *clks, + int nums, struct stratix10_clock_data *data) +{ + struct clk_hw *hw_clk; + void __iomem *base = data->base; + int i; + + for (i = 0; i < nums; i++) { + hw_clk = s10_register_periph(&clks[i], base); + if (IS_ERR(hw_clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + clks[i].name); + continue; + } + data->clk_data.hws[clks[i].id] = hw_clk; + } + return 0; +} + +static int +agilex5_clk_register_cnt_perip(const struct agilex5_perip_cnt_clock *clks, + int nums, struct stratix10_clock_data *data) +{ + struct clk_hw *hw_clk; + void __iomem *base = data->base; + int i; + + for (i = 0; i < nums; i++) { + hw_clk = agilex5_register_cnt_periph(&clks[i], base); + if (IS_ERR(hw_clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + clks[i].name); + continue; + } + data->clk_data.hws[clks[i].id] = hw_clk; + } + + return 0; +} + +static int agilex5_clk_register_gate(const struct agilex5_gate_clock *clks, + int nums, + struct stratix10_clock_data *data) +{ + struct clk_hw *hw_clk; + void __iomem *base = data->base; + int i; + + for (i = 0; i < nums; i++) { + hw_clk = agilex5_register_gate(&clks[i], base); + if (IS_ERR(hw_clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + clks[i].name); + continue; + } + data->clk_data.hws[clks[i].id] = hw_clk; + } + + return 0; +} + +static int agilex5_clk_register_pll(const struct agilex5_pll_clock *clks, + int nums, struct stratix10_clock_data *data) +{ + struct clk_hw *hw_clk; + void __iomem *base = data->base; + int i; + + for (i = 0; i < nums; i++) { + hw_clk = agilex5_register_pll(&clks[i], base); + if (IS_ERR(hw_clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + clks[i].name); + continue; + } + data->clk_data.hws[clks[i].id] = hw_clk; + } + + return 0; +} + +static int agilex5_clkmgr_init(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct stratix10_clock_data *clk_data; + void __iomem *base; + int i, num_clks; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + num_clks = AGILEX5_NUM_CLKS; + + clk_data = devm_kzalloc(dev, struct_size(clk_data, clk_data.hws, + num_clks), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->base = base; + clk_data->clk_data.num = num_clks; + + for (i = 0; i < num_clks; i++) + clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT); + + agilex5_clk_register_pll(agilex5_pll_clks, ARRAY_SIZE(agilex5_pll_clks), + clk_data); + + /* mainPLL C0, C1, C2, C3 and periph PLL C0, C1, C2, C3*/ + agilex5_clk_register_c_perip(agilex5_main_perip_c_clks, + ARRAY_SIZE(agilex5_main_perip_c_clks), + clk_data); + + agilex5_clk_register_cnt_perip(agilex5_main_perip_cnt_clks, + ARRAY_SIZE(agilex5_main_perip_cnt_clks), + clk_data); + + agilex5_clk_register_gate(agilex5_gate_clks, + ARRAY_SIZE(agilex5_gate_clks), clk_data); + + of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data); + return 0; +} + +static int agilex5_clkmgr_probe(struct platform_device *pdev) +{ + int (*probe_func)(struct platform_device *init_func); + + probe_func = of_device_get_match_data(&pdev->dev); + if (!probe_func) + return -ENODEV; + return probe_func(pdev); +} + +static const struct of_device_id agilex5_clkmgr_match_table[] = { + { .compatible = "intel,agilex5-clkmgr", .data = agilex5_clkmgr_init }, + {} +}; + +static struct platform_driver agilex5_clkmgr_driver = { + .probe = agilex5_clkmgr_probe, + .driver = { + .name = "agilex5-clkmgr", + .suppress_bind_attrs = true, + .of_match_table = agilex5_clkmgr_match_table, + }, +}; + +static int __init agilex5_clk_init(void) +{ + return platform_driver_register(&agilex5_clkmgr_driver); +} +core_initcall(agilex5_clk_init); diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c index 3930d922efb4d..dce3ef137bf37 100644 --- a/drivers/clk/socfpga/clk-gate-s10.c +++ b/drivers/clk/socfpga/clk-gate-s10.c @@ -239,3 +239,56 @@ struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, voi } return hw_clk; } + +struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks, void __iomem *regbase) +{ + struct clk_hw *hw_clk; + struct socfpga_gate_clk *socfpga_clk; + struct clk_init_data init; + int ret; + + socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); + if (!socfpga_clk) + return NULL; + + socfpga_clk->hw.reg = regbase + clks->gate_reg; + socfpga_clk->hw.bit_idx = clks->gate_idx; + + gateclk_ops.enable = clk_gate_ops.enable; + gateclk_ops.disable = clk_gate_ops.disable; + + socfpga_clk->fixed_div = clks->fixed_div; + + if (clks->div_reg) + socfpga_clk->div_reg = regbase + clks->div_reg; + else + socfpga_clk->div_reg = NULL; + + socfpga_clk->width = clks->div_width; + socfpga_clk->shift = clks->div_offset; + + if (clks->bypass_reg) + socfpga_clk->bypass_reg = regbase + clks->bypass_reg; + else + socfpga_clk->bypass_reg = NULL; + socfpga_clk->bypass_shift = clks->bypass_shift; + + if (streq(clks->name, "cs_pdbg_clk")) + init.ops = &dbgclk_ops; + else + init.ops = &agilex_gateclk_ops; + + init.name = clks->name; + init.flags = clks->flags; + init.num_parents = clks->num_parents; + init.parent_names = clks->parent_names; + socfpga_clk->hw.hw.init = &init; + hw_clk = &socfpga_clk->hw.hw; + + ret = clk_hw_register(NULL, &socfpga_clk->hw.hw); + if (ret) { + kfree(socfpga_clk); + return ERR_PTR(ret); + } + return hw_clk; +} diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c index f5c1ca42b6686..f12ca43ffe7c8 100644 --- a/drivers/clk/socfpga/clk-periph-s10.c +++ b/drivers/clk/socfpga/clk-periph-s10.c @@ -214,3 +214,44 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c } return hw_clk; } + +struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock *clks, + void __iomem *regbase) +{ + struct clk_hw *hw_clk; + struct socfpga_periph_clk *periph_clk; + struct clk_init_data init; + const char *name = clks->name; + int ret; + + periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); + if (WARN_ON(!periph_clk)) + return NULL; + + if (clks->offset) + periph_clk->hw.reg = regbase + clks->offset; + else + periph_clk->hw.reg = NULL; + + if (clks->bypass_reg) + periph_clk->bypass_reg = regbase + clks->bypass_reg; + else + periph_clk->bypass_reg = NULL; + periph_clk->bypass_shift = clks->bypass_shift; + periph_clk->fixed_div = clks->fixed_divider; + + init.name = name; + init.ops = &peri_cnt_clk_ops; + init.flags = clks->flags; + init.num_parents = clks->num_parents; + init.parent_names = clks->parent_names; + periph_clk->hw.hw.init = &init; + hw_clk = &periph_clk->hw.hw; + + ret = clk_hw_register(NULL, hw_clk); + if (ret) { + kfree(periph_clk); + return ERR_PTR(ret); + } + return hw_clk; +} diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c index a88c212bda129..1be92827cd938 100644 --- a/drivers/clk/socfpga/clk-pll-s10.c +++ b/drivers/clk/socfpga/clk-pll-s10.c @@ -304,3 +304,39 @@ struct clk_hw *n5x_register_pll(const struct stratix10_pll_clock *clks, } return hw_clk; } + +struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks, + void __iomem *reg) +{ + struct clk_hw *hw_clk; + struct socfpga_pll *pll_clk; + struct clk_init_data init; + const char *name = clks->name; + int ret; + + pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + if (WARN_ON(!pll_clk)) + return NULL; + + pll_clk->hw.reg = reg + clks->offset; + + if (streq(name, SOCFPGA_BOOT_CLK)) + init.ops = &clk_boot_ops; + else + init.ops = &agilex_clk_pll_ops; + + init.name = name; + init.flags = clks->flags; + init.num_parents = clks->num_parents; + init.parent_names = clks->parent_names; + pll_clk->hw.hw.init = &init; + pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER; + hw_clk = &pll_clk->hw.hw; + + ret = clk_hw_register(NULL, hw_clk); + if (ret) { + kfree(pll_clk); + return ERR_PTR(ret); + } + return hw_clk; +} diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h index 83fe4eb3133cb..d1fe4578b3e08 100644 --- a/drivers/clk/socfpga/stratix10-clk.h +++ b/drivers/clk/socfpga/stratix10-clk.h @@ -73,12 +73,55 @@ struct stratix10_gate_clock { u8 fixed_div; }; +struct agilex5_pll_clock { + unsigned int id; + const char *name; + const char * const *parent_names; + u8 num_parents; + unsigned long flags; + unsigned long offset; +}; + +struct agilex5_perip_cnt_clock { + unsigned int id; + const char *name; + const char * const *parent_names; + u8 num_parents; + unsigned long flags; + unsigned long offset; + u8 fixed_divider; + unsigned long bypass_reg; + unsigned long bypass_shift; +}; + +struct agilex5_gate_clock { + unsigned int id; + const char *name; + const char * const *parent_names; + u8 num_parents; + unsigned long flags; + unsigned long gate_reg; + u8 gate_idx; + unsigned long div_reg; + u8 div_offset; + u8 div_width; + unsigned long bypass_reg; + u8 bypass_shift; + u8 fixed_div; +}; + struct clk_hw *s10_register_pll(const struct stratix10_pll_clock *clks, void __iomem *reg); struct clk_hw *agilex_register_pll(const struct stratix10_pll_clock *clks, void __iomem *reg); struct clk_hw *n5x_register_pll(const struct stratix10_pll_clock *clks, void __iomem *reg); +struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks, + void __iomem *reg); +struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock *clks, + void __iomem *regbase); +struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks, + void __iomem *regbase); struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks, void __iomem *reg); struct clk_hw *n5x_register_periph(const struct n5x_perip_c_clock *clks, diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c index f5a9fe6ba1859..4761bc1e3b6e6 100644 --- a/drivers/clk/spacemit/ccu-k1.c +++ b/drivers/clk/spacemit/ccu-k1.c @@ -1018,6 +1018,8 @@ static int spacemit_ccu_register(struct device *dev, if (!clk_data) return -ENOMEM; + clk_data->num = data->num; + for (i = 0; i < data->num; i++) { struct clk_hw *hw = data->hws[i]; struct ccu_common *common; @@ -1044,8 +1046,6 @@ static int spacemit_ccu_register(struct device *dev, clk_data->hws[i] = hw; } - clk_data->num = data->num; - ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); if (ret) dev_err(dev, "failed to add clock hardware provider (%d)\n", ret); diff --git a/drivers/clk/spacemit/ccu_mix.h b/drivers/clk/spacemit/ccu_mix.h index 54d40cd39b275..c406508e3504e 100644 --- a/drivers/clk/spacemit/ccu_mix.h +++ b/drivers/clk/spacemit/ccu_mix.h @@ -220,4 +220,4 @@ extern const struct clk_ops spacemit_ccu_div_gate_ops; extern const struct clk_ops spacemit_ccu_mux_gate_ops; extern const struct clk_ops spacemit_ccu_mux_div_ops; extern const struct clk_ops spacemit_ccu_mux_div_gate_ops; -#endif /* _CCU_DIV_H_ */ +#endif /* _CCU_MIX_H_ */ diff --git a/drivers/clk/sprd/sc9860-clk.c b/drivers/clk/sprd/sc9860-clk.c index cc5ed2dd82670..d7fe924fbe971 100644 --- a/drivers/clk/sprd/sc9860-clk.c +++ b/drivers/clk/sprd/sc9860-clk.c @@ -2021,17 +2021,13 @@ MODULE_DEVICE_TABLE(of, sprd_sc9860_clk_ids); static int sc9860_clk_probe(struct platform_device *pdev) { - const struct of_device_id *match; const struct sprd_clk_desc *desc; int ret; - match = of_match_node(sprd_sc9860_clk_ids, pdev->dev.of_node); - if (!match) { - pr_err("%s: of_match_node() failed", __func__); + desc = device_get_match_data(&pdev->dev); + if (!desc) return -ENODEV; - } - desc = match->data; ret = sprd_clk_regmap_init(pdev, desc); if (ret) return ret; diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 412902f573b54..504d0ea997a51 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -3444,7 +3444,7 @@ static void tegra210_disable_cpu_clock(u32 cpu) static u32 spare_reg_ctx, misc_clk_enb_ctx, clk_msk_arm_ctx; static u32 cpu_softrst_ctx[3]; -static int tegra210_clk_suspend(void) +static int tegra210_clk_suspend(void *data) { unsigned int i; @@ -3465,7 +3465,7 @@ static int tegra210_clk_suspend(void) return 0; } -static void tegra210_clk_resume(void) +static void tegra210_clk_resume(void *data) { unsigned int i; @@ -3523,13 +3523,17 @@ static void tegra210_cpu_clock_resume(void) } #endif -static struct syscore_ops tegra_clk_syscore_ops = { +static const struct syscore_ops tegra_clk_syscore_ops = { #ifdef CONFIG_PM_SLEEP .suspend = tegra210_clk_suspend, .resume = tegra210_clk_resume, #endif }; +static struct syscore tegra_clk_syscore = { + .ops = &tegra_clk_syscore_ops, +}; + static struct tegra_cpu_car_ops tegra210_cpu_car_ops = { .wait_for_reset = tegra210_wait_cpu_in_reset, .disable_clock = tegra210_disable_cpu_clock, @@ -3813,6 +3817,6 @@ static void __init tegra210_clock_init(struct device_node *np) tegra_cpu_car_ops = &tegra210_cpu_car_ops; - register_syscore_ops(&tegra_clk_syscore_ops); + register_syscore(&tegra_clk_syscore); } CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); diff --git a/drivers/clk/visconti/clkc-tmpv770x.c b/drivers/clk/visconti/clkc-tmpv770x.c index 6c753b2cb558f..1e2e8d6437fe7 100644 --- a/drivers/clk/visconti/clkc-tmpv770x.c +++ b/drivers/clk/visconti/clkc-tmpv770x.c @@ -17,6 +17,10 @@ #include "clkc.h" #include "reset.h" +/* Must be equal to the last clock/reset ID increased by one */ +#define CLKS_NR (TMPV770X_CLK_VIIFBS1_PROC + 1) +#define RESETS_NR (TMPV770X_RESET_VIIFBS1_L1ISP + 1) + static DEFINE_SPINLOCK(tmpv770x_clk_lock); static DEFINE_SPINLOCK(tmpv770x_rst_lock); @@ -28,6 +32,10 @@ static const struct clk_parent_data pietherplls_parent_data[] = { { .fw_name = "pietherpll", .name = "pietherpll", }, }; +static const struct clk_parent_data pidnnplls_parent_data[] = { + { .fw_name = "pidnnpll", .name = "pidnnpll", }, +}; + static const struct visconti_fixed_clk fixed_clk_tables[] = { /* PLL1 */ /* PICMPT0/1, PITSC, PIUWDT, PISWDT, PISBUS, PIPMU, PIGPMU, PITMU */ @@ -64,6 +72,41 @@ static const struct visconti_clk_gate_table pietherpll_clk_gate_tables[] = { TMPV770X_RESET_PIETHER_125M, }, }; +static const struct visconti_clk_gate_table pidnnpll_clk_gate_tables[] = { + { TMPV770X_CLK_VIIFBS0, "viifbs0", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 1, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS0_PROC, "viifbs0_proc", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 18, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS0_L1ISP, "viifbs0_l1isp", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 17, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS0_L2ISP, "viifbs0_l2isp", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 16, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS1, "viifbs1", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 5, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS1_PROC, "viifbs1_proc", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 22, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS1_L1ISP, "viifbs1_l1isp", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 21, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS1_L2ISP, "viifbs1_l2isp", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 20, 1, + NO_RESET, }, +}; + static const struct visconti_clk_gate_table clk_gate_tables[] = { { TMPV770X_CLK_HOX, "hox", clks_parent_data, ARRAY_SIZE(clks_parent_data), @@ -185,6 +228,22 @@ static const struct visconti_clk_gate_table clk_gate_tables[] = { clks_parent_data, ARRAY_SIZE(clks_parent_data), 0, 0x14, 0x114, 0, 4, TMPV770X_RESET_SBUSCLK, }, + { TMPV770X_CLK_VIIF0_CFGCLK, "csi2rx0cfg", + clks_parent_data, ARRAY_SIZE(clks_parent_data), + 0, 0x58, 0x158, 0, 24, + NO_RESET, }, + { TMPV770X_CLK_VIIF0_APBCLK, "csi2rx0apb", + clks_parent_data, ARRAY_SIZE(clks_parent_data), + 0, 0x58, 0x158, 2, 4, + NO_RESET, }, + { TMPV770X_CLK_VIIF1_CFGCLK, "csi2rx1cfg", + clks_parent_data, ARRAY_SIZE(clks_parent_data), + 0, 0x58, 0x158, 4, 24, + NO_RESET, }, + { TMPV770X_CLK_VIIF1_APBCLK, "csi2rx1apb", + clks_parent_data, ARRAY_SIZE(clks_parent_data), + 0, 0x58, 0x158, 6, 4, + NO_RESET, }, }; static const struct visconti_reset_data clk_reset_data[] = { @@ -220,6 +279,14 @@ static const struct visconti_reset_data clk_reset_data[] = { [TMPV770X_RESET_PIPCMIF] = { 0x464, 0x564, 0, }, [TMPV770X_RESET_PICKMON] = { 0x410, 0x510, 8, }, [TMPV770X_RESET_SBUSCLK] = { 0x414, 0x514, 0, }, + [TMPV770X_RESET_VIIFBS0] = { 0x458, 0x558, 0, }, + [TMPV770X_RESET_VIIFBS0_APB] = { 0x458, 0x558, 1, }, + [TMPV770X_RESET_VIIFBS0_L2ISP] = { 0x458, 0x558, 16, }, + [TMPV770X_RESET_VIIFBS0_L1ISP] = { 0x458, 0x558, 17, }, + [TMPV770X_RESET_VIIFBS1] = { 0x458, 0x558, 4, }, + [TMPV770X_RESET_VIIFBS1_APB] = { 0x458, 0x558, 5, }, + [TMPV770X_RESET_VIIFBS1_L2ISP] = { 0x458, 0x558, 20, }, + [TMPV770X_RESET_VIIFBS1_L1ISP] = { 0x458, 0x558, 21, }, }; static int visconti_clk_probe(struct platform_device *pdev) @@ -234,12 +301,12 @@ static int visconti_clk_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); - ctx = visconti_init_clk(dev, regmap, TMPV770X_NR_CLK); + ctx = visconti_init_clk(dev, regmap, CLKS_NR); if (IS_ERR(ctx)) return PTR_ERR(ctx); ret = visconti_register_reset_controller(dev, regmap, clk_reset_data, - TMPV770X_NR_RESET, + RESETS_NR, &visconti_reset_ops, &tmpv770x_rst_lock); if (ret) { @@ -272,6 +339,14 @@ static int visconti_clk_probe(struct platform_device *pdev) return ret; } + ret = visconti_clk_register_gates(ctx, pidnnpll_clk_gate_tables, + ARRAY_SIZE(pidnnpll_clk_gate_tables), + clk_reset_data, &tmpv770x_clk_lock); + if (ret) { + dev_err(dev, "Failed to register pidnnpll clock gate: %d\n", ret); + return ret; + } + return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &ctx->clk_data); } diff --git a/drivers/clk/visconti/pll-tmpv770x.c b/drivers/clk/visconti/pll-tmpv770x.c index 8360ccf888672..a2208c5fc12e0 100644 --- a/drivers/clk/visconti/pll-tmpv770x.c +++ b/drivers/clk/visconti/pll-tmpv770x.c @@ -16,6 +16,9 @@ #include "pll.h" +/* Must be equal to the last pll ID increased by one */ +#define PLLS_NR (TMPV770X_PLL_PIIMGERPLL + 1) + static DEFINE_SPINLOCK(tmpv770x_pll_lock); static const struct visconti_pll_rate_table pipll0_rates[] __initconst = { @@ -66,7 +69,7 @@ static void __init tmpv770x_setup_plls(struct device_node *np) if (!reg_base) return; - ctx = visconti_init_pll(np, reg_base, TMPV770X_NR_PLL); + ctx = visconti_init_pll(np, reg_base, PLLS_NR); if (IS_ERR(ctx)) { iounmap(reg_base); return; diff --git a/drivers/clocksource/timer-armada-370-xp.c b/drivers/clocksource/timer-armada-370-xp.c index 54284c1c06514..f2b4cc40db93a 100644 --- a/drivers/clocksource/timer-armada-370-xp.c +++ b/drivers/clocksource/timer-armada-370-xp.c @@ -207,14 +207,14 @@ static int armada_370_xp_timer_dying_cpu(unsigned int cpu) static u32 timer0_ctrl_reg, timer0_local_ctrl_reg; -static int armada_370_xp_timer_suspend(void) +static int armada_370_xp_timer_suspend(void *data) { timer0_ctrl_reg = readl(timer_base + TIMER_CTRL_OFF); timer0_local_ctrl_reg = readl(local_base + TIMER_CTRL_OFF); return 0; } -static void armada_370_xp_timer_resume(void) +static void armada_370_xp_timer_resume(void *data) { writel(0xffffffff, timer_base + TIMER0_VAL_OFF); writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); @@ -222,11 +222,15 @@ static void armada_370_xp_timer_resume(void) writel(timer0_local_ctrl_reg, local_base + TIMER_CTRL_OFF); } -static struct syscore_ops armada_370_xp_timer_syscore_ops = { +static const struct syscore_ops armada_370_xp_timer_syscore_ops = { .suspend = armada_370_xp_timer_suspend, .resume = armada_370_xp_timer_resume, }; +static struct syscore armada_370_xp_timer_syscore = { + .ops = &armada_370_xp_timer_syscore_ops, +}; + static unsigned long armada_370_delay_timer_read(void) { return ~readl(timer_base + TIMER0_VAL_OFF); @@ -324,7 +328,7 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np) return res; } - register_syscore_ops(&armada_370_xp_timer_syscore_ops); + register_syscore(&armada_370_xp_timer_syscore); return 0; } diff --git a/drivers/comedi/comedi_buf.c b/drivers/comedi/comedi_buf.c index c7c262a2d8cad..785977b40a934 100644 --- a/drivers/comedi/comedi_buf.c +++ b/drivers/comedi/comedi_buf.c @@ -273,19 +273,8 @@ unsigned int comedi_buf_write_n_available(struct comedi_subdevice *s) return free_end - async->buf_write_count; } -/** - * comedi_buf_write_alloc() - Reserve buffer space for writing - * @s: COMEDI subdevice. - * @nbytes: Maximum space to reserve in bytes. - * - * Reserve up to @nbytes bytes of space to be written in the COMEDI acquisition - * data buffer associated with the subdevice. The amount reserved is limited - * by the space available. - * - * Return: The amount of space reserved in bytes. - */ -unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, - unsigned int nbytes) +unsigned int _comedi_buf_write_alloc(struct comedi_subdevice *s, + unsigned int nbytes) { struct comedi_async *async = s->async; unsigned int unalloc = comedi_buf_write_n_unalloc(s); @@ -303,6 +292,29 @@ unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, return nbytes; } + +/** + * comedi_buf_write_alloc() - Reserve buffer space for writing + * @s: COMEDI subdevice. + * @nbytes: Maximum space to reserve in bytes. + * + * Reserve up to @nbytes bytes of space to be written in the COMEDI acquisition + * data buffer associated with the subdevice. The amount reserved is limited + * by the space available. + * + * Return: The amount of space reserved in bytes. + */ +unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, + unsigned int nbytes) +{ + if (comedi_get_is_subdevice_running(s)) { + nbytes = _comedi_buf_write_alloc(s, nbytes); + comedi_put_is_subdevice_running(s); + } else { + nbytes = 0; + } + return nbytes; +} EXPORT_SYMBOL_GPL(comedi_buf_write_alloc); /* @@ -362,6 +374,24 @@ unsigned int comedi_buf_write_n_allocated(struct comedi_subdevice *s) return async->buf_write_alloc_count - async->buf_write_count; } +unsigned int _comedi_buf_write_free(struct comedi_subdevice *s, + unsigned int nbytes) +{ + struct comedi_async *async = s->async; + unsigned int allocated = comedi_buf_write_n_allocated(s); + + if (nbytes > allocated) + nbytes = allocated; + + async->buf_write_count += nbytes; + async->buf_write_ptr += nbytes; + comedi_buf_munge(s, async->buf_write_count - async->munge_count); + if (async->buf_write_ptr >= async->prealloc_bufsz) + async->buf_write_ptr %= async->prealloc_bufsz; + + return nbytes; +} + /** * comedi_buf_write_free() - Free buffer space after it is written * @s: COMEDI subdevice. @@ -379,22 +409,35 @@ unsigned int comedi_buf_write_n_allocated(struct comedi_subdevice *s) */ unsigned int comedi_buf_write_free(struct comedi_subdevice *s, unsigned int nbytes) +{ + if (comedi_get_is_subdevice_running(s)) { + nbytes = _comedi_buf_write_free(s, nbytes); + comedi_put_is_subdevice_running(s); + } else { + nbytes = 0; + } + return nbytes; +} +EXPORT_SYMBOL_GPL(comedi_buf_write_free); + +unsigned int _comedi_buf_read_n_available(struct comedi_subdevice *s) { struct comedi_async *async = s->async; - unsigned int allocated = comedi_buf_write_n_allocated(s); + unsigned int num_bytes; - if (nbytes > allocated) - nbytes = allocated; + if (!async) + return 0; - async->buf_write_count += nbytes; - async->buf_write_ptr += nbytes; - comedi_buf_munge(s, async->buf_write_count - async->munge_count); - if (async->buf_write_ptr >= async->prealloc_bufsz) - async->buf_write_ptr %= async->prealloc_bufsz; + num_bytes = async->munge_count - async->buf_read_count; - return nbytes; + /* + * ensure the async buffer 'counts' are read before we + * attempt to read data from the buffer + */ + smp_rmb(); + + return num_bytes; } -EXPORT_SYMBOL_GPL(comedi_buf_write_free); /** * comedi_buf_read_n_available() - Determine amount of readable buffer space @@ -409,23 +452,38 @@ EXPORT_SYMBOL_GPL(comedi_buf_write_free); */ unsigned int comedi_buf_read_n_available(struct comedi_subdevice *s) { - struct comedi_async *async = s->async; unsigned int num_bytes; - if (!async) - return 0; + if (comedi_get_is_subdevice_running(s)) { + num_bytes = _comedi_buf_read_n_available(s); + comedi_put_is_subdevice_running(s); + } else { + num_bytes = 0; + } + return num_bytes; +} +EXPORT_SYMBOL_GPL(comedi_buf_read_n_available); - num_bytes = async->munge_count - async->buf_read_count; +unsigned int _comedi_buf_read_alloc(struct comedi_subdevice *s, + unsigned int nbytes) +{ + struct comedi_async *async = s->async; + unsigned int available; + + available = async->munge_count - async->buf_read_alloc_count; + if (nbytes > available) + nbytes = available; + + async->buf_read_alloc_count += nbytes; /* * ensure the async buffer 'counts' are read before we - * attempt to read data from the buffer + * attempt to read data from the read-alloc'ed buffer space */ smp_rmb(); - return num_bytes; + return nbytes; } -EXPORT_SYMBOL_GPL(comedi_buf_read_n_available); /** * comedi_buf_read_alloc() - Reserve buffer space for reading @@ -445,21 +503,12 @@ EXPORT_SYMBOL_GPL(comedi_buf_read_n_available); unsigned int comedi_buf_read_alloc(struct comedi_subdevice *s, unsigned int nbytes) { - struct comedi_async *async = s->async; - unsigned int available; - - available = async->munge_count - async->buf_read_alloc_count; - if (nbytes > available) - nbytes = available; - - async->buf_read_alloc_count += nbytes; - - /* - * ensure the async buffer 'counts' are read before we - * attempt to read data from the read-alloc'ed buffer space - */ - smp_rmb(); - + if (comedi_get_is_subdevice_running(s)) { + nbytes = _comedi_buf_read_alloc(s, nbytes); + comedi_put_is_subdevice_running(s); + } else { + nbytes = 0; + } return nbytes; } EXPORT_SYMBOL_GPL(comedi_buf_read_alloc); @@ -469,21 +518,8 @@ static unsigned int comedi_buf_read_n_allocated(struct comedi_async *async) return async->buf_read_alloc_count - async->buf_read_count; } -/** - * comedi_buf_read_free() - Free buffer space after it has been read - * @s: COMEDI subdevice. - * @nbytes: Maximum space to free in bytes. - * - * Free up to @nbytes bytes of buffer space previously reserved for reading in - * the COMEDI acquisition data buffer associated with the subdevice. The - * amount of space freed is limited to the amount that was reserved. - * - * The freed space becomes available for allocation by the writer. - * - * Return: The amount of space freed in bytes. - */ -unsigned int comedi_buf_read_free(struct comedi_subdevice *s, - unsigned int nbytes) +unsigned int _comedi_buf_read_free(struct comedi_subdevice *s, + unsigned int nbytes) { struct comedi_async *async = s->async; unsigned int allocated; @@ -503,6 +539,31 @@ unsigned int comedi_buf_read_free(struct comedi_subdevice *s, async->buf_read_ptr %= async->prealloc_bufsz; return nbytes; } + +/** + * comedi_buf_read_free() - Free buffer space after it has been read + * @s: COMEDI subdevice. + * @nbytes: Maximum space to free in bytes. + * + * Free up to @nbytes bytes of buffer space previously reserved for reading in + * the COMEDI acquisition data buffer associated with the subdevice. The + * amount of space freed is limited to the amount that was reserved. + * + * The freed space becomes available for allocation by the writer. + * + * Return: The amount of space freed in bytes. + */ +unsigned int comedi_buf_read_free(struct comedi_subdevice *s, + unsigned int nbytes) +{ + if (comedi_get_is_subdevice_running(s)) { + nbytes = _comedi_buf_read_free(s, nbytes); + comedi_put_is_subdevice_running(s); + } else { + nbytes = 0; + } + return nbytes; +} EXPORT_SYMBOL_GPL(comedi_buf_read_free); static void comedi_buf_memcpy_to(struct comedi_subdevice *s, @@ -558,6 +619,38 @@ static void comedi_buf_memcpy_from(struct comedi_subdevice *s, } } +static unsigned int _comedi_buf_write_samples(struct comedi_subdevice *s, + const void *data, + unsigned int nsamples) +{ + unsigned int max_samples; + unsigned int nbytes; + + /* + * Make sure there is enough room in the buffer for all the samples. + * If not, clamp the nsamples to the number that will fit, flag the + * buffer overrun and add the samples that fit. + */ + max_samples = comedi_bytes_to_samples(s, comedi_buf_write_n_unalloc(s)); + if (nsamples > max_samples) { + dev_warn(s->device->class_dev, "buffer overrun\n"); + s->async->events |= COMEDI_CB_OVERFLOW; + nsamples = max_samples; + } + + if (nsamples == 0) + return 0; + + nbytes = comedi_samples_to_bytes(s, nsamples); + nbytes = _comedi_buf_write_alloc(s, nbytes); + comedi_buf_memcpy_to(s, data, nbytes); + _comedi_buf_write_free(s, nbytes); + _comedi_inc_scan_progress(s, nbytes); + s->async->events |= COMEDI_CB_BLOCK; + + return nbytes; +} + /** * comedi_buf_write_samples() - Write sample data to COMEDI buffer * @s: COMEDI subdevice. @@ -577,35 +670,43 @@ static void comedi_buf_memcpy_from(struct comedi_subdevice *s, */ unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, const void *data, unsigned int nsamples) +{ + unsigned int nbytes; + + if (comedi_get_is_subdevice_running(s)) { + nbytes = _comedi_buf_write_samples(s, data, nsamples); + comedi_put_is_subdevice_running(s); + } else { + nbytes = 0; + } + return nbytes; +} +EXPORT_SYMBOL_GPL(comedi_buf_write_samples); + +static unsigned int _comedi_buf_read_samples(struct comedi_subdevice *s, + void *data, unsigned int nsamples) { unsigned int max_samples; unsigned int nbytes; - /* - * Make sure there is enough room in the buffer for all the samples. - * If not, clamp the nsamples to the number that will fit, flag the - * buffer overrun and add the samples that fit. - */ - max_samples = comedi_bytes_to_samples(s, comedi_buf_write_n_unalloc(s)); - if (nsamples > max_samples) { - dev_warn(s->device->class_dev, "buffer overrun\n"); - s->async->events |= COMEDI_CB_OVERFLOW; + /* clamp nsamples to the number of full samples available */ + max_samples = comedi_bytes_to_samples(s, + _comedi_buf_read_n_available(s)); + if (nsamples > max_samples) nsamples = max_samples; - } if (nsamples == 0) return 0; - nbytes = comedi_buf_write_alloc(s, + nbytes = _comedi_buf_read_alloc(s, comedi_samples_to_bytes(s, nsamples)); - comedi_buf_memcpy_to(s, data, nbytes); - comedi_buf_write_free(s, nbytes); - comedi_inc_scan_progress(s, nbytes); + comedi_buf_memcpy_from(s, data, nbytes); + _comedi_buf_read_free(s, nbytes); + _comedi_inc_scan_progress(s, nbytes); s->async->events |= COMEDI_CB_BLOCK; return nbytes; } -EXPORT_SYMBOL_GPL(comedi_buf_write_samples); /** * comedi_buf_read_samples() - Read sample data from COMEDI buffer @@ -624,25 +725,14 @@ EXPORT_SYMBOL_GPL(comedi_buf_write_samples); unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, void *data, unsigned int nsamples) { - unsigned int max_samples; unsigned int nbytes; - /* clamp nsamples to the number of full samples available */ - max_samples = comedi_bytes_to_samples(s, - comedi_buf_read_n_available(s)); - if (nsamples > max_samples) - nsamples = max_samples; - - if (nsamples == 0) - return 0; - - nbytes = comedi_buf_read_alloc(s, - comedi_samples_to_bytes(s, nsamples)); - comedi_buf_memcpy_from(s, data, nbytes); - comedi_buf_read_free(s, nbytes); - comedi_inc_scan_progress(s, nbytes); - s->async->events |= COMEDI_CB_BLOCK; - + if (comedi_get_is_subdevice_running(s)) { + nbytes = _comedi_buf_read_samples(s, data, nsamples); + comedi_put_is_subdevice_running(s); + } else { + nbytes = 0; + } return nbytes; } EXPORT_SYMBOL_GPL(comedi_buf_read_samples); diff --git a/drivers/comedi/comedi_fops.c b/drivers/comedi/comedi_fops.c index 7e2f2b1a1c362..657c98cd723e0 100644 --- a/drivers/comedi/comedi_fops.c +++ b/drivers/comedi/comedi_fops.c @@ -38,6 +38,7 @@ * COMEDI_SRF_ERROR: indicates an COMEDI_CB_ERROR event has occurred * since the last command was started * COMEDI_SRF_RUNNING: command is running + * COMEDI_SRF_BUSY: command was started and subdevice still busy * COMEDI_SRF_FREE_SPRIV: free s->private on detach * * COMEDI_SRF_BUSY_MASK: runflags that indicate the subdevice is "busy" @@ -45,9 +46,11 @@ #define COMEDI_SRF_RT BIT(1) #define COMEDI_SRF_ERROR BIT(2) #define COMEDI_SRF_RUNNING BIT(27) +#define COMEDI_SRF_BUSY BIT(28) #define COMEDI_SRF_FREE_SPRIV BIT(31) -#define COMEDI_SRF_BUSY_MASK (COMEDI_SRF_ERROR | COMEDI_SRF_RUNNING) +#define COMEDI_SRF_BUSY_MASK \ + (COMEDI_SRF_ERROR | COMEDI_SRF_RUNNING | COMEDI_SRF_BUSY) /** * struct comedi_file - Per-file private data for COMEDI device @@ -665,6 +668,11 @@ static bool comedi_is_runflags_in_error(unsigned int runflags) return runflags & COMEDI_SRF_ERROR; } +static bool comedi_is_runflags_busy(unsigned int runflags) +{ + return runflags & COMEDI_SRF_BUSY; +} + /** * comedi_is_subdevice_running() - Check if async command running on subdevice * @s: COMEDI subdevice. @@ -687,6 +695,46 @@ static bool __comedi_is_subdevice_running(struct comedi_subdevice *s) return comedi_is_runflags_running(runflags); } +/** + * comedi_get_is_subdevice_running() - Get if async command running on subdevice + * @s: COMEDI subdevice. + * + * If an asynchronous COMEDI command is running on the subdevice, increment + * a reference counter. If the function return value indicates that a + * command is running, then the details of the command will not be destroyed + * before a matching call to comedi_put_is_subdevice_running(). + * + * Return: %true if an asynchronous COMEDI command is active on the + * subdevice, else %false. + */ +bool comedi_get_is_subdevice_running(struct comedi_subdevice *s) +{ + unsigned long flags; + bool running; + + spin_lock_irqsave(&s->spin_lock, flags); + running = __comedi_is_subdevice_running(s); + if (running) + refcount_inc(&s->async->run_active); + spin_unlock_irqrestore(&s->spin_lock, flags); + return running; +} +EXPORT_SYMBOL_GPL(comedi_get_is_subdevice_running); + +/** + * comedi_put_is_subdevice_running() - Put if async command running on subdevice + * @s: COMEDI subdevice. + * + * Decrements the reference counter that was incremented when + * comedi_get_is_subdevice_running() returned %true. + */ +void comedi_put_is_subdevice_running(struct comedi_subdevice *s) +{ + if (refcount_dec_and_test(&s->async->run_active)) + complete_all(&s->async->run_complete); +} +EXPORT_SYMBOL_GPL(comedi_put_is_subdevice_running); + bool comedi_can_auto_free_spriv(struct comedi_subdevice *s) { unsigned int runflags = __comedi_get_subdevice_runflags(s); @@ -736,20 +784,28 @@ static void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s) { struct comedi_async *async = s->async; + unsigned int runflags; + unsigned long flags; lockdep_assert_held(&dev->mutex); - comedi_update_subdevice_runflags(s, COMEDI_SRF_RUNNING, 0); - if (async) { + spin_lock_irqsave(&s->spin_lock, flags); + runflags = __comedi_get_subdevice_runflags(s); + __comedi_clear_subdevice_runflags(s, COMEDI_SRF_RUNNING | + COMEDI_SRF_BUSY); + spin_unlock_irqrestore(&s->spin_lock, flags); + if (comedi_is_runflags_busy(runflags)) { + /* + * "Run active" counter was set to 1 when setting up the + * command. Decrement it and wait for it to become 0. + */ + comedi_put_is_subdevice_running(s); + wait_for_completion(&async->run_complete); comedi_buf_reset(s); async->inttrig = NULL; kfree(async->cmd.chanlist); async->cmd.chanlist = NULL; s->busy = NULL; wake_up_interruptible_all(&async->wait_head); - } else { - dev_err(dev->class_dev, - "BUG: (?) %s called with async=NULL\n", __func__); - s->busy = NULL; } } @@ -1150,15 +1206,15 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, if (!(async->cmd.flags & CMDF_WRITE)) { /* command was set up in "read" direction */ if (bi.bytes_read) { - comedi_buf_read_alloc(s, bi.bytes_read); - bi.bytes_read = comedi_buf_read_free(s, bi.bytes_read); + _comedi_buf_read_alloc(s, bi.bytes_read); + bi.bytes_read = _comedi_buf_read_free(s, bi.bytes_read); } /* * If nothing left to read, and command has stopped, and * {"read" position not updated or command stopped normally}, * then become non-busy. */ - if (comedi_buf_read_n_available(s) == 0 && + if (_comedi_buf_read_n_available(s) == 0 && !comedi_is_runflags_running(runflags) && (bi.bytes_read == 0 || !comedi_is_runflags_in_error(runflags))) { @@ -1175,9 +1231,9 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, if (comedi_is_runflags_in_error(runflags)) retval = -EPIPE; } else if (bi.bytes_written) { - comedi_buf_write_alloc(s, bi.bytes_written); + _comedi_buf_write_alloc(s, bi.bytes_written); bi.bytes_written = - comedi_buf_write_free(s, bi.bytes_written); + _comedi_buf_write_free(s, bi.bytes_written); } bi.bytes_read = 0; } @@ -1860,8 +1916,14 @@ static int do_cmd_ioctl(struct comedi_device *dev, if (async->cmd.flags & CMDF_WAKE_EOS) async->cb_mask |= COMEDI_CB_EOS; + /* + * Set the "run active" counter with an initial count of 1 that will + * complete the "safe to reset" event when it is decremented to 0. + */ + refcount_set(&s->async->run_active, 1); + reinit_completion(&s->async->run_complete); comedi_update_subdevice_runflags(s, COMEDI_SRF_BUSY_MASK, - COMEDI_SRF_RUNNING); + COMEDI_SRF_RUNNING | COMEDI_SRF_BUSY); /* * Set s->busy _after_ setting COMEDI_SRF_RUNNING flag to avoid @@ -2284,15 +2346,10 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, rc = check_insnlist_len(dev, insnlist.n_insns); if (rc) break; - insns = kcalloc(insnlist.n_insns, sizeof(*insns), GFP_KERNEL); - if (!insns) { - rc = -ENOMEM; - break; - } - if (copy_from_user(insns, insnlist.insns, - sizeof(*insns) * insnlist.n_insns)) { - rc = -EFAULT; - kfree(insns); + insns = memdup_array_user(insnlist.insns, insnlist.n_insns, + sizeof(*insns)); + if (IS_ERR(insns)) { + rc = PTR_ERR(insns); break; } rc = do_insnlist_ioctl(dev, insns, insnlist.n_insns, file); @@ -2512,7 +2569,7 @@ static __poll_t comedi_poll(struct file *file, poll_table *wait) poll_wait(file, &s->async->wait_head, wait); if (s->busy != file || !comedi_is_subdevice_running(s) || (s->async->cmd.flags & CMDF_WRITE) || - comedi_buf_read_n_available(s) > 0) + _comedi_buf_read_n_available(s) > 0) mask |= EPOLLIN | EPOLLRDNORM; } @@ -2645,7 +2702,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, break; /* Allocate all free buffer space. */ - comedi_buf_write_alloc(s, async->prealloc_bufsz); + _comedi_buf_write_alloc(s, async->prealloc_bufsz); m = comedi_buf_write_n_allocated(s); n = min_t(size_t, m, nbytes); @@ -2673,7 +2730,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, n -= m; retval = -EFAULT; } - comedi_buf_write_free(s, n); + _comedi_buf_write_free(s, n); count += n; nbytes -= n; @@ -2759,7 +2816,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, while (count == 0 && !retval) { set_current_state(TASK_INTERRUPTIBLE); - m = comedi_buf_read_n_available(s); + m = _comedi_buf_read_n_available(s); n = min_t(size_t, m, nbytes); if (n == 0) { @@ -2799,8 +2856,8 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, retval = -EFAULT; } - comedi_buf_read_alloc(s, n); - comedi_buf_read_free(s, n); + _comedi_buf_read_alloc(s, n); + _comedi_buf_read_free(s, n); count += n; nbytes -= n; @@ -2834,7 +2891,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, s == new_s && new_s->async == async && s->busy == file && !(async->cmd.flags & CMDF_WRITE) && !comedi_is_subdevice_running(s) && - comedi_buf_read_n_available(s) == 0) + _comedi_buf_read_n_available(s) == 0) do_become_nonbusy(dev, s); mutex_unlock(&dev->mutex); } @@ -3023,7 +3080,12 @@ static int compat_chaninfo(struct file *file, unsigned long arg) chaninfo.rangelist = compat_ptr(chaninfo32.rangelist); mutex_lock(&dev->mutex); - err = do_chaninfo_ioctl(dev, &chaninfo); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + err = -ENODEV; + } else { + err = do_chaninfo_ioctl(dev, &chaninfo); + } mutex_unlock(&dev->mutex); return err; } @@ -3044,7 +3106,12 @@ static int compat_rangeinfo(struct file *file, unsigned long arg) rangeinfo.range_ptr = compat_ptr(rangeinfo32.range_ptr); mutex_lock(&dev->mutex); - err = do_rangeinfo_ioctl(dev, &rangeinfo); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + err = -ENODEV; + } else { + err = do_rangeinfo_ioctl(dev, &rangeinfo); + } mutex_unlock(&dev->mutex); return err; } @@ -3120,7 +3187,12 @@ static int compat_cmd(struct file *file, unsigned long arg) return rc; mutex_lock(&dev->mutex); - rc = do_cmd_ioctl(dev, &cmd, ©, file); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + rc = -ENODEV; + } else { + rc = do_cmd_ioctl(dev, &cmd, ©, file); + } mutex_unlock(&dev->mutex); if (copy) { /* Special case: copy cmd back to user. */ @@ -3145,7 +3217,12 @@ static int compat_cmdtest(struct file *file, unsigned long arg) return rc; mutex_lock(&dev->mutex); - rc = do_cmdtest_ioctl(dev, &cmd, ©, file); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + rc = -ENODEV; + } else { + rc = do_cmdtest_ioctl(dev, &cmd, ©, file); + } mutex_unlock(&dev->mutex); if (copy) { err = put_compat_cmd(compat_ptr(arg), &cmd); @@ -3205,7 +3282,12 @@ static int compat_insnlist(struct file *file, unsigned long arg) } mutex_lock(&dev->mutex); - rc = do_insnlist_ioctl(dev, insns, insnlist32.n_insns, file); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + rc = -ENODEV; + } else { + rc = do_insnlist_ioctl(dev, insns, insnlist32.n_insns, file); + } mutex_unlock(&dev->mutex); kfree(insns); return rc; @@ -3224,7 +3306,12 @@ static int compat_insn(struct file *file, unsigned long arg) return rc; mutex_lock(&dev->mutex); - rc = do_insn_ioctl(dev, &insn, file); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + rc = -ENODEV; + } else { + rc = do_insn_ioctl(dev, &insn, file); + } mutex_unlock(&dev->mutex); return rc; } @@ -3299,18 +3386,7 @@ static const struct file_operations comedi_fops = { .llseek = noop_llseek, }; -/** - * comedi_event() - Handle events for asynchronous COMEDI command - * @dev: COMEDI device. - * @s: COMEDI subdevice. - * Context: in_interrupt() (usually), @s->spin_lock spin-lock not held. - * - * If an asynchronous COMEDI command is active on the subdevice, process - * any %COMEDI_CB_... event flags that have been set, usually by an - * interrupt handler. These may change the run state of the asynchronous - * command, wake a task, and/or send a %SIGIO signal. - */ -void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) +void _comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) { struct comedi_async *async = s->async; unsigned int events; @@ -3346,6 +3422,25 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) if (si_code) kill_fasync(&dev->async_queue, SIGIO, si_code); } + +/** + * comedi_event() - Handle events for asynchronous COMEDI command + * @dev: COMEDI device. + * @s: COMEDI subdevice. + * Context: in_interrupt() (usually), @s->spin_lock spin-lock not held. + * + * If an asynchronous COMEDI command is active on the subdevice, process + * any %COMEDI_CB_... event flags that have been set, usually by an + * interrupt handler. These may change the run state of the asynchronous + * command, wake a task, and/or send a %SIGIO signal. + */ +void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) +{ + if (comedi_get_is_subdevice_running(s)) { + comedi_event(dev, s); + comedi_put_is_subdevice_running(s); + } +} EXPORT_SYMBOL_GPL(comedi_event); /* Note: the ->mutex is pre-locked on successful return */ diff --git a/drivers/comedi/comedi_internal.h b/drivers/comedi/comedi_internal.h index cf10ba016ebc8..41a3b09f8f050 100644 --- a/drivers/comedi/comedi_internal.h +++ b/drivers/comedi/comedi_internal.h @@ -36,6 +36,18 @@ struct comedi_buf_map * comedi_buf_map_from_subdev_get(struct comedi_subdevice *s); unsigned int comedi_buf_write_n_available(struct comedi_subdevice *s); unsigned int comedi_buf_write_n_allocated(struct comedi_subdevice *s); +unsigned int _comedi_buf_write_alloc(struct comedi_subdevice *s, + unsigned int nbytes); +unsigned int _comedi_buf_write_free(struct comedi_subdevice *s, + unsigned int nbytes); +unsigned int _comedi_buf_read_n_available(struct comedi_subdevice *s); +unsigned int _comedi_buf_read_alloc(struct comedi_subdevice *s, + unsigned int nbytes); +unsigned int _comedi_buf_read_free(struct comedi_subdevice *s, + unsigned int nbytes); +void _comedi_inc_scan_progress(struct comedi_subdevice *s, + unsigned int num_bytes); +void _comedi_event(struct comedi_device *dev, struct comedi_subdevice *s); void comedi_device_cancel_all(struct comedi_device *dev); bool comedi_can_auto_free_spriv(struct comedi_subdevice *s); diff --git a/drivers/comedi/drivers.c b/drivers/comedi/drivers.c index c9ebaadc5e82a..69cd2a253c663 100644 --- a/drivers/comedi/drivers.c +++ b/drivers/comedi/drivers.c @@ -441,6 +441,13 @@ unsigned int comedi_bytes_per_scan_cmd(struct comedi_subdevice *s, } EXPORT_SYMBOL_GPL(comedi_bytes_per_scan_cmd); +static unsigned int _comedi_bytes_per_scan(struct comedi_subdevice *s) +{ + struct comedi_cmd *cmd = &s->async->cmd; + + return comedi_bytes_per_scan_cmd(s, cmd); +} + /** * comedi_bytes_per_scan() - Get length of asynchronous command "scan" in bytes * @s: COMEDI subdevice. @@ -458,9 +465,16 @@ EXPORT_SYMBOL_GPL(comedi_bytes_per_scan_cmd); */ unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s) { - struct comedi_cmd *cmd = &s->async->cmd; + unsigned int num_bytes; - return comedi_bytes_per_scan_cmd(s, cmd); + if (comedi_get_is_subdevice_running(s)) { + num_bytes = _comedi_bytes_per_scan(s); + comedi_put_is_subdevice_running(s); + } else { + /* Use nomimal, single sample scan length. */ + num_bytes = comedi_samples_to_bytes(s, 1); + } + return num_bytes; } EXPORT_SYMBOL_GPL(comedi_bytes_per_scan); @@ -482,6 +496,17 @@ static unsigned int __comedi_nscans_left(struct comedi_subdevice *s, return nscans; } +static unsigned int _comedi_nscans_left(struct comedi_subdevice *s, + unsigned int nscans) +{ + if (nscans == 0) { + unsigned int nbytes = _comedi_buf_read_n_available(s); + + nscans = nbytes / _comedi_bytes_per_scan(s); + } + return __comedi_nscans_left(s, nscans); +} + /** * comedi_nscans_left() - Return the number of scans left in the command * @s: COMEDI subdevice. @@ -499,25 +524,18 @@ static unsigned int __comedi_nscans_left(struct comedi_subdevice *s, unsigned int comedi_nscans_left(struct comedi_subdevice *s, unsigned int nscans) { - if (nscans == 0) { - unsigned int nbytes = comedi_buf_read_n_available(s); - - nscans = nbytes / comedi_bytes_per_scan(s); + if (comedi_get_is_subdevice_running(s)) { + nscans = _comedi_nscans_left(s, nscans); + comedi_put_is_subdevice_running(s); + } else { + nscans = 0; } - return __comedi_nscans_left(s, nscans); + return nscans; } EXPORT_SYMBOL_GPL(comedi_nscans_left); -/** - * comedi_nsamples_left() - Return the number of samples left in the command - * @s: COMEDI subdevice. - * @nsamples: The expected number of samples. - * - * Returns the number of samples remaining to complete the command, or the - * specified expected number of samples (@nsamples), whichever is fewer. - */ -unsigned int comedi_nsamples_left(struct comedi_subdevice *s, - unsigned int nsamples) +static unsigned int _comedi_nsamples_left(struct comedi_subdevice *s, + unsigned int nsamples) { struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -538,24 +556,34 @@ unsigned int comedi_nsamples_left(struct comedi_subdevice *s, return samples_left; return nsamples; } -EXPORT_SYMBOL_GPL(comedi_nsamples_left); /** - * comedi_inc_scan_progress() - Update scan progress in asynchronous command + * comedi_nsamples_left() - Return the number of samples left in the command * @s: COMEDI subdevice. - * @num_bytes: Amount of data in bytes to increment scan progress. + * @nsamples: The expected number of samples. * - * Increments the scan progress by the number of bytes specified by @num_bytes. - * If the scan progress reaches or exceeds the scan length in bytes, reduce - * it modulo the scan length in bytes and set the "end of scan" asynchronous - * event flag (%COMEDI_CB_EOS) to be processed later. + * Returns the number of samples remaining to complete the command, or the + * specified expected number of samples (@nsamples), whichever is fewer. */ -void comedi_inc_scan_progress(struct comedi_subdevice *s, - unsigned int num_bytes) +unsigned int comedi_nsamples_left(struct comedi_subdevice *s, + unsigned int nsamples) +{ + if (comedi_get_is_subdevice_running(s)) { + nsamples = _comedi_nsamples_left(s, nsamples); + comedi_put_is_subdevice_running(s); + } else { + nsamples = 0; + } + return nsamples; +} +EXPORT_SYMBOL_GPL(comedi_nsamples_left); + +void _comedi_inc_scan_progress(struct comedi_subdevice *s, + unsigned int num_bytes) { struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - unsigned int scan_length = comedi_bytes_per_scan(s); + unsigned int scan_length = _comedi_bytes_per_scan(s); /* track the 'cur_chan' for non-SDF_PACKED subdevices */ if (!(s->subdev_flags & SDF_PACKED)) { @@ -576,8 +604,43 @@ void comedi_inc_scan_progress(struct comedi_subdevice *s, async->events |= COMEDI_CB_EOS; } } + +/** + * comedi_inc_scan_progress() - Update scan progress in asynchronous command + * @s: COMEDI subdevice. + * @num_bytes: Amount of data in bytes to increment scan progress. + * + * Increments the scan progress by the number of bytes specified by @num_bytes. + * If the scan progress reaches or exceeds the scan length in bytes, reduce + * it modulo the scan length in bytes and set the "end of scan" asynchronous + * event flag (%COMEDI_CB_EOS) to be processed later. + */ +void comedi_inc_scan_progress(struct comedi_subdevice *s, + unsigned int num_bytes) +{ + if (comedi_get_is_subdevice_running(s)) { + _comedi_inc_scan_progress(s, num_bytes); + comedi_put_is_subdevice_running(s); + } +} EXPORT_SYMBOL_GPL(comedi_inc_scan_progress); +static unsigned int _comedi_handle_events(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + unsigned int events = s->async->events; + + if (events == 0) + return events; + + if ((events & COMEDI_CB_CANCEL_MASK) && s->cancel) + s->cancel(dev, s); + + _comedi_event(dev, s); + + return events; +} + /** * comedi_handle_events() - Handle events and possibly stop acquisition * @dev: COMEDI device. @@ -597,16 +660,14 @@ EXPORT_SYMBOL_GPL(comedi_inc_scan_progress); unsigned int comedi_handle_events(struct comedi_device *dev, struct comedi_subdevice *s) { - unsigned int events = s->async->events; - - if (events == 0) - return events; - - if ((events & COMEDI_CB_CANCEL_MASK) && s->cancel) - s->cancel(dev, s); - - comedi_event(dev, s); + unsigned int events; + if (comedi_get_is_subdevice_running(s)) { + events = _comedi_handle_events(dev, s); + comedi_put_is_subdevice_running(s); + } else { + events = 0; + } return events; } EXPORT_SYMBOL_GPL(comedi_handle_events); @@ -677,6 +738,7 @@ static int __comedi_device_postconfig_async(struct comedi_device *dev, return -ENOMEM; init_waitqueue_head(&async->wait_head); + init_completion(&async->run_complete); s->async = async; async->max_bufsize = comedi_default_buf_maxsize_kb * 1024; diff --git a/drivers/comedi/drivers/8255.c b/drivers/comedi/drivers/8255.c index f45f7bd1c61a7..5f70938b44773 100644 --- a/drivers/comedi/drivers/8255.c +++ b/drivers/comedi/drivers/8255.c @@ -77,19 +77,17 @@ static int dev_8255_attach(struct comedi_device *dev, * base address of the chip. */ ret = __comedi_request_region(dev, iobase, I8255_SIZE); + if (ret) + return ret; + ret = subdev_8255_io_init(dev, s, iobase); if (ret) { + /* + * Release the I/O port region here, as the + * "detach" handler cannot find it. + */ + release_region(iobase, I8255_SIZE); s->type = COMEDI_SUBD_UNUSED; - } else { - ret = subdev_8255_io_init(dev, s, iobase); - if (ret) { - /* - * Release the I/O port region here, as the - * "detach" handler cannot find it. - */ - release_region(iobase, I8255_SIZE); - s->type = COMEDI_SUBD_UNUSED; - return ret; - } + return ret; } } diff --git a/drivers/comedi/drivers/c6xdigio.c b/drivers/comedi/drivers/c6xdigio.c index 14b90d1c64dc1..8a38d97d463b2 100644 --- a/drivers/comedi/drivers/c6xdigio.c +++ b/drivers/comedi/drivers/c6xdigio.c @@ -249,9 +249,6 @@ static int c6xdigio_attach(struct comedi_device *dev, if (ret) return ret; - /* Make sure that PnP ports get activated */ - pnp_register_driver(&c6xdigio_pnp_driver); - s = &dev->subdevices[0]; /* pwm output subdevice */ s->type = COMEDI_SUBD_PWM; @@ -278,19 +275,46 @@ static int c6xdigio_attach(struct comedi_device *dev, return 0; } -static void c6xdigio_detach(struct comedi_device *dev) -{ - comedi_legacy_detach(dev); - pnp_unregister_driver(&c6xdigio_pnp_driver); -} - static struct comedi_driver c6xdigio_driver = { .driver_name = "c6xdigio", .module = THIS_MODULE, .attach = c6xdigio_attach, - .detach = c6xdigio_detach, + .detach = comedi_legacy_detach, }; -module_comedi_driver(c6xdigio_driver); + +static bool c6xdigio_pnp_registered = false; + +static int __init c6xdigio_module_init(void) +{ + int ret; + + ret = comedi_driver_register(&c6xdigio_driver); + if (ret) + return ret; + + if (IS_ENABLED(CONFIG_PNP)) { + /* Try to activate the PnP ports */ + ret = pnp_register_driver(&c6xdigio_pnp_driver); + if (ret) { + pr_warn("failed to register pnp driver - err %d\n", + ret); + ret = 0; /* ignore the error. */ + } else { + c6xdigio_pnp_registered = true; + } + } + + return 0; +} +module_init(c6xdigio_module_init); + +static void __exit c6xdigio_module_exit(void) +{ + if (c6xdigio_pnp_registered) + pnp_unregister_driver(&c6xdigio_pnp_driver); + comedi_driver_unregister(&c6xdigio_driver); +} +module_exit(c6xdigio_module_exit); MODULE_AUTHOR("Comedi https://www.comedi.org"); MODULE_DESCRIPTION("Comedi driver for the C6x_DIGIO DSP daughter card"); diff --git a/drivers/comedi/drivers/comedi_bond.c b/drivers/comedi/drivers/comedi_bond.c index 78c39fa841776..30650fa36fff2 100644 --- a/drivers/comedi/drivers/comedi_bond.c +++ b/drivers/comedi/drivers/comedi_bond.c @@ -205,7 +205,7 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it) snprintf(file, sizeof(file), "/dev/comedi%d", minor); file[sizeof(file) - 1] = 0; - d = comedi_open(file); + d = comedi_open_from(file, dev->minor); if (!d) { dev_err(dev->class_dev, @@ -326,7 +326,7 @@ static void bonding_detach(struct comedi_device *dev) if (!bdev) continue; if (!test_and_set_bit(bdev->minor, devs_closed)) - comedi_close(bdev->dev); + comedi_close_from(bdev->dev, dev->minor); kfree(bdev); } kfree(devpriv->devs); diff --git a/drivers/comedi/drivers/multiq3.c b/drivers/comedi/drivers/multiq3.c index 07ff5383da997..ac369e9a262d7 100644 --- a/drivers/comedi/drivers/multiq3.c +++ b/drivers/comedi/drivers/multiq3.c @@ -67,6 +67,11 @@ #define MULTIQ3_TRSFRCNTR_OL 0x10 /* xfer CNTR to OL (x and y) */ #define MULTIQ3_EFLAG_RESET 0x06 /* reset E bit of flag reg */ +/* + * Limit on the number of optional encoder channels + */ +#define MULTIQ3_MAX_ENC_CHANS 8 + static void multiq3_set_ctrl(struct comedi_device *dev, unsigned int bits) { /* @@ -312,6 +317,10 @@ static int multiq3_attach(struct comedi_device *dev, s->insn_read = multiq3_encoder_insn_read; s->insn_config = multiq3_encoder_insn_config; + /* sanity check for number of encoder channels */ + if (s->n_chan > MULTIQ3_MAX_ENC_CHANS) + s->n_chan = MULTIQ3_MAX_ENC_CHANS; + for (i = 0; i < s->n_chan; i++) multiq3_encoder_reset(dev, i); diff --git a/drivers/comedi/drivers/ni_670x.c b/drivers/comedi/drivers/ni_670x.c index c875d251c2302..563a9c790f123 100644 --- a/drivers/comedi/drivers/ni_670x.c +++ b/drivers/comedi/drivers/ni_670x.c @@ -199,7 +199,7 @@ static int ni_670x_auto_attach(struct comedi_device *dev, const struct comedi_lrange **range_table_list; range_table_list = kmalloc_array(32, - sizeof(struct comedi_lrange *), + sizeof(*range_table_list), GFP_KERNEL); if (!range_table_list) return -ENOMEM; diff --git a/drivers/comedi/drivers/pcl818.c b/drivers/comedi/drivers/pcl818.c index 4127adcfb2295..06fe06396f23a 100644 --- a/drivers/comedi/drivers/pcl818.c +++ b/drivers/comedi/drivers/pcl818.c @@ -1111,10 +1111,9 @@ static void pcl818_detach(struct comedi_device *dev) { struct pcl818_private *devpriv = dev->private; - if (devpriv) { - pcl818_ai_cancel(dev, dev->read_subdev); + if (devpriv) pcl818_reset(dev); - } + pcl818_free_dma(dev); comedi_legacy_detach(dev); } diff --git a/drivers/comedi/kcomedilib/kcomedilib_main.c b/drivers/comedi/kcomedilib/kcomedilib_main.c index 43fbe1a63b14f..baa9eaaf97d4c 100644 --- a/drivers/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/comedi/kcomedilib/kcomedilib_main.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -24,7 +25,104 @@ MODULE_AUTHOR("David Schleef "); MODULE_DESCRIPTION("Comedi kernel library"); MODULE_LICENSE("GPL"); -struct comedi_device *comedi_open(const char *filename) +static DEFINE_MUTEX(kcomedilib_to_from_lock); + +/* + * Row index is the "to" node, column index is the "from" node, element value + * is the number of links from the "from" node to the "to" node. + */ +static unsigned char + kcomedilib_to_from[COMEDI_NUM_BOARD_MINORS][COMEDI_NUM_BOARD_MINORS]; + +static bool kcomedilib_set_link_from_to(unsigned int from, unsigned int to) +{ + DECLARE_BITMAP(destinations[2], COMEDI_NUM_BOARD_MINORS); + unsigned int cur = 0; + bool okay = true; + + /* + * Allow "from" node to be out of range (no loop checking), + * but require "to" node to be in range. + */ + if (to >= COMEDI_NUM_BOARD_MINORS) + return false; + if (from >= COMEDI_NUM_BOARD_MINORS) + return true; + + /* + * Check that kcomedilib_to_from[to][from] can be made non-zero + * without creating a loop. + * + * Termination of the loop-testing code relies on the assumption that + * kcomedilib_to_from[][] does not contain any loops. + * + * Start with a set destinations set containing "from" as the only + * element and work backwards looking for loops. + */ + bitmap_zero(destinations[cur], COMEDI_NUM_BOARD_MINORS); + set_bit(from, destinations[cur]); + mutex_lock(&kcomedilib_to_from_lock); + do { + unsigned int next = 1 - cur; + unsigned int t = 0; + + if (test_bit(to, destinations[cur])) { + /* Loop detected. */ + okay = false; + break; + } + /* Create next set of destinations. */ + bitmap_zero(destinations[next], COMEDI_NUM_BOARD_MINORS); + while ((t = find_next_bit(destinations[cur], + COMEDI_NUM_BOARD_MINORS, + t)) < COMEDI_NUM_BOARD_MINORS) { + unsigned int f; + + for (f = 0; f < COMEDI_NUM_BOARD_MINORS; f++) { + if (kcomedilib_to_from[t][f]) + set_bit(f, destinations[next]); + } + t++; + } + cur = next; + } while (!bitmap_empty(destinations[cur], COMEDI_NUM_BOARD_MINORS)); + if (okay) { + /* Allow a maximum of 255 links from "from" to "to". */ + if (kcomedilib_to_from[to][from] < 255) + kcomedilib_to_from[to][from]++; + else + okay = false; + } + mutex_unlock(&kcomedilib_to_from_lock); + return okay; +} + +static void kcomedilib_clear_link_from_to(unsigned int from, unsigned int to) +{ + if (to < COMEDI_NUM_BOARD_MINORS && from < COMEDI_NUM_BOARD_MINORS) { + mutex_lock(&kcomedilib_to_from_lock); + if (kcomedilib_to_from[to][from]) + kcomedilib_to_from[to][from]--; + mutex_unlock(&kcomedilib_to_from_lock); + } +} + +/** + * comedi_open_from() - Open a COMEDI device from the kernel with loop checks + * @filename: Fake pathname of the form "/dev/comediN". + * @from: Device number it is being opened from (if in range). + * + * Converts @filename to a COMEDI device number and "opens" it if it exists + * and is attached to a low-level COMEDI driver. + * + * If @from is in range, refuse to open the device if doing so would form a + * loop of devices opening each other. There is also a limit of 255 on the + * number of concurrent opens from one device to another. + * + * Return: A pointer to the COMEDI device on success. + * Return %NULL on failure. + */ +struct comedi_device *comedi_open_from(const char *filename, int from) { struct comedi_device *dev, *retval = NULL; unsigned int minor; @@ -43,7 +141,7 @@ struct comedi_device *comedi_open(const char *filename) return NULL; down_read(&dev->attach_lock); - if (dev->attached) + if (dev->attached && kcomedilib_set_link_from_to(from, minor)) retval = dev; else retval = NULL; @@ -54,14 +152,26 @@ struct comedi_device *comedi_open(const char *filename) return retval; } -EXPORT_SYMBOL_GPL(comedi_open); +EXPORT_SYMBOL_GPL(comedi_open_from); -int comedi_close(struct comedi_device *dev) +/** + * comedi_close_from() - Close a COMEDI device from the kernel with loop checks + * @dev: COMEDI device. + * @from: Device number it was opened from (if in range). + * + * Closes a COMEDI device previously opened by comedi_open_from(). + * + * If @from is in range, it should be match the one used by comedi_open_from(). + * + * Returns: 0 + */ +int comedi_close_from(struct comedi_device *dev, int from) { + kcomedilib_clear_link_from_to(from, dev->minor); comedi_dev_put(dev); return 0; } -EXPORT_SYMBOL_GPL(comedi_close); +EXPORT_SYMBOL_GPL(comedi_close_from); static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn, diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index dc11b62399ad5..b06a43143d23c 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -219,20 +219,14 @@ static bool __init cpu0_node_has_opp_v2_prop(void) static int __init cpufreq_dt_platdev_init(void) { - struct device_node *np __free(device_node) = of_find_node_by_path("/"); - const struct of_device_id *match; const void *data = NULL; - if (!np) - return -ENODEV; - - match = of_match_node(allowlist, np); - if (match) { - data = match->data; + if (of_machine_device_match(allowlist)) { + data = of_machine_get_match_data(allowlist); goto create_pdev; } - if (cpu0_node_has_opp_v2_prop() && !of_match_node(blocklist, np)) + if (cpu0_node_has_opp_v2_prop() && !of_machine_device_match(blocklist)) goto create_pdev; return -ENODEV; diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 5d50a231f9444..052ca7cd2f4fd 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -764,22 +764,14 @@ MODULE_DEVICE_TABLE(of, mtk_cpufreq_machines); static int __init mtk_cpufreq_driver_init(void) { - struct device_node *np; - const struct of_device_id *match; const struct mtk_cpufreq_platform_data *data; int err; - np = of_find_node_by_path("/"); - if (!np) - return -ENODEV; - - match = of_match_node(mtk_cpufreq_machines, np); - of_node_put(np); - if (!match) { + data = of_machine_get_match_data(mtk_cpufreq_machines); + if (!data) { pr_debug("Machine is not compatible with mtk-cpufreq\n"); return -ENODEV; } - data = match->data; err = platform_driver_register(&mtk_cpufreq_platdrv); if (err) diff --git a/drivers/cpufreq/rcpufreq_dt.rs b/drivers/cpufreq/rcpufreq_dt.rs index 53923b8ef7a14..31e07f0279dbd 100644 --- a/drivers/cpufreq/rcpufreq_dt.rs +++ b/drivers/cpufreq/rcpufreq_dt.rs @@ -207,9 +207,9 @@ impl platform::Driver for CPUFreqDTDriver { fn probe( pdev: &platform::Device, _id_info: Option<&Self::IdInfo>, - ) -> Result>> { + ) -> impl PinInit { cpufreq::Registration::::new_foreign_owned(pdev.as_ref())?; - Ok(KBox::new(Self {}, GFP_KERNEL)?.into()) + Ok(Self {}) } } diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c index 744312a44279c..4fffc8e83692e 100644 --- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c +++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c @@ -332,13 +332,6 @@ static const struct of_device_id sun50i_cpufreq_match_list[] = { }; MODULE_DEVICE_TABLE(of, sun50i_cpufreq_match_list); -static const struct of_device_id *sun50i_cpufreq_match_node(void) -{ - struct device_node *np __free(device_node) = of_find_node_by_path("/"); - - return of_match_node(sun50i_cpufreq_match_list, np); -} - /* * Since the driver depends on nvmem drivers, which may return EPROBE_DEFER, * all the real activity is done in the probe, which may be defered as well. @@ -346,11 +339,9 @@ static const struct of_device_id *sun50i_cpufreq_match_node(void) */ static int __init sun50i_cpufreq_init(void) { - const struct of_device_id *match; int ret; - match = sun50i_cpufreq_match_node(); - if (!match) + if (!of_machine_device_match(sun50i_cpufreq_match_list)) return -ENODEV; ret = platform_driver_register(&sun50i_cpufreq_driver); diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c index 4abba42fcc311..08f6bf2f64091 100644 --- a/drivers/cpuidle/cpuidle-big_little.c +++ b/drivers/cpuidle/cpuidle-big_little.c @@ -166,20 +166,11 @@ static const struct of_device_id compatible_machine_match[] = { static int __init bl_idle_init(void) { int ret; - struct device_node *root = of_find_node_by_path("/"); - const struct of_device_id *match_id; - - if (!root) - return -ENODEV; /* * Initialize the driver just for a compliant set of machines */ - match_id = of_match_node(compatible_machine_match, root); - - of_node_put(root); - - if (!match_id) + if (!of_machine_device_match(compatible_machine_match)) return -ENODEV; if (!mcpm_is_available()) diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c index b19bc60cc627b..dcf20ea5ef5e3 100644 --- a/drivers/cpuidle/cpuidle-psci.c +++ b/drivers/cpuidle/cpuidle-psci.c @@ -177,26 +177,30 @@ static void psci_idle_syscore_switch(bool suspend) } } -static int psci_idle_syscore_suspend(void) +static int psci_idle_syscore_suspend(void *data) { psci_idle_syscore_switch(true); return 0; } -static void psci_idle_syscore_resume(void) +static void psci_idle_syscore_resume(void *data) { psci_idle_syscore_switch(false); } -static struct syscore_ops psci_idle_syscore_ops = { +static const struct syscore_ops psci_idle_syscore_ops = { .suspend = psci_idle_syscore_suspend, .resume = psci_idle_syscore_resume, }; +static struct syscore psci_idle_syscore = { + .ops = &psci_idle_syscore_ops, +}; + static void psci_idle_init_syscore(void) { if (psci_cpuidle_use_syscore) - register_syscore_ops(&psci_idle_syscore_ops); + register_syscore(&psci_idle_syscore); } static void psci_idle_init_cpuhp(void) @@ -382,8 +386,8 @@ static int psci_idle_init_cpu(struct device *dev, int cpu) drv->states[0].exit_latency = 1; drv->states[0].target_residency = 1; drv->states[0].power_usage = UINT_MAX; - strcpy(drv->states[0].name, "WFI"); - strcpy(drv->states[0].desc, "ARM WFI"); + strscpy(drv->states[0].name, "WFI"); + strscpy(drv->states[0].desc, "ARM WFI"); /* * If no DT idle states are detected (ret == 0) let the driver diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig index f394e45e11ab4..f16a0f6113175 100644 --- a/drivers/crypto/ccp/Kconfig +++ b/drivers/crypto/ccp/Kconfig @@ -39,6 +39,7 @@ config CRYPTO_DEV_SP_PSP bool "Platform Security Processor (PSP) device" default y depends on CRYPTO_DEV_CCP_DD && X86_64 && AMD_IOMMU + select PCI_TSM if PCI help Provide support for the AMD Platform Security Processor (PSP). The PSP is a dedicated processor that provides support for key diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile index a9626b30044ae..0424e08561ef1 100644 --- a/drivers/crypto/ccp/Makefile +++ b/drivers/crypto/ccp/Makefile @@ -16,6 +16,10 @@ ccp-$(CONFIG_CRYPTO_DEV_SP_PSP) += psp-dev.o \ hsti.o \ sfs.o +ifeq ($(CONFIG_PCI_TSM),y) +ccp-$(CONFIG_CRYPTO_DEV_SP_PSP) += sev-dev-tsm.o sev-dev-tio.o +endif + obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o ccp-crypto-objs := ccp-crypto-main.o \ ccp-crypto-aes.o \ diff --git a/drivers/crypto/ccp/sev-dev-tio.c b/drivers/crypto/ccp/sev-dev-tio.c new file mode 100644 index 0000000000000..9a98f98c20a79 --- /dev/null +++ b/drivers/crypto/ccp/sev-dev-tio.c @@ -0,0 +1,864 @@ +// SPDX-License-Identifier: GPL-2.0-only + +// Interface to PSP for CCP/SEV-TIO/SNP-VM + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sev-dev.h" +#include "sev-dev-tio.h" + +#define to_tio_status(dev_data) \ + (container_of((dev_data), struct tio_dsm, data)->sev->tio_status) + +#define SLA_PAGE_TYPE_DATA 0 +#define SLA_PAGE_TYPE_SCATTER 1 +#define SLA_PAGE_SIZE_4K 0 +#define SLA_PAGE_SIZE_2M 1 +#define SLA_SZ(s) ((s).page_size == SLA_PAGE_SIZE_2M ? SZ_2M : SZ_4K) +#define SLA_SCATTER_LEN(s) (SLA_SZ(s) / sizeof(struct sla_addr_t)) +#define SLA_EOL ((struct sla_addr_t) { .pfn = ((1UL << 40) - 1) }) +#define SLA_NULL ((struct sla_addr_t) { 0 }) +#define IS_SLA_NULL(s) ((s).sla == SLA_NULL.sla) +#define IS_SLA_EOL(s) ((s).sla == SLA_EOL.sla) + +static phys_addr_t sla_to_pa(struct sla_addr_t sla) +{ + u64 pfn = sla.pfn; + u64 pa = pfn << PAGE_SHIFT; + + return pa; +} + +static void *sla_to_va(struct sla_addr_t sla) +{ + void *va = __va(__sme_clr(sla_to_pa(sla))); + + return va; +} + +#define sla_to_pfn(sla) (__pa(sla_to_va(sla)) >> PAGE_SHIFT) +#define sla_to_page(sla) virt_to_page(sla_to_va(sla)) + +static struct sla_addr_t make_sla(struct page *pg, bool stp) +{ + u64 pa = __sme_set(page_to_phys(pg)); + struct sla_addr_t ret = { + .pfn = pa >> PAGE_SHIFT, + .page_size = SLA_PAGE_SIZE_4K, /* Do not do SLA_PAGE_SIZE_2M ATM */ + .page_type = stp ? SLA_PAGE_TYPE_SCATTER : SLA_PAGE_TYPE_DATA + }; + + return ret; +} + +/* the BUFFER Structure */ +#define SLA_BUFFER_FLAG_ENCRYPTION BIT(0) + +/* + * struct sla_buffer_hdr - Scatter list address buffer header + * + * @capacity_sz: Total capacity of the buffer in bytes + * @payload_sz: Size of buffer payload in bytes, must be multiple of 32B + * @flags: Buffer flags (SLA_BUFFER_FLAG_ENCRYPTION: buffer is encrypted) + * @iv: Initialization vector used for encryption + * @authtag: Authentication tag for encrypted buffer + */ +struct sla_buffer_hdr { + u32 capacity_sz; + u32 payload_sz; /* The size of BUFFER_PAYLOAD in bytes. Must be multiple of 32B */ + u32 flags; + u8 reserved1[4]; + u8 iv[16]; /* IV used for the encryption of this buffer */ + u8 authtag[16]; /* Authentication tag for this buffer */ + u8 reserved2[16]; +} __packed; + +enum spdm_data_type_t { + DOBJ_DATA_TYPE_SPDM = 0x1, + DOBJ_DATA_TYPE_SECURE_SPDM = 0x2, +}; + +struct spdm_dobj_hdr_req { + struct spdm_dobj_hdr hdr; /* hdr.id == SPDM_DOBJ_ID_REQ */ + u8 data_type; /* spdm_data_type_t */ + u8 reserved2[5]; +} __packed; + +struct spdm_dobj_hdr_resp { + struct spdm_dobj_hdr hdr; /* hdr.id == SPDM_DOBJ_ID_RESP */ + u8 data_type; /* spdm_data_type_t */ + u8 reserved2[5]; +} __packed; + +/* Defined in sev-dev-tio.h so sev-dev-tsm.c can read types of blobs */ +struct spdm_dobj_hdr_cert; +struct spdm_dobj_hdr_meas; +struct spdm_dobj_hdr_report; + +/* Used in all SPDM-aware TIO commands */ +struct spdm_ctrl { + struct sla_addr_t req; + struct sla_addr_t resp; + struct sla_addr_t scratch; + struct sla_addr_t output; +} __packed; + +static size_t sla_dobj_id_to_size(u8 id) +{ + size_t n; + + BUILD_BUG_ON(sizeof(struct spdm_dobj_hdr_resp) != 0x10); + switch (id) { + case SPDM_DOBJ_ID_REQ: + n = sizeof(struct spdm_dobj_hdr_req); + break; + case SPDM_DOBJ_ID_RESP: + n = sizeof(struct spdm_dobj_hdr_resp); + break; + default: + WARN_ON(1); + n = 0; + break; + } + + return n; +} + +#define SPDM_DOBJ_HDR_SIZE(hdr) sla_dobj_id_to_size((hdr)->id) +#define SPDM_DOBJ_DATA(hdr) ((u8 *)(hdr) + SPDM_DOBJ_HDR_SIZE(hdr)) +#define SPDM_DOBJ_LEN(hdr) ((hdr)->length - SPDM_DOBJ_HDR_SIZE(hdr)) + +#define sla_to_dobj_resp_hdr(buf) ((struct spdm_dobj_hdr_resp *) \ + sla_to_dobj_hdr_check((buf), SPDM_DOBJ_ID_RESP)) +#define sla_to_dobj_req_hdr(buf) ((struct spdm_dobj_hdr_req *) \ + sla_to_dobj_hdr_check((buf), SPDM_DOBJ_ID_REQ)) + +static struct spdm_dobj_hdr *sla_to_dobj_hdr(struct sla_buffer_hdr *buf) +{ + if (!buf) + return NULL; + + return (struct spdm_dobj_hdr *) &buf[1]; +} + +static struct spdm_dobj_hdr *sla_to_dobj_hdr_check(struct sla_buffer_hdr *buf, u32 check_dobjid) +{ + struct spdm_dobj_hdr *hdr = sla_to_dobj_hdr(buf); + + if (WARN_ON_ONCE(!hdr)) + return NULL; + + if (hdr->id != check_dobjid) { + pr_err("! ERROR: expected %d, found %d\n", check_dobjid, hdr->id); + return NULL; + } + + return hdr; +} + +static void *sla_to_data(struct sla_buffer_hdr *buf, u32 dobjid) +{ + struct spdm_dobj_hdr *hdr = sla_to_dobj_hdr(buf); + + if (WARN_ON_ONCE(dobjid != SPDM_DOBJ_ID_REQ && dobjid != SPDM_DOBJ_ID_RESP)) + return NULL; + + if (!hdr) + return NULL; + + return (u8 *) hdr + sla_dobj_id_to_size(dobjid); +} + +/* + * struct sev_data_tio_status - SEV_CMD_TIO_STATUS command + * + * @length: Length of this command buffer in bytes + * @status_paddr: System physical address of the TIO_STATUS structure + */ +struct sev_data_tio_status { + u32 length; + u8 reserved[4]; + u64 status_paddr; +} __packed; + +/* TIO_INIT */ +struct sev_data_tio_init { + u32 length; + u8 reserved[12]; +} __packed; + +/* + * struct sev_data_tio_dev_create - TIO_DEV_CREATE command + * + * @length: Length in bytes of this command buffer + * @dev_ctx_sla: Scatter list address pointing to a buffer to be used as a device context buffer + * @device_id: PCIe Routing Identifier of the device to connect to + * @root_port_id: PCIe Routing Identifier of the root port of the device + * @segment_id: PCIe Segment Identifier of the device to connect to + */ +struct sev_data_tio_dev_create { + u32 length; + u8 reserved1[4]; + struct sla_addr_t dev_ctx_sla; + u16 device_id; + u16 root_port_id; + u8 segment_id; + u8 reserved2[11]; +} __packed; + +/* + * struct sev_data_tio_dev_connect - TIO_DEV_CONNECT command + * + * @length: Length in bytes of this command buffer + * @spdm_ctrl: SPDM control structure defined in Section 5.1 + * @dev_ctx_sla: Scatter list address of the device context buffer + * @tc_mask: Bitmask of the traffic classes to initialize for SEV-TIO usage. + * Setting the kth bit of the TC_MASK to 1 indicates that the traffic + * class k will be initialized + * @cert_slot: Slot number of the certificate requested for constructing the SPDM session + * @ide_stream_id: IDE stream IDs to be associated with this device. + * Valid only if corresponding bit in TC_MASK is set + */ +struct sev_data_tio_dev_connect { + u32 length; + u8 reserved1[4]; + struct spdm_ctrl spdm_ctrl; + u8 reserved2[8]; + struct sla_addr_t dev_ctx_sla; + u8 tc_mask; + u8 cert_slot; + u8 reserved3[6]; + u8 ide_stream_id[8]; + u8 reserved4[8]; +} __packed; + +/* + * struct sev_data_tio_dev_disconnect - TIO_DEV_DISCONNECT command + * + * @length: Length in bytes of this command buffer + * @flags: Command flags (TIO_DEV_DISCONNECT_FLAG_FORCE: force disconnect) + * @spdm_ctrl: SPDM control structure defined in Section 5.1 + * @dev_ctx_sla: Scatter list address of the device context buffer + */ +#define TIO_DEV_DISCONNECT_FLAG_FORCE BIT(0) + +struct sev_data_tio_dev_disconnect { + u32 length; + u32 flags; + struct spdm_ctrl spdm_ctrl; + struct sla_addr_t dev_ctx_sla; +} __packed; + +/* + * struct sev_data_tio_dev_meas - TIO_DEV_MEASUREMENTS command + * + * @length: Length in bytes of this command buffer + * @flags: Command flags (TIO_DEV_MEAS_FLAG_RAW_BITSTREAM: request raw measurements) + * @spdm_ctrl: SPDM control structure defined in Section 5.1 + * @dev_ctx_sla: Scatter list address of the device context buffer + * @meas_nonce: Nonce for measurement freshness verification + */ +#define TIO_DEV_MEAS_FLAG_RAW_BITSTREAM BIT(0) + +struct sev_data_tio_dev_meas { + u32 length; + u32 flags; + struct spdm_ctrl spdm_ctrl; + struct sla_addr_t dev_ctx_sla; + u8 meas_nonce[32]; +} __packed; + +/* + * struct sev_data_tio_dev_certs - TIO_DEV_CERTIFICATES command + * + * @length: Length in bytes of this command buffer + * @spdm_ctrl: SPDM control structure defined in Section 5.1 + * @dev_ctx_sla: Scatter list address of the device context buffer + */ +struct sev_data_tio_dev_certs { + u32 length; + u8 reserved[4]; + struct spdm_ctrl spdm_ctrl; + struct sla_addr_t dev_ctx_sla; +} __packed; + +/* + * struct sev_data_tio_dev_reclaim - TIO_DEV_RECLAIM command + * + * @length: Length in bytes of this command buffer + * @dev_ctx_sla: Scatter list address of the device context buffer + * + * This command reclaims resources associated with a device context. + */ +struct sev_data_tio_dev_reclaim { + u32 length; + u8 reserved[4]; + struct sla_addr_t dev_ctx_sla; +} __packed; + +static struct sla_buffer_hdr *sla_buffer_map(struct sla_addr_t sla) +{ + struct sla_buffer_hdr *buf; + + BUILD_BUG_ON(sizeof(struct sla_buffer_hdr) != 0x40); + if (IS_SLA_NULL(sla)) + return NULL; + + if (sla.page_type == SLA_PAGE_TYPE_SCATTER) { + struct sla_addr_t *scatter = sla_to_va(sla); + unsigned int i, npages = 0; + + for (i = 0; i < SLA_SCATTER_LEN(sla); ++i) { + if (WARN_ON_ONCE(SLA_SZ(scatter[i]) > SZ_4K)) + return NULL; + + if (WARN_ON_ONCE(scatter[i].page_type == SLA_PAGE_TYPE_SCATTER)) + return NULL; + + if (IS_SLA_EOL(scatter[i])) { + npages = i; + break; + } + } + if (WARN_ON_ONCE(!npages)) + return NULL; + + struct page **pp = kmalloc_array(npages, sizeof(pp[0]), GFP_KERNEL); + + if (!pp) + return NULL; + + for (i = 0; i < npages; ++i) + pp[i] = sla_to_page(scatter[i]); + + buf = vm_map_ram(pp, npages, 0); + kfree(pp); + } else { + struct page *pg = sla_to_page(sla); + + buf = vm_map_ram(&pg, 1, 0); + } + + return buf; +} + +static void sla_buffer_unmap(struct sla_addr_t sla, struct sla_buffer_hdr *buf) +{ + if (!buf) + return; + + if (sla.page_type == SLA_PAGE_TYPE_SCATTER) { + struct sla_addr_t *scatter = sla_to_va(sla); + unsigned int i, npages = 0; + + for (i = 0; i < SLA_SCATTER_LEN(sla); ++i) { + if (IS_SLA_EOL(scatter[i])) { + npages = i; + break; + } + } + if (!npages) + return; + + vm_unmap_ram(buf, npages); + } else { + vm_unmap_ram(buf, 1); + } +} + +static void dobj_response_init(struct sla_buffer_hdr *buf) +{ + struct spdm_dobj_hdr *dobj = sla_to_dobj_hdr(buf); + + dobj->id = SPDM_DOBJ_ID_RESP; + dobj->version.major = 0x1; + dobj->version.minor = 0; + dobj->length = 0; + buf->payload_sz = sla_dobj_id_to_size(dobj->id) + dobj->length; +} + +static void sla_free(struct sla_addr_t sla, size_t len, bool firmware_state) +{ + unsigned int npages = PAGE_ALIGN(len) >> PAGE_SHIFT; + struct sla_addr_t *scatter = NULL; + int ret = 0, i; + + if (IS_SLA_NULL(sla)) + return; + + if (firmware_state) { + if (sla.page_type == SLA_PAGE_TYPE_SCATTER) { + scatter = sla_to_va(sla); + + for (i = 0; i < npages; ++i) { + if (IS_SLA_EOL(scatter[i])) + break; + + ret = snp_reclaim_pages(sla_to_pa(scatter[i]), 1, false); + if (ret) + break; + } + } else { + ret = snp_reclaim_pages(sla_to_pa(sla), 1, false); + } + } + + if (WARN_ON(ret)) + return; + + if (scatter) { + for (i = 0; i < npages; ++i) { + if (IS_SLA_EOL(scatter[i])) + break; + free_page((unsigned long)sla_to_va(scatter[i])); + } + } + + free_page((unsigned long)sla_to_va(sla)); +} + +static struct sla_addr_t sla_alloc(size_t len, bool firmware_state) +{ + unsigned long i, npages = PAGE_ALIGN(len) >> PAGE_SHIFT; + struct sla_addr_t *scatter = NULL; + struct sla_addr_t ret = SLA_NULL; + struct sla_buffer_hdr *buf; + struct page *pg; + + if (npages == 0) + return ret; + + if (WARN_ON_ONCE(npages > ((PAGE_SIZE / sizeof(struct sla_addr_t)) + 1))) + return ret; + + BUILD_BUG_ON(PAGE_SIZE < SZ_4K); + + if (npages > 1) { + pg = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!pg) + return SLA_NULL; + + ret = make_sla(pg, true); + scatter = page_to_virt(pg); + for (i = 0; i < npages; ++i) { + pg = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!pg) + goto no_reclaim_exit; + + scatter[i] = make_sla(pg, false); + } + scatter[i] = SLA_EOL; + } else { + pg = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!pg) + return SLA_NULL; + + ret = make_sla(pg, false); + } + + buf = sla_buffer_map(ret); + if (!buf) + goto no_reclaim_exit; + + buf->capacity_sz = (npages << PAGE_SHIFT); + sla_buffer_unmap(ret, buf); + + if (firmware_state) { + if (scatter) { + for (i = 0; i < npages; ++i) { + if (rmp_make_private(sla_to_pfn(scatter[i]), 0, + PG_LEVEL_4K, 0, true)) + goto free_exit; + } + } else { + if (rmp_make_private(sla_to_pfn(ret), 0, PG_LEVEL_4K, 0, true)) + goto no_reclaim_exit; + } + } + + return ret; + +no_reclaim_exit: + firmware_state = false; +free_exit: + sla_free(ret, len, firmware_state); + return SLA_NULL; +} + +/* Expands a buffer, only firmware owned buffers allowed for now */ +static int sla_expand(struct sla_addr_t *sla, size_t *len) +{ + struct sla_buffer_hdr *oldbuf = sla_buffer_map(*sla), *newbuf; + struct sla_addr_t oldsla = *sla, newsla; + size_t oldlen = *len, newlen; + + if (!oldbuf) + return -EFAULT; + + newlen = oldbuf->capacity_sz; + if (oldbuf->capacity_sz == oldlen) { + /* This buffer does not require expansion, must be another buffer */ + sla_buffer_unmap(oldsla, oldbuf); + return 1; + } + + pr_notice("Expanding BUFFER from %ld to %ld bytes\n", oldlen, newlen); + + newsla = sla_alloc(newlen, true); + if (IS_SLA_NULL(newsla)) + return -ENOMEM; + + newbuf = sla_buffer_map(newsla); + if (!newbuf) { + sla_free(newsla, newlen, true); + return -EFAULT; + } + + memcpy(newbuf, oldbuf, oldlen); + + sla_buffer_unmap(newsla, newbuf); + sla_free(oldsla, oldlen, true); + *sla = newsla; + *len = newlen; + + return 0; +} + +static int sev_tio_do_cmd(int cmd, void *data, size_t data_len, int *psp_ret, + struct tsm_dsm_tio *dev_data) +{ + int rc; + + *psp_ret = 0; + rc = sev_do_cmd(cmd, data, psp_ret); + + if (WARN_ON(!rc && *psp_ret == SEV_RET_SPDM_REQUEST)) + return -EIO; + + if (rc == 0 && *psp_ret == SEV_RET_EXPAND_BUFFER_LENGTH_REQUEST) { + int rc1, rc2; + + rc1 = sla_expand(&dev_data->output, &dev_data->output_len); + if (rc1 < 0) + return rc1; + + rc2 = sla_expand(&dev_data->scratch, &dev_data->scratch_len); + if (rc2 < 0) + return rc2; + + if (!rc1 && !rc2) + /* Neither buffer requires expansion, this is wrong */ + return -EFAULT; + + *psp_ret = 0; + rc = sev_do_cmd(cmd, data, psp_ret); + } + + if ((rc == 0 || rc == -EIO) && *psp_ret == SEV_RET_SPDM_REQUEST) { + struct spdm_dobj_hdr_resp *resp_hdr; + struct spdm_dobj_hdr_req *req_hdr; + struct sev_tio_status *tio_status = to_tio_status(dev_data); + size_t resp_len = tio_status->spdm_req_size_max - + (sla_dobj_id_to_size(SPDM_DOBJ_ID_RESP) + sizeof(struct sla_buffer_hdr)); + + if (!dev_data->cmd) { + if (WARN_ON_ONCE(!data_len || (data_len != *(u32 *) data))) + return -EINVAL; + if (WARN_ON(data_len > sizeof(dev_data->cmd_data))) + return -EFAULT; + memcpy(dev_data->cmd_data, data, data_len); + memset(&dev_data->cmd_data[data_len], 0xFF, + sizeof(dev_data->cmd_data) - data_len); + dev_data->cmd = cmd; + } + + req_hdr = sla_to_dobj_req_hdr(dev_data->reqbuf); + resp_hdr = sla_to_dobj_resp_hdr(dev_data->respbuf); + switch (req_hdr->data_type) { + case DOBJ_DATA_TYPE_SPDM: + rc = PCI_DOE_FEATURE_CMA; + break; + case DOBJ_DATA_TYPE_SECURE_SPDM: + rc = PCI_DOE_FEATURE_SSESSION; + break; + default: + return -EINVAL; + } + resp_hdr->data_type = req_hdr->data_type; + dev_data->spdm.req_len = req_hdr->hdr.length - + sla_dobj_id_to_size(SPDM_DOBJ_ID_REQ); + dev_data->spdm.rsp_len = resp_len; + } else if (dev_data && dev_data->cmd) { + /* For either error or success just stop the bouncing */ + memset(dev_data->cmd_data, 0, sizeof(dev_data->cmd_data)); + dev_data->cmd = 0; + } + + return rc; +} + +int sev_tio_continue(struct tsm_dsm_tio *dev_data) +{ + struct spdm_dobj_hdr_resp *resp_hdr; + int ret; + + if (!dev_data || !dev_data->cmd) + return -EINVAL; + + resp_hdr = sla_to_dobj_resp_hdr(dev_data->respbuf); + resp_hdr->hdr.length = ALIGN(sla_dobj_id_to_size(SPDM_DOBJ_ID_RESP) + + dev_data->spdm.rsp_len, 32); + dev_data->respbuf->payload_sz = resp_hdr->hdr.length; + + ret = sev_tio_do_cmd(dev_data->cmd, dev_data->cmd_data, 0, + &dev_data->psp_ret, dev_data); + if (ret) + return ret; + + if (dev_data->psp_ret != SEV_RET_SUCCESS) + return -EINVAL; + + return 0; +} + +static void spdm_ctrl_init(struct spdm_ctrl *ctrl, struct tsm_dsm_tio *dev_data) +{ + ctrl->req = dev_data->req; + ctrl->resp = dev_data->resp; + ctrl->scratch = dev_data->scratch; + ctrl->output = dev_data->output; +} + +static void spdm_ctrl_free(struct tsm_dsm_tio *dev_data) +{ + struct sev_tio_status *tio_status = to_tio_status(dev_data); + size_t len = tio_status->spdm_req_size_max - + (sla_dobj_id_to_size(SPDM_DOBJ_ID_RESP) + + sizeof(struct sla_buffer_hdr)); + struct tsm_spdm *spdm = &dev_data->spdm; + + sla_buffer_unmap(dev_data->resp, dev_data->respbuf); + sla_buffer_unmap(dev_data->req, dev_data->reqbuf); + spdm->rsp = NULL; + spdm->req = NULL; + sla_free(dev_data->req, len, true); + sla_free(dev_data->resp, len, false); + sla_free(dev_data->scratch, tio_status->spdm_scratch_size_max, true); + + dev_data->req.sla = 0; + dev_data->resp.sla = 0; + dev_data->scratch.sla = 0; + dev_data->respbuf = NULL; + dev_data->reqbuf = NULL; + sla_free(dev_data->output, tio_status->spdm_out_size_max, true); +} + +static int spdm_ctrl_alloc(struct tsm_dsm_tio *dev_data) +{ + struct sev_tio_status *tio_status = to_tio_status(dev_data); + struct tsm_spdm *spdm = &dev_data->spdm; + int ret; + + dev_data->req = sla_alloc(tio_status->spdm_req_size_max, true); + dev_data->resp = sla_alloc(tio_status->spdm_req_size_max, false); + dev_data->scratch_len = tio_status->spdm_scratch_size_max; + dev_data->scratch = sla_alloc(dev_data->scratch_len, true); + dev_data->output_len = tio_status->spdm_out_size_max; + dev_data->output = sla_alloc(dev_data->output_len, true); + + if (IS_SLA_NULL(dev_data->req) || IS_SLA_NULL(dev_data->resp) || + IS_SLA_NULL(dev_data->scratch) || IS_SLA_NULL(dev_data->dev_ctx)) { + ret = -ENOMEM; + goto free_spdm_exit; + } + + dev_data->reqbuf = sla_buffer_map(dev_data->req); + dev_data->respbuf = sla_buffer_map(dev_data->resp); + if (!dev_data->reqbuf || !dev_data->respbuf) { + ret = -EFAULT; + goto free_spdm_exit; + } + + spdm->req = sla_to_data(dev_data->reqbuf, SPDM_DOBJ_ID_REQ); + spdm->rsp = sla_to_data(dev_data->respbuf, SPDM_DOBJ_ID_RESP); + if (!spdm->req || !spdm->rsp) { + ret = -EFAULT; + goto free_spdm_exit; + } + + dobj_response_init(dev_data->respbuf); + + return 0; + +free_spdm_exit: + spdm_ctrl_free(dev_data); + return ret; +} + +int sev_tio_init_locked(void *tio_status_page) +{ + struct sev_tio_status *tio_status = tio_status_page; + struct sev_data_tio_status data_status = { + .length = sizeof(data_status), + }; + int ret, psp_ret; + + data_status.status_paddr = __psp_pa(tio_status_page); + ret = __sev_do_cmd_locked(SEV_CMD_TIO_STATUS, &data_status, &psp_ret); + if (ret) + return ret; + + if (tio_status->length < offsetofend(struct sev_tio_status, tdictx_size) || + tio_status->reserved) + return -EFAULT; + + if (!tio_status->tio_en && !tio_status->tio_init_done) + return -ENOENT; + + if (tio_status->tio_init_done) + return -EBUSY; + + struct sev_data_tio_init ti = { .length = sizeof(ti) }; + + ret = __sev_do_cmd_locked(SEV_CMD_TIO_INIT, &ti, &psp_ret); + if (ret) + return ret; + + ret = __sev_do_cmd_locked(SEV_CMD_TIO_STATUS, &data_status, &psp_ret); + if (ret) + return ret; + + return 0; +} + +int sev_tio_dev_create(struct tsm_dsm_tio *dev_data, u16 device_id, + u16 root_port_id, u8 segment_id) +{ + struct sev_tio_status *tio_status = to_tio_status(dev_data); + struct sev_data_tio_dev_create create = { + .length = sizeof(create), + .device_id = device_id, + .root_port_id = root_port_id, + .segment_id = segment_id, + }; + void *data_pg; + int ret; + + dev_data->dev_ctx = sla_alloc(tio_status->devctx_size, true); + if (IS_SLA_NULL(dev_data->dev_ctx)) + return -ENOMEM; + + data_pg = snp_alloc_firmware_page(GFP_KERNEL_ACCOUNT); + if (!data_pg) { + ret = -ENOMEM; + goto free_ctx_exit; + } + + create.dev_ctx_sla = dev_data->dev_ctx; + ret = sev_do_cmd(SEV_CMD_TIO_DEV_CREATE, &create, &dev_data->psp_ret); + if (ret) + goto free_data_pg_exit; + + dev_data->data_pg = data_pg; + + return 0; + +free_data_pg_exit: + snp_free_firmware_page(data_pg); +free_ctx_exit: + sla_free(create.dev_ctx_sla, tio_status->devctx_size, true); + return ret; +} + +int sev_tio_dev_reclaim(struct tsm_dsm_tio *dev_data) +{ + struct sev_tio_status *tio_status = to_tio_status(dev_data); + struct sev_data_tio_dev_reclaim r = { + .length = sizeof(r), + .dev_ctx_sla = dev_data->dev_ctx, + }; + int ret; + + if (dev_data->data_pg) { + snp_free_firmware_page(dev_data->data_pg); + dev_data->data_pg = NULL; + } + + if (IS_SLA_NULL(dev_data->dev_ctx)) + return 0; + + ret = sev_do_cmd(SEV_CMD_TIO_DEV_RECLAIM, &r, &dev_data->psp_ret); + + sla_free(dev_data->dev_ctx, tio_status->devctx_size, true); + dev_data->dev_ctx = SLA_NULL; + + spdm_ctrl_free(dev_data); + + return ret; +} + +int sev_tio_dev_connect(struct tsm_dsm_tio *dev_data, u8 tc_mask, u8 ids[8], u8 cert_slot) +{ + struct sev_data_tio_dev_connect connect = { + .length = sizeof(connect), + .tc_mask = tc_mask, + .cert_slot = cert_slot, + .dev_ctx_sla = dev_data->dev_ctx, + .ide_stream_id = { + ids[0], ids[1], ids[2], ids[3], + ids[4], ids[5], ids[6], ids[7] + }, + }; + int ret; + + if (WARN_ON(IS_SLA_NULL(dev_data->dev_ctx))) + return -EFAULT; + if (!(tc_mask & 1)) + return -EINVAL; + + ret = spdm_ctrl_alloc(dev_data); + if (ret) + return ret; + + spdm_ctrl_init(&connect.spdm_ctrl, dev_data); + + return sev_tio_do_cmd(SEV_CMD_TIO_DEV_CONNECT, &connect, sizeof(connect), + &dev_data->psp_ret, dev_data); +} + +int sev_tio_dev_disconnect(struct tsm_dsm_tio *dev_data, bool force) +{ + struct sev_data_tio_dev_disconnect dc = { + .length = sizeof(dc), + .dev_ctx_sla = dev_data->dev_ctx, + .flags = force ? TIO_DEV_DISCONNECT_FLAG_FORCE : 0, + }; + + if (WARN_ON_ONCE(IS_SLA_NULL(dev_data->dev_ctx))) + return -EFAULT; + + spdm_ctrl_init(&dc.spdm_ctrl, dev_data); + + return sev_tio_do_cmd(SEV_CMD_TIO_DEV_DISCONNECT, &dc, sizeof(dc), + &dev_data->psp_ret, dev_data); +} + +int sev_tio_cmd_buffer_len(int cmd) +{ + switch (cmd) { + case SEV_CMD_TIO_STATUS: return sizeof(struct sev_data_tio_status); + case SEV_CMD_TIO_INIT: return sizeof(struct sev_data_tio_init); + case SEV_CMD_TIO_DEV_CREATE: return sizeof(struct sev_data_tio_dev_create); + case SEV_CMD_TIO_DEV_RECLAIM: return sizeof(struct sev_data_tio_dev_reclaim); + case SEV_CMD_TIO_DEV_CONNECT: return sizeof(struct sev_data_tio_dev_connect); + case SEV_CMD_TIO_DEV_DISCONNECT: return sizeof(struct sev_data_tio_dev_disconnect); + default: return 0; + } +} diff --git a/drivers/crypto/ccp/sev-dev-tio.h b/drivers/crypto/ccp/sev-dev-tio.h new file mode 100644 index 0000000000000..67512b3dbc538 --- /dev/null +++ b/drivers/crypto/ccp/sev-dev-tio.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __PSP_SEV_TIO_H__ +#define __PSP_SEV_TIO_H__ + +#include +#include +#include +#include + +struct sla_addr_t { + union { + u64 sla; + struct { + u64 page_type :1, + page_size :1, + reserved1 :10, + pfn :40, + reserved2 :12; + }; + }; +} __packed; + +#define SEV_TIO_MAX_COMMAND_LENGTH 128 + +/* SPDM control structure for DOE */ +struct tsm_spdm { + unsigned long req_len; + void *req; + unsigned long rsp_len; + void *rsp; +}; + +/* Describes TIO device */ +struct tsm_dsm_tio { + u8 cert_slot; + struct sla_addr_t dev_ctx; + struct sla_addr_t req; + struct sla_addr_t resp; + struct sla_addr_t scratch; + struct sla_addr_t output; + size_t output_len; + size_t scratch_len; + struct tsm_spdm spdm; + struct sla_buffer_hdr *reqbuf; /* vmap'ed @req for DOE */ + struct sla_buffer_hdr *respbuf; /* vmap'ed @resp for DOE */ + + int cmd; + int psp_ret; + u8 cmd_data[SEV_TIO_MAX_COMMAND_LENGTH]; + void *data_pg; /* Data page for DEV_STATUS/TDI_STATUS/TDI_INFO/ASID_FENCE */ + +#define TIO_IDE_MAX_TC 8 + struct pci_ide *ide[TIO_IDE_MAX_TC]; +}; + +/* Describes TSM structure for PF0 pointed by pci_dev->tsm */ +struct tio_dsm { + struct pci_tsm_pf0 tsm; + struct tsm_dsm_tio data; + struct sev_device *sev; +}; + +/* Data object IDs */ +#define SPDM_DOBJ_ID_NONE 0 +#define SPDM_DOBJ_ID_REQ 1 +#define SPDM_DOBJ_ID_RESP 2 + +struct spdm_dobj_hdr { + u32 id; /* Data object type identifier */ + u32 length; /* Length of the data object, INCLUDING THIS HEADER */ + struct { /* Version of the data object structure */ + u8 minor; + u8 major; + } version; +} __packed; + +/** + * struct sev_tio_status - TIO_STATUS command's info_paddr buffer + * + * @length: Length of this structure in bytes + * @tio_en: Indicates that SNP_INIT_EX initialized the RMP for SEV-TIO + * @tio_init_done: Indicates TIO_INIT has been invoked + * @spdm_req_size_min: Minimum SPDM request buffer size in bytes + * @spdm_req_size_max: Maximum SPDM request buffer size in bytes + * @spdm_scratch_size_min: Minimum SPDM scratch buffer size in bytes + * @spdm_scratch_size_max: Maximum SPDM scratch buffer size in bytes + * @spdm_out_size_min: Minimum SPDM output buffer size in bytes + * @spdm_out_size_max: Maximum for the SPDM output buffer size in bytes + * @spdm_rsp_size_min: Minimum SPDM response buffer size in bytes + * @spdm_rsp_size_max: Maximum SPDM response buffer size in bytes + * @devctx_size: Size of a device context buffer in bytes + * @tdictx_size: Size of a TDI context buffer in bytes + * @tio_crypto_alg: TIO crypto algorithms supported + */ +struct sev_tio_status { + u32 length; + u32 tio_en :1, + tio_init_done :1, + reserved :30; + u32 spdm_req_size_min; + u32 spdm_req_size_max; + u32 spdm_scratch_size_min; + u32 spdm_scratch_size_max; + u32 spdm_out_size_min; + u32 spdm_out_size_max; + u32 spdm_rsp_size_min; + u32 spdm_rsp_size_max; + u32 devctx_size; + u32 tdictx_size; + u32 tio_crypto_alg; + u8 reserved2[12]; +} __packed; + +int sev_tio_init_locked(void *tio_status_page); +int sev_tio_continue(struct tsm_dsm_tio *dev_data); + +int sev_tio_dev_create(struct tsm_dsm_tio *dev_data, u16 device_id, u16 root_port_id, + u8 segment_id); +int sev_tio_dev_connect(struct tsm_dsm_tio *dev_data, u8 tc_mask, u8 ids[8], u8 cert_slot); +int sev_tio_dev_disconnect(struct tsm_dsm_tio *dev_data, bool force); +int sev_tio_dev_reclaim(struct tsm_dsm_tio *dev_data); + +#endif /* __PSP_SEV_TIO_H__ */ diff --git a/drivers/crypto/ccp/sev-dev-tsm.c b/drivers/crypto/ccp/sev-dev-tsm.c new file mode 100644 index 0000000000000..ea29cd5d0ff9f --- /dev/null +++ b/drivers/crypto/ccp/sev-dev-tsm.c @@ -0,0 +1,405 @@ +// SPDX-License-Identifier: GPL-2.0-only + +// Interface to CCP/SEV-TIO for generic PCIe TDISP module + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "psp-dev.h" +#include "sev-dev.h" +#include "sev-dev-tio.h" + +MODULE_IMPORT_NS("PCI_IDE"); + +#define TIO_DEFAULT_NR_IDE_STREAMS 1 + +static uint nr_ide_streams = TIO_DEFAULT_NR_IDE_STREAMS; +module_param_named(ide_nr, nr_ide_streams, uint, 0644); +MODULE_PARM_DESC(ide_nr, "Set the maximum number of IDE streams per PHB"); + +#define dev_to_sp(dev) ((struct sp_device *)dev_get_drvdata(dev)) +#define dev_to_psp(dev) ((struct psp_device *)(dev_to_sp(dev)->psp_data)) +#define dev_to_sev(dev) ((struct sev_device *)(dev_to_psp(dev)->sev_data)) +#define tsm_dev_to_sev(tsmdev) dev_to_sev((tsmdev)->dev.parent) + +#define pdev_to_tio_dsm(pdev) (container_of((pdev)->tsm, struct tio_dsm, tsm.base_tsm)) + +static int sev_tio_spdm_cmd(struct tio_dsm *dsm, int ret) +{ + struct tsm_dsm_tio *dev_data = &dsm->data; + struct tsm_spdm *spdm = &dev_data->spdm; + + /* Check the main command handler response before entering the loop */ + if (ret == 0 && dev_data->psp_ret != SEV_RET_SUCCESS) + return -EINVAL; + + if (ret <= 0) + return ret; + + /* ret > 0 means "SPDM requested" */ + while (ret == PCI_DOE_FEATURE_CMA || ret == PCI_DOE_FEATURE_SSESSION) { + ret = pci_doe(dsm->tsm.doe_mb, PCI_VENDOR_ID_PCI_SIG, ret, + spdm->req, spdm->req_len, spdm->rsp, spdm->rsp_len); + if (ret < 0) + break; + + WARN_ON_ONCE(ret == 0); /* The response should never be empty */ + spdm->rsp_len = ret; + ret = sev_tio_continue(dev_data); + } + + return ret; +} + +static int stream_enable(struct pci_ide *ide) +{ + struct pci_dev *rp = pcie_find_root_port(ide->pdev); + int ret; + + ret = pci_ide_stream_enable(rp, ide); + if (ret) + return ret; + + ret = pci_ide_stream_enable(ide->pdev, ide); + if (ret) + pci_ide_stream_disable(rp, ide); + + return ret; +} + +static int streams_enable(struct pci_ide **ide) +{ + int ret = 0; + + for (int i = 0; i < TIO_IDE_MAX_TC; ++i) { + if (ide[i]) { + ret = stream_enable(ide[i]); + if (ret) + break; + } + } + + return ret; +} + +static void stream_disable(struct pci_ide *ide) +{ + pci_ide_stream_disable(ide->pdev, ide); + pci_ide_stream_disable(pcie_find_root_port(ide->pdev), ide); +} + +static void streams_disable(struct pci_ide **ide) +{ + for (int i = 0; i < TIO_IDE_MAX_TC; ++i) + if (ide[i]) + stream_disable(ide[i]); +} + +static void stream_setup(struct pci_ide *ide) +{ + struct pci_dev *rp = pcie_find_root_port(ide->pdev); + + ide->partner[PCI_IDE_EP].rid_start = 0; + ide->partner[PCI_IDE_EP].rid_end = 0xffff; + ide->partner[PCI_IDE_RP].rid_start = 0; + ide->partner[PCI_IDE_RP].rid_end = 0xffff; + + ide->pdev->ide_cfg = 0; + ide->pdev->ide_tee_limit = 1; + rp->ide_cfg = 1; + rp->ide_tee_limit = 0; + + pci_warn(ide->pdev, "Forcing CFG/TEE for %s", pci_name(rp)); + pci_ide_stream_setup(ide->pdev, ide); + pci_ide_stream_setup(rp, ide); +} + +static u8 streams_setup(struct pci_ide **ide, u8 *ids) +{ + bool def = false; + u8 tc_mask = 0; + int i; + + for (i = 0; i < TIO_IDE_MAX_TC; ++i) { + if (!ide[i]) { + ids[i] = 0xFF; + continue; + } + + tc_mask |= BIT(i); + ids[i] = ide[i]->stream_id; + + if (!def) { + struct pci_ide_partner *settings; + + settings = pci_ide_to_settings(ide[i]->pdev, ide[i]); + settings->default_stream = 1; + def = true; + } + + stream_setup(ide[i]); + } + + return tc_mask; +} + +static int streams_register(struct pci_ide **ide) +{ + int ret = 0, i; + + for (i = 0; i < TIO_IDE_MAX_TC; ++i) { + if (ide[i]) { + ret = pci_ide_stream_register(ide[i]); + if (ret) + break; + } + } + + return ret; +} + +static void streams_unregister(struct pci_ide **ide) +{ + for (int i = 0; i < TIO_IDE_MAX_TC; ++i) + if (ide[i]) + pci_ide_stream_unregister(ide[i]); +} + +static void stream_teardown(struct pci_ide *ide) +{ + pci_ide_stream_teardown(ide->pdev, ide); + pci_ide_stream_teardown(pcie_find_root_port(ide->pdev), ide); +} + +static void streams_teardown(struct pci_ide **ide) +{ + for (int i = 0; i < TIO_IDE_MAX_TC; ++i) { + if (ide[i]) { + stream_teardown(ide[i]); + pci_ide_stream_free(ide[i]); + ide[i] = NULL; + } + } +} + +static int stream_alloc(struct pci_dev *pdev, struct pci_ide **ide, + unsigned int tc) +{ + struct pci_dev *rp = pcie_find_root_port(pdev); + struct pci_ide *ide1; + + if (ide[tc]) { + pci_err(pdev, "Stream for class=%d already registered", tc); + return -EBUSY; + } + + /* FIXME: find a better way */ + if (nr_ide_streams != TIO_DEFAULT_NR_IDE_STREAMS) + pci_notice(pdev, "Enable non-default %d streams", nr_ide_streams); + pci_ide_set_nr_streams(to_pci_host_bridge(rp->bus->bridge), nr_ide_streams); + + ide1 = pci_ide_stream_alloc(pdev); + if (!ide1) + return -EFAULT; + + /* Blindly assign streamid=0 to TC=0, and so on */ + ide1->stream_id = tc; + + ide[tc] = ide1; + + return 0; +} + +static struct pci_tsm *tio_pf0_probe(struct pci_dev *pdev, struct sev_device *sev) +{ + struct tio_dsm *dsm __free(kfree) = kzalloc(sizeof(*dsm), GFP_KERNEL); + int rc; + + if (!dsm) + return NULL; + + rc = pci_tsm_pf0_constructor(pdev, &dsm->tsm, sev->tsmdev); + if (rc) + return NULL; + + pci_dbg(pdev, "TSM enabled\n"); + dsm->sev = sev; + return &no_free_ptr(dsm)->tsm.base_tsm; +} + +static struct pci_tsm *dsm_probe(struct tsm_dev *tsmdev, struct pci_dev *pdev) +{ + struct sev_device *sev = tsm_dev_to_sev(tsmdev); + + if (is_pci_tsm_pf0(pdev)) + return tio_pf0_probe(pdev, sev); + return 0; +} + +static void dsm_remove(struct pci_tsm *tsm) +{ + struct pci_dev *pdev = tsm->pdev; + + pci_dbg(pdev, "TSM disabled\n"); + + if (is_pci_tsm_pf0(pdev)) { + struct tio_dsm *dsm = container_of(tsm, struct tio_dsm, tsm.base_tsm); + + pci_tsm_pf0_destructor(&dsm->tsm); + kfree(dsm); + } +} + +static int dsm_create(struct tio_dsm *dsm) +{ + struct pci_dev *pdev = dsm->tsm.base_tsm.pdev; + u8 segment_id = pdev->bus ? pci_domain_nr(pdev->bus) : 0; + struct pci_dev *rootport = pcie_find_root_port(pdev); + u16 device_id = pci_dev_id(pdev); + u16 root_port_id; + u32 lnkcap = 0; + + if (pci_read_config_dword(rootport, pci_pcie_cap(rootport) + PCI_EXP_LNKCAP, + &lnkcap)) + return -ENODEV; + + root_port_id = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap); + + return sev_tio_dev_create(&dsm->data, device_id, root_port_id, segment_id); +} + +static int dsm_connect(struct pci_dev *pdev) +{ + struct tio_dsm *dsm = pdev_to_tio_dsm(pdev); + struct tsm_dsm_tio *dev_data = &dsm->data; + u8 ids[TIO_IDE_MAX_TC]; + u8 tc_mask; + int ret; + + if (pci_find_doe_mailbox(pdev, PCI_VENDOR_ID_PCI_SIG, + PCI_DOE_FEATURE_SSESSION) != dsm->tsm.doe_mb) { + pci_err(pdev, "CMA DOE MB must support SSESSION\n"); + return -EFAULT; + } + + ret = stream_alloc(pdev, dev_data->ide, 0); + if (ret) + return ret; + + ret = dsm_create(dsm); + if (ret) + goto ide_free_exit; + + tc_mask = streams_setup(dev_data->ide, ids); + + ret = sev_tio_dev_connect(dev_data, tc_mask, ids, dev_data->cert_slot); + ret = sev_tio_spdm_cmd(dsm, ret); + if (ret) + goto free_exit; + + streams_enable(dev_data->ide); + + ret = streams_register(dev_data->ide); + if (ret) + goto free_exit; + + return 0; + +free_exit: + sev_tio_dev_reclaim(dev_data); + + streams_disable(dev_data->ide); +ide_free_exit: + + streams_teardown(dev_data->ide); + + return ret; +} + +static void dsm_disconnect(struct pci_dev *pdev) +{ + bool force = SYSTEM_HALT <= system_state && system_state <= SYSTEM_RESTART; + struct tio_dsm *dsm = pdev_to_tio_dsm(pdev); + struct tsm_dsm_tio *dev_data = &dsm->data; + int ret; + + ret = sev_tio_dev_disconnect(dev_data, force); + ret = sev_tio_spdm_cmd(dsm, ret); + if (ret && !force) { + ret = sev_tio_dev_disconnect(dev_data, true); + sev_tio_spdm_cmd(dsm, ret); + } + + sev_tio_dev_reclaim(dev_data); + + streams_disable(dev_data->ide); + streams_unregister(dev_data->ide); + streams_teardown(dev_data->ide); +} + +static struct pci_tsm_ops sev_tsm_ops = { + .probe = dsm_probe, + .remove = dsm_remove, + .connect = dsm_connect, + .disconnect = dsm_disconnect, +}; + +void sev_tsm_init_locked(struct sev_device *sev, void *tio_status_page) +{ + struct sev_tio_status *t = kzalloc(sizeof(*t), GFP_KERNEL); + struct tsm_dev *tsmdev; + int ret; + + WARN_ON(sev->tio_status); + + if (!t) + return; + + ret = sev_tio_init_locked(tio_status_page); + if (ret) { + pr_warn("SEV-TIO STATUS failed with %d\n", ret); + goto error_exit; + } + + tsmdev = tsm_register(sev->dev, &sev_tsm_ops); + if (IS_ERR(tsmdev)) + goto error_exit; + + memcpy(t, tio_status_page, sizeof(*t)); + + pr_notice("SEV-TIO status: EN=%d INIT_DONE=%d rq=%d..%d rs=%d..%d " + "scr=%d..%d out=%d..%d dev=%d tdi=%d algos=%x\n", + t->tio_en, t->tio_init_done, + t->spdm_req_size_min, t->spdm_req_size_max, + t->spdm_rsp_size_min, t->spdm_rsp_size_max, + t->spdm_scratch_size_min, t->spdm_scratch_size_max, + t->spdm_out_size_min, t->spdm_out_size_max, + t->devctx_size, t->tdictx_size, + t->tio_crypto_alg); + + sev->tsmdev = tsmdev; + sev->tio_status = t; + + return; + +error_exit: + kfree(t); + pr_err("Failed to enable SEV-TIO: ret=%d en=%d initdone=%d SEV=%d\n", + ret, t->tio_en, t->tio_init_done, boot_cpu_has(X86_FEATURE_SEV)); +} + +void sev_tsm_uninit(struct sev_device *sev) +{ + if (sev->tsmdev) + tsm_unregister(sev->tsmdev); + + sev->tsmdev = NULL; +} diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index b28a6f50daaaa..956ea609d0cce 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -75,6 +75,14 @@ static bool psp_init_on_probe = true; module_param(psp_init_on_probe, bool, 0444); MODULE_PARM_DESC(psp_init_on_probe, " if true, the PSP will be initialized on module init. Else the PSP will be initialized on the first command requiring it"); +#if IS_ENABLED(CONFIG_PCI_TSM) +static bool sev_tio_enabled = true; +module_param_named(tio, sev_tio_enabled, bool, 0444); +MODULE_PARM_DESC(tio, "Enables TIO in SNP_INIT_EX"); +#else +static const bool sev_tio_enabled = false; +#endif + MODULE_FIRMWARE("amd/amd_sev_fam17h_model0xh.sbin"); /* 1st gen EPYC */ MODULE_FIRMWARE("amd/amd_sev_fam17h_model3xh.sbin"); /* 2nd gen EPYC */ MODULE_FIRMWARE("amd/amd_sev_fam19h_model0xh.sbin"); /* 3rd gen EPYC */ @@ -251,7 +259,7 @@ static int sev_cmd_buffer_len(int cmd) case SEV_CMD_SNP_COMMIT: return sizeof(struct sev_data_snp_commit); case SEV_CMD_SNP_FEATURE_INFO: return sizeof(struct sev_data_snp_feature_info); case SEV_CMD_SNP_VLEK_LOAD: return sizeof(struct sev_user_data_snp_vlek_load); - default: return 0; + default: return sev_tio_cmd_buffer_len(cmd); } return 0; @@ -380,13 +388,7 @@ static int sev_write_init_ex_file_if_required(int cmd_id) return sev_write_init_ex_file(); } -/* - * snp_reclaim_pages() needs __sev_do_cmd_locked(), and __sev_do_cmd_locked() - * needs snp_reclaim_pages(), so a forward declaration is needed. - */ -static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret); - -static int snp_reclaim_pages(unsigned long paddr, unsigned int npages, bool locked) +int snp_reclaim_pages(unsigned long paddr, unsigned int npages, bool locked) { int ret, err, i; @@ -420,6 +422,7 @@ static int snp_reclaim_pages(unsigned long paddr, unsigned int npages, bool lock snp_leak_pages(__phys_to_pfn(paddr), npages - i); return ret; } +EXPORT_SYMBOL_GPL(snp_reclaim_pages); static int rmp_mark_pages_firmware(unsigned long paddr, unsigned int npages, bool locked) { @@ -850,7 +853,7 @@ static int snp_reclaim_cmd_buf(int cmd, void *cmd_buf) return 0; } -static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) +int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) { struct cmd_buf_desc desc_list[CMD_BUF_DESC_MAX] = {0}; struct psp_device *psp = psp_master; @@ -1392,6 +1395,8 @@ static int __sev_snp_init_locked(int *error, unsigned int max_snp_asid) * */ if (sev_version_greater_or_equal(SNP_MIN_API_MAJOR, 52)) { + bool tio_supp = !!(sev->snp_feat_info_0.ebx & SNP_SEV_TIO_SUPPORTED); + /* * Firmware checks that the pages containing the ranges enumerated * in the RANGES structure are either in the default page state or in the @@ -1432,6 +1437,17 @@ static int __sev_snp_init_locked(int *error, unsigned int max_snp_asid) data.init_rmp = 1; data.list_paddr_en = 1; data.list_paddr = __psp_pa(snp_range_list); + + data.tio_en = tio_supp && sev_tio_enabled && amd_iommu_sev_tio_supported(); + + /* + * When psp_init_on_probe is disabled, the userspace calling + * SEV ioctl can inadvertently shut down SNP and SEV-TIO causing + * unexpected state loss. + */ + if (data.tio_en && !psp_init_on_probe) + dev_warn(sev->dev, "SEV-TIO as incompatible with psp_init_on_probe=0\n"); + cmd = SEV_CMD_SNP_INIT_EX; } else { cmd = SEV_CMD_SNP_INIT; @@ -1469,7 +1485,8 @@ static int __sev_snp_init_locked(int *error, unsigned int max_snp_asid) snp_hv_fixed_pages_state_update(sev, HV_FIXED); sev->snp_initialized = true; - dev_dbg(sev->dev, "SEV-SNP firmware initialized\n"); + dev_dbg(sev->dev, "SEV-SNP firmware initialized, SEV-TIO is %s\n", + data.tio_en ? "enabled" : "disabled"); dev_info(sev->dev, "SEV-SNP API:%d.%d build:%d\n", sev->api_major, sev->api_minor, sev->build); @@ -1477,6 +1494,23 @@ static int __sev_snp_init_locked(int *error, unsigned int max_snp_asid) atomic_notifier_chain_register(&panic_notifier_list, &snp_panic_notifier); + if (data.tio_en) { + /* + * This executes with the sev_cmd_mutex held so down the stack + * snp_reclaim_pages(locked=false) might be needed (which is extremely + * unlikely) but will cause a deadlock. + * Instead of exporting __snp_alloc_firmware_pages(), allocate a page + * for this one call here. + */ + void *tio_status = page_address(__snp_alloc_firmware_pages( + GFP_KERNEL_ACCOUNT | __GFP_ZERO, 0, true)); + + if (tio_status) { + sev_tsm_init_locked(sev, tio_status); + __snp_free_firmware_pages(virt_to_page(tio_status), 0, true); + } + } + sev_es_tmr_size = SNP_TMR_SIZE; return 0; @@ -2756,8 +2790,20 @@ static void __sev_firmware_shutdown(struct sev_device *sev, bool panic) static void sev_firmware_shutdown(struct sev_device *sev) { + /* + * Calling without sev_cmd_mutex held as TSM will likely try disconnecting + * IDE and this ends up calling sev_do_cmd() which locks sev_cmd_mutex. + */ + if (sev->tio_status) + sev_tsm_uninit(sev); + mutex_lock(&sev_cmd_mutex); + __sev_firmware_shutdown(sev, false); + + kfree(sev->tio_status); + sev->tio_status = NULL; + mutex_unlock(&sev_cmd_mutex); } @@ -2770,6 +2816,43 @@ void sev_platform_shutdown(void) } EXPORT_SYMBOL_GPL(sev_platform_shutdown); +u64 sev_get_snp_policy_bits(void) +{ + struct psp_device *psp = psp_master; + struct sev_device *sev; + u64 policy_bits; + + if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) + return 0; + + if (!psp || !psp->sev_data) + return 0; + + sev = psp->sev_data; + + policy_bits = SNP_POLICY_MASK_BASE; + + if (sev->snp_plat_status.feature_info) { + if (sev->snp_feat_info_0.ecx & SNP_RAPL_DISABLE_SUPPORTED) + policy_bits |= SNP_POLICY_MASK_RAPL_DIS; + + if (sev->snp_feat_info_0.ecx & SNP_CIPHER_TEXT_HIDING_SUPPORTED) + policy_bits |= SNP_POLICY_MASK_CIPHERTEXT_HIDING_DRAM; + + if (sev->snp_feat_info_0.ecx & SNP_AES_256_XTS_POLICY_SUPPORTED) + policy_bits |= SNP_POLICY_MASK_MEM_AES_256_XTS; + + if (sev->snp_feat_info_0.ecx & SNP_CXL_ALLOW_POLICY_SUPPORTED) + policy_bits |= SNP_POLICY_MASK_CXL_ALLOW; + + if (sev_version_greater_or_equal(1, 58)) + policy_bits |= SNP_POLICY_MASK_PAGE_SWAP_DISABLE; + } + + return policy_bits; +} +EXPORT_SYMBOL_GPL(sev_get_snp_policy_bits); + void sev_dev_destroy(struct psp_device *psp) { struct sev_device *sev = psp->sev_data; diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h index ac03bd0848f74..b1cd556bbbf65 100644 --- a/drivers/crypto/ccp/sev-dev.h +++ b/drivers/crypto/ccp/sev-dev.h @@ -34,6 +34,8 @@ struct sev_misc_dev { struct miscdevice misc; }; +struct sev_tio_status; + struct sev_device { struct device *dev; struct psp_device *psp; @@ -61,15 +63,24 @@ struct sev_device { struct sev_user_data_snp_status snp_plat_status; struct snp_feature_info snp_feat_info_0; + + struct tsm_dev *tsmdev; + struct sev_tio_status *tio_status; }; int sev_dev_init(struct psp_device *psp); void sev_dev_destroy(struct psp_device *psp); +int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret); + void sev_pci_init(void); void sev_pci_exit(void); struct page *snp_alloc_hv_fixed_pages(unsigned int num_2mb_pages); void snp_free_hv_fixed_pages(struct page *page); +void sev_tsm_init_locked(struct sev_device *sev, void *tio_status_page); +void sev_tsm_uninit(struct sev_device *sev); +int sev_tio_cmd_buffer_len(int cmd); + #endif /* __SEV_DEV_H */ diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index be25ecbdba695..f8bfff5dd0bde 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -3032,11 +3032,36 @@ static void qm_put_pci_res(struct hisi_qm *qm) pci_release_mem_regions(pdev); } +static void hisi_mig_region_clear(struct hisi_qm *qm) +{ + u32 val; + + /* Clear migration region set of PF */ + if (qm->fun_type == QM_HW_PF && qm->ver > QM_HW_V3) { + val = readl(qm->io_base + QM_MIG_REGION_SEL); + val &= ~QM_MIG_REGION_EN; + writel(val, qm->io_base + QM_MIG_REGION_SEL); + } +} + +static void hisi_mig_region_enable(struct hisi_qm *qm) +{ + u32 val; + + /* Select migration region of PF */ + if (qm->fun_type == QM_HW_PF && qm->ver > QM_HW_V3) { + val = readl(qm->io_base + QM_MIG_REGION_SEL); + val |= QM_MIG_REGION_EN; + writel(val, qm->io_base + QM_MIG_REGION_SEL); + } +} + static void hisi_qm_pci_uninit(struct hisi_qm *qm) { struct pci_dev *pdev = qm->pdev; pci_free_irq_vectors(pdev); + hisi_mig_region_clear(qm); qm_put_pci_res(qm); pci_disable_device(pdev); } @@ -5752,6 +5777,7 @@ int hisi_qm_init(struct hisi_qm *qm) goto err_free_qm_memory; qm_cmd_init(qm); + hisi_mig_region_enable(qm); return 0; @@ -5890,6 +5916,7 @@ static int qm_rebuild_for_resume(struct hisi_qm *qm) } qm_cmd_init(qm); + hisi_mig_region_enable(qm); hisi_qm_dev_err_init(qm); /* Set the doorbell timeout to QM_DB_TIMEOUT_CFG ns. */ writel(QM_DB_TIMEOUT_SET, qm->io_base + QM_DB_TIMEOUT_CFG); diff --git a/drivers/crypto/intel/qat/qat_common/adf_aer.c b/drivers/crypto/intel/qat/qat_common/adf_aer.c index 667d5e320f509..11728cf32653c 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_aer.c +++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c @@ -105,7 +105,6 @@ void adf_dev_restore(struct adf_accel_dev *accel_dev) accel_dev->accel_id); hw_device->reset_device(accel_dev); pci_restore_state(pdev); - pci_save_state(pdev); } } @@ -204,7 +203,6 @@ static pci_ers_result_t adf_slot_reset(struct pci_dev *pdev) 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; diff --git a/drivers/crypto/intel/qat/qat_common/adf_pm_dbgfs_utils.c b/drivers/crypto/intel/qat/qat_common/adf_pm_dbgfs_utils.c index 69295a9ddf0ac..4ccc94ed9493a 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_pm_dbgfs_utils.c +++ b/drivers/crypto/intel/qat/qat_common/adf_pm_dbgfs_utils.c @@ -1,18 +1,12 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright(c) 2025 Intel Corporation */ +#include #include #include #include #include "adf_pm_dbgfs_utils.h" -/* - * This is needed because a variable is used to index the mask at - * pm_scnprint_table(), making it not compile time constant, so the compile - * asserts from FIELD_GET() or u32_get_bits() won't be fulfilled. - */ -#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) - #define PM_INFO_MAX_KEY_LEN 21 static int pm_scnprint_table(char *buff, const struct pm_status_row *table, diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index bd2e282ca93a0..77ac940e30138 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -11,25 +11,36 @@ #include "cxlpci.h" #include "cxl.h" -struct cxl_cxims_data { - int nr_maps; - u64 xormaps[] __counted_by(nr_maps); -}; - static const guid_t acpi_cxl_qtg_id_guid = GUID_INIT(0xF365F9A6, 0xA7DE, 0x4071, 0xA6, 0x6A, 0xB4, 0x0C, 0x0B, 0x4F, 0x8E, 0x52); -static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr) +#define HBIW_TO_NR_MAPS_SIZE (CXL_DECODER_MAX_INTERLEAVE + 1) +static const int hbiw_to_nr_maps[HBIW_TO_NR_MAPS_SIZE] = { + [1] = 0, [2] = 1, [3] = 0, [4] = 2, [6] = 1, [8] = 3, [12] = 2, [16] = 4 +}; + +static const int valid_hbiw[] = { 1, 2, 3, 4, 6, 8, 12, 16 }; + +u64 cxl_do_xormap_calc(struct cxl_cxims_data *cximsd, u64 addr, int hbiw) { - struct cxl_cxims_data *cximsd = cxlrd->platform_data; - int hbiw = cxlrd->cxlsd.nr_targets; + int nr_maps_to_apply = -1; u64 val; int pos; - /* No xormaps for host bridge interleave ways of 1 or 3 */ - if (hbiw == 1 || hbiw == 3) - return addr; + /* + * Strictly validate hbiw since this function is used for testing and + * that nullifies any expectation of trusted parameters from the CXL + * Region Driver. + */ + for (int i = 0; i < ARRAY_SIZE(valid_hbiw); i++) { + if (valid_hbiw[i] == hbiw) { + nr_maps_to_apply = hbiw_to_nr_maps[hbiw]; + break; + } + } + if (nr_maps_to_apply == -1 || nr_maps_to_apply > cximsd->nr_maps) + return ULLONG_MAX; /* * In regions using XOR interleave arithmetic the CXL HPA may not @@ -60,6 +71,14 @@ static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr) return addr; } +EXPORT_SYMBOL_FOR_MODULES(cxl_do_xormap_calc, "cxl_translate"); + +static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr) +{ + struct cxl_cxims_data *cximsd = cxlrd->platform_data; + + return cxl_do_xormap_calc(cximsd, addr, cxlrd->cxlsd.nr_targets); +} struct cxl_cxims_context { struct device *dev; @@ -353,7 +372,7 @@ static int cxl_acpi_set_cache_size(struct cxl_root_decoder *cxlrd) rc = hmat_get_extended_linear_cache_size(&res, nid, &cache_size); if (rc) - return rc; + return 0; /* * The cache range is expected to be within the CFMWS. @@ -378,21 +397,18 @@ static void cxl_setup_extended_linear_cache(struct cxl_root_decoder *cxlrd) int rc; rc = cxl_acpi_set_cache_size(cxlrd); - if (!rc) - return; - - if (rc != -EOPNOTSUPP) { + if (rc) { /* - * Failing to support extended linear cache region resize does not + * Failing to retrieve extended linear cache region resize does not * prevent the region from functioning. Only causes cxl list showing * incorrect region size. */ dev_warn(cxlrd->cxlsd.cxld.dev.parent, - "Extended linear cache calculation failed rc:%d\n", rc); - } + "Extended linear cache retrieval failed rc:%d\n", rc); - /* Ignoring return code */ - cxlrd->cache_size = 0; + /* Ignoring return code */ + cxlrd->cache_size = 0; + } } DEFINE_FREE(put_cxlrd, struct cxl_root_decoder *, @@ -453,8 +469,6 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws, ig = CXL_DECODER_MIN_GRANULARITY; cxld->interleave_granularity = ig; - cxl_setup_extended_linear_cache(cxlrd); - if (cfmws->interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_XOR) { if (ways != 1 && ways != 3) { cxims_ctx = (struct cxl_cxims_context) { @@ -470,18 +484,13 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws, return -EINVAL; } } + cxlrd->ops.hpa_to_spa = cxl_apply_xor_maps; + cxlrd->ops.spa_to_hpa = cxl_apply_xor_maps; } - cxlrd->qos_class = cfmws->qtg_id; - - if (cfmws->interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_XOR) { - cxlrd->ops = kzalloc(sizeof(*cxlrd->ops), GFP_KERNEL); - if (!cxlrd->ops) - return -ENOMEM; + cxl_setup_extended_linear_cache(cxlrd); - cxlrd->ops->hpa_to_spa = cxl_apply_xor_maps; - cxlrd->ops->spa_to_hpa = cxl_apply_xor_maps; - } + cxlrd->qos_class = cfmws->qtg_id; rc = cxl_decoder_add(cxld); if (rc) diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c index c4bd6e8a0cf03..7120b5f2e31fe 100644 --- a/drivers/cxl/core/cdat.c +++ b/drivers/cxl/core/cdat.c @@ -826,7 +826,7 @@ static struct xarray *cxl_switch_gather_bandwidth(struct cxl_region *cxlr, cxl_coordinates_combine(coords, coords, ctx->coord); /* - * Take the min of the calculated bandwdith and the upstream + * Take the min of the calculated bandwidth and the upstream * switch SSLBIS bandwidth if there's a parent switch */ if (!is_root) @@ -949,7 +949,7 @@ static struct xarray *cxl_hb_gather_bandwidth(struct xarray *xa) /** * cxl_region_update_bandwidth - Update the bandwidth access coordinates of a region * @cxlr: The region being operated on - * @input_xa: xarray holds cxl_perf_ctx wht calculated bandwidth per ACPI0017 instance + * @input_xa: xarray holds cxl_perf_ctx with calculated bandwidth per ACPI0017 instance */ static void cxl_region_update_bandwidth(struct cxl_region *cxlr, struct xarray *input_xa) diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c index d3a094ca01ad9..1c5d2022c87a9 100644 --- a/drivers/cxl/core/hdm.c +++ b/drivers/cxl/core/hdm.c @@ -905,6 +905,9 @@ static void cxl_decoder_reset(struct cxl_decoder *cxld) if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0) return; + if (test_bit(CXL_DECODER_F_LOCK, &cxld->flags)) + return; + if (port->commit_end == id) cxl_port_commit_reap(cxld); else diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c index 18825e1505d6a..5b023a0178a47 100644 --- a/drivers/cxl/core/pci.c +++ b/drivers/cxl/core/pci.c @@ -71,85 +71,6 @@ struct cxl_dport *__devm_cxl_add_dport_by_dev(struct cxl_port *port, } EXPORT_SYMBOL_NS_GPL(__devm_cxl_add_dport_by_dev, "CXL"); -struct cxl_walk_context { - struct pci_bus *bus; - struct cxl_port *port; - int type; - int error; - int count; -}; - -static int match_add_dports(struct pci_dev *pdev, void *data) -{ - struct cxl_walk_context *ctx = data; - struct cxl_port *port = ctx->port; - int type = pci_pcie_type(pdev); - struct cxl_register_map map; - struct cxl_dport *dport; - u32 lnkcap, port_num; - int rc; - - if (pdev->bus != ctx->bus) - return 0; - if (!pci_is_pcie(pdev)) - return 0; - if (type != ctx->type) - return 0; - if (pci_read_config_dword(pdev, pci_pcie_cap(pdev) + PCI_EXP_LNKCAP, - &lnkcap)) - return 0; - - rc = cxl_find_regblock(pdev, CXL_REGLOC_RBI_COMPONENT, &map); - if (rc) - dev_dbg(&port->dev, "failed to find component registers\n"); - - port_num = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap); - dport = devm_cxl_add_dport(port, &pdev->dev, port_num, map.resource); - if (IS_ERR(dport)) { - ctx->error = PTR_ERR(dport); - return PTR_ERR(dport); - } - ctx->count++; - - return 0; -} - -/** - * devm_cxl_port_enumerate_dports - enumerate downstream ports of the upstream port - * @port: cxl_port whose ->uport_dev is the upstream of dports to be enumerated - * - * Returns a positive number of dports enumerated or a negative error - * code. - */ -int devm_cxl_port_enumerate_dports(struct cxl_port *port) -{ - struct pci_bus *bus = cxl_port_to_pci_bus(port); - struct cxl_walk_context ctx; - int type; - - if (!bus) - return -ENXIO; - - if (pci_is_root_bus(bus)) - type = PCI_EXP_TYPE_ROOT_PORT; - else - type = PCI_EXP_TYPE_DOWNSTREAM; - - ctx = (struct cxl_walk_context) { - .port = port, - .bus = bus, - .type = type, - }; - pci_walk_bus(bus, match_add_dports, &ctx); - - if (ctx.count == 0) - return -ENODEV; - if (ctx.error) - return ctx.error; - return ctx.count; -} -EXPORT_SYMBOL_NS_GPL(devm_cxl_port_enumerate_dports, "CXL"); - static int cxl_dvsec_mem_range_valid(struct cxl_dev_state *cxlds, int id) { struct pci_dev *pdev = to_pci_dev(cxlds->dev); @@ -1217,6 +1138,14 @@ int cxl_gpf_port_setup(struct cxl_dport *dport) return 0; } +struct cxl_walk_context { + struct pci_bus *bus; + struct cxl_port *port; + int type; + int error; + int count; +}; + static int count_dports(struct pci_dev *pdev, void *data) { struct cxl_walk_context *ctx = data; diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index 8128fd2b5b317..fef3aa0c6680c 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -459,7 +459,6 @@ static void cxl_root_decoder_release(struct device *dev) if (atomic_read(&cxlrd->region_id) >= 0) memregion_free(atomic_read(&cxlrd->region_id)); __cxl_decoder_release(&cxlrd->cxlsd.cxld); - kfree(cxlrd->ops); kfree(cxlrd); } diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 41b64d871c5a1..ae899f68551f7 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -236,7 +236,10 @@ static int cxl_region_invalidate_memregion(struct cxl_region *cxlr) return -ENXIO; } - cpu_cache_invalidate_memregion(IORES_DESC_CXL); + if (!cxlr->params.res) + return -ENXIO; + cpu_cache_invalidate_memregion(cxlr->params.res->start, + resource_size(cxlr->params.res)); return 0; } @@ -245,6 +248,9 @@ static void cxl_region_decode_reset(struct cxl_region *cxlr, int count) struct cxl_region_params *p = &cxlr->params; int i; + if (test_bit(CXL_REGION_F_LOCK, &cxlr->flags)) + return; + /* * Before region teardown attempt to flush, evict any data cached for * this region, or scream loudly about missing arch / platform support @@ -419,6 +425,9 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr, return len; } + if (test_bit(CXL_REGION_F_LOCK, &cxlr->flags)) + return -EPERM; + rc = queue_reset(cxlr); if (rc) return rc; @@ -461,21 +470,6 @@ static ssize_t commit_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(commit); -static umode_t cxl_region_visible(struct kobject *kobj, struct attribute *a, - int n) -{ - struct device *dev = kobj_to_dev(kobj); - struct cxl_region *cxlr = to_cxl_region(dev); - - /* - * Support tooling that expects to find a 'uuid' attribute for all - * regions regardless of mode. - */ - if (a == &dev_attr_uuid.attr && cxlr->mode != CXL_PARTMODE_PMEM) - return 0444; - return a->mode; -} - static ssize_t interleave_ways_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -754,6 +748,21 @@ static ssize_t size_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(size); +static ssize_t extended_linear_cache_size_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct cxl_region *cxlr = to_cxl_region(dev); + struct cxl_region_params *p = &cxlr->params; + ssize_t rc; + + ACQUIRE(rwsem_read_intr, rwsem)(&cxl_rwsem.region); + if ((rc = ACQUIRE_ERR(rwsem_read_intr, &rwsem))) + return rc; + return sysfs_emit(buf, "%#llx\n", p->cache_size); +} +static DEVICE_ATTR_RO(extended_linear_cache_size); + static struct attribute *cxl_region_attrs[] = { &dev_attr_uuid.attr, &dev_attr_commit.attr, @@ -762,9 +771,34 @@ static struct attribute *cxl_region_attrs[] = { &dev_attr_resource.attr, &dev_attr_size.attr, &dev_attr_mode.attr, + &dev_attr_extended_linear_cache_size.attr, NULL, }; +static umode_t cxl_region_visible(struct kobject *kobj, struct attribute *a, + int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct cxl_region *cxlr = to_cxl_region(dev); + + /* + * Support tooling that expects to find a 'uuid' attribute for all + * regions regardless of mode. + */ + if (a == &dev_attr_uuid.attr && cxlr->mode != CXL_PARTMODE_PMEM) + return 0444; + + /* + * Don't display extended linear cache attribute if there is no + * extended linear cache. + */ + if (a == &dev_attr_extended_linear_cache_size.attr && + cxlr->params.cache_size == 0) + return 0; + + return a->mode; +} + static const struct attribute_group cxl_region_group = { .attrs = cxl_region_attrs, .is_visible = cxl_region_visible, @@ -838,16 +872,16 @@ static int match_free_decoder(struct device *dev, const void *data) return 1; } -static bool region_res_match_cxl_range(const struct cxl_region_params *p, - const struct range *range) +static bool spa_maps_hpa(const struct cxl_region_params *p, + const struct range *range) { if (!p->res) return false; /* - * If an extended linear cache region then the CXL range is assumed - * to be fronted by the DRAM range in current known implementation. - * This assumption will be made until a variant implementation exists. + * The extended linear cache region is constructed by a 1:1 ratio + * where the SPA maps equal amounts of DRAM and CXL HPA capacity with + * CXL decoders at the high end of the SPA range. */ return p->res->start + p->cache_size == range->start && p->res->end == range->end; @@ -865,7 +899,7 @@ static int match_auto_decoder(struct device *dev, const void *data) cxld = to_cxl_decoder(dev); r = &cxld->hpa_range; - if (region_res_match_cxl_range(p, r)) + if (spa_maps_hpa(p, r)) return 1; return 0; @@ -1059,6 +1093,16 @@ static int cxl_rr_assign_decoder(struct cxl_port *port, struct cxl_region *cxlr, return 0; } +static void cxl_region_set_lock(struct cxl_region *cxlr, + struct cxl_decoder *cxld) +{ + if (!test_bit(CXL_DECODER_F_LOCK, &cxld->flags)) + return; + + set_bit(CXL_REGION_F_LOCK, &cxlr->flags); + clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); +} + /** * cxl_port_attach_region() - track a region's interest in a port by endpoint * @port: port to add a new region reference 'struct cxl_region_ref' @@ -1170,6 +1214,8 @@ static int cxl_port_attach_region(struct cxl_port *port, } } + cxl_region_set_lock(cxlr, cxld); + rc = cxl_rr_ep_add(cxl_rr, cxled); if (rc) { dev_dbg(&cxlr->dev, @@ -1328,7 +1374,7 @@ static int cxl_port_setup_targets(struct cxl_port *port, struct cxl_endpoint_decoder *cxled) { struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); - int parent_iw, parent_ig, ig, iw, rc, inc = 0, pos = cxled->pos; + int parent_iw, parent_ig, ig, iw, rc, pos = cxled->pos; struct cxl_port *parent_port = to_cxl_port(port->dev.parent); struct cxl_region_ref *cxl_rr = cxl_rr_load(port, cxlr); struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); @@ -1465,7 +1511,7 @@ static int cxl_port_setup_targets(struct cxl_port *port, if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) { if (cxld->interleave_ways != iw || (iw > 1 && cxld->interleave_granularity != ig) || - !region_res_match_cxl_range(p, &cxld->hpa_range) || + !spa_maps_hpa(p, &cxld->hpa_range) || ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) { dev_err(&cxlr->dev, "%s:%s %s expected iw: %d ig: %d %pr\n", @@ -1520,9 +1566,8 @@ static int cxl_port_setup_targets(struct cxl_port *port, cxlsd->target[cxl_rr->nr_targets_set] = ep->dport; cxlsd->cxld.target_map[cxl_rr->nr_targets_set] = ep->dport->port_id; } - inc = 1; + cxl_rr->nr_targets_set++; out_target_set: - cxl_rr->nr_targets_set += inc; dev_dbg(&cxlr->dev, "%s:%s target[%d] = %s for %s:%s @ %d\n", dev_name(port->uport_dev), dev_name(&port->dev), cxl_rr->nr_targets_set - 1, dev_name(ep->dport->dport_dev), @@ -2439,6 +2484,7 @@ static struct cxl_region *cxl_region_alloc(struct cxl_root_decoder *cxlrd, int i dev->bus = &cxl_bus_type; dev->type = &cxl_region_type; cxlr->id = id; + cxl_region_set_lock(cxlr, &cxlrd->cxlsd.cxld); return cxlr; } @@ -2924,38 +2970,119 @@ static bool cxl_is_hpa_in_chunk(u64 hpa, struct cxl_region *cxlr, int pos) return false; } -static bool has_hpa_to_spa(struct cxl_root_decoder *cxlrd) +#define CXL_POS_ZERO 0 +/** + * cxl_validate_translation_params + * @eiw: encoded interleave ways + * @eig: encoded interleave granularity + * @pos: position in interleave + * + * Callers pass CXL_POS_ZERO when no position parameter needs validating. + * + * Returns: 0 on success, -EINVAL on first invalid parameter + */ +int cxl_validate_translation_params(u8 eiw, u16 eig, int pos) { - return cxlrd->ops && cxlrd->ops->hpa_to_spa; + int ways, gran; + + if (eiw_to_ways(eiw, &ways)) { + pr_debug("%s: invalid eiw=%u\n", __func__, eiw); + return -EINVAL; + } + if (eig_to_granularity(eig, &gran)) { + pr_debug("%s: invalid eig=%u\n", __func__, eig); + return -EINVAL; + } + if (pos < 0 || pos >= ways) { + pr_debug("%s: invalid pos=%d for ways=%u\n", __func__, pos, + ways); + return -EINVAL; + } + + return 0; } +EXPORT_SYMBOL_FOR_MODULES(cxl_validate_translation_params, "cxl_translate"); -static bool has_spa_to_hpa(struct cxl_root_decoder *cxlrd) +u64 cxl_calculate_dpa_offset(u64 hpa_offset, u8 eiw, u16 eig) { - return cxlrd->ops && cxlrd->ops->spa_to_hpa; + u64 dpa_offset, bits_lower, bits_upper, temp; + int ret; + + ret = cxl_validate_translation_params(eiw, eig, CXL_POS_ZERO); + if (ret) + return ULLONG_MAX; + + /* + * DPA offset: CXL Spec 3.2 Section 8.2.4.20.13 + * Lower bits [IG+7:0] pass through unchanged + * (eiw < 8) + * Per spec: DPAOffset[51:IG+8] = (HPAOffset[51:IG+IW+8] >> IW) + * Clear the position bits to isolate upper section, then + * reverse the left shift by eiw that occurred during DPA->HPA + * (eiw >= 8) + * Per spec: DPAOffset[51:IG+8] = HPAOffset[51:IG+IW] / 3 + * Extract upper bits from the correct bit range and divide by 3 + * to recover the original DPA upper bits + */ + bits_lower = hpa_offset & GENMASK_ULL(eig + 7, 0); + if (eiw < 8) { + temp = hpa_offset &= ~GENMASK_ULL(eig + eiw + 8 - 1, 0); + dpa_offset = temp >> eiw; + } else { + bits_upper = div64_u64(hpa_offset >> (eig + eiw), 3); + dpa_offset = bits_upper << (eig + 8); + } + dpa_offset |= bits_lower; + + return dpa_offset; } +EXPORT_SYMBOL_FOR_MODULES(cxl_calculate_dpa_offset, "cxl_translate"); -u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, - u64 dpa) +int cxl_calculate_position(u64 hpa_offset, u8 eiw, u16 eig) { - struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); - u64 dpa_offset, hpa_offset, bits_upper, mask_upper, hpa; - struct cxl_region_params *p = &cxlr->params; - struct cxl_endpoint_decoder *cxled = NULL; - u16 eig = 0; - u8 eiw = 0; - int pos; + unsigned int ways = 0; + u64 shifted, rem; + int pos, ret; - for (int i = 0; i < p->nr_targets; i++) { - cxled = p->targets[i]; - if (cxlmd == cxled_to_memdev(cxled)) - break; + ret = cxl_validate_translation_params(eiw, eig, CXL_POS_ZERO); + if (ret) + return ret; + + if (!eiw) + /* position is 0 if no interleaving */ + return 0; + + /* + * Interleave position: CXL Spec 3.2 Section 8.2.4.20.13 + * eiw < 8 + * Position is in the IW bits at HPA_OFFSET[IG+8+IW-1:IG+8]. + * Per spec "remove IW bits starting with bit position IG+8" + * eiw >= 8 + * Position is not explicitly stored in HPA_OFFSET bits. It is + * derived from the modulo operation of the upper bits using + * the total number of interleave ways. + */ + if (eiw < 8) { + pos = (hpa_offset >> (eig + 8)) & GENMASK(eiw - 1, 0); + } else { + shifted = hpa_offset >> (eig + 8); + eiw_to_ways(eiw, &ways); + div64_u64_rem(shifted, ways, &rem); + pos = rem; } - if (!cxled || cxlmd != cxled_to_memdev(cxled)) - return ULLONG_MAX; - pos = cxled->pos; - ways_to_eiw(p->interleave_ways, &eiw); - granularity_to_eig(p->interleave_granularity, &eig); + return pos; +} +EXPORT_SYMBOL_FOR_MODULES(cxl_calculate_position, "cxl_translate"); + +u64 cxl_calculate_hpa_offset(u64 dpa_offset, int pos, u8 eiw, u16 eig) +{ + u64 mask_upper, hpa_offset, bits_upper; + int ret; + + ret = cxl_validate_translation_params(eiw, eig, pos); + if (ret) + return ULLONG_MAX; /* * The device position in the region interleave set was removed @@ -2967,9 +3094,6 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, * 8.2.4.19.13 Implementation Note: Device Decode Logic */ - /* Remove the dpa base */ - dpa_offset = dpa - cxl_dpa_resource_start(cxled); - mask_upper = GENMASK_ULL(51, eig + 8); if (eiw < 8) { @@ -2984,12 +3108,43 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, /* The lower bits remain unchanged */ hpa_offset |= dpa_offset & GENMASK_ULL(eig + 7, 0); + return hpa_offset; +} +EXPORT_SYMBOL_FOR_MODULES(cxl_calculate_hpa_offset, "cxl_translate"); + +u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, + u64 dpa) +{ + struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); + struct cxl_region_params *p = &cxlr->params; + struct cxl_endpoint_decoder *cxled = NULL; + u64 dpa_offset, hpa_offset, hpa; + u16 eig = 0; + u8 eiw = 0; + int pos; + + for (int i = 0; i < p->nr_targets; i++) { + if (cxlmd == cxled_to_memdev(p->targets[i])) { + cxled = p->targets[i]; + break; + } + } + if (!cxled) + return ULLONG_MAX; + + pos = cxled->pos; + ways_to_eiw(p->interleave_ways, &eiw); + granularity_to_eig(p->interleave_granularity, &eig); + + dpa_offset = dpa - cxl_dpa_resource_start(cxled); + hpa_offset = cxl_calculate_hpa_offset(dpa_offset, pos, eiw, eig); + /* Apply the hpa_offset to the region base address */ hpa = hpa_offset + p->res->start + p->cache_size; /* Root decoder translation overrides typical modulo decode */ - if (has_hpa_to_spa(cxlrd)) - hpa = cxlrd->ops->hpa_to_spa(cxlrd, hpa); + if (cxlrd->ops.hpa_to_spa) + hpa = cxlrd->ops.hpa_to_spa(cxlrd, hpa); if (!cxl_resource_contains_addr(p->res, hpa)) { dev_dbg(&cxlr->dev, @@ -2998,7 +3153,7 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, } /* Simple chunk check, by pos & gran, only applies to modulo decodes */ - if (!has_hpa_to_spa(cxlrd) && (!cxl_is_hpa_in_chunk(hpa, cxlr, pos))) + if (!cxlrd->ops.hpa_to_spa && !cxl_is_hpa_in_chunk(hpa, cxlr, pos)) return ULLONG_MAX; return hpa; @@ -3016,8 +3171,6 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset, struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); struct cxl_endpoint_decoder *cxled; u64 hpa, hpa_offset, dpa_offset; - u64 bits_upper, bits_lower; - u64 shifted, rem, temp; u16 eig = 0; u8 eiw = 0; int pos; @@ -3033,56 +3186,21 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset, * If the root decoder has SPA to CXL HPA callback, use it. Otherwise * CXL HPA is assumed to equal SPA. */ - if (has_spa_to_hpa(cxlrd)) { - hpa = cxlrd->ops->spa_to_hpa(cxlrd, p->res->start + offset); + if (cxlrd->ops.spa_to_hpa) { + hpa = cxlrd->ops.spa_to_hpa(cxlrd, p->res->start + offset); hpa_offset = hpa - p->res->start; } else { hpa_offset = offset; } - /* - * Interleave position: CXL Spec 3.2 Section 8.2.4.20.13 - * eiw < 8 - * Position is in the IW bits at HPA_OFFSET[IG+8+IW-1:IG+8]. - * Per spec "remove IW bits starting with bit position IG+8" - * eiw >= 8 - * Position is not explicitly stored in HPA_OFFSET bits. It is - * derived from the modulo operation of the upper bits using - * the total number of interleave ways. - */ - if (eiw < 8) { - pos = (hpa_offset >> (eig + 8)) & GENMASK(eiw - 1, 0); - } else { - shifted = hpa_offset >> (eig + 8); - div64_u64_rem(shifted, p->interleave_ways, &rem); - pos = rem; - } + + pos = cxl_calculate_position(hpa_offset, eiw, eig); if (pos < 0 || pos >= p->nr_targets) { dev_dbg(&cxlr->dev, "Invalid position %d for %d targets\n", pos, p->nr_targets); return -ENXIO; } - /* - * DPA offset: CXL Spec 3.2 Section 8.2.4.20.13 - * Lower bits [IG+7:0] pass through unchanged - * (eiw < 8) - * Per spec: DPAOffset[51:IG+8] = (HPAOffset[51:IG+IW+8] >> IW) - * Clear the position bits to isolate upper section, then - * reverse the left shift by eiw that occurred during DPA->HPA - * (eiw >= 8) - * Per spec: DPAOffset[51:IG+8] = HPAOffset[51:IG+IW] / 3 - * Extract upper bits from the correct bit range and divide by 3 - * to recover the original DPA upper bits - */ - bits_lower = hpa_offset & GENMASK_ULL(eig + 7, 0); - if (eiw < 8) { - temp = hpa_offset &= ~((u64)GENMASK(eig + eiw + 8 - 1, 0)); - dpa_offset = temp >> eiw; - } else { - bits_upper = div64_u64(hpa_offset >> (eig + eiw), 3); - dpa_offset = bits_upper << (eig + 8); - } - dpa_offset |= bits_lower; + dpa_offset = cxl_calculate_dpa_offset(hpa_offset, eiw, eig); /* Look-up and return the result: a memdev and a DPA */ for (int i = 0; i < p->nr_targets; i++) { @@ -3398,7 +3516,7 @@ static int match_region_by_range(struct device *dev, const void *data) p = &cxlr->params; guard(rwsem_read)(&cxl_rwsem.region); - return region_res_match_cxl_range(p, r); + return spa_maps_hpa(p, r); } static int cxl_extended_linear_cache_resize(struct cxl_region *cxlr, @@ -3479,6 +3597,10 @@ static int __construct_region(struct cxl_region *cxlr, "Extended linear cache calculation failed rc:%d\n", rc); } + rc = sysfs_update_group(&cxlr->dev.kobj, &cxl_region_group); + if (rc) + return rc; + rc = insert_resource(cxlrd->res, res); if (rc) { /* diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 231ddccf89773..ba17fa86d249e 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -451,7 +451,7 @@ struct cxl_root_decoder { void *platform_data; struct mutex range_lock; int qos_class; - struct cxl_rd_ops *ops; + struct cxl_rd_ops ops; struct cxl_switch_decoder cxlsd; }; @@ -517,6 +517,14 @@ enum cxl_partition_mode { */ #define CXL_REGION_F_NEEDS_RESET 1 +/* + * Indicate whether this region is locked due to 1 or more decoders that have + * been locked. The approach of all or nothing is taken with regard to the + * locked attribute. CXL_REGION_F_NEEDS_RESET should not be set if this flag is + * set. + */ +#define CXL_REGION_F_LOCK 2 + /** * struct cxl_region - CXL region * @dev: This region's device @@ -738,6 +746,25 @@ static inline bool is_cxl_root(struct cxl_port *port) return port->uport_dev == port->dev.parent; } +/* Address translation functions exported to cxl_translate test module only */ +int cxl_validate_translation_params(u8 eiw, u16 eig, int pos); +u64 cxl_calculate_hpa_offset(u64 dpa_offset, int pos, u8 eiw, u16 eig); +u64 cxl_calculate_dpa_offset(u64 hpa_offset, u8 eiw, u16 eig); +int cxl_calculate_position(u64 hpa_offset, u8 eiw, u16 eig); +struct cxl_cxims_data { + int nr_maps; + u64 xormaps[] __counted_by(nr_maps); +}; + +#if IS_ENABLED(CONFIG_CXL_ACPI) +u64 cxl_do_xormap_calc(struct cxl_cxims_data *cximsd, u64 addr, int hbiw); +#else +static inline u64 cxl_do_xormap_calc(struct cxl_cxims_data *cximsd, u64 addr, int hbiw) +{ + return ULLONG_MAX; +} +#endif + int cxl_num_decoders_committed(struct cxl_port *port); bool is_cxl_port(const struct device *dev); struct cxl_port *to_cxl_port(const struct device *dev); diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h index 7ae621e618e79..1d526bea84312 100644 --- a/drivers/cxl/cxlpci.h +++ b/drivers/cxl/cxlpci.h @@ -127,7 +127,6 @@ static inline bool cxl_pci_flit_256(struct pci_dev *pdev) return lnksta2 & PCI_EXP_LNKSTA2_FLIT; } -int devm_cxl_port_enumerate_dports(struct cxl_port *port); struct cxl_dev_state; void read_cdat_data(struct cxl_port *port); void cxl_cor_error_detected(struct pci_dev *pdev); diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index bd100ac31672d..0be4e508affe7 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -136,7 +136,7 @@ static irqreturn_t cxl_pci_mbox_irq(int irq, void *id) if (opcode == CXL_MBOX_OP_SANITIZE) { mutex_lock(&cxl_mbox->mbox_mutex); if (mds->security.sanitize_node) - mod_delayed_work(system_wq, &mds->security.poll_dwork, 0); + mod_delayed_work(system_percpu_wq, &mds->security.poll_dwork, 0); mutex_unlock(&cxl_mbox->mbox_mutex); } else { /* short-circuit the wait in __cxl_pci_mbox_send_cmd() */ diff --git a/drivers/dax/device.c b/drivers/dax/device.c index 2bb40a6060af3..22999a402e029 100644 --- a/drivers/dax/device.c +++ b/drivers/dax/device.c @@ -13,8 +13,9 @@ #include "dax-private.h" #include "bus.h" -static int check_vma(struct dev_dax *dev_dax, struct vm_area_struct *vma, - const char *func) +static int __check_vma(struct dev_dax *dev_dax, vm_flags_t vm_flags, + unsigned long start, unsigned long end, struct file *file, + const char *func) { struct device *dev = &dev_dax->dev; unsigned long mask; @@ -23,7 +24,7 @@ static int check_vma(struct dev_dax *dev_dax, struct vm_area_struct *vma, return -ENXIO; /* prevent private mappings from being established */ - if ((vma->vm_flags & VM_MAYSHARE) != VM_MAYSHARE) { + if ((vm_flags & VM_MAYSHARE) != VM_MAYSHARE) { dev_info_ratelimited(dev, "%s: %s: fail, attempted private mapping\n", current->comm, func); @@ -31,15 +32,15 @@ static int check_vma(struct dev_dax *dev_dax, struct vm_area_struct *vma, } mask = dev_dax->align - 1; - if (vma->vm_start & mask || vma->vm_end & mask) { + if (start & mask || end & mask) { dev_info_ratelimited(dev, "%s: %s: fail, unaligned vma (%#lx - %#lx, %#lx)\n", - current->comm, func, vma->vm_start, vma->vm_end, + current->comm, func, start, end, mask); return -EINVAL; } - if (!vma_is_dax(vma)) { + if (!file_is_dax(file)) { dev_info_ratelimited(dev, "%s: %s: fail, vma is not DAX capable\n", current->comm, func); @@ -49,6 +50,13 @@ static int check_vma(struct dev_dax *dev_dax, struct vm_area_struct *vma, return 0; } +static int check_vma(struct dev_dax *dev_dax, struct vm_area_struct *vma, + const char *func) +{ + return __check_vma(dev_dax, vma->vm_flags, vma->vm_start, vma->vm_end, + vma->vm_file, func); +} + /* see "strong" declaration in tools/testing/nvdimm/dax-dev.c */ __weak phys_addr_t dax_pgoff_to_phys(struct dev_dax *dev_dax, pgoff_t pgoff, unsigned long size) @@ -285,8 +293,9 @@ static const struct vm_operations_struct dax_vm_ops = { .pagesize = dev_dax_pagesize, }; -static int dax_mmap(struct file *filp, struct vm_area_struct *vma) +static int dax_mmap_prepare(struct vm_area_desc *desc) { + struct file *filp = desc->file; struct dev_dax *dev_dax = filp->private_data; int rc, id; @@ -297,13 +306,14 @@ static int dax_mmap(struct file *filp, struct vm_area_struct *vma) * fault time. */ id = dax_read_lock(); - rc = check_vma(dev_dax, vma, __func__); + rc = __check_vma(dev_dax, desc->vm_flags, desc->start, desc->end, filp, + __func__); dax_read_unlock(id); if (rc) return rc; - vma->vm_ops = &dax_vm_ops; - vm_flags_set(vma, VM_HUGEPAGE); + desc->vm_ops = &dax_vm_ops; + desc->vm_flags |= VM_HUGEPAGE; return 0; } @@ -330,14 +340,13 @@ static unsigned long dax_get_unmapped_area(struct file *filp, if ((off + len_align) < off) goto out; - addr_align = mm_get_unmapped_area(current->mm, filp, addr, len_align, - pgoff, flags); + addr_align = mm_get_unmapped_area(filp, addr, len_align, pgoff, flags); if (!IS_ERR_VALUE(addr_align)) { addr_align += (off - addr_align) & (align - 1); return addr_align; } out: - return mm_get_unmapped_area(current->mm, filp, addr, len, pgoff, flags); + return mm_get_unmapped_area(filp, addr, len, pgoff, flags); } static const struct address_space_operations dev_dax_aops = { @@ -377,7 +386,7 @@ static const struct file_operations dax_fops = { .open = dax_open, .release = dax_release, .get_unmapped_area = dax_get_unmapped_area, - .mmap = dax_mmap, + .mmap_prepare = dax_mmap_prepare, .fop_flags = FOP_MMAP_SYNC, }; diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 70ec901edf2c5..2008fb7481b35 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ - dma-fence-unwrap.o dma-resv.o + dma-fence-unwrap.o dma-resv.o dma-buf-mapping.o obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o obj-$(CONFIG_DMABUF_HEAPS) += heaps/ obj-$(CONFIG_SYNC_FILE) += sync_file.o diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c new file mode 100644 index 0000000000000..b7352e609fbdf --- /dev/null +++ b/drivers/dma-buf/dma-buf-mapping.c @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * DMA BUF Mapping Helpers + * + */ +#include +#include + +static struct scatterlist *fill_sg_entry(struct scatterlist *sgl, size_t length, + dma_addr_t addr) +{ + unsigned int len, nents; + int i; + + nents = DIV_ROUND_UP(length, UINT_MAX); + for (i = 0; i < nents; i++) { + len = min_t(size_t, length, UINT_MAX); + length -= len; + /* + * DMABUF abuses scatterlist to create a scatterlist + * that does not have any CPU list, only the DMA list. + * Always set the page related values to NULL to ensure + * importers can't use it. The phys_addr based DMA API + * does not require the CPU list for mapping or unmapping. + */ + sg_set_page(sgl, NULL, 0, 0); + sg_dma_address(sgl) = addr + (dma_addr_t)i * UINT_MAX; + sg_dma_len(sgl) = len; + sgl = sg_next(sgl); + } + + return sgl; +} + +static unsigned int calc_sg_nents(struct dma_iova_state *state, + struct dma_buf_phys_vec *phys_vec, + size_t nr_ranges, size_t size) +{ + unsigned int nents = 0; + size_t i; + + if (!state || !dma_use_iova(state)) { + for (i = 0; i < nr_ranges; i++) + nents += DIV_ROUND_UP(phys_vec[i].len, UINT_MAX); + } else { + /* + * In IOVA case, there is only one SG entry which spans + * for whole IOVA address space, but we need to make sure + * that it fits sg->length, maybe we need more. + */ + nents = DIV_ROUND_UP(size, UINT_MAX); + } + + return nents; +} + +/** + * struct dma_buf_dma - holds DMA mapping information + * @sgt: Scatter-gather table + * @state: DMA IOVA state relevant in IOMMU-based DMA + * @size: Total size of DMA transfer + */ +struct dma_buf_dma { + struct sg_table sgt; + struct dma_iova_state *state; + size_t size; +}; + +/** + * dma_buf_phys_vec_to_sgt - Returns the scatterlist table of the attachment + * from arrays of physical vectors. This funciton is intended for MMIO memory + * only. + * @attach: [in] attachment whose scatterlist is to be returned + * @provider: [in] p2pdma provider + * @phys_vec: [in] array of physical vectors + * @nr_ranges: [in] number of entries in phys_vec array + * @size: [in] total size of phys_vec + * @dir: [in] direction of DMA transfer + * + * Returns sg_table containing the scatterlist to be returned; returns ERR_PTR + * on error. May return -EINTR if it is interrupted by a signal. + * + * On success, the DMA addresses and lengths in the returned scatterlist are + * PAGE_SIZE aligned. + * + * A mapping must be unmapped by using dma_buf_free_sgt(). + * + * NOTE: This function is intended for exporters. If direct traffic routing is + * mandatory exporter should call routing pci_p2pdma_map_type() before calling + * this function. + */ +struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach, + struct p2pdma_provider *provider, + struct dma_buf_phys_vec *phys_vec, + size_t nr_ranges, size_t size, + enum dma_data_direction dir) +{ + unsigned int nents, mapped_len = 0; + struct dma_buf_dma *dma; + struct scatterlist *sgl; + dma_addr_t addr; + size_t i; + int ret; + + dma_resv_assert_held(attach->dmabuf->resv); + + if (WARN_ON(!attach || !attach->dmabuf || !provider)) + /* This function is supposed to work on MMIO memory only */ + return ERR_PTR(-EINVAL); + + dma = kzalloc(sizeof(*dma), GFP_KERNEL); + if (!dma) + return ERR_PTR(-ENOMEM); + + switch (pci_p2pdma_map_type(provider, attach->dev)) { + case PCI_P2PDMA_MAP_BUS_ADDR: + /* + * There is no need in IOVA at all for this flow. + */ + break; + case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE: + dma->state = kzalloc(sizeof(*dma->state), GFP_KERNEL); + if (!dma->state) { + ret = -ENOMEM; + goto err_free_dma; + } + + dma_iova_try_alloc(attach->dev, dma->state, 0, size); + break; + default: + ret = -EINVAL; + goto err_free_dma; + } + + nents = calc_sg_nents(dma->state, phys_vec, nr_ranges, size); + ret = sg_alloc_table(&dma->sgt, nents, GFP_KERNEL | __GFP_ZERO); + if (ret) + goto err_free_state; + + sgl = dma->sgt.sgl; + + for (i = 0; i < nr_ranges; i++) { + if (!dma->state) { + addr = pci_p2pdma_bus_addr_map(provider, + phys_vec[i].paddr); + } else if (dma_use_iova(dma->state)) { + ret = dma_iova_link(attach->dev, dma->state, + phys_vec[i].paddr, 0, + phys_vec[i].len, dir, + DMA_ATTR_MMIO); + if (ret) + goto err_unmap_dma; + + mapped_len += phys_vec[i].len; + } else { + addr = dma_map_phys(attach->dev, phys_vec[i].paddr, + phys_vec[i].len, dir, + DMA_ATTR_MMIO); + ret = dma_mapping_error(attach->dev, addr); + if (ret) + goto err_unmap_dma; + } + + if (!dma->state || !dma_use_iova(dma->state)) + sgl = fill_sg_entry(sgl, phys_vec[i].len, addr); + } + + if (dma->state && dma_use_iova(dma->state)) { + WARN_ON_ONCE(mapped_len != size); + ret = dma_iova_sync(attach->dev, dma->state, 0, mapped_len); + if (ret) + goto err_unmap_dma; + + sgl = fill_sg_entry(sgl, mapped_len, dma->state->addr); + } + + dma->size = size; + + /* + * No CPU list included — set orig_nents = 0 so others can detect + * this via SG table (use nents only). + */ + dma->sgt.orig_nents = 0; + + + /* + * SGL must be NULL to indicate that SGL is the last one + * and we allocated correct number of entries in sg_alloc_table() + */ + WARN_ON_ONCE(sgl); + return &dma->sgt; + +err_unmap_dma: + if (!i || !dma->state) { + ; /* Do nothing */ + } else if (dma_use_iova(dma->state)) { + dma_iova_destroy(attach->dev, dma->state, mapped_len, dir, + DMA_ATTR_MMIO); + } else { + for_each_sgtable_dma_sg(&dma->sgt, sgl, i) + dma_unmap_phys(attach->dev, sg_dma_address(sgl), + sg_dma_len(sgl), dir, DMA_ATTR_MMIO); + } + sg_free_table(&dma->sgt); +err_free_state: + kfree(dma->state); +err_free_dma: + kfree(dma); + return ERR_PTR(ret); +} +EXPORT_SYMBOL_NS_GPL(dma_buf_phys_vec_to_sgt, "DMA_BUF"); + +/** + * dma_buf_free_sgt- unmaps the buffer + * @attach: [in] attachment to unmap buffer from + * @sgt: [in] scatterlist info of the buffer to unmap + * @dir: [in] direction of DMA transfer + * + * This unmaps a DMA mapping for @attached obtained + * by dma_buf_phys_vec_to_sgt(). + */ +void dma_buf_free_sgt(struct dma_buf_attachment *attach, struct sg_table *sgt, + enum dma_data_direction dir) +{ + struct dma_buf_dma *dma = container_of(sgt, struct dma_buf_dma, sgt); + int i; + + dma_resv_assert_held(attach->dmabuf->resv); + + if (!dma->state) { + ; /* Do nothing */ + } else if (dma_use_iova(dma->state)) { + dma_iova_destroy(attach->dev, dma->state, dma->size, dir, + DMA_ATTR_MMIO); + } else { + struct scatterlist *sgl; + + for_each_sgtable_dma_sg(sgt, sgl, i) + dma_unmap_phys(attach->dev, sg_dma_address(sgl), + sg_dma_len(sgl), dir, DMA_ATTR_MMIO); + } + + sg_free_table(sgt); + kfree(dma->state); + kfree(dma); + +} +EXPORT_SYMBOL_NS_GPL(dma_buf_free_sgt, "DMA_BUF"); diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 39e6f93dc3100..b4f5c86352764 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -121,29 +121,27 @@ static const struct dma_fence_ops dma_fence_stub_ops = { .get_timeline_name = dma_fence_stub_get_name, }; +static int __init dma_fence_init_stub(void) +{ + dma_fence_init(&dma_fence_stub, &dma_fence_stub_ops, + &dma_fence_stub_lock, 0, 0); + + set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, + &dma_fence_stub.flags); + + dma_fence_signal(&dma_fence_stub); + return 0; +} +subsys_initcall(dma_fence_init_stub); + /** * dma_fence_get_stub - return a signaled fence * - * Return a stub fence which is already signaled. The fence's - * timestamp corresponds to the first time after boot this - * function is called. + * Return a stub fence which is already signaled. The fence's timestamp + * corresponds to the initialisation time of the linux kernel. */ struct dma_fence *dma_fence_get_stub(void) { - spin_lock(&dma_fence_stub_lock); - if (!dma_fence_stub.ops) { - dma_fence_init(&dma_fence_stub, - &dma_fence_stub_ops, - &dma_fence_stub_lock, - 0, 0); - - set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, - &dma_fence_stub.flags); - - dma_fence_signal_locked(&dma_fence_stub); - } - spin_unlock(&dma_fence_stub_lock); - return dma_fence_get(&dma_fence_stub); } EXPORT_SYMBOL(dma_fence_get_stub); @@ -999,19 +997,21 @@ EXPORT_SYMBOL(dma_fence_set_deadline); */ void dma_fence_describe(struct dma_fence *fence, struct seq_file *seq) { - const char __rcu *timeline; - const char __rcu *driver; + const char __rcu *timeline = ""; + const char __rcu *driver = ""; + const char *signaled = ""; rcu_read_lock(); - timeline = dma_fence_timeline_name(fence); - driver = dma_fence_driver_name(fence); + if (!dma_fence_is_signaled(fence)) { + timeline = dma_fence_timeline_name(fence); + driver = dma_fence_driver_name(fence); + signaled = "un"; + } - seq_printf(seq, "%s %s seq %llu %ssignalled\n", - rcu_dereference(driver), - rcu_dereference(timeline), - fence->seqno, - dma_fence_is_signaled(fence) ? "" : "un"); + seq_printf(seq, "%llu:%llu %s %s %ssignalled\n", + fence->context, fence->seqno, timeline, driver, + signaled); rcu_read_unlock(); } diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig index bb369b38b001a..a5eef06c42264 100644 --- a/drivers/dma-buf/heaps/Kconfig +++ b/drivers/dma-buf/heaps/Kconfig @@ -12,13 +12,3 @@ config DMABUF_HEAPS_CMA Choose this option to enable dma-buf CMA heap. This heap is backed by the Contiguous Memory Allocator (CMA). If your system has these regions, you should say Y here. - -config DMABUF_HEAPS_CMA_LEGACY - bool "Legacy DMA-BUF CMA Heap" - default y - depends on DMABUF_HEAPS_CMA - help - Add a duplicate CMA-backed dma-buf heap with legacy naming derived - from the CMA area's devicetree node, or "reserved" if the area is not - defined in the devicetree. This uses the same underlying allocator as - CONFIG_DMABUF_HEAPS_CMA. diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index 0df0071119754..42f88193eab9f 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -21,12 +22,27 @@ #include #include #include +#include +#include #include #include #include #define DEFAULT_CMA_NAME "default_cma_region" +static struct cma *dma_areas[MAX_CMA_AREAS] __initdata; +static unsigned int dma_areas_num __initdata; + +int __init dma_heap_cma_register_heap(struct cma *cma) +{ + if (dma_areas_num >= ARRAY_SIZE(dma_areas)) + return -EINVAL; + + dma_areas[dma_areas_num++] = cma; + + return 0; +} + struct cma_heap { struct dma_heap *heap; struct cma *cma; @@ -395,33 +411,30 @@ static int __init __add_cma_heap(struct cma *cma, const char *name) return 0; } -static int __init add_default_cma_heap(void) +static int __init add_cma_heaps(void) { struct cma *default_cma = dev_get_cma_area(NULL); - const char *legacy_cma_name; + unsigned int i; int ret; - if (!default_cma) - return 0; + if (default_cma) { + ret = __add_cma_heap(default_cma, DEFAULT_CMA_NAME); + if (ret) + return ret; + } - ret = __add_cma_heap(default_cma, DEFAULT_CMA_NAME); - if (ret) - return ret; + for (i = 0; i < dma_areas_num; i++) { + struct cma *cma = dma_areas[i]; - if (IS_ENABLED(CONFIG_DMABUF_HEAPS_CMA_LEGACY)) { - legacy_cma_name = cma_get_name(default_cma); - if (!strcmp(legacy_cma_name, DEFAULT_CMA_NAME)) { - pr_warn("legacy name and default name are the same, skipping legacy heap\n"); - return 0; + ret = __add_cma_heap(cma, cma_get_name(cma)); + if (ret) { + pr_warn("Failed to add CMA heap %s", cma_get_name(cma)); + continue; } - ret = __add_cma_heap(default_cma, legacy_cma_name); - if (ret) - pr_warn("failed to add legacy heap: %pe\n", - ERR_PTR(ret)); } return 0; } -module_init(add_default_cma_heap); +module_init(add_cma_heaps); MODULE_DESCRIPTION("DMA-BUF CMA Heap"); diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index bbe7881f13601..4c782fe33fd49 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -186,20 +186,35 @@ static int system_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) struct system_heap_buffer *buffer = dmabuf->priv; struct sg_table *table = &buffer->sg_table; unsigned long addr = vma->vm_start; - struct sg_page_iter piter; - int ret; + unsigned long pgoff = vma->vm_pgoff; + struct scatterlist *sg; + int i, ret; + + for_each_sgtable_sg(table, sg, i) { + unsigned long n = sg->length >> PAGE_SHIFT; - for_each_sgtable_page(table, &piter, vma->vm_pgoff) { - struct page *page = sg_page_iter_page(&piter); + if (pgoff < n) + break; + pgoff -= n; + } + + for (; sg && addr < vma->vm_end; sg = sg_next(sg)) { + unsigned long n = (sg->length >> PAGE_SHIFT) - pgoff; + struct page *page = sg_page(sg) + pgoff; + unsigned long size = n << PAGE_SHIFT; + + if (addr + size > vma->vm_end) + size = vma->vm_end - addr; - ret = remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, - vma->vm_page_prot); + ret = remap_pfn_range(vma, addr, page_to_pfn(page), + size, vma->vm_page_prot); if (ret) return ret; - addr += PAGE_SIZE; - if (addr >= vma->vm_end) - return 0; + + addr += size; + pgoff = 0; } + return 0; } diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c index 3c20f1d31cf54..6f09d13be6b67 100644 --- a/drivers/dma-buf/sw_sync.c +++ b/drivers/dma-buf/sw_sync.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -349,6 +350,9 @@ static long sw_sync_ioctl_create_fence(struct sync_timeline *obj, struct sync_file *sync_file; struct sw_sync_create_fence_data data; + /* SW sync fence are inherently unsafe and can deadlock the kernel */ + add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK); + if (fd < 0) return fd; diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index b8a74b1798ba1..8bb0a119ecd48 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -102,7 +102,7 @@ config ARM_DMA350 config AT_HDMAC tristate "Atmel AHB DMA support" - depends on ARCH_AT91 + depends on ARCH_AT91 || COMPILE_TEST select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help @@ -143,7 +143,7 @@ config BCM_SBA_RAID config DMA_BCM2835 tristate "BCM2835 DMA engine support" - depends on ARCH_BCM2835 + depends on ARCH_BCM2835 || COMPILE_TEST select DMA_ENGINE select DMA_VIRTUAL_CHANNELS diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 2d147712cbc69..7d226453961f8 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -887,7 +887,7 @@ atc_prep_dma_interleaved(struct dma_chan *chan, first = xt->sgl; dev_info(chan2dev(chan), - "%s: src=%pad, dest=%pad, numf=%d, frame_size=%d, flags=0x%lx\n", + "%s: src=%pad, dest=%pad, numf=%zu, frame_size=%zu, flags=0x%lx\n", __func__, &xt->src_start, &xt->dst_start, xt->numf, xt->frame_size, flags); @@ -1174,7 +1174,7 @@ atc_prep_dma_memset_sg(struct dma_chan *chan, int i; int ret; - dev_vdbg(chan2dev(chan), "%s: v0x%x l0x%zx f0x%lx\n", __func__, + dev_vdbg(chan2dev(chan), "%s: v0x%x l0x%x f0x%lx\n", __func__, value, sg_len, flags); if (unlikely(!sgl || !sg_len)) { @@ -1503,7 +1503,7 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, unsigned int periods = buf_len / period_len; unsigned int i; - dev_vdbg(chan2dev(chan), "prep_dma_cyclic: %s buf@%pad - %d (%d/%d)\n", + dev_vdbg(chan2dev(chan), "prep_dma_cyclic: %s buf@%pad - %d (%zu/%zu)\n", direction == DMA_MEM_TO_DEV ? "TO DEVICE" : "FROM DEVICE", &buf_addr, periods, buf_len, period_len); diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 0117bb2e8591b..321748e2983e5 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -1060,7 +1060,6 @@ static struct platform_driver bcm2835_dma_driver = { module_platform_driver(bcm2835_dma_driver); -MODULE_ALIAS("platform:bcm2835-dma"); MODULE_DESCRIPTION("BCM2835 DMA engine driver"); MODULE_AUTHOR("Florian Meier "); MODULE_LICENSE("GPL"); diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c index cee56cd31a611..c63fa52036d7f 100644 --- a/drivers/dma/dw/platform.c +++ b/drivers/dma/dw/platform.c @@ -21,8 +21,6 @@ #include "internal.h" -#define DRV_NAME "dw_dmac" - static int dw_probe(struct platform_device *pdev) { const struct dw_dma_chip_pdata *match; @@ -190,7 +188,7 @@ static struct platform_driver dw_driver = { .remove = dw_remove, .shutdown = dw_shutdown, .driver = { - .name = DRV_NAME, + .name = "dw_dmac", .pm = pm_sleep_ptr(&dw_dev_pm_ops), .of_match_table = of_match_ptr(dw_dma_of_id_table), .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table), @@ -211,4 +209,3 @@ module_exit(dw_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver"); -MODULE_ALIAS("platform:" DRV_NAME); diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c index 4976d7dde0809..a592127580299 100644 --- a/drivers/dma/fsl-edma-common.c +++ b/drivers/dma/fsl-edma-common.c @@ -206,15 +206,19 @@ void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan, mux_configure8(fsl_chan, muxaddr, ch_off, slot, enable); } -static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth addr_width) +static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth src_addr_width, + enum dma_slave_buswidth dst_addr_width) { - u32 val; + u32 src_val, dst_val; - if (addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) - addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + if (src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) + src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + if (dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) + dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - val = ffs(addr_width) - 1; - return val | (val << 8); + src_val = ffs(src_addr_width) - 1; + dst_val = ffs(dst_addr_width) - 1; + return dst_val | (src_val << 8); } void fsl_edma_free_desc(struct virt_dma_desc *vdesc) @@ -612,13 +616,19 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic( dma_buf_next = dma_addr; if (direction == DMA_MEM_TO_DEV) { + if (!fsl_chan->cfg.src_addr_width) + fsl_chan->cfg.src_addr_width = fsl_chan->cfg.dst_addr_width; fsl_chan->attr = - fsl_edma_get_tcd_attr(fsl_chan->cfg.dst_addr_width); + fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width, + fsl_chan->cfg.dst_addr_width); nbytes = fsl_chan->cfg.dst_addr_width * fsl_chan->cfg.dst_maxburst; } else { + if (!fsl_chan->cfg.dst_addr_width) + fsl_chan->cfg.dst_addr_width = fsl_chan->cfg.src_addr_width; fsl_chan->attr = - fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width); + fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width, + fsl_chan->cfg.dst_addr_width); nbytes = fsl_chan->cfg.src_addr_width * fsl_chan->cfg.src_maxburst; } @@ -689,13 +699,19 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( fsl_desc->dirn = direction; if (direction == DMA_MEM_TO_DEV) { + if (!fsl_chan->cfg.src_addr_width) + fsl_chan->cfg.src_addr_width = fsl_chan->cfg.dst_addr_width; fsl_chan->attr = - fsl_edma_get_tcd_attr(fsl_chan->cfg.dst_addr_width); + fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width, + fsl_chan->cfg.dst_addr_width); nbytes = fsl_chan->cfg.dst_addr_width * fsl_chan->cfg.dst_maxburst; } else { + if (!fsl_chan->cfg.dst_addr_width) + fsl_chan->cfg.dst_addr_width = fsl_chan->cfg.src_addr_width; fsl_chan->attr = - fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width); + fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width, + fsl_chan->cfg.dst_addr_width); nbytes = fsl_chan->cfg.src_addr_width * fsl_chan->cfg.src_maxburst; } @@ -766,6 +782,10 @@ struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(struct dma_chan *chan, { struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); struct fsl_edma_desc *fsl_desc; + u32 src_bus_width, dst_bus_width; + + src_bus_width = min_t(u32, DMA_SLAVE_BUSWIDTH_32_BYTES, 1 << (ffs(dma_src) - 1)); + dst_bus_width = min_t(u32, DMA_SLAVE_BUSWIDTH_32_BYTES, 1 << (ffs(dma_dst) - 1)); fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1); if (!fsl_desc) @@ -778,8 +798,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(struct dma_chan *chan, /* To match with copy_align and max_seg_size so 1 tcd is enough */ fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[0].vtcd, dma_src, dma_dst, - fsl_edma_get_tcd_attr(DMA_SLAVE_BUSWIDTH_32_BYTES), - 32, len, 0, 1, 1, 32, 0, true, true, false); + fsl_edma_get_tcd_attr(src_bus_width, dst_bus_width), + src_bus_width, len, 0, 1, 1, dst_bus_width, 0, true, + true, false); return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); } diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c index 97583c7d51a2e..a753b7cbfa7a3 100644 --- a/drivers/dma/fsl-edma-main.c +++ b/drivers/dma/fsl-edma-main.c @@ -999,6 +999,5 @@ static void __exit fsl_edma_exit(void) } module_exit(fsl_edma_exit); -MODULE_ALIAS("platform:fsl-edma"); MODULE_DESCRIPTION("Freescale eDMA engine driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c index 21e13f1207cbe..6ace5bf80c40b 100644 --- a/drivers/dma/fsl-qdma.c +++ b/drivers/dma/fsl-qdma.c @@ -1296,6 +1296,5 @@ static struct platform_driver fsl_qdma_driver = { module_platform_driver(fsl_qdma_driver); -MODULE_ALIAS("platform:fsl-qdma"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("NXP Layerscape qDMA engine driver"); diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 5cf419fe6b464..c2cdf41b6e576 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -16,6 +16,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand, u32 *status); static void idxd_device_wqs_clear_state(struct idxd_device *idxd); static void idxd_wq_disable_cleanup(struct idxd_wq *wq); +static int idxd_wq_config_write(struct idxd_wq *wq); /* Interrupt control bits */ void idxd_unmask_error_interrupts(struct idxd_device *idxd) @@ -215,14 +216,28 @@ int idxd_wq_disable(struct idxd_wq *wq, bool reset_config) return 0; } + /* + * Disable WQ does not drain address translations, if WQ attributes are + * changed before translations are drained, pending translations can + * be issued using updated WQ attibutes, resulting in invalid + * translations being cached in the device translation cache. + * + * To make sure pending translations are drained before WQ + * attributes are changed, we use a WQ Drain followed by WQ Reset and + * then restore the WQ configuration. + */ + idxd_wq_drain(wq); + operand = BIT(wq->id % 16) | ((wq->id / 16) << 16); - idxd_cmd_exec(idxd, IDXD_CMD_DISABLE_WQ, operand, &status); + idxd_cmd_exec(idxd, IDXD_CMD_RESET_WQ, operand, &status); if (status != IDXD_CMDSTS_SUCCESS) { - dev_dbg(dev, "WQ disable failed: %#x\n", status); + dev_dbg(dev, "WQ reset failed: %#x\n", status); return -ENXIO; } + idxd_wq_config_write(wq); + if (reset_config) idxd_wq_disable_cleanup(wq); clear_bit(wq->id, idxd->wq_enable_map); diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c index 02f68b3285112..227398673b731 100644 --- a/drivers/dma/ioat/init.c +++ b/drivers/dma/ioat/init.c @@ -1286,7 +1286,6 @@ static pci_ers_result_t ioat_pcie_error_slot_reset(struct pci_dev *pdev) } else { pci_set_master(pdev); pci_restore_state(pdev); - pci_save_state(pdev); pci_wake_from_d3(pdev, false); } diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index acc2983e28e0d..0f9cd7815f880 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -1034,5 +1034,4 @@ static struct platform_driver k3_pdma_driver = { module_platform_driver(k3_pdma_driver); MODULE_DESCRIPTION("HiSilicon k3 DMA Driver"); -MODULE_ALIAS("platform:k3dma"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index b7fb843c67a6f..ba03321eeff79 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c @@ -554,8 +554,7 @@ static void mmp_tdma_issue_pending(struct dma_chan *chan) static void mmp_tdma_remove(struct platform_device *pdev) { - if (pdev->dev.of_node) - of_dma_controller_free(pdev->dev.of_node); + of_dma_controller_free(pdev->dev.of_node); } static int mmp_tdma_chan_init(struct mmp_tdma_device *tdev, @@ -743,6 +742,5 @@ module_platform_driver(mmp_tdma_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MMP Two-Channel DMA Driver"); -MODULE_ALIAS("platform:mmp-tdma"); MODULE_AUTHOR("Leo Yan "); MODULE_AUTHOR("Zhangfei Gao "); diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c index 765462303de09..334425faac00b 100644 --- a/drivers/dma/nbpfaxi.c +++ b/drivers/dma/nbpfaxi.c @@ -1500,7 +1500,6 @@ static const struct platform_device_id nbpf_ids[] = { }; MODULE_DEVICE_TABLE(platform, nbpf_ids); -#ifdef CONFIG_PM static int nbpf_runtime_suspend(struct device *dev) { struct nbpf_device *nbpf = dev_get_drvdata(dev); @@ -1513,17 +1512,16 @@ static int nbpf_runtime_resume(struct device *dev) struct nbpf_device *nbpf = dev_get_drvdata(dev); return clk_prepare_enable(nbpf->clk); } -#endif static const struct dev_pm_ops nbpf_pm_ops = { - SET_RUNTIME_PM_OPS(nbpf_runtime_suspend, nbpf_runtime_resume, NULL) + RUNTIME_PM_OPS(nbpf_runtime_suspend, nbpf_runtime_resume, NULL) }; static struct platform_driver nbpf_driver = { .driver = { .name = "dma-nbpf", .of_match_table = nbpf_match, - .pm = &nbpf_pm_ops, + .pm = pm_ptr(&nbpf_pm_ops), }, .id_table = nbpf_ids, .probe = nbpf_probe, diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c index 8e87738086b25..66bfea1f156d1 100644 --- a/drivers/dma/qcom/gpi.c +++ b/drivers/dma/qcom/gpi.c @@ -1619,7 +1619,8 @@ gpi_peripheral_config(struct dma_chan *chan, struct dma_slave_config *config) } static int gpi_create_i2c_tre(struct gchan *chan, struct gpi_desc *desc, - struct scatterlist *sgl, enum dma_transfer_direction direction) + struct scatterlist *sgl, enum dma_transfer_direction direction, + unsigned long flags) { struct gpi_i2c_config *i2c = chan->config; struct device *dev = chan->gpii->gpi_dev->dev; @@ -1684,6 +1685,9 @@ static int gpi_create_i2c_tre(struct gchan *chan, struct gpi_desc *desc, tre->dword[3] = u32_encode_bits(TRE_TYPE_DMA, TRE_FLAGS_TYPE); tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_IEOT); + + if (!(flags & DMA_PREP_INTERRUPT)) + tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_BEI); } for (i = 0; i < tre_idx; i++) @@ -1827,6 +1831,9 @@ gpi_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; } + if (!(flags & DMA_PREP_INTERRUPT) && (nr - nr_tre < 2)) + return NULL; + gpi_desc = kzalloc(sizeof(*gpi_desc), GFP_NOWAIT); if (!gpi_desc) return NULL; @@ -1835,7 +1842,7 @@ gpi_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (gchan->protocol == QCOM_GPI_SPI) { i = gpi_create_spi_tre(gchan, gpi_desc, sgl, direction); } else if (gchan->protocol == QCOM_GPI_I2C) { - i = gpi_create_i2c_tre(gchan, gpi_desc, sgl, direction); + i = gpi_create_i2c_tre(gchan, gpi_desc, sgl, direction, flags); } else { dev_err(dev, "invalid peripheral: %d\n", gchan->protocol); kfree(gpi_desc); diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig index 8184d475a49a1..a16c7e83bd14a 100644 --- a/drivers/dma/sh/Kconfig +++ b/drivers/dma/sh/Kconfig @@ -50,7 +50,7 @@ config RENESAS_USB_DMAC config RZ_DMAC tristate "Renesas RZ DMA Controller" - depends on ARCH_R7S72100 || ARCH_RZG2L || COMPILE_TEST + depends on ARCH_RENESAS || COMPILE_TEST select RENESAS_DMA select DMA_VIRTUAL_CHANNELS help diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 0c45ce8c74aa2..475a347cae1b6 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -1728,19 +1728,12 @@ static struct dma_chan *rcar_dmac_of_xlate(struct of_phandle_args *dma_spec, * Power management */ -#ifdef CONFIG_PM -static int rcar_dmac_runtime_suspend(struct device *dev) -{ - return 0; -} - static int rcar_dmac_runtime_resume(struct device *dev) { struct rcar_dmac *dmac = dev_get_drvdata(dev); return rcar_dmac_init(dmac); } -#endif static const struct dev_pm_ops rcar_dmac_pm = { /* @@ -1748,10 +1741,9 @@ static const struct dev_pm_ops rcar_dmac_pm = { * - Wait for the current transfer to complete and stop the device, * - Resume transfers, if any. */ - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) - SET_RUNTIME_PM_OPS(rcar_dmac_runtime_suspend, rcar_dmac_runtime_resume, - NULL) + NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) + RUNTIME_PM_OPS(NULL, rcar_dmac_runtime_resume, NULL) }; /* ----------------------------------------------------------------------------- @@ -2036,7 +2028,7 @@ MODULE_DEVICE_TABLE(of, rcar_dmac_of_ids); static struct platform_driver rcar_dmac_driver = { .driver = { - .pm = &rcar_dmac_pm, + .pm = pm_ptr(&rcar_dmac_pm), .name = "rcar-dmac", .of_match_table = rcar_dmac_of_ids, }, diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index 7e2b6c97fa2f9..b42e5a66fd957 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c @@ -670,7 +670,6 @@ static struct dma_chan *usb_dmac_of_xlate(struct of_phandle_args *dma_spec, * Power management */ -#ifdef CONFIG_PM static int usb_dmac_runtime_suspend(struct device *dev) { struct usb_dmac *dmac = dev_get_drvdata(dev); @@ -691,13 +690,11 @@ static int usb_dmac_runtime_resume(struct device *dev) return usb_dmac_init(dmac); } -#endif /* CONFIG_PM */ static const struct dev_pm_ops usb_dmac_pm = { - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) - SET_RUNTIME_PM_OPS(usb_dmac_runtime_suspend, usb_dmac_runtime_resume, - NULL) + NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) + RUNTIME_PM_OPS(usb_dmac_runtime_suspend, usb_dmac_runtime_resume, NULL) }; /* ----------------------------------------------------------------------------- @@ -894,7 +891,7 @@ MODULE_DEVICE_TABLE(of, usb_dmac_of_ids); static struct platform_driver usb_dmac_driver = { .driver = { - .pm = &usb_dmac_pm, + .pm = pm_ptr(&usb_dmac_pm), .name = "usb-dmac", .of_match_table = usb_dmac_of_ids, }, diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c index 187a090463ced..6207e0b185e1d 100644 --- a/drivers/dma/sprd-dma.c +++ b/drivers/dma/sprd-dma.c @@ -1311,4 +1311,3 @@ MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("DMA driver for Spreadtrum"); MODULE_AUTHOR("Baolin Wang "); MODULE_AUTHOR("Eric Long "); -MODULE_ALIAS("platform:sprd-dma"); diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c index c65ee0c7bfbdb..dc2ab7d16cf2a 100644 --- a/drivers/dma/st_fdma.c +++ b/drivers/dma/st_fdma.c @@ -866,4 +866,3 @@ MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver"); MODULE_AUTHOR("Ludovic.barre "); MODULE_AUTHOR("Peter Griffin "); -MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index fad896ff29a2d..d0e8bb27a03b8 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -1230,7 +1230,6 @@ static struct platform_driver tegra_admac_driver = { module_platform_driver(tegra_admac_driver); -MODULE_ALIAS("platform:tegra210-adma"); MODULE_DESCRIPTION("NVIDIA Tegra ADMA driver"); MODULE_AUTHOR("Dara Ramesh "); MODULE_AUTHOR("Jon Hunter "); diff --git a/drivers/edac/ie31200_edac.c b/drivers/edac/ie31200_edac.c index 8d4ddaa85ae82..eaab6af143e1b 100644 --- a/drivers/edac/ie31200_edac.c +++ b/drivers/edac/ie31200_edac.c @@ -44,6 +44,7 @@ * but lo_hi_readq() ensures that we are safe across all e3-1200 processors. */ +#include #include #include #include @@ -139,9 +140,6 @@ #define IE31200_CAPID0_DDPCD BIT(6) #define IE31200_CAPID0_ECC BIT(1) -/* Non-constant mask variant of FIELD_GET() */ -#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) - static int nr_channels; static struct pci_dev *mci_pdev; static int ie31200_registered = 1; diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c index edceea083b980..bd76d599109ce 100644 --- a/drivers/eisa/eisa-bus.c +++ b/drivers/eisa/eisa-bus.c @@ -135,7 +135,7 @@ static int eisa_bus_uevent(const struct device *dev, struct kobj_uevent_env *env return 0; } -struct bus_type eisa_bus_type = { +const struct bus_type eisa_bus_type = { .name = "eisa", .match = eisa_bus_match, .uevent = eisa_bus_uevent, diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 66e1106db5e74..0462d7b9e547a 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -86,8 +86,6 @@ static size_t config_rom_length = 1 + 4 + 1 + 1; */ #define DEFAULT_SPLIT_TIMEOUT (2 * 8000) -#define CANON_OUI 0x000085 - static void generate_config_rom(struct fw_card *card, __be32 *config_rom) { struct fw_descriptor *desc; @@ -308,11 +306,9 @@ __must_hold(&card->lock) cpu_to_be32(local_id), }; bool grace = time_is_before_jiffies64(card->reset_jiffies + msecs_to_jiffies(125)); - bool irm_is_1394_1995_only = false; - bool keep_this_irm = false; struct fw_node *irm_node; struct fw_device *irm_device; - int irm_node_id; + int irm_node_id, irm_device_quirks = 0; int rcode; lockdep_assert_held(&card->lock); @@ -328,15 +324,12 @@ __must_hold(&card->lock) return BM_CONTENTION_OUTCOME_IRM_HAS_LINK_OFF; } + // NOTE: It is likely that the quirk detection for IRM device has not done yet. irm_device = fw_node_get_device(irm_node); - if (irm_device && irm_device->config_rom) { - irm_is_1394_1995_only = (irm_device->config_rom[2] & 0x000000f0) == 0; - - // Canon MV5i works unreliably if it is not root node. - keep_this_irm = irm_device->config_rom[3] >> 8 == CANON_OUI; - } - - if (irm_is_1394_1995_only && !keep_this_irm) { + if (irm_device) + irm_device_quirks = READ_ONCE(irm_device->quirks); + if ((irm_device_quirks & FW_DEVICE_QUIRK_IRM_IS_1394_1995_ONLY) && + !(irm_device_quirks & FW_DEVICE_QUIRK_IRM_IGNORES_BUS_MANAGER)) { fw_notice(card, "IRM is not 1394a compliant, making local node (%02x) root\n", local_id); return BM_CONTENTION_OUTCOME_IRM_COMPLIES_1394_1995_ONLY; @@ -373,7 +366,7 @@ __must_hold(&card->lock) return BM_CONTENTION_OUTCOME_IRM_HOLDS_LOCAL_NODE_AS_BM; } default: - if (!keep_this_irm) { + if (!(irm_device_quirks & FW_DEVICE_QUIRK_IRM_IGNORES_BUS_MANAGER)) { fw_notice(card, "BM lock failed (%s), making local node (%02x) root\n", fw_rcode_string(rcode), local_id); return BM_CONTENTION_OUTCOME_IRM_COMPLIES_1394_1995_ONLY; @@ -793,9 +786,13 @@ void fw_core_remove_card(struct fw_card *card) /* Switch off most of the card driver interface. */ dummy_driver.free_iso_context = card->driver->free_iso_context; dummy_driver.stop_iso = card->driver->stop_iso; + dummy_driver.disable = card->driver->disable; card->driver = &dummy_driver; + drain_workqueue(card->isoc_wq); drain_workqueue(card->async_wq); + card->driver->disable(card); + fw_cancel_pending_transactions(card); scoped_guard(spinlock_irqsave, &card->lock) fw_destroy_nodes(card); diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 457a0da024a76..9b0080397154d 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -542,8 +542,83 @@ static struct device_attribute fw_device_attributes[] = { __ATTR_NULL, }; -static int read_rom(struct fw_device *device, - int generation, int index, u32 *data) +#define CANON_OUI 0x000085 + +static int detect_quirks_by_bus_information_block(const u32 *bus_information_block) +{ + int quirks = 0; + + if ((bus_information_block[2] & 0x000000f0) == 0) + quirks |= FW_DEVICE_QUIRK_IRM_IS_1394_1995_ONLY; + + if ((bus_information_block[3] >> 8) == CANON_OUI) + quirks |= FW_DEVICE_QUIRK_IRM_IGNORES_BUS_MANAGER; + + return quirks; +} + +struct entry_match { + unsigned int index; + u32 value; +}; + +static const struct entry_match motu_audio_express_matches[] = { + { 1, 0x030001f2 }, + { 3, 0xd1000002 }, + { 4, 0x8d000005 }, + { 6, 0x120001f2 }, + { 7, 0x13000033 }, + { 8, 0x17104800 }, +}; + +static const struct entry_match tascam_fw_series_matches[] = { + { 1, 0x0300022e }, + { 3, 0x8d000006 }, + { 4, 0xd1000001 }, + { 6, 0x1200022e }, + { 8, 0xd4000004 }, +}; + +static int detect_quirks_by_root_directory(const u32 *root_directory, unsigned int length) +{ + static const struct { + enum fw_device_quirk quirk; + const struct entry_match *matches; + unsigned int match_count; + } *entry, entries[] = { + { + .quirk = FW_DEVICE_QUIRK_ACK_PACKET_WITH_INVALID_PENDING_CODE, + .matches = motu_audio_express_matches, + .match_count = ARRAY_SIZE(motu_audio_express_matches), + }, + { + .quirk = FW_DEVICE_QUIRK_UNSTABLE_AT_S400, + .matches = tascam_fw_series_matches, + .match_count = ARRAY_SIZE(tascam_fw_series_matches), + }, + }; + int quirks = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(entries); ++i) { + int j; + + entry = entries + i; + for (j = 0; j < entry->match_count; ++j) { + unsigned int index = entry->matches[j].index; + unsigned int value = entry->matches[j].value; + + if ((length < index) || (root_directory[index] != value)) + break; + } + if (j == entry->match_count) + quirks |= entry->quirk; + } + + return quirks; +} + +static int read_rom(struct fw_device *device, int generation, int speed, int index, u32 *data) { u64 offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4; int i, rcode; @@ -554,7 +629,7 @@ static int read_rom(struct fw_device *device, for (i = 10; i < 100; i += 10) { rcode = fw_run_transaction(device->card, TCODE_READ_QUADLET_REQUEST, device->node_id, - generation, device->max_speed, offset, data, 4); + generation, speed, offset, data, 4); if (rcode != RCODE_BUSY) break; msleep(i); @@ -578,10 +653,11 @@ static int read_rom(struct fw_device *device, static int read_config_rom(struct fw_device *device, int generation) { struct fw_card *card = device->card; - const u32 *old_rom, *new_rom; - u32 *rom, *stack; + const u32 *new_rom, *old_rom __free(kfree) = NULL; + u32 *stack, *rom __free(kfree) = NULL; u32 sp, key; - int i, end, length, ret; + int i, end, length, ret, speed; + int quirks; rom = kmalloc(sizeof(*rom) * MAX_CONFIG_ROM_SIZE + sizeof(*stack) * MAX_CONFIG_ROM_SIZE, GFP_KERNEL); @@ -591,13 +667,13 @@ static int read_config_rom(struct fw_device *device, int generation) stack = &rom[MAX_CONFIG_ROM_SIZE]; memset(rom, 0, sizeof(*rom) * MAX_CONFIG_ROM_SIZE); - device->max_speed = SCODE_100; + speed = SCODE_100; /* First read the bus info block. */ for (i = 0; i < 5; i++) { - ret = read_rom(device, generation, i, &rom[i]); + ret = read_rom(device, generation, speed, i, &rom[i]); if (ret != RCODE_COMPLETE) - goto out; + return ret; /* * As per IEEE1212 7.2, during initialization, devices can * reply with a 0 for the first quadlet of the config @@ -606,39 +682,14 @@ static int read_config_rom(struct fw_device *device, int generation) * harddisk). In that case we just fail, and the * retry mechanism will try again later. */ - if (i == 0 && rom[i] == 0) { - ret = RCODE_BUSY; - goto out; - } + if (i == 0 && rom[i] == 0) + return RCODE_BUSY; } - device->max_speed = device->node->max_speed; - - /* - * Determine the speed of - * - devices with link speed less than PHY speed, - * - devices with 1394b PHY (unless only connected to 1394a PHYs), - * - all devices if there are 1394b repeaters. - * Note, we cannot use the bus info block's link_spd as starting point - * because some buggy firmwares set it lower than necessary and because - * 1394-1995 nodes do not have the field. - */ - if ((rom[2] & 0x7) < device->max_speed || - device->max_speed == SCODE_BETA || - card->beta_repeaters_present) { - u32 dummy; - - /* for S1600 and S3200 */ - if (device->max_speed == SCODE_BETA) - device->max_speed = card->link_speed; + quirks = detect_quirks_by_bus_information_block(rom); - while (device->max_speed > SCODE_100) { - if (read_rom(device, generation, 0, &dummy) == - RCODE_COMPLETE) - break; - device->max_speed--; - } - } + // Just prevent from torn writing/reading. + WRITE_ONCE(device->quirks, quirks); /* * Now parse the config rom. The config rom is a recursive @@ -659,15 +710,13 @@ static int read_config_rom(struct fw_device *device, int generation) */ key = stack[--sp]; i = key & 0xffffff; - if (WARN_ON(i >= MAX_CONFIG_ROM_SIZE)) { - ret = -ENXIO; - goto out; - } + if (WARN_ON(i >= MAX_CONFIG_ROM_SIZE)) + return -ENXIO; /* Read header quadlet for the block to get the length. */ - ret = read_rom(device, generation, i, &rom[i]); + ret = read_rom(device, generation, speed, i, &rom[i]); if (ret != RCODE_COMPLETE) - goto out; + return ret; end = i + (rom[i] >> 16) + 1; if (end > MAX_CONFIG_ROM_SIZE) { /* @@ -689,9 +738,9 @@ static int read_config_rom(struct fw_device *device, int generation) * it references another block, and push it in that case. */ for (; i < end; i++) { - ret = read_rom(device, generation, i, &rom[i]); + ret = read_rom(device, generation, speed, i, &rom[i]); if (ret != RCODE_COMPLETE) - goto out; + return ret; if ((key >> 30) != 3 || (rom[i] >> 30) < 2) continue; @@ -716,27 +765,54 @@ static int read_config_rom(struct fw_device *device, int generation) length = i; } + quirks |= detect_quirks_by_root_directory(rom + ROOT_DIR_OFFSET, length - ROOT_DIR_OFFSET); + + // Just prevent from torn writing/reading. + WRITE_ONCE(device->quirks, quirks); + + if (unlikely(quirks & FW_DEVICE_QUIRK_UNSTABLE_AT_S400)) + speed = SCODE_200; + else + speed = device->node->max_speed; + + // Determine the speed of + // - devices with link speed less than PHY speed, + // - devices with 1394b PHY (unless only connected to 1394a PHYs), + // - all devices if there are 1394b repeaters. + // Note, we cannot use the bus info block's link_spd as starting point because some buggy + // firmwares set it lower than necessary and because 1394-1995 nodes do not have the field. + if ((rom[2] & 0x7) < speed || speed == SCODE_BETA || card->beta_repeaters_present) { + u32 dummy; + + // for S1600 and S3200. + if (speed == SCODE_BETA) + speed = card->link_speed; + + while (speed > SCODE_100) { + if (read_rom(device, generation, speed, 0, &dummy) == + RCODE_COMPLETE) + break; + --speed; + } + } + + device->max_speed = speed; + old_rom = device->config_rom; new_rom = kmemdup(rom, length * 4, GFP_KERNEL); - if (new_rom == NULL) { - ret = -ENOMEM; - goto out; - } + if (new_rom == NULL) + return -ENOMEM; scoped_guard(rwsem_write, &fw_device_rwsem) { device->config_rom = new_rom; device->config_rom_length = length; } - kfree(old_rom); - ret = RCODE_COMPLETE; device->max_rec = rom[2] >> 12 & 0xf; device->cmc = rom[2] >> 30 & 1; device->irmc = rom[2] >> 31 & 1; - out: - kfree(rom); - return ret; + return RCODE_COMPLETE; } static void fw_unit_release(struct device *dev) @@ -1122,10 +1198,10 @@ static void fw_device_init(struct work_struct *work) device->workfn = fw_device_shutdown; fw_schedule_device_work(device, SHUTDOWN_DELAY); } else { - fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n", + fw_notice(card, "created device %s: GUID %08x%08x, S%d00, quirks %08x\n", dev_name(&device->device), device->config_rom[3], device->config_rom[4], - 1 << device->max_speed); + 1 << device->max_speed, device->quirks); device->config_rom_retries = 0; set_broadcast_channel(device, device->generation); @@ -1160,7 +1236,7 @@ static int reread_config_rom(struct fw_device *device, int generation, int i, rcode; for (i = 0; i < 6; i++) { - rcode = read_rom(device, generation, i, &q); + rcode = read_rom(device, generation, device->max_speed, i, &q); if (rcode != RCODE_COMPLETE) return rcode; diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index c65f491c54d06..7fea11a5e359c 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -44,28 +44,68 @@ static int try_cancel_split_timeout(struct fw_transaction *t) return 1; } -static int close_transaction(struct fw_transaction *transaction, struct fw_card *card, int rcode, - u32 response_tstamp) +// card->transactions.lock must be acquired in advance. +static void remove_transaction_entry(struct fw_card *card, struct fw_transaction *entry) { - struct fw_transaction *t = NULL, *iter; + list_del_init(&entry->link); + card->transactions.tlabel_mask &= ~(1ULL << entry->tlabel); +} + +// Must be called without holding card->transactions.lock. +void fw_cancel_pending_transactions(struct fw_card *card) +{ + struct fw_transaction *t, *tmp; + LIST_HEAD(pending_list); // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for // local destination never runs in any type of IRQ context. scoped_guard(spinlock_irqsave, &card->transactions.lock) { - list_for_each_entry(iter, &card->transactions.list, link) { - if (iter == transaction) { - if (try_cancel_split_timeout(iter)) { - list_del_init(&iter->link); - card->transactions.tlabel_mask &= ~(1ULL << iter->tlabel); - t = iter; - } - break; - } + list_for_each_entry_safe(t, tmp, &card->transactions.list, link) { + if (try_cancel_split_timeout(t)) + list_move(&t->link, &pending_list); } } - if (!t) - return -ENOENT; + list_for_each_entry_safe(t, tmp, &pending_list, link) { + list_del(&t->link); + + if (!t->with_tstamp) { + t->callback.without_tstamp(card, RCODE_CANCELLED, NULL, 0, + t->callback_data); + } else { + t->callback.with_tstamp(card, RCODE_CANCELLED, t->packet.timestamp, 0, + NULL, 0, t->callback_data); + } + } +} + +// card->transactions.lock must be acquired in advance. +#define find_and_pop_transaction_entry(card, condition) \ +({ \ + struct fw_transaction *iter, *t = NULL; \ + list_for_each_entry(iter, &card->transactions.list, link) { \ + if (condition) { \ + t = iter; \ + break; \ + } \ + } \ + if (t && try_cancel_split_timeout(t)) \ + remove_transaction_entry(card, t); \ + t; \ +}) + +static int close_transaction(struct fw_transaction *transaction, struct fw_card *card, int rcode, + u32 response_tstamp) +{ + struct fw_transaction *t; + + // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for + // local destination never runs in any type of IRQ context. + scoped_guard(spinlock_irqsave, &card->transactions.lock) { + t = find_and_pop_transaction_entry(card, iter == transaction); + if (!t) + return -ENOENT; + } if (!t->with_tstamp) { t->callback.without_tstamp(card, rcode, NULL, 0, t->callback_data); @@ -122,8 +162,7 @@ static void split_transaction_timeout_callback(struct timer_list *timer) scoped_guard(spinlock_irqsave, &card->transactions.lock) { if (list_empty(&t->link)) return; - list_del(&t->link); - card->transactions.tlabel_mask &= ~(1ULL << t->tlabel); + remove_transaction_entry(card, t); } if (!t->with_tstamp) { @@ -1097,7 +1136,7 @@ EXPORT_SYMBOL(fw_core_handle_request); void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) { - struct fw_transaction *t = NULL, *iter; + struct fw_transaction *t = NULL; u32 *data; size_t data_length; int tcode, tlabel, source, rcode; @@ -1139,16 +1178,8 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for // local destination never runs in any type of IRQ context. scoped_guard(spinlock_irqsave, &card->transactions.lock) { - list_for_each_entry(iter, &card->transactions.list, link) { - if (iter->node_id == source && iter->tlabel == tlabel) { - if (try_cancel_split_timeout(iter)) { - list_del_init(&iter->link); - card->transactions.tlabel_mask &= ~(1ULL << iter->tlabel); - t = iter; - } - break; - } - } + t = find_and_pop_transaction_entry(card, + iter->node_id == source && iter->tlabel == tlabel); } trace_async_response_inbound((uintptr_t)t, card->index, p->generation, p->speed, p->ack, @@ -1437,7 +1468,8 @@ static int __init fw_core_init(void) { int ret; - fw_workqueue = alloc_workqueue("firewire", WQ_MEM_RECLAIM, 0); + fw_workqueue = alloc_workqueue("firewire", WQ_MEM_RECLAIM | WQ_UNBOUND, + 0); if (!fw_workqueue) return -ENOMEM; diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index e67395ce26b5e..41fb39d9a4e69 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -65,6 +65,9 @@ struct fw_card_driver { int (*enable)(struct fw_card *card, const __be32 *config_rom, size_t length); + // After returning the call, any function is no longer triggered to handle hardware event. + void (*disable)(struct fw_card *card); + int (*read_phy_reg)(struct fw_card *card, int address); int (*update_phy_reg)(struct fw_card *card, int address, int clear_bits, int set_bits); @@ -284,6 +287,8 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header, void fw_request_get(struct fw_request *request); void fw_request_put(struct fw_request *request); +void fw_cancel_pending_transactions(struct fw_card *card); + // Convert the value of IEEE 1394 CYCLE_TIME register to the format of timeStamp field in // descriptors of 1394 OHCI. static inline u32 cycle_time_to_ohci_tstamp(u32 tstamp) diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c index ea31ac7ac1ca9..e59053738a432 100644 --- a/drivers/firewire/nosy.c +++ b/drivers/firewire/nosy.c @@ -36,6 +36,8 @@ static char driver_name[] = KBUILD_MODNAME; +#define RCV_BUFFER_SIZE (16 * 1024) + /* this is the physical layout of a PCL, its size is 128 bytes */ struct pcl { __le32 next; @@ -517,16 +519,14 @@ remove_card(struct pci_dev *dev) lynx->rcv_start_pcl, lynx->rcv_start_pcl_bus); dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl), lynx->rcv_pcl, lynx->rcv_pcl_bus); - dma_free_coherent(&lynx->pci_device->dev, PAGE_SIZE, lynx->rcv_buffer, - lynx->rcv_buffer_bus); + dma_free_coherent(&lynx->pci_device->dev, RCV_BUFFER_SIZE, + lynx->rcv_buffer, lynx->rcv_buffer_bus); iounmap(lynx->registers); pci_disable_device(dev); lynx_put(lynx); } -#define RCV_BUFFER_SIZE (16 * 1024) - static int add_card(struct pci_dev *dev, const struct pci_device_id *unused) { @@ -680,7 +680,7 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused) dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl), lynx->rcv_pcl, lynx->rcv_pcl_bus); if (lynx->rcv_buffer) - dma_free_coherent(&lynx->pci_device->dev, PAGE_SIZE, + dma_free_coherent(&lynx->pci_device->dev, RCV_BUFFER_SIZE, lynx->rcv_buffer, lynx->rcv_buffer_bus); iounmap(lynx->registers); diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 030aed5453a17..e3e78dc42530b 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -1319,6 +1319,14 @@ static void at_context_flush(struct at_context *ctx) enable_work(&ctx->work); } +static int find_fw_device(struct device *dev, const void *data) +{ + struct fw_device *device = fw_device(dev); + const u32 *params = data; + + return (device->generation == params[0]) && (device->node_id == params[1]); +} + static int handle_at_packet(struct context *context, struct descriptor *d, struct descriptor *last) @@ -1390,6 +1398,27 @@ static int handle_at_packet(struct context *context, fallthrough; default: + if (unlikely(evt == 0x10)) { + u32 params[2] = { + packet->generation, + async_header_get_destination(packet->header), + }; + struct device *dev; + + fw_card_get(&ohci->card); + dev = device_find_child(ohci->card.device, (const void *)params, find_fw_device); + fw_card_put(&ohci->card); + if (dev) { + struct fw_device *device = fw_device(dev); + int quirks = READ_ONCE(device->quirks); + + put_device(dev); + if (quirks & FW_DEVICE_QUIRK_ACK_PACKET_WITH_INVALID_PENDING_CODE) { + packet->ack = ACK_PENDING; + break; + } + } + } packet->ack = RCODE_SEND_ERROR; break; } @@ -2379,6 +2408,41 @@ static int ohci_enable(struct fw_card *card, return 0; } +static void ohci_disable(struct fw_card *card) +{ + struct pci_dev *pdev = to_pci_dev(card->device); + struct fw_ohci *ohci = pci_get_drvdata(pdev); + int i, irq = pci_irq_vector(pdev, 0); + + // If the removal is happening from the suspend state, LPS won't be enabled and host + // registers (eg., IntMaskClear) won't be accessible. + if (!(reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_LPS)) + return; + + reg_write(ohci, OHCI1394_IntMaskClear, ~0); + flush_writes(ohci); + + if (irq >= 0) + synchronize_irq(irq); + + flush_work(&ohci->ar_request_ctx.work); + flush_work(&ohci->ar_response_ctx.work); + flush_work(&ohci->at_request_ctx.work); + flush_work(&ohci->at_response_ctx.work); + + for (i = 0; i < ohci->n_ir; ++i) { + if (!(ohci->ir_context_mask & BIT(i))) + flush_work(&ohci->ir_context_list[i].base.work); + } + for (i = 0; i < ohci->n_it; ++i) { + if (!(ohci->it_context_mask & BIT(i))) + flush_work(&ohci->it_context_list[i].base.work); + } + + at_context_flush(&ohci->at_request_ctx); + at_context_flush(&ohci->at_response_ctx); +} + static int ohci_set_config_rom(struct fw_card *card, const __be32 *config_rom, size_t length) { @@ -3413,6 +3477,7 @@ static int ohci_flush_iso_completions(struct fw_iso_context *base) static const struct fw_card_driver ohci_driver = { .enable = ohci_enable, + .disable = ohci_disable, .read_phy_reg = ohci_read_phy_reg, .update_phy_reg = ohci_update_phy_reg, .set_config_rom = ohci_set_config_rom, @@ -3652,21 +3717,8 @@ static void pci_remove(struct pci_dev *dev) struct fw_ohci *ohci = pci_get_drvdata(dev); int irq; - /* - * If the removal is happening from the suspend state, LPS won't be - * enabled and host registers (eg., IntMaskClear) won't be accessible. - */ - if (reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_LPS) { - reg_write(ohci, OHCI1394_IntMaskClear, ~0); - flush_writes(ohci); - } fw_core_remove_card(&ohci->card); - /* - * FIXME: Fail all pending packets here, now that the upper - * layers can't queue any more. - */ - software_reset(ohci); irq = pci_irq_vector(dev, 0); diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index f51047d8ea64f..525ac0f0a75d8 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -9,9 +9,11 @@ * Cirrus Logic International Semiconductor Ltd. */ +#include #include #include #include +#include #include #include #include @@ -316,44 +318,6 @@ struct cs_dsp_alg_region_list_item { struct cs_dsp_alg_region alg_region; }; -struct cs_dsp_buf { - struct list_head list; - void *buf; -}; - -static struct cs_dsp_buf *cs_dsp_buf_alloc(const void *src, size_t len, - struct list_head *list) -{ - struct cs_dsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); - - if (buf == NULL) - return NULL; - - buf->buf = vmalloc(len); - if (!buf->buf) { - kfree(buf); - return NULL; - } - memcpy(buf->buf, src, len); - - if (list) - list_add_tail(&buf->list, list); - - return buf; -} - -static void cs_dsp_buf_free(struct list_head *list) -{ - while (!list_empty(list)) { - struct cs_dsp_buf *buf = list_first_entry(list, - struct cs_dsp_buf, - list); - list_del(&buf->list); - vfree(buf->buf); - kfree(buf); - } -} - /** * cs_dsp_mem_region_name() - Return a name string for a memory type * @type: the memory type to match @@ -388,18 +352,14 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_mem_region_name, "FW_CS_DSP"); #ifdef CONFIG_DEBUG_FS static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) { - char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); - kfree(dsp->wmfw_file_name); - dsp->wmfw_file_name = tmp; + dsp->wmfw_file_name = kstrdup(s, GFP_KERNEL); } static void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, const char *s) { - char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); - kfree(dsp->bin_file_name); - dsp->bin_file_name = tmp; + dsp->bin_file_name = kstrdup(s, GFP_KERNEL); } static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) @@ -410,24 +370,33 @@ static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) dsp->bin_file_name = NULL; } +static ssize_t cs_dsp_debugfs_string_read(struct cs_dsp *dsp, + char __user *user_buf, + size_t count, loff_t *ppos, + const char **pstr) +{ + const char *str __free(kfree) = NULL; + + scoped_guard(mutex, &dsp->pwr_lock) { + if (!*pstr) + return 0; + + str = kasprintf(GFP_KERNEL, "%s\n", *pstr); + if (!str) + return -ENOMEM; + + return simple_read_from_buffer(user_buf, count, ppos, str, strlen(str)); + } +} + static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct cs_dsp *dsp = file->private_data; - ssize_t ret; - - mutex_lock(&dsp->pwr_lock); - if (!dsp->wmfw_file_name || !dsp->booted) - ret = 0; - else - ret = simple_read_from_buffer(user_buf, count, ppos, - dsp->wmfw_file_name, - strlen(dsp->wmfw_file_name)); - - mutex_unlock(&dsp->pwr_lock); - return ret; + return cs_dsp_debugfs_string_read(dsp, user_buf, count, ppos, + &dsp->wmfw_file_name); } static ssize_t cs_dsp_debugfs_bin_read(struct file *file, @@ -435,19 +404,9 @@ static ssize_t cs_dsp_debugfs_bin_read(struct file *file, size_t count, loff_t *ppos) { struct cs_dsp *dsp = file->private_data; - ssize_t ret; - - mutex_lock(&dsp->pwr_lock); - if (!dsp->bin_file_name || !dsp->booted) - ret = 0; - else - ret = simple_read_from_buffer(user_buf, count, ppos, - dsp->bin_file_name, - strlen(dsp->bin_file_name)); - - mutex_unlock(&dsp->pwr_lock); - return ret; + return cs_dsp_debugfs_string_read(dsp, user_buf, count, ppos, + &dsp->bin_file_name); } static const struct { @@ -479,9 +438,11 @@ static int cs_dsp_debugfs_read_controls_show(struct seq_file *s, void *ignored) struct cs_dsp_coeff_ctl *ctl; unsigned int reg; + guard(mutex)(&dsp->pwr_lock); + list_for_each_entry(ctl, &dsp->ctl_list, list) { cs_dsp_coeff_base_reg(ctl, ®, 0); - seq_printf(s, "%22.*s: %#8zx %s:%08x %#8x %s %#8x %#4x %c%c%c%c %s %s\n", + seq_printf(s, "%22.*s: %#8x %s:%08x %#8x %s %#8x %#4x %c%c%c%c %s %s\n", ctl->subname_len, ctl->subname, ctl->len, cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset, reg, ctl->fw_name, ctl->alg_region.alg, ctl->type, @@ -1028,7 +989,7 @@ static void cs_dsp_signal_event_controls(struct cs_dsp *dsp, static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) { - kfree(ctl->cache); + kvfree(ctl->cache); kfree(ctl->subname); kfree(ctl); } @@ -1078,7 +1039,7 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, ctl->type = type; ctl->offset = offset; ctl->len = len; - ctl->cache = kzalloc(ctl->len, GFP_KERNEL); + ctl->cache = kvzalloc(ctl->len, GFP_KERNEL); if (!ctl->cache) { ret = -ENOMEM; goto err_ctl_subname; @@ -1096,7 +1057,7 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, err_list_del: list_del(&ctl->list); - kfree(ctl->cache); + kvfree(ctl->cache); err_ctl_subname: kfree(ctl->subname); err_ctl: @@ -1485,7 +1446,9 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, const struct wmfw_region *region; const struct cs_dsp_region *mem; const char *region_name; - struct cs_dsp_buf *buf; + u8 *buf __free(kfree) = NULL; + size_t buf_len = 0; + size_t region_len; unsigned int reg; int regions = 0; int ret, offset, type; @@ -1605,23 +1568,23 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, region_name); if (reg) { - buf = cs_dsp_buf_alloc(region->data, - le32_to_cpu(region->len), - &buf_list); - if (!buf) { - cs_dsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; + region_len = le32_to_cpu(region->len); + if (region_len > buf_len) { + buf_len = round_up(region_len, PAGE_SIZE); + kfree(buf); + buf = kmalloc(buf_len, GFP_KERNEL | GFP_DMA); + if (!buf) { + ret = -ENOMEM; + goto out_fw; + } } - ret = regmap_raw_write(regmap, reg, buf->buf, - le32_to_cpu(region->len)); + memcpy(buf, region->data, region_len); + ret = regmap_raw_write(regmap, reg, buf, region_len); if (ret != 0) { cs_dsp_err(dsp, - "%s.%d: Failed to write %d bytes at %d in %s: %d\n", - file, regions, - le32_to_cpu(region->len), offset, - region_name, ret); + "%s.%d: Failed to write %zu bytes at %d in %s: %d\n", + file, regions, region_len, offset, region_name, ret); goto out_fw; } } @@ -1638,8 +1601,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, ret = 0; out_fw: - cs_dsp_buf_free(&buf_list); - if (ret == -EOVERFLOW) cs_dsp_err(dsp, "%s: file content overflows file data\n", file); @@ -2171,7 +2132,9 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware struct cs_dsp_alg_region *alg_region; const char *region_name; int ret, pos, blocks, type, offset, reg, version; - struct cs_dsp_buf *buf; + u8 *buf __free(kfree) = NULL; + size_t buf_len = 0; + size_t region_len; if (!firmware) return 0; @@ -2313,20 +2276,22 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware } if (reg) { - buf = cs_dsp_buf_alloc(blk->data, - le32_to_cpu(blk->len), - &buf_list); - if (!buf) { - cs_dsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; + region_len = le32_to_cpu(blk->len); + if (region_len > buf_len) { + buf_len = round_up(region_len, PAGE_SIZE); + kfree(buf); + buf = kmalloc(buf_len, GFP_KERNEL | GFP_DMA); + if (!buf) { + ret = -ENOMEM; + goto out_fw; + } } - cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", - file, blocks, le32_to_cpu(blk->len), - reg); - ret = regmap_raw_write(regmap, reg, buf->buf, - le32_to_cpu(blk->len)); + memcpy(buf, blk->data, region_len); + + cs_dsp_dbg(dsp, "%s.%d: Writing %zu bytes at %x\n", + file, blocks, region_len, reg); + ret = regmap_raw_write(regmap, reg, buf, region_len); if (ret != 0) { cs_dsp_err(dsp, "%s.%d: Failed to write to %x in %s: %d\n", @@ -2346,8 +2311,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware ret = 0; out_fw: - cs_dsp_buf_free(&buf_list); - if (ret == -EOVERFLOW) cs_dsp_err(dsp, "%s: file content overflows file data\n", file); @@ -2366,6 +2329,9 @@ static int cs_dsp_create_name(struct cs_dsp *dsp) return 0; } +static const struct cs_dsp_client_ops cs_dsp_default_client_ops = { +}; + static int cs_dsp_common_init(struct cs_dsp *dsp) { int ret; @@ -2379,6 +2345,9 @@ static int cs_dsp_common_init(struct cs_dsp *dsp) mutex_init(&dsp->pwr_lock); + if (!dsp->client_ops) + dsp->client_ops = &cs_dsp_default_client_ops; + #ifdef CONFIG_DEBUG_FS /* Ensure this is invalid if client never provides a debugfs root */ dsp->debugfs_root = ERR_PTR(-ENODEV); diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c b/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c index 8a9b66a3b7d35..e5a389808e5f2 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c @@ -600,6 +600,7 @@ KUNIT_ARRAY_PARAM(cs_dsp_callbacks_ops, static const struct cs_dsp_callbacks_test_param cs_dsp_no_callbacks_cases[] = { { .ops = &cs_dsp_callback_test_empty_client_ops, .case_name = "empty ops" }, + { .ops = NULL, .case_name = "NULL ops" }, }; KUNIT_ARRAY_PARAM(cs_dsp_no_callbacks, diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c index 83092d93f36a6..53a5336cde5af 100644 --- a/drivers/firmware/efi/arm-runtime.c +++ b/drivers/firmware/efi/arm-runtime.c @@ -12,18 +12,18 @@ #include #include #include +#include +#include #include #include #include #include #include #include -#include #include #include #include -#include #if defined(CONFIG_PTDUMP_DEBUGFS) || defined(CONFIG_ARM_PTDUMP_DEBUGFS) #include diff --git a/drivers/firmware/efi/cper-arm.c b/drivers/firmware/efi/cper-arm.c index f0a63d09d3c49..76542a53e2027 100644 --- a/drivers/firmware/efi/cper-arm.c +++ b/drivers/firmware/efi/cper-arm.c @@ -93,15 +93,11 @@ static void cper_print_arm_err_info(const char *pfx, u32 type, bool proc_context_corrupt, corrected, precise_pc, restartable_pc; bool time_out, access_mode; - /* If the type is unknown, bail. */ - if (type > CPER_ARM_MAX_TYPE) - return; - /* * Vendor type errors have error information values that are vendor * specific. */ - if (type == CPER_ARM_VENDOR_ERROR) + if (type & CPER_ARM_VENDOR_ERROR) return; if (error_info & CPER_ARM_ERR_VALID_TRANSACTION_TYPE) { @@ -116,43 +112,38 @@ static void cper_print_arm_err_info(const char *pfx, u32 type, if (error_info & CPER_ARM_ERR_VALID_OPERATION_TYPE) { op_type = ((error_info >> CPER_ARM_ERR_OPERATION_SHIFT) & CPER_ARM_ERR_OPERATION_MASK); - switch (type) { - case CPER_ARM_CACHE_ERROR: + if (type & CPER_ARM_CACHE_ERROR) { if (op_type < ARRAY_SIZE(arm_cache_err_op_strs)) { - printk("%soperation type: %s\n", pfx, + printk("%scache error, operation type: %s\n", pfx, arm_cache_err_op_strs[op_type]); } - break; - case CPER_ARM_TLB_ERROR: + } + if (type & CPER_ARM_TLB_ERROR) { if (op_type < ARRAY_SIZE(arm_tlb_err_op_strs)) { - printk("%soperation type: %s\n", pfx, + printk("%sTLB error, operation type: %s\n", pfx, arm_tlb_err_op_strs[op_type]); } - break; - case CPER_ARM_BUS_ERROR: + } + if (type & CPER_ARM_BUS_ERROR) { if (op_type < ARRAY_SIZE(arm_bus_err_op_strs)) { - printk("%soperation type: %s\n", pfx, + printk("%sbus error, operation type: %s\n", pfx, arm_bus_err_op_strs[op_type]); } - break; } } if (error_info & CPER_ARM_ERR_VALID_LEVEL) { level = ((error_info >> CPER_ARM_ERR_LEVEL_SHIFT) & CPER_ARM_ERR_LEVEL_MASK); - switch (type) { - case CPER_ARM_CACHE_ERROR: + if (type & CPER_ARM_CACHE_ERROR) printk("%scache level: %d\n", pfx, level); - break; - case CPER_ARM_TLB_ERROR: + + if (type & CPER_ARM_TLB_ERROR) printk("%sTLB level: %d\n", pfx, level); - break; - case CPER_ARM_BUS_ERROR: + + if (type & CPER_ARM_BUS_ERROR) printk("%saffinity level at which the bus error occurred: %d\n", pfx, level); - break; - } } if (error_info & CPER_ARM_ERR_VALID_PROC_CONTEXT_CORRUPT) { @@ -240,7 +231,8 @@ void cper_print_proc_arm(const char *pfx, int i, len, max_ctx_type; struct cper_arm_err_info *err_info; struct cper_arm_ctx_info *ctx_info; - char newpfx[64], infopfx[64]; + char newpfx[64], infopfx[ARRAY_SIZE(newpfx) + 1]; + char error_type[120]; printk("%sMIDR: 0x%016llx\n", pfx, proc->midr); @@ -289,9 +281,15 @@ void cper_print_proc_arm(const char *pfx, newpfx); } - printk("%serror_type: %d, %s\n", newpfx, err_info->type, - err_info->type < ARRAY_SIZE(cper_proc_error_type_strs) ? - cper_proc_error_type_strs[err_info->type] : "unknown"); + cper_bits_to_str(error_type, sizeof(error_type), + FIELD_GET(CPER_ARM_ERR_TYPE_MASK, err_info->type), + cper_proc_error_type_strs, + ARRAY_SIZE(cper_proc_error_type_strs)); + + printk("%serror_type: 0x%02x: %s%s\n", newpfx, err_info->type, + error_type, + (err_info->type & ~CPER_ARM_ERR_TYPE_MASK) ? " with reserved bit(s)" : ""); + if (err_info->validation_bits & CPER_ARM_INFO_VALID_ERR_INFO) { printk("%serror_info: 0x%016llx\n", newpfx, err_info->error_info); diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index 928409199a1a4..0232bd040f61c 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -12,6 +12,7 @@ * Specification version 2.4. */ +#include #include #include #include @@ -69,7 +70,7 @@ const char *cper_severity_str(unsigned int severity) } EXPORT_SYMBOL_GPL(cper_severity_str); -/* +/** * cper_print_bits - print strings for set bits * @pfx: prefix for each line, including log level and prefix string * @bits: bit mask @@ -106,6 +107,65 @@ void cper_print_bits(const char *pfx, unsigned int bits, printk("%s\n", buf); } +/** + * cper_bits_to_str - return a string for set bits + * @buf: buffer to store the output string + * @buf_size: size of the output string buffer + * @bits: bit mask + * @strs: string array, indexed by bit position + * @strs_size: size of the string array: @strs + * + * Add to @buf the bitmask in hexadecimal. Then, for each set bit in @bits, + * add the corresponding string describing the bit in @strs to @buf. + * + * A typical example is:: + * + * const char * const bits[] = { + * "bit 3 name", + * "bit 4 name", + * "bit 5 name", + * }; + * char str[120]; + * unsigned int bitmask = BIT(3) | BIT(5); + * #define MASK GENMASK(5,3) + * + * cper_bits_to_str(str, sizeof(str), FIELD_GET(MASK, bitmask), + * bits, ARRAY_SIZE(bits)); + * + * The above code fills the string ``str`` with ``bit 3 name|bit 5 name``. + * + * Return: number of bytes stored or an error code if lower than zero. + */ +int cper_bits_to_str(char *buf, int buf_size, unsigned long bits, + const char * const strs[], unsigned int strs_size) +{ + int len = buf_size; + char *str = buf; + int i, size; + + *buf = '\0'; + + for_each_set_bit(i, &bits, strs_size) { + if (!(bits & BIT_ULL(i))) + continue; + + if (*buf && len > 0) { + *str = '|'; + len--; + str++; + } + + size = strscpy(str, strs[i], len); + if (size < 0) + return size; + + len -= size; + str += size; + } + return len - buf_size; +} +EXPORT_SYMBOL_GPL(cper_bits_to_str); + static const char * const proc_type_strs[] = { "IA32/X64", "IA64", diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index a9070d00b833f..55452e61af31d 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -73,6 +73,7 @@ struct mm_struct efi_mm = { MMAP_LOCK_INITIALIZER(efi_mm) .page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock), .mmlist = LIST_HEAD_INIT(efi_mm.mmlist), + .user_ns = &init_user_ns, .cpu_bitmap = { [BITS_TO_LONGS(NR_CPUS)] = 0}, #ifdef CONFIG_SCHED_MM_CID .mm_cid.lock = __RAW_SPIN_LOCK_UNLOCKED(efi_mm.mm_cid.lock), diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index 874f63b4a3830..9cb814c5ba1bd 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -56,7 +56,7 @@ static struct screen_info *setup_graphics(void) { struct screen_info *si, tmp = {}; - if (efi_setup_gop(&tmp) != EFI_SUCCESS) + if (efi_setup_graphics(&tmp, NULL) != EFI_SUCCESS) return NULL; si = alloc_screen_info(); diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index f5ba032863a9c..b2fb0c3fa7217 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -34,6 +34,9 @@ #define EFI_ALLOC_LIMIT ULONG_MAX #endif +struct edid_info; +struct screen_info; + extern bool efi_no5lvl; extern bool efi_nochunk; extern bool efi_nokaslr; @@ -578,6 +581,32 @@ union efi_graphics_output_protocol { } mixed_mode; }; +typedef union efi_edid_discovered_protocol efi_edid_discovered_protocol_t; + +union efi_edid_discovered_protocol { + struct { + u32 size_of_edid; + u8 *edid; + }; + struct { + u32 size_of_edid; + u32 edid; + } mixed_mode; +}; + +typedef union efi_edid_active_protocol efi_edid_active_protocol_t; + +union efi_edid_active_protocol { + struct { + u32 size_of_edid; + u8 *edid; + }; + struct { + u32 size_of_edid; + u32 edid; + } mixed_mode; +}; + typedef union { struct { u32 revision; @@ -1085,7 +1114,7 @@ efi_status_t efi_parse_options(char const *cmdline); void efi_parse_option_graphics(char *option); -efi_status_t efi_setup_gop(struct screen_info *si); +efi_status_t efi_setup_graphics(struct screen_info *si, struct edid_info *edid); efi_status_t handle_cmdline_files(efi_loaded_image_t *image, const efi_char16_t *optstr, diff --git a/drivers/firmware/efi/libstub/gop.c b/drivers/firmware/efi/libstub/gop.c index 3785fb4986b43..80dc8cfeb33e9 100644 --- a/drivers/firmware/efi/libstub/gop.c +++ b/drivers/firmware/efi/libstub/gop.c @@ -12,6 +12,7 @@ #include #include #include +#include