Merge tag 'phy-for-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy

Pull phy updates from Vinod Koul:
"The usual bunch of device support and update to drivers.

New Support
- Qualcomm SM8750 QMP PCIe PHY dual lane support, PMIV0104 eusb2
repeater support, QCS8300 eDP PHY support
- Renesas RZ/T2H and RZ/N2H support and updates to driver for that
- TI TCAN1051 phy support
- Rockchip rk3588 dphy support, RK3528 combphy support

Updates:
- cadence updates for calibration and polling for ready and enabling
of lower resolutions, runtime pm support,
- Rockchip: enable U3 otg port
- Renesas USXGMII mode support
- Qualcomm UFS PHY and PLL regulator load support"

* tag 'phy-for-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (64 commits)
phy: rockchip: phy-rockchip-inno-csidphy: add support for rk3588 variant
phy: rockchip: phy-rockchip-inno-csidphy: allow for different reset lines
phy: rockchip: phy-rockchip-inno-csidphy: allow writes to grf register 0
dt-bindings: phy: rockchip-inno-csi-dphy: add rk3588 variant
dt-bindings: phy: rockchip-inno-csi-dphy: make power-domains non-required
phy: cadence: cdns-dphy: Enable lower resolutions in dphy
phy: renesas: r8a779f0-ether-serdes: add new step added to latest datasheet
phy: renesas: r8a779f0-ether-serdes: add USXGMII mode
phy: sophgo: Add USB 2.0 PHY driver for Sophgo CV18XX/SG200X
dt-bindings: phy: Add Sophgo CV1800 USB phy
phy: cadence: cdns-dphy: Update calibration wait time for startup state machine
phy: cadence: cdns-dphy: Fix PLL lock and O_CMN_READY polling
phy: renesas: rcar-gen3-usb2: Fix ID check logic with VBUS valid
dt-bindings: phy: ti,tcan104x-can: Document TI TCAN1051
phy: lynx-28g: check return value when calling lynx_28g_pll_get
phy: qcom: m31-eusb2: Fix the error log while enabling clock
phy: rockchip: usbdp: Remove redundant ternary operators
phy: renesas: rcar-gen3-usb2: Remove redundant ternary operators
phy: hisilicon: Remove redundant ternary operators
phy: qcom-qmp-ufs: Add PHY and PLL regulator load
...

