* [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
@ 2025-01-15 1:26 Peter Geis
2025-01-15 1:26 ` [RFC PATCH v1 1/6] clk: rockchip: fix wrong clk_ref_usb3otg parent " Peter Geis
` (8 more replies)
0 siblings, 9 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-15 1:26 UTC (permalink / raw)
To: Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Peter Geis, Alex Bee, Algea Cao, Arnd Bergmann, Conor Dooley,
Cristian Ciocaltea, Diederik de Haas, Dragan Simic, Elaine Zhang,
FUKAUMI Naoki, Johan Jonker, Jonas Karlman,
Kishon Vijay Abraham I, Krzysztof Kozlowski, Michael Turquette,
Philipp Zabel, Rob Herring, Sebastian Reichel, Stephen Boyd,
Trevor Woerner, Vinod Koul, Zhang Yubing, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-phy
This is my newly reworked phy driver for the rk3328 usb3 phy. It is
based loosely on my original version, but as of now almost nothing of
the original driver remains. The main fix here is the discovery of
BIT(6) in the interrupt enable grf register fixes the usb3 disconnection
detection (mostly). On occasion an unpopulated usb3 hub will take
several seconds to disconnect. However this means all of the hack around
work to reset the usb core manually is no longer required.
I did my best to document all registers I could find. A lot was taken
from emails between myself and Rockchip's engineers, much thanks to
William Wu <wulf@rock-chips.com> for their assistance here. The rest of
the config bits were taken from the rk3328 and rk3228h TRMs and the
downstream driver. Everything that I couldn't find a definition for is
prefixed UNK_ or UNKNOWN_. There's a lot of obviously used configuration
registers with the pipe interface that are also undocumented.
The only major bug I have so far is my AX88179 usb3 gigabit ethernet
adapter (Pluggable brand) crashes out when large amounts of data are
transmitted. I suspect this is related to the RX and TX tuning, as
leaving it at defaults makes things worse. As I am not a USB3 engineer
and I do not have the specialized knowledge and hardware to determine
what is going wrong, I am hoping the mailing list will have an answer
here.
Please test and review.
Very Respectfully,
Peter Geis
Peter Geis (6):
clk: rockchip: fix wrong clk_ref_usb3otg parent for rk3328
dt-bindings: phy: rockchip: add rk3328 usb3 phy
phy: rockchip: add driver for rk3328 usb3 phy
arm64: dts: rockchip: add rk3328 usb3 phy node
arm64: dts: rockchip: enable the usb3 phy on rk3328-roc boards
arm64: dts: rockchip: enable the usb3 phy on remaining rk3328 boards
.../bindings/phy/rockchip,inno-usb3phy.yaml | 166 ++++
.../boot/dts/rockchip/rk3328-nanopi-r2.dtsi | 12 +
.../dts/rockchip/rk3328-orangepi-r1-plus.dtsi | 12 +
arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 12 +
.../boot/dts/rockchip/rk3328-rock-pi-e.dts | 12 +
.../arm64/boot/dts/rockchip/rk3328-rock64.dts | 12 +
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 +
drivers/clk/rockchip/clk-rk3328.c | 2 +-
drivers/phy/rockchip/Kconfig | 10 +
drivers/phy/rockchip/Makefile | 1 +
drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 869 ++++++++++++++++++
11 files changed, 1146 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c
--
2.39.5
^ permalink raw reply [flat|nested] 44+ messages in thread
* [RFC PATCH v1 1/6] clk: rockchip: fix wrong clk_ref_usb3otg parent for rk3328
2025-01-15 1:26 [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Peter Geis
@ 2025-01-15 1:26 ` Peter Geis
2025-01-15 1:26 ` [RFC PATCH v1 2/6] dt-bindings: phy: rockchip: add rk3328 usb3 phy Peter Geis
` (7 subsequent siblings)
8 siblings, 0 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-15 1:26 UTC (permalink / raw)
To: Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Peter Geis, Elaine Zhang, Michael Turquette, Stephen Boyd,
linux-arm-kernel, linux-clk, linux-kernel
Correct the clk_ref_usb3otg parent to fix clock control for the usb3
controller on rk3328. Verified against the rk3328 trm, the rk3228h trm,
and the rk3328 usb3 phy clock map.
Fixes: fe3511ad8a1c ("clk: rockchip: add clock controller for rk3328")
Signed-off-by: Peter Geis <pgwipeout@gmail.com>
---
drivers/clk/rockchip/clk-rk3328.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
index 3bb87b27b662..cf60fcf2fa5c 100644
--- a/drivers/clk/rockchip/clk-rk3328.c
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -201,7 +201,7 @@ PNAME(mux_aclk_peri_pre_p) = { "cpll_peri",
"gpll_peri",
"hdmiphy_peri" };
PNAME(mux_ref_usb3otg_src_p) = { "xin24m",
- "clk_usb3otg_ref" };
+ "clk_ref_usb3otg_src" };
PNAME(mux_xin24m_32k_p) = { "xin24m",
"clk_rtc32k" };
PNAME(mux_mac2io_src_p) = { "clk_mac2io_src",
--
2.39.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [RFC PATCH v1 2/6] dt-bindings: phy: rockchip: add rk3328 usb3 phy
2025-01-15 1:26 [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Peter Geis
2025-01-15 1:26 ` [RFC PATCH v1 1/6] clk: rockchip: fix wrong clk_ref_usb3otg parent " Peter Geis
@ 2025-01-15 1:26 ` Peter Geis
2025-01-16 13:08 ` Krzysztof Kozlowski
2025-01-15 1:26 ` [RFC PATCH v1 3/6] phy: rockchip: add driver for " Peter Geis
` (6 subsequent siblings)
8 siblings, 1 reply; 44+ messages in thread
From: Peter Geis @ 2025-01-15 1:26 UTC (permalink / raw)
To: Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Peter Geis, Conor Dooley, Kishon Vijay Abraham I,
Krzysztof Kozlowski, Rob Herring, Vinod Koul, devicetree,
linux-arm-kernel, linux-kernel, linux-phy
Add documentation for the usb3 phy as implemented on the rk3328 SoC.
Signed-off-by: Peter Geis <pgwipeout@gmail.com>
---
.../bindings/phy/rockchip,inno-usb3phy.yaml | 166 ++++++++++++++++++
1 file changed, 166 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
new file mode 100644
index 000000000000..cde489ca87ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
@@ -0,0 +1,166 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/rockchip,inno-usb3phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip USB 3.0 phy with Innosilicon IP block
+
+maintainers:
+ - Heiko Stuebner <heiko@sntech.de>
+
+properties:
+ compatible:
+ enum:
+ - rockchip,rk3328-usb3phy
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ minItems: 3
+ maxItems: 3
+
+ clock-names:
+ items:
+ - const: refclk-usb3otg
+ - const: usb3phy-otg
+ - const: usb3phy-pipe
+
+ interrupts:
+ minItems: 4
+
+ interrupt-names:
+ items:
+ - const: bvalid
+ - const: id
+ - const: linestate
+ - const: rxdet
+
+ resets:
+ minItems: 6
+
+ reset-names:
+ items:
+ - const: usb3phy-u2-por
+ - const: usb3phy-u3-por
+ - const: usb3phy-pipe-mac
+ - const: usb3phy-utmi-mac
+ - const: usb3phy-utmi-apb
+ - const: usb3phy-pipe-apb
+
+ "#address-cells":
+ const: 2
+
+ "#size-cells":
+ const: 2
+
+ ranges: true
+
+patternProperties:
+
+ utmi-port@[0-9a-f]+$:
+ type: object
+ additionalProperties: false
+
+ properties:
+ compatible:
+ enum:
+ - rockchip,rk3328-usb3phy-utmi
+
+ reg:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+ phy-supply:
+ description:
+ Phandle to a regulator that provides power to VBUS.
+ See ./phy-bindings.txt for details.
+
+ required:
+ - compatible
+ - reg
+ - "#phy-cells"
+
+ pipe-port@[0-9a-f]+$:
+ type: object
+ additionalProperties: false
+
+ properties:
+ compatible:
+ enum:
+ - rockchip,rk3328-usb3phy-pipe
+
+ reg:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+ phy-supply:
+ description:
+ Phandle to a regulator that provides power to VBUS.
+ See ./phy-bindings.txt for details.
+
+ required:
+ - compatible
+ - reg
+ - "#phy-cells"
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - interrupts
+ - interrupt-names
+ - resets
+ - reset-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/rk3328-cru.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ usb3phy: usb3-phy@ff460000 {
+ compatible = "rockchip,rk3328-usb3phy";
+ reg = <0x0 0xff460000 0x0 0x10000>;
+ clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
+ clock-names = "refclk-usb3otg", "usb3phy-otg", "usb3phy-pipe";
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bvalid", "id", "linestate", "rxdet";
+ resets = <&cru SRST_USB3PHY_U2>,
+ <&cru SRST_USB3PHY_U3>,
+ <&cru SRST_USB3PHY_PIPE>,
+ <&cru SRST_USB3OTG_UTMI>,
+ <&cru SRST_USB3PHY_OTG_P>,
+ <&cru SRST_USB3PHY_PIPE_P>;
+ reset-names = "usb3phy-u2-por", "usb3phy-u3-por",
+ "usb3phy-pipe-mac", "usb3phy-utmi-mac",
+ "usb3phy-utmi-apb", "usb3phy-pipe-apb";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ usb3phy_utmi: utmi-port@ff470000 {
+ compatible = "rockchip,rk3328-usb3phy-utmi";
+ reg = <0x0 0xff470000 0x0 0x8000>;
+ #phy-cells = <0>;
+ };
+
+ usb3phy_pipe: pipe-port@ff478000 {
+ compatible = "rockchip,rk3328-usb3phy-pipe";
+ reg = <0x0 0xff478000 0x0 0x8000>;
+ #phy-cells = <0>;
+ };
+ };
+ };
--
2.39.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [RFC PATCH v1 3/6] phy: rockchip: add driver for rk3328 usb3 phy
2025-01-15 1:26 [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Peter Geis
2025-01-15 1:26 ` [RFC PATCH v1 1/6] clk: rockchip: fix wrong clk_ref_usb3otg parent " Peter Geis
2025-01-15 1:26 ` [RFC PATCH v1 2/6] dt-bindings: phy: rockchip: add rk3328 usb3 phy Peter Geis
@ 2025-01-15 1:26 ` Peter Geis
2025-01-15 11:24 ` Piotr Oniszczuk
` (2 more replies)
2025-01-15 1:26 ` [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node Peter Geis
` (5 subsequent siblings)
8 siblings, 3 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-15 1:26 UTC (permalink / raw)
To: Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Peter Geis, Algea Cao, Arnd Bergmann, Cristian Ciocaltea,
Kishon Vijay Abraham I, Philipp Zabel, Sebastian Reichel,
Vinod Koul, Zhang Yubing, linux-arm-kernel, linux-kernel,
linux-phy
The rk3328 has a combined usb2 and usb3 phy block for the usb3 dwc
interface. The implementation up until now has been bugged, with
multiple issues ranging from disconnect detection failures to low
performance. This driver fixes the majority of the original issues and
allows better performance for the rk3328 usb3 port.
This driver sources data from multiple sources, including the rk3328
trm, the rk3228h trm, emails from Rockchip, and both the 4.4 and 5.10
downstream drivers. The current implementation allows for basic bring up
of the phy block and fixes the detection issues. Interrupts are enabled,
but currently only used for debugging. Features missing currently are
power management, OTG handling, board specific tuning, regulator control,
Currently the only known bugs are a AX88179 usb3 gigabit adapter crashes
when operating at usb3 speeds and transmitting large amounts of data and
full disconnection detections may be slower than expected (~5-10 seconds).
Signed-off-by: Peter Geis <pgwipeout@gmail.com>
---
drivers/phy/rockchip/Kconfig | 10 +
drivers/phy/rockchip/Makefile | 1 +
drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 869 ++++++++++++++++++
3 files changed, 880 insertions(+)
create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c
diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 2f7a05f21dc5..aac623e84f96 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -48,6 +48,16 @@ config PHY_ROCKCHIP_INNO_USB2
help
Support for Rockchip USB2.0 PHY with Innosilicon IP block.
+config PHY_ROCKCHIP_INNO_USB3
+ tristate "Rockchip INNO USB3PHY Driver"
+ depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
+ depends on COMMON_CLK
+ depends on USB_SUPPORT
+ select GENERIC_PHY
+ select USB_COMMON
+ help
+ Support for Rockchip USB3.0 PHY with Innosilicon IP block.
+
config PHY_ROCKCHIP_INNO_CSIDPHY
tristate "Rockchip Innosilicon MIPI CSI PHY driver"
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
index 010a824e32ce..ec15dcf37fba 100644
--- a/drivers/phy/rockchip/Makefile
+++ b/drivers/phy/rockchip/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY) += phy-rockchip-inno-csidphy.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
+obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB3) += phy-rockchip-inno-usb3.o
obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o
obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX) += phy-rockchip-samsung-hdptx.o
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb3.c b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
new file mode 100644
index 000000000000..51b9f3b7fbfa
--- /dev/null
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
@@ -0,0 +1,869 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * phy-rockchip-inno-usb3.c - USB3 PHY based on Innosilicon IP as
+ * implemented on Rockchip rk3328. Tuning data magic bits are taken as is
+ * from the downstream driver. Downstream driver is located at:
+ * https://github.com/rockchip-linux/kernel/blob/240a5660d7c23841ccf7b7cc489078bf521b9802/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
+ *
+ * Author: Peter Geis <pgwipeout@gmail.com>
+ * TODO:
+ * - Find the rest of the register names / definitions.
+ * - Implement pm functions.
+ * - Implement board specific tuning from dts.
+ * - Implement regulator control.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/mfd/syscon.h>
+#include <linux/usb/of.h>
+
+#define REG_WRITE_MASK GENMASK(31, 16)
+#define REG_WRITE_SHIFT 16
+#define DISABLE_BITS 0x0
+
+/* USB3PHY GRF Registers */
+#define USB3PHY_WAKEUP_CON_REG 0x40
+#define USB3PHY_WAKEUP_STAT_REG 0x44
+#define USB3_LINESTATE_IRQ_EN BIT(0)
+#define USB3_RXDET_IRQ_EN BIT(1)
+#define USB3_BVALID_RISE_IRQ_EN BIT(2)
+#define USB3_BVALID_FALL_IRQ_EN BIT(3)
+#define USB3_BVALID_CLEAR_MASK GENMASK(3, 2)
+#define USB3_ID_RISE_IRQ_EN BIT(4)
+#define USB3_ID_FALL_IRQ_EN BIT(5)
+#define USB3_ID_CLEAR_MASK GENMASK(5, 4)
+#define USB3_RXDET_EN BIT(6)
+
+/* PIPE registers */
+/* 0x08 for SSC, default 0x0e */
+#define UNKNOWN_PIPE_REG_000 0x000
+#define UNKNOWN_SSC_000_MASK GENMASK(2, 1)
+#define UNKNOWN_SSC_000_ENABLE (0x00 << 1)
+
+/* 0x83 for 24m, 0x01 for 25m, default 0x86 */
+#define PIPE_REG_020 0x020
+/* RX CDR multiplier high bits [7:6], as P, default 0x2, RX data rate = (2*refclk*P)/Q */
+#define PIPE_RX_CDR_MULT_HIGH_MASK GENMASK(7, 6)
+/* TX PLL divider bits [4:0], as N, default 0x6, TX data rate = (2*refclk*M)/N */
+#define PIPE_TX_PLL_DIV_MASK GENMASK(4, 0)
+
+/* 0x71 for 24m, 0x64 for 25m, default 0x71 */
+#define PIPE_REG_028 0x028
+/* RX CDR multiplier low bits [7:0], as P, default 0x71, RX data rate = (2*refclk*P)/Q */
+#define PIPE_RX_CDR_MULT_LOW_MASK GENMASK(7, 0)
+
+/* 0x26 for 24m?, 0x21 for 25m, default 0x26 */
+#define PIPE_REG_030 0x030
+/* RX CDR divider bits [4:0], as Q, default 0x6, RX data rate = (2*refclk*P)/Q */
+#define PIPE_RX_CDR_DIV_MASK GENMASK(4, 0)
+
+/* 1'b1 Disable bandgap power, default 0x00 */
+#define PIPE_REG_044 0x044
+#define BANDGAP_POWER_DISABLE BIT(4)
+
+/* 0xe0 for rx tune?, default 0xe1 */
+#define PIPE_REG_060 0x060
+#define PIPE_TX_DETECT_BYPASS_DEBUG BIT(4) /* enable to always force detection */
+/* RX CTLE frequency bandwidth response tuning bits [1:0], default 0x1 */
+#define PIPE_RX_CTLE_FREQ_BW_MASK GENMASK(1, 0)
+#define PIPE_RX_CTLE_FREQ_BW_TUNE 0x0
+
+/* default 0x49 */
+#define PIPE_REG_064 0x064
+/* RX equalizer tail current control bits [6:4], default 0x4 */
+#define PIPE_RX_EQ_TAIL_CURR_MASK GENMASK(6, 4)
+
+/* 0x08 for rx tune?, default 0x07 */
+#define PIPE_REG_068 0x068
+/* RX equalizer low frequency gain control bits [7:4], default 0x0 */
+#define PIPE_RX_EQ_LOW_GAIN_MASK GENMASK(7, 4)
+#define PIPE_RX_EQ_LOW_GAIN_TUNE (0x1 << 4)
+/* RX CTLE gain tuning bits [3:0], higher = more gain default 0x7 */
+#define PIPE_RX_CTLE_GAIN_MASK GENMASK(3, 0)
+#define PIPE_RX_CTLE_GAIN_TUNE 0x7 /* 0x5 lowest functional value, 0xf highest */
+
+/* RX ODT manual resistance config, higher = less resistance, depends on REG_1C4 BIT(5) set */
+#define PIPE_REG_06C 0x06c
+/* RX ODT manual resistance high bits [3:0], default 0x0 */
+#define PIPE_RX_ODT_RES_HIGH_MASK GENMASK(3, 0)
+#define PIPE_RX_ODT_RES_HIGH_TUNE 0xf
+
+#define PIPE_REG_070 0x070
+/* RX ODT manual resistance mid bits [7:0], default 0x03 */
+#define PIPE_RX_ODT_RES_MID_MASK GENMASK(7, 0)
+#define PIPE_RX_ODT_RES_MID_TUNE 0xff
+
+#define PIPE_REG_074 0x074
+/* RX ODT manual resistance low bits [7:0], default 0xff */
+#define PIPE_RX_ODT_RES_LOW_MASK GENMASK(7, 0)
+#define PIPE_RX_ODT_RES_LOW_TUNE 0xff
+
+/* default 0x08 */
+#define PIPE_REG_080 0x080
+#define PIPE_TX_COMMON_MODE_DIS BIT(2) /* 1'b1 disable TX common type */
+
+/* default 0x33 */
+#define PIPE_REG_088 0x088
+#define PIPE_TX_DRIVER_PREEMP_EN BIT(4) /* 1'b1 enable pre-emphasis */
+
+/* default 0x18 */
+#define PIPE_REG_0C0 0x0c0
+#define PIPE_RX_CM_EN BIT(3) /* 1'b1 enable RX CM */
+#define PIPE_TX_OBS_EN BIT(4) /* 1'b1 enable TX OBS */
+
+/* 0x12 for rx tune?, default 0x14 */
+#define PIPE_REG_0C8 0x0c8
+/* RX CDR charge pump current bits [3:1], default 0x2 */
+#define PIPE_RX_CDR_CHG_PUMP_MASK GENMASK(3, 1)
+#define PIPE_RX_CDR_CHG_PUMP_TUNE (0x2 << 1)
+
+/* 0x02 for 24m, 0x06 for 25m, default 0x06 */
+#define UNKNOWN_PIPE_REG_108 0x108
+#define UNKNOWN_REFCLK_108_24M 0x02
+
+/* 0x80 for 24m, default 0x00 */
+#define UNKNOWN_PIPE_REG_10C 0x10c
+#define UNKNOWN_REFCLK_10C_24M BIT(7)
+
+/* 0x01 for 24m, 0x00 for 25m, default 0x02 */
+#define PIPE_REG_118 0x118
+/* TX PLL multiplier high bits [3:0], as M, default 0x2, TX data rate = (2*refclk*M)/N */
+#define PIPE_TX_PLL_MUL_HIGH_MASK GENMASK(3, 0)
+
+/* 0x38 for 24m, 0x64 for 25m, default 0x71 */
+#define PIPE_REG_11C 0x11c
+/* TX PLL multiplier low bits [7:0], as M, default 0x71, TX data rate = (2*refclk*M)/N */
+#define PIPE_TX_PLL_MUL_LOW_MASK GENMASK(7, 0)
+
+/* 0x0c for SSC, default 0x1c */
+#define UNKNOWN_PIPE_REG_120 0x120
+#define UNKNOWN_SSC_120_MASK BIT(4)
+#define UNKNOWN_SSC_120_ENABLE (0x0 << 4)
+
+/* default 0x40 */
+#define PIPE_REG_12C 0x12c
+#define PIPE_TX_PLL_ALWAYS_ON BIT(0) /* disable for PLL control by pipe_pd */
+
+/* 0x05 for rx tune, default 0x01 */
+#define PIPE_REG_148 0x148
+#define PIPE_RX_CHG_PUMP_DIV_2 BIT(2) /* RX CDR charge pump div/2, default 0 */
+
+/* 0x70 for rx tune, default 0x72 */
+#define PIPE_REG_150 0x150
+#define PIPE_TX_BIAS_EN BIT(6) /* 1'b1 Enable TX Bias */
+/* RX CDR phase tracking speed bits [3:0], default 0x2 */
+#define PIPE_RX_CDR_SPEED_MASK GENMASK(3, 0)
+#define PIPE_RX_CDR_SPEED_TUNE 0x00
+
+/* default 0xd4 */
+#define PIPE_REG_160
+/* RX common mode voltage strength bits [5:4], default 0x1 */
+#define PIPE_RX_CDR_COM_VOLT_MASK GENMASK(5, 4)
+#define PIPE_RX_CDR_COM_VOLT_TUNE (0x1 << 4)
+
+/* default 0x00 */
+#define PIPE_REG_180 0x180
+/* TX driver bias reference voltage bits [3:2], in mv */
+#define PIPE_TX_BIAS_REF_VOLT_MASK GENMASK(3, 2)
+#define PIPE_TX_BIAS_REF_VOLT_200 (0x0 << 2)
+#define PIPE_TX_BIAS_REF_VOLT_175 (0x1 << 2)
+#define PIPE_TX_BIAS_REF_VOLT_225 (0x2 << 2) /* downstream 5.10 driver setting */
+#define PIPE_TX_BIAS_REF_VOLT_250 (0x3 << 2)
+
+/* default 0x01 */
+#define PIPE_REG_1A8 0x1a8
+#define PIPE_LDO_POWER_DIS BIT(4) /* 1'b1 Disable LDO Power */
+
+/* default 0x07 */
+#define PIPE_REG_1AC 0x1ac
+/* TX driver output common voltage bits [5:4], in mv */
+#define PIPE_TX_COMMON_VOLT_MASK GENMASK(5, 4)
+#define PIPE_TX_COMMON_VOLT_800 (0x0 << 4)
+#define PIPE_TX_COMMON_VOLT_750 (0x1 << 4)
+#define PIPE_TX_COMMON_VOLT_950 (0x2 << 4)
+#define PIPE_TX_COMMON_VOLT_1100 (0x3 << 4)
+
+/* default 0xfb */
+#define PIPE_REG_1B8 0x1b8
+/* TX driver swing strength bits [7:4], range 0x0 to 0xf */
+#define PIPE_TX_DRIVER_SWING_MASK GENMASK(7, 4) /* 0x2 lowest functional value */
+/* TX driver pre-emphasis strength bits [1:0], default 0x3, enabled by REG 088 */
+#define PIPE_TX_DRIVER_PREEMP_STR_MASK GENMASK(1, 0)
+
+/* set to 0xf0 for rx tune?, default 0xd0 */
+#define PIPE_REG_1C4 0x1c4
+#define PIPE_RX_ODT_AUTO_DIS BIT(5) /* Disable RX ODT auto compensation */
+#define PIPE_TX_ODT_AUTO_DIS BIT(3) /* Disable TX ODT auto compensation */
+
+/* UTMI registers */
+/* 0x0f for utmi tune, default 0x09*/
+#define UTMI_REG_030 0x030
+/* {bits[2:0]=111}: always enable pre-emphasis */
+#define UTMI_ENABLE_PRE_EMPH_MASK GENMASK(2, 0)
+#define UTMI_ENABLE_PRE_EMPH 0x07
+
+/* 0x41 for utmi tune, default 0x49 */
+#define UTMI_REG_040 0x040
+/* TX HS pre-emphasis strength bits [5:3], default 0x1*/
+#define UTMI_TX_PRE_EMPH_STR_MASK GENMASK(5, 3)
+#define UTMI_TX_PRE_EMPH_WEAKEST (0x0 << 3)
+
+/* set to 0xb5 for utmi tune, default 0xb5 */
+#define UTMI_REG_11C 0x11c
+/* {bits[4:0]=10101}: odt 45ohm tuning */
+#define UTMI_ODT_45_OHM_MASK GENMASK(4, 0)
+#define UTMI_ODT_45_OHM_TUNE 0x15
+
+enum rockchip_usb3phy_type {
+ USB3PHY_TYPE_USB2,
+ USB3PHY_TYPE_USB3,
+ USB3PHY_TYPE_MAX,
+};
+
+/**
+ * struct rockchip_usb3phy_port - usb-phy port data.
+ * @phy: port usb phy struct.
+ * @regmap: port regmap.
+ * @type: port usb phy type.
+ */
+struct rockchip_usb3phy_port {
+ struct phy *phy;
+ struct regmap *regmap;
+ enum rockchip_usb3phy_type type;
+};
+
+struct rockchip_usb3phy {
+ struct device *dev;
+ struct regmap *regmap;
+ struct clk *clk_pipe;
+ struct clk *clk_otg;
+ struct clk *clk_ref;
+ struct reset_control *u3por_rst;
+ struct reset_control *u2por_rst;
+ struct reset_control *pipe_rst;
+ struct reset_control *utmi_rst;
+ struct reset_control *pipe_apb_rst;
+ struct reset_control *utmi_apb_rst;
+ struct rockchip_usb3phy_port ports[USB3PHY_TYPE_MAX];
+ int bvalid_irq;
+ int id_irq;
+ int ls_irq;
+ int rxdet_irq;
+};
+
+struct usb3phy_config {
+ unsigned int reg;
+ unsigned int mask;
+ u8 def;
+};
+
+static const struct usb3phy_config rk3328_rx_config[] = {
+ { PIPE_REG_150, PIPE_RX_CDR_SPEED_MASK, PIPE_RX_CDR_SPEED_TUNE },
+ { PIPE_REG_0C8, PIPE_RX_CDR_CHG_PUMP_MASK, PIPE_RX_CDR_CHG_PUMP_TUNE },
+ { PIPE_REG_148, PIPE_RX_CHG_PUMP_DIV_2, PIPE_RX_CHG_PUMP_DIV_2 },
+ { PIPE_REG_068, PIPE_RX_CTLE_GAIN_MASK, PIPE_RX_CTLE_GAIN_TUNE },
+// { PIPE_REG_1C4, PIPE_RX_ODT_AUTO_DIS, PIPE_RX_ODT_AUTO_DIS },
+ { PIPE_REG_070, PIPE_RX_ODT_RES_MID_MASK, PIPE_RX_ODT_RES_MID_TUNE },
+ { PIPE_REG_06C, PIPE_RX_ODT_RES_HIGH_MASK, PIPE_RX_ODT_RES_HIGH_TUNE },
+ { PIPE_REG_060, PIPE_RX_CTLE_FREQ_BW_MASK, PIPE_RX_CTLE_FREQ_BW_TUNE },
+ { UNKNOWN_PIPE_REG_10C, UNKNOWN_REFCLK_10C_24M, UNKNOWN_REFCLK_10C_24M },
+ { PIPE_REG_060, PIPE_RX_CTLE_FREQ_BW_MASK, PIPE_RX_CTLE_FREQ_BW_TUNE },
+ { PIPE_REG_068, PIPE_RX_EQ_LOW_GAIN_MASK, PIPE_RX_EQ_LOW_GAIN_TUNE },
+};
+
+static const struct usb3phy_config rk3328_tx_config[] = {
+ { PIPE_REG_180, PIPE_TX_BIAS_REF_VOLT_MASK, PIPE_TX_BIAS_REF_VOLT_250 },
+};
+
+static const struct usb3phy_config rk3328_ssc_config[] = {
+ { UNKNOWN_PIPE_REG_000, UNKNOWN_SSC_000_MASK, UNKNOWN_SSC_000_ENABLE },
+ { UNKNOWN_PIPE_REG_120, UNKNOWN_SSC_120_MASK, UNKNOWN_SSC_120_ENABLE },
+};
+
+static const struct usb3phy_config rk3328_utmi_config[] = {
+ { UTMI_REG_030, UTMI_ENABLE_PRE_EMPH_MASK, UTMI_ENABLE_PRE_EMPH },
+ { UTMI_REG_040, UTMI_TX_PRE_EMPH_STR_MASK, UTMI_TX_PRE_EMPH_WEAKEST },
+ { UTMI_REG_11C, UTMI_ODT_45_OHM_MASK, UTMI_ODT_45_OHM_TUNE },
+};
+
+static const struct usb3phy_config rk3328_pipe_pwr_en_config[] = {
+ { PIPE_REG_1A8, PIPE_LDO_POWER_DIS, DISABLE_BITS },
+ { PIPE_REG_044, BANDGAP_POWER_DISABLE, DISABLE_BITS },
+ { PIPE_REG_150, PIPE_TX_BIAS_EN, PIPE_TX_BIAS_EN },
+ { PIPE_REG_080, PIPE_TX_COMMON_MODE_DIS, DISABLE_BITS },
+ { PIPE_REG_0C0, PIPE_TX_OBS_EN, PIPE_TX_OBS_EN },
+ { PIPE_REG_0C0, PIPE_RX_CM_EN, PIPE_RX_CM_EN },
+};
+
+static int rockchip_usb3phy_reset(struct rockchip_usb3phy *usb3phy,
+ bool reset, enum rockchip_usb3phy_type type)
+{
+ if (reset) {
+ if (type == USB3PHY_TYPE_USB2) {
+ clk_disable_unprepare(usb3phy->clk_otg);
+ reset_control_assert(usb3phy->utmi_rst);
+ reset_control_assert(usb3phy->u2por_rst);
+ }
+ if (type == USB3PHY_TYPE_USB3) {
+ clk_disable_unprepare(usb3phy->clk_pipe);
+ reset_control_assert(usb3phy->pipe_rst);
+ reset_control_assert(usb3phy->u3por_rst);
+ }
+ } else {
+ if (type == USB3PHY_TYPE_USB2) {
+ reset_control_deassert(usb3phy->u2por_rst);
+ fsleep(1000);
+ clk_prepare_enable(usb3phy->clk_otg);
+ fsleep(500);
+ reset_control_deassert(usb3phy->utmi_rst);
+ fsleep(100);
+ }
+ if (type == USB3PHY_TYPE_USB3) {
+ reset_control_deassert(usb3phy->u3por_rst);
+ fsleep(500);
+ clk_prepare_enable(usb3phy->clk_pipe);
+ fsleep(1000);
+ reset_control_deassert(usb3phy->pipe_rst);
+ fsleep(100);
+ }
+ }
+ return 0;
+}
+
+static irqreturn_t rockchip_usb3phy_linestate_irq(int irq, void *data)
+{
+ struct rockchip_usb3phy *usb3phy = data;
+ int tmp;
+
+ /* check if the interrupt is enabled */
+ regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
+ if (!(tmp & USB3_LINESTATE_IRQ_EN)) {
+ dev_warn(usb3phy->dev, "invalid linestate irq received\n");
+ return IRQ_NONE;
+ }
+
+ regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
+ if (tmp & USB3_LINESTATE_IRQ_EN)
+ dev_dbg_ratelimited(usb3phy->dev, "linestate irq received\n");
+
+ /* clear the interrupt */
+ regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_LINESTATE_IRQ_EN);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t rockchip_usb3phy_bvalid_irq(int irq, void *data)
+{
+ struct rockchip_usb3phy *usb3phy = data;
+ int tmp;
+
+ /* check if the interrupt is enabled */
+ regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
+ if (!((tmp & USB3_BVALID_FALL_IRQ_EN) | (tmp & USB3_BVALID_RISE_IRQ_EN))) {
+ dev_warn_ratelimited(usb3phy->dev, "invalid bvalid irq received\n");
+ return IRQ_NONE;
+ }
+
+ regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
+ if (tmp & USB3_BVALID_FALL_IRQ_EN)
+ dev_dbg(usb3phy->dev, "bvalid falling irq received\n");
+ if (tmp & USB3_BVALID_RISE_IRQ_EN)
+ dev_dbg(usb3phy->dev, "bvalid rising irq received\n");
+
+ /* clear the interrupt */
+ regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_BVALID_CLEAR_MASK);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t rockchip_usb3phy_id_irq(int irq, void *data)
+{
+ struct rockchip_usb3phy *usb3phy = data;
+ int tmp;
+
+ /* check if the interrupt is enabled */
+ regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
+ if (!((tmp & USB3_ID_FALL_IRQ_EN) | (tmp & USB3_ID_RISE_IRQ_EN))) {
+ dev_warn(usb3phy->dev, "invalid id irq received\n");
+ return IRQ_NONE;
+ }
+
+ regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
+ if (tmp & USB3_ID_FALL_IRQ_EN)
+ dev_dbg(usb3phy->dev, "id falling irq received\n");
+ if (tmp & USB3_ID_RISE_IRQ_EN)
+ dev_dbg(usb3phy->dev, "id rising irq received\n");
+
+ /* clear the interrupt */
+ regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_ID_CLEAR_MASK);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t rockchip_usb3phy_rxdet_irq(int irq, void *data)
+{
+ struct rockchip_usb3phy *usb3phy = data;
+ int tmp;
+
+ /* check if the interrupt is enabled */
+ regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
+ if (!(tmp & USB3_RXDET_IRQ_EN)) {
+ dev_warn(usb3phy->dev, "invalid rxdet irq received\n");
+ return IRQ_NONE;
+ }
+
+ regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
+ if (tmp & USB3_RXDET_IRQ_EN)
+ dev_dbg_ratelimited(usb3phy->dev, "rxdet irq received\n");
+
+ /* clear the interrupt */
+ regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_RXDET_IRQ_EN);
+
+ return IRQ_HANDLED;
+}
+
+static int rockchip_usb3phy_bulk_update(struct rockchip_usb3phy *usb3phy, struct regmap *regmap,
+ const struct usb3phy_config *config, unsigned int size)
+{
+ unsigned int i, val, tmp;
+ int ret = 0;
+
+ for (i = 0; i < size; i++) {
+ ret = regmap_read(regmap, config[i].reg, &val);
+ if (ret < 0) {
+ dev_err(usb3phy->dev, "failed to read addr: 0x%02x\n", config[i].reg);
+ return ret;
+ }
+ tmp = val & ~config[i].mask;
+ tmp |= config[i].def;
+ dev_dbg(usb3phy->dev, "write: 0x%03x old: 0x%02x new: 0x%02x\n",
+ config[i].reg, val, tmp);
+ ret = regmap_write(regmap, config[i].reg, tmp);
+ if (ret < 0) {
+ dev_err(usb3phy->dev, "failed to write addr: 0x%02x\n", config[i].reg);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int rockchip_usb3phy_calc_rate(struct rockchip_usb3phy *usb3phy, struct regmap *regmap)
+{
+ long rate;
+ unsigned int mul, div, target = (5000000000 / 100000);
+
+ rate = clk_get_rate(usb3phy->clk_ref) / 100000;
+ if (rate < 0) {
+ dev_err(usb3phy->dev, "failed to get refclk, %ld\n", rate);
+ return rate;
+ /* lowest possible supported clock is 4.8MHZ, highest rk3328 can do is 1.6GHZ */
+ } else if ((rate < 48) | (rate > 16000)) {
+ goto error;
+ }
+
+ for (div = 1; div < 32; div++) {
+ for (mul = 1; mul < 1024; mul++) {
+ if (((2 * rate * mul) / div) == target)
+ goto done;
+ if (((2 * rate * mul) / div) > target)
+ break;
+ }
+ }
+
+error:
+ dev_err(usb3phy->dev, "invalid refclock rate, %ld\n", rate * 100000);
+ return -EINVAL;
+
+done:
+ dev_dbg(usb3phy->dev, "refclk rate mul: %x div: %x rate: %ld\n", mul, div, (rate * 100000));
+
+ regmap_write(regmap, PIPE_REG_020, (mul >> 2) & PIPE_RX_CDR_MULT_HIGH_MASK);
+ regmap_write(regmap, PIPE_REG_020, div & PIPE_TX_PLL_DIV_MASK);
+ regmap_write(regmap, PIPE_REG_028, mul & PIPE_RX_CDR_MULT_LOW_MASK);
+ regmap_write(regmap, PIPE_REG_030, div & PIPE_RX_CDR_DIV_MASK);
+ regmap_write(regmap, PIPE_REG_118, (mul >> 8) & PIPE_TX_PLL_MUL_HIGH_MASK);
+ regmap_write(regmap, PIPE_REG_11C, mul & PIPE_TX_PLL_MUL_LOW_MASK);
+
+ return 0;
+}
+
+static int rockchip_usb3phy_init(struct phy *phy)
+{
+ struct rockchip_usb3phy_port *port = phy_get_drvdata(phy);
+ struct rockchip_usb3phy *usb3phy = dev_get_drvdata(phy->dev.parent);
+ int tmp, ret;
+
+ dev_warn(usb3phy->dev, "usb3phy_init %s\n", dev_name(&phy->dev));
+ clk_prepare_enable(usb3phy->clk_ref);
+ rockchip_usb3phy_reset(usb3phy, false, port->type);
+
+ if (port->type == USB3PHY_TYPE_USB2) {
+ /*
+ * "For RK3328 SoC, pre-emphasis and pre-emphasis strength must be
+ * written as one fixed value. The ODT 45ohm value should be tuned
+ * for different boards to adjust HS eye height."
+ */
+ dev_dbg(usb3phy->dev, "tuning UTMI\n");
+ ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_utmi_config,
+ ARRAY_SIZE(rk3328_utmi_config));
+ }
+
+ if (port->type == USB3PHY_TYPE_USB3) {
+ /* Enable interrupts */
+ tmp = (USB3_LINESTATE_IRQ_EN | USB3_ID_FALL_IRQ_EN | USB3_ID_RISE_IRQ_EN |
+ USB3_RXDET_IRQ_EN | USB3_BVALID_RISE_IRQ_EN | USB3_BVALID_FALL_IRQ_EN);
+ tmp |= (tmp << REG_WRITE_SHIFT);
+
+ ret = regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, tmp);
+ if (ret < 0) {
+ /* interrupt write determines if we have write access */
+ dev_err(usb3phy->dev, "failed to write interrupts\n");
+ return ret;
+ }
+
+ /* Configure for 24M ref clk */
+ dev_dbg(usb3phy->dev, "setting pipe for 24M refclk\n");
+ if (rockchip_usb3phy_calc_rate(usb3phy, usb3phy->regmap))
+ return -EINVAL;
+
+ /* Enable SSC */
+ udelay(3);
+ dev_dbg(usb3phy->dev, "setting pipe for SSC\n");
+ ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_ssc_config,
+ ARRAY_SIZE(rk3328_ssc_config));
+
+ /* "Tuning RX for compliance RJTL test" */
+ dev_dbg(usb3phy->dev, "setting pipe for RX tuning\n");
+ ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_rx_config,
+ ARRAY_SIZE(rk3328_rx_config));
+ if (ret)
+ return ret;
+
+ /*
+ * "Tuning TX to increase the bias current used in TX driver and RX EQ,
+ * it can also increase the voltage of LFPS."
+ */
+ dev_dbg(usb3phy->dev, "setting pipe for TX tuning\n");
+ ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap,
+ rk3328_tx_config, ARRAY_SIZE(rk3328_tx_config));
+
+ /* Power up the pipe */
+ dev_dbg(usb3phy->dev, "setting pipe power on\n");
+ ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_pipe_pwr_en_config,
+ ARRAY_SIZE(rk3328_pipe_pwr_en_config));
+ }
+
+ return 0;
+}
+
+static int rockchip_usb3phy_parse_dt(struct rockchip_usb3phy *usb3phy, struct device *dev)
+{
+ int ret;
+
+ usb3phy->clk_pipe = devm_clk_get(dev, "usb3phy-pipe");
+ if (IS_ERR(usb3phy->clk_pipe)) {
+ dev_err(dev, "could not get usb3phy pipe clock\n");
+ return PTR_ERR(usb3phy->clk_pipe);
+ }
+
+ usb3phy->clk_otg = devm_clk_get(dev, "usb3phy-otg");
+ if (IS_ERR(usb3phy->clk_otg)) {
+ dev_err(dev, "could not get usb3phy otg clock\n");
+ return PTR_ERR(usb3phy->clk_otg);
+ }
+
+ usb3phy->clk_ref = devm_clk_get(dev, "refclk-usb3otg");
+ if (IS_ERR(usb3phy->clk_ref)) {
+ dev_err(dev, "could not get usb3phy ref clock\n");
+ return PTR_ERR(usb3phy->clk_ref);
+ }
+
+ usb3phy->u2por_rst = devm_reset_control_get(dev, "usb3phy-u2-por");
+ if (IS_ERR(usb3phy->u2por_rst)) {
+ dev_err(dev, "no usb3phy-u2-por reset control found\n");
+ return PTR_ERR(usb3phy->u2por_rst);
+ }
+
+ usb3phy->u3por_rst = devm_reset_control_get(dev, "usb3phy-u3-por");
+ if (IS_ERR(usb3phy->u3por_rst)) {
+ dev_err(dev, "no usb3phy-u3-por reset control found\n");
+ return PTR_ERR(usb3phy->u3por_rst);
+ }
+
+ usb3phy->pipe_rst = devm_reset_control_get(dev, "usb3phy-pipe-mac");
+ if (IS_ERR(usb3phy->pipe_rst)) {
+ dev_err(dev, "no usb3phy_pipe_mac reset control found\n");
+ return PTR_ERR(usb3phy->pipe_rst);
+ }
+
+ usb3phy->utmi_rst = devm_reset_control_get(dev, "usb3phy-utmi-mac");
+ if (IS_ERR(usb3phy->utmi_rst)) {
+ dev_err(dev, "no usb3phy-utmi-mac reset control found\n");
+ return PTR_ERR(usb3phy->utmi_rst);
+ }
+
+ usb3phy->pipe_apb_rst = devm_reset_control_get(dev, "usb3phy-pipe-apb");
+ if (IS_ERR(usb3phy->pipe_apb_rst)) {
+ dev_err(dev, "no usb3phy-pipe-apb reset control found\n");
+ return PTR_ERR(usb3phy->pipe_apb_rst);
+ }
+
+ usb3phy->utmi_apb_rst = devm_reset_control_get(dev, "usb3phy-utmi-apb");
+ if (IS_ERR(usb3phy->utmi_apb_rst)) {
+ dev_err(dev, "no usb3phy-utmi-apb reset control found\n");
+ return PTR_ERR(usb3phy->utmi_apb_rst);
+ }
+
+ usb3phy->ls_irq = of_irq_get_byname(dev->of_node, "linestate");
+ if (usb3phy->ls_irq < 0) {
+ dev_err(dev, "no linestate irq provided\n");
+ return usb3phy->ls_irq;
+ }
+
+ ret = devm_request_threaded_irq(dev, usb3phy->ls_irq, NULL, rockchip_usb3phy_linestate_irq,
+ IRQF_ONESHOT, "rockchip_usb3phy_ls", usb3phy);
+ if (ret) {
+ dev_err(dev, "failed to request linestate irq handle\n");
+ return ret;
+ }
+
+ usb3phy->bvalid_irq = of_irq_get_byname(dev->of_node, "bvalid");
+ if (usb3phy->bvalid_irq < 0) {
+ dev_err(dev, "no bvalid irq provided\n");
+ return usb3phy->bvalid_irq;
+ }
+
+ ret = devm_request_threaded_irq(dev, usb3phy->bvalid_irq, NULL, rockchip_usb3phy_bvalid_irq,
+ IRQF_ONESHOT, "rockchip_usb3phy_bvalid", usb3phy);
+ if (ret) {
+ dev_err(dev, "failed to request bvalid irq handle\n");
+ return ret;
+ }
+
+ usb3phy->id_irq = of_irq_get_byname(dev->of_node, "id");
+ if (usb3phy->id_irq < 0) {
+ dev_err(dev, "no id irq provided\n");
+ return usb3phy->id_irq;
+ }
+
+ ret = devm_request_threaded_irq(dev, usb3phy->id_irq, NULL, rockchip_usb3phy_id_irq,
+ IRQF_ONESHOT, "rockchip_usb3phy-id", usb3phy);
+ if (ret) {
+ dev_err(dev, "failed to request id irq handle\n");
+ return ret;
+ }
+
+ usb3phy->rxdet_irq = of_irq_get_byname(dev->of_node, "rxdet");
+ if (usb3phy->rxdet_irq < 0) {
+ dev_err(dev, "no rxdet irq provided\n");
+ return usb3phy->rxdet_irq;
+ }
+
+ ret = devm_request_threaded_irq(dev, usb3phy->rxdet_irq, NULL, rockchip_usb3phy_rxdet_irq,
+ IRQF_ONESHOT, "rockchip_usb3phy-rxdet", usb3phy);
+ if (ret) {
+ dev_err(dev, "failed to request rxdet irq handle\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rockchip_usb3phy_exit(struct phy *phy)
+{
+ struct rockchip_usb3phy_port *port = phy_get_drvdata(phy);
+ struct rockchip_usb3phy *usb3phy = dev_get_drvdata(phy->dev.parent);
+
+ dev_dbg(usb3phy->dev, "usb3phy_shutdown\n");
+ rockchip_usb3phy_reset(usb3phy, true, port->type);
+
+ return 0;
+}
+
+static const struct phy_ops rockchip_usb3phy_ops = {
+ .init = rockchip_usb3phy_init,
+ .exit = rockchip_usb3phy_exit,
+ .owner = THIS_MODULE,
+};
+
+static const struct regmap_config rockchip_usb3phy_utmi_port_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = 0x400,
+ .cache_type = REGCACHE_NONE,
+ .fast_io = true,
+ .name = "utmi-port",
+};
+
+static const struct regmap_config rockchip_usb3phy_pipe_port_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = 0x400,
+ .cache_type = REGCACHE_NONE,
+ .fast_io = true,
+ .name = "pipe-port",
+};
+
+static const struct regmap_config rockchip_usb3phy_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = 0x400,
+ .write_flag_mask = REG_WRITE_MASK,
+ .cache_type = REGCACHE_NONE,
+ .fast_io = true,
+};
+
+static int rockchip_usb3phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *child_np;
+ struct phy_provider *provider;
+ struct rockchip_usb3phy *usb3phy;
+ const struct regmap_config regmap_config = rockchip_usb3phy_regmap_config;
+ void __iomem *base;
+ int i, ret;
+
+ dev_dbg(dev, "Probe usb3phy main block\n");
+ usb3phy = devm_kzalloc(dev, sizeof(*usb3phy), GFP_KERNEL);
+ if (!usb3phy)
+ return -ENOMEM;
+
+ ret = rockchip_usb3phy_parse_dt(usb3phy, dev);
+ if (ret) {
+ dev_err(dev, "parse dt failed %i\n", ret);
+ return ret;
+ }
+
+ base = devm_of_iomap(dev, np, 0, NULL);
+ if (IS_ERR(base)) {
+ dev_err(dev, "failed port ioremap\n");
+ return PTR_ERR(base);
+ }
+
+ usb3phy->regmap = devm_regmap_init_mmio(dev, base, ®map_config);
+ if (IS_ERR(usb3phy->regmap)) {
+ dev_err(dev, "regmap init failed\n");
+ return PTR_ERR(usb3phy->regmap);
+ }
+
+ usb3phy->dev = dev;
+ platform_set_drvdata(pdev, usb3phy);
+
+ /* place block in reset */
+ reset_control_assert(usb3phy->pipe_rst);
+ reset_control_assert(usb3phy->utmi_rst);
+ reset_control_assert(usb3phy->u3por_rst);
+ reset_control_assert(usb3phy->u2por_rst);
+ reset_control_assert(usb3phy->pipe_apb_rst);
+ reset_control_assert(usb3phy->utmi_apb_rst);
+
+ fsleep(20);
+
+ /* take apb interface out of reset */
+ reset_control_deassert(usb3phy->utmi_apb_rst);
+ reset_control_deassert(usb3phy->pipe_apb_rst);
+
+ /* enable usb3phy rx detection to fix disconnection issues */
+ regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG,
+ (USB3_RXDET_EN | (USB3_RXDET_EN << REG_WRITE_SHIFT)));
+
+ dev_dbg(dev, "Completed usb3phy core probe\n");
+
+ /* probe the actual ports */
+ i = 0;
+ for_each_available_child_of_node(np, child_np) {
+ const struct regmap_config *regmap_port_config;
+ struct rockchip_usb3phy_port *port = &usb3phy->ports[i];
+ struct phy *phy;
+
+ if (of_node_name_eq(child_np, "utmi-port")) {
+ port->type = USB3PHY_TYPE_USB2;
+ regmap_port_config = &rockchip_usb3phy_utmi_port_regmap_config;
+ } else if (of_node_name_eq(child_np, "pipe-port")) {
+ port->type = USB3PHY_TYPE_USB3;
+ regmap_port_config = &rockchip_usb3phy_pipe_port_regmap_config;
+ } else {
+ dev_err(dev, "unknown child node port type %s\n", child_np->name);
+ goto err_port;
+ }
+
+ base = devm_of_iomap(dev, child_np, 0, NULL);
+ if (IS_ERR(base)) {
+ dev_err(dev, "failed port ioremap\n");
+ ret = PTR_ERR(base);
+ goto err_port;
+ }
+
+ port->regmap = devm_regmap_init_mmio(dev, base, regmap_port_config);
+ if (IS_ERR(port->regmap)) {
+ dev_err(dev, "regmap init failed\n");
+ ret = PTR_ERR(port->regmap);
+ goto err_port;
+ }
+
+ phy = devm_phy_create(dev, child_np, &rockchip_usb3phy_ops);
+ if (IS_ERR(phy)) {
+ dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
+ ret = PTR_ERR(phy);
+ goto err_port;
+ }
+
+ port->phy = phy;
+ phy_set_drvdata(port->phy, port);
+
+ /* to prevent out of boundary */
+ if (++i >= USB3PHY_TYPE_MAX) {
+ of_node_put(child_np);
+ break;
+ }
+
+ dev_info(dev, "Completed usb3phy %s port init\n", child_np->name);
+ }
+
+ provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ return PTR_ERR_OR_ZERO(provider);
+
+err_port:
+ of_node_put(child_np);
+ return ret;
+}
+
+static const struct of_device_id rockchip_usb3phy_dt_ids[] = {
+ { .compatible = "rockchip,rk3328-usb3phy", },
+};
+
+MODULE_DEVICE_TABLE(of, rockchip_usb3phy_dt_ids);
+
+static struct platform_driver rockchip_usb3phy_driver = {
+ .probe = rockchip_usb3phy_probe,
+ .driver = {
+ .name = "rockchip-usb3-phy",
+ .of_match_table = rockchip_usb3phy_dt_ids,
+ },
+};
+
+module_platform_driver(rockchip_usb3phy_driver);
+
+MODULE_AUTHOR("Peter Geis <pgwipeout@gmail.com>");
+MODULE_DESCRIPTION("Rockchip Innosilicon USB3PHY driver");
+MODULE_LICENSE("GPL");
--
2.39.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-15 1:26 [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Peter Geis
` (2 preceding siblings ...)
2025-01-15 1:26 ` [RFC PATCH v1 3/6] phy: rockchip: add driver for " Peter Geis
@ 2025-01-15 1:26 ` Peter Geis
2025-01-16 13:01 ` Krzysztof Kozlowski
2025-01-15 1:26 ` [RFC PATCH v1 5/6] arm64: dts: rockchip: enable the usb3 phy on rk3328-roc boards Peter Geis
` (4 subsequent siblings)
8 siblings, 1 reply; 44+ messages in thread
From: Peter Geis @ 2025-01-15 1:26 UTC (permalink / raw)
To: Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Peter Geis, Alex Bee, Conor Dooley, Diederik de Haas,
Dragan Simic, Johan Jonker, Jonas Karlman, Krzysztof Kozlowski,
Rob Herring, devicetree, linux-arm-kernel, linux-kernel
Add the node for the rk3328 usb3 phy. This node provides a combined usb2
and usb3 phy which are permenantly tied to the dwc3 usb3 controller.
Signed-off-by: Peter Geis <pgwipeout@gmail.com>
---
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 ++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 7d992c3c01ce..181a900d41f9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -903,6 +903,43 @@ u2phy_host: host-port {
};
};
+ usb3phy: usb3-phy@ff460000 {
+ compatible = "rockchip,rk3328-usb3phy";
+ reg = <0x0 0xff460000 0x0 0x10000>;
+ clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
+ clock-names = "refclk-usb3otg", "usb3phy-otg", "usb3phy-pipe";
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bvalid", "id", "linestate", "rxdet";
+ resets = <&cru SRST_USB3PHY_U2>,
+ <&cru SRST_USB3PHY_U3>,
+ <&cru SRST_USB3PHY_PIPE>,
+ <&cru SRST_USB3OTG_UTMI>,
+ <&cru SRST_USB3PHY_OTG_P>,
+ <&cru SRST_USB3PHY_PIPE_P>;
+ reset-names = "usb3phy-u2-por", "usb3phy-u3-por",
+ "usb3phy-pipe-mac", "usb3phy-utmi-mac",
+ "usb3phy-utmi-apb", "usb3phy-pipe-apb";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ status = "disabled";
+
+ usb3phy_utmi: utmi-port@ff470000 {
+ compatible = "rockchip,rk3328-usb3phy-utmi";
+ reg = <0x0 0xff470000 0x0 0x8000>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ usb3phy_pipe: pipe-port@ff478000 {
+ compatible = "rockchip,rk3328-usb3phy-pipe";
+ reg = <0x0 0xff478000 0x0 0x8000>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+
sdmmc: mmc@ff500000 {
compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xff500000 0x0 0x4000>;
@@ -1067,6 +1104,8 @@ usbdrd3: usb@ff600000 {
clock-names = "ref_clk", "suspend_clk",
"bus_clk";
dr_mode = "otg";
+ phys = <&usb3phy_utmi>, <&usb3phy_pipe>;
+ phy-names = "usb2-phy", "usb3-phy";
phy_type = "utmi_wide";
snps,dis-del-phy-power-chg-quirk;
snps,dis_enblslpm_quirk;
--
2.39.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [RFC PATCH v1 5/6] arm64: dts: rockchip: enable the usb3 phy on rk3328-roc boards
2025-01-15 1:26 [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Peter Geis
` (3 preceding siblings ...)
2025-01-15 1:26 ` [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node Peter Geis
@ 2025-01-15 1:26 ` Peter Geis
2025-01-15 1:26 ` [RFC PATCH v1 6/6] arm64: dts: rockchip: enable the usb3 phy on remaining rk3328 boards Peter Geis
` (3 subsequent siblings)
8 siblings, 0 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-15 1:26 UTC (permalink / raw)
To: Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Peter Geis, Conor Dooley, Diederik de Haas, Dragan Simic,
Johan Jonker, Krzysztof Kozlowski, Rob Herring, devicetree,
linux-arm-kernel, linux-kernel
Enable the new usb3 phy nodes on the rk3328-roc boards.
Signed-off-by: Peter Geis <pgwipeout@gmail.com>
---
arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
index b5bd5e7d5748..22d93c1901ed 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
@@ -360,6 +360,18 @@ &usbdrd3 {
status = "okay";
};
+&usb3phy {
+ status = "okay";
+};
+
+&usb3phy_utmi {
+ status = "okay";
+};
+
+&usb3phy_pipe {
+ status = "okay";
+};
+
&usb_host0_ehci {
status = "okay";
};
--
2.39.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [RFC PATCH v1 6/6] arm64: dts: rockchip: enable the usb3 phy on remaining rk3328 boards
2025-01-15 1:26 [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Peter Geis
` (4 preceding siblings ...)
2025-01-15 1:26 ` [RFC PATCH v1 5/6] arm64: dts: rockchip: enable the usb3 phy on rk3328-roc boards Peter Geis
@ 2025-01-15 1:26 ` Peter Geis
2025-01-15 11:22 ` [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Piotr Oniszczuk
` (2 subsequent siblings)
8 siblings, 0 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-15 1:26 UTC (permalink / raw)
To: Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Peter Geis, Conor Dooley, Diederik de Haas, Dragan Simic,
FUKAUMI Naoki, Johan Jonker, Krzysztof Kozlowski, Rob Herring,
Trevor Woerner, devicetree, linux-arm-kernel, linux-kernel
Enable the new usb3 phy nodes on the remaining rk3328 boards. This is
done separately from the rk3328-roc boards due to lack of testing, in
case of regressions.
Signed-off-by: Peter Geis <pgwipeout@gmail.com>
---
arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi | 12 ++++++++++++
.../boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi | 12 ++++++++++++
arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts | 12 ++++++++++++
arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 12 ++++++++++++
4 files changed, 48 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
index 1715d311e1f2..a4d880725a96 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
@@ -385,6 +385,18 @@ rtl8153: device@2 {
};
};
+&usb3phy {
+ status = "okay";
+};
+
+&usb3phy_utmi {
+ status = "okay";
+};
+
+&usb3phy_pipe {
+ status = "okay";
+};
+
&usb_host0_ehci {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
index 82021ffb0a49..f70d28e6da5d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
@@ -349,6 +349,18 @@ rtl8153: device@2 {
};
};
+&usb3phy {
+ status = "okay";
+};
+
+&usb3phy_utmi {
+ status = "okay";
+};
+
+&usb3phy_pipe {
+ status = "okay";
+};
+
&usb_host0_ehci {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
index 425de197ddb8..4ce6b16cf291 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
@@ -440,6 +440,18 @@ &usbdrd3 {
status = "okay";
};
+&usb3phy {
+ status = "okay";
+};
+
+&usb3phy_utmi {
+ status = "okay";
+};
+
+&usb3phy_pipe {
+ status = "okay";
+};
+
&usb_host0_ehci {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
index 745d3e996418..2e366de96390 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
@@ -379,6 +379,18 @@ &usbdrd3 {
status = "okay";
};
+&usb3phy {
+ status = "okay";
+};
+
+&usb3phy_utmi {
+ status = "okay";
+};
+
+&usb3phy_pipe {
+ status = "okay";
+};
+
&usb_host0_ehci {
status = "okay";
};
--
2.39.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-15 1:26 [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Peter Geis
` (5 preceding siblings ...)
2025-01-15 1:26 ` [RFC PATCH v1 6/6] arm64: dts: rockchip: enable the usb3 phy on remaining rk3328 boards Peter Geis
@ 2025-01-15 11:22 ` Piotr Oniszczuk
2025-01-15 12:25 ` Peter Geis
2025-01-18 9:08 ` Krzysztof Kozlowski
2025-02-26 19:49 ` (subset) " Heiko Stuebner
8 siblings, 1 reply; 44+ messages in thread
From: Piotr Oniszczuk @ 2025-01-15 11:22 UTC (permalink / raw)
To: Peter Geis
Cc: Heiko Stuebner, Algea Cao, Michael Turquette, kever.yang,
linux-phy, wulf, zyw, Dragan Simic, Kishon Vijay Abraham I,
Rob Herring, Sebastian Reichel, linux-clk, linux-rockchip,
devicetree, Conor Dooley, Philipp Zabel, Arnd Bergmann,
Jonas Karlman, frank.wang, Elaine Zhang, Alex Bee, william.wu,
Zhang Yubing, Johan Jonker, linux-arm-kernel, Trevor Woerner,
Stephen Boyd, linux-kernel, Vinod Koul, FUKAUMI Naoki,
Diederik de Haas, Krzysztof Kozlowski
> Wiadomość napisana przez Peter Geis <pgwipeout@gmail.com> w dniu 15 sty 2025, o godz. 02:26:
>
>
> This is my newly reworked phy driver for the rk3328 usb3 phy. It is
> based loosely on my original version, but as of now almost nothing of
> the original driver remains. The main fix here is the discovery of
> BIT(6) in the interrupt enable grf register fixes the usb3 disconnection
> detection (mostly). On occasion an unpopulated usb3 hub will take
> several seconds to disconnect. However this means all of the hack around
> work to reset the usb core manually is no longer required.
>
> I did my best to document all registers I could find. A lot was taken
> from emails between myself and Rockchip's engineers, much thanks to
> William Wu <wulf@rock-chips.com> for their assistance here. The rest of
> the config bits were taken from the rk3328 and rk3228h TRMs and the
> downstream driver. Everything that I couldn't find a definition for is
> prefixed UNK_ or UNKNOWN_. There's a lot of obviously used configuration
> registers with the pipe interface that are also undocumented.
>
> The only major bug I have so far is my AX88179 usb3 gigabit ethernet
> adapter (Pluggable brand) crashes out when large amounts of data are
> transmitted. I suspect this is related to the RX and TX tuning, as
> leaving it at defaults makes things worse. As I am not a USB3 engineer
> and I do not have the specialized knowledge and hardware to determine
> what is going wrong, I am hoping the mailing list will have an answer
> here.
>
> Please test and review.
>
> Very Respectfully,
> Peter Geis
>
>
>
> Peter Geis (6):
> clk: rockchip: fix wrong clk_ref_usb3otg parent for rk3328
> dt-bindings: phy: rockchip: add rk3328 usb3 phy
> phy: rockchip: add driver for rk3328 usb3 phy
> arm64: dts: rockchip: add rk3328 usb3 phy node
> arm64: dts: rockchip: enable the usb3 phy on rk3328-roc boards
> arm64: dts: rockchip: enable the usb3 phy on remaining rk3328 boards
>
> .../bindings/phy/rockchip,inno-usb3phy.yaml | 166 ++++
> .../boot/dts/rockchip/rk3328-nanopi-r2.dtsi | 12 +
> .../dts/rockchip/rk3328-orangepi-r1-plus.dtsi | 12 +
> arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 12 +
> .../boot/dts/rockchip/rk3328-rock-pi-e.dts | 12 +
> .../arm64/boot/dts/rockchip/rk3328-rock64.dts | 12 +
> arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 +
> drivers/clk/rockchip/clk-rk3328.c | 2 +-
> drivers/phy/rockchip/Kconfig | 10 +
> drivers/phy/rockchip/Makefile | 1 +
> drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 869 ++++++++++++++++++
> 11 files changed, 1146 insertions(+), 1 deletion(-)
> create mode 100644 Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c
>
> --
> 2.39.5
>
>
Peter,
I applied this as test run on 6.12.9 and dmesg says:
[ 16.368514] rockchip-usb3-phy ff460000.usb3-phy: could not get usb3phy ref clock
[ 16.368534] rockchip-usb3-phy ff460000.usb3-phy: parse dt failed -2
[ 16.368543] rockchip-usb3-phy ff460000.usb3-phy: probe with driver rockchip-usb3-phy failed with error -2
This is on beelink a1 tvbox.
Do I miss something?
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 3/6] phy: rockchip: add driver for rk3328 usb3 phy
2025-01-15 1:26 ` [RFC PATCH v1 3/6] phy: rockchip: add driver for " Peter Geis
@ 2025-01-15 11:24 ` Piotr Oniszczuk
2025-01-16 14:09 ` Peter Geis
2025-01-16 12:59 ` Krzysztof Kozlowski
2025-01-16 15:26 ` Diederik de Haas
2 siblings, 1 reply; 44+ messages in thread
From: Piotr Oniszczuk @ 2025-01-15 11:24 UTC (permalink / raw)
To: Peter Geis
Cc: Heiko Stuebner, Kishon Vijay Abraham I, Algea Cao, linux-kernel,
Philipp Zabel, Arnd Bergmann, frank.wang, william.wu, kever.yang,
linux-phy, Sebastian Reichel, linux-rockchip, Vinod Koul,
Zhang Yubing, zyw, wulf, linux-arm-kernel
> Wiadomość napisana przez Peter Geis <pgwipeout@gmail.com> w dniu 15 sty 2025, o godz. 02:26:
>
> The rk3328 has a combined usb2 and usb3 phy block for the usb3 dwc
> interface. The implementation up until now has been bugged, with
> multiple issues ranging from disconnect detection failures to low
> performance. This driver fixes the majority of the original issues and
> allows better performance for the rk3328 usb3 port.
>
> This driver sources data from multiple sources, including the rk3328
> trm, the rk3228h trm, emails from Rockchip, and both the 4.4 and 5.10
> downstream drivers. The current implementation allows for basic bring up
> of the phy block and fixes the detection issues. Interrupts are enabled,
> but currently only used for debugging. Features missing currently are
> power management, OTG handling, board specific tuning, regulator control,
>
> Currently the only known bugs are a AX88179 usb3 gigabit adapter crashes
> when operating at usb3 speeds and transmitting large amounts of data and
> full disconnection detections may be slower than expected (~5-10 seconds).
>
> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> ---
>
> drivers/phy/rockchip/Kconfig | 10 +
> drivers/phy/rockchip/Makefile | 1 +
> drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 869 ++++++++++++++++++
> 3 files changed, 880 insertions(+)
> create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c
>
> diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
> index 2f7a05f21dc5..aac623e84f96 100644
> --- a/drivers/phy/rockchip/Kconfig
> +++ b/drivers/phy/rockchip/Kconfig
> @@ -48,6 +48,16 @@ config PHY_ROCKCHIP_INNO_USB2
> help
> Support for Rockchip USB2.0 PHY with Innosilicon IP block.
>
> +config PHY_ROCKCHIP_INNO_USB3
> + tristate "Rockchip INNO USB3PHY Driver"
> + depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
> + depends on COMMON_CLK
> + depends on USB_SUPPORT
> + select GENERIC_PHY
> + select USB_COMMON
> + help
> + Support for Rockchip USB3.0 PHY with Innosilicon IP block.
> +
> config PHY_ROCKCHIP_INNO_CSIDPHY
> tristate "Rockchip Innosilicon MIPI CSI PHY driver"
> depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
> diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
> index 010a824e32ce..ec15dcf37fba 100644
> --- a/drivers/phy/rockchip/Makefile
> +++ b/drivers/phy/rockchip/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY) += phy-rockchip-inno-csidphy.o
> obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o
> obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
> obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
> +obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB3) += phy-rockchip-inno-usb3.o
> obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o
> obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
> obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX) += phy-rockchip-samsung-hdptx.o
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb3.c b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> new file mode 100644
> index 000000000000..51b9f3b7fbfa
> --- /dev/null
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> @@ -0,0 +1,869 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * phy-rockchip-inno-usb3.c - USB3 PHY based on Innosilicon IP as
> + * implemented on Rockchip rk3328. Tuning data magic bits are taken as is
> + * from the downstream driver. Downstream driver is located at:
> + * https://github.com/rockchip-linux/kernel/blob/240a5660d7c23841ccf7b7cc489078bf521b9802/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> + *
> + * Author: Peter Geis <pgwipeout@gmail.com>
> + * TODO:
> + * - Find the rest of the register names / definitions.
> + * - Implement pm functions.
> + * - Implement board specific tuning from dts.
> + * - Implement regulator control.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/usb/of.h>
> +
> +#define REG_WRITE_MASK GENMASK(31, 16)
> +#define REG_WRITE_SHIFT 16
> +#define DISABLE_BITS 0x0
> +
> +/* USB3PHY GRF Registers */
> +#define USB3PHY_WAKEUP_CON_REG 0x40
> +#define USB3PHY_WAKEUP_STAT_REG 0x44
> +#define USB3_LINESTATE_IRQ_EN BIT(0)
> +#define USB3_RXDET_IRQ_EN BIT(1)
> +#define USB3_BVALID_RISE_IRQ_EN BIT(2)
> +#define USB3_BVALID_FALL_IRQ_EN BIT(3)
> +#define USB3_BVALID_CLEAR_MASK GENMASK(3, 2)
> +#define USB3_ID_RISE_IRQ_EN BIT(4)
> +#define USB3_ID_FALL_IRQ_EN BIT(5)
> +#define USB3_ID_CLEAR_MASK GENMASK(5, 4)
> +#define USB3_RXDET_EN BIT(6)
> +
> +/* PIPE registers */
> +/* 0x08 for SSC, default 0x0e */
> +#define UNKNOWN_PIPE_REG_000 0x000
> +#define UNKNOWN_SSC_000_MASK GENMASK(2, 1)
> +#define UNKNOWN_SSC_000_ENABLE (0x00 << 1)
> +
> +/* 0x83 for 24m, 0x01 for 25m, default 0x86 */
> +#define PIPE_REG_020 0x020
> +/* RX CDR multiplier high bits [7:6], as P, default 0x2, RX data rate = (2*refclk*P)/Q */
> +#define PIPE_RX_CDR_MULT_HIGH_MASK GENMASK(7, 6)
> +/* TX PLL divider bits [4:0], as N, default 0x6, TX data rate = (2*refclk*M)/N */
> +#define PIPE_TX_PLL_DIV_MASK GENMASK(4, 0)
> +
> +/* 0x71 for 24m, 0x64 for 25m, default 0x71 */
> +#define PIPE_REG_028 0x028
> +/* RX CDR multiplier low bits [7:0], as P, default 0x71, RX data rate = (2*refclk*P)/Q */
> +#define PIPE_RX_CDR_MULT_LOW_MASK GENMASK(7, 0)
> +
> +/* 0x26 for 24m?, 0x21 for 25m, default 0x26 */
> +#define PIPE_REG_030 0x030
> +/* RX CDR divider bits [4:0], as Q, default 0x6, RX data rate = (2*refclk*P)/Q */
> +#define PIPE_RX_CDR_DIV_MASK GENMASK(4, 0)
> +
> +/* 1'b1 Disable bandgap power, default 0x00 */
> +#define PIPE_REG_044 0x044
> +#define BANDGAP_POWER_DISABLE BIT(4)
> +
> +/* 0xe0 for rx tune?, default 0xe1 */
> +#define PIPE_REG_060 0x060
> +#define PIPE_TX_DETECT_BYPASS_DEBUG BIT(4) /* enable to always force detection */
> +/* RX CTLE frequency bandwidth response tuning bits [1:0], default 0x1 */
> +#define PIPE_RX_CTLE_FREQ_BW_MASK GENMASK(1, 0)
> +#define PIPE_RX_CTLE_FREQ_BW_TUNE 0x0
> +
> +/* default 0x49 */
> +#define PIPE_REG_064 0x064
> +/* RX equalizer tail current control bits [6:4], default 0x4 */
> +#define PIPE_RX_EQ_TAIL_CURR_MASK GENMASK(6, 4)
> +
> +/* 0x08 for rx tune?, default 0x07 */
> +#define PIPE_REG_068 0x068
> +/* RX equalizer low frequency gain control bits [7:4], default 0x0 */
> +#define PIPE_RX_EQ_LOW_GAIN_MASK GENMASK(7, 4)
> +#define PIPE_RX_EQ_LOW_GAIN_TUNE (0x1 << 4)
> +/* RX CTLE gain tuning bits [3:0], higher = more gain default 0x7 */
> +#define PIPE_RX_CTLE_GAIN_MASK GENMASK(3, 0)
> +#define PIPE_RX_CTLE_GAIN_TUNE 0x7 /* 0x5 lowest functional value, 0xf highest */
> +
> +/* RX ODT manual resistance config, higher = less resistance, depends on REG_1C4 BIT(5) set */
> +#define PIPE_REG_06C 0x06c
> +/* RX ODT manual resistance high bits [3:0], default 0x0 */
> +#define PIPE_RX_ODT_RES_HIGH_MASK GENMASK(3, 0)
> +#define PIPE_RX_ODT_RES_HIGH_TUNE 0xf
> +
> +#define PIPE_REG_070 0x070
> +/* RX ODT manual resistance mid bits [7:0], default 0x03 */
> +#define PIPE_RX_ODT_RES_MID_MASK GENMASK(7, 0)
> +#define PIPE_RX_ODT_RES_MID_TUNE 0xff
> +
> +#define PIPE_REG_074 0x074
> +/* RX ODT manual resistance low bits [7:0], default 0xff */
> +#define PIPE_RX_ODT_RES_LOW_MASK GENMASK(7, 0)
> +#define PIPE_RX_ODT_RES_LOW_TUNE 0xff
> +
> +/* default 0x08 */
> +#define PIPE_REG_080 0x080
> +#define PIPE_TX_COMMON_MODE_DIS BIT(2) /* 1'b1 disable TX common type */
> +
> +/* default 0x33 */
> +#define PIPE_REG_088 0x088
> +#define PIPE_TX_DRIVER_PREEMP_EN BIT(4) /* 1'b1 enable pre-emphasis */
> +
> +/* default 0x18 */
> +#define PIPE_REG_0C0 0x0c0
> +#define PIPE_RX_CM_EN BIT(3) /* 1'b1 enable RX CM */
> +#define PIPE_TX_OBS_EN BIT(4) /* 1'b1 enable TX OBS */
> +
> +/* 0x12 for rx tune?, default 0x14 */
> +#define PIPE_REG_0C8 0x0c8
> +/* RX CDR charge pump current bits [3:1], default 0x2 */
> +#define PIPE_RX_CDR_CHG_PUMP_MASK GENMASK(3, 1)
> +#define PIPE_RX_CDR_CHG_PUMP_TUNE (0x2 << 1)
> +
> +/* 0x02 for 24m, 0x06 for 25m, default 0x06 */
> +#define UNKNOWN_PIPE_REG_108 0x108
> +#define UNKNOWN_REFCLK_108_24M 0x02
> +
> +/* 0x80 for 24m, default 0x00 */
> +#define UNKNOWN_PIPE_REG_10C 0x10c
> +#define UNKNOWN_REFCLK_10C_24M BIT(7)
> +
> +/* 0x01 for 24m, 0x00 for 25m, default 0x02 */
> +#define PIPE_REG_118 0x118
> +/* TX PLL multiplier high bits [3:0], as M, default 0x2, TX data rate = (2*refclk*M)/N */
> +#define PIPE_TX_PLL_MUL_HIGH_MASK GENMASK(3, 0)
> +
> +/* 0x38 for 24m, 0x64 for 25m, default 0x71 */
> +#define PIPE_REG_11C 0x11c
> +/* TX PLL multiplier low bits [7:0], as M, default 0x71, TX data rate = (2*refclk*M)/N */
> +#define PIPE_TX_PLL_MUL_LOW_MASK GENMASK(7, 0)
> +
> +/* 0x0c for SSC, default 0x1c */
> +#define UNKNOWN_PIPE_REG_120 0x120
> +#define UNKNOWN_SSC_120_MASK BIT(4)
> +#define UNKNOWN_SSC_120_ENABLE (0x0 << 4)
> +
> +/* default 0x40 */
> +#define PIPE_REG_12C 0x12c
> +#define PIPE_TX_PLL_ALWAYS_ON BIT(0) /* disable for PLL control by pipe_pd */
> +
> +/* 0x05 for rx tune, default 0x01 */
> +#define PIPE_REG_148 0x148
> +#define PIPE_RX_CHG_PUMP_DIV_2 BIT(2) /* RX CDR charge pump div/2, default 0 */
> +
> +/* 0x70 for rx tune, default 0x72 */
> +#define PIPE_REG_150 0x150
> +#define PIPE_TX_BIAS_EN BIT(6) /* 1'b1 Enable TX Bias */
> +/* RX CDR phase tracking speed bits [3:0], default 0x2 */
> +#define PIPE_RX_CDR_SPEED_MASK GENMASK(3, 0)
> +#define PIPE_RX_CDR_SPEED_TUNE 0x00
> +
> +/* default 0xd4 */
> +#define PIPE_REG_160
> +/* RX common mode voltage strength bits [5:4], default 0x1 */
> +#define PIPE_RX_CDR_COM_VOLT_MASK GENMASK(5, 4)
> +#define PIPE_RX_CDR_COM_VOLT_TUNE (0x1 << 4)
> +
> +/* default 0x00 */
> +#define PIPE_REG_180 0x180
> +/* TX driver bias reference voltage bits [3:2], in mv */
> +#define PIPE_TX_BIAS_REF_VOLT_MASK GENMASK(3, 2)
> +#define PIPE_TX_BIAS_REF_VOLT_200 (0x0 << 2)
> +#define PIPE_TX_BIAS_REF_VOLT_175 (0x1 << 2)
> +#define PIPE_TX_BIAS_REF_VOLT_225 (0x2 << 2) /* downstream 5.10 driver setting */
> +#define PIPE_TX_BIAS_REF_VOLT_250 (0x3 << 2)
> +
> +/* default 0x01 */
> +#define PIPE_REG_1A8 0x1a8
> +#define PIPE_LDO_POWER_DIS BIT(4) /* 1'b1 Disable LDO Power */
> +
> +/* default 0x07 */
> +#define PIPE_REG_1AC 0x1ac
> +/* TX driver output common voltage bits [5:4], in mv */
> +#define PIPE_TX_COMMON_VOLT_MASK GENMASK(5, 4)
> +#define PIPE_TX_COMMON_VOLT_800 (0x0 << 4)
> +#define PIPE_TX_COMMON_VOLT_750 (0x1 << 4)
> +#define PIPE_TX_COMMON_VOLT_950 (0x2 << 4)
> +#define PIPE_TX_COMMON_VOLT_1100 (0x3 << 4)
> +
> +/* default 0xfb */
> +#define PIPE_REG_1B8 0x1b8
> +/* TX driver swing strength bits [7:4], range 0x0 to 0xf */
> +#define PIPE_TX_DRIVER_SWING_MASK GENMASK(7, 4) /* 0x2 lowest functional value */
> +/* TX driver pre-emphasis strength bits [1:0], default 0x3, enabled by REG 088 */
> +#define PIPE_TX_DRIVER_PREEMP_STR_MASK GENMASK(1, 0)
> +
> +/* set to 0xf0 for rx tune?, default 0xd0 */
> +#define PIPE_REG_1C4 0x1c4
> +#define PIPE_RX_ODT_AUTO_DIS BIT(5) /* Disable RX ODT auto compensation */
> +#define PIPE_TX_ODT_AUTO_DIS BIT(3) /* Disable TX ODT auto compensation */
> +
> +/* UTMI registers */
> +/* 0x0f for utmi tune, default 0x09*/
> +#define UTMI_REG_030 0x030
> +/* {bits[2:0]=111}: always enable pre-emphasis */
> +#define UTMI_ENABLE_PRE_EMPH_MASK GENMASK(2, 0)
> +#define UTMI_ENABLE_PRE_EMPH 0x07
> +
> +/* 0x41 for utmi tune, default 0x49 */
> +#define UTMI_REG_040 0x040
> +/* TX HS pre-emphasis strength bits [5:3], default 0x1*/
> +#define UTMI_TX_PRE_EMPH_STR_MASK GENMASK(5, 3)
> +#define UTMI_TX_PRE_EMPH_WEAKEST (0x0 << 3)
> +
> +/* set to 0xb5 for utmi tune, default 0xb5 */
> +#define UTMI_REG_11C 0x11c
> +/* {bits[4:0]=10101}: odt 45ohm tuning */
> +#define UTMI_ODT_45_OHM_MASK GENMASK(4, 0)
> +#define UTMI_ODT_45_OHM_TUNE 0x15
> +
> +enum rockchip_usb3phy_type {
> + USB3PHY_TYPE_USB2,
> + USB3PHY_TYPE_USB3,
> + USB3PHY_TYPE_MAX,
> +};
> +
> +/**
> + * struct rockchip_usb3phy_port - usb-phy port data.
> + * @phy: port usb phy struct.
> + * @regmap: port regmap.
> + * @type: port usb phy type.
> + */
> +struct rockchip_usb3phy_port {
> + struct phy *phy;
> + struct regmap *regmap;
> + enum rockchip_usb3phy_type type;
> +};
> +
> +struct rockchip_usb3phy {
> + struct device *dev;
> + struct regmap *regmap;
> + struct clk *clk_pipe;
> + struct clk *clk_otg;
> + struct clk *clk_ref;
> + struct reset_control *u3por_rst;
> + struct reset_control *u2por_rst;
> + struct reset_control *pipe_rst;
> + struct reset_control *utmi_rst;
> + struct reset_control *pipe_apb_rst;
> + struct reset_control *utmi_apb_rst;
> + struct rockchip_usb3phy_port ports[USB3PHY_TYPE_MAX];
> + int bvalid_irq;
> + int id_irq;
> + int ls_irq;
> + int rxdet_irq;
> +};
> +
> +struct usb3phy_config {
> + unsigned int reg;
> + unsigned int mask;
> + u8 def;
> +};
> +
> +static const struct usb3phy_config rk3328_rx_config[] = {
> + { PIPE_REG_150, PIPE_RX_CDR_SPEED_MASK, PIPE_RX_CDR_SPEED_TUNE },
> + { PIPE_REG_0C8, PIPE_RX_CDR_CHG_PUMP_MASK, PIPE_RX_CDR_CHG_PUMP_TUNE },
> + { PIPE_REG_148, PIPE_RX_CHG_PUMP_DIV_2, PIPE_RX_CHG_PUMP_DIV_2 },
> + { PIPE_REG_068, PIPE_RX_CTLE_GAIN_MASK, PIPE_RX_CTLE_GAIN_TUNE },
> +// { PIPE_REG_1C4, PIPE_RX_ODT_AUTO_DIS, PIPE_RX_ODT_AUTO_DIS },
> + { PIPE_REG_070, PIPE_RX_ODT_RES_MID_MASK, PIPE_RX_ODT_RES_MID_TUNE },
> + { PIPE_REG_06C, PIPE_RX_ODT_RES_HIGH_MASK, PIPE_RX_ODT_RES_HIGH_TUNE },
> + { PIPE_REG_060, PIPE_RX_CTLE_FREQ_BW_MASK, PIPE_RX_CTLE_FREQ_BW_TUNE },
> + { UNKNOWN_PIPE_REG_10C, UNKNOWN_REFCLK_10C_24M, UNKNOWN_REFCLK_10C_24M },
> + { PIPE_REG_060, PIPE_RX_CTLE_FREQ_BW_MASK, PIPE_RX_CTLE_FREQ_BW_TUNE },
> + { PIPE_REG_068, PIPE_RX_EQ_LOW_GAIN_MASK, PIPE_RX_EQ_LOW_GAIN_TUNE },
> +};
> +
> +static const struct usb3phy_config rk3328_tx_config[] = {
> + { PIPE_REG_180, PIPE_TX_BIAS_REF_VOLT_MASK, PIPE_TX_BIAS_REF_VOLT_250 },
> +};
> +
> +static const struct usb3phy_config rk3328_ssc_config[] = {
> + { UNKNOWN_PIPE_REG_000, UNKNOWN_SSC_000_MASK, UNKNOWN_SSC_000_ENABLE },
> + { UNKNOWN_PIPE_REG_120, UNKNOWN_SSC_120_MASK, UNKNOWN_SSC_120_ENABLE },
> +};
> +
> +static const struct usb3phy_config rk3328_utmi_config[] = {
> + { UTMI_REG_030, UTMI_ENABLE_PRE_EMPH_MASK, UTMI_ENABLE_PRE_EMPH },
> + { UTMI_REG_040, UTMI_TX_PRE_EMPH_STR_MASK, UTMI_TX_PRE_EMPH_WEAKEST },
> + { UTMI_REG_11C, UTMI_ODT_45_OHM_MASK, UTMI_ODT_45_OHM_TUNE },
> +};
> +
> +static const struct usb3phy_config rk3328_pipe_pwr_en_config[] = {
> + { PIPE_REG_1A8, PIPE_LDO_POWER_DIS, DISABLE_BITS },
> + { PIPE_REG_044, BANDGAP_POWER_DISABLE, DISABLE_BITS },
> + { PIPE_REG_150, PIPE_TX_BIAS_EN, PIPE_TX_BIAS_EN },
> + { PIPE_REG_080, PIPE_TX_COMMON_MODE_DIS, DISABLE_BITS },
> + { PIPE_REG_0C0, PIPE_TX_OBS_EN, PIPE_TX_OBS_EN },
> + { PIPE_REG_0C0, PIPE_RX_CM_EN, PIPE_RX_CM_EN },
> +};
> +
> +static int rockchip_usb3phy_reset(struct rockchip_usb3phy *usb3phy,
> + bool reset, enum rockchip_usb3phy_type type)
> +{
> + if (reset) {
> + if (type == USB3PHY_TYPE_USB2) {
> + clk_disable_unprepare(usb3phy->clk_otg);
> + reset_control_assert(usb3phy->utmi_rst);
> + reset_control_assert(usb3phy->u2por_rst);
> + }
> + if (type == USB3PHY_TYPE_USB3) {
> + clk_disable_unprepare(usb3phy->clk_pipe);
> + reset_control_assert(usb3phy->pipe_rst);
> + reset_control_assert(usb3phy->u3por_rst);
> + }
> + } else {
> + if (type == USB3PHY_TYPE_USB2) {
> + reset_control_deassert(usb3phy->u2por_rst);
> + fsleep(1000);
> + clk_prepare_enable(usb3phy->clk_otg);
> + fsleep(500);
> + reset_control_deassert(usb3phy->utmi_rst);
> + fsleep(100);
> + }
> + if (type == USB3PHY_TYPE_USB3) {
> + reset_control_deassert(usb3phy->u3por_rst);
> + fsleep(500);
> + clk_prepare_enable(usb3phy->clk_pipe);
> + fsleep(1000);
> + reset_control_deassert(usb3phy->pipe_rst);
> + fsleep(100);
> + }
> + }
> + return 0;
> +}
> +
> +static irqreturn_t rockchip_usb3phy_linestate_irq(int irq, void *data)
> +{
> + struct rockchip_usb3phy *usb3phy = data;
> + int tmp;
> +
> + /* check if the interrupt is enabled */
> + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
> + if (!(tmp & USB3_LINESTATE_IRQ_EN)) {
> + dev_warn(usb3phy->dev, "invalid linestate irq received\n");
> + return IRQ_NONE;
> + }
> +
> + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
> + if (tmp & USB3_LINESTATE_IRQ_EN)
> + dev_dbg_ratelimited(usb3phy->dev, "linestate irq received\n");
> +
> + /* clear the interrupt */
> + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_LINESTATE_IRQ_EN);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t rockchip_usb3phy_bvalid_irq(int irq, void *data)
> +{
> + struct rockchip_usb3phy *usb3phy = data;
> + int tmp;
> +
> + /* check if the interrupt is enabled */
> + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
> + if (!((tmp & USB3_BVALID_FALL_IRQ_EN) | (tmp & USB3_BVALID_RISE_IRQ_EN))) {
> + dev_warn_ratelimited(usb3phy->dev, "invalid bvalid irq received\n");
> + return IRQ_NONE;
> + }
> +
> + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
> + if (tmp & USB3_BVALID_FALL_IRQ_EN)
> + dev_dbg(usb3phy->dev, "bvalid falling irq received\n");
> + if (tmp & USB3_BVALID_RISE_IRQ_EN)
> + dev_dbg(usb3phy->dev, "bvalid rising irq received\n");
> +
> + /* clear the interrupt */
> + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_BVALID_CLEAR_MASK);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t rockchip_usb3phy_id_irq(int irq, void *data)
> +{
> + struct rockchip_usb3phy *usb3phy = data;
> + int tmp;
> +
> + /* check if the interrupt is enabled */
> + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
> + if (!((tmp & USB3_ID_FALL_IRQ_EN) | (tmp & USB3_ID_RISE_IRQ_EN))) {
> + dev_warn(usb3phy->dev, "invalid id irq received\n");
> + return IRQ_NONE;
> + }
> +
> + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
> + if (tmp & USB3_ID_FALL_IRQ_EN)
> + dev_dbg(usb3phy->dev, "id falling irq received\n");
> + if (tmp & USB3_ID_RISE_IRQ_EN)
> + dev_dbg(usb3phy->dev, "id rising irq received\n");
> +
> + /* clear the interrupt */
> + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_ID_CLEAR_MASK);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t rockchip_usb3phy_rxdet_irq(int irq, void *data)
> +{
> + struct rockchip_usb3phy *usb3phy = data;
> + int tmp;
> +
> + /* check if the interrupt is enabled */
> + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
> + if (!(tmp & USB3_RXDET_IRQ_EN)) {
> + dev_warn(usb3phy->dev, "invalid rxdet irq received\n");
> + return IRQ_NONE;
> + }
> +
> + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
> + if (tmp & USB3_RXDET_IRQ_EN)
> + dev_dbg_ratelimited(usb3phy->dev, "rxdet irq received\n");
> +
> + /* clear the interrupt */
> + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_RXDET_IRQ_EN);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int rockchip_usb3phy_bulk_update(struct rockchip_usb3phy *usb3phy, struct regmap *regmap,
> + const struct usb3phy_config *config, unsigned int size)
> +{
> + unsigned int i, val, tmp;
> + int ret = 0;
> +
> + for (i = 0; i < size; i++) {
> + ret = regmap_read(regmap, config[i].reg, &val);
> + if (ret < 0) {
> + dev_err(usb3phy->dev, "failed to read addr: 0x%02x\n", config[i].reg);
> + return ret;
> + }
> + tmp = val & ~config[i].mask;
> + tmp |= config[i].def;
> + dev_dbg(usb3phy->dev, "write: 0x%03x old: 0x%02x new: 0x%02x\n",
> + config[i].reg, val, tmp);
> + ret = regmap_write(regmap, config[i].reg, tmp);
> + if (ret < 0) {
> + dev_err(usb3phy->dev, "failed to write addr: 0x%02x\n", config[i].reg);
> + return ret;
> + }
> + }
> +
> + return ret;
> +}
> +
> +static int rockchip_usb3phy_calc_rate(struct rockchip_usb3phy *usb3phy, struct regmap *regmap)
> +{
> + long rate;
> + unsigned int mul, div, target = (5000000000 / 100000);
> +
> + rate = clk_get_rate(usb3phy->clk_ref) / 100000;
> + if (rate < 0) {
> + dev_err(usb3phy->dev, "failed to get refclk, %ld\n", rate);
> + return rate;
> + /* lowest possible supported clock is 4.8MHZ, highest rk3328 can do is 1.6GHZ */
> + } else if ((rate < 48) | (rate > 16000)) {
> + goto error;
> + }
> +
> + for (div = 1; div < 32; div++) {
> + for (mul = 1; mul < 1024; mul++) {
> + if (((2 * rate * mul) / div) == target)
> + goto done;
> + if (((2 * rate * mul) / div) > target)
> + break;
> + }
> + }
> +
> +error:
> + dev_err(usb3phy->dev, "invalid refclock rate, %ld\n", rate * 100000);
> + return -EINVAL;
> +
> +done:
> + dev_dbg(usb3phy->dev, "refclk rate mul: %x div: %x rate: %ld\n", mul, div, (rate * 100000));
> +
> + regmap_write(regmap, PIPE_REG_020, (mul >> 2) & PIPE_RX_CDR_MULT_HIGH_MASK);
> + regmap_write(regmap, PIPE_REG_020, div & PIPE_TX_PLL_DIV_MASK);
> + regmap_write(regmap, PIPE_REG_028, mul & PIPE_RX_CDR_MULT_LOW_MASK);
> + regmap_write(regmap, PIPE_REG_030, div & PIPE_RX_CDR_DIV_MASK);
> + regmap_write(regmap, PIPE_REG_118, (mul >> 8) & PIPE_TX_PLL_MUL_HIGH_MASK);
> + regmap_write(regmap, PIPE_REG_11C, mul & PIPE_TX_PLL_MUL_LOW_MASK);
> +
> + return 0;
> +}
> +
> +static int rockchip_usb3phy_init(struct phy *phy)
> +{
> + struct rockchip_usb3phy_port *port = phy_get_drvdata(phy);
> + struct rockchip_usb3phy *usb3phy = dev_get_drvdata(phy->dev.parent);
> + int tmp, ret;
> +
> + dev_warn(usb3phy->dev, "usb3phy_init %s\n", dev_name(&phy->dev));
> + clk_prepare_enable(usb3phy->clk_ref);
> + rockchip_usb3phy_reset(usb3phy, false, port->type);
> +
> + if (port->type == USB3PHY_TYPE_USB2) {
> + /*
> + * "For RK3328 SoC, pre-emphasis and pre-emphasis strength must be
> + * written as one fixed value. The ODT 45ohm value should be tuned
> + * for different boards to adjust HS eye height."
> + */
> + dev_dbg(usb3phy->dev, "tuning UTMI\n");
> + ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_utmi_config,
> + ARRAY_SIZE(rk3328_utmi_config));
> + }
> +
> + if (port->type == USB3PHY_TYPE_USB3) {
> + /* Enable interrupts */
> + tmp = (USB3_LINESTATE_IRQ_EN | USB3_ID_FALL_IRQ_EN | USB3_ID_RISE_IRQ_EN |
> + USB3_RXDET_IRQ_EN | USB3_BVALID_RISE_IRQ_EN | USB3_BVALID_FALL_IRQ_EN);
> + tmp |= (tmp << REG_WRITE_SHIFT);
> +
> + ret = regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, tmp);
> + if (ret < 0) {
> + /* interrupt write determines if we have write access */
> + dev_err(usb3phy->dev, "failed to write interrupts\n");
> + return ret;
> + }
> +
> + /* Configure for 24M ref clk */
> + dev_dbg(usb3phy->dev, "setting pipe for 24M refclk\n");
> + if (rockchip_usb3phy_calc_rate(usb3phy, usb3phy->regmap))
> + return -EINVAL;
> +
> + /* Enable SSC */
> + udelay(3);
> + dev_dbg(usb3phy->dev, "setting pipe for SSC\n");
> + ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_ssc_config,
> + ARRAY_SIZE(rk3328_ssc_config));
> +
> + /* "Tuning RX for compliance RJTL test" */
> + dev_dbg(usb3phy->dev, "setting pipe for RX tuning\n");
> + ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_rx_config,
> + ARRAY_SIZE(rk3328_rx_config));
> + if (ret)
> + return ret;
> +
> + /*
> + * "Tuning TX to increase the bias current used in TX driver and RX EQ,
> + * it can also increase the voltage of LFPS."
> + */
> + dev_dbg(usb3phy->dev, "setting pipe for TX tuning\n");
> + ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap,
> + rk3328_tx_config, ARRAY_SIZE(rk3328_tx_config));
> +
> + /* Power up the pipe */
> + dev_dbg(usb3phy->dev, "setting pipe power on\n");
> + ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_pipe_pwr_en_config,
> + ARRAY_SIZE(rk3328_pipe_pwr_en_config));
> + }
> +
> + return 0;
> +}
> +
> +static int rockchip_usb3phy_parse_dt(struct rockchip_usb3phy *usb3phy, struct device *dev)
> +{
> + int ret;
> +
> + usb3phy->clk_pipe = devm_clk_get(dev, "usb3phy-pipe");
> + if (IS_ERR(usb3phy->clk_pipe)) {
> + dev_err(dev, "could not get usb3phy pipe clock\n");
> + return PTR_ERR(usb3phy->clk_pipe);
> + }
> +
> + usb3phy->clk_otg = devm_clk_get(dev, "usb3phy-otg");
> + if (IS_ERR(usb3phy->clk_otg)) {
> + dev_err(dev, "could not get usb3phy otg clock\n");
> + return PTR_ERR(usb3phy->clk_otg);
> + }
> +
> + usb3phy->clk_ref = devm_clk_get(dev, "refclk-usb3otg");
> + if (IS_ERR(usb3phy->clk_ref)) {
> + dev_err(dev, "could not get usb3phy ref clock\n");
> + return PTR_ERR(usb3phy->clk_ref);
> + }
> +
> + usb3phy->u2por_rst = devm_reset_control_get(dev, "usb3phy-u2-por");
> + if (IS_ERR(usb3phy->u2por_rst)) {
> + dev_err(dev, "no usb3phy-u2-por reset control found\n");
> + return PTR_ERR(usb3phy->u2por_rst);
> + }
> +
> + usb3phy->u3por_rst = devm_reset_control_get(dev, "usb3phy-u3-por");
> + if (IS_ERR(usb3phy->u3por_rst)) {
> + dev_err(dev, "no usb3phy-u3-por reset control found\n");
> + return PTR_ERR(usb3phy->u3por_rst);
> + }
> +
> + usb3phy->pipe_rst = devm_reset_control_get(dev, "usb3phy-pipe-mac");
> + if (IS_ERR(usb3phy->pipe_rst)) {
> + dev_err(dev, "no usb3phy_pipe_mac reset control found\n");
> + return PTR_ERR(usb3phy->pipe_rst);
> + }
> +
> + usb3phy->utmi_rst = devm_reset_control_get(dev, "usb3phy-utmi-mac");
> + if (IS_ERR(usb3phy->utmi_rst)) {
> + dev_err(dev, "no usb3phy-utmi-mac reset control found\n");
> + return PTR_ERR(usb3phy->utmi_rst);
> + }
> +
> + usb3phy->pipe_apb_rst = devm_reset_control_get(dev, "usb3phy-pipe-apb");
> + if (IS_ERR(usb3phy->pipe_apb_rst)) {
> + dev_err(dev, "no usb3phy-pipe-apb reset control found\n");
> + return PTR_ERR(usb3phy->pipe_apb_rst);
> + }
> +
> + usb3phy->utmi_apb_rst = devm_reset_control_get(dev, "usb3phy-utmi-apb");
> + if (IS_ERR(usb3phy->utmi_apb_rst)) {
> + dev_err(dev, "no usb3phy-utmi-apb reset control found\n");
> + return PTR_ERR(usb3phy->utmi_apb_rst);
> + }
> +
> + usb3phy->ls_irq = of_irq_get_byname(dev->of_node, "linestate");
> + if (usb3phy->ls_irq < 0) {
> + dev_err(dev, "no linestate irq provided\n");
> + return usb3phy->ls_irq;
> + }
> +
> + ret = devm_request_threaded_irq(dev, usb3phy->ls_irq, NULL, rockchip_usb3phy_linestate_irq,
> + IRQF_ONESHOT, "rockchip_usb3phy_ls", usb3phy);
> + if (ret) {
> + dev_err(dev, "failed to request linestate irq handle\n");
> + return ret;
> + }
> +
> + usb3phy->bvalid_irq = of_irq_get_byname(dev->of_node, "bvalid");
> + if (usb3phy->bvalid_irq < 0) {
> + dev_err(dev, "no bvalid irq provided\n");
> + return usb3phy->bvalid_irq;
> + }
> +
> + ret = devm_request_threaded_irq(dev, usb3phy->bvalid_irq, NULL, rockchip_usb3phy_bvalid_irq,
> + IRQF_ONESHOT, "rockchip_usb3phy_bvalid", usb3phy);
> + if (ret) {
> + dev_err(dev, "failed to request bvalid irq handle\n");
> + return ret;
> + }
> +
> + usb3phy->id_irq = of_irq_get_byname(dev->of_node, "id");
> + if (usb3phy->id_irq < 0) {
> + dev_err(dev, "no id irq provided\n");
> + return usb3phy->id_irq;
> + }
> +
> + ret = devm_request_threaded_irq(dev, usb3phy->id_irq, NULL, rockchip_usb3phy_id_irq,
> + IRQF_ONESHOT, "rockchip_usb3phy-id", usb3phy);
> + if (ret) {
> + dev_err(dev, "failed to request id irq handle\n");
> + return ret;
> + }
> +
> + usb3phy->rxdet_irq = of_irq_get_byname(dev->of_node, "rxdet");
> + if (usb3phy->rxdet_irq < 0) {
> + dev_err(dev, "no rxdet irq provided\n");
> + return usb3phy->rxdet_irq;
> + }
> +
> + ret = devm_request_threaded_irq(dev, usb3phy->rxdet_irq, NULL, rockchip_usb3phy_rxdet_irq,
> + IRQF_ONESHOT, "rockchip_usb3phy-rxdet", usb3phy);
> + if (ret) {
> + dev_err(dev, "failed to request rxdet irq handle\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int rockchip_usb3phy_exit(struct phy *phy)
> +{
> + struct rockchip_usb3phy_port *port = phy_get_drvdata(phy);
> + struct rockchip_usb3phy *usb3phy = dev_get_drvdata(phy->dev.parent);
> +
> + dev_dbg(usb3phy->dev, "usb3phy_shutdown\n");
> + rockchip_usb3phy_reset(usb3phy, true, port->type);
> +
> + return 0;
> +}
> +
> +static const struct phy_ops rockchip_usb3phy_ops = {
> + .init = rockchip_usb3phy_init,
> + .exit = rockchip_usb3phy_exit,
> + .owner = THIS_MODULE,
> +};
> +
> +static const struct regmap_config rockchip_usb3phy_utmi_port_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = 0x400,
> + .cache_type = REGCACHE_NONE,
> + .fast_io = true,
> + .name = "utmi-port",
> +};
> +
> +static const struct regmap_config rockchip_usb3phy_pipe_port_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = 0x400,
> + .cache_type = REGCACHE_NONE,
> + .fast_io = true,
> + .name = "pipe-port",
> +};
> +
> +static const struct regmap_config rockchip_usb3phy_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = 0x400,
> + .write_flag_mask = REG_WRITE_MASK,
> + .cache_type = REGCACHE_NONE,
> + .fast_io = true,
> +};
> +
> +static int rockchip_usb3phy_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + struct device_node *child_np;
> + struct phy_provider *provider;
> + struct rockchip_usb3phy *usb3phy;
> + const struct regmap_config regmap_config = rockchip_usb3phy_regmap_config;
> + void __iomem *base;
> + int i, ret;
> +
> + dev_dbg(dev, "Probe usb3phy main block\n");
> + usb3phy = devm_kzalloc(dev, sizeof(*usb3phy), GFP_KERNEL);
> + if (!usb3phy)
> + return -ENOMEM;
> +
> + ret = rockchip_usb3phy_parse_dt(usb3phy, dev);
> + if (ret) {
> + dev_err(dev, "parse dt failed %i\n", ret);
> + return ret;
> + }
> +
> + base = devm_of_iomap(dev, np, 0, NULL);
> + if (IS_ERR(base)) {
> + dev_err(dev, "failed port ioremap\n");
> + return PTR_ERR(base);
> + }
> +
> + usb3phy->regmap = devm_regmap_init_mmio(dev, base, ®map_config);
> + if (IS_ERR(usb3phy->regmap)) {
> + dev_err(dev, "regmap init failed\n");
> + return PTR_ERR(usb3phy->regmap);
> + }
> +
> + usb3phy->dev = dev;
> + platform_set_drvdata(pdev, usb3phy);
> +
> + /* place block in reset */
> + reset_control_assert(usb3phy->pipe_rst);
> + reset_control_assert(usb3phy->utmi_rst);
> + reset_control_assert(usb3phy->u3por_rst);
> + reset_control_assert(usb3phy->u2por_rst);
> + reset_control_assert(usb3phy->pipe_apb_rst);
> + reset_control_assert(usb3phy->utmi_apb_rst);
> +
> + fsleep(20);
> +
> + /* take apb interface out of reset */
> + reset_control_deassert(usb3phy->utmi_apb_rst);
> + reset_control_deassert(usb3phy->pipe_apb_rst);
> +
> + /* enable usb3phy rx detection to fix disconnection issues */
> + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG,
> + (USB3_RXDET_EN | (USB3_RXDET_EN << REG_WRITE_SHIFT)));
> +
> + dev_dbg(dev, "Completed usb3phy core probe\n");
> +
> + /* probe the actual ports */
> + i = 0;
> + for_each_available_child_of_node(np, child_np) {
> + const struct regmap_config *regmap_port_config;
> + struct rockchip_usb3phy_port *port = &usb3phy->ports[i];
> + struct phy *phy;
> +
> + if (of_node_name_eq(child_np, "utmi-port")) {
> + port->type = USB3PHY_TYPE_USB2;
> + regmap_port_config = &rockchip_usb3phy_utmi_port_regmap_config;
> + } else if (of_node_name_eq(child_np, "pipe-port")) {
> + port->type = USB3PHY_TYPE_USB3;
> + regmap_port_config = &rockchip_usb3phy_pipe_port_regmap_config;
> + } else {
> + dev_err(dev, "unknown child node port type %s\n", child_np->name);
> + goto err_port;
> + }
> +
> + base = devm_of_iomap(dev, child_np, 0, NULL);
> + if (IS_ERR(base)) {
> + dev_err(dev, "failed port ioremap\n");
> + ret = PTR_ERR(base);
> + goto err_port;
> + }
> +
> + port->regmap = devm_regmap_init_mmio(dev, base, regmap_port_config);
> + if (IS_ERR(port->regmap)) {
> + dev_err(dev, "regmap init failed\n");
> + ret = PTR_ERR(port->regmap);
> + goto err_port;
> + }
> +
> + phy = devm_phy_create(dev, child_np, &rockchip_usb3phy_ops);
> + if (IS_ERR(phy)) {
> + dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
> + ret = PTR_ERR(phy);
> + goto err_port;
> + }
> +
> + port->phy = phy;
> + phy_set_drvdata(port->phy, port);
> +
> + /* to prevent out of boundary */
> + if (++i >= USB3PHY_TYPE_MAX) {
> + of_node_put(child_np);
> + break;
> + }
> +
> + dev_info(dev, "Completed usb3phy %s port init\n", child_np->name);
> + }
> +
> + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> + return PTR_ERR_OR_ZERO(provider);
> +
> +err_port:
> + of_node_put(child_np);
> + return ret;
> +}
> +
> +static const struct of_device_id rockchip_usb3phy_dt_ids[] = {
> + { .compatible = "rockchip,rk3328-usb3phy", },
> +};
isn’t { /* sentinel */ } missing here?
> +
> +MODULE_DEVICE_TABLE(of, rockchip_usb3phy_dt_ids);
> +
> +static struct platform_driver rockchip_usb3phy_driver = {
> + .probe = rockchip_usb3phy_probe,
> + .driver = {
> + .name = "rockchip-usb3-phy",
> + .of_match_table = rockchip_usb3phy_dt_ids,
> + },
> +};
> +
> +module_platform_driver(rockchip_usb3phy_driver);
> +
> +MODULE_AUTHOR("Peter Geis <pgwipeout@gmail.com>");
> +MODULE_DESCRIPTION("Rockchip Innosilicon USB3PHY driver");
> +MODULE_LICENSE("GPL");
> --
> 2.39.5
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-15 11:22 ` [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Piotr Oniszczuk
@ 2025-01-15 12:25 ` Peter Geis
2025-01-15 12:35 ` Piotr Oniszczuk
0 siblings, 1 reply; 44+ messages in thread
From: Peter Geis @ 2025-01-15 12:25 UTC (permalink / raw)
To: Piotr Oniszczuk
Cc: Heiko Stuebner, Algea Cao, Michael Turquette, kever.yang,
linux-phy, wulf, zyw, Dragan Simic, Kishon Vijay Abraham I,
Rob Herring, Sebastian Reichel, linux-clk, linux-rockchip,
devicetree, Conor Dooley, Philipp Zabel, Arnd Bergmann,
Jonas Karlman, frank.wang, Elaine Zhang, Alex Bee, william.wu,
Zhang Yubing, Johan Jonker, linux-arm-kernel, Trevor Woerner,
Stephen Boyd, linux-kernel, Vinod Koul, FUKAUMI Naoki,
Diederik de Haas, Krzysztof Kozlowski
On Wed, Jan 15, 2025 at 6:22 AM Piotr Oniszczuk
<piotr.oniszczuk@gmail.com> wrote:
>
>
>
> > Wiadomość napisana przez Peter Geis <pgwipeout@gmail.com> w dniu 15 sty 2025, o godz. 02:26:
> >
> >
> > This is my newly reworked phy driver for the rk3328 usb3 phy. It is
> > based loosely on my original version, but as of now almost nothing of
> > the original driver remains. The main fix here is the discovery of
> > BIT(6) in the interrupt enable grf register fixes the usb3 disconnection
> > detection (mostly). On occasion an unpopulated usb3 hub will take
> > several seconds to disconnect. However this means all of the hack around
> > work to reset the usb core manually is no longer required.
> >
> > I did my best to document all registers I could find. A lot was taken
> > from emails between myself and Rockchip's engineers, much thanks to
> > William Wu <wulf@rock-chips.com> for their assistance here. The rest of
> > the config bits were taken from the rk3328 and rk3228h TRMs and the
> > downstream driver. Everything that I couldn't find a definition for is
> > prefixed UNK_ or UNKNOWN_. There's a lot of obviously used configuration
> > registers with the pipe interface that are also undocumented.
> >
> > The only major bug I have so far is my AX88179 usb3 gigabit ethernet
> > adapter (Pluggable brand) crashes out when large amounts of data are
> > transmitted. I suspect this is related to the RX and TX tuning, as
> > leaving it at defaults makes things worse. As I am not a USB3 engineer
> > and I do not have the specialized knowledge and hardware to determine
> > what is going wrong, I am hoping the mailing list will have an answer
> > here.
> >
> > Please test and review.
> >
> > Very Respectfully,
> > Peter Geis
> >
> >
> >
> > Peter Geis (6):
> > clk: rockchip: fix wrong clk_ref_usb3otg parent for rk3328
> > dt-bindings: phy: rockchip: add rk3328 usb3 phy
> > phy: rockchip: add driver for rk3328 usb3 phy
> > arm64: dts: rockchip: add rk3328 usb3 phy node
> > arm64: dts: rockchip: enable the usb3 phy on rk3328-roc boards
> > arm64: dts: rockchip: enable the usb3 phy on remaining rk3328 boards
> >
> > .../bindings/phy/rockchip,inno-usb3phy.yaml | 166 ++++
> > .../boot/dts/rockchip/rk3328-nanopi-r2.dtsi | 12 +
> > .../dts/rockchip/rk3328-orangepi-r1-plus.dtsi | 12 +
> > arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 12 +
> > .../boot/dts/rockchip/rk3328-rock-pi-e.dts | 12 +
> > .../arm64/boot/dts/rockchip/rk3328-rock64.dts | 12 +
> > arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 +
> > drivers/clk/rockchip/clk-rk3328.c | 2 +-
> > drivers/phy/rockchip/Kconfig | 10 +
> > drivers/phy/rockchip/Makefile | 1 +
> > drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 869 ++++++++++++++++++
> > 11 files changed, 1146 insertions(+), 1 deletion(-)
> > create mode 100644 Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> > create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> >
> > --
> > 2.39.5
> >
> >
>
> Peter,
> I applied this as test run on 6.12.9 and dmesg says:
>
> [ 16.368514] rockchip-usb3-phy ff460000.usb3-phy: could not get usb3phy ref clock
> [ 16.368534] rockchip-usb3-phy ff460000.usb3-phy: parse dt failed -2
> [ 16.368543] rockchip-usb3-phy ff460000.usb3-phy: probe with driver rockchip-usb3-phy failed with error -2
>
> This is on beelink a1 tvbox.
>
> Do I miss something?
>
Good Morning,
That is an interesting failure. The simplest answer is the
`clock-names = "refclk-usb3otg", "usb3phy-otg", "usb3phy-pipe";` line
was corrupted. Please check that when applied it matches the patch
exactly. If you are still having problems, you can send me the
compiled DTB and I'll take a look.
Very Respectfully,
Peter Geis
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-15 12:25 ` Peter Geis
@ 2025-01-15 12:35 ` Piotr Oniszczuk
2025-01-15 13:15 ` Peter Geis
0 siblings, 1 reply; 44+ messages in thread
From: Piotr Oniszczuk @ 2025-01-15 12:35 UTC (permalink / raw)
To: Peter Geis
Cc: Heiko Stuebner, Algea Cao, Michael Turquette, kever.yang,
linux-phy, wulf, zyw, Dragan Simic, Kishon Vijay Abraham I,
Rob Herring, Sebastian Reichel, linux-clk, linux-rockchip,
devicetree, Conor Dooley, Philipp Zabel, Arnd Bergmann,
Jonas Karlman, frank.wang, Elaine Zhang, Alex Bee, william.wu,
Zhang Yubing, Johan Jonker, linux-arm-kernel, Trevor Woerner,
Stephen Boyd, linux-kernel, Vinod Koul, FUKAUMI Naoki,
Diederik de Haas, Krzysztof Kozlowski
[-- Attachment #1: Type: text/plain, Size: 724 bytes --]
> Wiadomość napisana przez Peter Geis <pgwipeout@gmail.com> w dniu 15 sty 2025, o godz. 13:25:
>
>>
>>
>> Do I miss something?
>>
>
> Good Morning,
>
> That is an interesting failure. The simplest answer is the
> `clock-names = "refclk-usb3otg", "usb3phy-otg", "usb3phy-pipe";` line
> was corrupted. Please check that when applied it matches the patch
> exactly. If you are still having problems, you can send me the
> compiled DTB and I'll take a look.
>
oh - this check i done as first thing to look on :-)
pls find:
dtsi: https://gist.github.com/warpme/6af9e2778fb06bfb47b64f98fe79d678
and dt: https://gist.github.com/warpme/79340c54c87b2b1e52f2a146461d8c9f
and compiled .dtb
[-- Attachment #2: rk3328-a1.dtb --]
[-- Type: application/octet-stream, Size: 40319 bytes --]
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-15 12:35 ` Piotr Oniszczuk
@ 2025-01-15 13:15 ` Peter Geis
2025-01-15 13:25 ` Piotr Oniszczuk
0 siblings, 1 reply; 44+ messages in thread
From: Peter Geis @ 2025-01-15 13:15 UTC (permalink / raw)
To: Piotr Oniszczuk
Cc: Heiko Stuebner, Algea Cao, Michael Turquette, kever.yang,
linux-phy, wulf, zyw, Dragan Simic, Kishon Vijay Abraham I,
Rob Herring, Sebastian Reichel, linux-clk, linux-rockchip,
devicetree, Conor Dooley, Philipp Zabel, Arnd Bergmann,
Jonas Karlman, frank.wang, Elaine Zhang, Alex Bee, william.wu,
Zhang Yubing, Johan Jonker, linux-arm-kernel, Trevor Woerner,
Stephen Boyd, linux-kernel, Vinod Koul, FUKAUMI Naoki,
Diederik de Haas, Krzysztof Kozlowski
On Wed, Jan 15, 2025 at 7:35 AM Piotr Oniszczuk
<piotr.oniszczuk@gmail.com> wrote:
>
>
>
> > Wiadomość napisana przez Peter Geis <pgwipeout@gmail.com> w dniu 15 sty 2025, o godz. 13:25:
> >
> >>
> >>
> >> Do I miss something?
> >>
> >
> > Good Morning,
> >
> > That is an interesting failure. The simplest answer is the
> > `clock-names = "refclk-usb3otg", "usb3phy-otg", "usb3phy-pipe";` line
> > was corrupted. Please check that when applied it matches the patch
> > exactly. If you are still having problems, you can send me the
> > compiled DTB and I'll take a look.
> >
>
> oh - this check i done as first thing to look on :-)
>
> pls find:
>
> dtsi: https://gist.github.com/warpme/6af9e2778fb06bfb47b64f98fe79d678
> and dt: https://gist.github.com/warpme/79340c54c87b2b1e52f2a146461d8c9f
>
>
> and compiled .dtb
It all looks good.
Do you have any CRU errors in the boot log?
Can you check for the presence of clk_ref_usb3otg in
/sys/kernel/debug/clk/clk_summary?
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-15 13:15 ` Peter Geis
@ 2025-01-15 13:25 ` Piotr Oniszczuk
2025-01-16 14:02 ` Peter Geis
0 siblings, 1 reply; 44+ messages in thread
From: Piotr Oniszczuk @ 2025-01-15 13:25 UTC (permalink / raw)
To: Peter Geis
Cc: Heiko Stuebner, Algea Cao, Michael Turquette, kever.yang,
linux-phy, wulf, zyw, Dragan Simic, Kishon Vijay Abraham I,
Rob Herring, Sebastian Reichel, linux-clk, linux-rockchip,
devicetree, Conor Dooley, Philipp Zabel, Arnd Bergmann,
Jonas Karlman, frank.wang, Elaine Zhang, Alex Bee, william.wu,
Zhang Yubing, Johan Jonker, linux-arm-kernel, Trevor Woerner,
Stephen Boyd, linux-kernel, Vinod Koul, FUKAUMI Naoki,
Diederik de Haas, Krzysztof Kozlowski
> Wiadomość napisana przez Peter Geis <pgwipeout@gmail.com> w dniu 15 sty 2025, o godz. 14:15:
>
>>
>>
>> pls find:
>>
>> dtsi: https://gist.github.com/warpme/6af9e2778fb06bfb47b64f98fe79d678
>> and dt: https://gist.github.com/warpme/79340c54c87b2b1e52f2a146461d8c9f
>>
>>
>> and compiled .dtb
>
> It all looks good.
> Do you have any CRU errors in the boot log?
> Can you check for the presence of clk_ref_usb3otg in
> /sys/kernel/debug/clk/clk_summary?
>
>>
cru errors in dmesg - seems no any.
here is my dmesg: https://gist.github.com/warpme/ecf38482cc88fb68471355d011ecf974
For clk_ref_usb3otg i’m getting following:
root@myth-frontend-e67a8de4c815:~ # cat /sys/kernel/debug/clk/clk_summary | grep usb3
clk_usb3otg_suspend 0 0 0 30770 0 0 50000 N deviceless no_connection_id
clk_usb3otg_ref 0 0 0 24000000 0 0 50000 N deviceless no_connection_id
clk_ref_usb3otg 0 0 0 24000000 0 0 50000 Y deviceless no_connection_id
pclk_usb3_grf 0 0 0 75000000 0 0 50000 Y deviceless no_connection_id
pclk_usb3phy_pipe 0 0 0 75000000 0 0 50000 N deviceless no_connection_id
pclk_usb3phy_otg 0 0 0 75000000 0 0 50000 N deviceless no_connection_id
clk_ref_usb3otg_src 0 0 0 37500000 0 0 50000 N deviceless no_connection_id
aclk_usb3otg 0 0 0 150000000 0 0 50000 N deviceless no_connection_id
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 3/6] phy: rockchip: add driver for rk3328 usb3 phy
2025-01-15 1:26 ` [RFC PATCH v1 3/6] phy: rockchip: add driver for " Peter Geis
2025-01-15 11:24 ` Piotr Oniszczuk
@ 2025-01-16 12:59 ` Krzysztof Kozlowski
2025-01-16 13:14 ` Peter Geis
2025-01-16 15:26 ` Diederik de Haas
2 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-16 12:59 UTC (permalink / raw)
To: Peter Geis, Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Algea Cao, Arnd Bergmann, Cristian Ciocaltea,
Kishon Vijay Abraham I, Philipp Zabel, Sebastian Reichel,
Vinod Koul, Zhang Yubing, linux-arm-kernel, linux-kernel,
linux-phy
On 15/01/2025 02:26, Peter Geis wrote:
> The rk3328 has a combined usb2 and usb3 phy block for the usb3 dwc
> interface. The implementation up until now has been bugged, with
> multiple issues ranging from disconnect detection failures to low
> performance. This driver fixes the majority of the original issues and
> allows better performance for the rk3328 usb3 port.
>
> This driver sources data from multiple sources, including the rk3328
> trm, the rk3228h trm, emails from Rockchip, and both the 4.4 and 5.10
> downstream drivers. The current implementation allows for basic bring up
> of the phy block and fixes the detection issues. Interrupts are enabled,
> but currently only used for debugging. Features missing currently are
> power management, OTG handling, board specific tuning, regulator control,
>
> Currently the only known bugs are a AX88179 usb3 gigabit adapter crashes
> when operating at usb3 speeds and transmitting large amounts of data and
> full disconnection detections may be slower than expected (~5-10 seconds).
>
> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> ---
...
> +}
> +
> +static int rockchip_usb3phy_parse_dt(struct rockchip_usb3phy *usb3phy, struct device *dev)
> +{
> + int ret;
> +
> + usb3phy->clk_pipe = devm_clk_get(dev, "usb3phy-pipe");
> + if (IS_ERR(usb3phy->clk_pipe)) {
> + dev_err(dev, "could not get usb3phy pipe clock\n");
Syntax is always:
return dev_err_probe
> + return PTR_ERR(usb3phy->clk_pipe);
> + }
> +
> + usb3phy->clk_otg = devm_clk_get(dev, "usb3phy-otg");
> + if (IS_ERR(usb3phy->clk_otg)) {
> + dev_err(dev, "could not get usb3phy otg clock\n");
> + return PTR_ERR(usb3phy->clk_otg);
> + }
> +
> + usb3phy->clk_ref = devm_clk_get(dev, "refclk-usb3otg");
> + if (IS_ERR(usb3phy->clk_ref)) {
> + dev_err(dev, "could not get usb3phy ref clock\n");
> + return PTR_ERR(usb3phy->clk_ref);
> + }
> +
> + usb3phy->u2por_rst = devm_reset_control_get(dev, "usb3phy-u2-por");
> + if (IS_ERR(usb3phy->u2por_rst)) {
> + dev_err(dev, "no usb3phy-u2-por reset control found\n");
> + return PTR_ERR(usb3phy->u2por_rst);
> + }
> +
> + usb3phy->u3por_rst = devm_reset_control_get(dev, "usb3phy-u3-por");
> + if (IS_ERR(usb3phy->u3por_rst)) {
> + dev_err(dev, "no usb3phy-u3-por reset control found\n");
> + return PTR_ERR(usb3phy->u3por_rst);
> + }
> +
> + usb3phy->pipe_rst = devm_reset_control_get(dev, "usb3phy-pipe-mac");
> + if (IS_ERR(usb3phy->pipe_rst)) {
> + dev_err(dev, "no usb3phy_pipe_mac reset control found\n");
> + return PTR_ERR(usb3phy->pipe_rst);
> + }
> +
> + usb3phy->utmi_rst = devm_reset_control_get(dev, "usb3phy-utmi-mac");
> + if (IS_ERR(usb3phy->utmi_rst)) {
> + dev_err(dev, "no usb3phy-utmi-mac reset control found\n");
> + return PTR_ERR(usb3phy->utmi_rst);
> + }
> +
> + usb3phy->pipe_apb_rst = devm_reset_control_get(dev, "usb3phy-pipe-apb");
> + if (IS_ERR(usb3phy->pipe_apb_rst)) {
> + dev_err(dev, "no usb3phy-pipe-apb reset control found\n");
> + return PTR_ERR(usb3phy->pipe_apb_rst);
> + }
> +
> + usb3phy->utmi_apb_rst = devm_reset_control_get(dev, "usb3phy-utmi-apb");
> + if (IS_ERR(usb3phy->utmi_apb_rst)) {
> + dev_err(dev, "no usb3phy-utmi-apb reset control found\n");
> + return PTR_ERR(usb3phy->utmi_apb_rst);
> + }
> +
> + usb3phy->ls_irq = of_irq_get_byname(dev->of_node, "linestate");
> + if (usb3phy->ls_irq < 0) {
> + dev_err(dev, "no linestate irq provided\n");
> + return usb3phy->ls_irq;
> + }
> +
> + ret = devm_request_threaded_irq(dev, usb3phy->ls_irq, NULL, rockchip_usb3phy_linestate_irq,
> + IRQF_ONESHOT, "rockchip_usb3phy_ls", usb3phy);
> + if (ret) {
> + dev_err(dev, "failed to request linestate irq handle\n");
> + return ret;
> + }
> +
> + usb3phy->bvalid_irq = of_irq_get_byname(dev->of_node, "bvalid");
> + if (usb3phy->bvalid_irq < 0) {
> + dev_err(dev, "no bvalid irq provided\n");
> + return usb3phy->bvalid_irq;
> + }
> +
> + ret = devm_request_threaded_irq(dev, usb3phy->bvalid_irq, NULL, rockchip_usb3phy_bvalid_irq,
> + IRQF_ONESHOT, "rockchip_usb3phy_bvalid", usb3phy);
> + if (ret) {
> + dev_err(dev, "failed to request bvalid irq handle\n");
> + return ret;
> + }
> +
> + usb3phy->id_irq = of_irq_get_byname(dev->of_node, "id");
> + if (usb3phy->id_irq < 0) {
> + dev_err(dev, "no id irq provided\n");
> + return usb3phy->id_irq;
> + }
> +
> + ret = devm_request_threaded_irq(dev, usb3phy->id_irq, NULL, rockchip_usb3phy_id_irq,
> + IRQF_ONESHOT, "rockchip_usb3phy-id", usb3phy);
> + if (ret) {
> + dev_err(dev, "failed to request id irq handle\n");
> + return ret;
> + }
> +
> + usb3phy->rxdet_irq = of_irq_get_byname(dev->of_node, "rxdet");
> + if (usb3phy->rxdet_irq < 0) {
> + dev_err(dev, "no rxdet irq provided\n");
> + return usb3phy->rxdet_irq;
> + }
> +
> + ret = devm_request_threaded_irq(dev, usb3phy->rxdet_irq, NULL, rockchip_usb3phy_rxdet_irq,
> + IRQF_ONESHOT, "rockchip_usb3phy-rxdet", usb3phy);
> + if (ret) {
> + dev_err(dev, "failed to request rxdet irq handle\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int rockchip_usb3phy_exit(struct phy *phy)
> +{
> + struct rockchip_usb3phy_port *port = phy_get_drvdata(phy);
> + struct rockchip_usb3phy *usb3phy = dev_get_drvdata(phy->dev.parent);
> +
> + dev_dbg(usb3phy->dev, "usb3phy_shutdown\n");
> + rockchip_usb3phy_reset(usb3phy, true, port->type);
> +
> + return 0;
> +}
> +
> +static const struct phy_ops rockchip_usb3phy_ops = {
> + .init = rockchip_usb3phy_init,
> + .exit = rockchip_usb3phy_exit,
> + .owner = THIS_MODULE,
> +};
> +
> +static const struct regmap_config rockchip_usb3phy_utmi_port_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = 0x400,
> + .cache_type = REGCACHE_NONE,
> + .fast_io = true,
> + .name = "utmi-port",
> +};
> +
> +static const struct regmap_config rockchip_usb3phy_pipe_port_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = 0x400,
> + .cache_type = REGCACHE_NONE,
> + .fast_io = true,
> + .name = "pipe-port",
> +};
> +
> +static const struct regmap_config rockchip_usb3phy_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = 0x400,
> + .write_flag_mask = REG_WRITE_MASK,
> + .cache_type = REGCACHE_NONE,
> + .fast_io = true,
> +};
> +
> +static int rockchip_usb3phy_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + struct device_node *child_np;
> + struct phy_provider *provider;
> + struct rockchip_usb3phy *usb3phy;
> + const struct regmap_config regmap_config = rockchip_usb3phy_regmap_config;
> + void __iomem *base;
> + int i, ret;
> +
> + dev_dbg(dev, "Probe usb3phy main block\n");
> + usb3phy = devm_kzalloc(dev, sizeof(*usb3phy), GFP_KERNEL);
> + if (!usb3phy)
> + return -ENOMEM;
> +
> + ret = rockchip_usb3phy_parse_dt(usb3phy, dev);
> + if (ret) {
> + dev_err(dev, "parse dt failed %i\n", ret);
return dev_err_probe()
And do not print errors twice.
> + return ret;
> +
> + /* take apb interface out of reset */
> + reset_control_deassert(usb3phy->utmi_apb_rst);
> + reset_control_deassert(usb3phy->pipe_apb_rst);
> +
> + /* enable usb3phy rx detection to fix disconnection issues */
> + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG,
> + (USB3_RXDET_EN | (USB3_RXDET_EN << REG_WRITE_SHIFT)));
> +
> + dev_dbg(dev, "Completed usb3phy core probe\n");
Drop.
> +
> + /* probe the actual ports */
> + i = 0;
> + for_each_available_child_of_node(np, child_np) {
> + const struct regmap_config *regmap_port_config;
> + struct rockchip_usb3phy_port *port = &usb3phy->ports[i];
> + struct phy *phy;
> +
> + if (of_node_name_eq(child_np, "utmi-port")) {
Why are you comparing node names, if you decided to put there compatibles?
Decide on one method, but wait for full DT review.
> + port->type = USB3PHY_TYPE_USB2;
> + regmap_port_config = &rockchip_usb3phy_utmi_port_regmap_config;
> + } else if (of_node_name_eq(child_np, "pipe-port")) {
> + port->type = USB3PHY_TYPE_USB3;
> + regmap_port_config = &rockchip_usb3phy_pipe_port_regmap_config;
> + } else {
> + dev_err(dev, "unknown child node port type %s\n", child_np->name);
> + goto err_port;
> + }
> +
> + base = devm_of_iomap(dev, child_np, 0, NULL);
> + if (IS_ERR(base)) {
> + dev_err(dev, "failed port ioremap\n");
> + ret = PTR_ERR(base);
> + goto err_port;
> + }
> +
> + port->regmap = devm_regmap_init_mmio(dev, base, regmap_port_config);
> + if (IS_ERR(port->regmap)) {
> + dev_err(dev, "regmap init failed\n");
> + ret = PTR_ERR(port->regmap);
> + goto err_port;
> + }
> +
> + phy = devm_phy_create(dev, child_np, &rockchip_usb3phy_ops);
> + if (IS_ERR(phy)) {
> + dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
> + ret = PTR_ERR(phy);
Just read how dev_err_probe() works. The syntax is:
ret = dev_err_probe.
> + goto err_port;
> + }
> +
> + port->phy = phy;
> + phy_set_drvdata(port->phy, port);
> +
> + /* to prevent out of boundary */
> + if (++i >= USB3PHY_TYPE_MAX) {
> + of_node_put(child_np);
> + break;
> + }
> +
> + dev_info(dev, "Completed usb3phy %s port init\n", child_np->name);
Drop, not really helping.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-15 1:26 ` [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node Peter Geis
@ 2025-01-16 13:01 ` Krzysztof Kozlowski
2025-01-16 16:53 ` Diederik de Haas
0 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-16 13:01 UTC (permalink / raw)
To: Peter Geis, Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Alex Bee, Conor Dooley, Diederik de Haas, Dragan Simic,
Johan Jonker, Jonas Karlman, Krzysztof Kozlowski, Rob Herring,
devicetree, linux-arm-kernel, linux-kernel
On 15/01/2025 02:26, Peter Geis wrote:
> Add the node for the rk3328 usb3 phy. This node provides a combined usb2
> and usb3 phy which are permenantly tied to the dwc3 usb3 controller.
>
> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> ---
>
> arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 ++++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> index 7d992c3c01ce..181a900d41f9 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> @@ -903,6 +903,43 @@ u2phy_host: host-port {
> };
> };
>
> + usb3phy: usb3-phy@ff460000 {
> + compatible = "rockchip,rk3328-usb3phy";
> + reg = <0x0 0xff460000 0x0 0x10000>;
> + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
Please wrap code according to coding style (checkpatch is not a coding
style description, but only a tool), so at 80.
> + clock-names = "refclk-usb3otg", "usb3phy-otg", "usb3phy-pipe";
> + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-names = "bvalid", "id", "linestate", "rxdet";
> + resets = <&cru SRST_USB3PHY_U2>,
> + <&cru SRST_USB3PHY_U3>,
> + <&cru SRST_USB3PHY_PIPE>,
> + <&cru SRST_USB3OTG_UTMI>,
> + <&cru SRST_USB3PHY_OTG_P>,
> + <&cru SRST_USB3PHY_PIPE_P>;
> + reset-names = "usb3phy-u2-por", "usb3phy-u3-por",
> + "usb3phy-pipe-mac", "usb3phy-utmi-mac",
> + "usb3phy-utmi-apb", "usb3phy-pipe-apb";
> + #address-cells = <2>;
> + #size-cells = <2>;
> + ranges;
> + status = "disabled";
> +
> + usb3phy_utmi: utmi-port@ff470000 {
> + compatible = "rockchip,rk3328-usb3phy-utmi";
> + reg = <0x0 0xff470000 0x0 0x8000>;
> + #phy-cells = <0>;
Parent device is the phy provider, not child. This is odd...
> + status = "disabled";
> + };
> +
> + usb3phy_pipe: pipe-port@ff478000 {
> + compatible = "rockchip,rk3328-usb3phy-pipe";
> + reg = <0x0 0xff478000 0x0 0x8000>;
> + #phy-cells = <0>;
> + status = "disabled";
> + };
> + };
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 2/6] dt-bindings: phy: rockchip: add rk3328 usb3 phy
2025-01-15 1:26 ` [RFC PATCH v1 2/6] dt-bindings: phy: rockchip: add rk3328 usb3 phy Peter Geis
@ 2025-01-16 13:08 ` Krzysztof Kozlowski
2025-01-16 13:32 ` Peter Geis
0 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-16 13:08 UTC (permalink / raw)
To: Peter Geis, Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Conor Dooley, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-arm-kernel,
linux-kernel, linux-phy
On 15/01/2025 02:26, Peter Geis wrote:
> Add documentation for the usb3 phy as implemented on the rk3328 SoC.
>
> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> ---
>
> .../bindings/phy/rockchip,inno-usb3phy.yaml | 166 ++++++++++++++++++
> 1 file changed, 166 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
>
> diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> new file mode 100644
> index 000000000000..cde489ca87ab
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> @@ -0,0 +1,166 @@
> +# SPDX-License-Identifier: GPL-2.0-only
Wrong license.
Please run scripts/checkpatch.pl and fix reported warnings. After that,
run also `scripts/checkpatch.pl --strict` and (probably) fix more
warnings. Some warnings can be ignored, especially from --strict run,
but the code here looks like it needs a fix. Feel free to get in touch
if the warning is not clear.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/rockchip,inno-usb3phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip USB 3.0 phy with Innosilicon IP block
> +
> +maintainers:
> + - Heiko Stuebner <heiko@sntech.de>
> +
> +properties:
> + compatible:
> + enum:
> + - rockchip,rk3328-usb3phy
Why is this binding entirely different than existing usb2 phy? Nothing
in common? This looks like made for driver and both - driver and binding
- duplicating a lot.
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + minItems: 3
Drop
> + maxItems: 3
> +
> + clock-names:
> + items:
> + - const: refclk-usb3otg
ref
> + - const: usb3phy-otg
otg
> + - const: usb3phy-pipe
pipe
> +
> + interrupts:
> + minItems: 4
You code here randomly. reg has only maxItems, clocks have both and this
have only minItems. Does not make sense. If you get it wrong, I would
assume you repeat the same mistake but here it is like randomly chosen
pieces. And this is making me wonder whether this was not sent too fast.
Anyway: only maxItems.
> +
> + interrupt-names:
> + items:
> + - const: bvalid
> + - const: id
> + - const: linestate
> + - const: rxdet
> +
> + resets:
> + minItems: 6
maxItems instead
> +
> + reset-names:
> + items:
> + - const: usb3phy-u2-por
> + - const: usb3phy-u3-por
> + - const: usb3phy-pipe-mac
> + - const: usb3phy-utmi-mac
> + - const: usb3phy-utmi-apb
> + - const: usb3phy-pipe-apb
> +
> + "#address-cells":
> + const: 2
> +
> + "#size-cells":
> + const: 2
> +
> + ranges: true
> +
> +patternProperties:
> +
Drop blank line
> + utmi-port@[0-9a-f]+$:
This wasn't tested. Missing quotes, missing starting anchor.
> + type: object
Explain what are the children here - description.
> + additionalProperties: false
> +
> + properties:
> + compatible:
> + enum:
> + - rockchip,rk3328-usb3phy-utmi
> +
> + reg:
> + maxItems: 1
> +
> + "#phy-cells":
> + const: 0
Does not look correct. Your parent device is the phy, not child. Why do
you create children per each type of phy?
> +
> + phy-supply:
> + description:
> + Phandle to a regulator that provides power to VBUS.
> + See ./phy-bindings.txt for details.
> +
> + required:
> + - compatible
> + - reg
> + - "#phy-cells"
> +
> + pipe-port@[0-9a-f]+$:
> + type: object
> + additionalProperties: false
> +
> + properties:
> + compatible:
> + enum:
> + - rockchip,rk3328-usb3phy-pipe
> +
> + reg:
> + maxItems: 1
> +
> + "#phy-cells":
> + const: 0
> +
> + phy-supply:
> + description:
> + Phandle to a regulator that provides power to VBUS.
> + See ./phy-bindings.txt for details.
Drop "see ....".
> +
> + required:
> + - compatible
> + - reg
> + - "#phy-cells"
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - clock-names
> + - interrupts
> + - interrupt-names
> + - resets
> + - reset-names
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/rk3328-cru.h>
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> + #include <dt-bindings/interrupt-controller/irq.h>
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + usb3phy: usb3-phy@ff460000 {
> + compatible = "rockchip,rk3328-usb3phy";
> + reg = <0x0 0xff460000 0x0 0x10000>;
> + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
That's way over the limit. Wrapping is at 80.
> + clock-names = "refclk-usb3otg", "usb3phy-otg", "usb3phy-pipe";
> + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-names = "bvalid", "id", "linestate", "rxdet";
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 3/6] phy: rockchip: add driver for rk3328 usb3 phy
2025-01-16 12:59 ` Krzysztof Kozlowski
@ 2025-01-16 13:14 ` Peter Geis
0 siblings, 0 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-16 13:14 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Heiko Stuebner, zyw, kever.yang, frank.wang, william.wu, wulf,
linux-rockchip, Algea Cao, Arnd Bergmann, Cristian Ciocaltea,
Kishon Vijay Abraham I, Philipp Zabel, Sebastian Reichel,
Vinod Koul, Zhang Yubing, linux-arm-kernel, linux-kernel,
linux-phy
On Thu, Jan 16, 2025 at 7:59 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On 15/01/2025 02:26, Peter Geis wrote:
> > The rk3328 has a combined usb2 and usb3 phy block for the usb3 dwc
> > interface. The implementation up until now has been bugged, with
> > multiple issues ranging from disconnect detection failures to low
> > performance. This driver fixes the majority of the original issues and
> > allows better performance for the rk3328 usb3 port.
> >
> > This driver sources data from multiple sources, including the rk3328
> > trm, the rk3228h trm, emails from Rockchip, and both the 4.4 and 5.10
> > downstream drivers. The current implementation allows for basic bring up
> > of the phy block and fixes the detection issues. Interrupts are enabled,
> > but currently only used for debugging. Features missing currently are
> > power management, OTG handling, board specific tuning, regulator control,
> >
> > Currently the only known bugs are a AX88179 usb3 gigabit adapter crashes
> > when operating at usb3 speeds and transmitting large amounts of data and
> > full disconnection detections may be slower than expected (~5-10 seconds).
> >
> > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> > ---
>
>
> ...
>
> > +}
> > +
> > +static int rockchip_usb3phy_parse_dt(struct rockchip_usb3phy *usb3phy, struct device *dev)
> > +{
> > + int ret;
> > +
> > + usb3phy->clk_pipe = devm_clk_get(dev, "usb3phy-pipe");
> > + if (IS_ERR(usb3phy->clk_pipe)) {
> > + dev_err(dev, "could not get usb3phy pipe clock\n");
>
> Syntax is always:
> return dev_err_probe
>
> > + return PTR_ERR(usb3phy->clk_pipe);
> > + }
> > +
> > + usb3phy->clk_otg = devm_clk_get(dev, "usb3phy-otg");
> > + if (IS_ERR(usb3phy->clk_otg)) {
> > + dev_err(dev, "could not get usb3phy otg clock\n");
> > + return PTR_ERR(usb3phy->clk_otg);
> > + }
> > +
> > + usb3phy->clk_ref = devm_clk_get(dev, "refclk-usb3otg");
> > + if (IS_ERR(usb3phy->clk_ref)) {
> > + dev_err(dev, "could not get usb3phy ref clock\n");
> > + return PTR_ERR(usb3phy->clk_ref);
> > + }
> > +
> > + usb3phy->u2por_rst = devm_reset_control_get(dev, "usb3phy-u2-por");
> > + if (IS_ERR(usb3phy->u2por_rst)) {
> > + dev_err(dev, "no usb3phy-u2-por reset control found\n");
> > + return PTR_ERR(usb3phy->u2por_rst);
> > + }
> > +
> > + usb3phy->u3por_rst = devm_reset_control_get(dev, "usb3phy-u3-por");
> > + if (IS_ERR(usb3phy->u3por_rst)) {
> > + dev_err(dev, "no usb3phy-u3-por reset control found\n");
> > + return PTR_ERR(usb3phy->u3por_rst);
> > + }
> > +
> > + usb3phy->pipe_rst = devm_reset_control_get(dev, "usb3phy-pipe-mac");
> > + if (IS_ERR(usb3phy->pipe_rst)) {
> > + dev_err(dev, "no usb3phy_pipe_mac reset control found\n");
> > + return PTR_ERR(usb3phy->pipe_rst);
> > + }
> > +
> > + usb3phy->utmi_rst = devm_reset_control_get(dev, "usb3phy-utmi-mac");
> > + if (IS_ERR(usb3phy->utmi_rst)) {
> > + dev_err(dev, "no usb3phy-utmi-mac reset control found\n");
> > + return PTR_ERR(usb3phy->utmi_rst);
> > + }
> > +
> > + usb3phy->pipe_apb_rst = devm_reset_control_get(dev, "usb3phy-pipe-apb");
> > + if (IS_ERR(usb3phy->pipe_apb_rst)) {
> > + dev_err(dev, "no usb3phy-pipe-apb reset control found\n");
> > + return PTR_ERR(usb3phy->pipe_apb_rst);
> > + }
> > +
> > + usb3phy->utmi_apb_rst = devm_reset_control_get(dev, "usb3phy-utmi-apb");
> > + if (IS_ERR(usb3phy->utmi_apb_rst)) {
> > + dev_err(dev, "no usb3phy-utmi-apb reset control found\n");
> > + return PTR_ERR(usb3phy->utmi_apb_rst);
> > + }
> > +
> > + usb3phy->ls_irq = of_irq_get_byname(dev->of_node, "linestate");
> > + if (usb3phy->ls_irq < 0) {
> > + dev_err(dev, "no linestate irq provided\n");
> > + return usb3phy->ls_irq;
> > + }
> > +
> > + ret = devm_request_threaded_irq(dev, usb3phy->ls_irq, NULL, rockchip_usb3phy_linestate_irq,
> > + IRQF_ONESHOT, "rockchip_usb3phy_ls", usb3phy);
> > + if (ret) {
> > + dev_err(dev, "failed to request linestate irq handle\n");
> > + return ret;
> > + }
> > +
> > + usb3phy->bvalid_irq = of_irq_get_byname(dev->of_node, "bvalid");
> > + if (usb3phy->bvalid_irq < 0) {
> > + dev_err(dev, "no bvalid irq provided\n");
> > + return usb3phy->bvalid_irq;
> > + }
> > +
> > + ret = devm_request_threaded_irq(dev, usb3phy->bvalid_irq, NULL, rockchip_usb3phy_bvalid_irq,
> > + IRQF_ONESHOT, "rockchip_usb3phy_bvalid", usb3phy);
> > + if (ret) {
> > + dev_err(dev, "failed to request bvalid irq handle\n");
> > + return ret;
> > + }
> > +
> > + usb3phy->id_irq = of_irq_get_byname(dev->of_node, "id");
> > + if (usb3phy->id_irq < 0) {
> > + dev_err(dev, "no id irq provided\n");
> > + return usb3phy->id_irq;
> > + }
> > +
> > + ret = devm_request_threaded_irq(dev, usb3phy->id_irq, NULL, rockchip_usb3phy_id_irq,
> > + IRQF_ONESHOT, "rockchip_usb3phy-id", usb3phy);
> > + if (ret) {
> > + dev_err(dev, "failed to request id irq handle\n");
> > + return ret;
> > + }
> > +
> > + usb3phy->rxdet_irq = of_irq_get_byname(dev->of_node, "rxdet");
> > + if (usb3phy->rxdet_irq < 0) {
> > + dev_err(dev, "no rxdet irq provided\n");
> > + return usb3phy->rxdet_irq;
> > + }
> > +
> > + ret = devm_request_threaded_irq(dev, usb3phy->rxdet_irq, NULL, rockchip_usb3phy_rxdet_irq,
> > + IRQF_ONESHOT, "rockchip_usb3phy-rxdet", usb3phy);
> > + if (ret) {
> > + dev_err(dev, "failed to request rxdet irq handle\n");
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int rockchip_usb3phy_exit(struct phy *phy)
> > +{
> > + struct rockchip_usb3phy_port *port = phy_get_drvdata(phy);
> > + struct rockchip_usb3phy *usb3phy = dev_get_drvdata(phy->dev.parent);
> > +
> > + dev_dbg(usb3phy->dev, "usb3phy_shutdown\n");
> > + rockchip_usb3phy_reset(usb3phy, true, port->type);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct phy_ops rockchip_usb3phy_ops = {
> > + .init = rockchip_usb3phy_init,
> > + .exit = rockchip_usb3phy_exit,
> > + .owner = THIS_MODULE,
> > +};
> > +
> > +static const struct regmap_config rockchip_usb3phy_utmi_port_regmap_config = {
> > + .reg_bits = 32,
> > + .val_bits = 32,
> > + .reg_stride = 4,
> > + .max_register = 0x400,
> > + .cache_type = REGCACHE_NONE,
> > + .fast_io = true,
> > + .name = "utmi-port",
> > +};
> > +
> > +static const struct regmap_config rockchip_usb3phy_pipe_port_regmap_config = {
> > + .reg_bits = 32,
> > + .val_bits = 32,
> > + .reg_stride = 4,
> > + .max_register = 0x400,
> > + .cache_type = REGCACHE_NONE,
> > + .fast_io = true,
> > + .name = "pipe-port",
> > +};
> > +
> > +static const struct regmap_config rockchip_usb3phy_regmap_config = {
> > + .reg_bits = 32,
> > + .val_bits = 32,
> > + .reg_stride = 4,
> > + .max_register = 0x400,
> > + .write_flag_mask = REG_WRITE_MASK,
> > + .cache_type = REGCACHE_NONE,
> > + .fast_io = true,
> > +};
> > +
> > +static int rockchip_usb3phy_probe(struct platform_device *pdev)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct device_node *np = dev->of_node;
> > + struct device_node *child_np;
> > + struct phy_provider *provider;
> > + struct rockchip_usb3phy *usb3phy;
> > + const struct regmap_config regmap_config = rockchip_usb3phy_regmap_config;
> > + void __iomem *base;
> > + int i, ret;
> > +
> > + dev_dbg(dev, "Probe usb3phy main block\n");
> > + usb3phy = devm_kzalloc(dev, sizeof(*usb3phy), GFP_KERNEL);
> > + if (!usb3phy)
> > + return -ENOMEM;
> > +
> > + ret = rockchip_usb3phy_parse_dt(usb3phy, dev);
> > + if (ret) {
> > + dev_err(dev, "parse dt failed %i\n", ret);
>
> return dev_err_probe()
>
> And do not print errors twice.
This is a remnant of the debugging era, thank you for catching it.
>
> > + return ret;
>
>
>
>
> > +
> > + /* take apb interface out of reset */
> > + reset_control_deassert(usb3phy->utmi_apb_rst);
> > + reset_control_deassert(usb3phy->pipe_apb_rst);
> > +
> > + /* enable usb3phy rx detection to fix disconnection issues */
> > + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG,
> > + (USB3_RXDET_EN | (USB3_RXDET_EN << REG_WRITE_SHIFT)));
> > +
> > + dev_dbg(dev, "Completed usb3phy core probe\n");
>
> Drop.
>
> > +
> > + /* probe the actual ports */
> > + i = 0;
> > + for_each_available_child_of_node(np, child_np) {
> > + const struct regmap_config *regmap_port_config;
> > + struct rockchip_usb3phy_port *port = &usb3phy->ports[i];
> > + struct phy *phy;
> > +
> > + if (of_node_name_eq(child_np, "utmi-port")) {
>
> Why are you comparing node names, if you decided to put there compatibles?
>
> Decide on one method, but wait for full DT review.
The compatibles are remnants from the old method where the driver
bound each device individually. Now that I've switched to the generic
phy system from the usb-phy system, everything is bound at once, they
are no longer necessary.
>
> > + port->type = USB3PHY_TYPE_USB2;
> > + regmap_port_config = &rockchip_usb3phy_utmi_port_regmap_config;
> > + } else if (of_node_name_eq(child_np, "pipe-port")) {
> > + port->type = USB3PHY_TYPE_USB3;
> > + regmap_port_config = &rockchip_usb3phy_pipe_port_regmap_config;
> > + } else {
> > + dev_err(dev, "unknown child node port type %s\n", child_np->name);
> > + goto err_port;
> > + }
> > +
> > + base = devm_of_iomap(dev, child_np, 0, NULL);
> > + if (IS_ERR(base)) {
> > + dev_err(dev, "failed port ioremap\n");
> > + ret = PTR_ERR(base);
> > + goto err_port;
> > + }
> > +
> > + port->regmap = devm_regmap_init_mmio(dev, base, regmap_port_config);
> > + if (IS_ERR(port->regmap)) {
> > + dev_err(dev, "regmap init failed\n");
> > + ret = PTR_ERR(port->regmap);
> > + goto err_port;
> > + }
> > +
> > + phy = devm_phy_create(dev, child_np, &rockchip_usb3phy_ops);
> > + if (IS_ERR(phy)) {
> > + dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
> > + ret = PTR_ERR(phy);
>
> Just read how dev_err_probe() works. The syntax is:
> ret = dev_err_probe.
Thank you for reminding me of this. The error handling portion is
about the only part that remains from the original driver, back before
dev_err_probe became a big thing.
>
> > + goto err_port;
> > + }
> > +
> > + port->phy = phy;
> > + phy_set_drvdata(port->phy, port);
> > +
> > + /* to prevent out of boundary */
> > + if (++i >= USB3PHY_TYPE_MAX) {
> > + of_node_put(child_np);
> > + break;
> > + }
> > +
> > + dev_info(dev, "Completed usb3phy %s port init\n", child_np->name);
> Drop, not really helping.
Thank you for catching the remaining debugging stuff I missed stripping out.
>
> Best regards,
> Krzysztof
I appreciate your review.
Very Respectfully,
Peter Geis
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 2/6] dt-bindings: phy: rockchip: add rk3328 usb3 phy
2025-01-16 13:08 ` Krzysztof Kozlowski
@ 2025-01-16 13:32 ` Peter Geis
2025-01-16 13:59 ` Peter Geis
2025-01-18 9:06 ` Krzysztof Kozlowski
0 siblings, 2 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-16 13:32 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Heiko Stuebner, zyw, kever.yang, frank.wang, william.wu, wulf,
linux-rockchip, Conor Dooley, Kishon Vijay Abraham I,
Krzysztof Kozlowski, Rob Herring, Vinod Koul, devicetree,
linux-arm-kernel, linux-kernel, linux-phy
On Thu, Jan 16, 2025 at 8:08 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On 15/01/2025 02:26, Peter Geis wrote:
> > Add documentation for the usb3 phy as implemented on the rk3328 SoC.
> >
> > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> > ---
> >
> > .../bindings/phy/rockchip,inno-usb3phy.yaml | 166 ++++++++++++++++++
> > 1 file changed, 166 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> > new file mode 100644
> > index 000000000000..cde489ca87ab
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> > @@ -0,0 +1,166 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
>
> Wrong license.
>
> Please run scripts/checkpatch.pl and fix reported warnings. After that,
> run also `scripts/checkpatch.pl --strict` and (probably) fix more
> warnings. Some warnings can be ignored, especially from --strict run,
> but the code here looks like it needs a fix. Feel free to get in touch
> if the warning is not clear.
Checkpatch literally told me to change this. Ran against my original
dev binding:
./scripts/checkpatch.pl --strict
Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
CHECK: DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)
#1: FILE: Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml:1:
+# SPDX-License-Identifier: GPL-2.0
>
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/phy/rockchip,inno-usb3phy.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Rockchip USB 3.0 phy with Innosilicon IP block
>
> > +
> > +maintainers:
> > + - Heiko Stuebner <heiko@sntech.de>
> > +
> > +properties:
> > + compatible:
> > + enum:
> > + - rockchip,rk3328-usb3phy
>
> Why is this binding entirely different than existing usb2 phy? Nothing
> in common? This looks like made for driver and both - driver and binding
> - duplicating a lot.
Hmm, I hadn't considered merging it into the usb2 binding as it is a
unique (and uniquely broken) device. I'd like Heiko's thoughts on
this.
>
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + clocks:
> > + minItems: 3
>
> Drop
>
> > + maxItems: 3
> > +
> > + clock-names:
> > + items:
> > + - const: refclk-usb3otg
>
> ref
>
> > + - const: usb3phy-otg
>
> otg
>
> > + - const: usb3phy-pipe
>
> pipe
>
> > +
> > + interrupts:
> > + minItems: 4
>
> You code here randomly. reg has only maxItems, clocks have both and this
> have only minItems. Does not make sense. If you get it wrong, I would
> assume you repeat the same mistake but here it is like randomly chosen
> pieces. And this is making me wonder whether this was not sent too fast.
I admit, I dread writing bindings as even now I'm weak in YAML and it
seems to pick and choose what rules it wants to follow.
>
> Anyway: only maxItems.
>
>
> > +
> > + interrupt-names:
> > + items:
> > + - const: bvalid
> > + - const: id
> > + - const: linestate
> > + - const: rxdet
> > +
> > + resets:
> > + minItems: 6
>
> maxItems instead
>
> > +
> > + reset-names:
> > + items:
> > + - const: usb3phy-u2-por
> > + - const: usb3phy-u3-por
> > + - const: usb3phy-pipe-mac
> > + - const: usb3phy-utmi-mac
> > + - const: usb3phy-utmi-apb
> > + - const: usb3phy-pipe-apb
> > +
> > + "#address-cells":
> > + const: 2
> > +
> > + "#size-cells":
> > + const: 2
> > +
> > + ranges: true
> > +
> > +patternProperties:
> > +
>
> Drop blank line
>
> > + utmi-port@[0-9a-f]+$:
>
> This wasn't tested. Missing quotes, missing starting anchor.
make W=1 dt_binding_check didn't complain about it, using the
dt-schema from pip3 from about a week ago.
>
> > + type: object
>
> Explain what are the children here - description.
Fair, will do.
>
>
> > + additionalProperties: false
> > +
> > + properties:
> > + compatible:
> > + enum:
> > + - rockchip,rk3328-usb3phy-utmi
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + "#phy-cells":
> > + const: 0
>
> Does not look correct. Your parent device is the phy, not child. Why do
> you create children per each type of phy?
Because that's how it's done elsewhere in Rockchip's phys [1]. How
should it be done?
>
> > +
> > + phy-supply:
> > + description:
> > + Phandle to a regulator that provides power to VBUS.
> > + See ./phy-bindings.txt for details.
> > +
> > + required:
> > + - compatible
> > + - reg
> > + - "#phy-cells"
> > +
> > + pipe-port@[0-9a-f]+$:
> > + type: object
> > + additionalProperties: false
> > +
> > + properties:
> > + compatible:
> > + enum:
> > + - rockchip,rk3328-usb3phy-pipe
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + "#phy-cells":
> > + const: 0
> > +
> > + phy-supply:
> > + description:
> > + Phandle to a regulator that provides power to VBUS.
> > + See ./phy-bindings.txt for details.
>
> Drop "see ....".
I was tempted to convert phy-bindings.txt over but as above I dread
writing bindings. Will drop.
>
> > +
> > + required:
> > + - compatible
> > + - reg
> > + - "#phy-cells"
> > +
> > +required:
> > + - compatible
> > + - reg
> > + - clocks
> > + - clock-names
> > + - interrupts
> > + - interrupt-names
> > + - resets
> > + - reset-names
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > + - |
> > + #include <dt-bindings/clock/rk3328-cru.h>
> > + #include <dt-bindings/interrupt-controller/arm-gic.h>
> > + #include <dt-bindings/interrupt-controller/irq.h>
> > + soc {
> > + #address-cells = <2>;
> > + #size-cells = <2>;
> > +
> > + usb3phy: usb3-phy@ff460000 {
> > + compatible = "rockchip,rk3328-usb3phy";
> > + reg = <0x0 0xff460000 0x0 0x10000>;
> > + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
>
> That's way over the limit. Wrapping is at 80.
Will correct.
>
> > + clock-names = "refclk-usb3otg", "usb3phy-otg", "usb3phy-pipe";
> > + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> > + interrupt-names = "bvalid", "id", "linestate", "rxdet";
>
>
>
I appreciate all the feedback, I'll incorporate the changes you've recommended.
Very Respectfully,
Peter Geis
>
> Best regards,
> Krzysztof
[1] https://elixir.bootlin.com/linux/v6.13-rc3/source/arch/arm64/boot/dts/rockchip/rk3328.dtsi#L887
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 2/6] dt-bindings: phy: rockchip: add rk3328 usb3 phy
2025-01-16 13:32 ` Peter Geis
@ 2025-01-16 13:59 ` Peter Geis
2025-01-18 9:06 ` Krzysztof Kozlowski
1 sibling, 0 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-16 13:59 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Heiko Stuebner, zyw, kever.yang, frank.wang, william.wu, wulf,
linux-rockchip, Conor Dooley, Kishon Vijay Abraham I,
Krzysztof Kozlowski, Rob Herring, Vinod Koul, devicetree,
linux-arm-kernel, linux-kernel, linux-phy
On Thu, Jan 16, 2025 at 8:32 AM Peter Geis <pgwipeout@gmail.com> wrote:
>
> On Thu, Jan 16, 2025 at 8:08 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >
> > On 15/01/2025 02:26, Peter Geis wrote:
> > > Add documentation for the usb3 phy as implemented on the rk3328 SoC.
> > >
> > > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> > > ---
> > >
> > > .../bindings/phy/rockchip,inno-usb3phy.yaml | 166 ++++++++++++++++++
> > > 1 file changed, 166 insertions(+)
> > > create mode 100644 Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> > >
> > > diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> > > new file mode 100644
> > > index 000000000000..cde489ca87ab
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> > > @@ -0,0 +1,166 @@
> > > +# SPDX-License-Identifier: GPL-2.0-only
> >
> > Wrong license.
> >
> > Please run scripts/checkpatch.pl and fix reported warnings. After that,
> > run also `scripts/checkpatch.pl --strict` and (probably) fix more
> > warnings. Some warnings can be ignored, especially from --strict run,
> > but the code here looks like it needs a fix. Feel free to get in touch
> > if the warning is not clear.
>
> Checkpatch literally told me to change this. Ran against my original
> dev binding:
> ./scripts/checkpatch.pl --strict
> Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml
> CHECK: DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)
> #1: FILE: Documentation/devicetree/bindings/phy/rockchip,inno-usb3phy.yaml:1:
> +# SPDX-License-Identifier: GPL-2.0
I understand now, thank you. Perhaps checkpatch could put that in
quotes, instead saying ("GPL-2.0-only OR BSD-2-Clause") to make it
clear it's one thing.
>
> >
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/phy/rockchip,inno-usb3phy.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Rockchip USB 3.0 phy with Innosilicon IP block
> >
> > > +
> > > +maintainers:
> > > + - Heiko Stuebner <heiko@sntech.de>
> > > +
> > > +properties:
> > > + compatible:
> > > + enum:
> > > + - rockchip,rk3328-usb3phy
> >
> > Why is this binding entirely different than existing usb2 phy? Nothing
> > in common? This looks like made for driver and both - driver and binding
> > - duplicating a lot.
>
> Hmm, I hadn't considered merging it into the usb2 binding as it is a
> unique (and uniquely broken) device. I'd like Heiko's thoughts on
> this.
>
> >
> > > +
> > > + reg:
> > > + maxItems: 1
> > > +
> > > + clocks:
> > > + minItems: 3
> >
> > Drop
> >
> > > + maxItems: 3
> > > +
> > > + clock-names:
> > > + items:
> > > + - const: refclk-usb3otg
> >
> > ref
> >
> > > + - const: usb3phy-otg
> >
> > otg
> >
> > > + - const: usb3phy-pipe
> >
> > pipe
> >
> > > +
> > > + interrupts:
> > > + minItems: 4
> >
> > You code here randomly. reg has only maxItems, clocks have both and this
> > have only minItems. Does not make sense. If you get it wrong, I would
> > assume you repeat the same mistake but here it is like randomly chosen
> > pieces. And this is making me wonder whether this was not sent too fast.
>
> I admit, I dread writing bindings as even now I'm weak in YAML and it
> seems to pick and choose what rules it wants to follow.
>
> >
> > Anyway: only maxItems.
> >
> >
> > > +
> > > + interrupt-names:
> > > + items:
> > > + - const: bvalid
> > > + - const: id
> > > + - const: linestate
> > > + - const: rxdet
> > > +
> > > + resets:
> > > + minItems: 6
> >
> > maxItems instead
> >
> > > +
> > > + reset-names:
> > > + items:
> > > + - const: usb3phy-u2-por
> > > + - const: usb3phy-u3-por
> > > + - const: usb3phy-pipe-mac
> > > + - const: usb3phy-utmi-mac
> > > + - const: usb3phy-utmi-apb
> > > + - const: usb3phy-pipe-apb
> > > +
> > > + "#address-cells":
> > > + const: 2
> > > +
> > > + "#size-cells":
> > > + const: 2
> > > +
> > > + ranges: true
> > > +
> > > +patternProperties:
> > > +
> >
> > Drop blank line
> >
> > > + utmi-port@[0-9a-f]+$:
> >
> > This wasn't tested. Missing quotes, missing starting anchor.
>
> make W=1 dt_binding_check didn't complain about it, using the
> dt-schema from pip3 from about a week ago.
>
> >
> > > + type: object
> >
> > Explain what are the children here - description.
>
> Fair, will do.
>
> >
> >
> > > + additionalProperties: false
> > > +
> > > + properties:
> > > + compatible:
> > > + enum:
> > > + - rockchip,rk3328-usb3phy-utmi
> > > +
> > > + reg:
> > > + maxItems: 1
> > > +
> > > + "#phy-cells":
> > > + const: 0
> >
> > Does not look correct. Your parent device is the phy, not child. Why do
> > you create children per each type of phy?
>
> Because that's how it's done elsewhere in Rockchip's phys [1]. How
> should it be done?
>
> >
> > > +
> > > + phy-supply:
> > > + description:
> > > + Phandle to a regulator that provides power to VBUS.
> > > + See ./phy-bindings.txt for details.
> > > +
> > > + required:
> > > + - compatible
> > > + - reg
> > > + - "#phy-cells"
> > > +
> > > + pipe-port@[0-9a-f]+$:
> > > + type: object
> > > + additionalProperties: false
> > > +
> > > + properties:
> > > + compatible:
> > > + enum:
> > > + - rockchip,rk3328-usb3phy-pipe
> > > +
> > > + reg:
> > > + maxItems: 1
> > > +
> > > + "#phy-cells":
> > > + const: 0
> > > +
> > > + phy-supply:
> > > + description:
> > > + Phandle to a regulator that provides power to VBUS.
> > > + See ./phy-bindings.txt for details.
> >
> > Drop "see ....".
>
> I was tempted to convert phy-bindings.txt over but as above I dread
> writing bindings. Will drop.
>
> >
> > > +
> > > + required:
> > > + - compatible
> > > + - reg
> > > + - "#phy-cells"
> > > +
> > > +required:
> > > + - compatible
> > > + - reg
> > > + - clocks
> > > + - clock-names
> > > + - interrupts
> > > + - interrupt-names
> > > + - resets
> > > + - reset-names
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > + - |
> > > + #include <dt-bindings/clock/rk3328-cru.h>
> > > + #include <dt-bindings/interrupt-controller/arm-gic.h>
> > > + #include <dt-bindings/interrupt-controller/irq.h>
> > > + soc {
> > > + #address-cells = <2>;
> > > + #size-cells = <2>;
> > > +
> > > + usb3phy: usb3-phy@ff460000 {
> > > + compatible = "rockchip,rk3328-usb3phy";
> > > + reg = <0x0 0xff460000 0x0 0x10000>;
> > > + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
> >
> > That's way over the limit. Wrapping is at 80.
>
> Will correct.
>
> >
> > > + clock-names = "refclk-usb3otg", "usb3phy-otg", "usb3phy-pipe";
> > > + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
> > > + <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> > > + interrupt-names = "bvalid", "id", "linestate", "rxdet";
> >
> >
> >
>
> I appreciate all the feedback, I'll incorporate the changes you've recommended.
>
> Very Respectfully,
> Peter Geis
>
> >
> > Best regards,
> > Krzysztof
>
> [1] https://elixir.bootlin.com/linux/v6.13-rc3/source/arch/arm64/boot/dts/rockchip/rk3328.dtsi#L887
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-15 13:25 ` Piotr Oniszczuk
@ 2025-01-16 14:02 ` Peter Geis
2025-01-16 14:35 ` Piotr Oniszczuk
0 siblings, 1 reply; 44+ messages in thread
From: Peter Geis @ 2025-01-16 14:02 UTC (permalink / raw)
To: Piotr Oniszczuk
Cc: Heiko Stuebner, Algea Cao, Michael Turquette, kever.yang,
linux-phy, wulf, zyw, Dragan Simic, Kishon Vijay Abraham I,
Rob Herring, Sebastian Reichel, linux-clk, linux-rockchip,
devicetree, Conor Dooley, Philipp Zabel, Arnd Bergmann,
Jonas Karlman, frank.wang, Elaine Zhang, Alex Bee, william.wu,
Zhang Yubing, Johan Jonker, linux-arm-kernel, Trevor Woerner,
Stephen Boyd, linux-kernel, Vinod Koul, FUKAUMI Naoki,
Diederik de Haas, Krzysztof Kozlowski
On Wed, Jan 15, 2025 at 8:25 AM Piotr Oniszczuk
<piotr.oniszczuk@gmail.com> wrote:
>
>
>
> > Wiadomość napisana przez Peter Geis <pgwipeout@gmail.com> w dniu 15 sty 2025, o godz. 14:15:
> >
> >>
> >>
> >> pls find:
> >>
> >> dtsi: https://gist.github.com/warpme/6af9e2778fb06bfb47b64f98fe79d678
> >> and dt: https://gist.github.com/warpme/79340c54c87b2b1e52f2a146461d8c9f
> >>
> >>
> >> and compiled .dtb
> >
> > It all looks good.
> > Do you have any CRU errors in the boot log?
> > Can you check for the presence of clk_ref_usb3otg in
> > /sys/kernel/debug/clk/clk_summary?
> >
> >>
>
> cru errors in dmesg - seems no any.
> here is my dmesg: https://gist.github.com/warpme/ecf38482cc88fb68471355d011ecf974
>
> For clk_ref_usb3otg i’m getting following:
>
> root@myth-frontend-e67a8de4c815:~ # cat /sys/kernel/debug/clk/clk_summary | grep usb3
> clk_usb3otg_suspend 0 0 0 30770 0 0 50000 N deviceless no_connection_id
> clk_usb3otg_ref 0 0 0 24000000 0 0 50000 N deviceless no_connection_id
> clk_ref_usb3otg 0 0 0 24000000 0 0 50000 Y deviceless no_connection_id
> pclk_usb3_grf 0 0 0 75000000 0 0 50000 Y deviceless no_connection_id
> pclk_usb3phy_pipe 0 0 0 75000000 0 0 50000 N deviceless no_connection_id
> pclk_usb3phy_otg 0 0 0 75000000 0 0 50000 N deviceless no_connection_id
> clk_ref_usb3otg_src 0 0 0 37500000 0 0 50000 N deviceless no_connection_id
> aclk_usb3otg 0 0 0 150000000 0 0 50000 N deviceless no_connection_id
>
I'm at a loss here, I applied the patches to a clean 6.9 tree and even
built it as a module (thank you for the sentinel). I have no issues.
I'm wondering if it's your .config or something about your bootloader.
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 3/6] phy: rockchip: add driver for rk3328 usb3 phy
2025-01-15 11:24 ` Piotr Oniszczuk
@ 2025-01-16 14:09 ` Peter Geis
0 siblings, 0 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-16 14:09 UTC (permalink / raw)
To: Piotr Oniszczuk
Cc: Heiko Stuebner, Kishon Vijay Abraham I, Algea Cao, linux-kernel,
Philipp Zabel, Arnd Bergmann, frank.wang, william.wu, kever.yang,
linux-phy, Sebastian Reichel, linux-rockchip, Vinod Koul,
Zhang Yubing, zyw, wulf, linux-arm-kernel
On Wed, Jan 15, 2025 at 6:24 AM Piotr Oniszczuk
<piotr.oniszczuk@gmail.com> wrote:
>
>
>
> > Wiadomość napisana przez Peter Geis <pgwipeout@gmail.com> w dniu 15 sty 2025, o godz. 02:26:
> >
> > The rk3328 has a combined usb2 and usb3 phy block for the usb3 dwc
> > interface. The implementation up until now has been bugged, with
> > multiple issues ranging from disconnect detection failures to low
> > performance. This driver fixes the majority of the original issues and
> > allows better performance for the rk3328 usb3 port.
> >
> > This driver sources data from multiple sources, including the rk3328
> > trm, the rk3228h trm, emails from Rockchip, and both the 4.4 and 5.10
> > downstream drivers. The current implementation allows for basic bring up
> > of the phy block and fixes the detection issues. Interrupts are enabled,
> > but currently only used for debugging. Features missing currently are
> > power management, OTG handling, board specific tuning, regulator control,
> >
> > Currently the only known bugs are a AX88179 usb3 gigabit adapter crashes
> > when operating at usb3 speeds and transmitting large amounts of data and
> > full disconnection detections may be slower than expected (~5-10 seconds).
> >
> > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> > ---
> >
> > drivers/phy/rockchip/Kconfig | 10 +
> > drivers/phy/rockchip/Makefile | 1 +
> > drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 869 ++++++++++++++++++
> > 3 files changed, 880 insertions(+)
> > create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> >
> > diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
> > index 2f7a05f21dc5..aac623e84f96 100644
> > --- a/drivers/phy/rockchip/Kconfig
> > +++ b/drivers/phy/rockchip/Kconfig
> > @@ -48,6 +48,16 @@ config PHY_ROCKCHIP_INNO_USB2
> > help
> > Support for Rockchip USB2.0 PHY with Innosilicon IP block.
> >
> > +config PHY_ROCKCHIP_INNO_USB3
> > + tristate "Rockchip INNO USB3PHY Driver"
> > + depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
> > + depends on COMMON_CLK
> > + depends on USB_SUPPORT
> > + select GENERIC_PHY
> > + select USB_COMMON
> > + help
> > + Support for Rockchip USB3.0 PHY with Innosilicon IP block.
> > +
> > config PHY_ROCKCHIP_INNO_CSIDPHY
> > tristate "Rockchip Innosilicon MIPI CSI PHY driver"
> > depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
> > diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
> > index 010a824e32ce..ec15dcf37fba 100644
> > --- a/drivers/phy/rockchip/Makefile
> > +++ b/drivers/phy/rockchip/Makefile
> > @@ -6,6 +6,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY) += phy-rockchip-inno-csidphy.o
> > obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o
> > obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
> > obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
> > +obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB3) += phy-rockchip-inno-usb3.o
> > obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o
> > obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
> > obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX) += phy-rockchip-samsung-hdptx.o
> > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb3.c b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> > new file mode 100644
> > index 000000000000..51b9f3b7fbfa
> > --- /dev/null
> > +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> > @@ -0,0 +1,869 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +
> > +/*
> > + * phy-rockchip-inno-usb3.c - USB3 PHY based on Innosilicon IP as
> > + * implemented on Rockchip rk3328. Tuning data magic bits are taken as is
> > + * from the downstream driver. Downstream driver is located at:
> > + * https://github.com/rockchip-linux/kernel/blob/240a5660d7c23841ccf7b7cc489078bf521b9802/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> > + *
> > + * Author: Peter Geis <pgwipeout@gmail.com>
> > + * TODO:
> > + * - Find the rest of the register names / definitions.
> > + * - Implement pm functions.
> > + * - Implement board specific tuning from dts.
> > + * - Implement regulator control.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/reset.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/usb/of.h>
> > +
> > +#define REG_WRITE_MASK GENMASK(31, 16)
> > +#define REG_WRITE_SHIFT 16
> > +#define DISABLE_BITS 0x0
> > +
> > +/* USB3PHY GRF Registers */
> > +#define USB3PHY_WAKEUP_CON_REG 0x40
> > +#define USB3PHY_WAKEUP_STAT_REG 0x44
> > +#define USB3_LINESTATE_IRQ_EN BIT(0)
> > +#define USB3_RXDET_IRQ_EN BIT(1)
> > +#define USB3_BVALID_RISE_IRQ_EN BIT(2)
> > +#define USB3_BVALID_FALL_IRQ_EN BIT(3)
> > +#define USB3_BVALID_CLEAR_MASK GENMASK(3, 2)
> > +#define USB3_ID_RISE_IRQ_EN BIT(4)
> > +#define USB3_ID_FALL_IRQ_EN BIT(5)
> > +#define USB3_ID_CLEAR_MASK GENMASK(5, 4)
> > +#define USB3_RXDET_EN BIT(6)
> > +
> > +/* PIPE registers */
> > +/* 0x08 for SSC, default 0x0e */
> > +#define UNKNOWN_PIPE_REG_000 0x000
> > +#define UNKNOWN_SSC_000_MASK GENMASK(2, 1)
> > +#define UNKNOWN_SSC_000_ENABLE (0x00 << 1)
> > +
> > +/* 0x83 for 24m, 0x01 for 25m, default 0x86 */
> > +#define PIPE_REG_020 0x020
> > +/* RX CDR multiplier high bits [7:6], as P, default 0x2, RX data rate = (2*refclk*P)/Q */
> > +#define PIPE_RX_CDR_MULT_HIGH_MASK GENMASK(7, 6)
> > +/* TX PLL divider bits [4:0], as N, default 0x6, TX data rate = (2*refclk*M)/N */
> > +#define PIPE_TX_PLL_DIV_MASK GENMASK(4, 0)
> > +
> > +/* 0x71 for 24m, 0x64 for 25m, default 0x71 */
> > +#define PIPE_REG_028 0x028
> > +/* RX CDR multiplier low bits [7:0], as P, default 0x71, RX data rate = (2*refclk*P)/Q */
> > +#define PIPE_RX_CDR_MULT_LOW_MASK GENMASK(7, 0)
> > +
> > +/* 0x26 for 24m?, 0x21 for 25m, default 0x26 */
> > +#define PIPE_REG_030 0x030
> > +/* RX CDR divider bits [4:0], as Q, default 0x6, RX data rate = (2*refclk*P)/Q */
> > +#define PIPE_RX_CDR_DIV_MASK GENMASK(4, 0)
> > +
> > +/* 1'b1 Disable bandgap power, default 0x00 */
> > +#define PIPE_REG_044 0x044
> > +#define BANDGAP_POWER_DISABLE BIT(4)
> > +
> > +/* 0xe0 for rx tune?, default 0xe1 */
> > +#define PIPE_REG_060 0x060
> > +#define PIPE_TX_DETECT_BYPASS_DEBUG BIT(4) /* enable to always force detection */
> > +/* RX CTLE frequency bandwidth response tuning bits [1:0], default 0x1 */
> > +#define PIPE_RX_CTLE_FREQ_BW_MASK GENMASK(1, 0)
> > +#define PIPE_RX_CTLE_FREQ_BW_TUNE 0x0
> > +
> > +/* default 0x49 */
> > +#define PIPE_REG_064 0x064
> > +/* RX equalizer tail current control bits [6:4], default 0x4 */
> > +#define PIPE_RX_EQ_TAIL_CURR_MASK GENMASK(6, 4)
> > +
> > +/* 0x08 for rx tune?, default 0x07 */
> > +#define PIPE_REG_068 0x068
> > +/* RX equalizer low frequency gain control bits [7:4], default 0x0 */
> > +#define PIPE_RX_EQ_LOW_GAIN_MASK GENMASK(7, 4)
> > +#define PIPE_RX_EQ_LOW_GAIN_TUNE (0x1 << 4)
> > +/* RX CTLE gain tuning bits [3:0], higher = more gain default 0x7 */
> > +#define PIPE_RX_CTLE_GAIN_MASK GENMASK(3, 0)
> > +#define PIPE_RX_CTLE_GAIN_TUNE 0x7 /* 0x5 lowest functional value, 0xf highest */
> > +
> > +/* RX ODT manual resistance config, higher = less resistance, depends on REG_1C4 BIT(5) set */
> > +#define PIPE_REG_06C 0x06c
> > +/* RX ODT manual resistance high bits [3:0], default 0x0 */
> > +#define PIPE_RX_ODT_RES_HIGH_MASK GENMASK(3, 0)
> > +#define PIPE_RX_ODT_RES_HIGH_TUNE 0xf
> > +
> > +#define PIPE_REG_070 0x070
> > +/* RX ODT manual resistance mid bits [7:0], default 0x03 */
> > +#define PIPE_RX_ODT_RES_MID_MASK GENMASK(7, 0)
> > +#define PIPE_RX_ODT_RES_MID_TUNE 0xff
> > +
> > +#define PIPE_REG_074 0x074
> > +/* RX ODT manual resistance low bits [7:0], default 0xff */
> > +#define PIPE_RX_ODT_RES_LOW_MASK GENMASK(7, 0)
> > +#define PIPE_RX_ODT_RES_LOW_TUNE 0xff
> > +
> > +/* default 0x08 */
> > +#define PIPE_REG_080 0x080
> > +#define PIPE_TX_COMMON_MODE_DIS BIT(2) /* 1'b1 disable TX common type */
> > +
> > +/* default 0x33 */
> > +#define PIPE_REG_088 0x088
> > +#define PIPE_TX_DRIVER_PREEMP_EN BIT(4) /* 1'b1 enable pre-emphasis */
> > +
> > +/* default 0x18 */
> > +#define PIPE_REG_0C0 0x0c0
> > +#define PIPE_RX_CM_EN BIT(3) /* 1'b1 enable RX CM */
> > +#define PIPE_TX_OBS_EN BIT(4) /* 1'b1 enable TX OBS */
> > +
> > +/* 0x12 for rx tune?, default 0x14 */
> > +#define PIPE_REG_0C8 0x0c8
> > +/* RX CDR charge pump current bits [3:1], default 0x2 */
> > +#define PIPE_RX_CDR_CHG_PUMP_MASK GENMASK(3, 1)
> > +#define PIPE_RX_CDR_CHG_PUMP_TUNE (0x2 << 1)
> > +
> > +/* 0x02 for 24m, 0x06 for 25m, default 0x06 */
> > +#define UNKNOWN_PIPE_REG_108 0x108
> > +#define UNKNOWN_REFCLK_108_24M 0x02
> > +
> > +/* 0x80 for 24m, default 0x00 */
> > +#define UNKNOWN_PIPE_REG_10C 0x10c
> > +#define UNKNOWN_REFCLK_10C_24M BIT(7)
> > +
> > +/* 0x01 for 24m, 0x00 for 25m, default 0x02 */
> > +#define PIPE_REG_118 0x118
> > +/* TX PLL multiplier high bits [3:0], as M, default 0x2, TX data rate = (2*refclk*M)/N */
> > +#define PIPE_TX_PLL_MUL_HIGH_MASK GENMASK(3, 0)
> > +
> > +/* 0x38 for 24m, 0x64 for 25m, default 0x71 */
> > +#define PIPE_REG_11C 0x11c
> > +/* TX PLL multiplier low bits [7:0], as M, default 0x71, TX data rate = (2*refclk*M)/N */
> > +#define PIPE_TX_PLL_MUL_LOW_MASK GENMASK(7, 0)
> > +
> > +/* 0x0c for SSC, default 0x1c */
> > +#define UNKNOWN_PIPE_REG_120 0x120
> > +#define UNKNOWN_SSC_120_MASK BIT(4)
> > +#define UNKNOWN_SSC_120_ENABLE (0x0 << 4)
> > +
> > +/* default 0x40 */
> > +#define PIPE_REG_12C 0x12c
> > +#define PIPE_TX_PLL_ALWAYS_ON BIT(0) /* disable for PLL control by pipe_pd */
> > +
> > +/* 0x05 for rx tune, default 0x01 */
> > +#define PIPE_REG_148 0x148
> > +#define PIPE_RX_CHG_PUMP_DIV_2 BIT(2) /* RX CDR charge pump div/2, default 0 */
> > +
> > +/* 0x70 for rx tune, default 0x72 */
> > +#define PIPE_REG_150 0x150
> > +#define PIPE_TX_BIAS_EN BIT(6) /* 1'b1 Enable TX Bias */
> > +/* RX CDR phase tracking speed bits [3:0], default 0x2 */
> > +#define PIPE_RX_CDR_SPEED_MASK GENMASK(3, 0)
> > +#define PIPE_RX_CDR_SPEED_TUNE 0x00
> > +
> > +/* default 0xd4 */
> > +#define PIPE_REG_160
> > +/* RX common mode voltage strength bits [5:4], default 0x1 */
> > +#define PIPE_RX_CDR_COM_VOLT_MASK GENMASK(5, 4)
> > +#define PIPE_RX_CDR_COM_VOLT_TUNE (0x1 << 4)
> > +
> > +/* default 0x00 */
> > +#define PIPE_REG_180 0x180
> > +/* TX driver bias reference voltage bits [3:2], in mv */
> > +#define PIPE_TX_BIAS_REF_VOLT_MASK GENMASK(3, 2)
> > +#define PIPE_TX_BIAS_REF_VOLT_200 (0x0 << 2)
> > +#define PIPE_TX_BIAS_REF_VOLT_175 (0x1 << 2)
> > +#define PIPE_TX_BIAS_REF_VOLT_225 (0x2 << 2) /* downstream 5.10 driver setting */
> > +#define PIPE_TX_BIAS_REF_VOLT_250 (0x3 << 2)
> > +
> > +/* default 0x01 */
> > +#define PIPE_REG_1A8 0x1a8
> > +#define PIPE_LDO_POWER_DIS BIT(4) /* 1'b1 Disable LDO Power */
> > +
> > +/* default 0x07 */
> > +#define PIPE_REG_1AC 0x1ac
> > +/* TX driver output common voltage bits [5:4], in mv */
> > +#define PIPE_TX_COMMON_VOLT_MASK GENMASK(5, 4)
> > +#define PIPE_TX_COMMON_VOLT_800 (0x0 << 4)
> > +#define PIPE_TX_COMMON_VOLT_750 (0x1 << 4)
> > +#define PIPE_TX_COMMON_VOLT_950 (0x2 << 4)
> > +#define PIPE_TX_COMMON_VOLT_1100 (0x3 << 4)
> > +
> > +/* default 0xfb */
> > +#define PIPE_REG_1B8 0x1b8
> > +/* TX driver swing strength bits [7:4], range 0x0 to 0xf */
> > +#define PIPE_TX_DRIVER_SWING_MASK GENMASK(7, 4) /* 0x2 lowest functional value */
> > +/* TX driver pre-emphasis strength bits [1:0], default 0x3, enabled by REG 088 */
> > +#define PIPE_TX_DRIVER_PREEMP_STR_MASK GENMASK(1, 0)
> > +
> > +/* set to 0xf0 for rx tune?, default 0xd0 */
> > +#define PIPE_REG_1C4 0x1c4
> > +#define PIPE_RX_ODT_AUTO_DIS BIT(5) /* Disable RX ODT auto compensation */
> > +#define PIPE_TX_ODT_AUTO_DIS BIT(3) /* Disable TX ODT auto compensation */
> > +
> > +/* UTMI registers */
> > +/* 0x0f for utmi tune, default 0x09*/
> > +#define UTMI_REG_030 0x030
> > +/* {bits[2:0]=111}: always enable pre-emphasis */
> > +#define UTMI_ENABLE_PRE_EMPH_MASK GENMASK(2, 0)
> > +#define UTMI_ENABLE_PRE_EMPH 0x07
> > +
> > +/* 0x41 for utmi tune, default 0x49 */
> > +#define UTMI_REG_040 0x040
> > +/* TX HS pre-emphasis strength bits [5:3], default 0x1*/
> > +#define UTMI_TX_PRE_EMPH_STR_MASK GENMASK(5, 3)
> > +#define UTMI_TX_PRE_EMPH_WEAKEST (0x0 << 3)
> > +
> > +/* set to 0xb5 for utmi tune, default 0xb5 */
> > +#define UTMI_REG_11C 0x11c
> > +/* {bits[4:0]=10101}: odt 45ohm tuning */
> > +#define UTMI_ODT_45_OHM_MASK GENMASK(4, 0)
> > +#define UTMI_ODT_45_OHM_TUNE 0x15
> > +
> > +enum rockchip_usb3phy_type {
> > + USB3PHY_TYPE_USB2,
> > + USB3PHY_TYPE_USB3,
> > + USB3PHY_TYPE_MAX,
> > +};
> > +
> > +/**
> > + * struct rockchip_usb3phy_port - usb-phy port data.
> > + * @phy: port usb phy struct.
> > + * @regmap: port regmap.
> > + * @type: port usb phy type.
> > + */
> > +struct rockchip_usb3phy_port {
> > + struct phy *phy;
> > + struct regmap *regmap;
> > + enum rockchip_usb3phy_type type;
> > +};
> > +
> > +struct rockchip_usb3phy {
> > + struct device *dev;
> > + struct regmap *regmap;
> > + struct clk *clk_pipe;
> > + struct clk *clk_otg;
> > + struct clk *clk_ref;
> > + struct reset_control *u3por_rst;
> > + struct reset_control *u2por_rst;
> > + struct reset_control *pipe_rst;
> > + struct reset_control *utmi_rst;
> > + struct reset_control *pipe_apb_rst;
> > + struct reset_control *utmi_apb_rst;
> > + struct rockchip_usb3phy_port ports[USB3PHY_TYPE_MAX];
> > + int bvalid_irq;
> > + int id_irq;
> > + int ls_irq;
> > + int rxdet_irq;
> > +};
> > +
> > +struct usb3phy_config {
> > + unsigned int reg;
> > + unsigned int mask;
> > + u8 def;
> > +};
> > +
> > +static const struct usb3phy_config rk3328_rx_config[] = {
> > + { PIPE_REG_150, PIPE_RX_CDR_SPEED_MASK, PIPE_RX_CDR_SPEED_TUNE },
> > + { PIPE_REG_0C8, PIPE_RX_CDR_CHG_PUMP_MASK, PIPE_RX_CDR_CHG_PUMP_TUNE },
> > + { PIPE_REG_148, PIPE_RX_CHG_PUMP_DIV_2, PIPE_RX_CHG_PUMP_DIV_2 },
> > + { PIPE_REG_068, PIPE_RX_CTLE_GAIN_MASK, PIPE_RX_CTLE_GAIN_TUNE },
> > +// { PIPE_REG_1C4, PIPE_RX_ODT_AUTO_DIS, PIPE_RX_ODT_AUTO_DIS },
> > + { PIPE_REG_070, PIPE_RX_ODT_RES_MID_MASK, PIPE_RX_ODT_RES_MID_TUNE },
> > + { PIPE_REG_06C, PIPE_RX_ODT_RES_HIGH_MASK, PIPE_RX_ODT_RES_HIGH_TUNE },
> > + { PIPE_REG_060, PIPE_RX_CTLE_FREQ_BW_MASK, PIPE_RX_CTLE_FREQ_BW_TUNE },
> > + { UNKNOWN_PIPE_REG_10C, UNKNOWN_REFCLK_10C_24M, UNKNOWN_REFCLK_10C_24M },
> > + { PIPE_REG_060, PIPE_RX_CTLE_FREQ_BW_MASK, PIPE_RX_CTLE_FREQ_BW_TUNE },
> > + { PIPE_REG_068, PIPE_RX_EQ_LOW_GAIN_MASK, PIPE_RX_EQ_LOW_GAIN_TUNE },
> > +};
> > +
> > +static const struct usb3phy_config rk3328_tx_config[] = {
> > + { PIPE_REG_180, PIPE_TX_BIAS_REF_VOLT_MASK, PIPE_TX_BIAS_REF_VOLT_250 },
> > +};
> > +
> > +static const struct usb3phy_config rk3328_ssc_config[] = {
> > + { UNKNOWN_PIPE_REG_000, UNKNOWN_SSC_000_MASK, UNKNOWN_SSC_000_ENABLE },
> > + { UNKNOWN_PIPE_REG_120, UNKNOWN_SSC_120_MASK, UNKNOWN_SSC_120_ENABLE },
> > +};
> > +
> > +static const struct usb3phy_config rk3328_utmi_config[] = {
> > + { UTMI_REG_030, UTMI_ENABLE_PRE_EMPH_MASK, UTMI_ENABLE_PRE_EMPH },
> > + { UTMI_REG_040, UTMI_TX_PRE_EMPH_STR_MASK, UTMI_TX_PRE_EMPH_WEAKEST },
> > + { UTMI_REG_11C, UTMI_ODT_45_OHM_MASK, UTMI_ODT_45_OHM_TUNE },
> > +};
> > +
> > +static const struct usb3phy_config rk3328_pipe_pwr_en_config[] = {
> > + { PIPE_REG_1A8, PIPE_LDO_POWER_DIS, DISABLE_BITS },
> > + { PIPE_REG_044, BANDGAP_POWER_DISABLE, DISABLE_BITS },
> > + { PIPE_REG_150, PIPE_TX_BIAS_EN, PIPE_TX_BIAS_EN },
> > + { PIPE_REG_080, PIPE_TX_COMMON_MODE_DIS, DISABLE_BITS },
> > + { PIPE_REG_0C0, PIPE_TX_OBS_EN, PIPE_TX_OBS_EN },
> > + { PIPE_REG_0C0, PIPE_RX_CM_EN, PIPE_RX_CM_EN },
> > +};
> > +
> > +static int rockchip_usb3phy_reset(struct rockchip_usb3phy *usb3phy,
> > + bool reset, enum rockchip_usb3phy_type type)
> > +{
> > + if (reset) {
> > + if (type == USB3PHY_TYPE_USB2) {
> > + clk_disable_unprepare(usb3phy->clk_otg);
> > + reset_control_assert(usb3phy->utmi_rst);
> > + reset_control_assert(usb3phy->u2por_rst);
> > + }
> > + if (type == USB3PHY_TYPE_USB3) {
> > + clk_disable_unprepare(usb3phy->clk_pipe);
> > + reset_control_assert(usb3phy->pipe_rst);
> > + reset_control_assert(usb3phy->u3por_rst);
> > + }
> > + } else {
> > + if (type == USB3PHY_TYPE_USB2) {
> > + reset_control_deassert(usb3phy->u2por_rst);
> > + fsleep(1000);
> > + clk_prepare_enable(usb3phy->clk_otg);
> > + fsleep(500);
> > + reset_control_deassert(usb3phy->utmi_rst);
> > + fsleep(100);
> > + }
> > + if (type == USB3PHY_TYPE_USB3) {
> > + reset_control_deassert(usb3phy->u3por_rst);
> > + fsleep(500);
> > + clk_prepare_enable(usb3phy->clk_pipe);
> > + fsleep(1000);
> > + reset_control_deassert(usb3phy->pipe_rst);
> > + fsleep(100);
> > + }
> > + }
> > + return 0;
> > +}
> > +
> > +static irqreturn_t rockchip_usb3phy_linestate_irq(int irq, void *data)
> > +{
> > + struct rockchip_usb3phy *usb3phy = data;
> > + int tmp;
> > +
> > + /* check if the interrupt is enabled */
> > + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
> > + if (!(tmp & USB3_LINESTATE_IRQ_EN)) {
> > + dev_warn(usb3phy->dev, "invalid linestate irq received\n");
> > + return IRQ_NONE;
> > + }
> > +
> > + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
> > + if (tmp & USB3_LINESTATE_IRQ_EN)
> > + dev_dbg_ratelimited(usb3phy->dev, "linestate irq received\n");
> > +
> > + /* clear the interrupt */
> > + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_LINESTATE_IRQ_EN);
> > +
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static irqreturn_t rockchip_usb3phy_bvalid_irq(int irq, void *data)
> > +{
> > + struct rockchip_usb3phy *usb3phy = data;
> > + int tmp;
> > +
> > + /* check if the interrupt is enabled */
> > + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
> > + if (!((tmp & USB3_BVALID_FALL_IRQ_EN) | (tmp & USB3_BVALID_RISE_IRQ_EN))) {
> > + dev_warn_ratelimited(usb3phy->dev, "invalid bvalid irq received\n");
> > + return IRQ_NONE;
> > + }
> > +
> > + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
> > + if (tmp & USB3_BVALID_FALL_IRQ_EN)
> > + dev_dbg(usb3phy->dev, "bvalid falling irq received\n");
> > + if (tmp & USB3_BVALID_RISE_IRQ_EN)
> > + dev_dbg(usb3phy->dev, "bvalid rising irq received\n");
> > +
> > + /* clear the interrupt */
> > + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_BVALID_CLEAR_MASK);
> > +
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static irqreturn_t rockchip_usb3phy_id_irq(int irq, void *data)
> > +{
> > + struct rockchip_usb3phy *usb3phy = data;
> > + int tmp;
> > +
> > + /* check if the interrupt is enabled */
> > + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
> > + if (!((tmp & USB3_ID_FALL_IRQ_EN) | (tmp & USB3_ID_RISE_IRQ_EN))) {
> > + dev_warn(usb3phy->dev, "invalid id irq received\n");
> > + return IRQ_NONE;
> > + }
> > +
> > + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
> > + if (tmp & USB3_ID_FALL_IRQ_EN)
> > + dev_dbg(usb3phy->dev, "id falling irq received\n");
> > + if (tmp & USB3_ID_RISE_IRQ_EN)
> > + dev_dbg(usb3phy->dev, "id rising irq received\n");
> > +
> > + /* clear the interrupt */
> > + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_ID_CLEAR_MASK);
> > +
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static irqreturn_t rockchip_usb3phy_rxdet_irq(int irq, void *data)
> > +{
> > + struct rockchip_usb3phy *usb3phy = data;
> > + int tmp;
> > +
> > + /* check if the interrupt is enabled */
> > + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, &tmp);
> > + if (!(tmp & USB3_RXDET_IRQ_EN)) {
> > + dev_warn(usb3phy->dev, "invalid rxdet irq received\n");
> > + return IRQ_NONE;
> > + }
> > +
> > + regmap_read(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, &tmp);
> > + if (tmp & USB3_RXDET_IRQ_EN)
> > + dev_dbg_ratelimited(usb3phy->dev, "rxdet irq received\n");
> > +
> > + /* clear the interrupt */
> > + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_STAT_REG, USB3_RXDET_IRQ_EN);
> > +
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static int rockchip_usb3phy_bulk_update(struct rockchip_usb3phy *usb3phy, struct regmap *regmap,
> > + const struct usb3phy_config *config, unsigned int size)
> > +{
> > + unsigned int i, val, tmp;
> > + int ret = 0;
> > +
> > + for (i = 0; i < size; i++) {
> > + ret = regmap_read(regmap, config[i].reg, &val);
> > + if (ret < 0) {
> > + dev_err(usb3phy->dev, "failed to read addr: 0x%02x\n", config[i].reg);
> > + return ret;
> > + }
> > + tmp = val & ~config[i].mask;
> > + tmp |= config[i].def;
> > + dev_dbg(usb3phy->dev, "write: 0x%03x old: 0x%02x new: 0x%02x\n",
> > + config[i].reg, val, tmp);
> > + ret = regmap_write(regmap, config[i].reg, tmp);
> > + if (ret < 0) {
> > + dev_err(usb3phy->dev, "failed to write addr: 0x%02x\n", config[i].reg);
> > + return ret;
> > + }
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static int rockchip_usb3phy_calc_rate(struct rockchip_usb3phy *usb3phy, struct regmap *regmap)
> > +{
> > + long rate;
> > + unsigned int mul, div, target = (5000000000 / 100000);
> > +
> > + rate = clk_get_rate(usb3phy->clk_ref) / 100000;
> > + if (rate < 0) {
> > + dev_err(usb3phy->dev, "failed to get refclk, %ld\n", rate);
> > + return rate;
> > + /* lowest possible supported clock is 4.8MHZ, highest rk3328 can do is 1.6GHZ */
> > + } else if ((rate < 48) | (rate > 16000)) {
> > + goto error;
> > + }
> > +
> > + for (div = 1; div < 32; div++) {
> > + for (mul = 1; mul < 1024; mul++) {
> > + if (((2 * rate * mul) / div) == target)
> > + goto done;
> > + if (((2 * rate * mul) / div) > target)
> > + break;
> > + }
> > + }
> > +
> > +error:
> > + dev_err(usb3phy->dev, "invalid refclock rate, %ld\n", rate * 100000);
> > + return -EINVAL;
> > +
> > +done:
> > + dev_dbg(usb3phy->dev, "refclk rate mul: %x div: %x rate: %ld\n", mul, div, (rate * 100000));
> > +
> > + regmap_write(regmap, PIPE_REG_020, (mul >> 2) & PIPE_RX_CDR_MULT_HIGH_MASK);
> > + regmap_write(regmap, PIPE_REG_020, div & PIPE_TX_PLL_DIV_MASK);
> > + regmap_write(regmap, PIPE_REG_028, mul & PIPE_RX_CDR_MULT_LOW_MASK);
> > + regmap_write(regmap, PIPE_REG_030, div & PIPE_RX_CDR_DIV_MASK);
> > + regmap_write(regmap, PIPE_REG_118, (mul >> 8) & PIPE_TX_PLL_MUL_HIGH_MASK);
> > + regmap_write(regmap, PIPE_REG_11C, mul & PIPE_TX_PLL_MUL_LOW_MASK);
> > +
> > + return 0;
> > +}
> > +
> > +static int rockchip_usb3phy_init(struct phy *phy)
> > +{
> > + struct rockchip_usb3phy_port *port = phy_get_drvdata(phy);
> > + struct rockchip_usb3phy *usb3phy = dev_get_drvdata(phy->dev.parent);
> > + int tmp, ret;
> > +
> > + dev_warn(usb3phy->dev, "usb3phy_init %s\n", dev_name(&phy->dev));
> > + clk_prepare_enable(usb3phy->clk_ref);
> > + rockchip_usb3phy_reset(usb3phy, false, port->type);
> > +
> > + if (port->type == USB3PHY_TYPE_USB2) {
> > + /*
> > + * "For RK3328 SoC, pre-emphasis and pre-emphasis strength must be
> > + * written as one fixed value. The ODT 45ohm value should be tuned
> > + * for different boards to adjust HS eye height."
> > + */
> > + dev_dbg(usb3phy->dev, "tuning UTMI\n");
> > + ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_utmi_config,
> > + ARRAY_SIZE(rk3328_utmi_config));
> > + }
> > +
> > + if (port->type == USB3PHY_TYPE_USB3) {
> > + /* Enable interrupts */
> > + tmp = (USB3_LINESTATE_IRQ_EN | USB3_ID_FALL_IRQ_EN | USB3_ID_RISE_IRQ_EN |
> > + USB3_RXDET_IRQ_EN | USB3_BVALID_RISE_IRQ_EN | USB3_BVALID_FALL_IRQ_EN);
> > + tmp |= (tmp << REG_WRITE_SHIFT);
> > +
> > + ret = regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG, tmp);
> > + if (ret < 0) {
> > + /* interrupt write determines if we have write access */
> > + dev_err(usb3phy->dev, "failed to write interrupts\n");
> > + return ret;
> > + }
> > +
> > + /* Configure for 24M ref clk */
> > + dev_dbg(usb3phy->dev, "setting pipe for 24M refclk\n");
> > + if (rockchip_usb3phy_calc_rate(usb3phy, usb3phy->regmap))
> > + return -EINVAL;
> > +
> > + /* Enable SSC */
> > + udelay(3);
> > + dev_dbg(usb3phy->dev, "setting pipe for SSC\n");
> > + ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_ssc_config,
> > + ARRAY_SIZE(rk3328_ssc_config));
> > +
> > + /* "Tuning RX for compliance RJTL test" */
> > + dev_dbg(usb3phy->dev, "setting pipe for RX tuning\n");
> > + ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_rx_config,
> > + ARRAY_SIZE(rk3328_rx_config));
> > + if (ret)
> > + return ret;
> > +
> > + /*
> > + * "Tuning TX to increase the bias current used in TX driver and RX EQ,
> > + * it can also increase the voltage of LFPS."
> > + */
> > + dev_dbg(usb3phy->dev, "setting pipe for TX tuning\n");
> > + ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap,
> > + rk3328_tx_config, ARRAY_SIZE(rk3328_tx_config));
> > +
> > + /* Power up the pipe */
> > + dev_dbg(usb3phy->dev, "setting pipe power on\n");
> > + ret = rockchip_usb3phy_bulk_update(usb3phy, port->regmap, rk3328_pipe_pwr_en_config,
> > + ARRAY_SIZE(rk3328_pipe_pwr_en_config));
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int rockchip_usb3phy_parse_dt(struct rockchip_usb3phy *usb3phy, struct device *dev)
> > +{
> > + int ret;
> > +
> > + usb3phy->clk_pipe = devm_clk_get(dev, "usb3phy-pipe");
> > + if (IS_ERR(usb3phy->clk_pipe)) {
> > + dev_err(dev, "could not get usb3phy pipe clock\n");
> > + return PTR_ERR(usb3phy->clk_pipe);
> > + }
> > +
> > + usb3phy->clk_otg = devm_clk_get(dev, "usb3phy-otg");
> > + if (IS_ERR(usb3phy->clk_otg)) {
> > + dev_err(dev, "could not get usb3phy otg clock\n");
> > + return PTR_ERR(usb3phy->clk_otg);
> > + }
> > +
> > + usb3phy->clk_ref = devm_clk_get(dev, "refclk-usb3otg");
> > + if (IS_ERR(usb3phy->clk_ref)) {
> > + dev_err(dev, "could not get usb3phy ref clock\n");
> > + return PTR_ERR(usb3phy->clk_ref);
> > + }
> > +
> > + usb3phy->u2por_rst = devm_reset_control_get(dev, "usb3phy-u2-por");
> > + if (IS_ERR(usb3phy->u2por_rst)) {
> > + dev_err(dev, "no usb3phy-u2-por reset control found\n");
> > + return PTR_ERR(usb3phy->u2por_rst);
> > + }
> > +
> > + usb3phy->u3por_rst = devm_reset_control_get(dev, "usb3phy-u3-por");
> > + if (IS_ERR(usb3phy->u3por_rst)) {
> > + dev_err(dev, "no usb3phy-u3-por reset control found\n");
> > + return PTR_ERR(usb3phy->u3por_rst);
> > + }
> > +
> > + usb3phy->pipe_rst = devm_reset_control_get(dev, "usb3phy-pipe-mac");
> > + if (IS_ERR(usb3phy->pipe_rst)) {
> > + dev_err(dev, "no usb3phy_pipe_mac reset control found\n");
> > + return PTR_ERR(usb3phy->pipe_rst);
> > + }
> > +
> > + usb3phy->utmi_rst = devm_reset_control_get(dev, "usb3phy-utmi-mac");
> > + if (IS_ERR(usb3phy->utmi_rst)) {
> > + dev_err(dev, "no usb3phy-utmi-mac reset control found\n");
> > + return PTR_ERR(usb3phy->utmi_rst);
> > + }
> > +
> > + usb3phy->pipe_apb_rst = devm_reset_control_get(dev, "usb3phy-pipe-apb");
> > + if (IS_ERR(usb3phy->pipe_apb_rst)) {
> > + dev_err(dev, "no usb3phy-pipe-apb reset control found\n");
> > + return PTR_ERR(usb3phy->pipe_apb_rst);
> > + }
> > +
> > + usb3phy->utmi_apb_rst = devm_reset_control_get(dev, "usb3phy-utmi-apb");
> > + if (IS_ERR(usb3phy->utmi_apb_rst)) {
> > + dev_err(dev, "no usb3phy-utmi-apb reset control found\n");
> > + return PTR_ERR(usb3phy->utmi_apb_rst);
> > + }
> > +
> > + usb3phy->ls_irq = of_irq_get_byname(dev->of_node, "linestate");
> > + if (usb3phy->ls_irq < 0) {
> > + dev_err(dev, "no linestate irq provided\n");
> > + return usb3phy->ls_irq;
> > + }
> > +
> > + ret = devm_request_threaded_irq(dev, usb3phy->ls_irq, NULL, rockchip_usb3phy_linestate_irq,
> > + IRQF_ONESHOT, "rockchip_usb3phy_ls", usb3phy);
> > + if (ret) {
> > + dev_err(dev, "failed to request linestate irq handle\n");
> > + return ret;
> > + }
> > +
> > + usb3phy->bvalid_irq = of_irq_get_byname(dev->of_node, "bvalid");
> > + if (usb3phy->bvalid_irq < 0) {
> > + dev_err(dev, "no bvalid irq provided\n");
> > + return usb3phy->bvalid_irq;
> > + }
> > +
> > + ret = devm_request_threaded_irq(dev, usb3phy->bvalid_irq, NULL, rockchip_usb3phy_bvalid_irq,
> > + IRQF_ONESHOT, "rockchip_usb3phy_bvalid", usb3phy);
> > + if (ret) {
> > + dev_err(dev, "failed to request bvalid irq handle\n");
> > + return ret;
> > + }
> > +
> > + usb3phy->id_irq = of_irq_get_byname(dev->of_node, "id");
> > + if (usb3phy->id_irq < 0) {
> > + dev_err(dev, "no id irq provided\n");
> > + return usb3phy->id_irq;
> > + }
> > +
> > + ret = devm_request_threaded_irq(dev, usb3phy->id_irq, NULL, rockchip_usb3phy_id_irq,
> > + IRQF_ONESHOT, "rockchip_usb3phy-id", usb3phy);
> > + if (ret) {
> > + dev_err(dev, "failed to request id irq handle\n");
> > + return ret;
> > + }
> > +
> > + usb3phy->rxdet_irq = of_irq_get_byname(dev->of_node, "rxdet");
> > + if (usb3phy->rxdet_irq < 0) {
> > + dev_err(dev, "no rxdet irq provided\n");
> > + return usb3phy->rxdet_irq;
> > + }
> > +
> > + ret = devm_request_threaded_irq(dev, usb3phy->rxdet_irq, NULL, rockchip_usb3phy_rxdet_irq,
> > + IRQF_ONESHOT, "rockchip_usb3phy-rxdet", usb3phy);
> > + if (ret) {
> > + dev_err(dev, "failed to request rxdet irq handle\n");
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int rockchip_usb3phy_exit(struct phy *phy)
> > +{
> > + struct rockchip_usb3phy_port *port = phy_get_drvdata(phy);
> > + struct rockchip_usb3phy *usb3phy = dev_get_drvdata(phy->dev.parent);
> > +
> > + dev_dbg(usb3phy->dev, "usb3phy_shutdown\n");
> > + rockchip_usb3phy_reset(usb3phy, true, port->type);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct phy_ops rockchip_usb3phy_ops = {
> > + .init = rockchip_usb3phy_init,
> > + .exit = rockchip_usb3phy_exit,
> > + .owner = THIS_MODULE,
> > +};
> > +
> > +static const struct regmap_config rockchip_usb3phy_utmi_port_regmap_config = {
> > + .reg_bits = 32,
> > + .val_bits = 32,
> > + .reg_stride = 4,
> > + .max_register = 0x400,
> > + .cache_type = REGCACHE_NONE,
> > + .fast_io = true,
> > + .name = "utmi-port",
> > +};
> > +
> > +static const struct regmap_config rockchip_usb3phy_pipe_port_regmap_config = {
> > + .reg_bits = 32,
> > + .val_bits = 32,
> > + .reg_stride = 4,
> > + .max_register = 0x400,
> > + .cache_type = REGCACHE_NONE,
> > + .fast_io = true,
> > + .name = "pipe-port",
> > +};
> > +
> > +static const struct regmap_config rockchip_usb3phy_regmap_config = {
> > + .reg_bits = 32,
> > + .val_bits = 32,
> > + .reg_stride = 4,
> > + .max_register = 0x400,
> > + .write_flag_mask = REG_WRITE_MASK,
> > + .cache_type = REGCACHE_NONE,
> > + .fast_io = true,
> > +};
> > +
> > +static int rockchip_usb3phy_probe(struct platform_device *pdev)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct device_node *np = dev->of_node;
> > + struct device_node *child_np;
> > + struct phy_provider *provider;
> > + struct rockchip_usb3phy *usb3phy;
> > + const struct regmap_config regmap_config = rockchip_usb3phy_regmap_config;
> > + void __iomem *base;
> > + int i, ret;
> > +
> > + dev_dbg(dev, "Probe usb3phy main block\n");
> > + usb3phy = devm_kzalloc(dev, sizeof(*usb3phy), GFP_KERNEL);
> > + if (!usb3phy)
> > + return -ENOMEM;
> > +
> > + ret = rockchip_usb3phy_parse_dt(usb3phy, dev);
> > + if (ret) {
> > + dev_err(dev, "parse dt failed %i\n", ret);
> > + return ret;
> > + }
> > +
> > + base = devm_of_iomap(dev, np, 0, NULL);
> > + if (IS_ERR(base)) {
> > + dev_err(dev, "failed port ioremap\n");
> > + return PTR_ERR(base);
> > + }
> > +
> > + usb3phy->regmap = devm_regmap_init_mmio(dev, base, ®map_config);
> > + if (IS_ERR(usb3phy->regmap)) {
> > + dev_err(dev, "regmap init failed\n");
> > + return PTR_ERR(usb3phy->regmap);
> > + }
> > +
> > + usb3phy->dev = dev;
> > + platform_set_drvdata(pdev, usb3phy);
> > +
> > + /* place block in reset */
> > + reset_control_assert(usb3phy->pipe_rst);
> > + reset_control_assert(usb3phy->utmi_rst);
> > + reset_control_assert(usb3phy->u3por_rst);
> > + reset_control_assert(usb3phy->u2por_rst);
> > + reset_control_assert(usb3phy->pipe_apb_rst);
> > + reset_control_assert(usb3phy->utmi_apb_rst);
> > +
> > + fsleep(20);
> > +
> > + /* take apb interface out of reset */
> > + reset_control_deassert(usb3phy->utmi_apb_rst);
> > + reset_control_deassert(usb3phy->pipe_apb_rst);
> > +
> > + /* enable usb3phy rx detection to fix disconnection issues */
> > + regmap_write(usb3phy->regmap, USB3PHY_WAKEUP_CON_REG,
> > + (USB3_RXDET_EN | (USB3_RXDET_EN << REG_WRITE_SHIFT)));
> > +
> > + dev_dbg(dev, "Completed usb3phy core probe\n");
> > +
> > + /* probe the actual ports */
> > + i = 0;
> > + for_each_available_child_of_node(np, child_np) {
> > + const struct regmap_config *regmap_port_config;
> > + struct rockchip_usb3phy_port *port = &usb3phy->ports[i];
> > + struct phy *phy;
> > +
> > + if (of_node_name_eq(child_np, "utmi-port")) {
> > + port->type = USB3PHY_TYPE_USB2;
> > + regmap_port_config = &rockchip_usb3phy_utmi_port_regmap_config;
> > + } else if (of_node_name_eq(child_np, "pipe-port")) {
> > + port->type = USB3PHY_TYPE_USB3;
> > + regmap_port_config = &rockchip_usb3phy_pipe_port_regmap_config;
> > + } else {
> > + dev_err(dev, "unknown child node port type %s\n", child_np->name);
> > + goto err_port;
> > + }
> > +
> > + base = devm_of_iomap(dev, child_np, 0, NULL);
> > + if (IS_ERR(base)) {
> > + dev_err(dev, "failed port ioremap\n");
> > + ret = PTR_ERR(base);
> > + goto err_port;
> > + }
> > +
> > + port->regmap = devm_regmap_init_mmio(dev, base, regmap_port_config);
> > + if (IS_ERR(port->regmap)) {
> > + dev_err(dev, "regmap init failed\n");
> > + ret = PTR_ERR(port->regmap);
> > + goto err_port;
> > + }
> > +
> > + phy = devm_phy_create(dev, child_np, &rockchip_usb3phy_ops);
> > + if (IS_ERR(phy)) {
> > + dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
> > + ret = PTR_ERR(phy);
> > + goto err_port;
> > + }
> > +
> > + port->phy = phy;
> > + phy_set_drvdata(port->phy, port);
> > +
> > + /* to prevent out of boundary */
> > + if (++i >= USB3PHY_TYPE_MAX) {
> > + of_node_put(child_np);
> > + break;
> > + }
> > +
> > + dev_info(dev, "Completed usb3phy %s port init\n", child_np->name);
> > + }
> > +
> > + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > + return PTR_ERR_OR_ZERO(provider);
> > +
> > +err_port:
> > + of_node_put(child_np);
> > + return ret;
> > +}
> > +
> > +static const struct of_device_id rockchip_usb3phy_dt_ids[] = {
> > + { .compatible = "rockchip,rk3328-usb3phy", },
> > +};
>
> isn’t { /* sentinel */ } missing here?
Yes, there should be. Thank you.
>
>
> > +
> > +MODULE_DEVICE_TABLE(of, rockchip_usb3phy_dt_ids);
> > +
> > +static struct platform_driver rockchip_usb3phy_driver = {
> > + .probe = rockchip_usb3phy_probe,
> > + .driver = {
> > + .name = "rockchip-usb3-phy",
> > + .of_match_table = rockchip_usb3phy_dt_ids,
> > + },
> > +};
> > +
> > +module_platform_driver(rockchip_usb3phy_driver);
> > +
> > +MODULE_AUTHOR("Peter Geis <pgwipeout@gmail.com>");
> > +MODULE_DESCRIPTION("Rockchip Innosilicon USB3PHY driver");
> > +MODULE_LICENSE("GPL");
> > --
> > 2.39.5
> >
> >
> > _______________________________________________
> > Linux-rockchip mailing list
> > Linux-rockchip@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-16 14:02 ` Peter Geis
@ 2025-01-16 14:35 ` Piotr Oniszczuk
2025-01-16 16:00 ` Peter Geis
0 siblings, 1 reply; 44+ messages in thread
From: Piotr Oniszczuk @ 2025-01-16 14:35 UTC (permalink / raw)
To: Peter Geis
Cc: Heiko Stuebner, Algea Cao, Michael Turquette, kever.yang,
linux-phy, wulf, zyw, Dragan Simic, Kishon Vijay Abraham I,
Rob Herring, Sebastian Reichel, linux-clk, linux-rockchip,
devicetree, Conor Dooley, Philipp Zabel, Arnd Bergmann,
Jonas Karlman, frank.wang, Elaine Zhang, Alex Bee, william.wu,
Zhang Yubing, Johan Jonker, linux-arm-kernel, Trevor Woerner,
Stephen Boyd, linux-kernel, Vinod Koul, FUKAUMI Naoki,
Diederik de Haas, Krzysztof Kozlowski
> Wiadomość napisana przez Peter Geis <pgwipeout@gmail.com> w dniu 16 sty 2025, o godz. 15:02:
>
>>
>
> I'm at a loss here, I applied the patches to a clean 6.9 tree and even
>>
oh maybe issue is in kernel age?
6.9 seems a bit quite old.
i’m on 6.12.9….
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 3/6] phy: rockchip: add driver for rk3328 usb3 phy
2025-01-15 1:26 ` [RFC PATCH v1 3/6] phy: rockchip: add driver for " Peter Geis
2025-01-15 11:24 ` Piotr Oniszczuk
2025-01-16 12:59 ` Krzysztof Kozlowski
@ 2025-01-16 15:26 ` Diederik de Haas
2025-01-16 15:57 ` Peter Geis
2 siblings, 1 reply; 44+ messages in thread
From: Diederik de Haas @ 2025-01-16 15:26 UTC (permalink / raw)
To: Peter Geis, Heiko Stuebner
Cc: Kishon Vijay Abraham I, Algea Cao, linux-kernel, Philipp Zabel,
Arnd Bergmann, frank.wang, william.wu, kever.yang, linux-phy,
Sebastian Reichel, linux-rockchip, Vinod Koul, Zhang Yubing, zyw,
wulf, linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 11596 bytes --]
Hi Peter,
Thanks for working on this :-)
On Wed Jan 15, 2025 at 2:26 AM CET, Peter Geis wrote:
> The rk3328 has a combined usb2 and usb3 phy block for the usb3 dwc
> interface. The implementation up until now has been bugged, with
> multiple issues ranging from disconnect detection failures to low
> performance. This driver fixes the majority of the original issues and
> allows better performance for the rk3328 usb3 port.
>
> This driver sources data from multiple sources, including the rk3328
> trm, the rk3228h trm, emails from Rockchip, and both the 4.4 and 5.10
> downstream drivers. The current implementation allows for basic bring up
> of the phy block and fixes the detection issues. Interrupts are enabled,
> but currently only used for debugging. Features missing currently are
> power management, OTG handling, board specific tuning, regulator control,
>
> Currently the only known bugs are a AX88179 usb3 gigabit adapter crashes
> when operating at usb3 speeds and transmitting large amounts of data and
> full disconnection detections may be slower than expected (~5-10 seconds).
>
> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> ---
>
> drivers/phy/rockchip/Kconfig | 10 +
> drivers/phy/rockchip/Makefile | 1 +
> drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 869 ++++++++++++++++++
> 3 files changed, 880 insertions(+)
> create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c
>
> diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
> index 2f7a05f21dc5..aac623e84f96 100644
> --- a/drivers/phy/rockchip/Kconfig
> +++ b/drivers/phy/rockchip/Kconfig
> @@ -48,6 +48,16 @@ config PHY_ROCKCHIP_INNO_USB2
> help
> Support for Rockchip USB2.0 PHY with Innosilicon IP block.
>
> +config PHY_ROCKCHIP_INNO_USB3
> + tristate "Rockchip INNO USB3PHY Driver"
> + depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
> + depends on COMMON_CLK
> + depends on USB_SUPPORT
> + select GENERIC_PHY
> + select USB_COMMON
> + help
> + Support for Rockchip USB3.0 PHY with Innosilicon IP block.
> +
> config PHY_ROCKCHIP_INNO_CSIDPHY
> tristate "Rockchip Innosilicon MIPI CSI PHY driver"
> depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
> diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
> index 010a824e32ce..ec15dcf37fba 100644
> --- a/drivers/phy/rockchip/Makefile
> +++ b/drivers/phy/rockchip/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY) += phy-rockchip-inno-csidphy.o
> obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o
> obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
> obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
> +obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB3) += phy-rockchip-inno-usb3.o
> obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o
> obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
> obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX) += phy-rockchip-samsung-hdptx.o
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb3.c b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> new file mode 100644
> index 000000000000..51b9f3b7fbfa
> --- /dev/null
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> @@ -0,0 +1,869 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * phy-rockchip-inno-usb3.c - USB3 PHY based on Innosilicon IP as
> + * implemented on Rockchip rk3328. Tuning data magic bits are taken as is
> + * from the downstream driver. Downstream driver is located at:
> + * https://github.com/rockchip-linux/kernel/blob/240a5660d7c23841ccf7b7cc489078bf521b9802/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> + *
> + * Author: Peter Geis <pgwipeout@gmail.com>
> + * TODO:
> + * - Find the rest of the register names / definitions.
> + * - Implement pm functions.
> + * - Implement board specific tuning from dts.
> + * - Implement regulator control.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/usb/of.h>
> +
> +#define REG_WRITE_MASK GENMASK(31, 16)
> +#define REG_WRITE_SHIFT 16
> +#define DISABLE_BITS 0x0
> +
> +/* USB3PHY GRF Registers */
> +#define USB3PHY_WAKEUP_CON_REG 0x40
> +#define USB3PHY_WAKEUP_STAT_REG 0x44
> +#define USB3_LINESTATE_IRQ_EN BIT(0)
> +#define USB3_RXDET_IRQ_EN BIT(1)
> +#define USB3_BVALID_RISE_IRQ_EN BIT(2)
> +#define USB3_BVALID_FALL_IRQ_EN BIT(3)
> +#define USB3_BVALID_CLEAR_MASK GENMASK(3, 2)
> +#define USB3_ID_RISE_IRQ_EN BIT(4)
> +#define USB3_ID_FALL_IRQ_EN BIT(5)
> +#define USB3_ID_CLEAR_MASK GENMASK(5, 4)
> +#define USB3_RXDET_EN BIT(6)
> +
> +/* PIPE registers */
> +/* 0x08 for SSC, default 0x0e */
> +#define UNKNOWN_PIPE_REG_000 0x000
> +#define UNKNOWN_SSC_000_MASK GENMASK(2, 1)
> +#define UNKNOWN_SSC_000_ENABLE (0x00 << 1)
> +
> +/* 0x83 for 24m, 0x01 for 25m, default 0x86 */
> +#define PIPE_REG_020 0x020
> +/* RX CDR multiplier high bits [7:6], as P, default 0x2, RX data rate = (2*refclk*P)/Q */
> +#define PIPE_RX_CDR_MULT_HIGH_MASK GENMASK(7, 6)
> +/* TX PLL divider bits [4:0], as N, default 0x6, TX data rate = (2*refclk*M)/N */
> +#define PIPE_TX_PLL_DIV_MASK GENMASK(4, 0)
> +
> +/* 0x71 for 24m, 0x64 for 25m, default 0x71 */
> +#define PIPE_REG_028 0x028
> +/* RX CDR multiplier low bits [7:0], as P, default 0x71, RX data rate = (2*refclk*P)/Q */
> +#define PIPE_RX_CDR_MULT_LOW_MASK GENMASK(7, 0)
> +
> +/* 0x26 for 24m?, 0x21 for 25m, default 0x26 */
> +#define PIPE_REG_030 0x030
> +/* RX CDR divider bits [4:0], as Q, default 0x6, RX data rate = (2*refclk*P)/Q */
> +#define PIPE_RX_CDR_DIV_MASK GENMASK(4, 0)
> +
> +/* 1'b1 Disable bandgap power, default 0x00 */
> +#define PIPE_REG_044 0x044
> +#define BANDGAP_POWER_DISABLE BIT(4)
> +
> +/* 0xe0 for rx tune?, default 0xe1 */
> +#define PIPE_REG_060 0x060
> +#define PIPE_TX_DETECT_BYPASS_DEBUG BIT(4) /* enable to always force detection */
> +/* RX CTLE frequency bandwidth response tuning bits [1:0], default 0x1 */
> +#define PIPE_RX_CTLE_FREQ_BW_MASK GENMASK(1, 0)
> +#define PIPE_RX_CTLE_FREQ_BW_TUNE 0x0
> +
> +/* default 0x49 */
> +#define PIPE_REG_064 0x064
> +/* RX equalizer tail current control bits [6:4], default 0x4 */
> +#define PIPE_RX_EQ_TAIL_CURR_MASK GENMASK(6, 4)
> +
> +/* 0x08 for rx tune?, default 0x07 */
> +#define PIPE_REG_068 0x068
> +/* RX equalizer low frequency gain control bits [7:4], default 0x0 */
> +#define PIPE_RX_EQ_LOW_GAIN_MASK GENMASK(7, 4)
> +#define PIPE_RX_EQ_LOW_GAIN_TUNE (0x1 << 4)
> +/* RX CTLE gain tuning bits [3:0], higher = more gain default 0x7 */
> +#define PIPE_RX_CTLE_GAIN_MASK GENMASK(3, 0)
> +#define PIPE_RX_CTLE_GAIN_TUNE 0x7 /* 0x5 lowest functional value, 0xf highest */
> +
> +/* RX ODT manual resistance config, higher = less resistance, depends on REG_1C4 BIT(5) set */
> +#define PIPE_REG_06C 0x06c
> +/* RX ODT manual resistance high bits [3:0], default 0x0 */
> +#define PIPE_RX_ODT_RES_HIGH_MASK GENMASK(3, 0)
> +#define PIPE_RX_ODT_RES_HIGH_TUNE 0xf
> +
> +#define PIPE_REG_070 0x070
> +/* RX ODT manual resistance mid bits [7:0], default 0x03 */
> +#define PIPE_RX_ODT_RES_MID_MASK GENMASK(7, 0)
> +#define PIPE_RX_ODT_RES_MID_TUNE 0xff
> +
> +#define PIPE_REG_074 0x074
> +/* RX ODT manual resistance low bits [7:0], default 0xff */
> +#define PIPE_RX_ODT_RES_LOW_MASK GENMASK(7, 0)
> +#define PIPE_RX_ODT_RES_LOW_TUNE 0xff
> +
> +/* default 0x08 */
> +#define PIPE_REG_080 0x080
> +#define PIPE_TX_COMMON_MODE_DIS BIT(2) /* 1'b1 disable TX common type */
> +
> +/* default 0x33 */
> +#define PIPE_REG_088 0x088
> +#define PIPE_TX_DRIVER_PREEMP_EN BIT(4) /* 1'b1 enable pre-emphasis */
> +
> +/* default 0x18 */
> +#define PIPE_REG_0C0 0x0c0
> +#define PIPE_RX_CM_EN BIT(3) /* 1'b1 enable RX CM */
> +#define PIPE_TX_OBS_EN BIT(4) /* 1'b1 enable TX OBS */
> +
> +/* 0x12 for rx tune?, default 0x14 */
> +#define PIPE_REG_0C8 0x0c8
> +/* RX CDR charge pump current bits [3:1], default 0x2 */
> +#define PIPE_RX_CDR_CHG_PUMP_MASK GENMASK(3, 1)
> +#define PIPE_RX_CDR_CHG_PUMP_TUNE (0x2 << 1)
> +
> +/* 0x02 for 24m, 0x06 for 25m, default 0x06 */
> +#define UNKNOWN_PIPE_REG_108 0x108
> +#define UNKNOWN_REFCLK_108_24M 0x02
> +
> +/* 0x80 for 24m, default 0x00 */
> +#define UNKNOWN_PIPE_REG_10C 0x10c
> +#define UNKNOWN_REFCLK_10C_24M BIT(7)
> +
> +/* 0x01 for 24m, 0x00 for 25m, default 0x02 */
> +#define PIPE_REG_118 0x118
> +/* TX PLL multiplier high bits [3:0], as M, default 0x2, TX data rate = (2*refclk*M)/N */
> +#define PIPE_TX_PLL_MUL_HIGH_MASK GENMASK(3, 0)
> +
> +/* 0x38 for 24m, 0x64 for 25m, default 0x71 */
> +#define PIPE_REG_11C 0x11c
> +/* TX PLL multiplier low bits [7:0], as M, default 0x71, TX data rate = (2*refclk*M)/N */
> +#define PIPE_TX_PLL_MUL_LOW_MASK GENMASK(7, 0)
> +
> +/* 0x0c for SSC, default 0x1c */
> +#define UNKNOWN_PIPE_REG_120 0x120
> +#define UNKNOWN_SSC_120_MASK BIT(4)
> +#define UNKNOWN_SSC_120_ENABLE (0x0 << 4)
> +
> +/* default 0x40 */
> +#define PIPE_REG_12C 0x12c
> +#define PIPE_TX_PLL_ALWAYS_ON BIT(0) /* disable for PLL control by pipe_pd */
> +
> +/* 0x05 for rx tune, default 0x01 */
> +#define PIPE_REG_148 0x148
> +#define PIPE_RX_CHG_PUMP_DIV_2 BIT(2) /* RX CDR charge pump div/2, default 0 */
> +
> +/* 0x70 for rx tune, default 0x72 */
> +#define PIPE_REG_150 0x150
> +#define PIPE_TX_BIAS_EN BIT(6) /* 1'b1 Enable TX Bias */
> +/* RX CDR phase tracking speed bits [3:0], default 0x2 */
> +#define PIPE_RX_CDR_SPEED_MASK GENMASK(3, 0)
> +#define PIPE_RX_CDR_SPEED_TUNE 0x00
> +
> +/* default 0xd4 */
> +#define PIPE_REG_160
> +/* RX common mode voltage strength bits [5:4], default 0x1 */
> +#define PIPE_RX_CDR_COM_VOLT_MASK GENMASK(5, 4)
> +#define PIPE_RX_CDR_COM_VOLT_TUNE (0x1 << 4)
> +
> +/* default 0x00 */
> +#define PIPE_REG_180 0x180
> +/* TX driver bias reference voltage bits [3:2], in mv */
> +#define PIPE_TX_BIAS_REF_VOLT_MASK GENMASK(3, 2)
> +#define PIPE_TX_BIAS_REF_VOLT_200 (0x0 << 2)
> +#define PIPE_TX_BIAS_REF_VOLT_175 (0x1 << 2)
> +#define PIPE_TX_BIAS_REF_VOLT_225 (0x2 << 2) /* downstream 5.10 driver setting */
> +#define PIPE_TX_BIAS_REF_VOLT_250 (0x3 << 2)
> +
> +/* default 0x01 */
> +#define PIPE_REG_1A8 0x1a8
> +#define PIPE_LDO_POWER_DIS BIT(4) /* 1'b1 Disable LDO Power */
> +
> +/* default 0x07 */
> +#define PIPE_REG_1AC 0x1ac
> +/* TX driver output common voltage bits [5:4], in mv */
> +#define PIPE_TX_COMMON_VOLT_MASK GENMASK(5, 4)
> +#define PIPE_TX_COMMON_VOLT_800 (0x0 << 4)
> +#define PIPE_TX_COMMON_VOLT_750 (0x1 << 4)
> +#define PIPE_TX_COMMON_VOLT_950 (0x2 << 4)
> +#define PIPE_TX_COMMON_VOLT_1100 (0x3 << 4)
Just a question:
In this list as well as the one above it (PIPE_TX_BIAS_xyz) I noticed
the values are not sequential (800, 750, 950, 1100) and (200, 175, 225,
250). Is that correct?
Cheers,
Diederik
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 3/6] phy: rockchip: add driver for rk3328 usb3 phy
2025-01-16 15:26 ` Diederik de Haas
@ 2025-01-16 15:57 ` Peter Geis
0 siblings, 0 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-16 15:57 UTC (permalink / raw)
To: Diederik de Haas
Cc: Heiko Stuebner, Kishon Vijay Abraham I, Algea Cao, linux-kernel,
Philipp Zabel, Arnd Bergmann, frank.wang, william.wu, kever.yang,
linux-phy, Sebastian Reichel, linux-rockchip, Vinod Koul,
Zhang Yubing, zyw, wulf, linux-arm-kernel
On Thu, Jan 16, 2025 at 10:27 AM Diederik de Haas <didi.debian@cknow.org> wrote:
>
> Hi Peter,
>
> Thanks for working on this :-)
>
> On Wed Jan 15, 2025 at 2:26 AM CET, Peter Geis wrote:
> > The rk3328 has a combined usb2 and usb3 phy block for the usb3 dwc
> > interface. The implementation up until now has been bugged, with
> > multiple issues ranging from disconnect detection failures to low
> > performance. This driver fixes the majority of the original issues and
> > allows better performance for the rk3328 usb3 port.
> >
> > This driver sources data from multiple sources, including the rk3328
> > trm, the rk3228h trm, emails from Rockchip, and both the 4.4 and 5.10
> > downstream drivers. The current implementation allows for basic bring up
> > of the phy block and fixes the detection issues. Interrupts are enabled,
> > but currently only used for debugging. Features missing currently are
> > power management, OTG handling, board specific tuning, regulator control,
> >
> > Currently the only known bugs are a AX88179 usb3 gigabit adapter crashes
> > when operating at usb3 speeds and transmitting large amounts of data and
> > full disconnection detections may be slower than expected (~5-10 seconds).
> >
> > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> > ---
> >
> > drivers/phy/rockchip/Kconfig | 10 +
> > drivers/phy/rockchip/Makefile | 1 +
> > drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 869 ++++++++++++++++++
> > 3 files changed, 880 insertions(+)
> > create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> >
> > diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
> > index 2f7a05f21dc5..aac623e84f96 100644
> > --- a/drivers/phy/rockchip/Kconfig
> > +++ b/drivers/phy/rockchip/Kconfig
> > @@ -48,6 +48,16 @@ config PHY_ROCKCHIP_INNO_USB2
> > help
> > Support for Rockchip USB2.0 PHY with Innosilicon IP block.
> >
> > +config PHY_ROCKCHIP_INNO_USB3
> > + tristate "Rockchip INNO USB3PHY Driver"
> > + depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
> > + depends on COMMON_CLK
> > + depends on USB_SUPPORT
> > + select GENERIC_PHY
> > + select USB_COMMON
> > + help
> > + Support for Rockchip USB3.0 PHY with Innosilicon IP block.
> > +
> > config PHY_ROCKCHIP_INNO_CSIDPHY
> > tristate "Rockchip Innosilicon MIPI CSI PHY driver"
> > depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
> > diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
> > index 010a824e32ce..ec15dcf37fba 100644
> > --- a/drivers/phy/rockchip/Makefile
> > +++ b/drivers/phy/rockchip/Makefile
> > @@ -6,6 +6,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY) += phy-rockchip-inno-csidphy.o
> > obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o
> > obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
> > obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
> > +obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB3) += phy-rockchip-inno-usb3.o
> > obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o
> > obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
> > obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX) += phy-rockchip-samsung-hdptx.o
> > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb3.c b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> > new file mode 100644
> > index 000000000000..51b9f3b7fbfa
> > --- /dev/null
> > +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> > @@ -0,0 +1,869 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +
> > +/*
> > + * phy-rockchip-inno-usb3.c - USB3 PHY based on Innosilicon IP as
> > + * implemented on Rockchip rk3328. Tuning data magic bits are taken as is
> > + * from the downstream driver. Downstream driver is located at:
> > + * https://github.com/rockchip-linux/kernel/blob/240a5660d7c23841ccf7b7cc489078bf521b9802/drivers/phy/rockchip/phy-rockchip-inno-usb3.c
> > + *
> > + * Author: Peter Geis <pgwipeout@gmail.com>
> > + * TODO:
> > + * - Find the rest of the register names / definitions.
> > + * - Implement pm functions.
> > + * - Implement board specific tuning from dts.
> > + * - Implement regulator control.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/reset.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/usb/of.h>
> > +
> > +#define REG_WRITE_MASK GENMASK(31, 16)
> > +#define REG_WRITE_SHIFT 16
> > +#define DISABLE_BITS 0x0
> > +
> > +/* USB3PHY GRF Registers */
> > +#define USB3PHY_WAKEUP_CON_REG 0x40
> > +#define USB3PHY_WAKEUP_STAT_REG 0x44
> > +#define USB3_LINESTATE_IRQ_EN BIT(0)
> > +#define USB3_RXDET_IRQ_EN BIT(1)
> > +#define USB3_BVALID_RISE_IRQ_EN BIT(2)
> > +#define USB3_BVALID_FALL_IRQ_EN BIT(3)
> > +#define USB3_BVALID_CLEAR_MASK GENMASK(3, 2)
> > +#define USB3_ID_RISE_IRQ_EN BIT(4)
> > +#define USB3_ID_FALL_IRQ_EN BIT(5)
> > +#define USB3_ID_CLEAR_MASK GENMASK(5, 4)
> > +#define USB3_RXDET_EN BIT(6)
> > +
> > +/* PIPE registers */
> > +/* 0x08 for SSC, default 0x0e */
> > +#define UNKNOWN_PIPE_REG_000 0x000
> > +#define UNKNOWN_SSC_000_MASK GENMASK(2, 1)
> > +#define UNKNOWN_SSC_000_ENABLE (0x00 << 1)
> > +
> > +/* 0x83 for 24m, 0x01 for 25m, default 0x86 */
> > +#define PIPE_REG_020 0x020
> > +/* RX CDR multiplier high bits [7:6], as P, default 0x2, RX data rate = (2*refclk*P)/Q */
> > +#define PIPE_RX_CDR_MULT_HIGH_MASK GENMASK(7, 6)
> > +/* TX PLL divider bits [4:0], as N, default 0x6, TX data rate = (2*refclk*M)/N */
> > +#define PIPE_TX_PLL_DIV_MASK GENMASK(4, 0)
> > +
> > +/* 0x71 for 24m, 0x64 for 25m, default 0x71 */
> > +#define PIPE_REG_028 0x028
> > +/* RX CDR multiplier low bits [7:0], as P, default 0x71, RX data rate = (2*refclk*P)/Q */
> > +#define PIPE_RX_CDR_MULT_LOW_MASK GENMASK(7, 0)
> > +
> > +/* 0x26 for 24m?, 0x21 for 25m, default 0x26 */
> > +#define PIPE_REG_030 0x030
> > +/* RX CDR divider bits [4:0], as Q, default 0x6, RX data rate = (2*refclk*P)/Q */
> > +#define PIPE_RX_CDR_DIV_MASK GENMASK(4, 0)
> > +
> > +/* 1'b1 Disable bandgap power, default 0x00 */
> > +#define PIPE_REG_044 0x044
> > +#define BANDGAP_POWER_DISABLE BIT(4)
> > +
> > +/* 0xe0 for rx tune?, default 0xe1 */
> > +#define PIPE_REG_060 0x060
> > +#define PIPE_TX_DETECT_BYPASS_DEBUG BIT(4) /* enable to always force detection */
> > +/* RX CTLE frequency bandwidth response tuning bits [1:0], default 0x1 */
> > +#define PIPE_RX_CTLE_FREQ_BW_MASK GENMASK(1, 0)
> > +#define PIPE_RX_CTLE_FREQ_BW_TUNE 0x0
> > +
> > +/* default 0x49 */
> > +#define PIPE_REG_064 0x064
> > +/* RX equalizer tail current control bits [6:4], default 0x4 */
> > +#define PIPE_RX_EQ_TAIL_CURR_MASK GENMASK(6, 4)
> > +
> > +/* 0x08 for rx tune?, default 0x07 */
> > +#define PIPE_REG_068 0x068
> > +/* RX equalizer low frequency gain control bits [7:4], default 0x0 */
> > +#define PIPE_RX_EQ_LOW_GAIN_MASK GENMASK(7, 4)
> > +#define PIPE_RX_EQ_LOW_GAIN_TUNE (0x1 << 4)
> > +/* RX CTLE gain tuning bits [3:0], higher = more gain default 0x7 */
> > +#define PIPE_RX_CTLE_GAIN_MASK GENMASK(3, 0)
> > +#define PIPE_RX_CTLE_GAIN_TUNE 0x7 /* 0x5 lowest functional value, 0xf highest */
> > +
> > +/* RX ODT manual resistance config, higher = less resistance, depends on REG_1C4 BIT(5) set */
> > +#define PIPE_REG_06C 0x06c
> > +/* RX ODT manual resistance high bits [3:0], default 0x0 */
> > +#define PIPE_RX_ODT_RES_HIGH_MASK GENMASK(3, 0)
> > +#define PIPE_RX_ODT_RES_HIGH_TUNE 0xf
> > +
> > +#define PIPE_REG_070 0x070
> > +/* RX ODT manual resistance mid bits [7:0], default 0x03 */
> > +#define PIPE_RX_ODT_RES_MID_MASK GENMASK(7, 0)
> > +#define PIPE_RX_ODT_RES_MID_TUNE 0xff
> > +
> > +#define PIPE_REG_074 0x074
> > +/* RX ODT manual resistance low bits [7:0], default 0xff */
> > +#define PIPE_RX_ODT_RES_LOW_MASK GENMASK(7, 0)
> > +#define PIPE_RX_ODT_RES_LOW_TUNE 0xff
> > +
> > +/* default 0x08 */
> > +#define PIPE_REG_080 0x080
> > +#define PIPE_TX_COMMON_MODE_DIS BIT(2) /* 1'b1 disable TX common type */
> > +
> > +/* default 0x33 */
> > +#define PIPE_REG_088 0x088
> > +#define PIPE_TX_DRIVER_PREEMP_EN BIT(4) /* 1'b1 enable pre-emphasis */
> > +
> > +/* default 0x18 */
> > +#define PIPE_REG_0C0 0x0c0
> > +#define PIPE_RX_CM_EN BIT(3) /* 1'b1 enable RX CM */
> > +#define PIPE_TX_OBS_EN BIT(4) /* 1'b1 enable TX OBS */
> > +
> > +/* 0x12 for rx tune?, default 0x14 */
> > +#define PIPE_REG_0C8 0x0c8
> > +/* RX CDR charge pump current bits [3:1], default 0x2 */
> > +#define PIPE_RX_CDR_CHG_PUMP_MASK GENMASK(3, 1)
> > +#define PIPE_RX_CDR_CHG_PUMP_TUNE (0x2 << 1)
> > +
> > +/* 0x02 for 24m, 0x06 for 25m, default 0x06 */
> > +#define UNKNOWN_PIPE_REG_108 0x108
> > +#define UNKNOWN_REFCLK_108_24M 0x02
> > +
> > +/* 0x80 for 24m, default 0x00 */
> > +#define UNKNOWN_PIPE_REG_10C 0x10c
> > +#define UNKNOWN_REFCLK_10C_24M BIT(7)
> > +
> > +/* 0x01 for 24m, 0x00 for 25m, default 0x02 */
> > +#define PIPE_REG_118 0x118
> > +/* TX PLL multiplier high bits [3:0], as M, default 0x2, TX data rate = (2*refclk*M)/N */
> > +#define PIPE_TX_PLL_MUL_HIGH_MASK GENMASK(3, 0)
> > +
> > +/* 0x38 for 24m, 0x64 for 25m, default 0x71 */
> > +#define PIPE_REG_11C 0x11c
> > +/* TX PLL multiplier low bits [7:0], as M, default 0x71, TX data rate = (2*refclk*M)/N */
> > +#define PIPE_TX_PLL_MUL_LOW_MASK GENMASK(7, 0)
> > +
> > +/* 0x0c for SSC, default 0x1c */
> > +#define UNKNOWN_PIPE_REG_120 0x120
> > +#define UNKNOWN_SSC_120_MASK BIT(4)
> > +#define UNKNOWN_SSC_120_ENABLE (0x0 << 4)
> > +
> > +/* default 0x40 */
> > +#define PIPE_REG_12C 0x12c
> > +#define PIPE_TX_PLL_ALWAYS_ON BIT(0) /* disable for PLL control by pipe_pd */
> > +
> > +/* 0x05 for rx tune, default 0x01 */
> > +#define PIPE_REG_148 0x148
> > +#define PIPE_RX_CHG_PUMP_DIV_2 BIT(2) /* RX CDR charge pump div/2, default 0 */
> > +
> > +/* 0x70 for rx tune, default 0x72 */
> > +#define PIPE_REG_150 0x150
> > +#define PIPE_TX_BIAS_EN BIT(6) /* 1'b1 Enable TX Bias */
> > +/* RX CDR phase tracking speed bits [3:0], default 0x2 */
> > +#define PIPE_RX_CDR_SPEED_MASK GENMASK(3, 0)
> > +#define PIPE_RX_CDR_SPEED_TUNE 0x00
> > +
> > +/* default 0xd4 */
> > +#define PIPE_REG_160
> > +/* RX common mode voltage strength bits [5:4], default 0x1 */
> > +#define PIPE_RX_CDR_COM_VOLT_MASK GENMASK(5, 4)
> > +#define PIPE_RX_CDR_COM_VOLT_TUNE (0x1 << 4)
> > +
> > +/* default 0x00 */
> > +#define PIPE_REG_180 0x180
> > +/* TX driver bias reference voltage bits [3:2], in mv */
> > +#define PIPE_TX_BIAS_REF_VOLT_MASK GENMASK(3, 2)
> > +#define PIPE_TX_BIAS_REF_VOLT_200 (0x0 << 2)
> > +#define PIPE_TX_BIAS_REF_VOLT_175 (0x1 << 2)
> > +#define PIPE_TX_BIAS_REF_VOLT_225 (0x2 << 2) /* downstream 5.10 driver setting */
> > +#define PIPE_TX_BIAS_REF_VOLT_250 (0x3 << 2)
> > +
> > +/* default 0x01 */
> > +#define PIPE_REG_1A8 0x1a8
> > +#define PIPE_LDO_POWER_DIS BIT(4) /* 1'b1 Disable LDO Power */
> > +
> > +/* default 0x07 */
> > +#define PIPE_REG_1AC 0x1ac
> > +/* TX driver output common voltage bits [5:4], in mv */
> > +#define PIPE_TX_COMMON_VOLT_MASK GENMASK(5, 4)
> > +#define PIPE_TX_COMMON_VOLT_800 (0x0 << 4)
> > +#define PIPE_TX_COMMON_VOLT_750 (0x1 << 4)
> > +#define PIPE_TX_COMMON_VOLT_950 (0x2 << 4)
> > +#define PIPE_TX_COMMON_VOLT_1100 (0x3 << 4)
>
> Just a question:
> In this list as well as the one above it (PIPE_TX_BIAS_xyz) I noticed
> the values are not sequential (800, 750, 950, 1100) and (200, 175, 225,
> 250). Is that correct?
According to the rk3228h trm, that's accurate. I'm hoping someone with
access to Innosilicon's IP can confirm the registers I've found and
provide insight to the rest.
>
> Cheers,
> Diederik
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-16 14:35 ` Piotr Oniszczuk
@ 2025-01-16 16:00 ` Peter Geis
0 siblings, 0 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-16 16:00 UTC (permalink / raw)
To: Piotr Oniszczuk
Cc: Heiko Stuebner, Algea Cao, Michael Turquette, kever.yang,
linux-phy, wulf, zyw, Dragan Simic, Kishon Vijay Abraham I,
Rob Herring, Sebastian Reichel, linux-clk, linux-rockchip,
devicetree, Conor Dooley, Philipp Zabel, Arnd Bergmann,
Jonas Karlman, frank.wang, Elaine Zhang, Alex Bee, william.wu,
Zhang Yubing, Johan Jonker, linux-arm-kernel, Trevor Woerner,
Stephen Boyd, linux-kernel, Vinod Koul, FUKAUMI Naoki,
Diederik de Haas, Krzysztof Kozlowski
On Thu, Jan 16, 2025 at 9:35 AM Piotr Oniszczuk
<piotr.oniszczuk@gmail.com> wrote:
>
>
>
> > Wiadomość napisana przez Peter Geis <pgwipeout@gmail.com> w dniu 16 sty 2025, o godz. 15:02:
> >
> >>
> >
> > I'm at a loss here, I applied the patches to a clean 6.9 tree and even
> >>
>
> oh maybe issue is in kernel age?
> 6.9 seems a bit quite old.
> i’m on 6.12.9….
The patches were prepared and tested against 6.13-rc1, but nothing has
changed significantly in the kernel in regards to rk3328 clock
handling in several years. I jumped back to 6.9 due to dyslexia.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-16 13:01 ` Krzysztof Kozlowski
@ 2025-01-16 16:53 ` Diederik de Haas
2025-01-17 4:10 ` Dragan Simic
2025-01-18 8:41 ` Krzysztof Kozlowski
0 siblings, 2 replies; 44+ messages in thread
From: Diederik de Haas @ 2025-01-16 16:53 UTC (permalink / raw)
To: Krzysztof Kozlowski, Peter Geis, Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Alex Bee, Conor Dooley, Dragan Simic, Johan Jonker, Jonas Karlman,
Krzysztof Kozlowski, Rob Herring, devicetree, linux-arm-kernel,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1865 bytes --]
On Thu Jan 16, 2025 at 2:01 PM CET, Krzysztof Kozlowski wrote:
> On 15/01/2025 02:26, Peter Geis wrote:
> > Add the node for the rk3328 usb3 phy. This node provides a combined usb2
> > and usb3 phy which are permenantly tied to the dwc3 usb3 controller.
> >
> > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> > ---
> >
> > arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 ++++++++++++++++++++++++
> > 1 file changed, 39 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > index 7d992c3c01ce..181a900d41f9 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > @@ -903,6 +903,43 @@ u2phy_host: host-port {
> > };
> > };
> >
> > + usb3phy: usb3-phy@ff460000 {
> > + compatible = "rockchip,rk3328-usb3phy";
> > + reg = <0x0 0xff460000 0x0 0x10000>;
> > + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
>
> Please wrap code according to coding style (checkpatch is not a coding
> style description, but only a tool), so at 80.
I'm confused: is it 80 or 100?
I always thought it was 80, but then I saw several patches/commits by
Dragan Simic which deliberately changed code to make use of 100.
Being fed up with my own confusion, I submitted a PR to
https://github.com/gregkh/kernel-coding-style/ which got accepted:
https://github.com/gregkh/kernel-coding-style/commit/5c21f99dc79883bd0efeba368193180275c9c77a
So now both the vim plugins code and README say 100.
But as noted in my commit message:
Note that the current upstream 'Linux kernel coding style' does NOT
mention the 100 char limit, but only mentions the preferred max length
of 80.
Or is it 100 for code, but 80 for DeviceTree files and bindings?
Cheers,
Diederik
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-16 16:53 ` Diederik de Haas
@ 2025-01-17 4:10 ` Dragan Simic
2025-01-18 8:46 ` Krzysztof Kozlowski
2025-01-18 8:41 ` Krzysztof Kozlowski
1 sibling, 1 reply; 44+ messages in thread
From: Dragan Simic @ 2025-01-17 4:10 UTC (permalink / raw)
To: Diederik de Haas
Cc: Krzysztof Kozlowski, Peter Geis, Heiko Stuebner, zyw, kever.yang,
frank.wang, william.wu, wulf, linux-rockchip, Alex Bee,
Conor Dooley, Johan Jonker, Jonas Karlman, Krzysztof Kozlowski,
Rob Herring, devicetree, linux-arm-kernel, linux-kernel
Hello Diederik,
On 2025-01-16 17:53, Diederik de Haas wrote:
> On Thu Jan 16, 2025 at 2:01 PM CET, Krzysztof Kozlowski wrote:
>> On 15/01/2025 02:26, Peter Geis wrote:
>> > Add the node for the rk3328 usb3 phy. This node provides a combined usb2
>> > and usb3 phy which are permenantly tied to the dwc3 usb3 controller.
>> >
>> > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
>> > ---
>> >
>> > arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 ++++++++++++++++++++++++
>> > 1 file changed, 39 insertions(+)
>> >
>> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>> > index 7d992c3c01ce..181a900d41f9 100644
>> > --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>> > +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>> > @@ -903,6 +903,43 @@ u2phy_host: host-port {
>> > };
>> > };
>> >
>> > + usb3phy: usb3-phy@ff460000 {
>> > + compatible = "rockchip,rk3328-usb3phy";
>> > + reg = <0x0 0xff460000 0x0 0x10000>;
>> > + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
>>
>> Please wrap code according to coding style (checkpatch is not a coding
>> style description, but only a tool), so at 80.
>
> I'm confused: is it 80 or 100?
>
> I always thought it was 80, but then I saw several patches/commits by
> Dragan Simic which deliberately changed code to make use of 100.
> Being fed up with my own confusion, I submitted a PR to
> https://github.com/gregkh/kernel-coding-style/ which got accepted:
> https://github.com/gregkh/kernel-coding-style/commit/5c21f99dc79883bd0efeba368193180275c9c77a
>
> So now both the vim plugins code and README say 100.
> But as noted in my commit message:
>
> Note that the current upstream 'Linux kernel coding style' does NOT
> mention the 100 char limit, but only mentions the preferred max
> length
> of 80.
>
> Or is it 100 for code, but 80 for DeviceTree files and bindings?
I don't know about the DT files and bindings, but the 100-column limit
for the kernel code has been in effect for years. In this day and age,
80 columns is really not much (for the record, I've been around when
using 80x25 _physical_ CRT screens was the norm).
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-16 16:53 ` Diederik de Haas
2025-01-17 4:10 ` Dragan Simic
@ 2025-01-18 8:41 ` Krzysztof Kozlowski
2025-01-18 9:19 ` Krzysztof Kozlowski
2025-01-18 15:55 ` Diederik de Haas
1 sibling, 2 replies; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-18 8:41 UTC (permalink / raw)
To: Diederik de Haas, Peter Geis, Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Alex Bee, Conor Dooley, Dragan Simic, Johan Jonker, Jonas Karlman,
Krzysztof Kozlowski, Rob Herring, devicetree, linux-arm-kernel,
linux-kernel
On 16/01/2025 17:53, Diederik de Haas wrote:
> On Thu Jan 16, 2025 at 2:01 PM CET, Krzysztof Kozlowski wrote:
>> On 15/01/2025 02:26, Peter Geis wrote:
>>> Add the node for the rk3328 usb3 phy. This node provides a combined usb2
>>> and usb3 phy which are permenantly tied to the dwc3 usb3 controller.
>>>
>>> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
>>> ---
>>>
>>> arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 ++++++++++++++++++++++++
>>> 1 file changed, 39 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>> index 7d992c3c01ce..181a900d41f9 100644
>>> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>> @@ -903,6 +903,43 @@ u2phy_host: host-port {
>>> };
>>> };
>>>
>>> + usb3phy: usb3-phy@ff460000 {
>>> + compatible = "rockchip,rk3328-usb3phy";
>>> + reg = <0x0 0xff460000 0x0 0x10000>;
>>> + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
>>
>> Please wrap code according to coding style (checkpatch is not a coding
>> style description, but only a tool), so at 80.
>
> I'm confused: is it 80 or 100?
>
> I always thought it was 80, but then I saw several patches/commits by
Coding style is clear: it is 80. It also has caveat about code
readability and several maintainers have their own preference.
> Dragan Simic which deliberately changed code to make use of 100.
> Being fed up with my own confusion, I submitted a PR to
> https://github.com/gregkh/kernel-coding-style/ which got accepted:
> https://github.com/gregkh/kernel-coding-style/commit/5c21f99dc79883bd0efeba368193180275c9c77a
That's not kernel. That's Greg...
>
> So now both the vim plugins code and README say 100.
> But as noted in my commit message:
>
> Note that the current upstream 'Linux kernel coding style' does NOT
> mention the 100 char limit, but only mentions the preferred max length
> of 80.
>
> Or is it 100 for code, but 80 for DeviceTree files and bindings?
From where did you get 100? Checkpatch, right? Kernel coding style is
clear, there is no discussion, no mentioning 100:
"The preferred limit on the length of a single line is 80 columns. "
So to be clear: all DTS, all DT bindings, all code maintained by me and
some maintainers follows above (and further - there is caveat)
instruction from coding style. Some maintainers follow other rules and
that's fine.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-17 4:10 ` Dragan Simic
@ 2025-01-18 8:46 ` Krzysztof Kozlowski
2025-01-18 9:25 ` Dragan Simic
0 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-18 8:46 UTC (permalink / raw)
To: Dragan Simic, Diederik de Haas
Cc: Peter Geis, Heiko Stuebner, zyw, kever.yang, frank.wang,
william.wu, wulf, linux-rockchip, Alex Bee, Conor Dooley,
Johan Jonker, Jonas Karlman, Krzysztof Kozlowski, Rob Herring,
devicetree, linux-arm-kernel, linux-kernel
On 17/01/2025 05:10, Dragan Simic wrote:
> Hello Diederik,
>
> On 2025-01-16 17:53, Diederik de Haas wrote:
>> On Thu Jan 16, 2025 at 2:01 PM CET, Krzysztof Kozlowski wrote:
>>> On 15/01/2025 02:26, Peter Geis wrote:
>>>> Add the node for the rk3328 usb3 phy. This node provides a combined usb2
>>>> and usb3 phy which are permenantly tied to the dwc3 usb3 controller.
>>>>
>>>> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
>>>> ---
>>>>
>>>> arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 ++++++++++++++++++++++++
>>>> 1 file changed, 39 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>> index 7d992c3c01ce..181a900d41f9 100644
>>>> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>> @@ -903,6 +903,43 @@ u2phy_host: host-port {
>>>> };
>>>> };
>>>>
>>>> + usb3phy: usb3-phy@ff460000 {
>>>> + compatible = "rockchip,rk3328-usb3phy";
>>>> + reg = <0x0 0xff460000 0x0 0x10000>;
>>>> + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
>>>
>>> Please wrap code according to coding style (checkpatch is not a coding
>>> style description, but only a tool), so at 80.
>>
>> I'm confused: is it 80 or 100?
>>
>> I always thought it was 80, but then I saw several patches/commits by
>> Dragan Simic which deliberately changed code to make use of 100.
>> Being fed up with my own confusion, I submitted a PR to
>> https://github.com/gregkh/kernel-coding-style/ which got accepted:
>> https://github.com/gregkh/kernel-coding-style/commit/5c21f99dc79883bd0efeba368193180275c9c77a
>>
>> So now both the vim plugins code and README say 100.
>> But as noted in my commit message:
>>
>> Note that the current upstream 'Linux kernel coding style' does NOT
>> mention the 100 char limit, but only mentions the preferred max
>> length
>> of 80.
>>
>> Or is it 100 for code, but 80 for DeviceTree files and bindings?
>
> I don't know about the DT files and bindings, but the 100-column limit
> for the kernel code has been in effect for years. In this day and age,
That's just false. It was never in effect for years. Read kernel coding
style document.
> 80 columns is really not much (for the record, I've been around when
> using 80x25 _physical_ CRT screens was the norm).
You mistake agreement on dropping strong restriction in 2020 in
checkpatch, which is "not for years" and even read that commit: "Yes,
staying withing 80 columns is certainly still _preferred_."
Checkpatch is not coding style. Since when it would be? It's just a tool.
And there were more talks and the 80-preference got relaxed yet still
"not for years" (last talk was 2022?) and sill kernel coding style is
here specific.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 2/6] dt-bindings: phy: rockchip: add rk3328 usb3 phy
2025-01-16 13:32 ` Peter Geis
2025-01-16 13:59 ` Peter Geis
@ 2025-01-18 9:06 ` Krzysztof Kozlowski
1 sibling, 0 replies; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-18 9:06 UTC (permalink / raw)
To: Peter Geis
Cc: Heiko Stuebner, zyw, kever.yang, frank.wang, william.wu, wulf,
linux-rockchip, Conor Dooley, Kishon Vijay Abraham I,
Krzysztof Kozlowski, Rob Herring, Vinod Koul, devicetree,
linux-arm-kernel, linux-kernel, linux-phy
On 16/01/2025 14:32, Peter Geis wrote:
>>
>>
>>> + additionalProperties: false
>>> +
>>> + properties:
>>> + compatible:
>>> + enum:
>>> + - rockchip,rk3328-usb3phy-utmi
>>> +
>>> + reg:
>>> + maxItems: 1
>>> +
>>> + "#phy-cells":
>>> + const: 0
>>
>> Does not look correct. Your parent device is the phy, not child. Why do
>> you create children per each type of phy?
>
> Because that's how it's done elsewhere in Rockchip's phys [1]. How
> should it be done?
The phys have separate supplies and IO addresses? Then it is reasonable
to keep them separate and as children. But then more questions appear:
why resets - which are also per utmi or port - are in top-level node?
This should be represented in coherent way: either you define the
properties/nodes per PHY or just everything in one/entire PHY
controller. Not mixed.
Same concerns about clocks in top-level.
It also might be that everything is a bit mixed, so you have entire phy
controller handling common resources and still separate phy for USB2 and
USB3 as children, but that should be conscious choice coming from actual
hardware. You have entire "description:" in binding to explain the
hardware and any questions I asked now.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-15 1:26 [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Peter Geis
` (6 preceding siblings ...)
2025-01-15 11:22 ` [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Piotr Oniszczuk
@ 2025-01-18 9:08 ` Krzysztof Kozlowski
2025-01-18 14:35 ` Peter Geis
2025-02-26 19:49 ` (subset) " Heiko Stuebner
8 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-18 9:08 UTC (permalink / raw)
To: Peter Geis, Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Alex Bee, Algea Cao, Arnd Bergmann, Conor Dooley,
Cristian Ciocaltea, Diederik de Haas, Dragan Simic, Elaine Zhang,
FUKAUMI Naoki, Johan Jonker, Jonas Karlman,
Kishon Vijay Abraham I, Krzysztof Kozlowski, Michael Turquette,
Philipp Zabel, Rob Herring, Sebastian Reichel, Stephen Boyd,
Trevor Woerner, Vinod Koul, Zhang Yubing, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-phy
On 15/01/2025 02:26, Peter Geis wrote:
>
> This is my newly reworked phy driver for the rk3328 usb3 phy. It is
> based loosely on my original version, but as of now almost nothing of
> the original driver remains. The main fix here is the discovery of
> BIT(6) in the interrupt enable grf register fixes the usb3 disconnection
> detection (mostly). On occasion an unpopulated usb3 hub will take
> several seconds to disconnect. However this means all of the hack around
> work to reset the usb core manually is no longer required.
>
BTW, RFC for some maintainers means "do not review, work-in-progress".
For some means "review, but low priority" or "review, but for sure I
have bugs here". I usually review and then someone responds: "it is not
for review, it is just RFC", so to avoid my wasted time please always
mention in cover letter why this is RFC. What do you expect here or why
this is not ready for review as normal patch.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 8:41 ` Krzysztof Kozlowski
@ 2025-01-18 9:19 ` Krzysztof Kozlowski
2025-01-18 9:34 ` Dragan Simic
2025-01-18 15:55 ` Diederik de Haas
1 sibling, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-18 9:19 UTC (permalink / raw)
To: Diederik de Haas, Peter Geis, Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Alex Bee, Conor Dooley, Dragan Simic, Johan Jonker, Jonas Karlman,
Krzysztof Kozlowski, Rob Herring, devicetree, linux-arm-kernel,
linux-kernel
On 18/01/2025 09:41, Krzysztof Kozlowski wrote:
> On 16/01/2025 17:53, Diederik de Haas wrote:
>> On Thu Jan 16, 2025 at 2:01 PM CET, Krzysztof Kozlowski wrote:
>>> On 15/01/2025 02:26, Peter Geis wrote:
>>>> Add the node for the rk3328 usb3 phy. This node provides a combined usb2
>>>> and usb3 phy which are permenantly tied to the dwc3 usb3 controller.
>>>>
>>>> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
>>>> ---
>>>>
>>>> arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 ++++++++++++++++++++++++
>>>> 1 file changed, 39 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>> index 7d992c3c01ce..181a900d41f9 100644
>>>> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>> @@ -903,6 +903,43 @@ u2phy_host: host-port {
>>>> };
>>>> };
>>>>
>>>> + usb3phy: usb3-phy@ff460000 {
>>>> + compatible = "rockchip,rk3328-usb3phy";
>>>> + reg = <0x0 0xff460000 0x0 0x10000>;
>>>> + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
>>>
>>> Please wrap code according to coding style (checkpatch is not a coding
>>> style description, but only a tool), so at 80.
>>
>> I'm confused: is it 80 or 100?
>>
>> I always thought it was 80, but then I saw several patches/commits by
>
> Coding style is clear: it is 80. It also has caveat about code
> readability and several maintainers have their own preference.
>
>> Dragan Simic which deliberately changed code to make use of 100.
>> Being fed up with my own confusion, I submitted a PR to
>> https://github.com/gregkh/kernel-coding-style/ which got accepted:
>> https://github.com/gregkh/kernel-coding-style/commit/5c21f99dc79883bd0efeba368193180275c9c77a
>
> That's not kernel. That's Greg...
>
>>
>> So now both the vim plugins code and README say 100.
>> But as noted in my commit message:
>>
>> Note that the current upstream 'Linux kernel coding style' does NOT
>> mention the 100 char limit, but only mentions the preferred max length
>> of 80.
>>
>> Or is it 100 for code, but 80 for DeviceTree files and bindings?
>
> From where did you get 100? Checkpatch, right? Kernel coding style is
> clear, there is no discussion, no mentioning 100:
>
> "The preferred limit on the length of a single line is 80 columns. "
>
> So to be clear: all DTS, all DT bindings, all code maintained by me and
> some maintainers follows above (and further - there is caveat)
> instruction from coding style. Some maintainers follow other rules and
> that's fine.
Although let me add here caveat, after looking at some other code: DTS
due to its nature of a lot of parent-child relationships combined with
long constants ("GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>") has the strongest
exception or the strongest second part of the coding style:
"...unless exceeding 80 columns significantly increases readability..."
And again: that's from official coding style document (so something
which have been for years), no matter what other people tell you they
think exists since years as coding style.
Splitting line, I commented here in this patch, did not improve readability.
Quite opposite: the line there was less readable in current format thus
it is not even about coding style anymore, but just readability style.
Any list with more than two short entries (by number of characters in
list item) or any list with more than one long entry should be split for
readability. However actual ITEMS in list should not be split - but
again coding style is here very precise since years. 80 unless
significantly increases readability.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 8:46 ` Krzysztof Kozlowski
@ 2025-01-18 9:25 ` Dragan Simic
2025-01-18 9:31 ` Krzysztof Kozlowski
0 siblings, 1 reply; 44+ messages in thread
From: Dragan Simic @ 2025-01-18 9:25 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Diederik de Haas, Peter Geis, Heiko Stuebner, zyw, kever.yang,
frank.wang, william.wu, wulf, linux-rockchip, Alex Bee,
Conor Dooley, Johan Jonker, Jonas Karlman, Krzysztof Kozlowski,
Rob Herring, devicetree, linux-arm-kernel, linux-kernel
Hello Krzysztof,
On 2025-01-18 09:46, Krzysztof Kozlowski wrote:
> On 17/01/2025 05:10, Dragan Simic wrote:
>> On 2025-01-16 17:53, Diederik de Haas wrote:
>>> On Thu Jan 16, 2025 at 2:01 PM CET, Krzysztof Kozlowski wrote:
>>>> On 15/01/2025 02:26, Peter Geis wrote:
>>>>> Add the node for the rk3328 usb3 phy. This node provides a combined
>>>>> usb2
>>>>> and usb3 phy which are permenantly tied to the dwc3 usb3
>>>>> controller.
>>>>>
>>>>> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
>>>>> ---
>>>>>
>>>>> arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39
>>>>> ++++++++++++++++++++++++
>>>>> 1 file changed, 39 insertions(+)
>>>>>
>>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> index 7d992c3c01ce..181a900d41f9 100644
>>>>> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> @@ -903,6 +903,43 @@ u2phy_host: host-port {
>>>>> };
>>>>> };
>>>>>
>>>>> + usb3phy: usb3-phy@ff460000 {
>>>>> + compatible = "rockchip,rk3328-usb3phy";
>>>>> + reg = <0x0 0xff460000 0x0 0x10000>;
>>>>> + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru
>>>>> PCLK_USB3PHY_PIPE>;
>>>>
>>>> Please wrap code according to coding style (checkpatch is not a
>>>> coding
>>>> style description, but only a tool), so at 80.
>>>
>>> I'm confused: is it 80 or 100?
>>>
>>> I always thought it was 80, but then I saw several patches/commits by
>>> Dragan Simic which deliberately changed code to make use of 100.
>>> Being fed up with my own confusion, I submitted a PR to
>>> https://github.com/gregkh/kernel-coding-style/ which got accepted:
>>> https://github.com/gregkh/kernel-coding-style/commit/5c21f99dc79883bd0efeba368193180275c9c77a
>>>
>>> So now both the vim plugins code and README say 100.
>>> But as noted in my commit message:
>>>
>>> Note that the current upstream 'Linux kernel coding style' does NOT
>>> mention the 100 char limit, but only mentions the preferred max
>>> length
>>> of 80.
>>>
>>> Or is it 100 for code, but 80 for DeviceTree files and bindings?
>>
>> I don't know about the DT files and bindings, but the 100-column limit
>> for the kernel code has been in effect for years. In this day and
>> age,
>
> That's just false. It was never in effect for years. Read kernel coding
> style document.
Perhaps it's about the semantics.
Please see the commit bdc48fa11e46 (checkpatch/coding-style: deprecate
80-column warning, 2020-05-29), which clearly shows that the 80-column
rule is still _preferred_, but no longer _mandatory_.
>> 80 columns is really not much (for the record, I've been around when
>> using 80x25 _physical_ CRT screens was the norm).
>
> You mistake agreement on dropping strong restriction in 2020 in
> checkpatch, which is "not for years" and even read that commit: "Yes,
> staying withing 80 columns is certainly still _preferred_."
>
> Checkpatch is not coding style. Since when it would be? It's just a
> tool.
>
> And there were more talks and the 80-preference got relaxed yet still
> "not for years" (last talk was 2022?) and sill kernel coding style is
> here specific.
It's perhaps again about the semantics, this time about the meaning
of "for years". I don't think there's some strict definition of that
term, so perhaps different people see it differently.
To get back to the above-mentioned commit bdc48fa11e46, the 80-column
limit has obviously been lifted, putting the new 100-column limit as
an option for those who prefer having fewer "artificial" line breaks
over adhering strictly to the rules.
Thus, as a maintainer, you're obviously free to enforce the 80-column
limit of you want so.
If my opinion counts, I'd agree with the 80-column limit when it comes
to the device trees and bindings. Keeping those files at the lower
width usually makes them more readable to me. However, enforcing the
80-column limit in C and header files very often leads to having line
breaks that do nothing but make the code look a bit silly.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 9:25 ` Dragan Simic
@ 2025-01-18 9:31 ` Krzysztof Kozlowski
2025-01-18 9:43 ` Dragan Simic
0 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-18 9:31 UTC (permalink / raw)
To: Dragan Simic
Cc: Diederik de Haas, Peter Geis, Heiko Stuebner, zyw, kever.yang,
frank.wang, william.wu, wulf, linux-rockchip, Alex Bee,
Conor Dooley, Johan Jonker, Jonas Karlman, Krzysztof Kozlowski,
Rob Herring, devicetree, linux-arm-kernel, linux-kernel
On 18/01/2025 10:25, Dragan Simic wrote:
> Hello Krzysztof,
>
> On 2025-01-18 09:46, Krzysztof Kozlowski wrote:
>> On 17/01/2025 05:10, Dragan Simic wrote:
>>> On 2025-01-16 17:53, Diederik de Haas wrote:
>>>> On Thu Jan 16, 2025 at 2:01 PM CET, Krzysztof Kozlowski wrote:
>>>>> On 15/01/2025 02:26, Peter Geis wrote:
>>>>>> Add the node for the rk3328 usb3 phy. This node provides a combined
>>>>>> usb2
>>>>>> and usb3 phy which are permenantly tied to the dwc3 usb3
>>>>>> controller.
>>>>>>
>>>>>> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
>>>>>> ---
>>>>>>
>>>>>> arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39
>>>>>> ++++++++++++++++++++++++
>>>>>> 1 file changed, 39 insertions(+)
>>>>>>
>>>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>>> b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>>> index 7d992c3c01ce..181a900d41f9 100644
>>>>>> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>>> @@ -903,6 +903,43 @@ u2phy_host: host-port {
>>>>>> };
>>>>>> };
>>>>>>
>>>>>> + usb3phy: usb3-phy@ff460000 {
>>>>>> + compatible = "rockchip,rk3328-usb3phy";
>>>>>> + reg = <0x0 0xff460000 0x0 0x10000>;
>>>>>> + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru
>>>>>> PCLK_USB3PHY_PIPE>;
>>>>>
>>>>> Please wrap code according to coding style (checkpatch is not a
>>>>> coding
>>>>> style description, but only a tool), so at 80.
>>>>
>>>> I'm confused: is it 80 or 100?
>>>>
>>>> I always thought it was 80, but then I saw several patches/commits by
>>>> Dragan Simic which deliberately changed code to make use of 100.
>>>> Being fed up with my own confusion, I submitted a PR to
>>>> https://github.com/gregkh/kernel-coding-style/ which got accepted:
>>>> https://github.com/gregkh/kernel-coding-style/commit/5c21f99dc79883bd0efeba368193180275c9c77a
>>>>
>>>> So now both the vim plugins code and README say 100.
>>>> But as noted in my commit message:
>>>>
>>>> Note that the current upstream 'Linux kernel coding style' does NOT
>>>> mention the 100 char limit, but only mentions the preferred max
>>>> length
>>>> of 80.
>>>>
>>>> Or is it 100 for code, but 80 for DeviceTree files and bindings?
>>>
>>> I don't know about the DT files and bindings, but the 100-column limit
>>> for the kernel code has been in effect for years. In this day and
>>> age,
>>
>> That's just false. It was never in effect for years. Read kernel coding
>> style document.
>
> Perhaps it's about the semantics.
>
> Please see the commit bdc48fa11e46 (checkpatch/coding-style: deprecate
> 80-column warning, 2020-05-29), which clearly shows that the 80-column
> rule is still _preferred_, but no longer _mandatory_.
I brought that commit, but nice that you also found it.
Still: read the coding style, not checkpatch tool.
>
>>> 80 columns is really not much (for the record, I've been around when
>>> using 80x25 _physical_ CRT screens was the norm).
>>
>> You mistake agreement on dropping strong restriction in 2020 in
>> checkpatch, which is "not for years" and even read that commit: "Yes,
>> staying withing 80 columns is certainly still _preferred_."
>>
>> Checkpatch is not coding style. Since when it would be? It's just a
>> tool.
>>
>> And there were more talks and the 80-preference got relaxed yet still
>> "not for years" (last talk was 2022?) and sill kernel coding style is
>> here specific.
>
> It's perhaps again about the semantics, this time about the meaning
> of "for years". I don't think there's some strict definition of that
> term, so perhaps different people see it differently.
>
> To get back to the above-mentioned commit bdc48fa11e46, the 80-column
> limit has obviously been lifted, putting the new 100-column limit as
"Lifted" on *CHECKPATCH*, not on coding style. Do you see the
difference? One is a helper tool which people were using blindly and
wrapping lines without thinking, claiming that checkpatch told them to
do so. Other is the actual coding style.
You claim that coding style was changed. This never happened.
And my first - really the first - comment here was also precise
mentioning that difference:
"Please wrap code according to coding style (*checkpatch is not* a
coding style description, but only a tool), so at 80."
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 9:19 ` Krzysztof Kozlowski
@ 2025-01-18 9:34 ` Dragan Simic
0 siblings, 0 replies; 44+ messages in thread
From: Dragan Simic @ 2025-01-18 9:34 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Diederik de Haas, Peter Geis, Heiko Stuebner, zyw, kever.yang,
frank.wang, william.wu, wulf, linux-rockchip, Alex Bee,
Conor Dooley, Johan Jonker, Jonas Karlman, Krzysztof Kozlowski,
Rob Herring, devicetree, linux-arm-kernel, linux-kernel
On 2025-01-18 10:19, Krzysztof Kozlowski wrote:
> On 18/01/2025 09:41, Krzysztof Kozlowski wrote:
>> On 16/01/2025 17:53, Diederik de Haas wrote:
>>> On Thu Jan 16, 2025 at 2:01 PM CET, Krzysztof Kozlowski wrote:
>>>> On 15/01/2025 02:26, Peter Geis wrote:
>>>>> Add the node for the rk3328 usb3 phy. This node provides a combined
>>>>> usb2
>>>>> and usb3 phy which are permenantly tied to the dwc3 usb3
>>>>> controller.
>>>>>
>>>>> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
>>>>> ---
>>>>>
>>>>> arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39
>>>>> ++++++++++++++++++++++++
>>>>> 1 file changed, 39 insertions(+)
>>>>>
>>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> index 7d992c3c01ce..181a900d41f9 100644
>>>>> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> @@ -903,6 +903,43 @@ u2phy_host: host-port {
>>>>> };
>>>>> };
>>>>>
>>>>> + usb3phy: usb3-phy@ff460000 {
>>>>> + compatible = "rockchip,rk3328-usb3phy";
>>>>> + reg = <0x0 0xff460000 0x0 0x10000>;
>>>>> + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru
>>>>> PCLK_USB3PHY_PIPE>;
>>>>
>>>> Please wrap code according to coding style (checkpatch is not a
>>>> coding
>>>> style description, but only a tool), so at 80.
>>>
>>> I'm confused: is it 80 or 100?
>>>
>>> I always thought it was 80, but then I saw several patches/commits by
>>
>> Coding style is clear: it is 80. It also has caveat about code
>> readability and several maintainers have their own preference.
>>
>>> Dragan Simic which deliberately changed code to make use of 100.
>>> Being fed up with my own confusion, I submitted a PR to
>>> https://github.com/gregkh/kernel-coding-style/ which got accepted:
>>> https://github.com/gregkh/kernel-coding-style/commit/5c21f99dc79883bd0efeba368193180275c9c77a
>>
>> That's not kernel. That's Greg...
>>
>>>
>>> So now both the vim plugins code and README say 100.
>>> But as noted in my commit message:
>>>
>>> Note that the current upstream 'Linux kernel coding style' does NOT
>>> mention the 100 char limit, but only mentions the preferred max
>>> length
>>> of 80.
>>>
>>> Or is it 100 for code, but 80 for DeviceTree files and bindings?
>>
>> From where did you get 100? Checkpatch, right? Kernel coding style is
>> clear, there is no discussion, no mentioning 100:
>>
>> "The preferred limit on the length of a single line is 80 columns. "
>>
>> So to be clear: all DTS, all DT bindings, all code maintained by me
>> and
>> some maintainers follows above (and further - there is caveat)
>> instruction from coding style. Some maintainers follow other rules and
>> that's fine.
>
>
> Although let me add here caveat, after looking at some other code: DTS
> due to its nature of a lot of parent-child relationships combined with
> long constants ("GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>") has the strongest
> exception or the strongest second part of the coding style:
> "...unless exceeding 80 columns significantly increases readability..."
>
> And again: that's from official coding style document (so something
> which have been for years), no matter what other people tell you they
> think exists since years as coding style.
>
> Splitting line, I commented here in this patch, did not improve
> readability.
>
> Quite opposite: the line there was less readable in current format thus
> it is not even about coding style anymore, but just readability style.
> Any list with more than two short entries (by number of characters in
> list item) or any list with more than one long entry should be split
> for
> readability. However actual ITEMS in list should not be split - but
> again coding style is here very precise since years. 80 unless
> significantly increases readability.
I fully agree with the readability being the most important factor when
it comes to deciding on the column width. That's very well illustrated
by the example above, i.e. the list items in device trees, which are
much
more readable when the items are placed in separate lines.
Though, as I wrote in my earlier response, enforcing the 80-column limit
in C and headers files rather often leads to line breaks that are
obviously
"artificial" and do nothing but make the code less readable. That's
where
the 100-column with limit often improves the readability.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 9:31 ` Krzysztof Kozlowski
@ 2025-01-18 9:43 ` Dragan Simic
2025-01-18 9:52 ` Krzysztof Kozlowski
0 siblings, 1 reply; 44+ messages in thread
From: Dragan Simic @ 2025-01-18 9:43 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Diederik de Haas, Peter Geis, Heiko Stuebner, zyw, kever.yang,
frank.wang, william.wu, wulf, linux-rockchip, Alex Bee,
Conor Dooley, Johan Jonker, Jonas Karlman, Krzysztof Kozlowski,
Rob Herring, devicetree, linux-arm-kernel, linux-kernel
On 2025-01-18 10:31, Krzysztof Kozlowski wrote:
> On 18/01/2025 10:25, Dragan Simic wrote:
>> On 2025-01-18 09:46, Krzysztof Kozlowski wrote:
>>> On 17/01/2025 05:10, Dragan Simic wrote:
>>>> On 2025-01-16 17:53, Diederik de Haas wrote:
>>>>> On Thu Jan 16, 2025 at 2:01 PM CET, Krzysztof Kozlowski wrote:
>>>>>> On 15/01/2025 02:26, Peter Geis wrote:
>>>>>>> Add the node for the rk3328 usb3 phy. This node provides a
>>>>>>> combined
>>>>>>> usb2
>>>>>>> and usb3 phy which are permenantly tied to the dwc3 usb3
>>>>>>> controller.
>>>>>>>
>>>>>>> Signed-off-by: Peter Geis <pgwipeout@gmail.com>
>>>>>>> ---
>>>>>>>
>>>>>>> arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39
>>>>>>> ++++++++++++++++++++++++
>>>>>>> 1 file changed, 39 insertions(+)
>>>>>>>
>>>>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>>>> b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>>>> index 7d992c3c01ce..181a900d41f9 100644
>>>>>>> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>>>> @@ -903,6 +903,43 @@ u2phy_host: host-port {
>>>>>>> };
>>>>>>> };
>>>>>>>
>>>>>>> + usb3phy: usb3-phy@ff460000 {
>>>>>>> + compatible = "rockchip,rk3328-usb3phy";
>>>>>>> + reg = <0x0 0xff460000 0x0 0x10000>;
>>>>>>> + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>,
>>>>>>> <&cru
>>>>>>> PCLK_USB3PHY_PIPE>;
>>>>>>
>>>>>> Please wrap code according to coding style (checkpatch is not a
>>>>>> coding
>>>>>> style description, but only a tool), so at 80.
>>>>>
>>>>> I'm confused: is it 80 or 100?
>>>>>
>>>>> I always thought it was 80, but then I saw several patches/commits
>>>>> by
>>>>> Dragan Simic which deliberately changed code to make use of 100.
>>>>> Being fed up with my own confusion, I submitted a PR to
>>>>> https://github.com/gregkh/kernel-coding-style/ which got accepted:
>>>>> https://github.com/gregkh/kernel-coding-style/commit/5c21f99dc79883bd0efeba368193180275c9c77a
>>>>>
>>>>> So now both the vim plugins code and README say 100.
>>>>> But as noted in my commit message:
>>>>>
>>>>> Note that the current upstream 'Linux kernel coding style' does
>>>>> NOT
>>>>> mention the 100 char limit, but only mentions the preferred max
>>>>> length
>>>>> of 80.
>>>>>
>>>>> Or is it 100 for code, but 80 for DeviceTree files and bindings?
>>>>
>>>> I don't know about the DT files and bindings, but the 100-column
>>>> limit
>>>> for the kernel code has been in effect for years. In this day and
>>>> age,
>>>
>>> That's just false. It was never in effect for years. Read kernel
>>> coding
>>> style document.
>>
>> Perhaps it's about the semantics.
>>
>> Please see the commit bdc48fa11e46 (checkpatch/coding-style: deprecate
>> 80-column warning, 2020-05-29), which clearly shows that the 80-column
>> rule is still _preferred_, but no longer _mandatory_.
>
> I brought that commit, but nice that you also found it.
>
> Still: read the coding style, not checkpatch tool.
>
>>>> 80 columns is really not much (for the record, I've been around when
>>>> using 80x25 _physical_ CRT screens was the norm).
>>>
>>> You mistake agreement on dropping strong restriction in 2020 in
>>> checkpatch, which is "not for years" and even read that commit: "Yes,
>>> staying withing 80 columns is certainly still _preferred_."
>>>
>>> Checkpatch is not coding style. Since when it would be? It's just a
>>> tool.
>>>
>>> And there were more talks and the 80-preference got relaxed yet still
>>> "not for years" (last talk was 2022?) and sill kernel coding style is
>>> here specific.
>>
>> It's perhaps again about the semantics, this time about the meaning
>> of "for years". I don't think there's some strict definition of that
>> term, so perhaps different people see it differently.
>>
>> To get back to the above-mentioned commit bdc48fa11e46, the 80-column
>> limit has obviously been lifted, putting the new 100-column limit as
>
> "Lifted" on *CHECKPATCH*, not on coding style. Do you see the
> difference? One is a helper tool which people were using blindly and
> wrapping lines without thinking, claiming that checkpatch told them to
> do so. Other is the actual coding style.
>
> You claim that coding style was changed. This never happened.
It was obviously changed in the commit bdc48fa11e46, by making the
80-column width preferred, instead of if being mandatory. The way
I read the changes to the coding style introduced in that commit,
it's now possible to go over 80 columns, up to 100 columns, _if_
that actually improves the readability of the source code.
Just like enforcing the 80-column blindly can make the code much
less readable, it's also that going liberally to 100 columns can
make the code even less readable. To me, those rules aren't to be
followed blindly, but the resulting readability of the code should
be the deciding factor for pretty much each line of the code.
> And my first - really the first - comment here was also precise
> mentioning that difference:
>
> "Please wrap code according to coding style (*checkpatch is not* a
> coding style description, but only a tool), so at 80."
Again, I think that the readability should be the deciding factor.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 9:43 ` Dragan Simic
@ 2025-01-18 9:52 ` Krzysztof Kozlowski
2025-01-18 10:10 ` Dragan Simic
0 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-18 9:52 UTC (permalink / raw)
To: Dragan Simic
Cc: Diederik de Haas, Peter Geis, Heiko Stuebner, zyw, kever.yang,
frank.wang, william.wu, wulf, linux-rockchip, Alex Bee,
Conor Dooley, Johan Jonker, Jonas Karlman, Krzysztof Kozlowski,
Rob Herring, devicetree, linux-arm-kernel, linux-kernel
On 18/01/2025 10:43, Dragan Simic wrote:
>>>
>>> Please see the commit bdc48fa11e46 (checkpatch/coding-style: deprecate
>>> 80-column warning, 2020-05-29), which clearly shows that the 80-column
>>> rule is still _preferred_, but no longer _mandatory_.
>>
>> I brought that commit, but nice that you also found it.
>>
>> Still: read the coding style, not checkpatch tool.
>>
>>>>> 80 columns is really not much (for the record, I've been around when
>>>>> using 80x25 _physical_ CRT screens was the norm).
>>>>
>>>> You mistake agreement on dropping strong restriction in 2020 in
>>>> checkpatch, which is "not for years" and even read that commit: "Yes,
>>>> staying withing 80 columns is certainly still _preferred_."
>>>>
>>>> Checkpatch is not coding style. Since when it would be? It's just a
>>>> tool.
>>>>
>>>> And there were more talks and the 80-preference got relaxed yet still
>>>> "not for years" (last talk was 2022?) and sill kernel coding style is
>>>> here specific.
>>>
>>> It's perhaps again about the semantics, this time about the meaning
>>> of "for years". I don't think there's some strict definition of that
>>> term, so perhaps different people see it differently.
>>>
>>> To get back to the above-mentioned commit bdc48fa11e46, the 80-column
>>> limit has obviously been lifted, putting the new 100-column limit as
>>
>> "Lifted" on *CHECKPATCH*, not on coding style. Do you see the
Repeating myself about because you are not addressing the actual difference.
>> difference? One is a helper tool which people were using blindly and
>> wrapping lines without thinking, claiming that checkpatch told them to
>> do so. Other is the actual coding style.
>>
>> You claim that coding style was changed. This never happened.
>
> It was obviously changed in the commit bdc48fa11e46, by making the
> 80-column width preferred, instead of if being mandatory. The way
> I read the changes to the coding style introduced in that commit,
> it's now possible to go over 80 columns, up to 100 columns, _if_
> that actually improves the readability of the source code.
The commit is for checkpatch. Point to the change in coding style. You
are bringing argument for checkpatch, so only a tool, as argument for
coding style. Again, coding style did not change since years.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 9:52 ` Krzysztof Kozlowski
@ 2025-01-18 10:10 ` Dragan Simic
2025-01-18 10:29 ` Krzysztof Kozlowski
0 siblings, 1 reply; 44+ messages in thread
From: Dragan Simic @ 2025-01-18 10:10 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Diederik de Haas, Peter Geis, Heiko Stuebner, zyw, kever.yang,
frank.wang, william.wu, wulf, linux-rockchip, Alex Bee,
Conor Dooley, Johan Jonker, Jonas Karlman, Krzysztof Kozlowski,
Rob Herring, devicetree, linux-arm-kernel, linux-kernel
On 2025-01-18 10:52, Krzysztof Kozlowski wrote:
> On 18/01/2025 10:43, Dragan Simic wrote:
>>>>
>>>> Please see the commit bdc48fa11e46 (checkpatch/coding-style:
>>>> deprecate
>>>> 80-column warning, 2020-05-29), which clearly shows that the
>>>> 80-column
>>>> rule is still _preferred_, but no longer _mandatory_.
>>>
>>> I brought that commit, but nice that you also found it.
>>>
>>> Still: read the coding style, not checkpatch tool.
>>>
>>>>>> 80 columns is really not much (for the record, I've been around
>>>>>> when
>>>>>> using 80x25 _physical_ CRT screens was the norm).
>>>>>
>>>>> You mistake agreement on dropping strong restriction in 2020 in
>>>>> checkpatch, which is "not for years" and even read that commit:
>>>>> "Yes,
>>>>> staying withing 80 columns is certainly still _preferred_."
>>>>>
>>>>> Checkpatch is not coding style. Since when it would be? It's just a
>>>>> tool.
>>>>>
>>>>> And there were more talks and the 80-preference got relaxed yet
>>>>> still
>>>>> "not for years" (last talk was 2022?) and sill kernel coding style
>>>>> is
>>>>> here specific.
>>>>
>>>> It's perhaps again about the semantics, this time about the meaning
>>>> of "for years". I don't think there's some strict definition of
>>>> that
>>>> term, so perhaps different people see it differently.
>>>>
>>>> To get back to the above-mentioned commit bdc48fa11e46, the
>>>> 80-column
>>>> limit has obviously been lifted, putting the new 100-column limit as
>>>
>>> "Lifted" on *CHECKPATCH*, not on coding style. Do you see the
>
> Repeating myself about because you are not addressing the actual
> difference.
Please see below.
>>> difference? One is a helper tool which people were using blindly and
>>> wrapping lines without thinking, claiming that checkpatch told them
>>> to
>>> do so. Other is the actual coding style.
>>>
>>> You claim that coding style was changed. This never happened.
>>
>> It was obviously changed in the commit bdc48fa11e46, by making the
>> 80-column width preferred, instead of if being mandatory. The way
>> I read the changes to the coding style introduced in that commit,
>> it's now possible to go over 80 columns, up to 100 columns, _if_
>> that actually improves the readability of the source code.
>
> The commit is for checkpatch. Point to the change in coding style. You
> are bringing argument for checkpatch, so only a tool, as argument for
> coding style. Again, coding style did not change since years.
Commit bdc48fa11e46 obviously addresses
Documentation/process/coding-style.rst
as well, as visible in the quotation from the commit below:
-The limit on the length of lines is 80 columns and this is a strongly
-preferred limit.
-
-Statements longer than 80 columns will be broken into sensible
chunks, unless
-exceeding 80 columns significantly increases readability and does not
hide
-information. Descendants are always substantially shorter than the
parent and
-are placed substantially to the right. The same applies to function
headers
-with a long argument list. However, never break user-visible strings
such as
-printk messages, because that breaks the ability to grep for them.
+The preferred limit on the length of a single line is 80 columns.
+
+Statements longer than 80 columns should be broken into sensible
chunks,
+unless exceeding 80 columns significantly increases readability and
does
+not hide information.
+
+Descendants are always substantially shorter than the parent and are
+are placed substantially to the right. A very commonly used style
+is to align descendants to a function open parenthesis.
+
+These same rules are applied to function headers with a long argument
list.
+
+However, never break user-visible strings such as printk messages
because
+that breaks the ability to grep for them.
I think it's obvious that the 80-column width is no longer _strongly_
preferred, but has been demoted to some kind of a bit weaker preference.
Also, please note that the coding style explicitly says that the 80-
column rule is to be followed "unless exceeding 80 columns significantly
increases readability and does not hide information".
This just reinforces my opinion that the readability is what matters
most when deciding on the column width, instead of following the rules
blindly, both when deciding whether to wrap some lines at column 50,
for example, or to wrap them at column 98.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 10:10 ` Dragan Simic
@ 2025-01-18 10:29 ` Krzysztof Kozlowski
2025-01-18 10:45 ` Dragan Simic
0 siblings, 1 reply; 44+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-18 10:29 UTC (permalink / raw)
To: Dragan Simic
Cc: Diederik de Haas, Peter Geis, Heiko Stuebner, zyw, kever.yang,
frank.wang, william.wu, wulf, linux-rockchip, Alex Bee,
Conor Dooley, Johan Jonker, Jonas Karlman, Krzysztof Kozlowski,
Rob Herring, devicetree, linux-arm-kernel, linux-kernel
On 18/01/2025 11:10, Dragan Simic wrote:
> On 2025-01-18 10:52, Krzysztof Kozlowski wrote:
>> On 18/01/2025 10:43, Dragan Simic wrote:
>>>>>
>>>>> Please see the commit bdc48fa11e46 (checkpatch/coding-style:
>>>>> deprecate
>>>>> 80-column warning, 2020-05-29), which clearly shows that the
>>>>> 80-column
>>>>> rule is still _preferred_, but no longer _mandatory_.
>>>>
>>>> I brought that commit, but nice that you also found it.
>>>>
>>>> Still: read the coding style, not checkpatch tool.
>>>>
>>>>>>> 80 columns is really not much (for the record, I've been around
>>>>>>> when
>>>>>>> using 80x25 _physical_ CRT screens was the norm).
>>>>>>
>>>>>> You mistake agreement on dropping strong restriction in 2020 in
>>>>>> checkpatch, which is "not for years" and even read that commit:
>>>>>> "Yes,
>>>>>> staying withing 80 columns is certainly still _preferred_."
>>>>>>
>>>>>> Checkpatch is not coding style. Since when it would be? It's just a
>>>>>> tool.
>>>>>>
>>>>>> And there were more talks and the 80-preference got relaxed yet
>>>>>> still
>>>>>> "not for years" (last talk was 2022?) and sill kernel coding style
>>>>>> is
>>>>>> here specific.
>>>>>
>>>>> It's perhaps again about the semantics, this time about the meaning
>>>>> of "for years". I don't think there's some strict definition of
>>>>> that
>>>>> term, so perhaps different people see it differently.
>>>>>
>>>>> To get back to the above-mentioned commit bdc48fa11e46, the
>>>>> 80-column
>>>>> limit has obviously been lifted, putting the new 100-column limit as
>>>>
>>>> "Lifted" on *CHECKPATCH*, not on coding style. Do you see the
>>
>> Repeating myself about because you are not addressing the actual
>> difference.
>
> Please see below.
>
>>>> difference? One is a helper tool which people were using blindly and
>>>> wrapping lines without thinking, claiming that checkpatch told them
>>>> to
>>>> do so. Other is the actual coding style.
>>>>
>>>> You claim that coding style was changed. This never happened.
>>>
>>> It was obviously changed in the commit bdc48fa11e46, by making the
>>> 80-column width preferred, instead of if being mandatory. The way
>>> I read the changes to the coding style introduced in that commit,
>>> it's now possible to go over 80 columns, up to 100 columns, _if_
>>> that actually improves the readability of the source code.
>>
>> The commit is for checkpatch. Point to the change in coding style. You
>> are bringing argument for checkpatch, so only a tool, as argument for
>> coding style. Again, coding style did not change since years.
>
> Commit bdc48fa11e46 obviously addresses
> Documentation/process/coding-style.rst
> as well, as visible in the quotation from the commit below:
Yes.
>
> -The limit on the length of lines is 80 columns and this is a strongly
80 is here...
> -preferred limit.
> -
> -Statements longer than 80 columns will be broken into sensible
> chunks, unless
> -exceeding 80 columns significantly increases readability and does not
> hide
> -information. Descendants are always substantially shorter than the
> parent and
> -are placed substantially to the right. The same applies to function
> headers
> -with a long argument list. However, never break user-visible strings
> such as
> -printk messages, because that breaks the ability to grep for them.
> +The preferred limit on the length of a single line is 80 columns.
> +
> +Statements longer than 80 columns should be broken into sensible
80 is here as well.
So now to your original statement:
" but the 100-column limit
for the kernel code has been in effect for years."
Where is 100? Only in checkpatch. There is no 100 limit in kernel coding
style.
The change in coding style and checkpatch was partially done because of
your understanding: reading checkpatch output as a rule. But this was
never a correct approach and still is not. So whatever checkpatch is
telling you, e.g. "100 column limit", is not coding style. It's only
checkpatch, a tool trying to help you.
> chunks,
> +unless exceeding 80 columns significantly increases readability and
> does
> +not hide information.
> +
> +Descendants are always substantially shorter than the parent and are
> +are placed substantially to the right. A very commonly used style
> +is to align descendants to a function open parenthesis.
> +
> +These same rules are applied to function headers with a long argument
> list.
> +
> +However, never break user-visible strings such as printk messages
> because
> +that breaks the ability to grep for them.
>
> I think it's obvious that the 80-column width is no longer _strongly_
> preferred, but has been demoted to some kind of a bit weaker preference.
Yes, but this is not what you said before and this is not what I questioned.
>
> Also, please note that the coding style explicitly says that the 80-
> column rule is to be followed "unless exceeding 80 columns significantly
> increases readability and does not hide information".
I already said it earlier... so yeah, we keep repeating ourselves while
discussing original point claiming now something else than we actually
discuss.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 10:29 ` Krzysztof Kozlowski
@ 2025-01-18 10:45 ` Dragan Simic
2025-01-18 14:22 ` Peter Geis
0 siblings, 1 reply; 44+ messages in thread
From: Dragan Simic @ 2025-01-18 10:45 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Diederik de Haas, Peter Geis, Heiko Stuebner, zyw, kever.yang,
frank.wang, william.wu, wulf, linux-rockchip, Alex Bee,
Conor Dooley, Johan Jonker, Jonas Karlman, Krzysztof Kozlowski,
Rob Herring, devicetree, linux-arm-kernel, linux-kernel
On 2025-01-18 11:29, Krzysztof Kozlowski wrote:
> On 18/01/2025 11:10, Dragan Simic wrote:
>> On 2025-01-18 10:52, Krzysztof Kozlowski wrote:
>>> On 18/01/2025 10:43, Dragan Simic wrote:
>>>>>>
>>>>>> Please see the commit bdc48fa11e46 (checkpatch/coding-style:
>>>>>> deprecate
>>>>>> 80-column warning, 2020-05-29), which clearly shows that the
>>>>>> 80-column
>>>>>> rule is still _preferred_, but no longer _mandatory_.
>>>>>
>>>>> I brought that commit, but nice that you also found it.
>>>>>
>>>>> Still: read the coding style, not checkpatch tool.
>>>>>
>>>>>>>> 80 columns is really not much (for the record, I've been around
>>>>>>>> when
>>>>>>>> using 80x25 _physical_ CRT screens was the norm).
>>>>>>>
>>>>>>> You mistake agreement on dropping strong restriction in 2020 in
>>>>>>> checkpatch, which is "not for years" and even read that commit:
>>>>>>> "Yes,
>>>>>>> staying withing 80 columns is certainly still _preferred_."
>>>>>>>
>>>>>>> Checkpatch is not coding style. Since when it would be? It's just
>>>>>>> a
>>>>>>> tool.
>>>>>>>
>>>>>>> And there were more talks and the 80-preference got relaxed yet
>>>>>>> still
>>>>>>> "not for years" (last talk was 2022?) and sill kernel coding
>>>>>>> style
>>>>>>> is
>>>>>>> here specific.
>>>>>>
>>>>>> It's perhaps again about the semantics, this time about the
>>>>>> meaning
>>>>>> of "for years". I don't think there's some strict definition of
>>>>>> that
>>>>>> term, so perhaps different people see it differently.
>>>>>>
>>>>>> To get back to the above-mentioned commit bdc48fa11e46, the
>>>>>> 80-column
>>>>>> limit has obviously been lifted, putting the new 100-column limit
>>>>>> as
>>>>>
>>>>> "Lifted" on *CHECKPATCH*, not on coding style. Do you see the
>>>
>>> Repeating myself about because you are not addressing the actual
>>> difference.
>>
>> Please see below.
>>
>>>>> difference? One is a helper tool which people were using blindly
>>>>> and
>>>>> wrapping lines without thinking, claiming that checkpatch told them
>>>>> to
>>>>> do so. Other is the actual coding style.
>>>>>
>>>>> You claim that coding style was changed. This never happened.
>>>>
>>>> It was obviously changed in the commit bdc48fa11e46, by making the
>>>> 80-column width preferred, instead of if being mandatory. The way
>>>> I read the changes to the coding style introduced in that commit,
>>>> it's now possible to go over 80 columns, up to 100 columns, _if_
>>>> that actually improves the readability of the source code.
>>>
>>> The commit is for checkpatch. Point to the change in coding style.
>>> You
>>> are bringing argument for checkpatch, so only a tool, as argument for
>>> coding style. Again, coding style did not change since years.
>>
>> Commit bdc48fa11e46 obviously addresses
>> Documentation/process/coding-style.rst
>> as well, as visible in the quotation from the commit below:
>
> Yes.
>
>>
>> -The limit on the length of lines is 80 columns and this is a
>> strongly
>
> 80 is here...
>
>> -preferred limit.
>> -
>> -Statements longer than 80 columns will be broken into sensible
>> chunks, unless
>> -exceeding 80 columns significantly increases readability and does
>> not
>> hide
>> -information. Descendants are always substantially shorter than the
>> parent and
>> -are placed substantially to the right. The same applies to
>> function
>> headers
>> -with a long argument list. However, never break user-visible
>> strings
>> such as
>> -printk messages, because that breaks the ability to grep for them.
>> +The preferred limit on the length of a single line is 80 columns.
>> +
>> +Statements longer than 80 columns should be broken into sensible
>
> 80 is here as well.
>
> So now to your original statement:
> " but the 100-column limit
> for the kernel code has been in effect for years."
>
> Where is 100? Only in checkpatch. There is no 100 limit in kernel
> coding
> style.
Yes, "100" is in checkpatch only, but the coding style explicitly
says that going over the 80-column limit it fine if it improves
the readability. Thus, going over the 80 columns has been allowed
"for years", whatever one finds that term to mean, or more precisely
since mid-2020, and having "100" present in checkpatch establishes
"100" as the effective "hard" limit.
> The change in coding style and checkpatch was partially done because of
> your understanding: reading checkpatch output as a rule. But this was
> never a correct approach and still is not. So whatever checkpatch is
> telling you, e.g. "100 column limit", is not coding style. It's only
> checkpatch, a tool trying to help you.
No, that isn't my understanding. I don't take checkpatch's output
as some kind of mandatory rules; however, what checkpatch does and
suggests should be based on the coding style, and if checkpatch
advises wrongly, it should be fixed instead of being accused to be
invalid and pointless.
Though, in this particular case, checkpatch does it right. The
coding style explicitly says that going over the 80-column limit
is fine if that improves the readability, and checkpatch follows
that by allowing up to 100 columns.
>> chunks,
>> +unless exceeding 80 columns significantly increases readability
>> and
>> does
>> +not hide information.
>> +
>> +Descendants are always substantially shorter than the parent and
>> are
>> +are placed substantially to the right. A very commonly used style
>> +is to align descendants to a function open parenthesis.
>> +
>> +These same rules are applied to function headers with a long
>> argument
>> list.
>> +
>> +However, never break user-visible strings such as printk messages
>> because
>> +that breaks the ability to grep for them.
>>
>> I think it's obvious that the 80-column width is no longer _strongly_
>> preferred, but has been demoted to some kind of a bit weaker
>> preference.
>
> Yes, but this is not what you said before and this is not what I
> questioned.
It is, if you read what I wrote above carefully. The 100-column
width limit has been in effect "for years", and has been defined
by the combination of the coding style and checkpatch. The former
says that going over 80 columns is fine, and the latter limits that
to 100 columns, to prevent some very long lines.
>> Also, please note that the coding style explicitly says that the 80-
>> column rule is to be followed "unless exceeding 80 columns
>> significantly
>> increases readability and does not hide information".
>
> I already said it earlier... so yeah, we keep repeating ourselves while
> discussing original point claiming now something else than we actually
> discuss.
I think it's again about the semantics. :) Please see above.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 10:45 ` Dragan Simic
@ 2025-01-18 14:22 ` Peter Geis
0 siblings, 0 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-18 14:22 UTC (permalink / raw)
To: Dragan Simic
Cc: Krzysztof Kozlowski, Diederik de Haas, Heiko Stuebner, zyw,
kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Alex Bee, Conor Dooley, Johan Jonker, Jonas Karlman,
Krzysztof Kozlowski, Rob Herring, devicetree, linux-arm-kernel,
linux-kernel
On Sat, Jan 18, 2025 at 5:45 AM Dragan Simic <dsimic@manjaro.org> wrote:
>
> On 2025-01-18 11:29, Krzysztof Kozlowski wrote:
> > On 18/01/2025 11:10, Dragan Simic wrote:
> >> On 2025-01-18 10:52, Krzysztof Kozlowski wrote:
> >>> On 18/01/2025 10:43, Dragan Simic wrote:
> >>>>>>
> >>>>>> Please see the commit bdc48fa11e46 (checkpatch/coding-style:
> >>>>>> deprecate
> >>>>>> 80-column warning, 2020-05-29), which clearly shows that the
> >>>>>> 80-column
> >>>>>> rule is still _preferred_, but no longer _mandatory_.
> >>>>>
> >>>>> I brought that commit, but nice that you also found it.
> >>>>>
> >>>>> Still: read the coding style, not checkpatch tool.
> >>>>>
> >>>>>>>> 80 columns is really not much (for the record, I've been around
> >>>>>>>> when
> >>>>>>>> using 80x25 _physical_ CRT screens was the norm).
> >>>>>>>
> >>>>>>> You mistake agreement on dropping strong restriction in 2020 in
> >>>>>>> checkpatch, which is "not for years" and even read that commit:
> >>>>>>> "Yes,
> >>>>>>> staying withing 80 columns is certainly still _preferred_."
> >>>>>>>
> >>>>>>> Checkpatch is not coding style. Since when it would be? It's just
> >>>>>>> a
> >>>>>>> tool.
> >>>>>>>
> >>>>>>> And there were more talks and the 80-preference got relaxed yet
> >>>>>>> still
> >>>>>>> "not for years" (last talk was 2022?) and sill kernel coding
> >>>>>>> style
> >>>>>>> is
> >>>>>>> here specific.
> >>>>>>
> >>>>>> It's perhaps again about the semantics, this time about the
> >>>>>> meaning
> >>>>>> of "for years". I don't think there's some strict definition of
> >>>>>> that
> >>>>>> term, so perhaps different people see it differently.
> >>>>>>
> >>>>>> To get back to the above-mentioned commit bdc48fa11e46, the
> >>>>>> 80-column
> >>>>>> limit has obviously been lifted, putting the new 100-column limit
> >>>>>> as
> >>>>>
> >>>>> "Lifted" on *CHECKPATCH*, not on coding style. Do you see the
> >>>
> >>> Repeating myself about because you are not addressing the actual
> >>> difference.
> >>
> >> Please see below.
> >>
> >>>>> difference? One is a helper tool which people were using blindly
> >>>>> and
> >>>>> wrapping lines without thinking, claiming that checkpatch told them
> >>>>> to
> >>>>> do so. Other is the actual coding style.
> >>>>>
> >>>>> You claim that coding style was changed. This never happened.
> >>>>
> >>>> It was obviously changed in the commit bdc48fa11e46, by making the
> >>>> 80-column width preferred, instead of if being mandatory. The way
> >>>> I read the changes to the coding style introduced in that commit,
> >>>> it's now possible to go over 80 columns, up to 100 columns, _if_
> >>>> that actually improves the readability of the source code.
> >>>
> >>> The commit is for checkpatch. Point to the change in coding style.
> >>> You
> >>> are bringing argument for checkpatch, so only a tool, as argument for
> >>> coding style. Again, coding style did not change since years.
> >>
> >> Commit bdc48fa11e46 obviously addresses
> >> Documentation/process/coding-style.rst
> >> as well, as visible in the quotation from the commit below:
> >
> > Yes.
> >
> >>
> >> -The limit on the length of lines is 80 columns and this is a
> >> strongly
> >
> > 80 is here...
> >
> >> -preferred limit.
> >> -
> >> -Statements longer than 80 columns will be broken into sensible
> >> chunks, unless
> >> -exceeding 80 columns significantly increases readability and does
> >> not
> >> hide
> >> -information. Descendants are always substantially shorter than the
> >> parent and
> >> -are placed substantially to the right. The same applies to
> >> function
> >> headers
> >> -with a long argument list. However, never break user-visible
> >> strings
> >> such as
> >> -printk messages, because that breaks the ability to grep for them.
> >> +The preferred limit on the length of a single line is 80 columns.
> >> +
> >> +Statements longer than 80 columns should be broken into sensible
> >
> > 80 is here as well.
> >
> > So now to your original statement:
> > " but the 100-column limit
> > for the kernel code has been in effect for years."
> >
> > Where is 100? Only in checkpatch. There is no 100 limit in kernel
> > coding
> > style.
>
> Yes, "100" is in checkpatch only, but the coding style explicitly
> says that going over the 80-column limit it fine if it improves
> the readability. Thus, going over the 80 columns has been allowed
> "for years", whatever one finds that term to mean, or more precisely
> since mid-2020, and having "100" present in checkpatch establishes
> "100" as the effective "hard" limit.
>
> > The change in coding style and checkpatch was partially done because of
> > your understanding: reading checkpatch output as a rule. But this was
> > never a correct approach and still is not. So whatever checkpatch is
> > telling you, e.g. "100 column limit", is not coding style. It's only
> > checkpatch, a tool trying to help you.
>
> No, that isn't my understanding. I don't take checkpatch's output
> as some kind of mandatory rules; however, what checkpatch does and
> suggests should be based on the coding style, and if checkpatch
> advises wrongly, it should be fixed instead of being accused to be
> invalid and pointless.
>
> Though, in this particular case, checkpatch does it right. The
> coding style explicitly says that going over the 80-column limit
> is fine if that improves the readability, and checkpatch follows
> that by allowing up to 100 columns.
>
> >> chunks,
> >> +unless exceeding 80 columns significantly increases readability
> >> and
> >> does
> >> +not hide information.
> >> +
> >> +Descendants are always substantially shorter than the parent and
> >> are
> >> +are placed substantially to the right. A very commonly used style
> >> +is to align descendants to a function open parenthesis.
> >> +
> >> +These same rules are applied to function headers with a long
> >> argument
> >> list.
> >> +
> >> +However, never break user-visible strings such as printk messages
> >> because
> >> +that breaks the ability to grep for them.
> >>
> >> I think it's obvious that the 80-column width is no longer _strongly_
> >> preferred, but has been demoted to some kind of a bit weaker
> >> preference.
> >
> > Yes, but this is not what you said before and this is not what I
> > questioned.
>
> It is, if you read what I wrote above carefully. The 100-column
> width limit has been in effect "for years", and has been defined
> by the combination of the coding style and checkpatch. The former
> says that going over 80 columns is fine, and the latter limits that
> to 100 columns, to prevent some very long lines.
I'd like to say I appreciate the 80 / 100 limit on code, as it pushed
me to separate out my driver code write operations into a separate
function and significantly clean up the code.
I apologize if my submissions aren't perfect the first time around. I
admit I'm still a baby developer, this is not my day job (although I'd
probably love it if it was). This is only the second driver I've
written from scratch (first, if you consider this is the second
iteration of a driver I wrote before my motorcomm driver). I depend
heavily on checkpatch and the feedback from maintainers, as well as
the coding style from similar drivers. The style and coding policies
that employed kernel maintainers and developers have committed to
heart I need to look up every time I submit something.
So, thank you for your feedback.
>
> >> Also, please note that the coding style explicitly says that the 80-
> >> column rule is to be followed "unless exceeding 80 columns
> >> significantly
> >> increases readability and does not hide information".
> >
> > I already said it earlier... so yeah, we keep repeating ourselves while
> > discussing original point claiming now something else than we actually
> > discuss.
>
> I think it's again about the semantics. :) Please see above.
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-18 9:08 ` Krzysztof Kozlowski
@ 2025-01-18 14:35 ` Peter Geis
0 siblings, 0 replies; 44+ messages in thread
From: Peter Geis @ 2025-01-18 14:35 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Heiko Stuebner, zyw, kever.yang, frank.wang, william.wu, wulf,
linux-rockchip, Alex Bee, Algea Cao, Arnd Bergmann, Conor Dooley,
Cristian Ciocaltea, Diederik de Haas, Dragan Simic, Elaine Zhang,
FUKAUMI Naoki, Johan Jonker, Jonas Karlman,
Kishon Vijay Abraham I, Krzysztof Kozlowski, Michael Turquette,
Philipp Zabel, Rob Herring, Sebastian Reichel, Stephen Boyd,
Trevor Woerner, Vinod Koul, Zhang Yubing, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-phy
On Sat, Jan 18, 2025 at 4:08 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On 15/01/2025 02:26, Peter Geis wrote:
> >
> > This is my newly reworked phy driver for the rk3328 usb3 phy. It is
> > based loosely on my original version, but as of now almost nothing of
> > the original driver remains. The main fix here is the discovery of
> > BIT(6) in the interrupt enable grf register fixes the usb3 disconnection
> > detection (mostly). On occasion an unpopulated usb3 hub will take
> > several seconds to disconnect. However this means all of the hack around
> > work to reset the usb core manually is no longer required.
> >
> BTW, RFC for some maintainers means "do not review, work-in-progress".
> For some means "review, but low priority" or "review, but for sure I
> have bugs here". I usually review and then someone responds: "it is not
> for review, it is just RFC", so to avoid my wasted time please always
> mention in cover letter why this is RFC. What do you expect here or why
> this is not ready for review as normal patch.
Thank you, that makes sense. I marked it as RFC as I'm aware it isn't
a perfect solution and there's a lot of undefined values. What I was
looking for here was:
- Review for code quality, so if I'm completely off track I can get to
work fixing it. (Thank you so far)
- Sanity testing from others struggling with the issues it fixes.
- Feedback from USB engineers about the issues remaining.
- Hopefully someone with access to the IP can provide insight into the
magic registers.
>
> Best regards,
> Krzysztof
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node
2025-01-18 8:41 ` Krzysztof Kozlowski
2025-01-18 9:19 ` Krzysztof Kozlowski
@ 2025-01-18 15:55 ` Diederik de Haas
1 sibling, 0 replies; 44+ messages in thread
From: Diederik de Haas @ 2025-01-18 15:55 UTC (permalink / raw)
To: Krzysztof Kozlowski, Peter Geis, Heiko Stuebner
Cc: zyw, kever.yang, frank.wang, william.wu, wulf, linux-rockchip,
Alex Bee, Conor Dooley, Dragan Simic, Johan Jonker, Jonas Karlman,
Krzysztof Kozlowski, Rob Herring, devicetree, linux-arm-kernel,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2587 bytes --]
On Sat Jan 18, 2025 at 9:41 AM CET, Krzysztof Kozlowski wrote:
> On 16/01/2025 17:53, Diederik de Haas wrote:
> > On Thu Jan 16, 2025 at 2:01 PM CET, Krzysztof Kozlowski wrote:
> >> On 15/01/2025 02:26, Peter Geis wrote:
> >>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> >>> index 7d992c3c01ce..181a900d41f9 100644
> >>> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> >>> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> >>> @@ -903,6 +903,43 @@ u2phy_host: host-port {
> >>> };
> >>> };
> >>>
> >>> + usb3phy: usb3-phy@ff460000 {
> >>> + compatible = "rockchip,rk3328-usb3phy";
> >>> + reg = <0x0 0xff460000 0x0 0x10000>;
> >>> + clocks = <&cru SCLK_REF_USB3OTG>, <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>;
> >>
> >> Please wrap code according to coding style (checkpatch is not a coding
> >> style description, but only a tool), so at 80.
> >
> > I'm confused: is it 80 or 100?
> >
> > I always thought it was 80, but then I saw several patches/commits by
>
> Coding style is clear: it is 80. It also has caveat about code
> readability and several maintainers have their own preference.
>
> > Dragan Simic which deliberately changed code to make use of 100.
> > Being fed up with my own confusion, I submitted a PR to
> > https://github.com/gregkh/kernel-coding-style/ which got accepted:
> > https://github.com/gregkh/kernel-coding-style/commit/5c21f99dc79883bd0efeba368193180275c9c77a
>
> That's not kernel. That's Greg...
FWIW: what Greg and Linus think/say is relevant to me.
> > So now both the vim plugins code and README say 100.
> > But as noted in my commit message:
> >
> > Note that the current upstream 'Linux kernel coding style' does NOT
> > mention the 100 char limit, but only mentions the preferred max length
> > of 80.
> >
> > Or is it 100 for code, but 80 for DeviceTree files and bindings?
>
> From where did you get 100? Checkpatch, right? Kernel coding style is
> clear, there is no discussion, no mentioning 100:
>
> "The preferred limit on the length of a single line is 80 columns. "
>
> So to be clear: all DTS, all DT bindings, all code maintained by me and
> some maintainers follows above (and further - there is caveat)
> instruction from coding style. Some maintainers follow other rules and
> that's fine.
But indeed, before Greg or Linus (likely) see it, a patch submitter
needs to convince the (subsystem) maintainer that it is an improvement.
Thanks for the clarification :-)
Cheers,
Diederik
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: (subset) [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328
2025-01-15 1:26 [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Peter Geis
` (7 preceding siblings ...)
2025-01-18 9:08 ` Krzysztof Kozlowski
@ 2025-02-26 19:49 ` Heiko Stuebner
8 siblings, 0 replies; 44+ messages in thread
From: Heiko Stuebner @ 2025-02-26 19:49 UTC (permalink / raw)
To: Peter Geis
Cc: Heiko Stuebner, zyw, kever.yang, frank.wang, william.wu, wulf,
linux-rockchip, Alex Bee, Algea Cao, Arnd Bergmann, Conor Dooley,
Cristian Ciocaltea, Diederik de Haas, Dragan Simic, Elaine Zhang,
FUKAUMI Naoki, Johan Jonker, Jonas Karlman,
Kishon Vijay Abraham I, Krzysztof Kozlowski, Michael Turquette,
Philipp Zabel, Rob Herring, Sebastian Reichel, Stephen Boyd,
Trevor Woerner, Vinod Koul, Zhang Yubing, devicetree,
linux-arm-kernel, linux-clk, linux-kernel, linux-phy
On Wed, 15 Jan 2025 01:26:21 +0000, Peter Geis wrote:
> This is my newly reworked phy driver for the rk3328 usb3 phy. It is
> based loosely on my original version, but as of now almost nothing of
> the original driver remains. The main fix here is the discovery of
> BIT(6) in the interrupt enable grf register fixes the usb3 disconnection
> detection (mostly). On occasion an unpopulated usb3 hub will take
> several seconds to disconnect. However this means all of the hack around
> work to reset the usb core manually is no longer required.
>
> [...]
Applied, thanks!
[1/6] clk: rockchip: fix wrong clk_ref_usb3otg parent for rk3328
commit: a9e60f1ffe1ca57d6af6a2573e2f950e76efbf5b
Best regards,
--
Heiko Stuebner <heiko@sntech.de>
^ permalink raw reply [flat|nested] 44+ messages in thread
end of thread, other threads:[~2025-02-26 19:54 UTC | newest]
Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-15 1:26 [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Peter Geis
2025-01-15 1:26 ` [RFC PATCH v1 1/6] clk: rockchip: fix wrong clk_ref_usb3otg parent " Peter Geis
2025-01-15 1:26 ` [RFC PATCH v1 2/6] dt-bindings: phy: rockchip: add rk3328 usb3 phy Peter Geis
2025-01-16 13:08 ` Krzysztof Kozlowski
2025-01-16 13:32 ` Peter Geis
2025-01-16 13:59 ` Peter Geis
2025-01-18 9:06 ` Krzysztof Kozlowski
2025-01-15 1:26 ` [RFC PATCH v1 3/6] phy: rockchip: add driver for " Peter Geis
2025-01-15 11:24 ` Piotr Oniszczuk
2025-01-16 14:09 ` Peter Geis
2025-01-16 12:59 ` Krzysztof Kozlowski
2025-01-16 13:14 ` Peter Geis
2025-01-16 15:26 ` Diederik de Haas
2025-01-16 15:57 ` Peter Geis
2025-01-15 1:26 ` [RFC PATCH v1 4/6] arm64: dts: rockchip: add rk3328 usb3 phy node Peter Geis
2025-01-16 13:01 ` Krzysztof Kozlowski
2025-01-16 16:53 ` Diederik de Haas
2025-01-17 4:10 ` Dragan Simic
2025-01-18 8:46 ` Krzysztof Kozlowski
2025-01-18 9:25 ` Dragan Simic
2025-01-18 9:31 ` Krzysztof Kozlowski
2025-01-18 9:43 ` Dragan Simic
2025-01-18 9:52 ` Krzysztof Kozlowski
2025-01-18 10:10 ` Dragan Simic
2025-01-18 10:29 ` Krzysztof Kozlowski
2025-01-18 10:45 ` Dragan Simic
2025-01-18 14:22 ` Peter Geis
2025-01-18 8:41 ` Krzysztof Kozlowski
2025-01-18 9:19 ` Krzysztof Kozlowski
2025-01-18 9:34 ` Dragan Simic
2025-01-18 15:55 ` Diederik de Haas
2025-01-15 1:26 ` [RFC PATCH v1 5/6] arm64: dts: rockchip: enable the usb3 phy on rk3328-roc boards Peter Geis
2025-01-15 1:26 ` [RFC PATCH v1 6/6] arm64: dts: rockchip: enable the usb3 phy on remaining rk3328 boards Peter Geis
2025-01-15 11:22 ` [RFC PATCH v1 0/6] rockchip: add a functional usb3 phy driver for rk3328 Piotr Oniszczuk
2025-01-15 12:25 ` Peter Geis
2025-01-15 12:35 ` Piotr Oniszczuk
2025-01-15 13:15 ` Peter Geis
2025-01-15 13:25 ` Piotr Oniszczuk
2025-01-16 14:02 ` Peter Geis
2025-01-16 14:35 ` Piotr Oniszczuk
2025-01-16 16:00 ` Peter Geis
2025-01-18 9:08 ` Krzysztof Kozlowski
2025-01-18 14:35 ` Peter Geis
2025-02-26 19:49 ` (subset) " Heiko Stuebner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).