mirror of
				https://github.com/immortalwrt/immortalwrt.git
				synced 2025-10-30 07:49:55 +08:00 
			
		
		
		
	Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
		| @ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk | ||||
|  | ||||
| PKG_NAME:=elfutils | ||||
| PKG_VERSION:=0.192 | ||||
| PKG_RELEASE:=2 | ||||
| PKG_RELEASE:=1 | ||||
|  | ||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 | ||||
| PKG_SOURCE_URL:=https://sourceware.org/$(PKG_NAME)/ftp/$(PKG_VERSION) \ | ||||
| @ -87,7 +87,6 @@ TARGET_CFLAGS += \ | ||||
| 	-D_GNU_SOURCE \ | ||||
| 	-Wno-unused-result \ | ||||
| 	-Wno-format-nonliteral \ | ||||
| 	-Wno-error=nonnull-compare \ | ||||
| 	-Wno-error=use-after-free | ||||
|  | ||||
| define Build/InstallDev | ||||
|  | ||||
| @ -106,6 +106,17 @@ | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &usb0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &usb1 { | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	mediatek,u3p-dis-msk = <0x1>; | ||||
| 	phys = <&usb1_phy PHY_TYPE_USB2>; | ||||
| }; | ||||
|  | ||||
| &mmc0 { | ||||
| 	pinctrl-names = "default", "state_uhs"; | ||||
| 	pinctrl-0 = <&mmc_pins>; | ||||
|  | ||||
| @ -3,6 +3,9 @@ | ||||
| #include <dt-bindings/interrupt-controller/irq.h> | ||||
| #include <dt-bindings/interrupt-controller/arm-gic.h> | ||||
| #include <dt-bindings/clock/en7523-clk.h> | ||||
| #include <dt-bindings/phy/phy.h> | ||||
| #include <dt-bindings/phy/airoha,an7581-usb-phy.h> | ||||
| #include <dt-bindings/soc/airoha,scu-ssr.h> | ||||
| #include <dt-bindings/reset/airoha,en7581-reset.h> | ||||
| #include <dt-bindings/leds/common.h> | ||||
| #include <dt-bindings/thermal/thermal.h> | ||||
| @ -503,6 +506,52 @@ | ||||
| 			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; | ||||
| 		}; | ||||
|  | ||||
| 		usb0: usb@1fab0000 { | ||||
| 			compatible = "mediatek,mtk-xhci"; | ||||
| 			reg = <0x0 0x1fab0000 0x0 0x3e00>, | ||||
| 				<0x0 0x1fab3e00 0x0 0x100>; | ||||
| 			reg-names = "mac", "ippc"; | ||||
| 			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; | ||||
|  | ||||
| 			phys = <&usb0_phy PHY_TYPE_USB2>, <&usb0_phy PHY_TYPE_USB3>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		usb0_phy: phy@1fac0000 { | ||||
| 			compatible = "airoha,an7581-usb-phy"; | ||||
| 			reg = <0x0 0x1fac0000 0x0 0x10000>; | ||||
|  | ||||
| 			airoha,scu = <&scuclk>; | ||||
| 			airoha,usb2-monitor-clk-sel = <AIROHA_USB2_MONCLK_SEL1>; | ||||
| 			airoha,serdes-port = <AIROHA_SCU_SERDES_USB1>; | ||||
|  | ||||
| 			#phy-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		usb1: usb@1fad0000 { | ||||
| 			compatible = "mediatek,mtk-xhci"; | ||||
| 			reg = <0x0 0x1fad0000 0x0 0x3e00>, | ||||
| 				<0x0 0x1fad3e00 0x0 0x100>; | ||||
| 			reg-names = "mac", "ippc"; | ||||
| 			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>; | ||||
|  | ||||
| 			phys = <&usb1_phy PHY_TYPE_USB2>, <&usb1_phy PHY_TYPE_USB3>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		usb1_phy: phy@1fae0000 { | ||||
| 			compatible = "airoha,an7581-usb-phy"; | ||||
| 			reg = <0x0 0x1fae0000 0x0 0x10000>; | ||||
|  | ||||
| 			airoha,scu = <&scuclk>; | ||||
| 			airoha,usb2-monitor-clk-sel = <AIROHA_USB2_MONCLK_SEL2>; | ||||
| 			airoha,serdes-port = <AIROHA_SCU_SERDES_USB2>; | ||||
|  | ||||
| 			#phy-cells = <1>; | ||||
| 		}; | ||||
|  | ||||
| 		crypto@1e004000 { | ||||
| 			compatible = "inside-secure,safexcel-eip93ies"; | ||||
| 			reg = <0x0 0x1fb70000 0x0 0x1000>; | ||||
| @ -731,7 +780,7 @@ | ||||
| 			clocks = <&scuclk EN7523_CLK_PCIE>; | ||||
| 			clock-names = "sys-ck"; | ||||
|  | ||||
| 			phys = <&pciephy>; | ||||
| 			phys = <&usb1_phy PHY_TYPE_USB3>; | ||||
| 			phy-names = "pcie-phy"; | ||||
|  | ||||
| 			ranges = <0x02000000 0 0x28000000 0x0 0x28000000 0 0x4000000>; | ||||
|  | ||||
| @ -0,0 +1,35 @@ | ||||
| From 39537b6b334dfac001aba395229adb9318627463 Mon Sep 17 00:00:00 2001 | ||||
| From: Christian Marangi <ansuelsmth@gmail.com> | ||||
| Date: Tue, 28 Oct 2025 12:09:57 +0100 | ||||
| Subject: [PATCH 04/10] dt-bindings: soc: Add bindings for Airoha SCU Serdes | ||||
|  lines | ||||
|  | ||||
| The Airoha AN7581 SoC have can configure the SCU serdes lines for | ||||
| multiple purpose. For example the Serdes for the USB1 port can be both | ||||
| used for USB 3.0 operation or for Ethernet. Or the USB2 serdes can both | ||||
| used for USB 3.0 operation or for PCIe. | ||||
|  | ||||
| Add bindings to permit correct reference of the different ports in DT, | ||||
| mostly to differenciate the different supported modes internally to the | ||||
| drivers. | ||||
|  | ||||
| Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | ||||
| --- | ||||
|  include/dt-bindings/soc/airoha,scu-ssr.h | 11 +++++++++++ | ||||
|  1 file changed, 11 insertions(+) | ||||
|  create mode 100644 include/dt-bindings/soc/airoha,scu-ssr.h | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/include/dt-bindings/soc/airoha,scu-ssr.h | ||||
| @@ -0,0 +1,11 @@ | ||||
| +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ | ||||
| + | ||||
| +#ifndef __DT_BINDINGS_AIROHA_SCU_SSR_H | ||||
| +#define __DT_BINDINGS_AIROHA_SCU_SSR_H | ||||
| + | ||||
| +#define AIROHA_SCU_SERDES_WIFI1		0 | ||||
| +#define AIROHA_SCU_SERDES_WIFI2		1 | ||||
| +#define AIROHA_SCU_SERDES_USB1		2 | ||||
| +#define AIROHA_SCU_SERDES_USB2		3 | ||||
| + | ||||
| +#endif /* __DT_BINDINGS_AIROHA_SCU_SSR_H */ | ||||
| @ -0,0 +1,141 @@ | ||||
| From e0095e21dd9179250c304d6df2643e9a50d48edb Mon Sep 17 00:00:00 2001 | ||||
| From: Christian Marangi <ansuelsmth@gmail.com> | ||||
| Date: Fri, 7 Feb 2025 13:25:28 +0100 | ||||
| Subject: [PATCH 05/10] dt-bindings: phy: Add documentation for Airoha AN7581 | ||||
|  USB PHY | ||||
|  | ||||
| Add documentation for Airoha AN7581 USB PHY that describe the USB PHY | ||||
| for the USB controller. | ||||
|  | ||||
| Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is | ||||
| always supported. The USB 3.0 mode is optional and depends on the Serdes | ||||
| mode currently configured on the system for the USB port. | ||||
|  | ||||
| If the airoha,serdes-port property is not declared, it's assumed USB 3.0 | ||||
| mode is not supported, as the Serdes mode can't be validated. | ||||
|  | ||||
| Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | ||||
| --- | ||||
|  .../bindings/phy/airoha,an7581-usb-phy.yaml   | 83 +++++++++++++++++++ | ||||
|  MAINTAINERS                                   |  7 ++ | ||||
|  .../dt-bindings/phy/airoha,an7581-usb-phy.h   | 11 +++ | ||||
|  3 files changed, 101 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml | ||||
|  create mode 100644 include/dt-bindings/phy/airoha,an7581-usb-phy.h | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml | ||||
| @@ -0,0 +1,83 @@ | ||||
| +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | ||||
| +%YAML 1.2 | ||||
| +--- | ||||
| +$id: http://devicetree.org/schemas/phy/airoha,an7581-usb-phy.yaml# | ||||
| +$schema: http://devicetree.org/meta-schemas/core.yaml# | ||||
| + | ||||
| +title: Airoha AN7581 SoC USB PHY | ||||
| + | ||||
| +maintainers: | ||||
| +  - Christian Marangi <ansuelsmth@gmail.com> | ||||
| + | ||||
| +description: > | ||||
| +  The Airoha AN7581 SoC USB PHY describes the USB PHY for the USB controller. | ||||
| + | ||||
| +  Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is | ||||
| +  always supported. The USB 3.0 mode is optional and depends on the Serdes | ||||
| +  mode currently configured on the system for the USB port. | ||||
| + | ||||
| +  If the airoha,serdes-port property is not declared, it's assumed USB 3.0 | ||||
| +  mode is not supported, as the Serdes mode can't be validated. | ||||
| + | ||||
| +properties: | ||||
| +  compatible: | ||||
| +    const: airoha,an7581-usb-phy | ||||
| + | ||||
| +  reg: | ||||
| +    maxItems: 1 | ||||
| + | ||||
| + | ||||
| +  airoha,usb2-monitor-clk-sel: | ||||
| +    description: Describe what oscillator across the available 4 | ||||
| +      should be selected for USB 2.0 Slew Rate calibration. | ||||
| +    $ref: /schemas/types.yaml#/definitions/uint32 | ||||
| +    enum: [0, 1, 2, 3] | ||||
| + | ||||
| +  airoha,serdes-port: | ||||
| +    description: Describe what Serdes Port is attached to the USB 3.0 port. | ||||
| +    $ref: /schemas/types.yaml#/definitions/uint32 | ||||
| +    enum: [0, 1, 2, 3] | ||||
| + | ||||
| +  airoha,scu: | ||||
| +    description: Phandle to the SCU node for USB 3.0 Serdes mode validation. | ||||
| +    $ref: /schemas/types.yaml#/definitions/phandle | ||||
| + | ||||
| +  '#phy-cells': | ||||
| +    const: 1 | ||||
| + | ||||
| +required: | ||||
| +  - compatible | ||||
| +  - reg | ||||
| +  - airoha,usb2-monitor-clk-sel | ||||
| +  - '#phy-cells' | ||||
| + | ||||
| +dependentRequired: | ||||
| +  airoha,serdes-port: [ 'airoha,scu' ] | ||||
| + | ||||
| +additionalProperties: false | ||||
| + | ||||
| +examples: | ||||
| +  - | | ||||
| +    #include <dt-bindings/phy/airoha,an7581-usb-phy.h> | ||||
| +    #include <dt-bindings/soc/airoha,scu-ssr.h> | ||||
| + | ||||
| +    phy@1fac0000 { | ||||
| +        compatible = "airoha,an7581-usb-phy"; | ||||
| +        reg = <0x1fac0000 0x10000>; | ||||
| + | ||||
| +        airoha,usb2-monitor-clk-sel = <AIROHA_USB2_MONCLK_SEL1>; | ||||
| +        airoha,scu = <&scu>; | ||||
| +        airoha,serdes-port = <AIROHA_SCU_SERDES_USB1>; | ||||
| + | ||||
| +        #phy-cells = <1>; | ||||
| +    }; | ||||
| + | ||||
| +    phy@1fae0000 { | ||||
| +        compatible = "airoha,an7581-usb-phy"; | ||||
| +        reg = <0x1fae0000 0x10000>; | ||||
| + | ||||
| +        airoha,usb2-monitor-clk-sel = <AIROHA_USB2_MONCLK_SEL2>; | ||||
| + | ||||
| +        #phy-cells = <1>; | ||||
| +    }; | ||||
| + | ||||
| --- a/MAINTAINERS | ||||
| +++ b/MAINTAINERS | ||||
| @@ -737,6 +737,13 @@ S:	Maintained | ||||
|  F:	Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml | ||||
|  F:	drivers/spi/spi-airoha-snfi.c | ||||
|   | ||||
| +AIROHA USB PHY DRIVER | ||||
| +M:	Christian Marangi <ansuelsmth@gmail.com> | ||||
| +L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||||
| +S:	Maintained | ||||
| +F:	Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml | ||||
| +F:	include/dt-bindings/phy/airoha,an7581-usb-phy.h | ||||
| + | ||||
|  AIRSPY MEDIA DRIVER | ||||
|  L:	linux-media@vger.kernel.org | ||||
|  S:	Orphan | ||||
| --- /dev/null | ||||
| +++ b/include/dt-bindings/phy/airoha,an7581-usb-phy.h | ||||
| @@ -0,0 +1,11 @@ | ||||
| +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ | ||||
| + | ||||
| +#ifndef _DT_BINDINGS_AIROHA_AN7581_USB_PHY_H_ | ||||
| +#define _DT_BINDINGS_AIROHA_AN7581_USB_PHY_H_ | ||||
| + | ||||
| +#define AIROHA_USB2_MONCLK_SEL0                 0 | ||||
| +#define AIROHA_USB2_MONCLK_SEL1                 1 | ||||
| +#define AIROHA_USB2_MONCLK_SEL2                 2 | ||||
| +#define AIROHA_USB2_MONCLK_SEL3                 3 | ||||
| + | ||||
| +#endif | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -0,0 +1,667 @@ | ||||
| From fadd22890b239e5a251dbe47367cfbeb1ea105f7 Mon Sep 17 00:00:00 2001 | ||||
| From: Christian Marangi <ansuelsmth@gmail.com> | ||||
| Date: Fri, 7 Feb 2025 13:28:40 +0100 | ||||
| Subject: [PATCH 07/10] phy: airoha: Add support for Airoha AN7581 USB PHY | ||||
|  | ||||
| Add support for Airoha AN7581 USB PHY driver. AN7581 supports up to 2 | ||||
| USB port with USB 2.0 mode always supported and USB 3.0 mode available | ||||
| only if the Serdes port is correctly configured for USB 3.0. | ||||
|  | ||||
| The second USB port on the SoC can be both used for USB 3.0 operation or | ||||
| PCIe. (toggled by the SCU SSR register and configured by the USB PHY | ||||
| driver) | ||||
|  | ||||
| If the USB 3.0 mode is not configured, the modes needs to be also | ||||
| disabled in the xHCI node or the driver will report unsable clock and | ||||
| fail probe. | ||||
|  | ||||
| Also USB 3.0 PHY instance are provided only if the airoha,serdes-port | ||||
| and airoha,scu property is defined in DT, if it's not then USB 3.0 PHY | ||||
| is assumed not supported. | ||||
|  | ||||
| For USB 2.0 Slew Rate calibration, airoha,usb2-monitor-clk-sel is | ||||
| mandatory and is used to select the monitor clock for calibration. | ||||
|  | ||||
| Normally it's 1 for USB port 1 and 2 for USB port 2. | ||||
|  | ||||
| Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | ||||
| --- | ||||
|  MAINTAINERS                         |   1 + | ||||
|  drivers/phy/airoha/Kconfig          |  10 + | ||||
|  drivers/phy/airoha/Makefile         |   1 + | ||||
|  drivers/phy/airoha/phy-airoha-usb.c | 597 ++++++++++++++++++++++++++++ | ||||
|  4 files changed, 609 insertions(+) | ||||
|  create mode 100644 drivers/phy/airoha/phy-airoha-usb.c | ||||
|  | ||||
| --- a/MAINTAINERS | ||||
| +++ b/MAINTAINERS | ||||
| @@ -742,6 +742,7 @@ M:	Christian Marangi <ansuelsmth@gmail.c | ||||
|  L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||||
|  S:	Maintained | ||||
|  F:	Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml | ||||
| +F:	drivers/phy/airoha/phy-airoha-usb.c | ||||
|  F:	include/dt-bindings/phy/airoha,an7581-usb-phy.h | ||||
|   | ||||
|  AIRSPY MEDIA DRIVER | ||||
| --- a/drivers/phy/airoha/Kconfig | ||||
| +++ b/drivers/phy/airoha/Kconfig | ||||
| @@ -11,3 +11,13 @@ config PHY_AIROHA_PCIE | ||||
|  	  Say Y here to add support for Airoha PCIe PHY driver. | ||||
|  	  This driver create the basic PHY instance and provides initialize | ||||
|  	  callback for PCIe GEN3 port. | ||||
| + | ||||
| +config PHY_AIROHA_USB | ||||
| +	tristate "Airoha USB PHY Driver" | ||||
| +	depends on ARCH_AIROHA || COMPILE_TEST | ||||
| +	depends on OF | ||||
| +	select GENERIC_PHY | ||||
| +	help | ||||
| +	  Say 'Y' here to add support for Airoha USB PHY driver. | ||||
| +	  This driver create the basic PHY instance and provides initialize | ||||
| +	  callback for USB port. | ||||
| --- a/drivers/phy/airoha/Makefile | ||||
| +++ b/drivers/phy/airoha/Makefile | ||||
| @@ -1,3 +1,4 @@ | ||||
|  # SPDX-License-Identifier: GPL-2.0 | ||||
|   | ||||
|  obj-$(CONFIG_PHY_AIROHA_PCIE)		+= phy-airoha-pcie.o | ||||
| +obj-$(CONFIG_PHY_AIROHA_USB)		+= phy-airoha-usb.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/phy/airoha/phy-airoha-usb.c | ||||
| @@ -0,0 +1,596 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0 | ||||
| +/* | ||||
| + * Author: Christian Marangi <ansuelsmth@gmail.com> | ||||
| + */ | ||||
| + | ||||
| +#include <dt-bindings/phy/phy.h> | ||||
| +#include <dt-bindings/soc/airoha,scu-ssr.h> | ||||
| +#include <linux/bitfield.h> | ||||
| +#include <linux/math.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/mfd/syscon.h> | ||||
| +#include <linux/phy/phy.h> | ||||
| +#include <linux/platform_device.h> | ||||
| +#include <linux/regmap.h> | ||||
| + | ||||
| +/* SCU */ | ||||
| +#define AIROHA_SCU_SSTR				0x9c | ||||
| +#define   AIROHA_SCU_SSTR_USB_PCIE_SEL		BIT(3) | ||||
| +#define   AIROHA_SCU_SSTR_USB_PCIE_SEL_PCIE	FIELD_PREP_CONST(AIROHA_SCU_SSTR_USB_PCIE_SEL, 0x0) | ||||
| +#define   AIROHA_SCU_SSTR_USB_PCIE_SEL_USB	FIELD_PREP_CONST(AIROHA_SCU_SSTR_USB_PCIE_SEL, 0x1) | ||||
| + | ||||
| +/* U2PHY */ | ||||
| +#define AIROHA_USB_PHY_FMCR0			0x100 | ||||
| +#define   AIROHA_USB_PHY_MONCLK_SEL		GENMASK(27, 26) | ||||
| +#define   AIROHA_USB_PHY_MONCLK_SEL0		FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x0) | ||||
| +#define   AIROHA_USB_PHY_MONCLK_SEL1		FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x1) | ||||
| +#define   AIROHA_USB_PHY_MONCLK_SEL2		FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x2) | ||||
| +#define   AIROHA_USB_PHY_MONCLK_SEL3		FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x3) | ||||
| +#define   AIROHA_USB_PHY_FREQDET_EN		BIT(24) | ||||
| +#define   AIROHA_USB_PHY_CYCLECNT		GENMASK(23, 0) | ||||
| +#define AIROHA_USB_PHY_FMMONR0			0x10c | ||||
| +#define   AIROHA_USB_PHY_USB_FM_OUT		GENMASK(31, 0) | ||||
| +#define AIROHA_USB_PHY_FMMONR1			0x110 | ||||
| +#define   AIROHA_USB_PHY_FRCK_EN		BIT(8) | ||||
| + | ||||
| +#define AIROHA_USB_PHY_USBPHYACR4		0x310 | ||||
| +#define   AIROHA_USB_PHY_USB20_FS_CR		GENMASK(10, 8) | ||||
| +#define   AIROHA_USB_PHY_USB20_FS_CR_MAX	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x0) | ||||
| +#define   AIROHA_USB_PHY_USB20_FS_CR_NORMAL	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x2) | ||||
| +#define   AIROHA_USB_PHY_USB20_FS_CR_SMALLER	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x4) | ||||
| +#define   AIROHA_USB_PHY_USB20_FS_CR_MIN	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x6) | ||||
| +#define   AIROHA_USB_PHY_USB20_FS_SR		GENMASK(2, 0) | ||||
| +#define   AIROHA_USB_PHY_USB20_FS_SR_MAX	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x0) | ||||
| +#define   AIROHA_USB_PHY_USB20_FS_SR_NORMAL	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x2) | ||||
| +#define   AIROHA_USB_PHY_USB20_FS_SR_SMALLER	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x4) | ||||
| +#define   AIROHA_USB_PHY_USB20_FS_SR_MIN	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x6) | ||||
| +#define AIROHA_USB_PHY_USBPHYACR5		0x314 | ||||
| +#define   AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN	BIT(15) | ||||
| +#define   AIROHA_USB_PHY_USB20_HSTX_SRCTRL	GENMASK(14, 12) | ||||
| +#define AIROHA_USB_PHY_USBPHYACR6		0x318 | ||||
| +#define   AIROHA_USB_PHY_USB20_BC11_SW_EN	BIT(23) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH		GENMASK(7, 4) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_400	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x0) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_420	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x1) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_440	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x2) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_460	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x3) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_480	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x4) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_500	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x5) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_520	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x6) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_540	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x7) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_560	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x8) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_580	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x9) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_600	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xa) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_620	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xb) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_640	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xc) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_660	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xd) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_680	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xe) | ||||
| +#define   AIROHA_USB_PHY_USB20_DISCTH_700	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xf) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH		GENMASK(3, 0) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_85		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x0) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_90		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x1) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_95		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x2) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_100		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x3) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_105		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x4) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_110		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x5) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_115		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x6) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_120		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x7) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_125		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x8) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_130		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x9) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_135		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xa) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_140		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xb) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_145		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xc) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_150		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xd) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_155		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xe) | ||||
| +#define   AIROHA_USB_PHY_USB20_SQTH_160		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xf) | ||||
| + | ||||
| +#define AIROHA_USB_PHY_U2PHYDTM1		0x36c | ||||
| +#define   AIROHA_USB_PHY_FORCE_IDDIG		BIT(9) | ||||
| +#define   AIROHA_USB_PHY_IDDIG			BIT(1) | ||||
| + | ||||
| +#define AIROHA_USB_PHY_GPIO_CTLD		0x80c | ||||
| +#define   AIROHA_USB_PHY_C60802_GPIO_CTLD	GENMASK(31, 0) | ||||
| +#define     AIROHA_USB_PHY_SSUSB_IP_SW_RST	BIT(31) | ||||
| +#define     AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN	BIT(30) | ||||
| +#define     AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST BIT(29) | ||||
| +#define     AIROHA_USB_PHY_SSUSB_SW_RST		BIT(28) | ||||
| + | ||||
| +#define AIROHA_USB_PHY_U3_PHYA_REG0		0xb00 | ||||
| +#define   AIROHA_USB_PHY_SSUSB_BG_DIV		GENMASK(29, 28) | ||||
| +#define   AIROHA_USB_PHY_SSUSB_BG_DIV_2		FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x0) | ||||
| +#define   AIROHA_USB_PHY_SSUSB_BG_DIV_4		FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x1) | ||||
| +#define   AIROHA_USB_PHY_SSUSB_BG_DIV_8		FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x2) | ||||
| +#define   AIROHA_USB_PHY_SSUSB_BG_DIV_16	FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x3) | ||||
| +#define AIROHA_USB_PHY_U3_PHYA_REG1		0xb04 | ||||
| +#define   AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE	GENMASK(25, 10) | ||||
| +#define AIROHA_USB_PHY_U3_PHYA_REG6		0xb18 | ||||
| +#define   AIROHA_USB_PHY_SSUSB_CDR_RESERVE	GENMASK(31, 24) | ||||
| +#define AIROHA_USB_PHY_U3_PHYA_REG8		0xb20 | ||||
| +#define   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY	GENMASK(7, 6) | ||||
| +#define   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32	FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x0) | ||||
| +#define   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_64	FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x1) | ||||
| +#define   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_128	FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x2) | ||||
| +#define   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_216	FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x3) | ||||
| + | ||||
| +#define AIROHA_USB_PHY_U3_PHYA_DA_REG19		0xc38 | ||||
| +#define   AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3 GENMASK(15, 0) | ||||
| + | ||||
| +#define AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT	1024 | ||||
| +#define AIROHA_USB_PHY_REF_CK			20 | ||||
| +#define AIROHA_USB_PHY_U2_SR_COEF		28 | ||||
| +#define AIROHA_USB_PHY_U2_SR_COEF_DIVISOR	1000 | ||||
| + | ||||
| +#define AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION	0x5 | ||||
| +#define AIROHA_USB_PHY_FREQDET_SLEEP		1000 /* 1ms */ | ||||
| +#define AIROHA_USB_PHY_FREQDET_TIMEOUT		(AIROHA_USB_PHY_FREQDET_SLEEP * 10) | ||||
| + | ||||
| +struct airoha_usb_phy_instance { | ||||
| +	struct phy *phy; | ||||
| +	u32 type; | ||||
| +}; | ||||
| + | ||||
| +enum airoha_usb_phy_instance_type { | ||||
| +	AIROHA_PHY_USB2, | ||||
| +	AIROHA_PHY_USB3, | ||||
| + | ||||
| +	AIROHA_PHY_USB_MAX, | ||||
| +}; | ||||
| + | ||||
| +struct airoha_usb_phy_priv { | ||||
| +	struct device *dev; | ||||
| +	struct regmap *regmap; | ||||
| +	struct regmap *scu; | ||||
| + | ||||
| +	unsigned int monclk_sel; | ||||
| +	unsigned int serdes_port; | ||||
| + | ||||
| +	struct airoha_usb_phy_instance *phys[AIROHA_PHY_USB_MAX]; | ||||
| +}; | ||||
| + | ||||
| +static void airoha_usb_phy_u2_slew_rate_calibration(struct airoha_usb_phy_priv *priv) | ||||
| +{ | ||||
| +	u32 fm_out; | ||||
| +	u32 srctrl; | ||||
| + | ||||
| +	/* Enable HS TX SR calibration */ | ||||
| +	regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, | ||||
| +			AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN); | ||||
| + | ||||
| +	usleep_range(1000, 1500); | ||||
| + | ||||
| +	/* Enable Free run clock */ | ||||
| +	regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1, | ||||
| +			AIROHA_USB_PHY_FRCK_EN); | ||||
| + | ||||
| +	/* Select Monitor Clock */ | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, | ||||
| +			   AIROHA_USB_PHY_MONCLK_SEL, | ||||
| +			   FIELD_PREP(AIROHA_USB_PHY_MONCLK_SEL, | ||||
| +				      priv->monclk_sel)); | ||||
| + | ||||
| +	/* Set cyclecnt */ | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, | ||||
| +			   AIROHA_USB_PHY_CYCLECNT, | ||||
| +			   FIELD_PREP(AIROHA_USB_PHY_CYCLECNT, | ||||
| +				      AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT)); | ||||
| + | ||||
| +	/* Enable Frequency meter */ | ||||
| +	regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, | ||||
| +			AIROHA_USB_PHY_FREQDET_EN); | ||||
| + | ||||
| +	/* Timeout can happen and we will apply workaround at the end */ | ||||
| +	regmap_read_poll_timeout(priv->regmap, AIROHA_USB_PHY_FMMONR0, fm_out, | ||||
| +				 fm_out, AIROHA_USB_PHY_FREQDET_SLEEP, | ||||
| +				 AIROHA_USB_PHY_FREQDET_TIMEOUT); | ||||
| + | ||||
| +	/* Disable Frequency meter */ | ||||
| +	regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, | ||||
| +			  AIROHA_USB_PHY_FREQDET_EN); | ||||
| + | ||||
| +	/* Disable Free run clock */ | ||||
| +	regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1, | ||||
| +			  AIROHA_USB_PHY_FRCK_EN); | ||||
| + | ||||
| +	/* Disable HS TX SR calibration */ | ||||
| +	regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, | ||||
| +			  AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN); | ||||
| + | ||||
| +	usleep_range(1000, 1500); | ||||
| + | ||||
| +	/* Frequency was not detected, use default SR calibration value */ | ||||
| +	if (!fm_out) { | ||||
| +		srctrl = AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION; | ||||
| +		dev_err(priv->dev, "Frequency not detected, using default SR calibration.\n"); | ||||
| +	} else { | ||||
| +		/* (1024 / FM_OUT) * REF_CK * U2_SR_COEF (round to the nearest digits) */ | ||||
| +		srctrl = AIROHA_USB_PHY_REF_CK * AIROHA_USB_PHY_U2_SR_COEF; | ||||
| +		srctrl = (srctrl * AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT) / fm_out; | ||||
| +		srctrl = DIV_ROUND_CLOSEST(srctrl, AIROHA_USB_PHY_U2_SR_COEF_DIVISOR); | ||||
| +		dev_dbg(priv->dev, "SR calibration applied: %x\n", srctrl); | ||||
| +	} | ||||
| + | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, | ||||
| +			   AIROHA_USB_PHY_USB20_HSTX_SRCTRL, | ||||
| +			   FIELD_PREP(AIROHA_USB_PHY_USB20_HSTX_SRCTRL, srctrl)); | ||||
| +} | ||||
| + | ||||
| +static void airoha_usb_phy_u2_init(struct airoha_usb_phy_priv *priv) | ||||
| +{ | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4, | ||||
| +			   AIROHA_USB_PHY_USB20_FS_CR, | ||||
| +			   AIROHA_USB_PHY_USB20_FS_CR_MIN); | ||||
| + | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4, | ||||
| +			   AIROHA_USB_PHY_USB20_FS_SR, | ||||
| +			   AIROHA_USB_PHY_USB20_FS_SR_NORMAL); | ||||
| + | ||||
| +	/* FIXME: evaluate if needed */ | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, | ||||
| +			   AIROHA_USB_PHY_USB20_SQTH, | ||||
| +			   AIROHA_USB_PHY_USB20_SQTH_130); | ||||
| + | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, | ||||
| +			   AIROHA_USB_PHY_USB20_DISCTH, | ||||
| +			   AIROHA_USB_PHY_USB20_DISCTH_600); | ||||
| + | ||||
| +	/* Enable the USB port and then disable after calibration */ | ||||
| +	regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, | ||||
| +			  AIROHA_USB_PHY_USB20_BC11_SW_EN); | ||||
| + | ||||
| +	airoha_usb_phy_u2_slew_rate_calibration(priv); | ||||
| + | ||||
| +	regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, | ||||
| +			AIROHA_USB_PHY_USB20_BC11_SW_EN); | ||||
| + | ||||
| +	usleep_range(1000, 1500); | ||||
| +} | ||||
| + | ||||
| +/* | ||||
| + * USB 3.0 mode can only work if USB serdes is correctly set. | ||||
| + * This is validated in xLate function. | ||||
| + */ | ||||
| +static void airoha_usb_phy_u3_init(struct airoha_usb_phy_priv *priv) | ||||
| +{ | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG8, | ||||
| +			   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, | ||||
| +			   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32); | ||||
| + | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG6, | ||||
| +			   AIROHA_USB_PHY_SSUSB_CDR_RESERVE, | ||||
| +			   FIELD_PREP(AIROHA_USB_PHY_SSUSB_CDR_RESERVE, 0xe)); | ||||
| + | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG0, | ||||
| +			   AIROHA_USB_PHY_SSUSB_BG_DIV, | ||||
| +			   AIROHA_USB_PHY_SSUSB_BG_DIV_4); | ||||
| + | ||||
| +	regmap_set_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG1, | ||||
| +			FIELD_PREP(AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE, 0x600)); | ||||
| + | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_DA_REG19, | ||||
| +			   AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, | ||||
| +			   FIELD_PREP(AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, 0x43)); | ||||
| +} | ||||
| + | ||||
| +static int airoha_usb_phy_init(struct phy *phy) | ||||
| +{ | ||||
| +	struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); | ||||
| +	struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); | ||||
| + | ||||
| +	switch (instance->type) { | ||||
| +	case PHY_TYPE_USB2: | ||||
| +		airoha_usb_phy_u2_init(priv); | ||||
| +		break; | ||||
| +	case PHY_TYPE_USB3: | ||||
| +		if (phy_get_mode(phy) == PHY_MODE_PCIE) | ||||
| +			return 0; | ||||
| + | ||||
| +		airoha_usb_phy_u3_init(priv); | ||||
| +		break; | ||||
| +	default: | ||||
| +		return -EINVAL; | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int airoha_usb_phy_u2_power_on(struct airoha_usb_phy_priv *priv) | ||||
| +{ | ||||
| +	regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, | ||||
| +			  AIROHA_USB_PHY_USB20_BC11_SW_EN); | ||||
| + | ||||
| +	usleep_range(1000, 1500); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int airoha_usb_phy_u3_power_on(struct airoha_usb_phy_priv *priv) | ||||
| +{ | ||||
| +	regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD, | ||||
| +			  AIROHA_USB_PHY_SSUSB_IP_SW_RST | | ||||
| +			  AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN | | ||||
| +			  AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST | | ||||
| +			  AIROHA_USB_PHY_SSUSB_SW_RST); | ||||
| + | ||||
| +	usleep_range(1000, 1500); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int airoha_usb_phy_power_on(struct phy *phy) | ||||
| +{ | ||||
| +	struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); | ||||
| +	struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); | ||||
| + | ||||
| +	switch (instance->type) { | ||||
| +	case PHY_TYPE_USB2: | ||||
| +		airoha_usb_phy_u2_power_on(priv); | ||||
| +		break; | ||||
| +	case PHY_TYPE_USB3: | ||||
| +		if (phy_get_mode(phy) == PHY_MODE_PCIE) | ||||
| +			return 0; | ||||
| + | ||||
| +		airoha_usb_phy_u3_power_on(priv); | ||||
| +		break; | ||||
| +	default: | ||||
| +		return -EINVAL; | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int airoha_usb_phy_u2_power_off(struct airoha_usb_phy_priv *priv) | ||||
| +{ | ||||
| +	regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, | ||||
| +			AIROHA_USB_PHY_USB20_BC11_SW_EN); | ||||
| + | ||||
| +	usleep_range(1000, 1500); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int airoha_usb_phy_u3_power_off(struct airoha_usb_phy_priv *priv) | ||||
| +{ | ||||
| +	regmap_set_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD, | ||||
| +			AIROHA_USB_PHY_SSUSB_IP_SW_RST | | ||||
| +			AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST); | ||||
| + | ||||
| +	usleep_range(1000, 1500); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int airoha_usb_phy_power_off(struct phy *phy) | ||||
| +{ | ||||
| +	struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); | ||||
| +	struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); | ||||
| + | ||||
| +	switch (instance->type) { | ||||
| +	case PHY_TYPE_USB2: | ||||
| +		airoha_usb_phy_u2_power_off(priv); | ||||
| +		break; | ||||
| +	case PHY_TYPE_USB3: | ||||
| +		if (phy_get_mode(phy) == PHY_MODE_PCIE) | ||||
| +			return 0; | ||||
| + | ||||
| +		airoha_usb_phy_u3_power_off(priv); | ||||
| +		break; | ||||
| +	default: | ||||
| +		return -EINVAL; | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int airoha_usb_phy_u2_set_mode(struct airoha_usb_phy_priv *priv, | ||||
| +				      enum phy_mode mode) | ||||
| +{ | ||||
| +	u32 val; | ||||
| + | ||||
| +	/* | ||||
| +	 * For Device and Host mode, enable force IDDIG. | ||||
| +	 * For Device set IDDIG, for Host clear IDDIG. | ||||
| +	 * For OTG disable force and clear IDDIG bit while at it. | ||||
| +	 */ | ||||
| +	switch (mode) { | ||||
| +	case PHY_MODE_USB_DEVICE: | ||||
| +		val = AIROHA_USB_PHY_IDDIG; | ||||
| +		break; | ||||
| +	case PHY_MODE_USB_HOST: | ||||
| +		val = AIROHA_USB_PHY_FORCE_IDDIG | | ||||
| +		      AIROHA_USB_PHY_FORCE_IDDIG; | ||||
| +		break; | ||||
| +	case PHY_MODE_USB_OTG: | ||||
| +		val = 0; | ||||
| +		break; | ||||
| +	default: | ||||
| +		return 0; | ||||
| +	} | ||||
| + | ||||
| +	regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U2PHYDTM1, | ||||
| +			   AIROHA_USB_PHY_FORCE_IDDIG | | ||||
| +			   AIROHA_USB_PHY_IDDIG, val); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int airoha_usb_phy_u3_set_mode(struct airoha_usb_phy_priv *priv, | ||||
| +				      enum phy_mode mode) | ||||
| +{ | ||||
| +	u32 sel; | ||||
| + | ||||
| +	/* Only USB2 supports PCIe mode */ | ||||
| +	if (mode == PHY_MODE_PCIE && | ||||
| +	    priv->serdes_port != AIROHA_SCU_SERDES_USB2) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	if (mode == PHY_MODE_PCIE) | ||||
| +		sel = AIROHA_SCU_SSTR_USB_PCIE_SEL_PCIE; | ||||
| +	else | ||||
| +		sel = AIROHA_SCU_SSTR_USB_PCIE_SEL_USB; | ||||
| + | ||||
| +	regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, | ||||
| +			   AIROHA_SCU_SSTR_USB_PCIE_SEL, sel); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int airoha_usb_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) | ||||
| +{ | ||||
| +	struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); | ||||
| +	struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); | ||||
| + | ||||
| +	switch (instance->type) { | ||||
| +	case PHY_TYPE_USB2: | ||||
| +		return airoha_usb_phy_u2_set_mode(priv, mode); | ||||
| +	case PHY_TYPE_USB3: | ||||
| +		return airoha_usb_phy_u3_set_mode(priv, mode); | ||||
| +	default: | ||||
| +		return 0; | ||||
| +	} | ||||
| +} | ||||
| + | ||||
| +static struct phy *airoha_usb_phy_xlate(struct device *dev, | ||||
| +					const struct of_phandle_args *args) | ||||
| +{ | ||||
| +	struct airoha_usb_phy_priv *priv = dev_get_drvdata(dev); | ||||
| +	struct airoha_usb_phy_instance *instance = NULL; | ||||
| +	unsigned int index, phy_type; | ||||
| + | ||||
| +	if (args->args_count != 1) { | ||||
| +		dev_err(dev, "invalid number of cells in 'phy' property\n"); | ||||
| +		return ERR_PTR(-EINVAL); | ||||
| +	} | ||||
| + | ||||
| +	phy_type = args->args[0]; | ||||
| +	if (!(phy_type == PHY_TYPE_USB2 || phy_type == PHY_TYPE_USB3)) { | ||||
| +		dev_err(dev, "unsupported device type: %d\n", phy_type); | ||||
| +		return ERR_PTR(-EINVAL); | ||||
| +	} | ||||
| + | ||||
| +	for (index = 0; index < AIROHA_PHY_USB_MAX; index++) | ||||
| +		if (priv->phys[index] && | ||||
| +		    phy_type == priv->phys[index]->type) { | ||||
| +			instance = priv->phys[index]; | ||||
| +			break; | ||||
| +		} | ||||
| + | ||||
| +	if (!instance) { | ||||
| +		dev_err(dev, "failed to find appropriate phy\n"); | ||||
| +		return ERR_PTR(-EINVAL); | ||||
| +	} | ||||
| + | ||||
| +	return instance->phy; | ||||
| +} | ||||
| + | ||||
| +static const struct phy_ops airoha_phy = { | ||||
| +	.init		= airoha_usb_phy_init, | ||||
| +	.power_on	= airoha_usb_phy_power_on, | ||||
| +	.power_off	= airoha_usb_phy_power_off, | ||||
| +	.set_mode	= airoha_usb_phy_set_mode, | ||||
| +	.owner		= THIS_MODULE, | ||||
| +}; | ||||
| + | ||||
| +static const struct regmap_config airoha_usb_phy_regmap_config = { | ||||
| +	.reg_bits = 32, | ||||
| +	.val_bits = 32, | ||||
| +	.reg_stride = 4, | ||||
| +}; | ||||
| + | ||||
| +static int airoha_usb_phy_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct phy_provider *phy_provider; | ||||
| +	struct airoha_usb_phy_priv *priv; | ||||
| +	struct device *dev = &pdev->dev; | ||||
| +	unsigned int index; | ||||
| +	void *base; | ||||
| +	int ret; | ||||
| + | ||||
| +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||||
| +	if (!priv) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	priv->dev = dev; | ||||
| + | ||||
| +	ret = of_property_read_u32(dev->of_node, "airoha,usb2-monitor-clk-sel", | ||||
| +				   &priv->monclk_sel); | ||||
| +	if (ret) | ||||
| +		return dev_err_probe(dev, ret, "Monitor clock selection is mandatory for USB PHY calibration.\n"); | ||||
| + | ||||
| +	if (priv->monclk_sel > 3) | ||||
| +		return dev_err_probe(dev, -EINVAL, "only 4 Monitor clock are selectable on the SoC.\n"); | ||||
| + | ||||
| +	base = devm_platform_ioremap_resource(pdev, 0); | ||||
| +	if (IS_ERR(base)) | ||||
| +		return PTR_ERR(base); | ||||
| + | ||||
| +	priv->regmap = devm_regmap_init_mmio(dev, base, &airoha_usb_phy_regmap_config); | ||||
| +	if (IS_ERR(priv->regmap)) | ||||
| +		return PTR_ERR(priv->regmap); | ||||
| + | ||||
| +	platform_set_drvdata(pdev, priv); | ||||
| + | ||||
| +	for (index = 0; index < AIROHA_PHY_USB_MAX; index++) { | ||||
| +		enum airoha_usb_phy_instance_type phy_type; | ||||
| +		struct airoha_usb_phy_instance *instance; | ||||
| + | ||||
| +		switch (index) { | ||||
| +		case AIROHA_PHY_USB2: | ||||
| +			phy_type = PHY_TYPE_USB2; | ||||
| +			break; | ||||
| +		case AIROHA_PHY_USB3: | ||||
| +			phy_type = PHY_TYPE_USB3; | ||||
| +			break; | ||||
| +		} | ||||
| + | ||||
| +		/* Skip registering USB3 instance if not supported */ | ||||
| +		if (phy_type == PHY_TYPE_USB3) { | ||||
| +			ret = of_property_read_u32(dev->of_node, "airoha,serdes-port", | ||||
| +						   &priv->serdes_port); | ||||
| +			if (ret) | ||||
| +				continue; | ||||
| + | ||||
| +			/* With Serdes Port property, SCU is required */ | ||||
| +			priv->scu = syscon_regmap_lookup_by_phandle(dev->of_node, | ||||
| +								    "airoha,scu"); | ||||
| +			if (IS_ERR(priv->scu)) | ||||
| +				return dev_err_probe(dev, PTR_ERR(priv->scu), "failed to get SCU syscon.\n"); | ||||
| +		} | ||||
| + | ||||
| +		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL); | ||||
| +		if (!instance) | ||||
| +			return -ENOMEM; | ||||
| + | ||||
| +		instance->type = phy_type; | ||||
| +		priv->phys[index] = instance; | ||||
| + | ||||
| +		instance->phy = devm_phy_create(dev, NULL, &airoha_phy); | ||||
| +		if (IS_ERR(instance->phy)) | ||||
| +			return dev_err_probe(dev, PTR_ERR(instance->phy), "failed to create phy\n"); | ||||
| + | ||||
| +		phy_set_drvdata(instance->phy, instance); | ||||
| +	} | ||||
| + | ||||
| +	phy_provider = devm_of_phy_provider_register(&pdev->dev, airoha_usb_phy_xlate); | ||||
| + | ||||
| +	return PTR_ERR_OR_ZERO(phy_provider); | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id airoha_phy_id_table[] = { | ||||
| +	{ .compatible = "airoha,an7581-usb-phy" }, | ||||
| +	{ }, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, airoha_phy_id_table); | ||||
| + | ||||
| +static struct platform_driver airoha_usb_driver = { | ||||
| +	.probe		= airoha_usb_phy_probe, | ||||
| +	.driver		= { | ||||
| +		.name	= "airoha-usb-phy", | ||||
| +		.of_match_table = airoha_phy_id_table, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +module_platform_driver(airoha_usb_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| +MODULE_DESCRIPTION("Airoha USB PHY driver"); | ||||
| @ -0,0 +1,25 @@ | ||||
| From 3d3a406dea89b789dfb550bd05d0eba5ae926755 Mon Sep 17 00:00:00 2001 | ||||
| From: Christian Marangi <ansuelsmth@gmail.com> | ||||
| Date: Fri, 7 Feb 2025 14:17:06 +0100 | ||||
| Subject: [PATCH 08/10] usb: host: add ARCH_AIROHA in XHCI MTK dependency | ||||
|  | ||||
| Airoha SoC use the same register map a logic of the Mediatek xHCI | ||||
| driver, hence add it to the dependency list to permit compilation also | ||||
| on this ARCH. | ||||
|  | ||||
| Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | ||||
| --- | ||||
|  drivers/usb/host/Kconfig | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/usb/host/Kconfig | ||||
| +++ b/drivers/usb/host/Kconfig | ||||
| @@ -71,7 +71,7 @@ config USB_XHCI_HISTB | ||||
|  config USB_XHCI_MTK | ||||
|  	tristate "xHCI support for MediaTek SoCs" | ||||
|  	select MFD_SYSCON | ||||
| -	depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || COMPILE_TEST | ||||
| +	depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || ARCH_AIROHA || COMPILE_TEST | ||||
|  	help | ||||
|  	  Say 'Y' to enable the support for the xHCI host controller | ||||
|  	  found in MediaTek SoCs. | ||||
| @ -0,0 +1,34 @@ | ||||
| From 112c6ea7ac356dab16e11084f2183e653a289e91 Mon Sep 17 00:00:00 2001 | ||||
| From: Christian Marangi <ansuelsmth@gmail.com> | ||||
| Date: Tue, 28 Oct 2025 12:35:41 +0100 | ||||
| Subject: [PATCH 10/10] PCI: mediatek-gen3: set PHY mode for Airoha EN7581 | ||||
|  | ||||
| For the Airoha EN7581 SoC, the 3rd PCIe line is attached to a special | ||||
| PHY that can be both used for USB 3.0 operation or PCIe. | ||||
|  | ||||
| Configure the PHY for PCIe operation before init it to correctly | ||||
| configure the SCU Serdes register. | ||||
|  | ||||
| This permits correct functionality and enumeration of PCIe devices on | ||||
| the 3rd PCIe line present on the SoC. | ||||
|  | ||||
| Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | ||||
| --- | ||||
|  drivers/pci/controller/pcie-mediatek-gen3.c | 6 ++++++ | ||||
|  1 file changed, 6 insertions(+) | ||||
|  | ||||
| --- a/drivers/pci/controller/pcie-mediatek-gen3.c | ||||
| +++ b/drivers/pci/controller/pcie-mediatek-gen3.c | ||||
| @@ -925,6 +925,12 @@ static int mtk_pcie_en7581_power_up(stru | ||||
|  	size = lower_32_bits(resource_size(entry->res)); | ||||
|  	regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size))); | ||||
|   | ||||
| +	err = phy_set_mode(pcie->phy, PHY_MODE_PCIE); | ||||
| +	if (err) { | ||||
| +		dev_err(dev, "failed to set PHY mode\n"); | ||||
| +		return err; | ||||
| +	} | ||||
| + | ||||
|  	/* | ||||
|  	 * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581 | ||||
|  	 * requires PHY initialization and power-on before PHY reset deassert. | ||||
| @ -8,14 +8,14 @@ include $(TOPDIR)/rules.mk | ||||
| include $(INCLUDE_DIR)/target.mk | ||||
|  | ||||
| PKG_NAME:=fortify-headers | ||||
| PKG_VERSION:=2.3.3 | ||||
| PKG_RELEASE=1 | ||||
| PKG_VERSION:=1.1 | ||||
| PKG_RELEASE=3 | ||||
|  | ||||
| PKG_SOURCE_PROTO:=git | ||||
| PKG_SOURCE_URL:=https://github.com/jvoisin/$(PKG_NAME).git | ||||
| PKG_SOURCE_DATE:=2024-10-21 | ||||
| PKG_SOURCE_VERSION:=dcdd2f1fb065b6e98d87ab7b367e8fb483f9b59c | ||||
| PKG_MIRROR_HASH:=088a7fda614daf4e42110dbb2a288f0a5f3b25ee41ed92a988e7b3c15c76230b | ||||
| PKG_SOURCE_DATE:=2019-04-14 | ||||
| PKG_SOURCE_VERSION:=e3fee64643279c144efd3d6856ed4e818c0d5ca2 | ||||
| PKG_MIRROR_HASH:=f2ce18b031aecbf43d18142941ece7c90691a8b4e96fbb1d5af94f24e5572dad | ||||
|  | ||||
| include $(INCLUDE_DIR)/toolchain-build.mk | ||||
|  | ||||
|  | ||||
							
								
								
									
										11
									
								
								toolchain/fortify-headers/patches/001-__ppoll_time64.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								toolchain/fortify-headers/patches/001-__ppoll_time64.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| --- a/include/poll.h | ||||
| +++ b/include/poll.h | ||||
| @@ -39,7 +39,7 @@ _FORTIFY_FN(poll) int poll(struct pollfd | ||||
|  	return __orig_poll(__f, __n, __s); | ||||
|  } | ||||
|   | ||||
| -#ifdef _GNU_SOURCE | ||||
| +#if defined(_GNU_SOURCE) && !(defined(_REDIR_TIME64) && _REDIR_TIME64) | ||||
|  #undef ppoll | ||||
|  _FORTIFY_FN(ppoll) int ppoll(struct pollfd *__f, nfds_t __n, const struct timespec *__s, | ||||
|                               const sigset_t *__m) | ||||
| @ -12,7 +12,7 @@ Add __extension__ before #include-next in strings.h as was done for all other he | ||||
|  | ||||
| --- a/include/strings.h | ||||
| +++ b/include/strings.h | ||||
| @@ -17,6 +17,9 @@ | ||||
| @@ -16,6 +16,9 @@ | ||||
|  #ifndef _FORTIFY_STRINGS_H | ||||
|  #define _FORTIFY_STRINGS_H | ||||
|   | ||||
|  | ||||
| @ -1,261 +0,0 @@ | ||||
| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||
| From: Hauke Mehrtens <hauke@hauke-m.de> | ||||
| Date: Sun, 26 Oct 2025 17:38:41 +0100 | ||||
| Subject: Check if FORTIFY_USE_NATIVE_CHK is defined | ||||
|  | ||||
| The previews code tried to get the value defined for | ||||
| FORTIFY_USE_NATIVE_CHK and this resulted in some build errors like | ||||
| this: | ||||
| ``` | ||||
| /include/fortify/stdio.h: In function 'vsnprintf': | ||||
| /include/fortify/stdio.h:155:49: error: "FORTIFY_USE_NATIVE_CHK" is not defined, evaluates to 0 [-Werror=undef] | ||||
|   155 | #if __has_builtin(__builtin___vsnprintf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
|       |                                                 ^~~~~~~~~~~~~~~~~~~~~~ | ||||
| ``` | ||||
|  | ||||
| Check if it is defined instead. | ||||
|  | ||||
| Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | ||||
| --- | ||||
|  include/stdio.h  | 20 ++++++++++---------- | ||||
|  include/string.h | 32 ++++++++++++++++---------------- | ||||
|  2 files changed, 26 insertions(+), 26 deletions(-) | ||||
|  | ||||
| --- a/include/stdio.h | ||||
| +++ b/include/stdio.h | ||||
| @@ -152,7 +152,7 @@ __diagnose_as_builtin(__builtin_vsnprint | ||||
|  _FORTIFY_FN(vsnprintf) int vsnprintf(char * _FORTIFY_POS0 __s, size_t __n, | ||||
|                                       const char *__f, __builtin_va_list __v) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___vsnprintf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___vsnprintf_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___vsnprintf_chk(__s, __n, _FORTIFY_SOURCE, __fh_bos(__s, 0), __f, __v); | ||||
|  #else | ||||
|  	__fh_size_t __b = __fh_bos(__s, 0); | ||||
| @@ -172,7 +172,7 @@ __diagnose_as_builtin(__builtin_vsprintf | ||||
|  _FORTIFY_FN(vsprintf) int vsprintf(char * _FORTIFY_POS0 __s, const char *__f, | ||||
|                                     __builtin_va_list __v) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___vsprintf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___vsprintf_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___vsprintf_chk(__s, _FORTIFY_SOURCE, __fh_bos(__s, 0), __f, __v); | ||||
|  #else | ||||
|  	__fh_size_t __b = __fh_bos(__s, 0); | ||||
| @@ -200,7 +200,7 @@ __diagnose_as_builtin(__builtin_vfprintf | ||||
|  #endif | ||||
|  _FORTIFY_FN(vfprintf) int vfprintf(FILE * __s, const char *__f, __builtin_va_list __v) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___vfprintf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___vfprintf_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___vfprintf_chk(__s, _FORTIFY_SOURCE, __f, __v); | ||||
|  #else | ||||
|  	return __orig_vfprintf(__s, __f, __v); | ||||
| @@ -214,7 +214,7 @@ __diagnose_as_builtin(__builtin_vprintf, | ||||
|  #endif | ||||
|  _FORTIFY_FN(vprintf) int vprintf(const char *__f, __builtin_va_list __v) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___vprintf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___vprintf_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___vprintf_chk(_FORTIFY_SOURCE, __f, __v); | ||||
|  #else | ||||
|  	return __orig_vprintf(__f, __v); | ||||
| @@ -228,7 +228,7 @@ __diagnose_as_builtin(__builtin_vasprint | ||||
|  #endif | ||||
|  _FORTIFY_FN(vasprintf) int vasprintf(char **strp, const char *fmt, __builtin_va_list ap) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___vasprintf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___vasprintf_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___vasprintf_chk(_FORTIFY_SOURCE, strp, fmt, ap); | ||||
|  #else | ||||
|  	int ret = __orig_vasprintf(strp, fmt, ap); | ||||
| @@ -275,7 +275,7 @@ __fh_format(printf, 3, 4) | ||||
|  _FORTIFY_FN(snprintf) int snprintf(char *__s, size_t __n, | ||||
|                                      const char *__f, ...) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___snprintf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___snprintf_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___snprintf_chk(__s, __n, _FORTIFY_SOURCE, __fh_bos(__s, 0), __f, __builtin_va_arg_pack()); | ||||
|  #else | ||||
|  	__fh_size_t __b = __fh_bos(__s, 0); | ||||
| @@ -291,7 +291,7 @@ __fh_format(printf, 2, 3) | ||||
|  __fh_access(read_only, 2) | ||||
|  _FORTIFY_FN(sprintf) int sprintf(char *__s, const char *__f, ...) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___sprintf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___sprintf_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___sprintf_chk(__s, _FORTIFY_SOURCE, __fh_bos(__s, 0), __f, __builtin_va_arg_pack()); | ||||
|  #else | ||||
|  	__fh_size_t __b = __fh_bos(__s, 0); | ||||
| @@ -312,7 +312,7 @@ __fh_format(printf, 1, 2) | ||||
|  __fh_access(read_only, 1) | ||||
|  _FORTIFY_FN(printf) int printf(const char *__f, ...) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___printf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___printf_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___printf_chk(_FORTIFY_SOURCE, __f, __builtin_va_arg_pack()); | ||||
|  #else | ||||
|  	return __orig_printf(__f, __builtin_va_arg_pack()); | ||||
| @@ -326,7 +326,7 @@ __diagnose_as_builtin(__builtin_fprintf, | ||||
|  #endif | ||||
|  _FORTIFY_FN(fprintf) int fprintf(FILE *__s, const char *__f, ...) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___fprintf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___fprintf_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___fprintf_chk(_FORTIFY_SOURCE, __s, __f, __builtin_va_arg_pack()); | ||||
|  #else | ||||
|  	return __orig_fprintf(__s, __f, __builtin_va_arg_pack()); | ||||
| @@ -343,7 +343,7 @@ __diagnose_as_builtin(__builtin_asprintf | ||||
|  #endif | ||||
|  _FORTIFY_FN(asprintf) int asprintf(char **strp, const char *fmt, ...) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___asprintf_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___asprintf_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___asprintf_chk(_FORTIFY_SOURCE, strp, fmt, __builtin_va_arg_pack()); | ||||
|  #else | ||||
|  	int ret = __orig_asprintf(strp, fmt, __builtin_va_arg_pack()); | ||||
| --- a/include/string.h | ||||
| +++ b/include/string.h | ||||
| @@ -48,7 +48,7 @@ _FORTIFY_FN(memcpy) void *memcpy(void * | ||||
|                                   const void * _FORTIFY_POS0 __os, size_t __n) | ||||
|  __error_if((__fh_bos(__od, 0) < __n), "'memcpy' called with `n` bigger than the size of `d`.") | ||||
|  { | ||||
| -#if __has_builtin(__builtin___memcpy_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___memcpy_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___memcpy_chk(__od, __os, __n, __fh_bos(__od, 0)); | ||||
|  #else | ||||
|  #if defined FORTIFY_PEDANTIC_CHECKS | ||||
| @@ -75,7 +75,7 @@ __diagnose_as_builtin(__builtin_memmove, | ||||
|  _FORTIFY_FN(memmove) void *memmove(void * _FORTIFY_POS0 __d, | ||||
|                                     const void * _FORTIFY_POS0 __s, size_t __n) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___memmove_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___memmove_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___memmove_chk(__d, __s, __n, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  #if defined FORTIFY_PEDANTIC_CHECKS | ||||
| @@ -99,7 +99,7 @@ __diagnose_as_builtin(__builtin_memset, | ||||
|  _FORTIFY_FN(memset) void *memset(void * _FORTIFY_POS0 __d, int __c, size_t __n) | ||||
|  __warning_if(__c != 0 && __n == 0, "'memset' will set `0` bytes; did you invert the arguments?") | ||||
|  { | ||||
| -#if __has_builtin(__builtin___memset_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___memset_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___memset_chk(__d, __c, __n, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  #if defined FORTIFY_PEDANTIC_CHECKS | ||||
| @@ -121,7 +121,7 @@ __diagnose_as_builtin(__builtin_memchr, | ||||
|  #endif | ||||
|  _FORTIFY_FN(memchr) void *memchr(const void * _FORTIFY_POS0 __d, int __c, size_t __n) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___memchr_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___memchr_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___memchr_chk(__d, __c, __n, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  #if defined FORTIFY_PEDANTIC_CHECKS | ||||
| @@ -142,7 +142,7 @@ _FORTIFY_FN(memchr) void *memchr(const v | ||||
|  __fh_access(read_only, 1, 2) | ||||
|  _FORTIFY_FN(strchr) char *strchr(const char * _FORTIFY_POS0 __s, int __c) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___strchr_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___strchr_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___strchr_chk(__s, __c, __fh_bos(__s, 0)); | ||||
|  #else | ||||
|  	__fh_size_t __b = __fh_bos(__s, 0); | ||||
| @@ -157,7 +157,7 @@ _FORTIFY_FN(strchr) char *strchr(const c | ||||
|  __fh_access(read_only, 1, 2) | ||||
|  _FORTIFY_FN(strrchr) char *strrchr(const char * _FORTIFY_POS0 __s, int __c) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___strrchr_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___strrchr_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___strrchr_chk(__s, __c, __fh_bos(__s, 0)); | ||||
|  #else | ||||
|  	__fh_size_t __b = __fh_bos(__s, 0); | ||||
| @@ -181,7 +181,7 @@ __diagnose_as_builtin(__builtin_stpcpy, | ||||
|  #endif | ||||
|  _FORTIFY_FN(stpcpy) char *stpcpy(char * _FORTIFY_POS0 __d, const char *__s) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___stpcpy_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___stpcpy_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___stpcpy_chk(__d, __s, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  	__fh_size_t __n = strlen(__s) + 1; | ||||
| @@ -205,7 +205,7 @@ __diagnose_as_builtin(__builtin_stpncpy, | ||||
|  _FORTIFY_FN(stpncpy) char *stpncpy(char * _FORTIFY_POS0 __d, const char *__s, | ||||
|                                     size_t __n) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___stpncpy_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___stpncpy_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___stpncpy_chk(__d, __s, __n, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  	// If the length strlen(src) is smaller than n, the remaining | ||||
| @@ -227,7 +227,7 @@ __diagnose_as_builtin(__builtin_strcat, | ||||
|  #endif | ||||
|  _FORTIFY_FN(strcat) char *strcat(char * _FORTIFY_POS0 __d, const char *__s) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___strcat_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___strcat_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___strcat_chk(__d, __s, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  	__fh_size_t __b = __fh_bos(__d, 0); | ||||
| @@ -245,7 +245,7 @@ __diagnose_as_builtin(__builtin_strcpy, | ||||
|  #endif | ||||
|  _FORTIFY_FN(strcpy) char *strcpy(char * _FORTIFY_POS0 __d, const char *__s) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___strcpy_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___strcpy_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___strcpy_chk(__d, __s, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  	__fh_size_t __n = strlen(__s) + 1; | ||||
| @@ -266,7 +266,7 @@ __diagnose_as_builtin(__builtin_strlen, | ||||
|  #endif | ||||
|  _FORTIFY_FN(strlen) size_t strlen(const char * _FORTIFY_POS0 __s) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___strlen_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___strlen_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___strlen_chk(__s, __fh_bos(__s, 0)); | ||||
|  #else | ||||
|  	__fh_size_t ret = __orig_strlen(__s); | ||||
| @@ -284,7 +284,7 @@ __diagnose_as_builtin(__builtin_strncat, | ||||
|  _FORTIFY_FN(strncat) char *strncat(char * _FORTIFY_POS0 __d, const char *__s, | ||||
|                                     size_t __n) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___strncat_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___strncat_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___strncat_chk(__d, __s, __n, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  #if 0 // strlen(__s) isn't guaranteed to be valid. | ||||
| @@ -311,7 +311,7 @@ __diagnose_as_builtin(__builtin_strncpy, | ||||
|  _FORTIFY_FN(strncpy) char *strncpy(char * _FORTIFY_POS0 __d, | ||||
|                                     const char *__s, size_t __n) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___strncpy_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___strncpy_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___strncpy_chk(__d, __s, __n, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  	// If the length of src is less than n, strncpy() writes additional | ||||
| @@ -334,7 +334,7 @@ __diagnose_as_builtin(__builtin_mempcpy, | ||||
|  _FORTIFY_FN(mempcpy) void *mempcpy(void * _FORTIFY_POS0 __d, | ||||
|                                     const void * _FORTIFY_POS0 __s, size_t __n) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___mempcpy_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___mempcpy_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___mempcpy_chk(__d, __s, __n, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  	if (!__d || !__s) | ||||
| @@ -361,7 +361,7 @@ __diagnose_as_builtin(__builtin_strlcat, | ||||
|  _FORTIFY_FN(strlcat) size_t strlcat(char * _FORTIFY_POS0 __d, | ||||
|                                      const char *__s, size_t __n) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___strlcat_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___strlcat_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___strlcat_chk(__d, __s, __n, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  	__fh_size_t __b = __fh_bos(__d, 0); | ||||
| @@ -380,7 +380,7 @@ __diagnose_as_builtin(__builtin_strlcpy, | ||||
|  _FORTIFY_FN(strlcpy) size_t strlcpy(char * _FORTIFY_POS0 __d, | ||||
|                                      const char *__s, size_t __n) | ||||
|  { | ||||
| -#if __has_builtin(__builtin___strlcpy_chk) && FORTIFY_USE_NATIVE_CHK | ||||
| +#if __has_builtin(__builtin___strlcpy_chk) && defined(FORTIFY_USE_NATIVE_CHK) | ||||
|  	return __builtin___strlcpy_chk(__d, __s, __n, __fh_bos(__d, 0)); | ||||
|  #else | ||||
|  	__fh_size_t __b = __fh_bos(__d, 0); | ||||
| @ -1,32 +0,0 @@ | ||||
| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||
| From: Hauke Mehrtens <hauke@hauke-m.de> | ||||
| Date: Sun, 26 Oct 2025 23:15:30 +0100 | ||||
| Subject: poll: Check if _REDIR_TIME64 is defined | ||||
|  | ||||
| Treat _REDIR_TIME64 being undefined like being set to 0. | ||||
|  | ||||
| This fixes the following compile error in strace: | ||||
| ``` | ||||
| In file included from pathtrace.c:12: | ||||
| /include/fortify/poll.h:46:30: error: "_REDIR_TIME64" is not defined, evaluates to 0 [-Werror=undef] | ||||
|    46 | #if defined(_GNU_SOURCE) && !_REDIR_TIME64 | ||||
|       |                              ^~~~~~~~~~~~~ | ||||
| cc1: all warnings being treated as errors | ||||
| ``` | ||||
|  | ||||
| Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | ||||
| --- | ||||
|  include/poll.h | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/include/poll.h | ||||
| +++ b/include/poll.h | ||||
| @@ -43,7 +43,7 @@ _FORTIFY_FN(poll) int poll(struct pollfd | ||||
|  	return __orig_poll(__f, __n, __s); | ||||
|  } | ||||
|   | ||||
| -#if defined(_GNU_SOURCE) && !_REDIR_TIME64 | ||||
| +#if defined(_GNU_SOURCE) && (!defined(_REDIR_TIME64) || !_REDIR_TIME64) | ||||
|  #undef ppoll | ||||
|  #if __has_builtin(__builtin_ppoll) | ||||
|  __diagnose_as_builtin(__builtin_ppoll, 1, 2, 3, 4) | ||||
| @ -1,80 +0,0 @@ | ||||
| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||
| From: Hauke Mehrtens <hauke@hauke-m.de> | ||||
| Date: Sun, 26 Oct 2025 23:16:01 +0100 | ||||
| Subject: fortify-headers: Remove __fh_has_builtin() | ||||
|  | ||||
| GCC complains about the `defined` usage here. Just call `__has_builtin` directly. | ||||
|  | ||||
| This fixes the following compile error when compiling strace: | ||||
| ``` | ||||
| In file included from /home/hauke/openwrt/openwrt/staging_dir/toolchain-aarch64_generic_gcc-14.3.0_musl/include/fortify/stdlib.h:27, | ||||
|                  from number_set.c:14: | ||||
| /home/hauke/openwrt/openwrt/staging_dir/toolchain-aarch64_generic_gcc-14.3.0_musl/include/fortify/fortify-headers.h:26:30: error: this use of "defined" may not be portable [-Werror=expansion-to-defined] | ||||
|    26 | #define __fh_has_builtin(x) (__has_builtin(x) || defined(x)) | ||||
|       |                              ^~~~~~~~~~~~~ | ||||
| /home/hauke/openwrt/openwrt/staging_dir/toolchain-aarch64_generic_gcc-14.3.0_musl/include/fortify/fortify-headers.h:28:7: note: in expansion of macro '__fh_has_builtin' | ||||
|    28 | #if ! __fh_has_builtin(__builtin_trap) | ||||
|       |       ^~~~~~~~~~~~~~~~ | ||||
| /home/hauke/openwrt/openwrt/staging_dir/toolchain-aarch64_generic_gcc-14.3.0_musl/include/fortify/fortify-headers.h:26:30: error: this use of "defined" may not be portable [-Werror=expansion-to-defined] | ||||
|    26 | #define __fh_has_builtin(x) (__has_builtin(x) || defined(x)) | ||||
|       |                              ^~~~~~~~~~~~~ | ||||
| /home/hauke/openwrt/openwrt/staging_dir/toolchain-aarch64_generic_gcc-14.3.0_musl/include/fortify/fortify-headers.h:73:29: note: in expansion of macro '__fh_has_builtin' | ||||
|    73 | #if _FORTIFY_SOURCE  > 2 && __fh_has_builtin (__builtin_dynamic_object_size) | ||||
|       |                             ^~~~~~~~~~~~~~~~ | ||||
| /home/hauke/openwrt/openwrt/staging_dir/toolchain-aarch64_generic_gcc-14.3.0_musl/include/fortify/fortify-headers.h:26:30: error: this use of "defined" may not be portable [-Werror=expansion-to-defined] | ||||
|    26 | #define __fh_has_builtin(x) (__has_builtin(x) || defined(x)) | ||||
|       |                              ^~~~~~~~~~~~~ | ||||
| /home/hauke/openwrt/openwrt/staging_dir/toolchain-aarch64_generic_gcc-14.3.0_musl/include/fortify/fortify-headers.h:158:5: note: in expansion of macro '__fh_has_builtin' | ||||
|   158 | #if __fh_has_builtin (__builtin_mul_overflow_p) | ||||
|       |     ^~~~~~~~~~~~~~~~ | ||||
| cc1: all warnings being treated as errors | ||||
| ``` | ||||
|  | ||||
| Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | ||||
| --- | ||||
|  include/fortify-headers.h | 14 +++----------- | ||||
|  1 file changed, 3 insertions(+), 11 deletions(-) | ||||
|  | ||||
| --- a/include/fortify-headers.h | ||||
| +++ b/include/fortify-headers.h | ||||
| @@ -21,21 +21,13 @@ | ||||
|  #error a compiler with __has_builtin support is required | ||||
|  #endif | ||||
|   | ||||
| -// https://clang.llvm.org/docs/LanguageExtensions.html#has-builtin | ||||
| -// > __has_builtin should not be used to detect support for a builtin macro; use #ifdef instead. | ||||
| -#define __fh_has_builtin(x) (__has_builtin(x) || defined(x)) | ||||
| - | ||||
| -#if ! __fh_has_builtin(__builtin_trap) | ||||
| -#define __builtin_trap abort | ||||
| -#endif | ||||
| - | ||||
|  #if _FORTIFY_SOURCE > 3 | ||||
|  #warning _FORTIFY_SOURCE > 3 is treated as 3 | ||||
|  #endif | ||||
|   | ||||
|  #ifdef __clang__ | ||||
|   | ||||
| -#if _FORTIFY_SOURCE  > 2 && __fh_has_builtin (__builtin_dynamic_object_size) && __has_attribute(pass_dynamic_object_size) | ||||
| +#if _FORTIFY_SOURCE  > 2 && __has_builtin (__builtin_dynamic_object_size) && __has_attribute(pass_dynamic_object_size) | ||||
|  #define _FORTIFY_POSN(n) const __attribute__((pass_dynamic_object_size(n))) | ||||
|  #else | ||||
|  #define _FORTIFY_POSN(n) const __attribute__((pass_object_size(n))) | ||||
| @@ -70,7 +62,7 @@ | ||||
|  #define _FORTIFY_FN(fn) _FORTIFY_FNB(fn); _FORTIFY_INLINE | ||||
|   | ||||
|  /* Use __builtin_dynamic_object_size with _FORTIFY_SOURCE>2, if available.  */ | ||||
| -#if _FORTIFY_SOURCE  > 2 && __fh_has_builtin (__builtin_dynamic_object_size) | ||||
| +#if _FORTIFY_SOURCE  > 2 && __has_builtin (__builtin_dynamic_object_size) | ||||
|  /*  | ||||
|   * See: | ||||
|   * - https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html | ||||
| @@ -155,7 +147,7 @@ | ||||
|   * - https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html | ||||
|   * - https://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins | ||||
|   */ | ||||
| -#if __fh_has_builtin (__builtin_mul_overflow_p) | ||||
| +#if __has_builtin (__builtin_mul_overflow_p) | ||||
|  #define __bmo(x, y) (x != 0 && __builtin_mul_overflow_p(x, y, (__typeof__ ((x) + (y))) 0)) | ||||
|  #else /* !__builtin_mul_overflow_p */ | ||||
|  #define __bmo(x, y) (x != 0 && (x * y) / x != y) | ||||
		Reference in New Issue
	
	Block a user
	 Tianling Shen
					Tianling Shen