+1657 -493
-1
Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
··· 76 description: 77 Adjust TX de-emphasis attenuation in dB at nominal 78 3.5dB point as per USB specification 79 - $ref: /schemas/types.yaml#/definitions/uint32 80 minimum: 0 81 maximum: 36 82
··· 76 description: 77 Adjust TX de-emphasis attenuation in dB at nominal 78 3.5dB point as per USB specification 79 minimum: 0 80 maximum: 36 81
+7 -1
Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
··· 12 properties: 13 compatible: 14 enum: 15 - rockchip,rk3562-naneng-combphy 16 - rockchip,rk3568-naneng-combphy 17 - rockchip,rk3576-naneng-combphy ··· 45 46 phy-supply: 47 description: Single PHY regulator 48 49 rockchip,enable-ssc: 50 type: boolean ··· 109 properties: 110 compatible: 111 contains: 112 - const: rockchip,rk3588-naneng-combphy 113 then: 114 properties: 115 resets:
··· 12 properties: 13 compatible: 14 enum: 15 + - rockchip,rk3528-naneng-combphy 16 - rockchip,rk3562-naneng-combphy 17 - rockchip,rk3568-naneng-combphy 18 - rockchip,rk3576-naneng-combphy ··· 44 45 phy-supply: 46 description: Single PHY regulator 47 + 48 + power-domains: 49 + maxItems: 1 50 51 rockchip,enable-ssc: 52 type: boolean ··· 105 properties: 106 compatible: 107 contains: 108 + enum: 109 + - rockchip,rk3528-naneng-combphy 110 + - rockchip,rk3588-naneng-combphy 111 then: 112 properties: 113 resets:
+12 -7
Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
··· 16 17 properties: 18 compatible: 19 - enum: 20 - - qcom,sa8775p-edp-phy 21 - - qcom,sc7280-edp-phy 22 - - qcom,sc8180x-edp-phy 23 - - qcom,sc8280xp-dp-phy 24 - - qcom,sc8280xp-edp-phy 25 - - qcom,x1e80100-dp-phy 26 27 reg: 28 items:
··· 16 17 properties: 18 compatible: 19 + oneOf: 20 + - enum: 21 + - qcom,sa8775p-edp-phy 22 + - qcom,sc7280-edp-phy 23 + - qcom,sc8180x-edp-phy 24 + - qcom,sc8280xp-dp-phy 25 + - qcom,sc8280xp-edp-phy 26 + - qcom,x1e80100-dp-phy 27 + - items: 28 + - enum: 29 + - qcom,qcs8300-edp-phy 30 + - const: qcom,sa8775p-edp-phy 31 32 reg: 33 items:
+2
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
··· 42 - qcom,sm8550-qmp-gen4x2-pcie-phy 43 - qcom,sm8650-qmp-gen3x2-pcie-phy 44 - qcom,sm8650-qmp-gen4x2-pcie-phy 45 - qcom,x1e80100-qmp-gen3x2-pcie-phy 46 - qcom,x1e80100-qmp-gen4x2-pcie-phy 47 - qcom,x1e80100-qmp-gen4x4-pcie-phy ··· 165 - qcom,sm8550-qmp-gen4x2-pcie-phy 166 - qcom,sm8650-qmp-gen3x2-pcie-phy 167 - qcom,sm8650-qmp-gen4x2-pcie-phy 168 then: 169 properties: 170 clocks:
··· 42 - qcom,sm8550-qmp-gen4x2-pcie-phy 43 - qcom,sm8650-qmp-gen3x2-pcie-phy 44 - qcom,sm8650-qmp-gen4x2-pcie-phy 45 + - qcom,sm8750-qmp-gen3x2-pcie-phy 46 - qcom,x1e80100-qmp-gen3x2-pcie-phy 47 - qcom,x1e80100-qmp-gen4x2-pcie-phy 48 - qcom,x1e80100-qmp-gen4x4-pcie-phy ··· 164 - qcom,sm8550-qmp-gen4x2-pcie-phy 165 - qcom,sm8650-qmp-gen3x2-pcie-phy 166 - qcom,sm8650-qmp-gen4x2-pcie-phy 167 + - qcom,sm8750-qmp-gen3x2-pcie-phy 168 then: 169 properties: 170 clocks:
+3 -4
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
··· 73 description: 74 See include/dt-bindings/phy/phy-qcom-qmp.h 75 76 - orientation-switch: 77 - description: 78 - Flag the PHY as possible handler of USB Type-C orientation switching 79 - type: boolean 80 81 ports: 82 $ref: /schemas/graph.yaml#/properties/ports ··· 104 - "#phy-cells" 105 106 allOf: 107 - if: 108 properties: 109 compatible:
··· 73 description: 74 See include/dt-bindings/phy/phy-qcom-qmp.h 75 76 + mode-switch: true 77 + orientation-switch: true 78 79 ports: 80 $ref: /schemas/graph.yaml#/properties/ports ··· 106 - "#phy-cells" 107 108 allOf: 109 + - $ref: /schemas/usb/usb-switch.yaml# 110 - if: 111 properties: 112 compatible:
+7
Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml
··· 22 - const: qcom,pm8550b-eusb2-repeater 23 - enum: 24 - qcom,pm8550b-eusb2-repeater 25 - qcom,smb2360-eusb2-repeater 26 27 reg: ··· 50 qcom,tune-usb2-preem: 51 $ref: /schemas/types.yaml#/definitions/uint8 52 description: High-Speed TX pre-emphasis tuning 53 minimum: 0 54 maximum: 7 55
··· 22 - const: qcom,pm8550b-eusb2-repeater 23 - enum: 24 - qcom,pm8550b-eusb2-repeater 25 + - qcom,pmiv0104-eusb2-repeater 26 - qcom,smb2360-eusb2-repeater 27 28 reg: ··· 49 qcom,tune-usb2-preem: 50 $ref: /schemas/types.yaml#/definitions/uint8 51 description: High-Speed TX pre-emphasis tuning 52 + minimum: 0 53 + maximum: 7 54 + 55 + qcom,tune-res-fsdif: 56 + $ref: /schemas/types.yaml#/definitions/uint8 57 + description: FS Differential TX Output Resistance Tuning 58 minimum: 0 59 maximum: 7 60
+17
Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
··· 44 - const: renesas,usb2-phy-r9a09g056 # RZ/V2N 45 - const: renesas,usb2-phy-r9a09g057 46 47 reg: 48 maxItems: 1 49 ··· 125 minItems: 2 126 required: 127 - resets 128 129 additionalProperties: false 130
··· 44 - const: renesas,usb2-phy-r9a09g056 # RZ/V2N 45 - const: renesas,usb2-phy-r9a09g057 46 47 + - const: renesas,usb2-phy-r9a09g077 # RZ/T2H 48 + 49 + - items: 50 + - const: renesas,usb2-phy-r9a09g087 # RZ/N2H 51 + - const: renesas,usb2-phy-r9a09g077 52 + 53 reg: 54 maxItems: 1 55 ··· 119 minItems: 2 120 required: 121 - resets 122 + 123 + - if: 124 + properties: 125 + compatible: 126 + contains: 127 + const: renesas,usb2-phy-r9a09g077 128 + then: 129 + properties: 130 + clocks: 131 + minItems: 2 132 + resets: false 133 134 additionalProperties: false 135
+63 -2
Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
··· 21 - rockchip,rk3326-csi-dphy 22 - rockchip,rk3368-csi-dphy 23 - rockchip,rk3568-csi-dphy 24 25 reg: 26 maxItems: 1 ··· 41 42 resets: 43 items: 44 - - description: exclusive PHY reset line 45 46 reset-names: 47 items: 48 - const: apb 49 50 rockchip,grf: 51 $ref: /schemas/types.yaml#/definitions/phandle ··· 62 - clocks 63 - clock-names 64 - '#phy-cells' 65 - - power-domains 66 - resets 67 - reset-names 68 - rockchip,grf 69 70 additionalProperties: false 71 ··· 119 resets = <&cru 1>; 120 reset-names = "apb"; 121 rockchip,grf = <&grf>; 122 };
··· 21 - rockchip,rk3326-csi-dphy 22 - rockchip,rk3368-csi-dphy 23 - rockchip,rk3568-csi-dphy 24 + - rockchip,rk3588-csi-dphy 25 26 reg: 27 maxItems: 1 ··· 40 41 resets: 42 items: 43 + - description: APB reset line 44 + - description: PHY reset line 45 + minItems: 1 46 47 reset-names: 48 items: 49 - const: apb 50 + - const: phy 51 + minItems: 1 52 53 rockchip,grf: 54 $ref: /schemas/types.yaml#/definitions/phandle ··· 57 - clocks 58 - clock-names 59 - '#phy-cells' 60 - resets 61 - reset-names 62 - rockchip,grf 63 + 64 + allOf: 65 + - if: 66 + properties: 67 + compatible: 68 + contains: 69 + enum: 70 + - rockchip,px30-csi-dphy 71 + - rockchip,rk1808-csi-dphy 72 + - rockchip,rk3326-csi-dphy 73 + - rockchip,rk3368-csi-dphy 74 + then: 75 + required: 76 + - power-domains 77 + - if: 78 + properties: 79 + compatible: 80 + contains: 81 + enum: 82 + - rockchip,px30-csi-dphy 83 + - rockchip,rk1808-csi-dphy 84 + - rockchip,rk3326-csi-dphy 85 + - rockchip,rk3368-csi-dphy 86 + - rockchip,rk3568-csi-dphy 87 + then: 88 + properties: 89 + resets: 90 + maxItems: 1 91 + 92 + reset-names: 93 + maxItems: 1 94 + else: 95 + properties: 96 + resets: 97 + minItems: 2 98 + 99 + reset-names: 100 + minItems: 2 101 102 additionalProperties: false 103 ··· 77 resets = <&cru 1>; 78 reset-names = "apb"; 79 rockchip,grf = <&grf>; 80 + }; 81 + - | 82 + #include <dt-bindings/clock/rockchip,rk3588-cru.h> 83 + #include <dt-bindings/reset/rockchip,rk3588-cru.h> 84 + 85 + soc { 86 + #address-cells = <2>; 87 + #size-cells = <2>; 88 + 89 + phy@fedc0000 { 90 + compatible = "rockchip,rk3588-csi-dphy"; 91 + reg = <0x0 0xfedc0000 0x0 0x8000>; 92 + clocks = <&cru PCLK_CSIPHY0>; 93 + clock-names = "pclk"; 94 + #phy-cells = <0>; 95 + resets = <&cru SRST_P_CSIPHY0>, <&cru SRST_CSIPHY0>; 96 + reset-names = "apb", "phy"; 97 + rockchip,grf = <&csidphy0_grf>; 98 + }; 99 };
+54
Documentation/devicetree/bindings/phy/sophgo,cv1800b-usb2-phy.yaml
···
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/sophgo,cv1800b-usb2-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Sophgo CV18XX/SG200X USB 2.0 PHY 8 + 9 + maintainers: 10 + - Inochi Amaoto <inochiama@gmail.com> 11 + 12 + properties: 13 + compatible: 14 + const: sophgo,cv1800b-usb2-phy 15 + 16 + reg: 17 + maxItems: 1 18 + 19 + "#phy-cells": 20 + const: 0 21 + 22 + clocks: 23 + items: 24 + - description: PHY app clock 25 + - description: PHY stb clock 26 + - description: PHY lpm clock 27 + 28 + clock-names: 29 + items: 30 + - const: app 31 + - const: stb 32 + - const: lpm 33 + 34 + resets: 35 + maxItems: 1 36 + 37 + required: 38 + - compatible 39 + - "#phy-cells" 40 + - clocks 41 + - clock-names 42 + 43 + additionalProperties: false 44 + 45 + examples: 46 + - | 47 + phy@48 { 48 + compatible = "sophgo,cv1800b-usb2-phy"; 49 + reg = <0x48 0x4>; 50 + #phy-cells = <0>; 51 + clocks = <&clk 93>, <&clk 94>, <&clk 95>; 52 + clock-names = "app", "stb", "lpm"; 53 + resets = <&rst 58>; 54 + };
+1
Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
··· 18 - items: 19 - enum: 20 - microchip,ata6561 21 - const: ti,tcan1042 22 - enum: 23 - ti,tcan1042
··· 18 - items: 19 - enum: 20 - microchip,ata6561 21 + - ti,tcan1051 22 - const: ti,tcan1042 23 - enum: 24 - ti,tcan1042
+1
Documentation/devicetree/bindings/soc/rockchip/grf.yaml
··· 16 - enum: 17 - rockchip,rk3288-sgrf 18 - rockchip,rk3528-ioc-grf 19 - rockchip,rk3528-vo-grf 20 - rockchip,rk3528-vpu-grf 21 - rockchip,rk3562-ioc-grf
··· 16 - enum: 17 - rockchip,rk3288-sgrf 18 - rockchip,rk3528-ioc-grf 19 + - rockchip,rk3528-pipe-phy-grf 20 - rockchip,rk3528-vo-grf 21 - rockchip,rk3528-vpu-grf 22 - rockchip,rk3562-ioc-grf
+1
drivers/phy/Kconfig
··· 122 source "drivers/phy/rockchip/Kconfig" 123 source "drivers/phy/samsung/Kconfig" 124 source "drivers/phy/socionext/Kconfig" 125 source "drivers/phy/st/Kconfig" 126 source "drivers/phy/starfive/Kconfig" 127 source "drivers/phy/sunplus/Kconfig"
··· 122 source "drivers/phy/rockchip/Kconfig" 123 source "drivers/phy/samsung/Kconfig" 124 source "drivers/phy/socionext/Kconfig" 125 + source "drivers/phy/sophgo/Kconfig" 126 source "drivers/phy/st/Kconfig" 127 source "drivers/phy/starfive/Kconfig" 128 source "drivers/phy/sunplus/Kconfig"
+1
drivers/phy/Makefile
··· 35 rockchip/ \ 36 samsung/ \ 37 socionext/ \ 38 st/ \ 39 starfive/ \ 40 sunplus/ \
··· 35 rockchip/ \ 36 samsung/ \ 37 socionext/ \ 38 + sophgo/ \ 39 st/ \ 40 starfive/ \ 41 sunplus/ \
+13 -25
drivers/phy/allwinner/phy-sun4i-usb.c
··· 97 #define POLL_TIME msecs_to_jiffies(250) 98 99 struct sun4i_usb_phy_cfg { 100 - int num_phys; 101 int hsic_index; 102 u32 disc_thresh; 103 u32 hci_phy_ctl_clear; ··· 114 const struct sun4i_usb_phy_cfg *cfg; 115 enum usb_dr_mode dr_mode; 116 spinlock_t reg_lock; /* guard access to phyctl reg */ 117 struct sun4i_usb_phy { 118 struct phy *phy; 119 void __iomem *pmu; ··· 686 { 687 struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); 688 689 - if (args->args[0] >= data->cfg->num_phys) 690 return ERR_PTR(-ENODEV); 691 692 if (data->cfg->missing_phys & BIT(args->args[0])) ··· 779 return ret; 780 } 781 782 - for (i = 0; i < data->cfg->num_phys; i++) { 783 struct sun4i_usb_phy *phy = data->phys + i; 784 char name[32]; 785 786 if (data->cfg->missing_phys & BIT(i)) 787 continue; 788 789 snprintf(name, sizeof(name), "usb%d_vbus", i); 790 phy->vbus = devm_regulator_get_optional(dev, name); ··· 837 } 838 } 839 840 - snprintf(name, sizeof(name), "usb%d_reset", i); 841 - phy->reset = devm_reset_control_get(dev, name); 842 - if (IS_ERR(phy->reset)) { 843 - dev_err(dev, "failed to get reset %s\n", name); 844 - return PTR_ERR(phy->reset); 845 - } 846 - 847 if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */ 848 snprintf(name, sizeof(name), "pmu%d", i); 849 phy->pmu = devm_platform_ioremap_resource_byname(pdev, name); ··· 853 phy->index = i; 854 phy_set_drvdata(phy->phy, &data->phys[i]); 855 } 856 857 data->id_det_irq = gpiod_to_irq(data->id_det_gpio); 858 if (data->id_det_irq > 0) { ··· 904 } 905 906 static const struct sun4i_usb_phy_cfg suniv_f1c100s_cfg = { 907 - .num_phys = 1, 908 .disc_thresh = 3, 909 .phyctl_offset = REG_PHYCTL_A10, 910 .dedicated_clocks = true, 911 }; 912 913 static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = { 914 - .num_phys = 3, 915 .disc_thresh = 3, 916 .phyctl_offset = REG_PHYCTL_A10, 917 .dedicated_clocks = false, 918 }; 919 920 static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { 921 - .num_phys = 2, 922 .disc_thresh = 2, 923 .phyctl_offset = REG_PHYCTL_A10, 924 .dedicated_clocks = false, 925 }; 926 927 static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { 928 - .num_phys = 3, 929 .disc_thresh = 3, 930 .phyctl_offset = REG_PHYCTL_A10, 931 .dedicated_clocks = true, ··· 929 }; 930 931 static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { 932 - .num_phys = 3, 933 .disc_thresh = 2, 934 .phyctl_offset = REG_PHYCTL_A10, 935 .dedicated_clocks = false, 936 }; 937 938 static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { 939 - .num_phys = 2, 940 .disc_thresh = 3, 941 .phyctl_offset = REG_PHYCTL_A10, 942 .dedicated_clocks = true, ··· 942 }; 943 944 static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { 945 - .num_phys = 2, 946 .disc_thresh = 3, 947 .phyctl_offset = REG_PHYCTL_A33, 948 .dedicated_clocks = true, ··· 949 }; 950 951 static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = { 952 - .num_phys = 3, 953 .hsic_index = 2, 954 .phyctl_offset = REG_PHYCTL_A33, 955 .dedicated_clocks = true, ··· 956 }; 957 958 static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { 959 - .num_phys = 4, 960 .disc_thresh = 3, 961 .phyctl_offset = REG_PHYCTL_A33, 962 .dedicated_clocks = true, ··· 964 }; 965 966 static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = { 967 - .num_phys = 3, 968 .disc_thresh = 3, 969 .phyctl_offset = REG_PHYCTL_A33, 970 .dedicated_clocks = true, ··· 972 }; 973 974 static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { 975 - .num_phys = 1, 976 .disc_thresh = 3, 977 .phyctl_offset = REG_PHYCTL_A33, 978 .dedicated_clocks = true, ··· 980 }; 981 982 static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = { 983 - .num_phys = 2, 984 .phyctl_offset = REG_PHYCTL_A33, 985 .dedicated_clocks = true, 986 .hci_phy_ctl_clear = PHY_CTL_SIDDQ, ··· 988 }; 989 990 static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { 991 - .num_phys = 2, 992 .disc_thresh = 3, 993 .phyctl_offset = REG_PHYCTL_A33, 994 .dedicated_clocks = true, ··· 996 }; 997 998 static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = { 999 - .num_phys = 4, 1000 .phyctl_offset = REG_PHYCTL_A33, 1001 .dedicated_clocks = true, 1002 .phy0_dual_route = true, ··· 1004 }; 1005 1006 static const struct sun4i_usb_phy_cfg sun50i_h616_cfg = { 1007 - .num_phys = 4, 1008 .disc_thresh = 3, 1009 .phyctl_offset = REG_PHYCTL_A33, 1010 .dedicated_clocks = true,
··· 97 #define POLL_TIME msecs_to_jiffies(250) 98 99 struct sun4i_usb_phy_cfg { 100 int hsic_index; 101 u32 disc_thresh; 102 u32 hci_phy_ctl_clear; ··· 115 const struct sun4i_usb_phy_cfg *cfg; 116 enum usb_dr_mode dr_mode; 117 spinlock_t reg_lock; /* guard access to phyctl reg */ 118 + int num_phys; 119 struct sun4i_usb_phy { 120 struct phy *phy; 121 void __iomem *pmu; ··· 686 { 687 struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); 688 689 + if (args->args[0] >= data->num_phys) 690 return ERR_PTR(-ENODEV); 691 692 if (data->cfg->missing_phys & BIT(args->args[0])) ··· 779 return ret; 780 } 781 782 + for (i = 0; i < MAX_PHYS; i++) { 783 struct sun4i_usb_phy *phy = data->phys + i; 784 char name[32]; 785 786 if (data->cfg->missing_phys & BIT(i)) 787 continue; 788 + 789 + snprintf(name, sizeof(name), "usb%d_reset", i); 790 + phy->reset = devm_reset_control_get(dev, name); 791 + if (IS_ERR(phy->reset)) { 792 + if (PTR_ERR(phy->reset) == -ENOENT) 793 + break; 794 + dev_err(dev, "failed to get reset %s\n", name); 795 + return PTR_ERR(phy->reset); 796 + } 797 798 snprintf(name, sizeof(name), "usb%d_vbus", i); 799 phy->vbus = devm_regulator_get_optional(dev, name); ··· 828 } 829 } 830 831 if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */ 832 snprintf(name, sizeof(name), "pmu%d", i); 833 phy->pmu = devm_platform_ioremap_resource_byname(pdev, name); ··· 851 phy->index = i; 852 phy_set_drvdata(phy->phy, &data->phys[i]); 853 } 854 + data->num_phys = i; 855 856 data->id_det_irq = gpiod_to_irq(data->id_det_gpio); 857 if (data->id_det_irq > 0) { ··· 901 } 902 903 static const struct sun4i_usb_phy_cfg suniv_f1c100s_cfg = { 904 .disc_thresh = 3, 905 .phyctl_offset = REG_PHYCTL_A10, 906 .dedicated_clocks = true, 907 }; 908 909 static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = { 910 .disc_thresh = 3, 911 .phyctl_offset = REG_PHYCTL_A10, 912 .dedicated_clocks = false, 913 }; 914 915 static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { 916 .disc_thresh = 2, 917 .phyctl_offset = REG_PHYCTL_A10, 918 .dedicated_clocks = false, 919 }; 920 921 static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { 922 .disc_thresh = 3, 923 .phyctl_offset = REG_PHYCTL_A10, 924 .dedicated_clocks = true, ··· 930 }; 931 932 static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { 933 .disc_thresh = 2, 934 .phyctl_offset = REG_PHYCTL_A10, 935 .dedicated_clocks = false, 936 }; 937 938 static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { 939 .disc_thresh = 3, 940 .phyctl_offset = REG_PHYCTL_A10, 941 .dedicated_clocks = true, ··· 945 }; 946 947 static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { 948 .disc_thresh = 3, 949 .phyctl_offset = REG_PHYCTL_A33, 950 .dedicated_clocks = true, ··· 953 }; 954 955 static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = { 956 .hsic_index = 2, 957 .phyctl_offset = REG_PHYCTL_A33, 958 .dedicated_clocks = true, ··· 961 }; 962 963 static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { 964 .disc_thresh = 3, 965 .phyctl_offset = REG_PHYCTL_A33, 966 .dedicated_clocks = true, ··· 970 }; 971 972 static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = { 973 .disc_thresh = 3, 974 .phyctl_offset = REG_PHYCTL_A33, 975 .dedicated_clocks = true, ··· 979 }; 980 981 static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { 982 .disc_thresh = 3, 983 .phyctl_offset = REG_PHYCTL_A33, 984 .dedicated_clocks = true, ··· 988 }; 989 990 static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = { 991 .phyctl_offset = REG_PHYCTL_A33, 992 .dedicated_clocks = true, 993 .hci_phy_ctl_clear = PHY_CTL_SIDDQ, ··· 997 }; 998 999 static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { 1000 .disc_thresh = 3, 1001 .phyctl_offset = REG_PHYCTL_A33, 1002 .dedicated_clocks = true, ··· 1006 }; 1007 1008 static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = { 1009 .phyctl_offset = REG_PHYCTL_A33, 1010 .dedicated_clocks = true, 1011 .phy0_dual_route = true, ··· 1015 }; 1016 1017 static const struct sun4i_usb_phy_cfg sun50i_h616_cfg = { 1018 .disc_thresh = 3, 1019 .phyctl_offset = REG_PHYCTL_A33, 1020 .dedicated_clocks = true,
-1
drivers/phy/broadcom/phy-brcm-sata.c
··· 850 MODULE_LICENSE("GPL"); 851 MODULE_AUTHOR("Marc Carino"); 852 MODULE_AUTHOR("Brian Norris"); 853 - MODULE_ALIAS("platform:phy-brcm-sata");
··· 850 MODULE_LICENSE("GPL"); 851 MODULE_AUTHOR("Marc Carino"); 852 MODULE_AUTHOR("Brian Norris");
-1
drivers/phy/broadcom/phy-brcm-usb.c
··· 691 692 module_platform_driver(brcm_usb_driver); 693 694 - MODULE_ALIAS("platform:brcmstb-usb-phy"); 695 MODULE_AUTHOR("Al Cooper <acooper@broadcom.com>"); 696 MODULE_DESCRIPTION("BRCM USB PHY driver"); 697 MODULE_LICENSE("GPL v2");
··· 691 692 module_platform_driver(brcm_usb_driver); 693 694 MODULE_AUTHOR("Al Cooper <acooper@broadcom.com>"); 695 MODULE_DESCRIPTION("BRCM USB PHY driver"); 696 MODULE_LICENSE("GPL v2");
+2 -1
drivers/phy/cadence/cdns-dphy-rx.c
··· 12 #include <linux/phy/phy.h> 13 #include <linux/phy/phy-mipi-dphy.h> 14 #include <linux/platform_device.h> 15 #include <linux/sys_soc.h> 16 17 #define DPHY_PMA_CMN(reg) (reg) ··· 266 return PTR_ERR(provider); 267 } 268 269 - return 0; 270 } 271 272 static const struct of_device_id cdns_dphy_rx_of_match[] = {
··· 12 #include <linux/phy/phy.h> 13 #include <linux/phy/phy-mipi-dphy.h> 14 #include <linux/platform_device.h> 15 + #include <linux/pm_runtime.h> 16 #include <linux/sys_soc.h> 17 18 #define DPHY_PMA_CMN(reg) (reg) ··· 265 return PTR_ERR(provider); 266 } 267 268 + return devm_pm_runtime_enable(dev); 269 } 270 271 static const struct of_device_id cdns_dphy_rx_of_match[] = {
+107 -49
drivers/phy/cadence/cdns-dphy.c
··· 30 31 #define DPHY_CMN_SSM DPHY_PMA_CMN(0x20) 32 #define DPHY_CMN_SSM_EN BIT(0) 33 #define DPHY_CMN_TX_MODE_EN BIT(9) 34 35 #define DPHY_CMN_PWM DPHY_PMA_CMN(0x40) ··· 56 #define DPHY_PSM_CFG_FROM_REG BIT(0) 57 #define DPHY_PSM_CLK_DIV(x) ((x) << 1) 58 59 - #define DSI_HBP_FRAME_OVERHEAD 12 60 - #define DSI_HSA_FRAME_OVERHEAD 14 61 - #define DSI_HFP_FRAME_OVERHEAD 6 62 - #define DSI_HSS_VSS_VSE_FRAME_OVERHEAD 4 63 - #define DSI_BLANKING_FRAME_OVERHEAD 6 64 - #define DSI_NULL_FRAME_OVERHEAD 6 65 - #define DSI_EOT_PKT_SIZE 4 66 - 67 #define DPHY_TX_J721E_WIZ_PLL_CTRL 0xF04 68 #define DPHY_TX_J721E_WIZ_STATUS 0xF08 69 #define DPHY_TX_J721E_WIZ_RST_CTRL 0xF0C ··· 72 u8 pll_ipdiv; 73 u8 pll_opdiv; 74 u16 pll_fbdiv; 75 unsigned int nlanes; 76 }; 77 ··· 93 void (*set_pll_cfg)(struct cdns_dphy *dphy, 94 const struct cdns_dphy_cfg *cfg); 95 unsigned long (*get_wakeup_time_ns)(struct cdns_dphy *dphy); 96 }; 97 98 struct cdns_dphy { ··· 104 struct clk *pll_ref_clk; 105 const struct cdns_dphy_ops *ops; 106 struct phy *phy; 107 }; 108 109 /* Order of bands is important since the index is the band number. */ ··· 114 870, 950, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2500 115 }; 116 117 - static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, 118 - struct cdns_dphy_cfg *cfg, 119 - struct phy_configure_opts_mipi_dphy *opts, 120 - unsigned int *dsi_hfp_ext) 121 { 122 unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk); 123 u64 dlane_bps; ··· 136 137 dlane_bps = opts->hs_clk_rate; 138 139 - if (dlane_bps > 2500000000UL || dlane_bps < 160000000UL) 140 return -EINVAL; 141 else if (dlane_bps >= 1250000000) 142 cfg->pll_opdiv = 1; ··· 146 cfg->pll_opdiv = 4; 147 else if (dlane_bps >= 160000000) 148 cfg->pll_opdiv = 8; 149 150 cfg->pll_fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv * 151 cfg->pll_ipdiv, 152 pll_ref_hz); 153 154 return 0; 155 } ··· 191 static unsigned long cdns_dphy_get_wakeup_time_ns(struct cdns_dphy *dphy) 192 { 193 return dphy->ops->get_wakeup_time_ns(dphy); 194 } 195 196 static unsigned long cdns_dphy_ref_get_wakeup_time_ns(struct cdns_dphy *dphy) ··· 244 static void cdns_dphy_j721e_set_pll_cfg(struct cdns_dphy *dphy, 245 const struct cdns_dphy_cfg *cfg) 246 { 247 - u32 status; 248 249 /* 250 * set the PWM and PLL Byteclk divider settings to recommended values ··· 260 261 writel(DPHY_TX_J721E_WIZ_LANE_RSTB, 262 dphy->regs + DPHY_TX_J721E_WIZ_RST_CTRL); 263 - 264 - readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_PLL_CTRL, status, 265 - (status & DPHY_TX_WIZ_PLL_LOCK), 0, POLL_TIMEOUT_US); 266 - 267 - readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_STATUS, status, 268 - (status & DPHY_TX_WIZ_O_CMN_READY), 0, 269 - POLL_TIMEOUT_US); 270 } 271 272 static void cdns_dphy_j721e_set_psm_div(struct cdns_dphy *dphy, u8 div) 273 { 274 writel(div, dphy->regs + DPHY_TX_J721E_WIZ_PSM_FREQ); 275 } 276 277 /* ··· 299 .get_wakeup_time_ns = cdns_dphy_j721e_get_wakeup_time_ns, 300 .set_pll_cfg = cdns_dphy_j721e_set_pll_cfg, 301 .set_psm_div = cdns_dphy_j721e_set_psm_div, 302 }; 303 304 static int cdns_dphy_config_from_opts(struct phy *phy, ··· 308 struct cdns_dphy_cfg *cfg) 309 { 310 struct cdns_dphy *dphy = phy_get_drvdata(phy); 311 - unsigned int dsi_hfp_ext = 0; 312 int ret; 313 314 ret = phy_mipi_dphy_config_validate(opts); 315 if (ret) 316 return ret; 317 318 - ret = cdns_dsi_get_dphy_pll_cfg(dphy, cfg, 319 - opts, &dsi_hfp_ext); 320 if (ret) 321 return ret; 322 323 opts->wakeup = cdns_dphy_get_wakeup_time_ns(dphy) / 1000; 324 325 return 0; ··· 356 static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts) 357 { 358 struct cdns_dphy *dphy = phy_get_drvdata(phy); 359 - struct cdns_dphy_cfg cfg = { 0 }; 360 - int ret, band_ctrl; 361 - unsigned int reg; 362 363 - ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg); 364 - if (ret) 365 - return ret; 366 367 /* 368 * Configure the internal PSM clk divider so that the DPHY has a 369 * 1MHz clk (or something close). 370 */ 371 ret = cdns_dphy_setup_psm(dphy); 372 - if (ret) 373 - return ret; 374 375 /* 376 * Configure attach clk lanes to data lanes: the DPHY has 2 clk lanes ··· 400 * Configure the DPHY PLL that will be used to generate the TX byte 401 * clk. 402 */ 403 - cdns_dphy_set_pll_cfg(dphy, &cfg); 404 405 - band_ctrl = cdns_dphy_tx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate); 406 - if (band_ctrl < 0) 407 - return band_ctrl; 408 409 - reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, band_ctrl) | 410 - FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl); 411 writel(reg, dphy->regs + DPHY_BAND_CFG); 412 413 - return 0; 414 - } 415 - 416 - static int cdns_dphy_power_on(struct phy *phy) 417 - { 418 - struct cdns_dphy *dphy = phy_get_drvdata(phy); 419 - 420 - clk_prepare_enable(dphy->psm_clk); 421 - clk_prepare_enable(dphy->pll_ref_clk); 422 - 423 /* Start TX state machine. */ 424 - writel(DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN, 425 dphy->regs + DPHY_CMN_SSM); 426 427 return 0; 428 } 429 430 static int cdns_dphy_power_off(struct phy *phy) 431 { 432 struct cdns_dphy *dphy = phy_get_drvdata(phy); 433 434 clk_disable_unprepare(dphy->pll_ref_clk); 435 clk_disable_unprepare(dphy->psm_clk); 436 437 return 0; 438 }
··· 30 31 #define DPHY_CMN_SSM DPHY_PMA_CMN(0x20) 32 #define DPHY_CMN_SSM_EN BIT(0) 33 + #define DPHY_CMN_SSM_CAL_WAIT_TIME GENMASK(8, 1) 34 #define DPHY_CMN_TX_MODE_EN BIT(9) 35 36 #define DPHY_CMN_PWM DPHY_PMA_CMN(0x40) ··· 55 #define DPHY_PSM_CFG_FROM_REG BIT(0) 56 #define DPHY_PSM_CLK_DIV(x) ((x) << 1) 57 58 #define DPHY_TX_J721E_WIZ_PLL_CTRL 0xF04 59 #define DPHY_TX_J721E_WIZ_STATUS 0xF08 60 #define DPHY_TX_J721E_WIZ_RST_CTRL 0xF0C ··· 79 u8 pll_ipdiv; 80 u8 pll_opdiv; 81 u16 pll_fbdiv; 82 + u32 hs_clk_rate; 83 unsigned int nlanes; 84 }; 85 ··· 99 void (*set_pll_cfg)(struct cdns_dphy *dphy, 100 const struct cdns_dphy_cfg *cfg); 101 unsigned long (*get_wakeup_time_ns)(struct cdns_dphy *dphy); 102 + int (*wait_for_pll_lock)(struct cdns_dphy *dphy); 103 + int (*wait_for_cmn_ready)(struct cdns_dphy *dphy); 104 }; 105 106 struct cdns_dphy { ··· 108 struct clk *pll_ref_clk; 109 const struct cdns_dphy_ops *ops; 110 struct phy *phy; 111 + bool is_configured; 112 + bool is_powered; 113 }; 114 115 /* Order of bands is important since the index is the band number. */ ··· 116 870, 950, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2500 117 }; 118 119 + static int cdns_dphy_get_pll_cfg(struct cdns_dphy *dphy, 120 + struct cdns_dphy_cfg *cfg, 121 + struct phy_configure_opts_mipi_dphy *opts) 122 { 123 unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk); 124 u64 dlane_bps; ··· 139 140 dlane_bps = opts->hs_clk_rate; 141 142 + if (dlane_bps > 2500000000UL || dlane_bps < 80000000UL) 143 return -EINVAL; 144 else if (dlane_bps >= 1250000000) 145 cfg->pll_opdiv = 1; ··· 149 cfg->pll_opdiv = 4; 150 else if (dlane_bps >= 160000000) 151 cfg->pll_opdiv = 8; 152 + else if (dlane_bps >= 80000000) 153 + cfg->pll_opdiv = 16; 154 155 cfg->pll_fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv * 156 cfg->pll_ipdiv, 157 pll_ref_hz); 158 + 159 + cfg->hs_clk_rate = div_u64((u64)pll_ref_hz * cfg->pll_fbdiv, 160 + 2 * cfg->pll_opdiv * cfg->pll_ipdiv); 161 162 return 0; 163 } ··· 189 static unsigned long cdns_dphy_get_wakeup_time_ns(struct cdns_dphy *dphy) 190 { 191 return dphy->ops->get_wakeup_time_ns(dphy); 192 + } 193 + 194 + static int cdns_dphy_wait_for_pll_lock(struct cdns_dphy *dphy) 195 + { 196 + return dphy->ops->wait_for_pll_lock ? dphy->ops->wait_for_pll_lock(dphy) : 0; 197 + } 198 + 199 + static int cdns_dphy_wait_for_cmn_ready(struct cdns_dphy *dphy) 200 + { 201 + return dphy->ops->wait_for_cmn_ready ? dphy->ops->wait_for_cmn_ready(dphy) : 0; 202 } 203 204 static unsigned long cdns_dphy_ref_get_wakeup_time_ns(struct cdns_dphy *dphy) ··· 232 static void cdns_dphy_j721e_set_pll_cfg(struct cdns_dphy *dphy, 233 const struct cdns_dphy_cfg *cfg) 234 { 235 236 /* 237 * set the PWM and PLL Byteclk divider settings to recommended values ··· 249 250 writel(DPHY_TX_J721E_WIZ_LANE_RSTB, 251 dphy->regs + DPHY_TX_J721E_WIZ_RST_CTRL); 252 } 253 254 static void cdns_dphy_j721e_set_psm_div(struct cdns_dphy *dphy, u8 div) 255 { 256 writel(div, dphy->regs + DPHY_TX_J721E_WIZ_PSM_FREQ); 257 + } 258 + 259 + static int cdns_dphy_j721e_wait_for_pll_lock(struct cdns_dphy *dphy) 260 + { 261 + u32 status; 262 + 263 + return readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_PLL_CTRL, status, 264 + status & DPHY_TX_WIZ_PLL_LOCK, 0, POLL_TIMEOUT_US); 265 + } 266 + 267 + static int cdns_dphy_j721e_wait_for_cmn_ready(struct cdns_dphy *dphy) 268 + { 269 + u32 status; 270 + 271 + return readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_STATUS, status, 272 + status & DPHY_TX_WIZ_O_CMN_READY, 0, 273 + POLL_TIMEOUT_US); 274 } 275 276 /* ··· 278 .get_wakeup_time_ns = cdns_dphy_j721e_get_wakeup_time_ns, 279 .set_pll_cfg = cdns_dphy_j721e_set_pll_cfg, 280 .set_psm_div = cdns_dphy_j721e_set_psm_div, 281 + .wait_for_pll_lock = cdns_dphy_j721e_wait_for_pll_lock, 282 + .wait_for_cmn_ready = cdns_dphy_j721e_wait_for_cmn_ready, 283 }; 284 285 static int cdns_dphy_config_from_opts(struct phy *phy, ··· 285 struct cdns_dphy_cfg *cfg) 286 { 287 struct cdns_dphy *dphy = phy_get_drvdata(phy); 288 int ret; 289 290 ret = phy_mipi_dphy_config_validate(opts); 291 if (ret) 292 return ret; 293 294 + ret = cdns_dphy_get_pll_cfg(dphy, cfg, opts); 295 if (ret) 296 return ret; 297 298 + opts->hs_clk_rate = cfg->hs_clk_rate; 299 opts->wakeup = cdns_dphy_get_wakeup_time_ns(dphy) / 1000; 300 301 return 0; ··· 334 static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts) 335 { 336 struct cdns_dphy *dphy = phy_get_drvdata(phy); 337 + int ret; 338 339 + ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &dphy->cfg); 340 + if (!ret) 341 + dphy->is_configured = true; 342 + 343 + return ret; 344 + } 345 + 346 + static int cdns_dphy_power_on(struct phy *phy) 347 + { 348 + struct cdns_dphy *dphy = phy_get_drvdata(phy); 349 + int ret; 350 + u32 reg; 351 + 352 + if (!dphy->is_configured || dphy->is_powered) 353 + return -EINVAL; 354 + 355 + clk_prepare_enable(dphy->psm_clk); 356 + clk_prepare_enable(dphy->pll_ref_clk); 357 358 /* 359 * Configure the internal PSM clk divider so that the DPHY has a 360 * 1MHz clk (or something close). 361 */ 362 ret = cdns_dphy_setup_psm(dphy); 363 + if (ret) { 364 + dev_err(&dphy->phy->dev, "Failed to setup PSM with error %d\n", ret); 365 + goto err_power_on; 366 + } 367 368 /* 369 * Configure attach clk lanes to data lanes: the DPHY has 2 clk lanes ··· 363 * Configure the DPHY PLL that will be used to generate the TX byte 364 * clk. 365 */ 366 + cdns_dphy_set_pll_cfg(dphy, &dphy->cfg); 367 368 + ret = cdns_dphy_tx_get_band_ctrl(dphy->cfg.hs_clk_rate); 369 + if (ret < 0) { 370 + dev_err(&dphy->phy->dev, "Failed to get band control value with error %d\n", ret); 371 + goto err_power_on; 372 + } 373 374 + reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, ret) | 375 + FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, ret); 376 writel(reg, dphy->regs + DPHY_BAND_CFG); 377 378 /* Start TX state machine. */ 379 + reg = readl(dphy->regs + DPHY_CMN_SSM); 380 + writel((reg & DPHY_CMN_SSM_CAL_WAIT_TIME) | DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN, 381 dphy->regs + DPHY_CMN_SSM); 382 383 + ret = cdns_dphy_wait_for_pll_lock(dphy); 384 + if (ret) { 385 + dev_err(&dphy->phy->dev, "Failed to lock PLL with error %d\n", ret); 386 + goto err_power_on; 387 + } 388 + 389 + ret = cdns_dphy_wait_for_cmn_ready(dphy); 390 + if (ret) { 391 + dev_err(&dphy->phy->dev, "O_CMN_READY signal failed to assert with error %d\n", 392 + ret); 393 + goto err_power_on; 394 + } 395 + 396 + dphy->is_powered = true; 397 + 398 return 0; 399 + 400 + err_power_on: 401 + clk_disable_unprepare(dphy->pll_ref_clk); 402 + clk_disable_unprepare(dphy->psm_clk); 403 + 404 + return ret; 405 } 406 407 static int cdns_dphy_power_off(struct phy *phy) 408 { 409 struct cdns_dphy *dphy = phy_get_drvdata(phy); 410 + u32 reg; 411 412 clk_disable_unprepare(dphy->pll_ref_clk); 413 clk_disable_unprepare(dphy->psm_clk); 414 + 415 + /* Stop TX state machine. */ 416 + reg = readl(dphy->regs + DPHY_CMN_SSM); 417 + writel(reg & ~DPHY_CMN_SSM_EN, dphy->regs + DPHY_CMN_SSM); 418 + 419 + dphy->is_powered = false; 420 421 return 0; 422 }
-1
drivers/phy/cadence/phy-cadence-sierra.c
··· 2919 }; 2920 module_platform_driver(cdns_sierra_driver); 2921 2922 - MODULE_ALIAS("platform:cdns_sierra"); 2923 MODULE_AUTHOR("Cadence Design Systems"); 2924 MODULE_DESCRIPTION("CDNS sierra phy driver"); 2925 MODULE_LICENSE("GPL v2");
··· 2919 }; 2920 module_platform_driver(cdns_sierra_driver); 2921 2922 MODULE_AUTHOR("Cadence Design Systems"); 2923 MODULE_DESCRIPTION("CDNS sierra phy driver"); 2924 MODULE_LICENSE("GPL v2");
+14 -2
drivers/phy/freescale/phy-fsl-lynx-28g.c
··· 188 return pll; 189 } 190 191 return NULL; 192 } 193 ··· 280 lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_SGMII, PROTO_SEL_MSK); 281 lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_10_BIT, IF_WIDTH_MSK); 282 283 - /* Switch to the PLL that works with this interface type */ 284 pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_SGMII); 285 lynx_28g_lane_set_pll(lane, pll); 286 287 /* Choose the portion of clock net to be used on this lane */ ··· 320 lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_XFI, PROTO_SEL_MSK); 321 lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_20_BIT, IF_WIDTH_MSK); 322 323 - /* Switch to the PLL that works with this interface type */ 324 pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_10GBASER); 325 lynx_28g_lane_set_pll(lane, pll); 326 327 /* Choose the portion of clock net to be used on this lane */
··· 188 return pll; 189 } 190 191 + /* no pll supports requested mode, either caller forgot to check 192 + * lynx_28g_supports_lane_mode, or this is a bug. 193 + */ 194 + dev_WARN_ONCE(priv->dev, 1, "no pll for interface %s\n", phy_modes(intf)); 195 return NULL; 196 } 197 ··· 276 lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_SGMII, PROTO_SEL_MSK); 277 lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_10_BIT, IF_WIDTH_MSK); 278 279 + /* Find the PLL that works with this interface type */ 280 pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_SGMII); 281 + if (unlikely(pll == NULL)) 282 + return; 283 + 284 + /* Switch to the PLL that works with this interface type */ 285 lynx_28g_lane_set_pll(lane, pll); 286 287 /* Choose the portion of clock net to be used on this lane */ ··· 312 lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_XFI, PROTO_SEL_MSK); 313 lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_20_BIT, IF_WIDTH_MSK); 314 315 + /* Find the PLL that works with this interface type */ 316 pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_10GBASER); 317 + if (unlikely(pll == NULL)) 318 + return; 319 + 320 + /* Switch to the PLL that works with this interface type */ 321 lynx_28g_lane_set_pll(lane, pll); 322 323 /* Choose the portion of clock net to be used on this lane */
-1
drivers/phy/hisilicon/phy-hi6220-usb.c
··· 161 module_platform_driver(hi6220_phy_driver); 162 163 MODULE_DESCRIPTION("HISILICON HI6220 USB PHY driver"); 164 - MODULE_ALIAS("platform:hi6220-usb-phy"); 165 MODULE_LICENSE("GPL");
··· 161 module_platform_driver(hi6220_phy_driver); 162 163 MODULE_DESCRIPTION("HISILICON HI6220 USB PHY driver"); 164 MODULE_LICENSE("GPL");
+1 -1
drivers/phy/hisilicon/phy-histb-combphy.c
··· 73 74 static int is_mode_fixed(struct histb_combphy_mode *mode) 75 { 76 - return (mode->fixed != PHY_NONE) ? true : false; 77 } 78 79 static int histb_combphy_set_mode(struct histb_combphy_priv *priv)
··· 73 74 static int is_mode_fixed(struct histb_combphy_mode *mode) 75 { 76 + return mode->fixed != PHY_NONE; 77 } 78 79 static int histb_combphy_set_mode(struct histb_combphy_priv *priv)
+2 -6
drivers/phy/ingenic/phy-ingenic-usb.c
··· 339 priv->clk = devm_clk_get(dev, NULL); 340 if (IS_ERR(priv->clk)) { 341 err = PTR_ERR(priv->clk); 342 - if (err != -EPROBE_DEFER) 343 - dev_err(dev, "Failed to get clock\n"); 344 - return err; 345 } 346 347 priv->vcc_supply = devm_regulator_get(dev, "vcc"); 348 if (IS_ERR(priv->vcc_supply)) { 349 err = PTR_ERR(priv->vcc_supply); 350 - if (err != -EPROBE_DEFER) 351 - dev_err(dev, "Failed to get regulator\n"); 352 - return err; 353 } 354 355 priv->phy = devm_phy_create(dev, NULL, &ingenic_usb_phy_ops);
··· 339 priv->clk = devm_clk_get(dev, NULL); 340 if (IS_ERR(priv->clk)) { 341 err = PTR_ERR(priv->clk); 342 + return dev_err_probe(dev, err, "Failed to get clock\n"); 343 } 344 345 priv->vcc_supply = devm_regulator_get(dev, "vcc"); 346 if (IS_ERR(priv->vcc_supply)) { 347 err = PTR_ERR(priv->vcc_supply); 348 + return dev_err_probe(dev, err, "Failed to get regulator\n"); 349 } 350 351 priv->phy = devm_phy_create(dev, NULL, &ingenic_usb_phy_ops);
+15
drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
··· 82 .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), 83 }; 84 85 static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = { 86 .init_tbl = smb2360_init_tbl, 87 .init_tbl_num = ARRAY_SIZE(smb2360_init_tbl), ··· 143 144 if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val)) 145 regmap_write(regmap, base + EUSB2_TUNE_IUSB2, val); 146 147 /* Wait for status OK */ 148 ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, poll_val, ··· 269 { 270 .compatible = "qcom,pm8550b-eusb2-repeater", 271 .data = &pm8550b_eusb2_cfg, 272 }, 273 { 274 .compatible = "qcom,smb2360-eusb2-repeater",
··· 82 .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), 83 }; 84 85 + static const struct eusb2_repeater_cfg pmiv0104_eusb2_cfg = { 86 + /* No PMIC-specific init sequence, only board level tuning via DT */ 87 + .init_tbl = (struct eusb2_repeater_init_tbl_reg[]) {}, 88 + .init_tbl_num = 0, 89 + .vreg_list = pm8550b_vreg_l, 90 + .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), 91 + }; 92 + 93 static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = { 94 .init_tbl = smb2360_init_tbl, 95 .init_tbl_num = ARRAY_SIZE(smb2360_init_tbl), ··· 135 136 if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val)) 137 regmap_write(regmap, base + EUSB2_TUNE_IUSB2, val); 138 + 139 + if (!of_property_read_u8(np, "qcom,tune-res-fsdif", &val)) 140 + regmap_write(regmap, base + EUSB2_TUNE_RES_FSDIF, val); 141 142 /* Wait for status OK */ 143 ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, poll_val, ··· 258 { 259 .compatible = "qcom,pm8550b-eusb2-repeater", 260 .data = &pm8550b_eusb2_cfg, 261 + }, 262 + { 263 + .compatible = "qcom,pmiv0104-eusb2-repeater", 264 + .data = &pmiv0104_eusb2_cfg, 265 }, 266 { 267 .compatible = "qcom,smb2360-eusb2-repeater",
-1
drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
··· 559 560 module_platform_driver(qcom_ipq806x_usb_phy_driver); 561 562 - MODULE_ALIAS("platform:phy-qcom-ipq806x-usb"); 563 MODULE_LICENSE("GPL v2"); 564 MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>"); 565 MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
··· 559 560 module_platform_driver(qcom_ipq806x_usb_phy_driver); 561 562 MODULE_LICENSE("GPL v2"); 563 MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>"); 564 MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
+1 -1
drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
··· 196 197 ret = clk_prepare_enable(phy->clk); 198 if (ret) { 199 - dev_err(&uphy->dev, "failed to enable cfg ahb clock, %d\n", ret); 200 goto disable_repeater; 201 } 202
··· 196 197 ret = clk_prepare_enable(phy->clk); 198 if (ret) { 199 + dev_err(&uphy->dev, "failed to enable ref clock, %d\n", ret); 200 goto disable_repeater; 201 } 202
+163 -16
drivers/phy/qualcomm/phy-qcom-qmp-combo.c
··· 19 #include <linux/reset.h> 20 #include <linux/slab.h> 21 #include <linux/usb/typec.h> 22 #include <linux/usb/typec_mux.h> 23 24 #include <drm/bridge/aux-bridge.h> ··· 62 #define SW_PORTSELECT_MUX BIT(1) 63 64 #define PHY_INIT_COMPLETE_TIMEOUT 10000 65 66 /* set of registers with offsets different per-PHY */ 67 enum qphy_reg_layout { ··· 1851 1852 struct mutex phy_mutex; 1853 int init_count; 1854 1855 struct phy *usb_phy; 1856 - enum phy_mode mode; 1857 unsigned int usb_init_count; 1858 1859 struct phy *dp_phy; 1860 unsigned int dp_aux_cfg; 1861 struct phy_configure_opts_dp dp_opts; 1862 unsigned int dp_init_count; 1863 1864 struct clk_fixed_rate pipe_clk_fixed; 1865 struct clk_hw dp_link_hw; ··· 1869 1870 struct typec_switch_dev *sw; 1871 enum typec_orientation orientation; 1872 }; 1873 1874 static void qmp_v3_dp_aux_init(struct qmp_combo *qmp); ··· 3047 if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) 3048 val |= SW_PORTSELECT_VAL; 3049 writel(val, com + QPHY_V3_DP_COM_TYPEC_CTRL); 3050 - writel(USB3_MODE | DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL); 3051 3052 - /* bring both QMP USB and QMP DP PHYs PCS block out of reset */ 3053 - qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, 3054 - SW_DPPHY_RESET_MUX | SW_DPPHY_RESET | 3055 - SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); 3056 3057 qphy_clrbits(com, QPHY_V3_DP_COM_SWI_CTRL, 0x03); 3058 qphy_clrbits(com, QPHY_V3_DP_COM_SW_RESET, SW_RESET); ··· 3165 /* Configure link rate, swing, etc. */ 3166 cfg->configure_dp_phy(qmp); 3167 3168 mutex_unlock(&qmp->phy_mutex); 3169 3170 return 0; ··· 3180 3181 /* Assert DP PHY power down */ 3182 writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); 3183 3184 mutex_unlock(&qmp->phy_mutex); 3185 ··· 3318 { 3319 struct qmp_combo *qmp = phy_get_drvdata(phy); 3320 3321 - qmp->mode = mode; 3322 3323 return 0; 3324 } ··· 3347 void __iomem *pcs_misc = qmp->pcs_misc; 3348 u32 intr_mask; 3349 3350 - if (qmp->mode == PHY_MODE_USB_HOST_SS || 3351 - qmp->mode == PHY_MODE_USB_DEVICE_SS) 3352 intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN; 3353 else 3354 intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL; ··· 3391 { 3392 struct qmp_combo *qmp = dev_get_drvdata(dev); 3393 3394 - dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); 3395 3396 if (!qmp->init_count) { 3397 dev_vdbg(dev, "PHY not initialized, bailing out\n"); ··· 3411 struct qmp_combo *qmp = dev_get_drvdata(dev); 3412 int ret = 0; 3413 3414 - dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); 3415 3416 if (!qmp->init_count) { 3417 dev_vdbg(dev, "PHY not initialized, bailing out\n"); ··· 3805 return 0; 3806 } 3807 3808 - static void qmp_combo_typec_unregister(void *data) 3809 { 3810 struct qmp_combo *qmp = data; 3811 3812 typec_switch_unregister(qmp->sw); 3813 } 3814 3815 - static int qmp_combo_typec_switch_register(struct qmp_combo *qmp) 3816 { 3817 struct typec_switch_desc sw_desc = {}; 3818 struct device *dev = qmp->dev; 3819 3820 sw_desc.drvdata = qmp; 3821 sw_desc.fwnode = dev->fwnode; ··· 3918 return PTR_ERR(qmp->sw); 3919 } 3920 3921 - return devm_add_action_or_reset(dev, qmp_combo_typec_unregister, qmp); 3922 } 3923 #else 3924 - static int qmp_combo_typec_switch_register(struct qmp_combo *qmp) 3925 { 3926 return 0; 3927 } ··· 4167 if (ret) 4168 goto err_node_put; 4169 4170 - ret = qmp_combo_typec_switch_register(qmp); 4171 if (ret) 4172 goto err_node_put; 4173 ··· 4188 ret = qmp_combo_register_clocks(qmp, usb_np, dp_np); 4189 if (ret) 4190 goto err_node_put; 4191 4192 qmp->usb_phy = devm_phy_create(dev, usb_np, &qmp_combo_usb_phy_ops); 4193 if (IS_ERR(qmp->usb_phy)) {
··· 19 #include <linux/reset.h> 20 #include <linux/slab.h> 21 #include <linux/usb/typec.h> 22 + #include <linux/usb/typec_dp.h> 23 #include <linux/usb/typec_mux.h> 24 25 #include <drm/bridge/aux-bridge.h> ··· 61 #define SW_PORTSELECT_MUX BIT(1) 62 63 #define PHY_INIT_COMPLETE_TIMEOUT 10000 64 + 65 + enum qmpphy_mode { 66 + QMPPHY_MODE_USB3DP = 0, 67 + QMPPHY_MODE_DP_ONLY, 68 + QMPPHY_MODE_USB3_ONLY, 69 + }; 70 71 /* set of registers with offsets different per-PHY */ 72 enum qphy_reg_layout { ··· 1844 1845 struct mutex phy_mutex; 1846 int init_count; 1847 + enum qmpphy_mode qmpphy_mode; 1848 1849 struct phy *usb_phy; 1850 + enum phy_mode phy_mode; 1851 unsigned int usb_init_count; 1852 1853 struct phy *dp_phy; 1854 unsigned int dp_aux_cfg; 1855 struct phy_configure_opts_dp dp_opts; 1856 unsigned int dp_init_count; 1857 + bool dp_powered_on; 1858 1859 struct clk_fixed_rate pipe_clk_fixed; 1860 struct clk_hw dp_link_hw; ··· 1860 1861 struct typec_switch_dev *sw; 1862 enum typec_orientation orientation; 1863 + 1864 + struct typec_mux_dev *mux; 1865 }; 1866 1867 static void qmp_v3_dp_aux_init(struct qmp_combo *qmp); ··· 3036 if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) 3037 val |= SW_PORTSELECT_VAL; 3038 writel(val, com + QPHY_V3_DP_COM_TYPEC_CTRL); 3039 3040 + switch (qmp->qmpphy_mode) { 3041 + case QMPPHY_MODE_USB3DP: 3042 + writel(USB3_MODE | DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL); 3043 + 3044 + /* bring both QMP USB and QMP DP PHYs PCS block out of reset */ 3045 + qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, 3046 + SW_DPPHY_RESET_MUX | SW_DPPHY_RESET | 3047 + SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); 3048 + break; 3049 + 3050 + case QMPPHY_MODE_DP_ONLY: 3051 + writel(DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL); 3052 + 3053 + /* bring QMP DP PHY PCS block out of reset */ 3054 + qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, 3055 + SW_DPPHY_RESET_MUX | SW_DPPHY_RESET); 3056 + break; 3057 + 3058 + case QMPPHY_MODE_USB3_ONLY: 3059 + writel(USB3_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL); 3060 + 3061 + /* bring QMP USB PHY PCS block out of reset */ 3062 + qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, 3063 + SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); 3064 + break; 3065 + } 3066 3067 qphy_clrbits(com, QPHY_V3_DP_COM_SWI_CTRL, 0x03); 3068 qphy_clrbits(com, QPHY_V3_DP_COM_SW_RESET, SW_RESET); ··· 3133 /* Configure link rate, swing, etc. */ 3134 cfg->configure_dp_phy(qmp); 3135 3136 + qmp->dp_powered_on = true; 3137 + 3138 mutex_unlock(&qmp->phy_mutex); 3139 3140 return 0; ··· 3146 3147 /* Assert DP PHY power down */ 3148 writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); 3149 + 3150 + qmp->dp_powered_on = false; 3151 3152 mutex_unlock(&qmp->phy_mutex); 3153 ··· 3282 { 3283 struct qmp_combo *qmp = phy_get_drvdata(phy); 3284 3285 + qmp->phy_mode = mode; 3286 3287 return 0; 3288 } ··· 3311 void __iomem *pcs_misc = qmp->pcs_misc; 3312 u32 intr_mask; 3313 3314 + if (qmp->phy_mode == PHY_MODE_USB_HOST_SS || 3315 + qmp->phy_mode == PHY_MODE_USB_DEVICE_SS) 3316 intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN; 3317 else 3318 intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL; ··· 3355 { 3356 struct qmp_combo *qmp = dev_get_drvdata(dev); 3357 3358 + dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->phy_mode); 3359 3360 if (!qmp->init_count) { 3361 dev_vdbg(dev, "PHY not initialized, bailing out\n"); ··· 3375 struct qmp_combo *qmp = dev_get_drvdata(dev); 3376 int ret = 0; 3377 3378 + dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->phy_mode); 3379 3380 if (!qmp->init_count) { 3381 dev_vdbg(dev, "PHY not initialized, bailing out\n"); ··· 3769 return 0; 3770 } 3771 3772 + static int qmp_combo_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) 3773 + { 3774 + struct qmp_combo *qmp = typec_mux_get_drvdata(mux); 3775 + const struct qmp_phy_cfg *cfg = qmp->cfg; 3776 + enum qmpphy_mode new_mode; 3777 + unsigned int svid; 3778 + 3779 + guard(mutex)(&qmp->phy_mutex); 3780 + 3781 + if (state->alt) 3782 + svid = state->alt->svid; 3783 + else 3784 + svid = 0; 3785 + 3786 + if (svid == USB_TYPEC_DP_SID) { 3787 + switch (state->mode) { 3788 + /* DP Only */ 3789 + case TYPEC_DP_STATE_C: 3790 + case TYPEC_DP_STATE_E: 3791 + new_mode = QMPPHY_MODE_DP_ONLY; 3792 + break; 3793 + 3794 + /* DP + USB */ 3795 + case TYPEC_DP_STATE_D: 3796 + case TYPEC_DP_STATE_F: 3797 + 3798 + /* Safe fallback...*/ 3799 + default: 3800 + new_mode = QMPPHY_MODE_USB3DP; 3801 + break; 3802 + } 3803 + } else { 3804 + /* No DP SVID => don't care, assume it's just USB3 */ 3805 + new_mode = QMPPHY_MODE_USB3_ONLY; 3806 + } 3807 + 3808 + if (new_mode == qmp->qmpphy_mode) { 3809 + dev_dbg(qmp->dev, "typec_mux_set: same qmpphy mode, bail out\n"); 3810 + return 0; 3811 + } 3812 + 3813 + if (qmp->qmpphy_mode != QMPPHY_MODE_USB3_ONLY && qmp->dp_powered_on) { 3814 + dev_dbg(qmp->dev, "typec_mux_set: DP PHY is still in use, delaying switch\n"); 3815 + return 0; 3816 + } 3817 + 3818 + dev_dbg(qmp->dev, "typec_mux_set: switching from qmpphy mode %d to %d\n", 3819 + qmp->qmpphy_mode, new_mode); 3820 + 3821 + qmp->qmpphy_mode = new_mode; 3822 + 3823 + if (qmp->init_count) { 3824 + if (qmp->usb_init_count) 3825 + qmp_combo_usb_power_off(qmp->usb_phy); 3826 + 3827 + if (qmp->dp_init_count) 3828 + writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); 3829 + 3830 + qmp_combo_com_exit(qmp, true); 3831 + 3832 + /* Now everything's powered down, power up the right PHYs */ 3833 + qmp_combo_com_init(qmp, true); 3834 + 3835 + if (new_mode == QMPPHY_MODE_DP_ONLY) { 3836 + if (qmp->usb_init_count) 3837 + qmp->usb_init_count--; 3838 + } 3839 + 3840 + if (new_mode == QMPPHY_MODE_USB3DP || new_mode == QMPPHY_MODE_USB3_ONLY) { 3841 + qmp_combo_usb_power_on(qmp->usb_phy); 3842 + if (!qmp->usb_init_count) 3843 + qmp->usb_init_count++; 3844 + } 3845 + 3846 + if (new_mode == QMPPHY_MODE_DP_ONLY || new_mode == QMPPHY_MODE_USB3DP) { 3847 + if (qmp->dp_init_count) 3848 + cfg->dp_aux_init(qmp); 3849 + } 3850 + } 3851 + 3852 + return 0; 3853 + } 3854 + 3855 + static void qmp_combo_typec_switch_unregister(void *data) 3856 { 3857 struct qmp_combo *qmp = data; 3858 3859 typec_switch_unregister(qmp->sw); 3860 } 3861 3862 + static void qmp_combo_typec_mux_unregister(void *data) 3863 + { 3864 + struct qmp_combo *qmp = data; 3865 + 3866 + typec_mux_unregister(qmp->mux); 3867 + } 3868 + 3869 + static int qmp_combo_typec_register(struct qmp_combo *qmp) 3870 { 3871 struct typec_switch_desc sw_desc = {}; 3872 + struct typec_mux_desc mux_desc = { }; 3873 struct device *dev = qmp->dev; 3874 + int ret; 3875 3876 sw_desc.drvdata = qmp; 3877 sw_desc.fwnode = dev->fwnode; ··· 3790 return PTR_ERR(qmp->sw); 3791 } 3792 3793 + ret = devm_add_action_or_reset(dev, qmp_combo_typec_switch_unregister, qmp); 3794 + if (ret) 3795 + return ret; 3796 + 3797 + mux_desc.drvdata = qmp; 3798 + mux_desc.fwnode = dev->fwnode; 3799 + mux_desc.set = qmp_combo_typec_mux_set; 3800 + qmp->mux = typec_mux_register(dev, &mux_desc); 3801 + if (IS_ERR(qmp->mux)) { 3802 + dev_err(dev, "Unable to register typec mux: %pe\n", qmp->mux); 3803 + return PTR_ERR(qmp->mux); 3804 + } 3805 + 3806 + return devm_add_action_or_reset(dev, qmp_combo_typec_mux_unregister, qmp); 3807 } 3808 #else 3809 + static int qmp_combo_typec_register(struct qmp_combo *qmp) 3810 { 3811 return 0; 3812 } ··· 4026 if (ret) 4027 goto err_node_put; 4028 4029 + ret = qmp_combo_typec_register(qmp); 4030 if (ret) 4031 goto err_node_put; 4032 ··· 4047 ret = qmp_combo_register_clocks(qmp, usb_np, dp_np); 4048 if (ret) 4049 goto err_node_put; 4050 + 4051 + /* 4052 + * The hw default is USB3_ONLY, but USB3+DP mode lets us more easily 4053 + * check both sub-blocks' init tables for blunders at probe time. 4054 + */ 4055 + qmp->qmpphy_mode = QMPPHY_MODE_USB3DP; 4056 4057 qmp->usb_phy = devm_phy_create(dev, usb_np, &qmp_combo_usb_phy_ops); 4058 if (IS_ERR(qmp->usb_phy)) {
+149
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
··· 93 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_POWER_DOWN_CONTROL, 94 }; 95 96 static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = { 97 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14), 98 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), ··· 2597 QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff), 2598 }; 2599 2600 static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x2_pcie_serdes_alt_tbl[] = { 2601 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14), 2602 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f), ··· 3322 .rx = 0x0200, 3323 .tx2 = 0x3800, 3324 .rx2 = 0x3a00, 3325 }; 3326 3327 static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_20 = { ··· 4118 .vreg_list = qmp_phy_vreg_l, 4119 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 4120 .regs = pciephy_v5_regs_layout, 4121 4122 .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4123 .phy_status = PHYSTATUS, ··· 5258 }, { 5259 .compatible = "qcom,sm8650-qmp-gen4x2-pcie-phy", 5260 .data = &sm8650_qmp_gen4x2_pciephy_cfg, 5261 }, { 5262 .compatible = "qcom,x1e80100-qmp-gen3x2-pcie-phy", 5263 .data = &sm8550_qmp_gen3x2_pciephy_cfg,
··· 93 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_POWER_DOWN_CONTROL, 94 }; 95 96 + static const unsigned int pciephy_v7_regs_layout[QPHY_LAYOUT_SIZE] = { 97 + [QPHY_SW_RESET] = QPHY_V7_PCS_SW_RESET, 98 + [QPHY_START_CTRL] = QPHY_V7_PCS_START_CONTROL, 99 + [QPHY_PCS_STATUS] = QPHY_V7_PCS_PCS_STATUS1, 100 + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V7_PCS_POWER_DOWN_CONTROL, 101 + }; 102 + 103 static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = { 104 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14), 105 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), ··· 2590 QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff), 2591 }; 2592 2593 + static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_serdes_tbl[] = { 2594 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_EN_CENTER, 0x1), 2595 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_PER1, 0x62), 2596 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_PER2, 0x02), 2597 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE1_MODE0, 0xf8), 2598 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE2_MODE0, 0x01), 2599 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE1_MODE1, 0x93), 2600 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE2_MODE1, 0x01), 2601 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CLK_ENABLE1, 0x90), 2602 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SYS_CLK_CTRL, 0x82), 2603 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_IVCO, 0x07), 2604 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CP_CTRL_MODE0, 0x02), 2605 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CP_CTRL_MODE1, 0x02), 2606 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_RCTRL_MODE0, 0x16), 2607 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_RCTRL_MODE1, 0x16), 2608 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_CCTRL_MODE0, 0x36), 2609 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_CCTRL_MODE1, 0x36), 2610 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SYSCLK_EN_SEL, 0x08), 2611 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_BG_TIMER, 0x0a), 2612 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP_EN, 0x42), 2613 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP1_MODE0, 0x04), 2614 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP2_MODE0, 0x0d), 2615 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP1_MODE1, 0x0a), 2616 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP2_MODE1, 0x1a), 2617 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DEC_START_MODE0, 0x41), 2618 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DEC_START_MODE1, 0x34), 2619 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START1_MODE0, 0xab), 2620 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START2_MODE0, 0xaa), 2621 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START3_MODE0, 0x01), 2622 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START1_MODE1, 0x55), 2623 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START2_MODE1, 0x55), 2624 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START3_MODE1, 0x01), 2625 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_VCO_TUNE_MAP, 0x14), 2626 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CLK_SELECT, 0x34), 2627 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_HSCLK_SEL_1, 0x01), 2628 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CORECLK_DIV_MODE1, 0x04), 2629 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CMN_CONFIG_1, 0x16), 2630 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_ADDITIONAL_MISC_3, 0x0F), 2631 + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CORE_CLK_EN, 0xA0), 2632 + }; 2633 + 2634 + static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_rx_tbl[] = { 2635 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), 2636 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_GM_CAL, 0x11), 2637 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH, 0xBF), 2638 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH2, 0xBF), 2639 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH3, 0xB7), 2640 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH4, 0xEA), 2641 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_LOW, 0x3F), 2642 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH, 0x09), 2643 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH2, 0x49), 2644 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH3, 0x1B), 2645 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH4, 0x9C), 2646 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_LOW, 0xD1), 2647 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH, 0x09), 2648 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH2, 0x49), 2649 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH3, 0x1B), 2650 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH4, 0x9C), 2651 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_LOW, 0xD1), 2652 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_TX_ADAPT_PRE_THRESH1, 0x3E), 2653 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_TX_ADAPT_PRE_THRESH2, 0x1E), 2654 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_TX_ADAPT_POST_THRESH, 0xD2), 2655 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_FO_GAIN, 0x09), 2656 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_SO_GAIN, 0x05), 2657 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_SB2_THRESH1, 0x08), 2658 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_SB2_THRESH2, 0x08), 2659 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_VGA_CAL_CNTRL2, 0x09), 2660 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_SIGDET_ENABLES, 0x1C), 2661 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_SIGDET_CNTRL, 0x60), 2662 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW, 0x07), 2663 + QMP_PHY_INIT_CFG(QSERDES_V7_RX_SIGDET_CAL_TRIM, 0x08), 2664 + }; 2665 + 2666 + static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_tx_tbl[] = { 2667 + QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_1, 0x35), 2668 + QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_3, 0x10), 2669 + QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_4, 0x31), 2670 + QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_5, 0x7F), 2671 + QMP_PHY_INIT_CFG(QSERDES_V7_TX_PI_QEC_CTRL, 0x02), 2672 + QMP_PHY_INIT_CFG(QSERDES_V7_TX_RES_CODE_LANE_OFFSET_RX, 0x08), 2673 + QMP_PHY_INIT_CFG(QSERDES_V7_TX_RES_CODE_LANE_OFFSET_TX, 0x14), 2674 + }; 2675 + 2676 + static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_pcs_tbl[] = { 2677 + QMP_PHY_INIT_CFG(QPHY_V7_PCS_REFGEN_REQ_CONFIG1, 0x05), 2678 + QMP_PHY_INIT_CFG(QPHY_V7_PCS_RX_SIGDET_LVL, 0x77), 2679 + QMP_PHY_INIT_CFG(QPHY_V7_PCS_RATE_SLEW_CNTRL1, 0x0B), 2680 + QMP_PHY_INIT_CFG(QPHY_V7_PCS_EQ_CONFIG2, 0x0F), 2681 + QMP_PHY_INIT_CFG(QPHY_V7_PCS_PCS_TX_RX_CONFIG, 0x8C), 2682 + QMP_PHY_INIT_CFG(QPHY_V7_PCS_G12S1_TXDEEMPH_M6DB, 0x17), 2683 + QMP_PHY_INIT_CFG(QPHY_V7_PCS_G3S2_PRE_GAIN, 0x2E), 2684 + }; 2685 + 2686 + static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_pcs_misc_tbl[] = { 2687 + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_EQ_CONFIG1, 0x1E), 2688 + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_RXEQEVAL_TIME, 0x27), 2689 + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2, 0x1D), 2690 + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07), 2691 + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xC1), 2692 + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00), 2693 + }; 2694 + 2695 static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x2_pcie_serdes_alt_tbl[] = { 2696 QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14), 2697 QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f), ··· 3213 .rx = 0x0200, 3214 .tx2 = 0x3800, 3215 .rx2 = 0x3a00, 3216 + }; 3217 + 3218 + static const struct qmp_pcie_offsets qmp_pcie_offsets_v7 = { 3219 + .serdes = 0x0, 3220 + .pcs = 0x400, 3221 + .pcs_misc = 0x800, 3222 + .tx = 0x1000, 3223 + .rx = 0x1200, 3224 + .tx2 = 0x1800, 3225 + .rx2 = 0x1a00, 3226 }; 3227 3228 static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_20 = { ··· 3999 .vreg_list = qmp_phy_vreg_l, 4000 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 4001 .regs = pciephy_v5_regs_layout, 4002 + 4003 + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4004 + .phy_status = PHYSTATUS, 4005 + }; 4006 + 4007 + static const struct qmp_phy_cfg sm8750_qmp_gen3x2_pciephy_cfg = { 4008 + .lanes = 2, 4009 + 4010 + .offsets = &qmp_pcie_offsets_v7, 4011 + 4012 + .tbls = { 4013 + .serdes = sm8750_qmp_gen3x2_pcie_serdes_tbl, 4014 + .serdes_num = ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_serdes_tbl), 4015 + .tx = sm8750_qmp_gen3x2_pcie_tx_tbl, 4016 + .tx_num = ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_tx_tbl), 4017 + .rx = sm8750_qmp_gen3x2_pcie_rx_tbl, 4018 + .rx_num = ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_rx_tbl), 4019 + .pcs = sm8750_qmp_gen3x2_pcie_pcs_tbl, 4020 + .pcs_num = ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_pcs_tbl), 4021 + .pcs_misc = sm8750_qmp_gen3x2_pcie_pcs_misc_tbl, 4022 + .pcs_misc_num = ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_pcs_misc_tbl), 4023 + }, 4024 + .reset_list = sdm845_pciephy_reset_l, 4025 + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), 4026 + .vreg_list = qmp_phy_vreg_l, 4027 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 4028 + .regs = pciephy_v7_regs_layout, 4029 4030 .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4031 .phy_status = PHYSTATUS, ··· 5112 }, { 5113 .compatible = "qcom,sm8650-qmp-gen4x2-pcie-phy", 5114 .data = &sm8650_qmp_gen4x2_pciephy_cfg, 5115 + }, { 5116 + .compatible = "qcom,sm8750-qmp-gen3x2-pcie-phy", 5117 + .data = &sm8750_qmp_gen3x2_pciephy_cfg, 5118 }, { 5119 .compatible = "qcom,x1e80100-qmp-gen3x2-pcie-phy", 5120 .data = &sm8550_qmp_gen3x2_pciephy_cfg,
+2
drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h
··· 17 #define QPHY_V7_PCS_LOCK_DETECT_CONFIG3 0x0cc 18 #define QPHY_V7_PCS_LOCK_DETECT_CONFIG6 0x0d8 19 #define QPHY_V7_PCS_REFGEN_REQ_CONFIG1 0x0dc 20 #define QPHY_V7_PCS_RX_SIGDET_LVL 0x188 21 #define QPHY_V7_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 22 #define QPHY_V7_PCS_RCVR_DTCT_DLY_P1U2_H 0x194
··· 17 #define QPHY_V7_PCS_LOCK_DETECT_CONFIG3 0x0cc 18 #define QPHY_V7_PCS_LOCK_DETECT_CONFIG6 0x0d8 19 #define QPHY_V7_PCS_REFGEN_REQ_CONFIG1 0x0dc 20 + #define QPHY_V7_PCS_G12S1_TXDEEMPH_M6DB 0x168 21 + #define QPHY_V7_PCS_G3S2_PRE_GAIN 0x170 22 #define QPHY_V7_PCS_RX_SIGDET_LVL 0x188 23 #define QPHY_V7_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 24 #define QPHY_V7_PCS_RCVR_DTCT_DLY_P1U2_H 0x194
+3 -1
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h
··· 40 #define QSERDES_V7_RX_UCDR_SB2_GAIN1 0x54 41 #define QSERDES_V7_RX_UCDR_SB2_GAIN2 0x58 42 #define QSERDES_V7_RX_AUX_DATA_TCOARSE_TFINE 0x60 43 #define QSERDES_V7_RX_TX_ADAPT_POST_THRESH 0xcc 44 #define QSERDES_V7_RX_VGA_CAL_CNTRL1 0xd4 45 #define QSERDES_V7_RX_VGA_CAL_CNTRL2 0xd8 ··· 52 #define QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW 0xf8 53 #define QSERDES_V7_RX_RX_IDAC_TSETTLE_HIGH 0xfc 54 #define QSERDES_V7_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110 55 - #define QSERDES_V7_RX_SIDGET_ENABLES 0x118 56 #define QSERDES_V7_RX_SIGDET_CNTRL 0x11c 57 #define QSERDES_V7_RX_SIGDET_DEGLITCH_CNTRL 0x124 58 #define QSERDES_V7_RX_RX_MODE_00_LOW 0x15c
··· 40 #define QSERDES_V7_RX_UCDR_SB2_GAIN1 0x54 41 #define QSERDES_V7_RX_UCDR_SB2_GAIN2 0x58 42 #define QSERDES_V7_RX_AUX_DATA_TCOARSE_TFINE 0x60 43 + #define QSERDES_V7_RX_TX_ADAPT_PRE_THRESH1 0xc4 44 + #define QSERDES_V7_RX_TX_ADAPT_PRE_THRESH2 0xc8 45 #define QSERDES_V7_RX_TX_ADAPT_POST_THRESH 0xcc 46 #define QSERDES_V7_RX_VGA_CAL_CNTRL1 0xd4 47 #define QSERDES_V7_RX_VGA_CAL_CNTRL2 0xd8 ··· 50 #define QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW 0xf8 51 #define QSERDES_V7_RX_RX_IDAC_TSETTLE_HIGH 0xfc 52 #define QSERDES_V7_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110 53 + #define QSERDES_V7_RX_SIGDET_ENABLES 0x118 54 #define QSERDES_V7_RX_SIGDET_CNTRL 0x11c 55 #define QSERDES_V7_RX_SIGDET_DEGLITCH_CNTRL 0x124 56 #define QSERDES_V7_RX_RX_MODE_00_LOW 0x15c
+108 -51
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
··· 1107 const struct qmp_phy_cfg_tbls tbls_hs_overlay[NUM_OVERLAY]; 1108 1109 /* regulators to be requested */ 1110 - const char * const *vreg_list; 1111 int num_vregs; 1112 1113 /* array of registers with different offsets */ ··· 1164 readl(base + offset); 1165 } 1166 1167 - /* list of regulators */ 1168 - static const char * const qmp_phy_vreg_l[] = { 1169 - "vdda-phy", "vdda-pll", 1170 }; 1171 1172 static const struct qmp_ufs_offsets qmp_ufs_offsets = { ··· 1273 .rx_num = ARRAY_SIZE(msm8996_ufsphy_rx), 1274 }, 1275 1276 - .vreg_list = qmp_phy_vreg_l, 1277 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1278 1279 .regs = ufsphy_v2_regs_layout, 1280 ··· 1310 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 1311 .max_gear = UFS_HS_G4, 1312 }, 1313 - .vreg_list = qmp_phy_vreg_l, 1314 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1315 .regs = ufsphy_v5_regs_layout, 1316 }; 1317 ··· 1344 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), 1345 .max_gear = UFS_HS_G4, 1346 }, 1347 - .vreg_list = qmp_phy_vreg_l, 1348 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1349 .regs = ufsphy_v4_regs_layout, 1350 }; 1351 ··· 1378 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 1379 .max_gear = UFS_HS_G4, 1380 }, 1381 - .vreg_list = qmp_phy_vreg_l, 1382 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1383 .regs = ufsphy_v5_regs_layout, 1384 }; 1385 ··· 1403 .serdes = sdm845_ufsphy_hs_b_serdes, 1404 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes), 1405 }, 1406 - .vreg_list = qmp_phy_vreg_l, 1407 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1408 .regs = ufsphy_v3_regs_layout, 1409 1410 .no_pcs_sw_reset = true, ··· 1430 .serdes = sm6115_ufsphy_hs_b_serdes, 1431 .serdes_num = ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes), 1432 }, 1433 - .vreg_list = qmp_phy_vreg_l, 1434 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1435 .regs = ufsphy_v2_regs_layout, 1436 1437 .no_pcs_sw_reset = true, ··· 1457 .serdes = sdm845_ufsphy_hs_b_serdes, 1458 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes), 1459 }, 1460 - .vreg_list = qmp_phy_vreg_l, 1461 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1462 .regs = ufsphy_v3_regs_layout, 1463 1464 .no_pcs_sw_reset = true, ··· 1493 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), 1494 .max_gear = UFS_HS_G4, 1495 }, 1496 - .vreg_list = qmp_phy_vreg_l, 1497 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1498 .regs = ufsphy_v4_regs_layout, 1499 }; 1500 ··· 1527 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), 1528 .max_gear = UFS_HS_G4, 1529 }, 1530 - .vreg_list = qmp_phy_vreg_l, 1531 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1532 .regs = ufsphy_v4_regs_layout, 1533 }; 1534 ··· 1561 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 1562 .max_gear = UFS_HS_G4, 1563 }, 1564 - .vreg_list = qmp_phy_vreg_l, 1565 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1566 .regs = ufsphy_v5_regs_layout, 1567 }; 1568 ··· 1595 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 1596 .max_gear = UFS_HS_G4, 1597 }, 1598 - .vreg_list = qmp_phy_vreg_l, 1599 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1600 .regs = ufsphy_v5_regs_layout, 1601 }; 1602 ··· 1631 .pcs_num = ARRAY_SIZE(sm8475_ufsphy_g4_pcs), 1632 .max_gear = UFS_HS_G4, 1633 }, 1634 - .vreg_list = qmp_phy_vreg_l, 1635 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1636 .regs = ufsphy_v6_regs_layout, 1637 }; 1638 ··· 1676 .pcs_num = ARRAY_SIZE(sm8550_ufsphy_g5_pcs), 1677 .max_gear = UFS_HS_G5, 1678 }, 1679 - .vreg_list = qmp_phy_vreg_l, 1680 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1681 .regs = ufsphy_v6_regs_layout, 1682 }; 1683 ··· 1708 .max_gear = UFS_HS_G5, 1709 }, 1710 1711 - .vreg_list = qmp_phy_vreg_l, 1712 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1713 .regs = ufsphy_v6_regs_layout, 1714 }; 1715 ··· 1746 .max_gear = UFS_HS_G5, 1747 }, 1748 1749 - .vreg_list = qmp_phy_vreg_l, 1750 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1751 .regs = ufsphy_v6_regs_layout, 1752 1753 }; ··· 1961 .owner = THIS_MODULE, 1962 }; 1963 1964 - static int qmp_ufs_vreg_init(struct qmp_ufs *qmp) 1965 - { 1966 - const struct qmp_phy_cfg *cfg = qmp->cfg; 1967 - struct device *dev = qmp->dev; 1968 - int num = cfg->num_vregs; 1969 - int i; 1970 - 1971 - qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); 1972 - if (!qmp->vregs) 1973 - return -ENOMEM; 1974 - 1975 - for (i = 0; i < num; i++) 1976 - qmp->vregs[i].supply = cfg->vreg_list[i]; 1977 - 1978 - return devm_regulator_bulk_get(dev, num, qmp->vregs); 1979 - } 1980 1981 static int qmp_ufs_clk_init(struct qmp_ufs *qmp) 1982 { ··· 2123 if (ret) 2124 return ret; 2125 2126 - ret = qmp_ufs_vreg_init(qmp); 2127 if (ret) 2128 return ret; 2129
··· 1107 const struct qmp_phy_cfg_tbls tbls_hs_overlay[NUM_OVERLAY]; 1108 1109 /* regulators to be requested */ 1110 + const struct regulator_bulk_data *vreg_list; 1111 int num_vregs; 1112 1113 /* array of registers with different offsets */ ··· 1164 readl(base + offset); 1165 } 1166 1167 + /* Regulator bulk data with load values for specific configurations */ 1168 + static const struct regulator_bulk_data msm8996_ufsphy_vreg_l[] = { 1169 + { .supply = "vdda-phy", .init_load_uA = 51400 }, 1170 + { .supply = "vdda-pll", .init_load_uA = 14600 }, 1171 + }; 1172 + 1173 + static const struct regulator_bulk_data sa8775p_ufsphy_vreg_l[] = { 1174 + { .supply = "vdda-phy", .init_load_uA = 137000 }, 1175 + { .supply = "vdda-pll", .init_load_uA = 18300 }, 1176 + }; 1177 + 1178 + static const struct regulator_bulk_data sc7280_ufsphy_vreg_l[] = { 1179 + { .supply = "vdda-phy", .init_load_uA = 97500 }, 1180 + { .supply = "vdda-pll", .init_load_uA = 18400 }, 1181 + }; 1182 + 1183 + static const struct regulator_bulk_data sc8280xp_ufsphy_vreg_l[] = { 1184 + { .supply = "vdda-phy", .init_load_uA = 85700 }, 1185 + { .supply = "vdda-pll", .init_load_uA = 18300 }, 1186 + }; 1187 + 1188 + static const struct regulator_bulk_data sdm845_ufsphy_vreg_l[] = { 1189 + { .supply = "vdda-phy", .init_load_uA = 51400 }, 1190 + { .supply = "vdda-pll", .init_load_uA = 14600 }, 1191 + }; 1192 + 1193 + static const struct regulator_bulk_data sm6115_ufsphy_vreg_l[] = { 1194 + { .supply = "vdda-phy", .init_load_uA = 51400 }, 1195 + { .supply = "vdda-pll", .init_load_uA = 14200 }, 1196 + }; 1197 + 1198 + static const struct regulator_bulk_data sm7150_ufsphy_vreg_l[] = { 1199 + { .supply = "vdda-phy", .init_load_uA = 62900 }, 1200 + { .supply = "vdda-pll", .init_load_uA = 18300 }, 1201 + }; 1202 + 1203 + static const struct regulator_bulk_data sm8150_ufsphy_vreg_l[] = { 1204 + { .supply = "vdda-phy", .init_load_uA = 90200 }, 1205 + { .supply = "vdda-pll", .init_load_uA = 19000 }, 1206 + }; 1207 + 1208 + static const struct regulator_bulk_data sm8250_ufsphy_vreg_l[] = { 1209 + { .supply = "vdda-phy", .init_load_uA = 89900 }, 1210 + { .supply = "vdda-pll", .init_load_uA = 18800 }, 1211 + }; 1212 + 1213 + static const struct regulator_bulk_data sm8350_ufsphy_vreg_l[] = { 1214 + { .supply = "vdda-phy", .init_load_uA = 91600 }, 1215 + { .supply = "vdda-pll", .init_load_uA = 19000 }, 1216 + }; 1217 + 1218 + static const struct regulator_bulk_data sm8450_ufsphy_vreg_l[] = { 1219 + { .supply = "vdda-phy", .init_load_uA = 173000 }, 1220 + { .supply = "vdda-pll", .init_load_uA = 24900 }, 1221 + }; 1222 + 1223 + static const struct regulator_bulk_data sm8475_ufsphy_vreg_l[] = { 1224 + { .supply = "vdda-phy", .init_load_uA = 213030 }, 1225 + { .supply = "vdda-pll", .init_load_uA = 18340 }, 1226 + }; 1227 + 1228 + static const struct regulator_bulk_data sm8550_ufsphy_vreg_l[] = { 1229 + { .supply = "vdda-phy", .init_load_uA = 188000 }, 1230 + { .supply = "vdda-pll", .init_load_uA = 18300 }, 1231 + }; 1232 + 1233 + static const struct regulator_bulk_data sm8650_ufsphy_vreg_l[] = { 1234 + { .supply = "vdda-phy", .init_load_uA = 205000 }, 1235 + { .supply = "vdda-pll", .init_load_uA = 17500 }, 1236 + }; 1237 + 1238 + static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = { 1239 + { .supply = "vdda-phy", .init_load_uA = 213000 }, 1240 + { .supply = "vdda-pll", .init_load_uA = 18300 }, 1241 }; 1242 1243 static const struct qmp_ufs_offsets qmp_ufs_offsets = { ··· 1202 .rx_num = ARRAY_SIZE(msm8996_ufsphy_rx), 1203 }, 1204 1205 + .vreg_list = msm8996_ufsphy_vreg_l, 1206 + .num_vregs = ARRAY_SIZE(msm8996_ufsphy_vreg_l), 1207 1208 .regs = ufsphy_v2_regs_layout, 1209 ··· 1239 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 1240 .max_gear = UFS_HS_G4, 1241 }, 1242 + .vreg_list = sa8775p_ufsphy_vreg_l, 1243 + .num_vregs = ARRAY_SIZE(sa8775p_ufsphy_vreg_l), 1244 .regs = ufsphy_v5_regs_layout, 1245 }; 1246 ··· 1273 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), 1274 .max_gear = UFS_HS_G4, 1275 }, 1276 + .vreg_list = sc7280_ufsphy_vreg_l, 1277 + .num_vregs = ARRAY_SIZE(sc7280_ufsphy_vreg_l), 1278 .regs = ufsphy_v4_regs_layout, 1279 }; 1280 ··· 1307 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 1308 .max_gear = UFS_HS_G4, 1309 }, 1310 + .vreg_list = sc8280xp_ufsphy_vreg_l, 1311 + .num_vregs = ARRAY_SIZE(sc8280xp_ufsphy_vreg_l), 1312 .regs = ufsphy_v5_regs_layout, 1313 }; 1314 ··· 1332 .serdes = sdm845_ufsphy_hs_b_serdes, 1333 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes), 1334 }, 1335 + .vreg_list = sdm845_ufsphy_vreg_l, 1336 + .num_vregs = ARRAY_SIZE(sdm845_ufsphy_vreg_l), 1337 .regs = ufsphy_v3_regs_layout, 1338 1339 .no_pcs_sw_reset = true, ··· 1359 .serdes = sm6115_ufsphy_hs_b_serdes, 1360 .serdes_num = ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes), 1361 }, 1362 + .vreg_list = sm6115_ufsphy_vreg_l, 1363 + .num_vregs = ARRAY_SIZE(sm6115_ufsphy_vreg_l), 1364 .regs = ufsphy_v2_regs_layout, 1365 1366 .no_pcs_sw_reset = true, ··· 1386 .serdes = sdm845_ufsphy_hs_b_serdes, 1387 .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes), 1388 }, 1389 + .vreg_list = sm7150_ufsphy_vreg_l, 1390 + .num_vregs = ARRAY_SIZE(sm7150_ufsphy_vreg_l), 1391 .regs = ufsphy_v3_regs_layout, 1392 1393 .no_pcs_sw_reset = true, ··· 1422 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), 1423 .max_gear = UFS_HS_G4, 1424 }, 1425 + .vreg_list = sm8150_ufsphy_vreg_l, 1426 + .num_vregs = ARRAY_SIZE(sm8150_ufsphy_vreg_l), 1427 .regs = ufsphy_v4_regs_layout, 1428 }; 1429 ··· 1456 .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), 1457 .max_gear = UFS_HS_G4, 1458 }, 1459 + .vreg_list = sm8250_ufsphy_vreg_l, 1460 + .num_vregs = ARRAY_SIZE(sm8250_ufsphy_vreg_l), 1461 .regs = ufsphy_v4_regs_layout, 1462 }; 1463 ··· 1490 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 1491 .max_gear = UFS_HS_G4, 1492 }, 1493 + .vreg_list = sm8350_ufsphy_vreg_l, 1494 + .num_vregs = ARRAY_SIZE(sm8350_ufsphy_vreg_l), 1495 .regs = ufsphy_v5_regs_layout, 1496 }; 1497 ··· 1524 .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), 1525 .max_gear = UFS_HS_G4, 1526 }, 1527 + .vreg_list = sm8450_ufsphy_vreg_l, 1528 + .num_vregs = ARRAY_SIZE(sm8450_ufsphy_vreg_l), 1529 .regs = ufsphy_v5_regs_layout, 1530 }; 1531 ··· 1560 .pcs_num = ARRAY_SIZE(sm8475_ufsphy_g4_pcs), 1561 .max_gear = UFS_HS_G4, 1562 }, 1563 + .vreg_list = sm8475_ufsphy_vreg_l, 1564 + .num_vregs = ARRAY_SIZE(sm8475_ufsphy_vreg_l), 1565 .regs = ufsphy_v6_regs_layout, 1566 }; 1567 ··· 1605 .pcs_num = ARRAY_SIZE(sm8550_ufsphy_g5_pcs), 1606 .max_gear = UFS_HS_G5, 1607 }, 1608 + .vreg_list = sm8550_ufsphy_vreg_l, 1609 + .num_vregs = ARRAY_SIZE(sm8550_ufsphy_vreg_l), 1610 .regs = ufsphy_v6_regs_layout, 1611 }; 1612 ··· 1637 .max_gear = UFS_HS_G5, 1638 }, 1639 1640 + .vreg_list = sm8650_ufsphy_vreg_l, 1641 + .num_vregs = ARRAY_SIZE(sm8650_ufsphy_vreg_l), 1642 .regs = ufsphy_v6_regs_layout, 1643 }; 1644 ··· 1675 .max_gear = UFS_HS_G5, 1676 }, 1677 1678 + .vreg_list = sm8750_ufsphy_vreg_l, 1679 + .num_vregs = ARRAY_SIZE(sm8750_ufsphy_vreg_l), 1680 .regs = ufsphy_v6_regs_layout, 1681 1682 }; ··· 1890 .owner = THIS_MODULE, 1891 }; 1892 1893 1894 static int qmp_ufs_clk_init(struct qmp_ufs *qmp) 1895 { ··· 2068 if (ret) 2069 return ret; 2070 2071 + ret = devm_regulator_bulk_get_const(dev, qmp->cfg->num_vregs, 2072 + qmp->cfg->vreg_list, 2073 + &qmp->vregs); 2074 if (ret) 2075 return ret; 2076
+100 -36
drivers/phy/renesas/phy-rcar-gen3-usb2.c
··· 9 * Copyright (C) 2014 Cogent Embedded, Inc. 10 */ 11 12 #include <linux/cleanup.h> 13 #include <linux/extcon-provider.h> 14 #include <linux/interrupt.h> ··· 71 #define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */ 72 73 /* OBINTSTA and OBINTEN */ 74 #define USB2_OBINT_SESSVLDCHG BIT(12) 75 #define USB2_OBINT_IDDIGCHG BIT(11) 76 - #define USB2_OBINT_BITS (USB2_OBINT_SESSVLDCHG | \ 77 - USB2_OBINT_IDDIGCHG) 78 79 /* VBCTRL */ 80 #define USB2_VBCTRL_OCCLREN BIT(16) 81 #define USB2_VBCTRL_DRVVBUSSEL BIT(8) 82 #define USB2_VBCTRL_VBOUT BIT(0) 83 84 /* LINECTRL1 */ ··· 97 /* ADPCTRL */ 98 #define USB2_ADPCTRL_OTGSESSVLD BIT(20) 99 #define USB2_ADPCTRL_IDDIG BIT(19) 100 #define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */ 101 #define USB2_ADPCTRL_DRVVBUS BIT(4) 102 103 /* RZ/G2L specific */ 104 - #define USB2_OBINT_IDCHG_EN BIT(0) 105 #define USB2_LINECTRL1_USB2_IDMON BIT(0) 106 107 #define NUM_OF_PHYS 4 ··· 130 struct rcar_gen3_chan { 131 void __iomem *base; 132 struct device *dev; /* platform_device's device */ 133 struct extcon_dev *extcon; 134 struct rcar_gen3_phy rphys[NUM_OF_PHYS]; 135 struct regulator *vbus; ··· 138 struct work_struct work; 139 spinlock_t lock; /* protects access to hardware and driver data structure. */ 140 enum usb_dr_mode dr_mode; 141 - u32 obint_enable_bits; 142 bool extcon_host; 143 bool is_otg_channel; 144 bool uses_otg_pins; 145 - bool soc_no_adp_ctrl; 146 - bool utmi_ctrl; 147 }; 148 149 struct rcar_gen3_phy_drv_data { ··· 148 bool no_adp_ctrl; 149 bool init_bus; 150 bool utmi_ctrl; 151 }; 152 153 /* ··· 211 u32 vbus_ctrl_val = USB2_ADPCTRL_DRVVBUS; 212 u32 val; 213 214 - dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); 215 - if (ch->soc_no_adp_ctrl) { 216 if (ch->vbus) 217 regulator_hardware_enable(ch->vbus, vbus); 218 ··· 224 val |= vbus_ctrl_val; 225 else 226 val &= ~vbus_ctrl_val; 227 writel(val, usb2_base + vbus_ctrl_reg); 228 } 229 ··· 234 u32 val = readl(usb2_base + USB2_OBINTEN); 235 236 if (ch->uses_otg_pins && enable) 237 - val |= ch->obint_enable_bits; 238 else 239 - val &= ~ch->obint_enable_bits; 240 writel(val, usb2_base + USB2_OBINTEN); 241 } 242 ··· 295 296 static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch) 297 { 298 - if (!ch->uses_otg_pins) 299 - return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true; 300 301 - if (ch->soc_no_adp_ctrl) 302 return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON); 303 304 return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); ··· 439 USB2_LINECTRL1_DMRPD_EN | USB2_LINECTRL1_DM_RPD; 440 writel(val, usb2_base + USB2_LINECTRL1); 441 442 - if (!ch->soc_no_adp_ctrl) { 443 - val = readl(usb2_base + USB2_VBCTRL); 444 - val &= ~USB2_VBCTRL_OCCLREN; 445 - writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); 446 - val = readl(usb2_base + USB2_ADPCTRL); 447 - writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); 448 } 449 mdelay(20); 450 451 writel(0xffffffff, usb2_base + USB2_OBINTSTA); 452 - writel(ch->obint_enable_bits, usb2_base + USB2_OBINTEN); 453 454 rcar_gen3_device_recognition(ch); 455 } 456 457 static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) ··· 495 496 scoped_guard(spinlock, &ch->lock) { 497 status = readl(usb2_base + USB2_OBINTSTA); 498 - if (status & ch->obint_enable_bits) { 499 dev_vdbg(dev, "%s: %08x\n", __func__, status); 500 - writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA); 501 rcar_gen3_device_recognition(ch); 502 ret = IRQ_HANDLED; 503 } 504 } ··· 535 if (rphy->int_enable_bits) 536 rcar_gen3_init_otg(channel); 537 538 - if (channel->utmi_ctrl) { 539 val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN; 540 writel(val, usb2_base + USB2_REGEN_CG_CTRL); 541 ··· 647 static const struct rcar_gen3_phy_drv_data rcar_gen3_phy_usb2_data = { 648 .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 649 .no_adp_ctrl = false, 650 }; 651 652 static const struct rcar_gen3_phy_drv_data rz_g1c_phy_usb2_data = { 653 .phy_usb2_ops = &rz_g1c_phy_usb2_ops, 654 .no_adp_ctrl = false, 655 }; 656 657 static const struct rcar_gen3_phy_drv_data rz_g2l_phy_usb2_data = { 658 .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 659 .no_adp_ctrl = true, 660 }; 661 662 static const struct rcar_gen3_phy_drv_data rz_g3s_phy_usb2_data = { 663 .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 664 .no_adp_ctrl = true, 665 .init_bus = true, 666 }; 667 668 static const struct rcar_gen3_phy_drv_data rz_v2h_phy_usb2_data = { 669 .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 670 .no_adp_ctrl = true, 671 .utmi_ctrl = true, 672 }; 673 674 static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { ··· 708 { 709 .compatible = "renesas,usb2-phy-r9a09g057", 710 .data = &rz_v2h_phy_usb2_data, 711 }, 712 { 713 .compatible = "renesas,rzg2l-usb2-phy", ··· 802 803 static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) 804 { 805 - const struct rcar_gen3_phy_drv_data *phy_data; 806 struct device *dev = &pdev->dev; 807 struct rcar_gen3_chan *channel; 808 struct phy_provider *provider; ··· 820 if (IS_ERR(channel->base)) 821 return PTR_ERR(channel->base); 822 823 - channel->obint_enable_bits = USB2_OBINT_BITS; 824 channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node); 825 if (channel->dr_mode != USB_DR_MODE_UNKNOWN) { 826 channel->is_otg_channel = true; ··· 843 */ 844 pm_runtime_enable(dev); 845 846 - phy_data = of_device_get_match_data(dev); 847 - if (!phy_data) { 848 ret = -EINVAL; 849 goto error; 850 } ··· 852 platform_set_drvdata(pdev, channel); 853 channel->dev = dev; 854 855 - if (phy_data->init_bus) { 856 ret = rcar_gen3_phy_usb2_init_bus(channel); 857 if (ret) 858 goto error; 859 } 860 861 - channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl; 862 - if (phy_data->no_adp_ctrl) 863 - channel->obint_enable_bits = USB2_OBINT_IDCHG_EN; 864 - 865 - channel->utmi_ctrl = phy_data->utmi_ctrl; 866 - 867 spin_lock_init(&channel->lock); 868 for (i = 0; i < NUM_OF_PHYS; i++) { 869 channel->rphys[i].phy = devm_phy_create(dev, NULL, 870 - phy_data->phy_usb2_ops); 871 if (IS_ERR(channel->rphys[i].phy)) { 872 dev_err(dev, "Failed to create USB2 PHY\n"); 873 ret = PTR_ERR(channel->rphys[i].phy); ··· 872 phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]); 873 } 874 875 - if (channel->soc_no_adp_ctrl && channel->is_otg_channel) 876 channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); 877 else 878 channel->vbus = devm_regulator_get_optional(dev, "vbus");
··· 9 * Copyright (C) 2014 Cogent Embedded, Inc. 10 */ 11 12 + #include <linux/bitfield.h> 13 + #include <linux/bits.h> 14 #include <linux/cleanup.h> 15 #include <linux/extcon-provider.h> 16 #include <linux/interrupt.h> ··· 69 #define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */ 70 71 /* OBINTSTA and OBINTEN */ 72 + #define USB2_OBINTSTA_CLEAR GENMASK(31, 0) 73 #define USB2_OBINT_SESSVLDCHG BIT(12) 74 #define USB2_OBINT_IDDIGCHG BIT(11) 75 + #define USB2_OBINT_VBSTAINT BIT(3) 76 + #define USB2_OBINT_IDCHG_EN BIT(0) /* RZ/G2L specific */ 77 78 /* VBCTRL */ 79 + #define USB2_VBCTRL_VBSTA_MASK GENMASK(31, 28) 80 + #define USB2_VBCTRL_VBSTA_DEFAULT 2 81 + #define USB2_VBCTRL_VBLVL_MASK GENMASK(23, 20) 82 + #define USB2_VBCTRL_VBLVL(m) FIELD_PREP_CONST(USB2_VBCTRL_VBLVL_MASK, (m)) 83 #define USB2_VBCTRL_OCCLREN BIT(16) 84 #define USB2_VBCTRL_DRVVBUSSEL BIT(8) 85 + #define USB2_VBCTRL_SIDDQREL BIT(2) 86 #define USB2_VBCTRL_VBOUT BIT(0) 87 88 /* LINECTRL1 */ ··· 89 /* ADPCTRL */ 90 #define USB2_ADPCTRL_OTGSESSVLD BIT(20) 91 #define USB2_ADPCTRL_IDDIG BIT(19) 92 + #define USB2_ADPCTRL_VBUSVALID BIT(18) 93 #define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */ 94 #define USB2_ADPCTRL_DRVVBUS BIT(4) 95 96 /* RZ/G2L specific */ 97 #define USB2_LINECTRL1_USB2_IDMON BIT(0) 98 99 #define NUM_OF_PHYS 4 ··· 122 struct rcar_gen3_chan { 123 void __iomem *base; 124 struct device *dev; /* platform_device's device */ 125 + const struct rcar_gen3_phy_drv_data *phy_data; 126 struct extcon_dev *extcon; 127 struct rcar_gen3_phy rphys[NUM_OF_PHYS]; 128 struct regulator *vbus; ··· 129 struct work_struct work; 130 spinlock_t lock; /* protects access to hardware and driver data structure. */ 131 enum usb_dr_mode dr_mode; 132 bool extcon_host; 133 bool is_otg_channel; 134 bool uses_otg_pins; 135 }; 136 137 struct rcar_gen3_phy_drv_data { ··· 142 bool no_adp_ctrl; 143 bool init_bus; 144 bool utmi_ctrl; 145 + bool vblvl_ctrl; 146 + u32 obint_enable_bits; 147 }; 148 149 /* ··· 203 u32 vbus_ctrl_val = USB2_ADPCTRL_DRVVBUS; 204 u32 val; 205 206 + if (ch->phy_data->no_adp_ctrl || ch->phy_data->vblvl_ctrl) { 207 if (ch->vbus) 208 regulator_hardware_enable(ch->vbus, vbus); 209 ··· 217 val |= vbus_ctrl_val; 218 else 219 val &= ~vbus_ctrl_val; 220 + dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); 221 writel(val, usb2_base + vbus_ctrl_reg); 222 } 223 ··· 226 u32 val = readl(usb2_base + USB2_OBINTEN); 227 228 if (ch->uses_otg_pins && enable) 229 + val |= ch->phy_data->obint_enable_bits; 230 else 231 + val &= ~ch->phy_data->obint_enable_bits; 232 writel(val, usb2_base + USB2_OBINTEN); 233 } 234 ··· 287 288 static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch) 289 { 290 + if (ch->phy_data->vblvl_ctrl) { 291 + bool vbus_valid; 292 + bool device; 293 294 + device = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); 295 + vbus_valid = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_VBUSVALID); 296 + 297 + return vbus_valid ? device : !device; 298 + } 299 + 300 + if (!ch->uses_otg_pins) 301 + return ch->dr_mode != USB_DR_MODE_HOST; 302 + 303 + if (ch->phy_data->no_adp_ctrl) 304 return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON); 305 306 return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); ··· 421 USB2_LINECTRL1_DMRPD_EN | USB2_LINECTRL1_DM_RPD; 422 writel(val, usb2_base + USB2_LINECTRL1); 423 424 + if (!ch->phy_data->no_adp_ctrl) { 425 + if (ch->phy_data->vblvl_ctrl) { 426 + val = readl(usb2_base + USB2_VBCTRL); 427 + val = (val & ~USB2_VBCTRL_VBLVL_MASK) | USB2_VBCTRL_VBLVL(2); 428 + writel(val, usb2_base + USB2_VBCTRL); 429 + val = readl(usb2_base + USB2_ADPCTRL); 430 + writel(val | USB2_ADPCTRL_IDPULLUP | USB2_ADPCTRL_DRVVBUS, 431 + usb2_base + USB2_ADPCTRL); 432 + } else { 433 + val = readl(usb2_base + USB2_VBCTRL); 434 + val &= ~USB2_VBCTRL_OCCLREN; 435 + writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); 436 + val = readl(usb2_base + USB2_ADPCTRL); 437 + writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); 438 + } 439 } 440 mdelay(20); 441 442 writel(0xffffffff, usb2_base + USB2_OBINTSTA); 443 + writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTEN); 444 445 rcar_gen3_device_recognition(ch); 446 + } 447 + 448 + static void rcar_gen3_configure_vblvl_ctrl(struct rcar_gen3_chan *ch) 449 + { 450 + void __iomem *usb2_base = ch->base; 451 + u32 val; 452 + 453 + if (!ch->phy_data->vblvl_ctrl) 454 + return; 455 + 456 + val = readl(usb2_base + USB2_VBCTRL); 457 + if ((val & USB2_VBCTRL_VBSTA_MASK) == 458 + FIELD_PREP_CONST(USB2_VBCTRL_VBSTA_MASK, USB2_VBCTRL_VBSTA_DEFAULT)) 459 + val &= ~USB2_VBCTRL_VBLVL_MASK; 460 + else 461 + val |= USB2_VBCTRL_VBLVL(USB2_VBCTRL_VBSTA_DEFAULT); 462 + writel(val, usb2_base + USB2_VBCTRL); 463 } 464 465 static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) ··· 451 452 scoped_guard(spinlock, &ch->lock) { 453 status = readl(usb2_base + USB2_OBINTSTA); 454 + if (status & ch->phy_data->obint_enable_bits) { 455 dev_vdbg(dev, "%s: %08x\n", __func__, status); 456 + if (ch->phy_data->vblvl_ctrl) 457 + writel(USB2_OBINTSTA_CLEAR, usb2_base + USB2_OBINTSTA); 458 + else 459 + writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTSTA); 460 rcar_gen3_device_recognition(ch); 461 + rcar_gen3_configure_vblvl_ctrl(ch); 462 ret = IRQ_HANDLED; 463 } 464 } ··· 487 if (rphy->int_enable_bits) 488 rcar_gen3_init_otg(channel); 489 490 + if (channel->phy_data->vblvl_ctrl) { 491 + /* SIDDQ mode release */ 492 + writel(readl(usb2_base + USB2_VBCTRL) | USB2_VBCTRL_SIDDQREL, 493 + usb2_base + USB2_VBCTRL); 494 + udelay(250); 495 + } 496 + 497 + if (channel->phy_data->utmi_ctrl) { 498 val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN; 499 writel(val, usb2_base + USB2_REGEN_CG_CTRL); 500 ··· 592 static const struct rcar_gen3_phy_drv_data rcar_gen3_phy_usb2_data = { 593 .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 594 .no_adp_ctrl = false, 595 + .obint_enable_bits = USB2_OBINT_SESSVLDCHG | 596 + USB2_OBINT_IDDIGCHG, 597 }; 598 599 static const struct rcar_gen3_phy_drv_data rz_g1c_phy_usb2_data = { 600 .phy_usb2_ops = &rz_g1c_phy_usb2_ops, 601 .no_adp_ctrl = false, 602 + .obint_enable_bits = USB2_OBINT_SESSVLDCHG | 603 + USB2_OBINT_IDDIGCHG, 604 }; 605 606 static const struct rcar_gen3_phy_drv_data rz_g2l_phy_usb2_data = { 607 .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 608 .no_adp_ctrl = true, 609 + .obint_enable_bits = USB2_OBINT_IDCHG_EN, 610 }; 611 612 static const struct rcar_gen3_phy_drv_data rz_g3s_phy_usb2_data = { 613 .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 614 .no_adp_ctrl = true, 615 .init_bus = true, 616 + .obint_enable_bits = USB2_OBINT_IDCHG_EN, 617 + }; 618 + 619 + static const struct rcar_gen3_phy_drv_data rz_t2h_phy_usb2_data = { 620 + .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 621 + .vblvl_ctrl = true, 622 + .obint_enable_bits = USB2_OBINT_IDCHG_EN | USB2_OBINT_VBSTAINT, 623 }; 624 625 static const struct rcar_gen3_phy_drv_data rz_v2h_phy_usb2_data = { 626 .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 627 .no_adp_ctrl = true, 628 .utmi_ctrl = true, 629 + .obint_enable_bits = USB2_OBINT_IDCHG_EN, 630 }; 631 632 static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { ··· 640 { 641 .compatible = "renesas,usb2-phy-r9a09g057", 642 .data = &rz_v2h_phy_usb2_data, 643 + }, 644 + { 645 + .compatible = "renesas,usb2-phy-r9a09g077", 646 + .data = &rz_t2h_phy_usb2_data, 647 }, 648 { 649 .compatible = "renesas,rzg2l-usb2-phy", ··· 730 731 static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) 732 { 733 struct device *dev = &pdev->dev; 734 struct rcar_gen3_chan *channel; 735 struct phy_provider *provider; ··· 749 if (IS_ERR(channel->base)) 750 return PTR_ERR(channel->base); 751 752 channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node); 753 if (channel->dr_mode != USB_DR_MODE_UNKNOWN) { 754 channel->is_otg_channel = true; ··· 773 */ 774 pm_runtime_enable(dev); 775 776 + channel->phy_data = of_device_get_match_data(dev); 777 + if (!channel->phy_data) { 778 ret = -EINVAL; 779 goto error; 780 } ··· 782 platform_set_drvdata(pdev, channel); 783 channel->dev = dev; 784 785 + if (channel->phy_data->init_bus) { 786 ret = rcar_gen3_phy_usb2_init_bus(channel); 787 if (ret) 788 goto error; 789 } 790 791 spin_lock_init(&channel->lock); 792 for (i = 0; i < NUM_OF_PHYS; i++) { 793 channel->rphys[i].phy = devm_phy_create(dev, NULL, 794 + channel->phy_data->phy_usb2_ops); 795 if (IS_ERR(channel->rphys[i].phy)) { 796 dev_err(dev, "Failed to create USB2 PHY\n"); 797 ret = PTR_ERR(channel->rphys[i].phy); ··· 808 phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]); 809 } 810 811 + if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel) 812 channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); 813 else 814 channel->vbus = devm_regulator_get_optional(dev, "vbus");
+85 -12
drivers/phy/renesas/r8a779f0-ether-serdes.c
··· 1 // SPDX-License-Identifier: GPL-2.0 2 /* Renesas Ethernet SERDES device driver 3 * 4 - * Copyright (C) 2022 Renesas Electronics Corporation 5 */ 6 7 #include <linux/delay.h> ··· 49 iowrite32(data, addr + offs); 50 } 51 52 static int 53 r8a779f0_eth_serdes_reg_wait(struct r8a779f0_eth_serdes_channel *channel, 54 u32 offs, u32 bank, u32 mask, u32 expected) ··· 99 { 100 struct r8a779f0_eth_serdes_drv_data *dd = channel->dd; 101 102 - switch (channel->phy_interface) { 103 - case PHY_INTERFACE_MODE_SGMII: 104 - r8a779f0_eth_serdes_write32(dd->addr, 0x0244, 0x180, 0x0097); 105 - r8a779f0_eth_serdes_write32(dd->addr, 0x01d0, 0x180, 0x0060); 106 - r8a779f0_eth_serdes_write32(dd->addr, 0x01d8, 0x180, 0x2200); 107 - r8a779f0_eth_serdes_write32(dd->addr, 0x01d4, 0x180, 0x0000); 108 - r8a779f0_eth_serdes_write32(dd->addr, 0x01e0, 0x180, 0x003d); 109 - return 0; 110 - default: 111 - return -EOPNOTSUPP; 112 - } 113 } 114 115 static int ··· 163 r8a779f0_eth_serdes_write32(channel->addr, 0x0028, 0x1f80, 0x07a1); 164 r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f80, 0x0208); 165 break; 166 default: 167 return -EOPNOTSUPP; 168 } ··· 222 if (ret) 223 return ret; 224 r8a779f0_eth_serdes_write32(channel->addr, 0x0008, 0x1f80, 0x0000); 225 break; 226 default: 227 return -EOPNOTSUPP; ··· 326 *channel) 327 { 328 int ret; 329 330 ret = r8a779f0_eth_serdes_chan_setting(channel); 331 if (ret) ··· 339 r8a779f0_eth_serdes_write32(channel->addr, 0x03c0, 0x380, 0x0000); 340 341 r8a779f0_eth_serdes_write32(channel->addr, 0x03d0, 0x380, 0x0000); 342 343 return r8a779f0_eth_serdes_monitor_linkup(channel); 344 }
··· 1 // SPDX-License-Identifier: GPL-2.0 2 /* Renesas Ethernet SERDES device driver 3 * 4 + * Copyright (C) 2022-2025 Renesas Electronics Corporation 5 */ 6 7 #include <linux/delay.h> ··· 49 iowrite32(data, addr + offs); 50 } 51 52 + static u32 r8a779f0_eth_serdes_read32(void __iomem *addr, u32 offs, u32 bank) 53 + { 54 + iowrite32(bank, addr + R8A779F0_ETH_SERDES_BANK_SELECT); 55 + 56 + return ioread32(addr + offs); 57 + } 58 + 59 static int 60 r8a779f0_eth_serdes_reg_wait(struct r8a779f0_eth_serdes_channel *channel, 61 u32 offs, u32 bank, u32 mask, u32 expected) ··· 92 { 93 struct r8a779f0_eth_serdes_drv_data *dd = channel->dd; 94 95 + /* Set combination mode */ 96 + r8a779f0_eth_serdes_write32(dd->addr, 0x0244, 0x180, 0x00d7); 97 + r8a779f0_eth_serdes_write32(dd->addr, 0x01cc, 0x180, 0xc200); 98 + r8a779f0_eth_serdes_write32(dd->addr, 0x01c4, 0x180, 0x0042); 99 + r8a779f0_eth_serdes_write32(dd->addr, 0x01c8, 0x180, 0x0000); 100 + r8a779f0_eth_serdes_write32(dd->addr, 0x01dc, 0x180, 0x002f); 101 + r8a779f0_eth_serdes_write32(dd->addr, 0x01d0, 0x180, 0x0060); 102 + r8a779f0_eth_serdes_write32(dd->addr, 0x01d8, 0x180, 0x2200); 103 + r8a779f0_eth_serdes_write32(dd->addr, 0x01d4, 0x180, 0x0000); 104 + r8a779f0_eth_serdes_write32(dd->addr, 0x01e0, 0x180, 0x003d); 105 + 106 + return 0; 107 } 108 109 static int ··· 155 r8a779f0_eth_serdes_write32(channel->addr, 0x0028, 0x1f80, 0x07a1); 156 r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f80, 0x0208); 157 break; 158 + 159 + case PHY_INTERFACE_MODE_USXGMII: 160 + r8a779f0_eth_serdes_write32(channel->addr, 0x001c, 0x300, 0x0000); 161 + r8a779f0_eth_serdes_write32(channel->addr, 0x0014, 0x380, 0x0050); 162 + r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2200); 163 + r8a779f0_eth_serdes_write32(channel->addr, 0x001c, 0x380, 0x0400); 164 + r8a779f0_eth_serdes_write32(channel->addr, 0x01c0, 0x180, 0x0001); 165 + r8a779f0_eth_serdes_write32(channel->addr, 0x0248, 0x180, 0x056a); 166 + r8a779f0_eth_serdes_write32(channel->addr, 0x0258, 0x180, 0x0015); 167 + r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, 0x1100); 168 + r8a779f0_eth_serdes_write32(channel->addr, 0x01a0, 0x180, 0x0001); 169 + r8a779f0_eth_serdes_write32(channel->addr, 0x00d0, 0x180, 0x0001); 170 + r8a779f0_eth_serdes_write32(channel->addr, 0x0150, 0x180, 0x0001); 171 + r8a779f0_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x0300); 172 + r8a779f0_eth_serdes_write32(channel->addr, 0x0148, 0x180, 0x0300); 173 + r8a779f0_eth_serdes_write32(channel->addr, 0x0174, 0x180, 0x0000); 174 + r8a779f0_eth_serdes_write32(channel->addr, 0x0160, 0x180, 0x0004); 175 + r8a779f0_eth_serdes_write32(channel->addr, 0x01ac, 0x180, 0x0000); 176 + r8a779f0_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x0310); 177 + r8a779f0_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x0301); 178 + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x00c8, 0x180, BIT(0), 0); 179 + if (ret) 180 + return ret; 181 + r8a779f0_eth_serdes_write32(channel->addr, 0x0148, 0x180, 0x0301); 182 + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0148, 0x180, BIT(0), 0); 183 + if (ret) 184 + return ret; 185 + r8a779f0_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x1310); 186 + r8a779f0_eth_serdes_write32(channel->addr, 0x00d8, 0x180, 0x1800); 187 + r8a779f0_eth_serdes_write32(channel->addr, 0x00dc, 0x180, 0x0000); 188 + r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2300); 189 + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0000, 0x380, BIT(8), 0); 190 + if (ret) 191 + return ret; 192 + break; 193 + 194 default: 195 return -EOPNOTSUPP; 196 } ··· 178 if (ret) 179 return ret; 180 r8a779f0_eth_serdes_write32(channel->addr, 0x0008, 0x1f80, 0x0000); 181 + break; 182 + case PHY_INTERFACE_MODE_USXGMII: 183 + r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x0120); 184 + usleep_range(10, 20); 185 + r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2600); 186 + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0000, 0x380, BIT(10), 0); 187 + if (ret) 188 + return ret; 189 break; 190 default: 191 return -EOPNOTSUPP; ··· 274 *channel) 275 { 276 int ret; 277 + u32 val; 278 279 ret = r8a779f0_eth_serdes_chan_setting(channel); 280 if (ret) ··· 286 r8a779f0_eth_serdes_write32(channel->addr, 0x03c0, 0x380, 0x0000); 287 288 r8a779f0_eth_serdes_write32(channel->addr, 0x03d0, 0x380, 0x0000); 289 + 290 + val = r8a779f0_eth_serdes_read32(channel->addr, 0x00c0, 0x180); 291 + r8a779f0_eth_serdes_write32(channel->addr, 0x00c0, 0x180, val | BIT(8)); 292 + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0100, 0x180, BIT(0), 1); 293 + if (ret) 294 + return ret; 295 + r8a779f0_eth_serdes_write32(channel->addr, 0x00c0, 0x180, val & ~BIT(8)); 296 + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0100, 0x180, BIT(0), 0); 297 + if (ret) 298 + return ret; 299 + 300 + val = r8a779f0_eth_serdes_read32(channel->addr, 0x0144, 0x180); 301 + r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, val | BIT(4)); 302 + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0180, 0x180, BIT(0), 1); 303 + if (ret) 304 + return ret; 305 + r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, val & ~BIT(4)); 306 + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0180, 0x180, BIT(0), 0); 307 + if (ret) 308 + return ret; 309 310 return r8a779f0_eth_serdes_monitor_linkup(channel); 311 }
+61 -6
drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
··· 30 #define RK3568_GRF_VI_CON0 0x0340 31 #define RK3568_GRF_VI_CON1 0x0344 32 33 /* PHY */ 34 #define CSIDPHY_CTRL_LANE_ENABLE 0x00 35 #define CSIDPHY_CTRL_LANE_ENABLE_CK BIT(6) ··· 69 #define RK1808_CSIDPHY_CLK_CALIB_EN 0x168 70 #define RK3568_CSIDPHY_CLK_CALIB_EN 0x168 71 72 /* 73 * The higher 16-bit of this register is used for write protection 74 * only if BIT(x + 16) set to 1 the BIT(x) can be written. ··· 91 u32 offset; 92 u32 mask; 93 u32 shift; 94 }; 95 96 #define PHY_REG(_offset, _width, _shift) \ 97 - { .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, } 98 99 static const struct dphy_reg rk1808_grf_dphy_regs[] = { 100 [GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 4, 0), ··· 119 [GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3568_GRF_VI_CON0, 1, 8), 120 }; 121 122 struct hsfreq_range { 123 u32 range_h; 124 u8 cfg_bit; ··· 137 const struct hsfreq_range *hsfreq_ranges; 138 int num_hsfreq_ranges; 139 const struct dphy_reg *grf_regs; 140 }; 141 142 struct rockchip_inno_csidphy { ··· 146 void __iomem *phy_base; 147 struct clk *pclk; 148 struct regmap *grf; 149 - struct reset_control *rst; 150 const struct dphy_drv_data *drv_data; 151 struct phy_configure_opts_mipi_dphy config; 152 u8 hsfreq; ··· 159 const struct dphy_drv_data *drv_data = priv->drv_data; 160 const struct dphy_reg *reg = &drv_data->grf_regs[index]; 161 162 - if (reg->offset) 163 regmap_write(priv->grf, reg->offset, 164 HIWORD_UPDATE(value, reg->mask, reg->shift)); 165 } ··· 185 { 299, 0x04}, { 399, 0x05}, { 499, 0x06}, { 599, 0x07}, 186 { 699, 0x08}, { 799, 0x09}, { 899, 0x0a}, {1099, 0x0b}, 187 {1249, 0x0c}, {1349, 0x0d}, {1500, 0x0e} 188 }; 189 190 static void rockchip_inno_csidphy_ths_settle(struct rockchip_inno_csidphy *priv, ··· 366 .hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges, 367 .num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges), 368 .grf_regs = rk1808_grf_dphy_regs, 369 }; 370 371 static const struct dphy_drv_data rk3326_mipidphy_drv_data = { ··· 377 .hsfreq_ranges = rk3326_mipidphy_hsfreq_ranges, 378 .num_hsfreq_ranges = ARRAY_SIZE(rk3326_mipidphy_hsfreq_ranges), 379 .grf_regs = rk3326_grf_dphy_regs, 380 }; 381 382 static const struct dphy_drv_data rk3368_mipidphy_drv_data = { ··· 388 .hsfreq_ranges = rk3368_mipidphy_hsfreq_ranges, 389 .num_hsfreq_ranges = ARRAY_SIZE(rk3368_mipidphy_hsfreq_ranges), 390 .grf_regs = rk3368_grf_dphy_regs, 391 }; 392 393 static const struct dphy_drv_data rk3568_mipidphy_drv_data = { ··· 399 .hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges, 400 .num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges), 401 .grf_regs = rk3568_grf_dphy_regs, 402 }; 403 404 static const struct of_device_id rockchip_inno_csidphy_match_id[] = { ··· 435 .compatible = "rockchip,rk3568-csi-dphy", 436 .data = &rk3568_mipidphy_drv_data, 437 }, 438 {} 439 }; 440 MODULE_DEVICE_TABLE(of, rockchip_inno_csidphy_match_id); ··· 449 struct device *dev = &pdev->dev; 450 struct phy_provider *phy_provider; 451 struct phy *phy; 452 453 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 454 if (!priv) ··· 481 return PTR_ERR(priv->pclk); 482 } 483 484 - priv->rst = devm_reset_control_get(dev, "apb"); 485 - if (IS_ERR(priv->rst)) { 486 dev_err(dev, "failed to get system reset control\n"); 487 - return PTR_ERR(priv->rst); 488 } 489 490 phy = devm_phy_create(dev, NULL, &rockchip_inno_csidphy_ops);
··· 30 #define RK3568_GRF_VI_CON0 0x0340 31 #define RK3568_GRF_VI_CON1 0x0344 32 33 + #define RK3588_CSIDPHY_GRF_CON0 0x0000 34 + 35 /* PHY */ 36 #define CSIDPHY_CTRL_LANE_ENABLE 0x00 37 #define CSIDPHY_CTRL_LANE_ENABLE_CK BIT(6) ··· 67 #define RK1808_CSIDPHY_CLK_CALIB_EN 0x168 68 #define RK3568_CSIDPHY_CLK_CALIB_EN 0x168 69 70 + #define RESETS_MAX 2 71 + 72 /* 73 * The higher 16-bit of this register is used for write protection 74 * only if BIT(x + 16) set to 1 the BIT(x) can be written. ··· 87 u32 offset; 88 u32 mask; 89 u32 shift; 90 + u8 valid; 91 }; 92 93 #define PHY_REG(_offset, _width, _shift) \ 94 + { .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, .valid = 1, } 95 96 static const struct dphy_reg rk1808_grf_dphy_regs[] = { 97 [GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 4, 0), ··· 114 [GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3568_GRF_VI_CON0, 1, 8), 115 }; 116 117 + static const struct dphy_reg rk3588_grf_dphy_regs[] = { 118 + [GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 4, 0), 119 + [GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 4, 4), 120 + [GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 1, 8), 121 + }; 122 + 123 struct hsfreq_range { 124 u32 range_h; 125 u8 cfg_bit; ··· 126 const struct hsfreq_range *hsfreq_ranges; 127 int num_hsfreq_ranges; 128 const struct dphy_reg *grf_regs; 129 + const char *const *resets; 130 + unsigned int resets_num; 131 }; 132 133 struct rockchip_inno_csidphy { ··· 133 void __iomem *phy_base; 134 struct clk *pclk; 135 struct regmap *grf; 136 + struct reset_control_bulk_data resets[RESETS_MAX]; 137 + unsigned int resets_num; 138 const struct dphy_drv_data *drv_data; 139 struct phy_configure_opts_mipi_dphy config; 140 u8 hsfreq; ··· 145 const struct dphy_drv_data *drv_data = priv->drv_data; 146 const struct dphy_reg *reg = &drv_data->grf_regs[index]; 147 148 + if (reg->valid) 149 regmap_write(priv->grf, reg->offset, 150 HIWORD_UPDATE(value, reg->mask, reg->shift)); 151 } ··· 171 { 299, 0x04}, { 399, 0x05}, { 499, 0x06}, { 599, 0x07}, 172 { 699, 0x08}, { 799, 0x09}, { 899, 0x0a}, {1099, 0x0b}, 173 {1249, 0x0c}, {1349, 0x0d}, {1500, 0x0e} 174 + }; 175 + 176 + static const char *const rk3368_reset_names[] = { 177 + "apb" 178 + }; 179 + 180 + static const char *const rk3588_reset_names[] = { 181 + "apb", 182 + "phy" 183 }; 184 185 static void rockchip_inno_csidphy_ths_settle(struct rockchip_inno_csidphy *priv, ··· 343 .hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges, 344 .num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges), 345 .grf_regs = rk1808_grf_dphy_regs, 346 + .resets = rk3368_reset_names, 347 + .resets_num = ARRAY_SIZE(rk3368_reset_names), 348 }; 349 350 static const struct dphy_drv_data rk3326_mipidphy_drv_data = { ··· 352 .hsfreq_ranges = rk3326_mipidphy_hsfreq_ranges, 353 .num_hsfreq_ranges = ARRAY_SIZE(rk3326_mipidphy_hsfreq_ranges), 354 .grf_regs = rk3326_grf_dphy_regs, 355 + .resets = rk3368_reset_names, 356 + .resets_num = ARRAY_SIZE(rk3368_reset_names), 357 }; 358 359 static const struct dphy_drv_data rk3368_mipidphy_drv_data = { ··· 361 .hsfreq_ranges = rk3368_mipidphy_hsfreq_ranges, 362 .num_hsfreq_ranges = ARRAY_SIZE(rk3368_mipidphy_hsfreq_ranges), 363 .grf_regs = rk3368_grf_dphy_regs, 364 + .resets = rk3368_reset_names, 365 + .resets_num = ARRAY_SIZE(rk3368_reset_names), 366 }; 367 368 static const struct dphy_drv_data rk3568_mipidphy_drv_data = { ··· 370 .hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges, 371 .num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges), 372 .grf_regs = rk3568_grf_dphy_regs, 373 + .resets = rk3368_reset_names, 374 + .resets_num = ARRAY_SIZE(rk3368_reset_names), 375 + }; 376 + 377 + static const struct dphy_drv_data rk3588_mipidphy_drv_data = { 378 + .pwrctl_offset = -1, 379 + .ths_settle_offset = RK3568_CSIDPHY_CLK_WR_THS_SETTLE, 380 + .calib_offset = RK3568_CSIDPHY_CLK_CALIB_EN, 381 + .hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges, 382 + .num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges), 383 + .grf_regs = rk3588_grf_dphy_regs, 384 + .resets = rk3588_reset_names, 385 + .resets_num = ARRAY_SIZE(rk3588_reset_names), 386 }; 387 388 static const struct of_device_id rockchip_inno_csidphy_match_id[] = { ··· 393 .compatible = "rockchip,rk3568-csi-dphy", 394 .data = &rk3568_mipidphy_drv_data, 395 }, 396 + { 397 + .compatible = "rockchip,rk3588-csi-dphy", 398 + .data = &rk3588_mipidphy_drv_data, 399 + }, 400 {} 401 }; 402 MODULE_DEVICE_TABLE(of, rockchip_inno_csidphy_match_id); ··· 403 struct device *dev = &pdev->dev; 404 struct phy_provider *phy_provider; 405 struct phy *phy; 406 + int ret; 407 408 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 409 if (!priv) ··· 434 return PTR_ERR(priv->pclk); 435 } 436 437 + if (priv->drv_data->resets_num > RESETS_MAX) { 438 + dev_err(dev, "invalid number of resets\n"); 439 + return -EINVAL; 440 + } 441 + priv->resets_num = priv->drv_data->resets_num; 442 + for (unsigned int i = 0; i < priv->resets_num; i++) 443 + priv->resets[i].id = priv->drv_data->resets[i]; 444 + ret = devm_reset_control_bulk_get_exclusive(dev, priv->resets_num, 445 + priv->resets); 446 + if (ret) { 447 dev_err(dev, "failed to get system reset control\n"); 448 + return ret; 449 } 450 451 phy = devm_phy_create(dev, NULL, &rockchip_inno_csidphy_ops);
+469 -254
drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
··· 20 #define REF_CLOCK_25MHz (25 * HZ_PER_MHZ) 21 #define REF_CLOCK_100MHz (100 * HZ_PER_MHZ) 22 23 - /* COMBO PHY REG */ 24 - #define PHYREG6 0x14 25 - #define PHYREG6_PLL_DIV_MASK GENMASK(7, 6) 26 - #define PHYREG6_PLL_DIV_SHIFT 6 27 - #define PHYREG6_PLL_DIV_2 1 28 29 - #define PHYREG7 0x18 30 - #define PHYREG7_TX_RTERM_MASK GENMASK(7, 4) 31 - #define PHYREG7_TX_RTERM_SHIFT 4 32 - #define PHYREG7_TX_RTERM_50OHM 8 33 - #define PHYREG7_RX_RTERM_MASK GENMASK(3, 0) 34 - #define PHYREG7_RX_RTERM_SHIFT 0 35 - #define PHYREG7_RX_RTERM_44OHM 15 36 37 - #define PHYREG8 0x1C 38 - #define PHYREG8_SSC_EN BIT(4) 39 40 - #define PHYREG10 0x24 41 - #define PHYREG10_SSC_PCM_MASK GENMASK(3, 0) 42 - #define PHYREG10_SSC_PCM_3500PPM 7 43 44 - #define PHYREG11 0x28 45 - #define PHYREG11_SU_TRIM_0_7 0xF0 46 47 - #define PHYREG12 0x2C 48 - #define PHYREG12_PLL_LPF_ADJ_VALUE 4 49 50 - #define PHYREG13 0x30 51 - #define PHYREG13_RESISTER_MASK GENMASK(5, 4) 52 - #define PHYREG13_RESISTER_SHIFT 0x4 53 - #define PHYREG13_RESISTER_HIGH_Z 3 54 - #define PHYREG13_CKRCV_AMP0 BIT(7) 55 56 - #define PHYREG14 0x34 57 - #define PHYREG14_CKRCV_AMP1 BIT(0) 58 59 - #define PHYREG15 0x38 60 - #define PHYREG15_CTLE_EN BIT(0) 61 - #define PHYREG15_SSC_CNT_MASK GENMASK(7, 6) 62 - #define PHYREG15_SSC_CNT_SHIFT 6 63 - #define PHYREG15_SSC_CNT_VALUE 1 64 65 - #define PHYREG16 0x3C 66 - #define PHYREG16_SSC_CNT_VALUE 0x5f 67 68 - #define PHYREG17 0x40 69 70 - #define PHYREG18 0x44 71 - #define PHYREG18_PLL_LOOP 0x32 72 73 - #define PHYREG21 0x50 74 - #define PHYREG21_RX_SQUELCH_VAL 0x0D 75 76 - #define PHYREG27 0x6C 77 - #define PHYREG27_RX_TRIM_RK3588 0x4C 78 79 - #define PHYREG30 0x74 80 81 - #define PHYREG32 0x7C 82 - #define PHYREG32_SSC_MASK GENMASK(7, 4) 83 - #define PHYREG32_SSC_DIR_MASK GENMASK(5, 4) 84 - #define PHYREG32_SSC_DIR_SHIFT 4 85 - #define PHYREG32_SSC_UPWARD 0 86 - #define PHYREG32_SSC_DOWNWARD 1 87 - #define PHYREG32_SSC_OFFSET_MASK GENMASK(7, 6) 88 - #define PHYREG32_SSC_OFFSET_SHIFT 6 89 - #define PHYREG32_SSC_OFFSET_500PPM 1 90 91 - #define PHYREG33 0x80 92 - #define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) 93 - #define PHYREG33_PLL_KVCO_SHIFT 2 94 - #define PHYREG33_PLL_KVCO_VALUE 2 95 - #define PHYREG33_PLL_KVCO_VALUE_RK3576 4 96 97 struct rockchip_combphy_priv; 98 ··· 178 struct combphy_reg pipe_xpcs_phy_ready; 179 struct combphy_reg pipe_pcie1l0_sel; 180 struct combphy_reg pipe_pcie1l1_sel; 181 }; 182 183 struct rockchip_combphy_cfg { ··· 439 return PTR_ERR_OR_ZERO(phy_provider); 440 } 441 442 static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) 443 { 444 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; ··· 592 switch (priv->type) { 593 case PHY_TYPE_PCIE: 594 /* Set SSC downward spread spectrum */ 595 - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, 596 - PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, 597 - PHYREG32); 598 599 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 600 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); ··· 602 break; 603 case PHY_TYPE_USB3: 604 /* Set SSC downward spread spectrum */ 605 - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, 606 - PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, 607 - PHYREG32); 608 609 /* Enable adaptive CTLE for USB3.0 Rx */ 610 - rockchip_combphy_updatel(priv, PHYREG15_CTLE_EN, 611 - PHYREG15_CTLE_EN, PHYREG15); 612 613 /* Set PLL KVCO fine tuning signals */ 614 - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33); 615 616 /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 617 - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); 618 619 /* Set PLL input clock divider 1/2 */ 620 - val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2); 621 - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6); 622 623 /* Set PLL loop divider */ 624 - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); 625 626 /* Set PLL KVCO to min and set PLL charge pump current to max */ 627 - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); 628 629 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 630 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); ··· 643 case REF_CLOCK_24MHz: 644 if (priv->type == PHY_TYPE_USB3) { 645 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ 646 - val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE); 647 - rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, 648 - val, PHYREG15); 649 650 - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); 651 } 652 break; 653 case REF_CLOCK_25MHz: ··· 658 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 659 if (priv->type == PHY_TYPE_PCIE) { 660 /* PLL KVCO tuning fine */ 661 - val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE); 662 - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 663 - val, PHYREG33); 664 665 /* Enable controlling random jitter, aka RMJ */ 666 - writel(0x4, priv->mmio + PHYREG12); 667 668 - val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT; 669 - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, 670 - val, PHYREG6); 671 672 - writel(0x32, priv->mmio + PHYREG18); 673 - writel(0xf0, priv->mmio + PHYREG11); 674 } 675 break; 676 default: ··· 682 if (priv->ext_refclk) { 683 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 684 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 685 - val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; 686 - val |= PHYREG13_CKRCV_AMP0; 687 - rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); 688 689 - val = readl(priv->mmio + PHYREG14); 690 - val |= PHYREG14_CKRCV_AMP1; 691 - writel(val, priv->mmio + PHYREG14); 692 } 693 } 694 695 if (priv->enable_ssc) { 696 - val = readl(priv->mmio + PHYREG8); 697 - val |= PHYREG8_SSC_EN; 698 - writel(val, priv->mmio + PHYREG8); 699 } 700 701 return 0; ··· 743 switch (priv->type) { 744 case PHY_TYPE_PCIE: 745 /* Set SSC downward spread spectrum. */ 746 - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, 747 - PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, 748 - PHYREG32); 749 750 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 751 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); ··· 755 756 case PHY_TYPE_USB3: 757 /* Set SSC downward spread spectrum. */ 758 - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, 759 - PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, 760 - PHYREG32); 761 762 /* Enable adaptive CTLE for USB3.0 Rx. */ 763 - val = readl(priv->mmio + PHYREG15); 764 - val |= PHYREG15_CTLE_EN; 765 - writel(val, priv->mmio + PHYREG15); 766 767 /* Set PLL KVCO fine tuning signals. */ 768 - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 769 - PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, 770 - PHYREG33); 771 772 /* Enable controlling random jitter. */ 773 - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); 774 775 /* Set PLL input clock divider 1/2. */ 776 - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, 777 - PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, 778 - PHYREG6); 779 780 - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); 781 - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); 782 783 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 784 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 785 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 786 rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); 787 break; 788 789 case PHY_TYPE_SATA: 790 /* Enable adaptive CTLE for SATA Rx. */ 791 - val = readl(priv->mmio + PHYREG15); 792 - val |= PHYREG15_CTLE_EN; 793 - writel(val, priv->mmio + PHYREG15); 794 /* 795 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. 796 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) 797 */ 798 - val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; 799 - val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; 800 - writel(val, priv->mmio + PHYREG7); 801 802 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); 803 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); ··· 838 case REF_CLOCK_24MHz: 839 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { 840 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ 841 - val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; 842 - rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, 843 - val, PHYREG15); 844 845 - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); 846 } 847 break; 848 ··· 854 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 855 if (priv->type == PHY_TYPE_PCIE) { 856 /* PLL KVCO fine tuning. */ 857 - val = PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT; 858 - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 859 - val, PHYREG33); 860 861 /* Enable controlling random jitter. */ 862 - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); 863 864 - val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT; 865 - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, 866 - val, PHYREG6); 867 868 - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); 869 - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); 870 } else if (priv->type == PHY_TYPE_SATA) { 871 /* downward spread spectrum +500ppm */ 872 - val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; 873 - val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; 874 - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); 875 } 876 break; 877 ··· 885 if (priv->ext_refclk) { 886 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 887 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 888 - val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; 889 - val |= PHYREG13_CKRCV_AMP0; 890 - rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); 891 892 - val = readl(priv->mmio + PHYREG14); 893 - val |= PHYREG14_CKRCV_AMP1; 894 - writel(val, priv->mmio + PHYREG14); 895 } 896 } 897 898 if (priv->enable_ssc) { 899 - val = readl(priv->mmio + PHYREG8); 900 - val |= PHYREG8_SSC_EN; 901 - writel(val, priv->mmio + PHYREG8); 902 } 903 904 return 0; ··· 936 /* pipe-grf */ 937 .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 }, 938 .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 }, 939 }; 940 941 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { ··· 960 switch (priv->type) { 961 case PHY_TYPE_PCIE: 962 /* Set SSC downward spread spectrum */ 963 - val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD); 964 - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); 965 966 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 967 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); ··· 971 972 case PHY_TYPE_USB3: 973 /* Set SSC downward spread spectrum */ 974 - val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD); 975 - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); 976 977 /* Enable adaptive CTLE for USB3.0 Rx */ 978 - val = readl(priv->mmio + PHYREG15); 979 - val |= PHYREG15_CTLE_EN; 980 - writel(val, priv->mmio + PHYREG15); 981 982 /* Set PLL KVCO fine tuning signals */ 983 - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33); 984 985 /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 986 - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); 987 988 /* Set PLL input clock divider 1/2 */ 989 - val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2); 990 - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6); 991 992 /* Set PLL loop divider */ 993 - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); 994 995 /* Set PLL KVCO to min and set PLL charge pump current to max */ 996 - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); 997 998 /* Set Rx squelch input filler bandwidth */ 999 - writel(PHYREG21_RX_SQUELCH_VAL, priv->mmio + PHYREG21); 1000 1001 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 1002 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); ··· 1006 1007 case PHY_TYPE_SATA: 1008 /* Enable adaptive CTLE for SATA Rx */ 1009 - val = readl(priv->mmio + PHYREG15); 1010 - val |= PHYREG15_CTLE_EN; 1011 - writel(val, priv->mmio + PHYREG15); 1012 1013 /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */ 1014 - val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; 1015 - val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; 1016 - writel(val, priv->mmio + PHYREG7); 1017 1018 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); 1019 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); ··· 1035 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true); 1036 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { 1037 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ 1038 - val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE); 1039 - rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, 1040 - val, PHYREG15); 1041 1042 - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); 1043 } else if (priv->type == PHY_TYPE_PCIE) { 1044 /* PLL KVCO tuning fine */ 1045 - val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); 1046 - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 1047 - val, PHYREG33); 1048 1049 /* Set up rx_pck invert and rx msb to disable */ 1050 - writel(0x00, priv->mmio + PHYREG27); 1051 1052 /* 1053 * Set up SU adjust signal: ··· 1057 * su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b011 1058 * su_trim[31:24], CKDRV adjust 1059 */ 1060 - writel(0x90, priv->mmio + PHYREG11); 1061 - writel(0x02, priv->mmio + PHYREG12); 1062 - writel(0x57, priv->mmio + PHYREG14); 1063 1064 - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); 1065 } 1066 break; 1067 ··· 1073 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 1074 if (priv->type == PHY_TYPE_PCIE) { 1075 /* gate_tx_pck_sel length select work for L1SS */ 1076 - writel(0xc0, priv->mmio + PHYREG30); 1077 1078 /* PLL KVCO tuning fine */ 1079 - val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); 1080 - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 1081 - val, PHYREG33); 1082 1083 /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ 1084 - writel(0x4c, priv->mmio + PHYREG27); 1085 1086 /* 1087 * Set up SU adjust signal: ··· 1092 * su_trim[23:16], CKRCV adjust 1093 * su_trim[31:24], CKDRV adjust 1094 */ 1095 - writel(0x90, priv->mmio + PHYREG11); 1096 - writel(0x43, priv->mmio + PHYREG12); 1097 - writel(0x88, priv->mmio + PHYREG13); 1098 - writel(0x56, priv->mmio + PHYREG14); 1099 } else if (priv->type == PHY_TYPE_SATA) { 1100 /* downward spread spectrum +500ppm */ 1101 - val = FIELD_PREP(PHYREG32_SSC_DIR_MASK, PHYREG32_SSC_DOWNWARD); 1102 - val |= FIELD_PREP(PHYREG32_SSC_OFFSET_MASK, PHYREG32_SSC_OFFSET_500PPM); 1103 - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); 1104 1105 /* ssc ppm adjust to 3500ppm */ 1106 - rockchip_combphy_updatel(priv, PHYREG10_SSC_PCM_MASK, 1107 - PHYREG10_SSC_PCM_3500PPM, 1108 - PHYREG10); 1109 } 1110 break; 1111 ··· 1120 if (priv->ext_refclk) { 1121 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 1122 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 1123 - val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); 1124 - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 1125 - val, PHYREG33); 1126 1127 /* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */ 1128 - writel(0x0c, priv->mmio + PHYREG27); 1129 1130 /* 1131 * Set up SU adjust signal: ··· 1136 * su_trim[23:16], CKRCV adjust 1137 * su_trim[31:24], CKDRV adjust 1138 */ 1139 - writel(0x90, priv->mmio + PHYREG11); 1140 - writel(0x43, priv->mmio + PHYREG12); 1141 - writel(0x88, priv->mmio + PHYREG13); 1142 - writel(0x56, priv->mmio + PHYREG14); 1143 } 1144 } 1145 1146 if (priv->enable_ssc) { 1147 - val = readl(priv->mmio + PHYREG8); 1148 - val |= PHYREG8_SSC_EN; 1149 - writel(val, priv->mmio + PHYREG8); 1150 1151 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) { 1152 /* Set PLL loop divider */ 1153 - writel(0x00, priv->mmio + PHYREG17); 1154 - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); 1155 1156 /* Set up rx_pck invert and rx msb to disable */ 1157 - writel(0x00, priv->mmio + PHYREG27); 1158 1159 /* 1160 * Set up SU adjust signal: ··· 1163 * su_trim[23:16], CKRCV adjust 1164 * su_trim[31:24], CKDRV adjust 1165 */ 1166 - writel(0x90, priv->mmio + PHYREG11); 1167 - writel(0x02, priv->mmio + PHYREG12); 1168 - writel(0x08, priv->mmio + PHYREG13); 1169 - writel(0x57, priv->mmio + PHYREG14); 1170 - writel(0x40, priv->mmio + PHYREG15); 1171 1172 - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); 1173 1174 - val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); 1175 - writel(val, priv->mmio + PHYREG33); 1176 } 1177 } 1178 ··· 1243 break; 1244 case PHY_TYPE_USB3: 1245 /* Set SSC downward spread spectrum */ 1246 - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, 1247 - PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, 1248 - PHYREG32); 1249 1250 /* Enable adaptive CTLE for USB3.0 Rx. */ 1251 - val = readl(priv->mmio + PHYREG15); 1252 - val |= PHYREG15_CTLE_EN; 1253 - writel(val, priv->mmio + PHYREG15); 1254 1255 /* Set PLL KVCO fine tuning signals. */ 1256 - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 1257 - PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, 1258 - PHYREG33); 1259 1260 /* Enable controlling random jitter. */ 1261 - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); 1262 1263 /* Set PLL input clock divider 1/2. */ 1264 - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, 1265 - PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, 1266 - PHYREG6); 1267 1268 - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); 1269 - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); 1270 1271 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 1272 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); ··· 1272 break; 1273 case PHY_TYPE_SATA: 1274 /* Enable adaptive CTLE for SATA Rx. */ 1275 - val = readl(priv->mmio + PHYREG15); 1276 - val |= PHYREG15_CTLE_EN; 1277 - writel(val, priv->mmio + PHYREG15); 1278 /* 1279 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. 1280 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) 1281 */ 1282 - val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; 1283 - val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; 1284 - writel(val, priv->mmio + PHYREG7); 1285 1286 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); 1287 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); ··· 1303 case REF_CLOCK_24MHz: 1304 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { 1305 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ 1306 - val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; 1307 - rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, 1308 - val, PHYREG15); 1309 1310 - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); 1311 } 1312 break; 1313 ··· 1318 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 1319 if (priv->type == PHY_TYPE_PCIE) { 1320 /* PLL KVCO fine tuning. */ 1321 - val = 4 << PHYREG33_PLL_KVCO_SHIFT; 1322 - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, 1323 - val, PHYREG33); 1324 1325 /* Enable controlling random jitter. */ 1326 - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); 1327 1328 /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ 1329 - writel(PHYREG27_RX_TRIM_RK3588, priv->mmio + PHYREG27); 1330 1331 /* Set up su_trim: */ 1332 - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); 1333 } else if (priv->type == PHY_TYPE_SATA) { 1334 /* downward spread spectrum +500ppm */ 1335 - val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; 1336 - val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; 1337 - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); 1338 } 1339 break; 1340 default: ··· 1347 if (priv->ext_refclk) { 1348 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 1349 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 1350 - val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; 1351 - val |= PHYREG13_CKRCV_AMP0; 1352 - rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); 1353 1354 - val = readl(priv->mmio + PHYREG14); 1355 - val |= PHYREG14_CKRCV_AMP1; 1356 - writel(val, priv->mmio + PHYREG14); 1357 } 1358 } 1359 1360 if (priv->enable_ssc) { 1361 - val = readl(priv->mmio + PHYREG8); 1362 - val |= PHYREG8_SSC_EN; 1363 - writel(val, priv->mmio + PHYREG8); 1364 } 1365 1366 return 0; ··· 1408 }; 1409 1410 static const struct of_device_id rockchip_combphy_of_match[] = { 1411 { 1412 .compatible = "rockchip,rk3562-naneng-combphy", 1413 .data = &rk3562_combphy_cfgs,
··· 20 #define REF_CLOCK_25MHz (25 * HZ_PER_MHZ) 21 #define REF_CLOCK_100MHz (100 * HZ_PER_MHZ) 22 23 + /* RK3528 COMBO PHY REG */ 24 + #define RK3528_PHYREG6 0x18 25 + #define RK3528_PHYREG6_PLL_KVCO GENMASK(12, 10) 26 + #define RK3528_PHYREG6_PLL_KVCO_VALUE 0x2 27 + #define RK3528_PHYREG6_SSC_DIR GENMASK(5, 4) 28 + #define RK3528_PHYREG6_SSC_UPWARD 0 29 + #define RK3528_PHYREG6_SSC_DOWNWARD 1 30 31 + #define RK3528_PHYREG40 0x100 32 + #define RK3528_PHYREG40_SSC_EN BIT(20) 33 + #define RK3528_PHYREG40_SSC_CNT GENMASK(10, 0) 34 + #define RK3528_PHYREG40_SSC_CNT_VALUE 0x17d 35 36 + #define RK3528_PHYREG42 0x108 37 + #define RK3528_PHYREG42_CKDRV_CLK_SEL BIT(29) 38 + #define RK3528_PHYREG42_CKDRV_CLK_PLL 0 39 + #define RK3528_PHYREG42_CKDRV_CLK_CKRCV 1 40 + #define RK3528_PHYREG42_PLL_LPF_R1_ADJ GENMASK(10, 7) 41 + #define RK3528_PHYREG42_PLL_LPF_R1_ADJ_VALUE 0x9 42 + #define RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ GENMASK(6, 4) 43 + #define RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ_VALUE 0x7 44 + #define RK3528_PHYREG42_PLL_KVCO_ADJ GENMASK(2, 0) 45 + #define RK3528_PHYREG42_PLL_KVCO_ADJ_VALUE 0x0 46 47 + #define RK3528_PHYREG80 0x200 48 + #define RK3528_PHYREG80_CTLE_EN BIT(17) 49 50 + #define RK3528_PHYREG81 0x204 51 + #define RK3528_PHYREG81_CDR_PHASE_PATH_GAIN_2X BIT(5) 52 + #define RK3528_PHYREG81_SLEW_RATE_CTRL GENMASK(2, 0) 53 + #define RK3528_PHYREG81_SLEW_RATE_CTRL_SLOW 0x7 54 55 + #define RK3528_PHYREG83 0x20c 56 + #define RK3528_PHYREG83_RX_SQUELCH GENMASK(2, 0) 57 + #define RK3528_PHYREG83_RX_SQUELCH_VALUE 0x6 58 59 + #define RK3528_PHYREG86 0x218 60 + #define RK3528_PHYREG86_RTERM_DET_CLK_EN BIT(14) 61 62 + /* RK3568 COMBO PHY REG */ 63 + #define RK3568_PHYREG6 0x14 64 + #define RK3568_PHYREG6_PLL_DIV_MASK GENMASK(7, 6) 65 + #define RK3568_PHYREG6_PLL_DIV_SHIFT 6 66 + #define RK3568_PHYREG6_PLL_DIV_2 1 67 68 + #define RK3568_PHYREG7 0x18 69 + #define RK3568_PHYREG7_TX_RTERM_MASK GENMASK(7, 4) 70 + #define RK3568_PHYREG7_TX_RTERM_SHIFT 4 71 + #define RK3568_PHYREG7_TX_RTERM_50OHM 8 72 + #define RK3568_PHYREG7_RX_RTERM_MASK GENMASK(3, 0) 73 + #define RK3568_PHYREG7_RX_RTERM_SHIFT 0 74 + #define RK3568_PHYREG7_RX_RTERM_44OHM 15 75 76 + #define RK3568_PHYREG8 0x1C 77 + #define RK3568_PHYREG8_SSC_EN BIT(4) 78 79 + #define RK3568_PHYREG11 0x28 80 + #define RK3568_PHYREG11_SU_TRIM_0_7 0xF0 81 82 + #define RK3568_PHYREG12 0x2C 83 + #define RK3568_PHYREG12_PLL_LPF_ADJ_VALUE 4 84 85 + #define RK3568_PHYREG13 0x30 86 + #define RK3568_PHYREG13_RESISTER_MASK GENMASK(5, 4) 87 + #define RK3568_PHYREG13_RESISTER_SHIFT 0x4 88 + #define RK3568_PHYREG13_RESISTER_HIGH_Z 3 89 + #define RK3568_PHYREG13_CKRCV_AMP0 BIT(7) 90 91 + #define RK3568_PHYREG14 0x34 92 + #define RK3568_PHYREG14_CKRCV_AMP1 BIT(0) 93 94 + #define RK3568_PHYREG15 0x38 95 + #define RK3568_PHYREG15_CTLE_EN BIT(0) 96 + #define RK3568_PHYREG15_SSC_CNT_MASK GENMASK(7, 6) 97 + #define RK3568_PHYREG15_SSC_CNT_SHIFT 6 98 + #define RK3568_PHYREG15_SSC_CNT_VALUE 1 99 100 + #define RK3568_PHYREG16 0x3C 101 + #define RK3568_PHYREG16_SSC_CNT_VALUE 0x5f 102 103 + #define RK3568_PHYREG18 0x44 104 + #define RK3568_PHYREG18_PLL_LOOP 0x32 105 + 106 + #define RK3568_PHYREG32 0x7C 107 + #define RK3568_PHYREG32_SSC_MASK GENMASK(7, 4) 108 + #define RK3568_PHYREG32_SSC_DIR_MASK GENMASK(5, 4) 109 + #define RK3568_PHYREG32_SSC_DIR_SHIFT 4 110 + #define RK3568_PHYREG32_SSC_UPWARD 0 111 + #define RK3568_PHYREG32_SSC_DOWNWARD 1 112 + #define RK3568_PHYREG32_SSC_OFFSET_MASK GENMASK(7, 6) 113 + #define RK3568_PHYREG32_SSC_OFFSET_SHIFT 6 114 + #define RK3568_PHYREG32_SSC_OFFSET_500PPM 1 115 + 116 + #define RK3568_PHYREG33 0x80 117 + #define RK3568_PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) 118 + #define RK3568_PHYREG33_PLL_KVCO_SHIFT 2 119 + #define RK3568_PHYREG33_PLL_KVCO_VALUE 2 120 + #define RK3576_PHYREG33_PLL_KVCO_VALUE 4 121 + 122 + /* RK3588 COMBO PHY registers */ 123 + #define RK3588_PHYREG27 0x6C 124 + #define RK3588_PHYREG27_RX_TRIM 0x4C 125 + 126 + /* RK3576 COMBO PHY registers */ 127 + #define RK3576_PHYREG10 0x24 128 + #define RK3576_PHYREG10_SSC_PCM_MASK GENMASK(3, 0) 129 + #define RK3576_PHYREG10_SSC_PCM_3500PPM 7 130 + 131 + #define RK3576_PHYREG17 0x40 132 + 133 + #define RK3576_PHYREG21 0x50 134 + #define RK3576_PHYREG21_RX_SQUELCH_VAL 0x0D 135 + 136 + #define RK3576_PHYREG30 0x74 137 138 struct rockchip_combphy_priv; 139 ··· 137 struct combphy_reg pipe_xpcs_phy_ready; 138 struct combphy_reg pipe_pcie1l0_sel; 139 struct combphy_reg pipe_pcie1l1_sel; 140 + struct combphy_reg u3otg0_port_en; 141 + struct combphy_reg u3otg1_port_en; 142 }; 143 144 struct rockchip_combphy_cfg { ··· 396 return PTR_ERR_OR_ZERO(phy_provider); 397 } 398 399 + static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv) 400 + { 401 + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 402 + unsigned long rate; 403 + u32 val; 404 + 405 + /* Set SSC downward spread spectrum */ 406 + val = FIELD_PREP(RK3528_PHYREG6_SSC_DIR, RK3528_PHYREG6_SSC_DOWNWARD); 407 + rockchip_combphy_updatel(priv, RK3528_PHYREG6_SSC_DIR, val, RK3528_PHYREG6); 408 + 409 + switch (priv->type) { 410 + case PHY_TYPE_PCIE: 411 + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 412 + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 413 + rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 414 + rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 415 + break; 416 + case PHY_TYPE_USB3: 417 + /* Enable adaptive CTLE for USB3.0 Rx */ 418 + rockchip_combphy_updatel(priv, RK3528_PHYREG80_CTLE_EN, RK3528_PHYREG80_CTLE_EN, 419 + RK3528_PHYREG80); 420 + 421 + /* Set slow slew rate control for PI */ 422 + val = FIELD_PREP(RK3528_PHYREG81_SLEW_RATE_CTRL, 423 + RK3528_PHYREG81_SLEW_RATE_CTRL_SLOW); 424 + rockchip_combphy_updatel(priv, RK3528_PHYREG81_SLEW_RATE_CTRL, val, 425 + RK3528_PHYREG81); 426 + 427 + /* Set CDR phase path with 2x gain */ 428 + rockchip_combphy_updatel(priv, RK3528_PHYREG81_CDR_PHASE_PATH_GAIN_2X, 429 + RK3528_PHYREG81_CDR_PHASE_PATH_GAIN_2X, RK3528_PHYREG81); 430 + 431 + /* Set Rx squelch input filler bandwidth */ 432 + val = FIELD_PREP(RK3528_PHYREG83_RX_SQUELCH, RK3528_PHYREG83_RX_SQUELCH_VALUE); 433 + rockchip_combphy_updatel(priv, RK3528_PHYREG83_RX_SQUELCH, val, RK3528_PHYREG83); 434 + 435 + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 436 + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 437 + rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); 438 + rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg0_port_en, true); 439 + break; 440 + default: 441 + dev_err(priv->dev, "incompatible PHY type\n"); 442 + return -EINVAL; 443 + } 444 + 445 + rate = clk_get_rate(priv->refclk); 446 + 447 + switch (rate) { 448 + case REF_CLOCK_24MHz: 449 + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true); 450 + if (priv->type == PHY_TYPE_USB3) { 451 + /* Set ssc_cnt[10:0]=00101111101 & 31.5KHz */ 452 + val = FIELD_PREP(RK3528_PHYREG40_SSC_CNT, RK3528_PHYREG40_SSC_CNT_VALUE); 453 + rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_CNT, val, 454 + RK3528_PHYREG40); 455 + } else if (priv->type == PHY_TYPE_PCIE) { 456 + /* tx_trim[14]=1, Enable the counting clock of the rterm detect */ 457 + rockchip_combphy_updatel(priv, RK3528_PHYREG86_RTERM_DET_CLK_EN, 458 + RK3528_PHYREG86_RTERM_DET_CLK_EN, RK3528_PHYREG86); 459 + } 460 + break; 461 + case REF_CLOCK_100MHz: 462 + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 463 + if (priv->type == PHY_TYPE_PCIE) { 464 + /* PLL KVCO tuning fine */ 465 + val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE); 466 + rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val, 467 + RK3528_PHYREG6); 468 + 469 + /* su_trim[6:4]=111, [10:7]=1001, [2:0]=000, swing 650mv */ 470 + writel(0x570804f0, priv->mmio + RK3528_PHYREG42); 471 + } 472 + break; 473 + default: 474 + dev_err(priv->dev, "Unsupported rate: %lu\n", rate); 475 + return -EINVAL; 476 + } 477 + 478 + if (device_property_read_bool(priv->dev, "rockchip,ext-refclk")) { 479 + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 480 + 481 + if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 482 + val = FIELD_PREP(RK3528_PHYREG42_CKDRV_CLK_SEL, 483 + RK3528_PHYREG42_CKDRV_CLK_CKRCV); 484 + val |= FIELD_PREP(RK3528_PHYREG42_PLL_LPF_R1_ADJ, 485 + RK3528_PHYREG42_PLL_LPF_R1_ADJ_VALUE); 486 + val |= FIELD_PREP(RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ, 487 + RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ_VALUE); 488 + val |= FIELD_PREP(RK3528_PHYREG42_PLL_KVCO_ADJ, 489 + RK3528_PHYREG42_PLL_KVCO_ADJ_VALUE); 490 + rockchip_combphy_updatel(priv, 491 + RK3528_PHYREG42_CKDRV_CLK_SEL | 492 + RK3528_PHYREG42_PLL_LPF_R1_ADJ | 493 + RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ | 494 + RK3528_PHYREG42_PLL_KVCO_ADJ, 495 + val, RK3528_PHYREG42); 496 + 497 + val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE); 498 + rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val, 499 + RK3528_PHYREG6); 500 + } 501 + } 502 + 503 + if (priv->type == PHY_TYPE_PCIE) { 504 + if (device_property_read_bool(priv->dev, "rockchip,enable-ssc")) 505 + rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_EN, 506 + RK3528_PHYREG40_SSC_EN, RK3528_PHYREG40); 507 + } 508 + 509 + return 0; 510 + } 511 + 512 + static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = { 513 + /* pipe-phy-grf */ 514 + .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 515 + .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 516 + .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 517 + .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 518 + .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 519 + .pipe_clk_24m = { 0x0004, 14, 13, 0x00, 0x00 }, 520 + .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 521 + .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 522 + .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 523 + .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 524 + .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 525 + .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 526 + .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x110 }, 527 + .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x00 }, 528 + .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x101 }, 529 + .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 530 + /* pipe-grf */ 531 + .u3otg0_port_en = { 0x0044, 15, 0, 0x0181, 0x1100 }, 532 + }; 533 + 534 + static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = { 535 + .num_phys = 1, 536 + .phy_ids = { 537 + 0xffdc0000, 538 + }, 539 + .grfcfg = &rk3528_combphy_grfcfgs, 540 + .combphy_cfg = rk3528_combphy_cfg, 541 + }; 542 + 543 static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) 544 { 545 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; ··· 405 switch (priv->type) { 406 case PHY_TYPE_PCIE: 407 /* Set SSC downward spread spectrum */ 408 + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; 409 + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); 410 411 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 412 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); ··· 416 break; 417 case PHY_TYPE_USB3: 418 /* Set SSC downward spread spectrum */ 419 + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; 420 + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, 421 + RK3568_PHYREG32); 422 423 /* Enable adaptive CTLE for USB3.0 Rx */ 424 + rockchip_combphy_updatel(priv, RK3568_PHYREG15_CTLE_EN, 425 + RK3568_PHYREG15_CTLE_EN, RK3568_PHYREG15); 426 427 /* Set PLL KVCO fine tuning signals */ 428 + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, 429 + BIT(3), RK3568_PHYREG33); 430 431 /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 432 + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); 433 434 /* Set PLL input clock divider 1/2 */ 435 + val = FIELD_PREP(RK3568_PHYREG6_PLL_DIV_MASK, RK3568_PHYREG6_PLL_DIV_2); 436 + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, val, RK3568_PHYREG6); 437 438 /* Set PLL loop divider */ 439 + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); 440 441 /* Set PLL KVCO to min and set PLL charge pump current to max */ 442 + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); 443 444 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 445 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); ··· 456 case REF_CLOCK_24MHz: 457 if (priv->type == PHY_TYPE_USB3) { 458 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ 459 + val = FIELD_PREP(RK3568_PHYREG15_SSC_CNT_MASK, 460 + RK3568_PHYREG15_SSC_CNT_VALUE); 461 + rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, 462 + val, RK3568_PHYREG15); 463 464 + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); 465 } 466 break; 467 case REF_CLOCK_25MHz: ··· 470 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 471 if (priv->type == PHY_TYPE_PCIE) { 472 /* PLL KVCO tuning fine */ 473 + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, 474 + RK3568_PHYREG33_PLL_KVCO_VALUE); 475 + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, 476 + val, RK3568_PHYREG33); 477 478 /* Enable controlling random jitter, aka RMJ */ 479 + writel(0x4, priv->mmio + RK3568_PHYREG12); 480 481 + val = RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT; 482 + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, 483 + val, RK3568_PHYREG6); 484 485 + writel(0x32, priv->mmio + RK3568_PHYREG18); 486 + writel(0xf0, priv->mmio + RK3568_PHYREG11); 487 } 488 break; 489 default: ··· 493 if (priv->ext_refclk) { 494 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 495 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 496 + val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT; 497 + val |= RK3568_PHYREG13_CKRCV_AMP0; 498 + rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val, 499 + RK3568_PHYREG13); 500 501 + val = readl(priv->mmio + RK3568_PHYREG14); 502 + val |= RK3568_PHYREG14_CKRCV_AMP1; 503 + writel(val, priv->mmio + RK3568_PHYREG14); 504 } 505 } 506 507 if (priv->enable_ssc) { 508 + val = readl(priv->mmio + RK3568_PHYREG8); 509 + val |= RK3568_PHYREG8_SSC_EN; 510 + writel(val, priv->mmio + RK3568_PHYREG8); 511 } 512 513 return 0; ··· 553 switch (priv->type) { 554 case PHY_TYPE_PCIE: 555 /* Set SSC downward spread spectrum. */ 556 + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; 557 + 558 + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); 559 560 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 561 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); ··· 565 566 case PHY_TYPE_USB3: 567 /* Set SSC downward spread spectrum. */ 568 + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT, 569 + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); 570 571 /* Enable adaptive CTLE for USB3.0 Rx. */ 572 + val = readl(priv->mmio + RK3568_PHYREG15); 573 + val |= RK3568_PHYREG15_CTLE_EN; 574 + writel(val, priv->mmio + RK3568_PHYREG15); 575 576 /* Set PLL KVCO fine tuning signals. */ 577 + val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT; 578 + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, val, RK3568_PHYREG33); 579 580 /* Enable controlling random jitter. */ 581 + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); 582 583 /* Set PLL input clock divider 1/2. */ 584 + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, 585 + RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT, 586 + RK3568_PHYREG6); 587 588 + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); 589 + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); 590 591 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 592 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 593 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 594 rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); 595 + switch (priv->id) { 596 + case 0: 597 + rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg0_port_en, true); 598 + break; 599 + case 1: 600 + rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg1_port_en, true); 601 + break; 602 + } 603 break; 604 605 case PHY_TYPE_SATA: 606 /* Enable adaptive CTLE for SATA Rx. */ 607 + val = readl(priv->mmio + RK3568_PHYREG15); 608 + val |= RK3568_PHYREG15_CTLE_EN; 609 + writel(val, priv->mmio + RK3568_PHYREG15); 610 /* 611 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. 612 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) 613 */ 614 + val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT; 615 + val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT; 616 + writel(val, priv->mmio + RK3568_PHYREG7); 617 618 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); 619 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); ··· 642 case REF_CLOCK_24MHz: 643 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { 644 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ 645 + val = RK3568_PHYREG15_SSC_CNT_VALUE << RK3568_PHYREG15_SSC_CNT_SHIFT; 646 + rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, 647 + val, RK3568_PHYREG15); 648 649 + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); 650 } 651 break; 652 ··· 658 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 659 if (priv->type == PHY_TYPE_PCIE) { 660 /* PLL KVCO fine tuning. */ 661 + val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT; 662 + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, 663 + val, RK3568_PHYREG33); 664 665 /* Enable controlling random jitter. */ 666 + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); 667 668 + val = RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT; 669 + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, 670 + val, RK3568_PHYREG6); 671 672 + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); 673 + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); 674 } else if (priv->type == PHY_TYPE_SATA) { 675 /* downward spread spectrum +500ppm */ 676 + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; 677 + val |= RK3568_PHYREG32_SSC_OFFSET_500PPM << 678 + RK3568_PHYREG32_SSC_OFFSET_SHIFT; 679 + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, 680 + RK3568_PHYREG32); 681 } 682 break; 683 ··· 687 if (priv->ext_refclk) { 688 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 689 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 690 + val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT; 691 + val |= RK3568_PHYREG13_CKRCV_AMP0; 692 + rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val, 693 + RK3568_PHYREG13); 694 695 + val = readl(priv->mmio + RK3568_PHYREG14); 696 + val |= RK3568_PHYREG14_CKRCV_AMP1; 697 + writel(val, priv->mmio + RK3568_PHYREG14); 698 } 699 } 700 701 if (priv->enable_ssc) { 702 + val = readl(priv->mmio + RK3568_PHYREG8); 703 + val |= RK3568_PHYREG8_SSC_EN; 704 + writel(val, priv->mmio + RK3568_PHYREG8); 705 } 706 707 return 0; ··· 737 /* pipe-grf */ 738 .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 }, 739 .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 }, 740 + .u3otg0_port_en = { 0x0104, 15, 0, 0x0181, 0x1100 }, 741 + .u3otg1_port_en = { 0x0144, 15, 0, 0x0181, 0x1100 }, 742 }; 743 744 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { ··· 759 switch (priv->type) { 760 case PHY_TYPE_PCIE: 761 /* Set SSC downward spread spectrum */ 762 + val = FIELD_PREP(RK3568_PHYREG32_SSC_MASK, RK3568_PHYREG32_SSC_DOWNWARD); 763 + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); 764 765 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 766 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); ··· 770 771 case PHY_TYPE_USB3: 772 /* Set SSC downward spread spectrum */ 773 + val = FIELD_PREP(RK3568_PHYREG32_SSC_MASK, RK3568_PHYREG32_SSC_DOWNWARD); 774 + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); 775 776 /* Enable adaptive CTLE for USB3.0 Rx */ 777 + val = readl(priv->mmio + RK3568_PHYREG15); 778 + val |= RK3568_PHYREG15_CTLE_EN; 779 + writel(val, priv->mmio + RK3568_PHYREG15); 780 781 /* Set PLL KVCO fine tuning signals */ 782 + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, BIT(3), 783 + RK3568_PHYREG33); 784 785 /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 786 + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); 787 788 /* Set PLL input clock divider 1/2 */ 789 + val = FIELD_PREP(RK3568_PHYREG6_PLL_DIV_MASK, RK3568_PHYREG6_PLL_DIV_2); 790 + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, val, RK3568_PHYREG6); 791 792 /* Set PLL loop divider */ 793 + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); 794 795 /* Set PLL KVCO to min and set PLL charge pump current to max */ 796 + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); 797 798 /* Set Rx squelch input filler bandwidth */ 799 + writel(RK3576_PHYREG21_RX_SQUELCH_VAL, priv->mmio + RK3576_PHYREG21); 800 801 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 802 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); ··· 804 805 case PHY_TYPE_SATA: 806 /* Enable adaptive CTLE for SATA Rx */ 807 + val = readl(priv->mmio + RK3568_PHYREG15); 808 + val |= RK3568_PHYREG15_CTLE_EN; 809 + writel(val, priv->mmio + RK3568_PHYREG15); 810 811 /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */ 812 + val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT; 813 + val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT; 814 + writel(val, priv->mmio + RK3568_PHYREG7); 815 816 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); 817 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); ··· 833 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true); 834 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { 835 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ 836 + val = FIELD_PREP(RK3568_PHYREG15_SSC_CNT_MASK, 837 + RK3568_PHYREG15_SSC_CNT_VALUE); 838 + rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, 839 + val, RK3568_PHYREG15); 840 841 + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); 842 } else if (priv->type == PHY_TYPE_PCIE) { 843 /* PLL KVCO tuning fine */ 844 + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, 845 + RK3576_PHYREG33_PLL_KVCO_VALUE); 846 + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, 847 + val, RK3568_PHYREG33); 848 849 /* Set up rx_pck invert and rx msb to disable */ 850 + writel(0x00, priv->mmio + RK3588_PHYREG27); 851 852 /* 853 * Set up SU adjust signal: ··· 853 * su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b011 854 * su_trim[31:24], CKDRV adjust 855 */ 856 + writel(0x90, priv->mmio + RK3568_PHYREG11); 857 + writel(0x02, priv->mmio + RK3568_PHYREG12); 858 + writel(0x57, priv->mmio + RK3568_PHYREG14); 859 860 + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); 861 } 862 break; 863 ··· 869 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 870 if (priv->type == PHY_TYPE_PCIE) { 871 /* gate_tx_pck_sel length select work for L1SS */ 872 + writel(0xc0, priv->mmio + RK3576_PHYREG30); 873 874 /* PLL KVCO tuning fine */ 875 + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, 876 + RK3576_PHYREG33_PLL_KVCO_VALUE); 877 + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, 878 + val, RK3568_PHYREG33); 879 880 /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ 881 + writel(0x4c, priv->mmio + RK3588_PHYREG27); 882 883 /* 884 * Set up SU adjust signal: ··· 887 * su_trim[23:16], CKRCV adjust 888 * su_trim[31:24], CKDRV adjust 889 */ 890 + writel(0x90, priv->mmio + RK3568_PHYREG11); 891 + writel(0x43, priv->mmio + RK3568_PHYREG12); 892 + writel(0x88, priv->mmio + RK3568_PHYREG13); 893 + writel(0x56, priv->mmio + RK3568_PHYREG14); 894 } else if (priv->type == PHY_TYPE_SATA) { 895 /* downward spread spectrum +500ppm */ 896 + val = FIELD_PREP(RK3568_PHYREG32_SSC_DIR_MASK, 897 + RK3568_PHYREG32_SSC_DOWNWARD); 898 + val |= FIELD_PREP(RK3568_PHYREG32_SSC_OFFSET_MASK, 899 + RK3568_PHYREG32_SSC_OFFSET_500PPM); 900 + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, 901 + RK3568_PHYREG32); 902 903 /* ssc ppm adjust to 3500ppm */ 904 + rockchip_combphy_updatel(priv, RK3576_PHYREG10_SSC_PCM_MASK, 905 + RK3576_PHYREG10_SSC_PCM_3500PPM, 906 + RK3576_PHYREG10); 907 } 908 break; 909 ··· 912 if (priv->ext_refclk) { 913 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 914 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 915 + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, 916 + RK3576_PHYREG33_PLL_KVCO_VALUE); 917 + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, 918 + val, RK3568_PHYREG33); 919 920 /* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */ 921 + writel(0x0c, priv->mmio + RK3588_PHYREG27); 922 923 /* 924 * Set up SU adjust signal: ··· 927 * su_trim[23:16], CKRCV adjust 928 * su_trim[31:24], CKDRV adjust 929 */ 930 + writel(0x90, priv->mmio + RK3568_PHYREG11); 931 + writel(0x43, priv->mmio + RK3568_PHYREG12); 932 + writel(0x88, priv->mmio + RK3568_PHYREG13); 933 + writel(0x56, priv->mmio + RK3568_PHYREG14); 934 } 935 } 936 937 if (priv->enable_ssc) { 938 + val = readl(priv->mmio + RK3568_PHYREG8); 939 + val |= RK3568_PHYREG8_SSC_EN; 940 + writel(val, priv->mmio + RK3568_PHYREG8); 941 942 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) { 943 /* Set PLL loop divider */ 944 + writel(0x00, priv->mmio + RK3576_PHYREG17); 945 + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); 946 947 /* Set up rx_pck invert and rx msb to disable */ 948 + writel(0x00, priv->mmio + RK3588_PHYREG27); 949 950 /* 951 * Set up SU adjust signal: ··· 954 * su_trim[23:16], CKRCV adjust 955 * su_trim[31:24], CKDRV adjust 956 */ 957 + writel(0x90, priv->mmio + RK3568_PHYREG11); 958 + writel(0x02, priv->mmio + RK3568_PHYREG12); 959 + writel(0x08, priv->mmio + RK3568_PHYREG13); 960 + writel(0x57, priv->mmio + RK3568_PHYREG14); 961 + writel(0x40, priv->mmio + RK3568_PHYREG15); 962 963 + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); 964 965 + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, 966 + RK3576_PHYREG33_PLL_KVCO_VALUE); 967 + writel(val, priv->mmio + RK3568_PHYREG33); 968 } 969 } 970 ··· 1033 break; 1034 case PHY_TYPE_USB3: 1035 /* Set SSC downward spread spectrum */ 1036 + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; 1037 + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); 1038 1039 /* Enable adaptive CTLE for USB3.0 Rx. */ 1040 + val = readl(priv->mmio + RK3568_PHYREG15); 1041 + val |= RK3568_PHYREG15_CTLE_EN; 1042 + writel(val, priv->mmio + RK3568_PHYREG15); 1043 1044 /* Set PLL KVCO fine tuning signals. */ 1045 + val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT; 1046 + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, val, RK3568_PHYREG33); 1047 1048 /* Enable controlling random jitter. */ 1049 + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); 1050 1051 /* Set PLL input clock divider 1/2. */ 1052 + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, 1053 + RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT, 1054 + RK3568_PHYREG6); 1055 1056 + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); 1057 + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); 1058 1059 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 1060 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); ··· 1064 break; 1065 case PHY_TYPE_SATA: 1066 /* Enable adaptive CTLE for SATA Rx. */ 1067 + val = readl(priv->mmio + RK3568_PHYREG15); 1068 + val |= RK3568_PHYREG15_CTLE_EN; 1069 + writel(val, priv->mmio + RK3568_PHYREG15); 1070 /* 1071 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. 1072 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) 1073 */ 1074 + val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT; 1075 + val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT; 1076 + writel(val, priv->mmio + RK3568_PHYREG7); 1077 1078 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); 1079 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); ··· 1095 case REF_CLOCK_24MHz: 1096 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { 1097 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ 1098 + val = RK3568_PHYREG15_SSC_CNT_VALUE << RK3568_PHYREG15_SSC_CNT_SHIFT; 1099 + rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, 1100 + val, RK3568_PHYREG15); 1101 1102 + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); 1103 } 1104 break; 1105 ··· 1110 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 1111 if (priv->type == PHY_TYPE_PCIE) { 1112 /* PLL KVCO fine tuning. */ 1113 + val = 4 << RK3568_PHYREG33_PLL_KVCO_SHIFT; 1114 + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, 1115 + val, RK3568_PHYREG33); 1116 1117 /* Enable controlling random jitter. */ 1118 + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); 1119 1120 /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ 1121 + writel(RK3588_PHYREG27_RX_TRIM, priv->mmio + RK3588_PHYREG27); 1122 1123 /* Set up su_trim: */ 1124 + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); 1125 } else if (priv->type == PHY_TYPE_SATA) { 1126 /* downward spread spectrum +500ppm */ 1127 + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; 1128 + val |= RK3568_PHYREG32_SSC_OFFSET_500PPM << 1129 + RK3568_PHYREG32_SSC_OFFSET_SHIFT; 1130 + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, 1131 + RK3568_PHYREG32); 1132 } 1133 break; 1134 default: ··· 1137 if (priv->ext_refclk) { 1138 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 1139 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { 1140 + val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT; 1141 + val |= RK3568_PHYREG13_CKRCV_AMP0; 1142 + rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val, 1143 + RK3568_PHYREG13); 1144 1145 + val = readl(priv->mmio + RK3568_PHYREG14); 1146 + val |= RK3568_PHYREG14_CKRCV_AMP1; 1147 + writel(val, priv->mmio + RK3568_PHYREG14); 1148 } 1149 } 1150 1151 if (priv->enable_ssc) { 1152 + val = readl(priv->mmio + RK3568_PHYREG8); 1153 + val |= RK3568_PHYREG8_SSC_EN; 1154 + writel(val, priv->mmio + RK3568_PHYREG8); 1155 } 1156 1157 return 0; ··· 1197 }; 1198 1199 static const struct of_device_id rockchip_combphy_of_match[] = { 1200 + { 1201 + .compatible = "rockchip,rk3528-naneng-combphy", 1202 + .data = &rk3528_combphy_cfgs, 1203 + }, 1204 { 1205 .compatible = "rockchip,rk3562-naneng-combphy", 1206 .data = &rk3562_combphy_cfgs,
-1
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
··· 795 .val_bits = 32, 796 .writeable_reg = rk_hdptx_phy_is_rw_reg, 797 .readable_reg = rk_hdptx_phy_is_rw_reg, 798 - .fast_io = true, 799 .max_register = 0x18b4, 800 }; 801
··· 795 .val_bits = 32, 796 .writeable_reg = rk_hdptx_phy_is_rw_reg, 797 .readable_reg = rk_hdptx_phy_is_rw_reg, 798 .max_register = 0x18b4, 799 }; 800
+1 -2
drivers/phy/rockchip/phy-rockchip-usbdp.c
··· 666 goto unlock_ret; 667 } 668 669 - udphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false; 670 rk_udphy_set_typec_default_mapping(udphy); 671 rk_udphy_usb_bvalid_enable(udphy, true); 672 ··· 1430 .reg_bits = 32, 1431 .reg_stride = 4, 1432 .val_bits = 32, 1433 - .fast_io = true, 1434 .max_register = 0x20dc, 1435 }; 1436
··· 666 goto unlock_ret; 667 } 668 669 + udphy->flip = orien == TYPEC_ORIENTATION_REVERSE; 670 rk_udphy_set_typec_default_mapping(udphy); 671 rk_udphy_usb_bvalid_enable(udphy, true); 672 ··· 1430 .reg_bits = 32, 1431 .reg_stride = 4, 1432 .val_bits = 32, 1433 .max_register = 0x20dc, 1434 }; 1435
-1
drivers/phy/samsung/phy-exynos5-usbdrd.c
··· 2417 MODULE_DESCRIPTION("Samsung Exynos5 SoCs USB 3.0 DRD controller PHY driver"); 2418 MODULE_AUTHOR("Vivek Gautam <gautam.vivek@samsung.com>"); 2419 MODULE_LICENSE("GPL v2"); 2420 - MODULE_ALIAS("platform:exynos5_usb3drd_phy");
··· 2417 MODULE_DESCRIPTION("Samsung Exynos5 SoCs USB 3.0 DRD controller PHY driver"); 2418 MODULE_AUTHOR("Vivek Gautam <gautam.vivek@samsung.com>"); 2419 MODULE_LICENSE("GPL v2");
-1
drivers/phy/samsung/phy-samsung-usb2.c
··· 258 MODULE_DESCRIPTION("Samsung S5P/Exynos SoC USB PHY driver"); 259 MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>"); 260 MODULE_LICENSE("GPL v2"); 261 - MODULE_ALIAS("platform:samsung-usb2-phy");
··· 258 MODULE_DESCRIPTION("Samsung S5P/Exynos SoC USB PHY driver"); 259 MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>"); 260 MODULE_LICENSE("GPL v2");
+19
drivers/phy/sophgo/Kconfig
···
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # 3 + # Phy drivers for Sophgo platforms 4 + # 5 + 6 + if ARCH_SOPHGO || COMPILE_TEST 7 + 8 + config PHY_SOPHGO_CV1800_USB2 9 + tristate "Sophgo CV18XX/SG200X USB 2.0 PHY support" 10 + depends on MFD_SYSCON 11 + depends on USB_SUPPORT 12 + select GENERIC_PHY 13 + help 14 + Enable this to support the USB 2.0 PHY used with 15 + the DWC2 USB controller in Sophgo CV18XX/SG200X 16 + series SoC. 17 + If unsure, say N. 18 + 19 + endif # ARCH_SOPHGO || COMPILE_TEST
+2
drivers/phy/sophgo/Makefile
···
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + obj-$(CONFIG_PHY_SOPHGO_CV1800_USB2) += phy-cv1800-usb2.o
+170
drivers/phy/sophgo/phy-cv1800-usb2.c
···
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2025 Inochi Amaoto <inochiama@outlook.com> 4 + */ 5 + 6 + #include <linux/clk.h> 7 + #include <linux/bitfield.h> 8 + #include <linux/debugfs.h> 9 + #include <linux/kernel.h> 10 + #include <linux/mfd/syscon.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + #include <linux/of_address.h> 14 + #include <linux/of_gpio.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/phy/phy.h> 17 + #include <linux/regmap.h> 18 + #include <linux/spinlock.h> 19 + 20 + #define REG_USB_PHY_CTRL 0x048 21 + 22 + #define PHY_VBUS_POWER_EN BIT(0) 23 + #define PHY_VBUS_POWER BIT(1) 24 + #define PHY_ID_OVERWRITE_EN BIT(6) 25 + #define PHY_ID_OVERWRITE_MODE BIT(7) 26 + #define PHY_ID_OVERWRITE_MODE_HOST FIELD_PREP(BIT(7), 0) 27 + #define PHY_ID_OVERWRITE_MODE_DEVICE FIELD_PREP(BIT(7), 1) 28 + 29 + #define PHY_APP_CLK_RATE 125000000 30 + #define PHY_LPM_CLK_RATE 12000000 31 + #define PHY_STB_CLK_RATE 333334 32 + 33 + struct cv1800_usb_phy { 34 + struct phy *phy; 35 + struct regmap *syscon; 36 + spinlock_t lock; 37 + struct clk *usb_app_clk; 38 + struct clk *usb_lpm_clk; 39 + struct clk *usb_stb_clk; 40 + bool support_otg; 41 + }; 42 + 43 + static int cv1800_usb_phy_set_mode(struct phy *_phy, 44 + enum phy_mode mode, int submode) 45 + { 46 + struct cv1800_usb_phy *phy = phy_get_drvdata(_phy); 47 + unsigned int regval = 0; 48 + int ret; 49 + 50 + dev_info(&phy->phy->dev, "set mode %d", (int)mode); 51 + 52 + switch (mode) { 53 + case PHY_MODE_USB_DEVICE: 54 + regval = PHY_ID_OVERWRITE_EN | PHY_ID_OVERWRITE_MODE_DEVICE; 55 + regmap_clear_bits(phy->syscon, REG_USB_PHY_CTRL, PHY_VBUS_POWER); 56 + break; 57 + case PHY_MODE_USB_HOST: 58 + regval = PHY_ID_OVERWRITE_EN | PHY_ID_OVERWRITE_MODE_HOST; 59 + regmap_set_bits(phy->syscon, REG_USB_PHY_CTRL, PHY_VBUS_POWER); 60 + break; 61 + case PHY_MODE_USB_OTG: 62 + if (!phy->support_otg) 63 + return 0; 64 + 65 + ret = regmap_read(phy->syscon, REG_USB_PHY_CTRL, &regval); 66 + if (ret) 67 + return ret; 68 + 69 + regval = FIELD_GET(PHY_ID_OVERWRITE_MODE, regval); 70 + break; 71 + default: 72 + return -EINVAL; 73 + } 74 + 75 + return regmap_update_bits(phy->syscon, REG_USB_PHY_CTRL, 76 + PHY_ID_OVERWRITE_EN | PHY_ID_OVERWRITE_MODE, 77 + regval); 78 + } 79 + 80 + static int cv1800_usb_phy_set_clock(struct cv1800_usb_phy *phy) 81 + { 82 + int ret; 83 + 84 + ret = clk_set_rate(phy->usb_app_clk, PHY_APP_CLK_RATE); 85 + if (ret) 86 + return ret; 87 + 88 + ret = clk_set_rate(phy->usb_lpm_clk, PHY_LPM_CLK_RATE); 89 + if (ret) 90 + return ret; 91 + 92 + return clk_set_rate(phy->usb_stb_clk, PHY_STB_CLK_RATE); 93 + } 94 + 95 + static const struct phy_ops cv1800_usb_phy_ops = { 96 + .set_mode = cv1800_usb_phy_set_mode, 97 + .owner = THIS_MODULE, 98 + }; 99 + 100 + static int cv1800_usb_phy_probe(struct platform_device *pdev) 101 + { 102 + struct device *dev = &pdev->dev; 103 + struct device *parent = dev->parent; 104 + struct cv1800_usb_phy *phy; 105 + struct phy_provider *phy_provider; 106 + int ret; 107 + 108 + if (!parent) 109 + return -ENODEV; 110 + 111 + phy = devm_kmalloc(dev, sizeof(*phy), GFP_KERNEL); 112 + if (!phy) 113 + return -ENOMEM; 114 + 115 + phy->syscon = syscon_node_to_regmap(parent->of_node); 116 + if (IS_ERR_OR_NULL(phy->syscon)) 117 + return -ENODEV; 118 + 119 + phy->support_otg = false; 120 + 121 + spin_lock_init(&phy->lock); 122 + 123 + phy->usb_app_clk = devm_clk_get_enabled(dev, "app"); 124 + if (IS_ERR(phy->usb_app_clk)) 125 + return dev_err_probe(dev, PTR_ERR(phy->usb_app_clk), 126 + "Failed to get app clock\n"); 127 + 128 + phy->usb_lpm_clk = devm_clk_get_enabled(dev, "lpm"); 129 + if (IS_ERR(phy->usb_lpm_clk)) 130 + return dev_err_probe(dev, PTR_ERR(phy->usb_lpm_clk), 131 + "Failed to get lpm clock\n"); 132 + 133 + phy->usb_stb_clk = devm_clk_get_enabled(dev, "stb"); 134 + if (IS_ERR(phy->usb_stb_clk)) 135 + return dev_err_probe(dev, PTR_ERR(phy->usb_stb_clk), 136 + "Failed to get stb clock\n"); 137 + 138 + phy->phy = devm_phy_create(dev, NULL, &cv1800_usb_phy_ops); 139 + if (IS_ERR(phy->phy)) 140 + return dev_err_probe(dev, PTR_ERR(phy->phy), 141 + "Failed to create phy\n"); 142 + 143 + ret = cv1800_usb_phy_set_clock(phy); 144 + if (ret) 145 + return ret; 146 + 147 + phy_set_drvdata(phy->phy, phy); 148 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 149 + 150 + return PTR_ERR_OR_ZERO(phy_provider); 151 + } 152 + 153 + static const struct of_device_id cv1800_usb_phy_ids[] = { 154 + { .compatible = "sophgo,cv1800b-usb2-phy" }, 155 + { }, 156 + }; 157 + MODULE_DEVICE_TABLE(of, cv1800_usb_phy_ids); 158 + 159 + static struct platform_driver cv1800_usb_phy_driver = { 160 + .probe = cv1800_usb_phy_probe, 161 + .driver = { 162 + .name = "cv1800-usb2-phy", 163 + .of_match_table = cv1800_usb_phy_ids, 164 + }, 165 + }; 166 + module_platform_driver(cv1800_usb_phy_driver); 167 + 168 + MODULE_AUTHOR("Inochi Amaoto <inochiama@outlook.com>"); 169 + MODULE_DESCRIPTION("CV1800/SG2000 SoC USB 2.0 PHY driver"); 170 + MODULE_LICENSE("GPL");
+1 -1
drivers/phy/ti/Kconfig
··· 62 63 config OMAP_USB2 64 tristate "OMAP USB2 PHY Driver" 65 - depends on ARCH_OMAP2PLUS || ARCH_K3 66 depends on USB_SUPPORT 67 select GENERIC_PHY 68 select USB_PHY
··· 62 63 config OMAP_USB2 64 tristate "OMAP USB2 PHY Driver" 65 + depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST 66 depends on USB_SUPPORT 67 select GENERIC_PHY 68 select USB_PHY
-1
drivers/phy/ti/phy-am654-serdes.c
··· 99 .reg_bits = 32, 100 .val_bits = 32, 101 .reg_stride = 4, 102 - .fast_io = true, 103 .max_register = 0x1ffc, 104 }; 105
··· 99 .reg_bits = 32, 100 .val_bits = 32, 101 .reg_stride = 4, 102 .max_register = 0x1ffc, 103 }; 104
-1
drivers/phy/ti/phy-dm816x-usb.c
··· 269 270 module_platform_driver(dm816x_usb_phy_driver); 271 272 - MODULE_ALIAS("platform:dm816x_usb"); 273 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>"); 274 MODULE_DESCRIPTION("dm816x usb phy driver"); 275 MODULE_LICENSE("GPL v2");
··· 269 270 module_platform_driver(dm816x_usb_phy_driver); 271 272 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>"); 273 MODULE_DESCRIPTION("dm816x usb phy driver"); 274 MODULE_LICENSE("GPL v2");
-1
drivers/phy/ti/phy-j721e-wiz.c
··· 1319 .reg_bits = 32, 1320 .val_bits = 32, 1321 .reg_stride = 4, 1322 - .fast_io = true, 1323 }; 1324 1325 static struct wiz_data j721e_16g_data = {
··· 1319 .reg_bits = 32, 1320 .val_bits = 32, 1321 .reg_stride = 4, 1322 }; 1323 1324 static struct wiz_data j721e_16g_data = {
-1
drivers/phy/ti/phy-omap-control.c
··· 334 } 335 module_exit(omap_control_phy_exit); 336 337 - MODULE_ALIAS("platform:omap_control_phy"); 338 MODULE_AUTHOR("Texas Instruments Inc."); 339 MODULE_DESCRIPTION("OMAP Control Module PHY Driver"); 340 MODULE_LICENSE("GPL v2");
··· 334 } 335 module_exit(omap_control_phy_exit); 336 337 MODULE_AUTHOR("Texas Instruments Inc."); 338 MODULE_DESCRIPTION("OMAP Control Module PHY Driver"); 339 MODULE_LICENSE("GPL v2");
-1
drivers/phy/ti/phy-omap-usb2.c
··· 533 534 module_platform_driver(omap_usb2_driver); 535 536 - MODULE_ALIAS("platform:omap_usb2"); 537 MODULE_AUTHOR("Texas Instruments Inc."); 538 MODULE_DESCRIPTION("OMAP USB2 phy driver"); 539 MODULE_LICENSE("GPL v2");
··· 533 534 module_platform_driver(omap_usb2_driver); 535 536 MODULE_AUTHOR("Texas Instruments Inc."); 537 MODULE_DESCRIPTION("OMAP USB2 phy driver"); 538 MODULE_LICENSE("GPL v2");
-1
drivers/phy/ti/phy-ti-pipe3.c
··· 942 943 module_platform_driver(ti_pipe3_driver); 944 945 - MODULE_ALIAS("platform:ti_pipe3"); 946 MODULE_AUTHOR("Texas Instruments Inc."); 947 MODULE_DESCRIPTION("TI PIPE3 phy driver"); 948 MODULE_LICENSE("GPL v2");
··· 942 943 module_platform_driver(ti_pipe3_driver); 944 945 MODULE_AUTHOR("Texas Instruments Inc."); 946 MODULE_DESCRIPTION("TI PIPE3 phy driver"); 947 MODULE_LICENSE("GPL v2");