Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull phy updates from Vinod Koul:
"Core:
- Drop Kishon as maintainer, thanks to him for helping, move to
credits and add Neil to help with reviews.
- Add new phy_notify_stat to notify phy from controllers during the
runtime transitions and usage in samsung phy

New hardware support:
- Renesas RZ/G3E USB3.0 driver
- NXP Support TJA1048/TJA1051 CAN phy
- Rockchip support for rk3506 dsi dphy
- Qualcomm Glymur QMP PCIe PHY support

Updates:
- PM support for rcar-gen3-usb2 driver
- Samsung HDMI/eDP Transmitter Combo PHY updates
- Freescale imx8mq support for alternate reference clock"

* tag 'phy-for-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (40 commits)
MAINTAINERS: phy: Add Neil Armstrong as reviewers for phy subsystem
MAINTAINERS: phy: Move Kishon Vijay Abraham I to credits
phy: fsl-imx8mq-usb: support alternate reference clock
dt-bindings: phy: imx8mq-usb: add alternate reference clock
phy: rockchip: samsung-hdptx: Prevent Inter-Pair Skew from exceeding the limits
phy: rockchip: samsung-hdptx: Reduce ROPLL loop bandwidth
phy: rockchip: samsung-hdptx: Fix reported clock rate in high bpc mode
phy: ti: gmii-sel: Add a sanity check on the phy_id
phy: qcom: qmp-pcie: Add support for Glymur PCIe Gen5x4 PHY
phy: qcom-qmp: pcs: Add v8.50 register offsets
dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the Glymur QMP PCIe PHY
dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Restrict resets per each device
phy: freescale: Initialize priv->lock
phy: renesas: Remove unneeded semicolons
phy: qcom: m31-eusb2: Update init sequence to set PHY_ENABLE
phy: qcom: qmp-combo: get the USB3 & DisplayPort lanes mapping from DT
dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: Document lanes mapping when not using in USB-C complex
phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3562
phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3528
phy: renesas: rcar-gen3-usb2: Add suspend/resume support
...

+1119 -143
+4
CREDITS
··· 16 16 S: (ask for current address) 17 17 S: Finland 18 18 19 + N: Kishon Vijay Abraham I 20 + E: kishon@kernel.org 21 + D: Generic Phy Framework 22 + 19 23 N: Thomas Abraham 20 24 E: thomas.ab@samsung.com 21 25 D: Samsung pin controller driver
+6 -1
Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
··· 27 27 const: 0 28 28 29 29 clocks: 30 - maxItems: 1 30 + minItems: 1 31 + items: 32 + - description: PHY configuration clock 33 + - description: Alternate PHY reference clock 31 34 32 35 clock-names: 36 + minItems: 1 33 37 items: 34 38 - const: phy 39 + - const: alt 35 40 36 41 power-domains: 37 42 maxItems: 1
+1
Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
··· 80 80 - mediatek,mt2712-tphy 81 81 - mediatek,mt6893-tphy 82 82 - mediatek,mt7629-tphy 83 + - mediatek,mt7981-tphy 83 84 - mediatek,mt7986-tphy 84 85 - mediatek,mt8183-tphy 85 86 - mediatek,mt8186-tphy
+11
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
··· 16 16 properties: 17 17 compatible: 18 18 enum: 19 + - qcom,glymur-qmp-gen5x4-pcie-phy 19 20 - qcom,qcs615-qmp-gen3x1-pcie-phy 20 21 - qcom,qcs8300-qmp-gen4x2-pcie-phy 21 22 - qcom,sa8775p-qmp-gen4x2-pcie-phy ··· 179 178 compatible: 180 179 contains: 181 180 enum: 181 + - qcom,glymur-qmp-gen5x4-pcie-phy 182 182 - qcom,sa8775p-qmp-gen4x2-pcie-phy 183 183 - qcom,sa8775p-qmp-gen4x4-pcie-phy 184 184 - qcom,sc8280xp-qmp-gen3x1-pcie-phy ··· 215 213 compatible: 216 214 contains: 217 215 enum: 216 + - qcom,glymur-qmp-gen5x4-pcie-phy 218 217 - qcom,sm8550-qmp-gen4x2-pcie-phy 219 218 - qcom,sm8650-qmp-gen4x2-pcie-phy 219 + - qcom,x1e80100-qmp-gen3x2-pcie-phy 220 220 - qcom,x1e80100-qmp-gen4x2-pcie-phy 221 221 - qcom,x1e80100-qmp-gen4x4-pcie-phy 222 222 - qcom,x1e80100-qmp-gen4x8-pcie-phy 223 + - qcom,x1p42100-qmp-gen4x4-pcie-phy 223 224 then: 224 225 properties: 225 226 resets: 226 227 minItems: 2 227 228 reset-names: 228 229 minItems: 2 230 + else: 231 + properties: 232 + resets: 233 + maxItems: 1 234 + reset-names: 235 + maxItems: 1 229 236 230 237 - if: 231 238 properties:
+68 -1
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
··· 78 78 79 79 ports: 80 80 $ref: /schemas/graph.yaml#/properties/ports 81 + 81 82 properties: 82 83 port@0: 83 - $ref: /schemas/graph.yaml#/properties/port 84 + $ref: /schemas/graph.yaml#/$defs/port-base 84 85 description: Output endpoint of the PHY 86 + unevaluatedProperties: false 87 + 88 + properties: 89 + endpoint: 90 + $ref: /schemas/graph.yaml#/$defs/endpoint-base 91 + unevaluatedProperties: false 92 + 93 + endpoint@0: 94 + $ref: /schemas/graph.yaml#/$defs/endpoint-base 95 + description: Display Port Output lanes of the PHY when used with static mapping, 96 + The entry index is the DP lanes index, and the number is the PHY 97 + signal in the order RX0, TX0, TX1, RX1. 98 + unevaluatedProperties: false 99 + 100 + properties: 101 + # Static lane mappings are mutually exclusive with typec-mux/orientation-mux 102 + data-lanes: 103 + $ref: /schemas/types.yaml#/definitions/uint32-array 104 + minItems: 2 105 + maxItems: 4 106 + oneOf: 107 + - items: # DisplayPort 1 lane, normal orientation 108 + - const: 3 109 + - items: # DisplayPort 1 lane, flipped orientation 110 + - const: 0 111 + - items: # DisplayPort 2 lanes, normal orientation 112 + - const: 3 113 + - const: 2 114 + - items: # DisplayPort 2 lanes, flipped orientation 115 + - const: 0 116 + - const: 1 117 + - items: # DisplayPort 4 lanes, normal orientation 118 + - const: 3 119 + - const: 2 120 + - const: 1 121 + - const: 0 122 + - items: # DisplayPort 4 lanes, flipped orientation 123 + - const: 0 124 + - const: 1 125 + - const: 2 126 + - const: 3 127 + required: 128 + - data-lanes 129 + 130 + endpoint@1: 131 + $ref: /schemas/graph.yaml#/$defs/endpoint-base 132 + description: USB Output lanes of the PHY when used with static mapping. 133 + The entry index is the USB3 lane in the order TX then RX, and the 134 + number is the PHY signal in the order RX0, TX0, TX1, RX1. 135 + unevaluatedProperties: false 136 + 137 + properties: 138 + # Static lane mappings are mutually exclusive with typec-mux/orientation-mux 139 + data-lanes: 140 + $ref: /schemas/types.yaml#/definitions/uint32-array 141 + minItems: 2 142 + oneOf: 143 + - items: # USB3, normal orientation 144 + - const: 1 145 + - const: 0 146 + - items: # USB3, flipped orientation 147 + - const: 2 148 + - const: 3 149 + 150 + required: 151 + - data-lanes 85 152 86 153 port@1: 87 154 $ref: /schemas/graph.yaml#/properties/port
+63
Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-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/renesas,rzg3e-usb3-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Renesas RZ/G3E USB 3.0 PHY 8 + 9 + maintainers: 10 + - Biju Das <biju.das.jz@bp.renesas.com> 11 + 12 + properties: 13 + compatible: 14 + const: renesas,r9a09g047-usb3-phy 15 + 16 + reg: 17 + maxItems: 1 18 + 19 + clocks: 20 + items: 21 + - description: APB bus clock 22 + - description: USB 2.0 PHY reference clock 23 + - description: USB 3.0 PHY reference clock 24 + 25 + clock-names: 26 + items: 27 + - const: pclk 28 + - const: core 29 + - const: ref_alt_clk_p 30 + 31 + power-domains: 32 + maxItems: 1 33 + 34 + resets: 35 + maxItems: 1 36 + 37 + '#phy-cells': 38 + const: 0 39 + 40 + required: 41 + - compatible 42 + - reg 43 + - clocks 44 + - clock-names 45 + - power-domains 46 + - resets 47 + - '#phy-cells' 48 + 49 + additionalProperties: false 50 + 51 + examples: 52 + - | 53 + #include <dt-bindings/clock/renesas,r9a09g047-cpg.h> 54 + 55 + usb-phy@15870000 { 56 + compatible = "renesas,r9a09g047-usb3-phy"; 57 + reg = <0x15870000 0x10000>; 58 + clocks = <&cpg CPG_MOD 0xb0>, <&cpg CPG_CORE 13>, <&cpg CPG_CORE 12>; 59 + clock-names = "pclk", "core", "ref_alt_clk_p"; 60 + power-domains = <&cpg>; 61 + resets = <&cpg 0xaa>; 62 + #phy-cells = <0>; 63 + };
+1
Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
··· 118 118 contains: 119 119 enum: 120 120 - renesas,usb2-phy-r9a09g057 121 + - renesas,usb2-phy-r9a08g045 121 122 - renesas,rzg2l-usb2-phy 122 123 then: 123 124 properties:
+1
Documentation/devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml
··· 18 18 - rockchip,px30-dsi-dphy 19 19 - rockchip,rk3128-dsi-dphy 20 20 - rockchip,rk3368-dsi-dphy 21 + - rockchip,rk3506-dsi-dphy 21 22 - rockchip,rk3568-dsi-dphy 22 23 - rockchip,rv1126-dsi-dphy 23 24
+66 -3
Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
··· 23 23 - enum: 24 24 - ti,tcan1042 25 25 - ti,tcan1043 26 + - nxp,tja1048 27 + - nxp,tja1051 28 + - nxp,tja1057 26 29 - nxp,tjr1443 27 30 28 31 '#phy-cells': 29 - const: 0 32 + enum: [0, 1] 33 + 34 + silent-gpios: 35 + description: 36 + gpio node to toggle silent signal on transceiver 37 + maxItems: 1 30 38 31 39 standby-gpios: 32 40 description: 33 - gpio node to toggle standby signal on transceiver 34 - maxItems: 1 41 + gpio node to toggle standby signal on transceiver. For two Items, item 1 42 + is for stbn1, item 2 is for stbn2. 43 + minItems: 1 44 + maxItems: 2 35 45 36 46 enable-gpios: 37 47 description: ··· 63 53 required: 64 54 - compatible 65 55 - '#phy-cells' 56 + 57 + allOf: 58 + - if: 59 + properties: 60 + compatible: 61 + enum: 62 + - nxp,tjr1443 63 + - ti,tcan1042 64 + - ti,tcan1043 65 + then: 66 + properties: 67 + '#phy-cells': 68 + const: 0 69 + silent-gpios: false 70 + standby-gpios: 71 + maxItems: 1 72 + 73 + - if: 74 + properties: 75 + compatible: 76 + contains: 77 + const: nxp,tja1048 78 + then: 79 + properties: 80 + '#phy-cells': 81 + const: 1 82 + enable-gpios: false 83 + silent-gpios: false 84 + standby-gpios: 85 + minItems: 2 86 + 87 + - if: 88 + properties: 89 + compatible: 90 + contains: 91 + const: nxp,tja1051 92 + then: 93 + properties: 94 + '#phy-cells': 95 + const: 0 96 + standby-gpios: false 97 + 98 + - if: 99 + properties: 100 + compatible: 101 + contains: 102 + const: nxp,tja1057 103 + then: 104 + properties: 105 + '#phy-cells': 106 + const: 0 107 + enable-gpios: false 108 + standby-gpios: false 66 109 67 110 additionalProperties: false 68 111
+1 -1
MAINTAINERS
··· 10547 10547 10548 10548 GENERIC PHY FRAMEWORK 10549 10549 M: Vinod Koul <vkoul@kernel.org> 10550 - M: Kishon Vijay Abraham I <kishon@kernel.org> 10550 + R: Neil Armstrong <neil.armstrong@linaro.org> 10551 10551 L: linux-phy@lists.infradead.org 10552 10552 S: Supported 10553 10553 Q: https://patchwork.kernel.org/project/linux-phy/list/
+3 -3
drivers/phy/broadcom/phy-bcm63xx-usbh.c
··· 375 375 return of_phy_simple_xlate(dev, args); 376 376 } 377 377 378 - static int __init bcm63xx_usbh_phy_probe(struct platform_device *pdev) 378 + static int bcm63xx_usbh_phy_probe(struct platform_device *pdev) 379 379 { 380 380 struct device *dev = &pdev->dev; 381 381 struct bcm63xx_usbh_phy *usbh; ··· 432 432 return 0; 433 433 } 434 434 435 - static const struct of_device_id bcm63xx_usbh_phy_ids[] __initconst = { 435 + static const struct of_device_id bcm63xx_usbh_phy_ids[] = { 436 436 { .compatible = "brcm,bcm6318-usbh-phy", .data = &usbh_bcm6318 }, 437 437 { .compatible = "brcm,bcm6328-usbh-phy", .data = &usbh_bcm6328 }, 438 438 { .compatible = "brcm,bcm6358-usbh-phy", .data = &usbh_bcm6358 }, ··· 443 443 }; 444 444 MODULE_DEVICE_TABLE(of, bcm63xx_usbh_phy_ids); 445 445 446 - static struct platform_driver bcm63xx_usbh_phy_driver __refdata = { 446 + static struct platform_driver bcm63xx_usbh_phy_driver = { 447 447 .driver = { 448 448 .name = "bcm63xx-usbh-phy", 449 449 .of_match_table = bcm63xx_usbh_phy_ids,
+21 -2
drivers/phy/freescale/phy-fsl-imx8mq-usb.c
··· 16 16 #define PHY_CTRL0_REF_SSP_EN BIT(2) 17 17 #define PHY_CTRL0_FSEL_MASK GENMASK(10, 5) 18 18 #define PHY_CTRL0_FSEL_24M 0x2a 19 + #define PHY_CTRL0_FSEL_100M 0x27 19 20 20 21 #define PHY_CTRL1 0x4 21 22 #define PHY_CTRL1_RESET BIT(0) ··· 109 108 struct imx8mq_usb_phy { 110 109 struct phy *phy; 111 110 struct clk *clk; 111 + struct clk *alt_clk; 112 112 void __iomem *base; 113 113 struct regulator *vbus; 114 114 struct tca_blk *tca; ··· 584 582 /* USB3.0 PHY signal fsel for 24M ref */ 585 583 value = readl(imx_phy->base + PHY_CTRL0); 586 584 value &= ~PHY_CTRL0_FSEL_MASK; 587 - value |= FIELD_PREP(PHY_CTRL0_FSEL_MASK, PHY_CTRL0_FSEL_24M); 585 + value |= FIELD_PREP(PHY_CTRL0_FSEL_MASK, imx_phy->alt_clk ? 586 + PHY_CTRL0_FSEL_100M : PHY_CTRL0_FSEL_24M); 588 587 writel(value, imx_phy->base + PHY_CTRL0); 589 588 590 589 /* Disable alt_clk_en and use internal MPLL clocks */ ··· 629 626 if (ret) 630 627 return ret; 631 628 632 - return clk_prepare_enable(imx_phy->clk); 629 + ret = clk_prepare_enable(imx_phy->clk); 630 + if (ret) 631 + return ret; 632 + 633 + ret = clk_prepare_enable(imx_phy->alt_clk); 634 + if (ret) { 635 + clk_disable_unprepare(imx_phy->clk); 636 + return ret; 637 + } 638 + 639 + return ret; 633 640 } 634 641 635 642 static int imx8mq_phy_power_off(struct phy *phy) 636 643 { 637 644 struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy); 638 645 646 + clk_disable_unprepare(imx_phy->alt_clk); 639 647 clk_disable_unprepare(imx_phy->clk); 640 648 regulator_disable(imx_phy->vbus); 641 649 ··· 694 680 dev_err(dev, "failed to get imx8mq usb phy clock\n"); 695 681 return PTR_ERR(imx_phy->clk); 696 682 } 683 + 684 + imx_phy->alt_clk = devm_clk_get_optional(dev, "alt"); 685 + if (IS_ERR(imx_phy->alt_clk)) 686 + return dev_err_probe(dev, PTR_ERR(imx_phy->alt_clk), 687 + "Failed to get alt clk\n"); 697 688 698 689 imx_phy->base = devm_platform_ioremap_resource(pdev, 0); 699 690 if (IS_ERR(imx_phy->base))
+4 -1
drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
··· 533 533 534 534 static int imx_hsio_probe(struct platform_device *pdev) 535 535 { 536 - int i; 536 + int i, ret; 537 537 void __iomem *off; 538 538 struct device *dev = &pdev->dev; 539 539 struct device_node *np = dev->of_node; ··· 545 545 return -ENOMEM; 546 546 priv->dev = &pdev->dev; 547 547 priv->drvdata = of_device_get_match_data(dev); 548 + ret = devm_mutex_init(dev, &priv->lock); 549 + if (ret) 550 + return ret; 548 551 549 552 /* Get HSIO configuration mode */ 550 553 if (of_property_read_string(np, "fsl,hsio-cfg", &priv->hsio_cfg))
+118 -42
drivers/phy/phy-can-transceiver.c
··· 17 17 u32 flags; 18 18 #define CAN_TRANSCEIVER_STB_PRESENT BIT(0) 19 19 #define CAN_TRANSCEIVER_EN_PRESENT BIT(1) 20 + #define CAN_TRANSCEIVER_DUAL_CH BIT(2) 21 + #define CAN_TRANSCEIVER_SILENT_PRESENT BIT(3) 20 22 }; 21 23 22 24 struct can_transceiver_phy { 23 25 struct phy *generic_phy; 26 + struct gpio_desc *silent_gpio; 24 27 struct gpio_desc *standby_gpio; 25 28 struct gpio_desc *enable_gpio; 29 + struct can_transceiver_priv *priv; 30 + }; 31 + 32 + struct can_transceiver_priv { 26 33 struct mux_state *mux_state; 34 + int num_ch; 35 + struct can_transceiver_phy can_transceiver_phy[] __counted_by(num_ch); 27 36 }; 28 37 29 38 /* Power on function */ 30 39 static int can_transceiver_phy_power_on(struct phy *phy) 31 40 { 32 41 struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy); 42 + struct can_transceiver_priv *priv = can_transceiver_phy->priv; 33 43 int ret; 34 44 35 - if (can_transceiver_phy->mux_state) { 36 - ret = mux_state_select(can_transceiver_phy->mux_state); 45 + if (priv->mux_state) { 46 + ret = mux_state_select(priv->mux_state); 37 47 if (ret) { 38 48 dev_err(&phy->dev, "Failed to select CAN mux: %d\n", ret); 39 49 return ret; 40 50 } 41 51 } 42 - if (can_transceiver_phy->standby_gpio) 43 - gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 0); 44 - if (can_transceiver_phy->enable_gpio) 45 - gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 1); 52 + gpiod_set_value_cansleep(can_transceiver_phy->silent_gpio, 0); 53 + gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 0); 54 + gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 1); 46 55 47 56 return 0; 48 57 } ··· 60 51 static int can_transceiver_phy_power_off(struct phy *phy) 61 52 { 62 53 struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy); 54 + struct can_transceiver_priv *priv = can_transceiver_phy->priv; 63 55 64 - if (can_transceiver_phy->standby_gpio) 65 - gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1); 66 - if (can_transceiver_phy->enable_gpio) 67 - gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0); 68 - if (can_transceiver_phy->mux_state) 69 - mux_state_deselect(can_transceiver_phy->mux_state); 56 + gpiod_set_value_cansleep(can_transceiver_phy->silent_gpio, 1); 57 + gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1); 58 + gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0); 59 + if (priv->mux_state) 60 + mux_state_deselect(priv->mux_state); 70 61 71 62 return 0; 72 63 } ··· 85 76 .flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_EN_PRESENT, 86 77 }; 87 78 79 + static const struct can_transceiver_data tja1048_drvdata = { 80 + .flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_DUAL_CH, 81 + }; 82 + 83 + static const struct can_transceiver_data tja1051_drvdata = { 84 + .flags = CAN_TRANSCEIVER_SILENT_PRESENT | CAN_TRANSCEIVER_EN_PRESENT, 85 + }; 86 + 87 + static const struct can_transceiver_data tja1057_drvdata = { 88 + .flags = CAN_TRANSCEIVER_SILENT_PRESENT, 89 + }; 90 + 88 91 static const struct of_device_id can_transceiver_phy_ids[] = { 89 92 { 90 93 .compatible = "ti,tcan1042", ··· 105 84 { 106 85 .compatible = "ti,tcan1043", 107 86 .data = &tcan1043_drvdata 87 + }, 88 + { 89 + .compatible = "nxp,tja1048", 90 + .data = &tja1048_drvdata 91 + }, 92 + { 93 + .compatible = "nxp,tja1051", 94 + .data = &tja1051_drvdata 95 + }, 96 + { 97 + .compatible = "nxp,tja1057", 98 + .data = &tja1057_drvdata 108 99 }, 109 100 { 110 101 .compatible = "nxp,tjr1443", ··· 136 103 return devm_mux_state_get(dev, mux_name); 137 104 } 138 105 106 + static struct phy *can_transceiver_phy_xlate(struct device *dev, 107 + const struct of_phandle_args *args) 108 + { 109 + struct can_transceiver_priv *priv = dev_get_drvdata(dev); 110 + u32 idx; 111 + 112 + if (priv->num_ch == 1) 113 + return priv->can_transceiver_phy[0].generic_phy; 114 + 115 + if (args->args_count != 1) 116 + return ERR_PTR(-EINVAL); 117 + 118 + idx = args->args[0]; 119 + if (idx >= priv->num_ch) 120 + return ERR_PTR(-EINVAL); 121 + 122 + return priv->can_transceiver_phy[idx].generic_phy; 123 + } 124 + 139 125 static int can_transceiver_phy_probe(struct platform_device *pdev) 140 126 { 141 127 struct phy_provider *phy_provider; 142 128 struct device *dev = &pdev->dev; 143 129 struct can_transceiver_phy *can_transceiver_phy; 130 + struct can_transceiver_priv *priv; 144 131 const struct can_transceiver_data *drvdata; 145 132 const struct of_device_id *match; 146 133 struct phy *phy; 134 + struct gpio_desc *silent_gpio; 147 135 struct gpio_desc *standby_gpio; 148 136 struct gpio_desc *enable_gpio; 149 137 struct mux_state *mux_state; 150 138 u32 max_bitrate = 0; 151 - int err; 152 - 153 - can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL); 154 - if (!can_transceiver_phy) 155 - return -ENOMEM; 139 + int err, i, num_ch = 1; 156 140 157 141 match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node); 158 142 drvdata = match->data; 143 + if (drvdata->flags & CAN_TRANSCEIVER_DUAL_CH) 144 + num_ch = 2; 145 + 146 + priv = devm_kzalloc(dev, struct_size(priv, can_transceiver_phy, num_ch), GFP_KERNEL); 147 + if (!priv) 148 + return -ENOMEM; 149 + 150 + priv->num_ch = num_ch; 151 + platform_set_drvdata(pdev, priv); 159 152 160 153 mux_state = devm_mux_state_get_optional(dev, NULL); 161 154 if (IS_ERR(mux_state)) 162 155 return PTR_ERR(mux_state); 163 156 164 - can_transceiver_phy->mux_state = mux_state; 165 - 166 - phy = devm_phy_create(dev, dev->of_node, 167 - &can_transceiver_phy_ops); 168 - if (IS_ERR(phy)) { 169 - dev_err(dev, "failed to create can transceiver phy\n"); 170 - return PTR_ERR(phy); 171 - } 157 + priv->mux_state = mux_state; 172 158 173 159 err = device_property_read_u32(dev, "max-bitrate", &max_bitrate); 174 160 if ((err != -EINVAL) && !max_bitrate) 175 161 dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n"); 176 - phy->attrs.max_link_rate = max_bitrate; 177 162 178 - can_transceiver_phy->generic_phy = phy; 163 + for (i = 0; i < num_ch; i++) { 164 + can_transceiver_phy = &priv->can_transceiver_phy[i]; 165 + can_transceiver_phy->priv = priv; 179 166 180 - if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) { 181 - standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH); 182 - if (IS_ERR(standby_gpio)) 183 - return PTR_ERR(standby_gpio); 184 - can_transceiver_phy->standby_gpio = standby_gpio; 167 + phy = devm_phy_create(dev, dev->of_node, &can_transceiver_phy_ops); 168 + if (IS_ERR(phy)) { 169 + dev_err(dev, "failed to create can transceiver phy\n"); 170 + return PTR_ERR(phy); 171 + } 172 + 173 + phy->attrs.max_link_rate = max_bitrate; 174 + 175 + can_transceiver_phy->generic_phy = phy; 176 + can_transceiver_phy->priv = priv; 177 + 178 + if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) { 179 + standby_gpio = devm_gpiod_get_index_optional(dev, "standby", i, 180 + GPIOD_OUT_HIGH); 181 + if (IS_ERR(standby_gpio)) 182 + return PTR_ERR(standby_gpio); 183 + can_transceiver_phy->standby_gpio = standby_gpio; 184 + } 185 + 186 + if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) { 187 + enable_gpio = devm_gpiod_get_index_optional(dev, "enable", i, 188 + GPIOD_OUT_LOW); 189 + if (IS_ERR(enable_gpio)) 190 + return PTR_ERR(enable_gpio); 191 + can_transceiver_phy->enable_gpio = enable_gpio; 192 + } 193 + 194 + if (drvdata->flags & CAN_TRANSCEIVER_SILENT_PRESENT) { 195 + silent_gpio = devm_gpiod_get_index_optional(dev, "silent", i, 196 + GPIOD_OUT_LOW); 197 + if (IS_ERR(silent_gpio)) 198 + return PTR_ERR(silent_gpio); 199 + can_transceiver_phy->silent_gpio = silent_gpio; 200 + } 201 + 202 + phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy); 203 + 185 204 } 186 205 187 - if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) { 188 - enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); 189 - if (IS_ERR(enable_gpio)) 190 - return PTR_ERR(enable_gpio); 191 - can_transceiver_phy->enable_gpio = enable_gpio; 192 - } 193 - 194 - phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy); 195 - 196 - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 206 + phy_provider = devm_of_phy_provider_register(dev, can_transceiver_phy_xlate); 197 207 198 208 return PTR_ERR_OR_ZERO(phy_provider); 199 209 }
+26 -1
drivers/phy/phy-core.c
··· 361 361 362 362 mutex_lock(&phy->mutex); 363 363 if (phy->power_count == 1 && phy->ops->power_off) { 364 - ret = phy->ops->power_off(phy); 364 + ret = phy->ops->power_off(phy); 365 365 if (ret < 0) { 366 366 dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret); 367 367 mutex_unlock(&phy->mutex); ··· 519 519 return ret; 520 520 } 521 521 EXPORT_SYMBOL_GPL(phy_notify_disconnect); 522 + 523 + /** 524 + * phy_notify_state() - phy state notification 525 + * @phy: the PHY returned by phy_get() 526 + * @state: the PHY state 527 + * 528 + * Notify the PHY of a state transition. Used to notify and 529 + * configure the PHY accordingly. 530 + * 531 + * Returns: %0 if successful, a negative error code otherwise 532 + */ 533 + int phy_notify_state(struct phy *phy, union phy_notify state) 534 + { 535 + int ret; 536 + 537 + if (!phy || !phy->ops->notify_phystate) 538 + return 0; 539 + 540 + mutex_lock(&phy->mutex); 541 + ret = phy->ops->notify_phystate(phy, state); 542 + mutex_unlock(&phy->mutex); 543 + 544 + return ret; 545 + } 546 + EXPORT_SYMBOL_GPL(phy_notify_state); 522 547 523 548 /** 524 549 * phy_configure() - Changes the phy parameters
+2
drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
··· 25 25 #define POR BIT(1) 26 26 27 27 #define USB_PHY_HS_PHY_CTRL_COMMON0 (0x54) 28 + #define PHY_ENABLE BIT(0) 28 29 #define SIDDQ_SEL BIT(1) 29 30 #define SIDDQ BIT(2) 30 31 #define FSEL GENMASK(6, 4) ··· 82 81 static const struct m31_phy_tbl_entry m31_eusb2_setup_tbl[] = { 83 82 M31_EUSB_PHY_INIT_CFG(USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 1), 84 83 M31_EUSB_PHY_INIT_CFG(USB_PHY_UTMI_CTRL5, POR, 1), 84 + M31_EUSB_PHY_INIT_CFG(USB_PHY_HS_PHY_CTRL_COMMON0, PHY_ENABLE, 1), 85 85 M31_EUSB_PHY_INIT_CFG(USB_PHY_CFG1, PLL_EN, 1), 86 86 M31_EUSB_PHY_INIT_CFG(USB_PHY_FSEL_SEL, FSEL_SEL, 1), 87 87 };
+140 -51
drivers/phy/qualcomm/phy-qcom-qmp-combo.c
··· 13 13 #include <linux/module.h> 14 14 #include <linux/of.h> 15 15 #include <linux/of_address.h> 16 + #include <linux/of_graph.h> 16 17 #include <linux/phy/phy.h> 17 18 #include <linux/platform_device.h> 18 19 #include <linux/regulator/consumer.h> ··· 1644 1643 }; 1645 1644 1646 1645 /* list of regulators */ 1647 - struct qmp_regulator_data { 1648 - const char *name; 1649 - unsigned int enable_load; 1650 - }; 1651 - 1652 - static struct qmp_regulator_data qmp_phy_vreg_l[] = { 1653 - { .name = "vdda-phy", .enable_load = 21800 }, 1654 - { .name = "vdda-pll", .enable_load = 36000 }, 1646 + static struct regulator_bulk_data qmp_phy_vreg_l[] = { 1647 + { .supply = "vdda-phy", .init_load_uA = 21800, }, 1648 + { .supply = "vdda-pll", .init_load_uA = 36000, }, 1655 1649 }; 1656 1650 1657 1651 static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = { ··· 1740 1744 { 0x22, 0xff, 0xff, 0xff } 1741 1745 }; 1742 1746 1747 + struct qmp_combo_lane_mapping { 1748 + unsigned int lanes_count; 1749 + enum typec_orientation orientation; 1750 + u32 lanes[4]; 1751 + }; 1752 + 1753 + static const struct qmp_combo_lane_mapping usb3_data_lanes[] = { 1754 + { 2, TYPEC_ORIENTATION_NORMAL, { 1, 0 }}, 1755 + { 2, TYPEC_ORIENTATION_REVERSE, { 2, 3 }}, 1756 + }; 1757 + 1758 + static const struct qmp_combo_lane_mapping dp_data_lanes[] = { 1759 + { 1, TYPEC_ORIENTATION_NORMAL, { 3 }}, 1760 + { 1, TYPEC_ORIENTATION_REVERSE, { 0 }}, 1761 + { 2, TYPEC_ORIENTATION_NORMAL, { 3, 2 }}, 1762 + { 2, TYPEC_ORIENTATION_REVERSE, { 0, 1 }}, 1763 + { 4, TYPEC_ORIENTATION_NORMAL, { 3, 2, 1, 0 }}, 1764 + { 4, TYPEC_ORIENTATION_REVERSE, { 0, 1, 2, 3 }}, 1765 + }; 1766 + 1743 1767 struct qmp_combo; 1744 1768 1745 1769 struct qmp_combo_offsets { ··· 1824 1808 const char * const *reset_list; 1825 1809 int num_resets; 1826 1810 /* regulators to be requested */ 1827 - const struct qmp_regulator_data *vreg_list; 1811 + const struct regulator_bulk_data *vreg_list; 1828 1812 int num_vregs; 1829 1813 1830 1814 /* array of registers with different offsets */ ··· 3455 3439 qmp_combo_runtime_resume, NULL) 3456 3440 }; 3457 3441 3458 - static int qmp_combo_vreg_init(struct qmp_combo *qmp) 3459 - { 3460 - const struct qmp_phy_cfg *cfg = qmp->cfg; 3461 - struct device *dev = qmp->dev; 3462 - int num = cfg->num_vregs; 3463 - int ret, i; 3464 - 3465 - qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); 3466 - if (!qmp->vregs) 3467 - return -ENOMEM; 3468 - 3469 - for (i = 0; i < num; i++) 3470 - qmp->vregs[i].supply = cfg->vreg_list[i].name; 3471 - 3472 - ret = devm_regulator_bulk_get(dev, num, qmp->vregs); 3473 - if (ret) { 3474 - dev_err(dev, "failed at devm_regulator_bulk_get\n"); 3475 - return ret; 3476 - } 3477 - 3478 - for (i = 0; i < num; i++) { 3479 - ret = regulator_set_load(qmp->vregs[i].consumer, 3480 - cfg->vreg_list[i].enable_load); 3481 - if (ret) { 3482 - dev_err(dev, "failed to set load at %s\n", 3483 - qmp->vregs[i].supply); 3484 - return ret; 3485 - } 3486 - } 3487 - 3488 - return 0; 3489 - } 3490 - 3491 3442 static int qmp_combo_reset_init(struct qmp_combo *qmp) 3492 3443 { 3493 3444 const struct qmp_phy_cfg *cfg = qmp->cfg; ··· 4100 4117 return ERR_PTR(-EINVAL); 4101 4118 } 4102 4119 4120 + static void qmp_combo_find_lanes_orientation(const struct qmp_combo_lane_mapping *mapping, 4121 + unsigned int mapping_count, 4122 + u32 *lanes, unsigned int lanes_count, 4123 + enum typec_orientation *orientation) 4124 + { 4125 + int i; 4126 + 4127 + for (i = 0; i < mapping_count; i++) { 4128 + if (mapping[i].lanes_count != lanes_count) 4129 + continue; 4130 + if (!memcmp(mapping[i].lanes, lanes, sizeof(u32) * lanes_count)) { 4131 + *orientation = mapping[i].orientation; 4132 + return; 4133 + } 4134 + } 4135 + } 4136 + 4137 + static int qmp_combo_get_dt_lanes_mapping(struct device *dev, unsigned int endpoint, 4138 + u32 *data_lanes, unsigned int max, 4139 + unsigned int *count) 4140 + { 4141 + struct device_node *ep __free(device_node) = NULL; 4142 + int ret; 4143 + 4144 + ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, endpoint); 4145 + if (!ep) 4146 + return -EINVAL; 4147 + 4148 + ret = of_property_count_u32_elems(ep, "data-lanes"); 4149 + if (ret < 0) 4150 + return ret; 4151 + 4152 + *count = ret; 4153 + if (*count > max) 4154 + return -EINVAL; 4155 + 4156 + return of_property_read_u32_array(ep, "data-lanes", data_lanes, 4157 + min_t(unsigned int, *count, max)); 4158 + } 4159 + 4160 + static int qmp_combo_get_dt_dp_orientation(struct device *dev, 4161 + enum typec_orientation *orientation) 4162 + { 4163 + unsigned int count; 4164 + u32 data_lanes[4]; 4165 + int ret; 4166 + 4167 + /* DP is described on the first endpoint of the first port */ 4168 + ret = qmp_combo_get_dt_lanes_mapping(dev, 0, data_lanes, 4, &count); 4169 + if (ret < 0) 4170 + return ret == -EINVAL ? 0 : ret; 4171 + 4172 + /* Search for a match and only update orientation if found */ 4173 + qmp_combo_find_lanes_orientation(dp_data_lanes, ARRAY_SIZE(dp_data_lanes), 4174 + data_lanes, count, orientation); 4175 + 4176 + return 0; 4177 + } 4178 + 4179 + static int qmp_combo_get_dt_usb3_orientation(struct device *dev, 4180 + enum typec_orientation *orientation) 4181 + { 4182 + unsigned int count; 4183 + u32 data_lanes[2]; 4184 + int ret; 4185 + 4186 + /* USB3 is described on the second endpoint of the first port */ 4187 + ret = qmp_combo_get_dt_lanes_mapping(dev, 1, data_lanes, 2, &count); 4188 + if (ret < 0) 4189 + return ret == -EINVAL ? 0 : ret; 4190 + 4191 + /* Search for a match and only update orientation if found */ 4192 + qmp_combo_find_lanes_orientation(usb3_data_lanes, ARRAY_SIZE(usb3_data_lanes), 4193 + data_lanes, count, orientation); 4194 + 4195 + return 0; 4196 + } 4197 + 4103 4198 static int qmp_combo_probe(struct platform_device *pdev) 4104 4199 { 4105 4200 struct qmp_combo *qmp; ··· 4205 4144 if (ret) 4206 4145 return ret; 4207 4146 4208 - ret = qmp_combo_vreg_init(qmp); 4147 + ret = devm_regulator_bulk_get_const(dev, qmp->cfg->num_vregs, 4148 + qmp->cfg->vreg_list, &qmp->vregs); 4209 4149 if (ret) 4210 4150 return ret; 4211 4151 ··· 4229 4167 if (ret) 4230 4168 goto err_node_put; 4231 4169 4232 - ret = qmp_combo_typec_register(qmp); 4233 - if (ret) 4234 - goto err_node_put; 4170 + qmp->qmpphy_mode = QMPPHY_MODE_USB3DP; 4171 + 4172 + if (of_property_present(dev->of_node, "mode-switch") || 4173 + of_property_present(dev->of_node, "orientation-switch")) { 4174 + ret = qmp_combo_typec_register(qmp); 4175 + if (ret) 4176 + goto err_node_put; 4177 + } else { 4178 + enum typec_orientation dp_orientation = TYPEC_ORIENTATION_NONE; 4179 + enum typec_orientation usb3_orientation = TYPEC_ORIENTATION_NONE; 4180 + 4181 + ret = qmp_combo_get_dt_dp_orientation(dev, &dp_orientation); 4182 + if (ret) 4183 + goto err_node_put; 4184 + 4185 + ret = qmp_combo_get_dt_usb3_orientation(dev, &usb3_orientation); 4186 + if (ret) 4187 + goto err_node_put; 4188 + 4189 + if (dp_orientation == TYPEC_ORIENTATION_NONE && 4190 + usb3_orientation != TYPEC_ORIENTATION_NONE) { 4191 + qmp->qmpphy_mode = QMPPHY_MODE_USB3_ONLY; 4192 + qmp->orientation = usb3_orientation; 4193 + } else if (usb3_orientation == TYPEC_ORIENTATION_NONE && 4194 + dp_orientation != TYPEC_ORIENTATION_NONE) { 4195 + qmp->qmpphy_mode = QMPPHY_MODE_DP_ONLY; 4196 + qmp->orientation = dp_orientation; 4197 + } else if (dp_orientation != TYPEC_ORIENTATION_NONE && 4198 + dp_orientation == usb3_orientation) { 4199 + qmp->qmpphy_mode = QMPPHY_MODE_USB3DP; 4200 + qmp->orientation = dp_orientation; 4201 + } else { 4202 + dev_warn(dev, "unable to determine orientation & mode from data-lanes"); 4203 + } 4204 + } 4235 4205 4236 4206 ret = drm_aux_bridge_register(dev); 4237 4207 if (ret) ··· 4283 4189 if (ret) 4284 4190 goto err_node_put; 4285 4191 4286 - /* 4287 - * The hw default is USB3_ONLY, but USB3+DP mode lets us more easily 4288 - * check both sub-blocks' init tables for blunders at probe time. 4289 - */ 4290 - qmp->qmpphy_mode = QMPPHY_MODE_USB3DP; 4291 4192 4292 4193 qmp->usb_phy = devm_phy_create(dev, usb_np, &qmp_combo_usb_phy_ops); 4293 4194 if (IS_ERR(qmp->usb_phy)) {
+32
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
··· 100 100 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V7_PCS_POWER_DOWN_CONTROL, 101 101 }; 102 102 103 + static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = { 104 + [QPHY_START_CTRL] = QPHY_V8_50_PCS_START_CONTROL, 105 + [QPHY_PCS_STATUS] = QPHY_V8_50_PCS_STATUS1, 106 + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_50_PCS_POWER_DOWN_CONTROL, 107 + }; 108 + 103 109 static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = { 104 110 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14), 105 111 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), ··· 3078 3072 u16 rx2; 3079 3073 u16 txz; 3080 3074 u16 rxz; 3075 + u16 txrxz; 3081 3076 u16 ln_shrd; 3082 3077 }; 3083 3078 ··· 3361 3354 .txz = 0xe000, 3362 3355 .rxz = 0xe200, 3363 3356 .ln_shrd = 0x8000, 3357 + }; 3358 + 3359 + static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = { 3360 + .serdes = 0x8000, 3361 + .pcs = 0x9000, 3362 + .txrxz = 0xd000, 3364 3363 }; 3365 3364 3366 3365 static const struct qmp_phy_cfg ipq8074_pciephy_cfg = { ··· 4425 4412 .phy_status = PHYSTATUS_4_20, 4426 4413 }; 4427 4414 4415 + static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = { 4416 + .lanes = 4, 4417 + 4418 + .offsets = &qmp_pcie_offsets_v8_50, 4419 + 4420 + .reset_list = sdm845_pciephy_reset_l, 4421 + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), 4422 + .vreg_list = qmp_phy_vreg_l, 4423 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 4424 + 4425 + .regs = pciephy_v8_50_regs_layout, 4426 + 4427 + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4428 + .phy_status = PHYSTATUS_4_20, 4429 + }; 4430 + 4428 4431 static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls) 4429 4432 { 4430 4433 const struct qmp_phy_cfg *cfg = qmp->cfg; ··· 5192 5163 5193 5164 static const struct of_device_id qmp_pcie_of_match_table[] = { 5194 5165 { 5166 + .compatible = "qcom,glymur-qmp-gen5x4-pcie-phy", 5167 + .data = &glymur_qmp_gen5x4_pciephy_cfg, 5168 + }, { 5195 5169 .compatible = "qcom,ipq6018-qmp-pcie-phy", 5196 5170 .data = &ipq6018_pciephy_cfg, 5197 5171 }, {
+13
drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_PCS_V8_50_H_ 7 + #define QCOM_PHY_QMP_PCS_V8_50_H_ 8 + 9 + #define QPHY_V8_50_PCS_STATUS1 0x010 10 + #define QPHY_V8_50_PCS_START_CONTROL 0x05c 11 + #define QPHY_V8_50_PCS_POWER_DOWN_CONTROL 0x64 12 + 13 + #endif
+2
drivers/phy/qualcomm/phy-qcom-qmp.h
··· 58 58 59 59 #include "phy-qcom-qmp-pcs-v8.h" 60 60 61 + #include "phy-qcom-qmp-pcs-v8_50.h" 62 + 61 63 /* QPHY_SW_RESET bit */ 62 64 #define SW_RESET BIT(0) 63 65 /* QPHY_POWER_DOWN_CONTROL */
+7
drivers/phy/renesas/Kconfig
··· 40 40 select GENERIC_PHY 41 41 help 42 42 Support for USB 3.0 PHY found on Renesas R-Car generation 3 SoCs. 43 + 44 + config PHY_RZ_G3E_USB3 45 + tristate "Renesas RZ/G3E USB 3.0 PHY driver" 46 + depends on ARCH_RENESAS || COMPILE_TEST 47 + select GENERIC_PHY 48 + help 49 + Support for USB 3.0 PHY found on Renesas RZ/G3E SoCs.
+1
drivers/phy/renesas/Makefile
··· 4 4 obj-$(CONFIG_PHY_RCAR_GEN3_PCIE) += phy-rcar-gen3-pcie.o 5 5 obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o 6 6 obj-$(CONFIG_PHY_RCAR_GEN3_USB3) += phy-rcar-gen3-usb3.o 7 + obj-$(CONFIG_PHY_RZ_G3E_USB3) += phy-rzg3e-usb3.o
+1 -1
drivers/phy/renesas/phy-rcar-gen3-pcie.c
··· 128 128 static void rcar_gen3_phy_pcie_remove(struct platform_device *pdev) 129 129 { 130 130 pm_runtime_disable(&pdev->dev); 131 - }; 131 + } 132 132 133 133 static struct platform_driver rcar_gen3_phy_driver = { 134 134 .driver = {
+53 -17
drivers/phy/renesas/phy-rcar-gen3-usb2.c
··· 132 132 struct device *dev; /* platform_device's device */ 133 133 const struct rcar_gen3_phy_drv_data *phy_data; 134 134 struct extcon_dev *extcon; 135 + struct reset_control *rstc; 135 136 struct rcar_gen3_phy rphys[NUM_OF_PHYS]; 136 137 struct regulator *vbus; 137 - struct reset_control *rstc; 138 138 struct work_struct work; 139 139 spinlock_t lock; /* protects access to hardware and driver data structure. */ 140 140 enum usb_dr_mode dr_mode; ··· 771 771 return candidate; 772 772 } 773 773 774 + static void rcar_gen3_reset_assert(void *data) 775 + { 776 + reset_control_assert(data); 777 + } 778 + 774 779 static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel) 775 780 { 776 781 struct device *dev = channel->dev; 777 782 int ret; 778 783 u32 val; 779 784 780 - channel->rstc = devm_reset_control_array_get_shared(dev); 781 - if (IS_ERR(channel->rstc)) 782 - return PTR_ERR(channel->rstc); 785 + if (!channel->phy_data->init_bus) 786 + return 0; 783 787 784 788 ret = pm_runtime_resume_and_get(dev); 785 789 if (ret) 786 790 return ret; 787 - 788 - ret = reset_control_deassert(channel->rstc); 789 - if (ret) 790 - goto rpm_put; 791 791 792 792 val = readl(channel->base + USB2_AHB_BUS_CTR); 793 793 val &= ~USB2_AHB_BUS_CTR_MBL_MASK; 794 794 val |= USB2_AHB_BUS_CTR_MBL_INCR4; 795 795 writel(val, channel->base + USB2_AHB_BUS_CTR); 796 796 797 - rpm_put: 798 797 pm_runtime_put(dev); 799 798 800 - return ret; 799 + return 0; 801 800 } 802 801 803 802 static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) ··· 836 837 } 837 838 } 838 839 840 + channel->rstc = devm_reset_control_array_get_optional_shared(dev); 841 + if (IS_ERR(channel->rstc)) 842 + return PTR_ERR(channel->rstc); 843 + 844 + ret = reset_control_deassert(channel->rstc); 845 + if (ret) 846 + return ret; 847 + 848 + ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert, channel->rstc); 849 + if (ret) 850 + return ret; 851 + 839 852 /* 840 853 * devm_phy_create() will call pm_runtime_enable(&phy->dev); 841 854 * And then, phy-core will manage runtime pm for this device. ··· 863 852 platform_set_drvdata(pdev, channel); 864 853 channel->dev = dev; 865 854 866 - if (channel->phy_data->init_bus) { 867 - ret = rcar_gen3_phy_usb2_init_bus(channel); 868 - if (ret) 869 - goto error; 870 - } 855 + ret = rcar_gen3_phy_usb2_init_bus(channel); 856 + if (ret) 857 + goto error; 871 858 872 859 spin_lock_init(&channel->lock); 873 860 for (i = 0; i < NUM_OF_PHYS; i++) { ··· 933 924 if (channel->is_otg_channel) 934 925 device_remove_file(&pdev->dev, &dev_attr_role); 935 926 936 - reset_control_assert(channel->rstc); 937 927 pm_runtime_disable(&pdev->dev); 938 - }; 928 + } 929 + 930 + static int rcar_gen3_phy_usb2_suspend(struct device *dev) 931 + { 932 + struct rcar_gen3_chan *channel = dev_get_drvdata(dev); 933 + 934 + return reset_control_assert(channel->rstc); 935 + } 936 + 937 + static int rcar_gen3_phy_usb2_resume(struct device *dev) 938 + { 939 + struct rcar_gen3_chan *channel = dev_get_drvdata(dev); 940 + int ret; 941 + 942 + ret = reset_control_deassert(channel->rstc); 943 + if (ret) 944 + return ret; 945 + 946 + ret = rcar_gen3_phy_usb2_init_bus(channel); 947 + if (ret) 948 + reset_control_assert(channel->rstc); 949 + 950 + return ret; 951 + } 952 + 953 + static DEFINE_SIMPLE_DEV_PM_OPS(rcar_gen3_phy_usb2_pm_ops, 954 + rcar_gen3_phy_usb2_suspend, 955 + rcar_gen3_phy_usb2_resume); 939 956 940 957 static struct platform_driver rcar_gen3_phy_usb2_driver = { 941 958 .driver = { 942 959 .name = "phy_rcar_gen3_usb2", 943 960 .of_match_table = rcar_gen3_phy_usb2_match_table, 961 + .pm = pm_ptr(&rcar_gen3_phy_usb2_pm_ops), 944 962 }, 945 963 .probe = rcar_gen3_phy_usb2_probe, 946 964 .remove = rcar_gen3_phy_usb2_remove,
+1 -1
drivers/phy/renesas/phy-rcar-gen3-usb3.c
··· 202 202 static void rcar_gen3_phy_usb3_remove(struct platform_device *pdev) 203 203 { 204 204 pm_runtime_disable(&pdev->dev); 205 - }; 205 + } 206 206 207 207 static struct platform_driver rcar_gen3_phy_usb3_driver = { 208 208 .driver = {
+259
drivers/phy/renesas/phy-rzg3e-usb3.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Renesas RZ/G3E USB3.0 PHY driver 4 + * 5 + * Copyright (C) 2025 Renesas Electronics Corporation 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/delay.h> 10 + #include <linux/io.h> 11 + #include <linux/iopoll.h> 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/phy/phy.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/pm_runtime.h> 17 + #include <linux/reset.h> 18 + 19 + #define USB3_TEST_RESET 0x0000 20 + #define USB3_TEST_UTMICTRL2 0x0b04 21 + #define USB3_TEST_PRMCTRL5_R 0x0c10 22 + #define USB3_TEST_PRMCTRL6_R 0x0c14 23 + 24 + #define USB3_TEST_RSTCTRL 0x1000 25 + #define USB3_TEST_CLKCTRL 0x1004 26 + #define USB3_TEST_RAMCTRL 0x100c 27 + #define USB3_TEST_CREGCTRL 0x1010 28 + #define USB3_TEST_LANECONFIG0 0x1030 29 + 30 + #define USB3_TEST_RESET_PORTRESET0_CTRL BIT(9) 31 + #define USB3_TEST_RESET_SIDDQ BIT(3) 32 + #define USB3_TEST_RESET_PHY_RESET BIT(2) 33 + #define USB3_TEST_RESET_PORTRESET0 BIT(1) 34 + #define USB3_TEST_RESET_RELEASE_OVERRIDE (0) 35 + 36 + #define USB3_TEST_UTMICTRL2_CTRL_MASK GENMASK(9, 8) 37 + #define USB3_TEST_UTMICTRL2_MODE_MASK GENMASK(1, 0) 38 + 39 + #define USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK GENMASK(2, 1) 40 + 41 + #define USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK GENMASK(2, 0) 42 + 43 + #define USB3_TEST_RSTCTRL_HARDRESET_ODEN BIT(9) 44 + #define USB3_TEST_RSTCTRL_PIPERESET_ODEN BIT(8) 45 + #define USB3_TEST_RSTCTRL_HARDRESET BIT(1) 46 + #define USB3_TEST_RSTCTRL_PIPERESET BIT(0) 47 + #define USB3_TEST_RSTCTRL_ASSERT \ 48 + (USB3_TEST_RSTCTRL_HARDRESET_ODEN | USB3_TEST_RSTCTRL_PIPERESET_ODEN | \ 49 + USB3_TEST_RSTCTRL_HARDRESET | USB3_TEST_RSTCTRL_PIPERESET) 50 + #define USB3_TEST_RSTCTRL_RELEASE_HARDRESET \ 51 + (USB3_TEST_RSTCTRL_HARDRESET_ODEN | USB3_TEST_RSTCTRL_PIPERESET_ODEN | \ 52 + USB3_TEST_RSTCTRL_PIPERESET) 53 + #define USB3_TEST_RSTCTRL_DEASSERT \ 54 + (USB3_TEST_RSTCTRL_HARDRESET_ODEN | USB3_TEST_RSTCTRL_PIPERESET_ODEN) 55 + #define USB3_TEST_RSTCTRL_RELEASE_OVERRIDE (0) 56 + 57 + #define USB3_TEST_CLKCTRL_MPLLA_SSC_EN BIT(2) 58 + 59 + #define USB3_TEST_RAMCTRL_SRAM_INIT_DONE BIT(2) 60 + #define USB3_TEST_RAMCTRL_SRAM_EXT_LD_DONE BIT(0) 61 + 62 + #define USB3_TEST_CREGCTRL_PARA_SEL BIT(8) 63 + 64 + #define USB3_TEST_LANECONFIG0_DEFAULT (0xd) 65 + 66 + struct rz_usb3 { 67 + void __iomem *base; 68 + struct reset_control *rstc; 69 + bool skip_reinit; 70 + }; 71 + 72 + static void rzg3e_phy_usb2test_phy_init(void __iomem *base) 73 + { 74 + u32 val; 75 + 76 + val = readl(base + USB3_TEST_UTMICTRL2); 77 + val |= USB3_TEST_UTMICTRL2_CTRL_MASK | USB3_TEST_UTMICTRL2_MODE_MASK; 78 + writel(val, base + USB3_TEST_UTMICTRL2); 79 + 80 + val = readl(base + USB3_TEST_PRMCTRL5_R); 81 + val &= ~USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK; 82 + val |= FIELD_PREP(USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK, 2); 83 + writel(val, base + USB3_TEST_PRMCTRL5_R); 84 + 85 + val = readl(base + USB3_TEST_PRMCTRL6_R); 86 + val &= ~USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK; 87 + val |= FIELD_PREP(USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK, 7); 88 + writel(val, base + USB3_TEST_PRMCTRL6_R); 89 + 90 + val = readl(base + USB3_TEST_RESET); 91 + val &= ~USB3_TEST_RESET_SIDDQ; 92 + val |= USB3_TEST_RESET_PORTRESET0_CTRL | USB3_TEST_RESET_PHY_RESET | 93 + USB3_TEST_RESET_PORTRESET0; 94 + writel(val, base + USB3_TEST_RESET); 95 + fsleep(10); 96 + 97 + val &= ~(USB3_TEST_RESET_PHY_RESET | USB3_TEST_RESET_PORTRESET0); 98 + writel(val, base + USB3_TEST_RESET); 99 + fsleep(10); 100 + 101 + val = readl(base + USB3_TEST_UTMICTRL2); 102 + val &= ~USB3_TEST_UTMICTRL2_CTRL_MASK; 103 + writel(val, base + USB3_TEST_UTMICTRL2); 104 + 105 + writel(USB3_TEST_RESET_RELEASE_OVERRIDE, base + USB3_TEST_RESET); 106 + } 107 + 108 + static int rzg3e_phy_usb3test_phy_init(void __iomem *base) 109 + { 110 + int ret; 111 + u32 val; 112 + 113 + writel(USB3_TEST_CREGCTRL_PARA_SEL, base + USB3_TEST_CREGCTRL); 114 + writel(USB3_TEST_RSTCTRL_ASSERT, base + USB3_TEST_RSTCTRL); 115 + fsleep(20); 116 + 117 + writel(USB3_TEST_CLKCTRL_MPLLA_SSC_EN, base + USB3_TEST_CLKCTRL); 118 + writel(USB3_TEST_LANECONFIG0_DEFAULT, base + USB3_TEST_LANECONFIG0); 119 + writel(USB3_TEST_RSTCTRL_RELEASE_HARDRESET, base + USB3_TEST_RSTCTRL); 120 + 121 + ret = readl_poll_timeout_atomic(base + USB3_TEST_RAMCTRL, val, 122 + val & USB3_TEST_RAMCTRL_SRAM_INIT_DONE, 1, 10000); 123 + if (ret) 124 + return ret; 125 + 126 + writel(USB3_TEST_RSTCTRL_DEASSERT, base + USB3_TEST_RSTCTRL); 127 + writel(USB3_TEST_RAMCTRL_SRAM_EXT_LD_DONE, base + USB3_TEST_RAMCTRL); 128 + writel(USB3_TEST_RSTCTRL_RELEASE_OVERRIDE, base + USB3_TEST_RSTCTRL); 129 + 130 + return 0; 131 + } 132 + 133 + static int rzg3e_phy_usb3_init_helper(void __iomem *base) 134 + { 135 + rzg3e_phy_usb2test_phy_init(base); 136 + 137 + return rzg3e_phy_usb3test_phy_init(base); 138 + } 139 + 140 + static int rzg3e_phy_usb3_init(struct phy *p) 141 + { 142 + struct rz_usb3 *r = phy_get_drvdata(p); 143 + int ret = 0; 144 + 145 + if (!r->skip_reinit) 146 + ret = rzg3e_phy_usb3_init_helper(r->base); 147 + 148 + return ret; 149 + } 150 + 151 + static const struct phy_ops rzg3e_phy_usb3_ops = { 152 + .init = rzg3e_phy_usb3_init, 153 + .owner = THIS_MODULE, 154 + }; 155 + 156 + static int rzg3e_phy_usb3_probe(struct platform_device *pdev) 157 + { 158 + struct device *dev = &pdev->dev; 159 + struct phy_provider *provider; 160 + struct rz_usb3 *r; 161 + struct phy *phy; 162 + int ret; 163 + 164 + r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL); 165 + if (!r) 166 + return -ENOMEM; 167 + 168 + r->base = devm_platform_ioremap_resource(pdev, 0); 169 + if (IS_ERR(r->base)) 170 + return PTR_ERR(r->base); 171 + 172 + r->rstc = devm_reset_control_get_shared_deasserted(dev, NULL); 173 + if (IS_ERR(r->rstc)) 174 + return dev_err_probe(dev, PTR_ERR(r->rstc), "failed to get deasserted reset\n"); 175 + 176 + /* 177 + * devm_phy_create() will call pm_runtime_enable(&phy->dev); 178 + * And then, phy-core will manage runtime pm for this device. 179 + */ 180 + ret = devm_pm_runtime_enable(dev); 181 + if (ret < 0) 182 + return ret; 183 + 184 + phy = devm_phy_create(dev, NULL, &rzg3e_phy_usb3_ops); 185 + if (IS_ERR(phy)) 186 + return dev_err_probe(dev, PTR_ERR(phy), "failed to create USB3 PHY\n"); 187 + 188 + platform_set_drvdata(pdev, r); 189 + phy_set_drvdata(phy, r); 190 + 191 + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 192 + if (IS_ERR(provider)) 193 + return dev_err_probe(dev, PTR_ERR(provider), "failed to register PHY provider\n"); 194 + 195 + return 0; 196 + } 197 + 198 + static int rzg3e_phy_usb3_suspend(struct device *dev) 199 + { 200 + struct rz_usb3 *r = dev_get_drvdata(dev); 201 + 202 + pm_runtime_put(dev); 203 + reset_control_assert(r->rstc); 204 + r->skip_reinit = false; 205 + 206 + return 0; 207 + } 208 + 209 + static int rzg3e_phy_usb3_resume(struct device *dev) 210 + { 211 + struct rz_usb3 *r = dev_get_drvdata(dev); 212 + int ret; 213 + 214 + ret = reset_control_deassert(r->rstc); 215 + if (ret) 216 + return ret; 217 + 218 + ret = pm_runtime_resume_and_get(dev); 219 + if (ret) 220 + goto reset_assert; 221 + 222 + ret = rzg3e_phy_usb3_init_helper(r->base); 223 + if (ret) 224 + goto pm_put; 225 + 226 + r->skip_reinit = true; 227 + 228 + return 0; 229 + 230 + pm_put: 231 + pm_runtime_put(dev); 232 + reset_assert: 233 + reset_control_assert(r->rstc); 234 + return ret; 235 + } 236 + 237 + static const struct dev_pm_ops rzg3e_phy_usb3_pm = { 238 + NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume) 239 + }; 240 + 241 + static const struct of_device_id rzg3e_phy_usb3_match_table[] = { 242 + { .compatible = "renesas,r9a09g047-usb3-phy" }, 243 + { /* Sentinel */ } 244 + }; 245 + 246 + MODULE_DEVICE_TABLE(of, rzg3e_phy_usb3_match_table); 247 + static struct platform_driver rzg3e_phy_usb3_driver = { 248 + .driver = { 249 + .name = "phy_rzg3e_usb3", 250 + .of_match_table = rzg3e_phy_usb3_match_table, 251 + .pm = pm_sleep_ptr(&rzg3e_phy_usb3_pm), 252 + }, 253 + .probe = rzg3e_phy_usb3_probe, 254 + }; 255 + module_platform_driver(rzg3e_phy_usb3_driver); 256 + 257 + MODULE_LICENSE("GPL"); 258 + MODULE_DESCRIPTION("Renesas RZ/G3E USB3.0 PHY Driver"); 259 + MODULE_AUTHOR("biju.das.jz@bp.renesas.com>");
+88 -3
drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
··· 99 99 #define VOD_MID_RANGE 0x3 100 100 #define VOD_BIG_RANGE 0x7 101 101 #define VOD_MAX_RANGE 0xf 102 + /* Analog Register Part: reg18 */ 103 + #define LANE0_PRE_EMPHASIS_ENABLE_MASK BIT(6) 104 + #define LANE0_PRE_EMPHASIS_ENABLE BIT(6) 105 + #define LANE0_PRE_EMPHASIS_DISABLE 0 106 + #define LANE1_PRE_EMPHASIS_ENABLE_MASK BIT(5) 107 + #define LANE1_PRE_EMPHASIS_ENABLE BIT(5) 108 + #define LANE1_PRE_EMPHASIS_DISABLE 0 109 + /* Analog Register Part: reg19 */ 110 + #define PRE_EMPHASIS_RANGE_SET_MASK GENMASK(7, 6) 111 + #define PRE_EMPHASIS_RANGE_SET(x) UPDATE(x, 7, 6) 102 112 /* Analog Register Part: reg1E */ 103 113 #define PLL_MODE_SEL_MASK GENMASK(6, 5) 104 114 #define PLL_MODE_SEL_LVDS_MODE 0 105 115 #define PLL_MODE_SEL_MIPI_MODE BIT(5) 116 + /* Analog Register Part: reg20 */ 117 + #define LANE0_PRE_EMPHASIS_RANGE_SET_MASK GENMASK(7, 6) 118 + #define LANE0_PRE_EMPHASIS_RANGE_SET(x) UPDATE(x, 7, 6) 119 + /* Analog Register Part: reg21 */ 120 + #define LANE1_PRE_EMPHASIS_RANGE_SET_MASK GENMASK(7, 6) 121 + #define LANE1_PRE_EMPHASIS_RANGE_SET(x) UPDATE(x, 7, 6) 122 + #define PRE_EMPHASIS_MIN_RANGE 0x0 123 + #define PRE_EMPHASIS_MID_RANGE 0x1 124 + #define PRE_EMPHASIS_MAX_RANGE 0x2 125 + #define PRE_EMPHASIS_RESERVED_RANGE 0x3 106 126 /* Digital Register Part: reg00 */ 107 127 #define REG_DIG_RSTN_MASK BIT(0) 108 128 #define REG_DIG_RSTN_NORMAL BIT(0) ··· 213 193 214 194 enum phy_max_rate { 215 195 MAX_1GHZ, 196 + MAX_1_5GHZ, 216 197 MAX_2_5GHZ, 217 198 }; 218 199 ··· 221 200 const struct inno_mipi_dphy_timing *inno_mipi_dphy_timing_table; 222 201 const unsigned int num_timings; 223 202 enum phy_max_rate max_rate; 203 + unsigned int max_lanes; 224 204 }; 225 205 226 206 struct inno_dsidphy { ··· 278 256 { 700000000, 0x0, 0x3e, 0x1e, 0x08, 0x6a}, 279 257 { 800000000, 0x0, 0x21, 0x1f, 0x09, 0x29}, 280 258 {1000000000, 0x0, 0x09, 0x20, 0x09, 0x27}, 259 + }; 260 + 261 + static const 262 + struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_1_5ghz[] = { 263 + { 110, 0x02, 0x7f, 0x16, 0x02, 0x02}, 264 + { 150, 0x02, 0x7f, 0x16, 0x03, 0x02}, 265 + { 200, 0x02, 0x7f, 0x17, 0x04, 0x02}, 266 + { 250, 0x02, 0x7f, 0x17, 0x05, 0x04}, 267 + { 300, 0x02, 0x7f, 0x18, 0x06, 0x04}, 268 + { 400, 0x03, 0x7e, 0x19, 0x07, 0x04}, 269 + { 500, 0x03, 0x7c, 0x1b, 0x07, 0x08}, 270 + { 600, 0x03, 0x70, 0x1d, 0x08, 0x10}, 271 + { 700, 0x05, 0x40, 0x1e, 0x08, 0x30}, 272 + { 800, 0x05, 0x02, 0x1f, 0x09, 0x30}, 273 + {1000, 0x05, 0x08, 0x20, 0x09, 0x30}, 274 + {1200, 0x06, 0x03, 0x32, 0x14, 0x0f}, 275 + {1400, 0x09, 0x03, 0x32, 0x14, 0x0f}, 276 + {1500, 0x0d, 0x42, 0x36, 0x0e, 0x0f}, 281 277 }; 282 278 283 279 static const ··· 412 372 u32 hs_exit, clk_post, clk_pre, wakeup, lpx, ta_go, ta_sure, ta_wait; 413 373 u32 hs_prepare, hs_trail, hs_zero, clk_lane_hs_zero, data_lane_hs_zero; 414 374 unsigned int i; 375 + u32 val; 415 376 416 377 timings = inno->pdata->inno_mipi_dphy_timing_table; 417 378 ··· 431 390 if (inno->pdata->max_rate == MAX_2_5GHZ) { 432 391 phy_update_bits(inno, REGISTER_PART_ANALOG, 0x08, 433 392 PLL_POST_DIV_ENABLE_MASK, PLL_POST_DIV_ENABLE); 393 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x0b, 394 + CLOCK_LANE_VOD_RANGE_SET_MASK, 395 + CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE)); 396 + } else if (inno->pdata->max_rate == MAX_1_5GHZ) { 397 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x18, 398 + LANE0_PRE_EMPHASIS_ENABLE_MASK, LANE0_PRE_EMPHASIS_ENABLE); 399 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x18, 400 + LANE1_PRE_EMPHASIS_ENABLE_MASK, LANE1_PRE_EMPHASIS_ENABLE); 401 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x19, 402 + PRE_EMPHASIS_RANGE_SET_MASK, 403 + PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE)); 404 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x1a, 405 + LANE0_PRE_EMPHASIS_RANGE_SET_MASK, 406 + LANE0_PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE)); 407 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x1b, 408 + LANE1_PRE_EMPHASIS_RANGE_SET_MASK, 409 + LANE1_PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE)); 434 410 phy_update_bits(inno, REGISTER_PART_ANALOG, 0x0b, 435 411 CLOCK_LANE_VOD_RANGE_SET_MASK, 436 412 CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE)); ··· 576 518 T_TA_WAIT_CNT(ta_wait)); 577 519 } 578 520 579 - /* Enable all lanes on analog part */ 521 + /* Enable lanes on analog part */ 522 + switch (inno->pdata->max_lanes) { 523 + case 1: 524 + val = LANE_EN_0; 525 + break; 526 + case 2: 527 + val = LANE_EN_0 | LANE_EN_1; 528 + break; 529 + case 3: 530 + val = LANE_EN_0 | LANE_EN_1 | LANE_EN_2; 531 + break; 532 + case 4: 533 + default: 534 + val = LANE_EN_0 | LANE_EN_1 | LANE_EN_2 | LANE_EN_3; 535 + break; 536 + } 537 + 580 538 phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00, 581 - LANE_EN_MASK, LANE_EN_CK | LANE_EN_3 | LANE_EN_2 | 582 - LANE_EN_1 | LANE_EN_0); 539 + LANE_EN_MASK, LANE_EN_CK | val); 583 540 } 584 541 585 542 static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno) ··· 753 680 .inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_1ghz, 754 681 .num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_1ghz), 755 682 .max_rate = MAX_1GHZ, 683 + .max_lanes = 4, 684 + }; 685 + 686 + static const struct inno_video_phy_plat_data max_1_5ghz_video_phy_plat_data = { 687 + .inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_1_5ghz, 688 + .num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_1_5ghz), 689 + .max_rate = MAX_1_5GHZ, 690 + .max_lanes = 2, 756 691 }; 757 692 758 693 static const struct inno_video_phy_plat_data max_2_5ghz_video_phy_plat_data = { 759 694 .inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_2_5ghz, 760 695 .num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_2_5ghz), 761 696 .max_rate = MAX_2_5GHZ, 697 + .max_lanes = 4, 762 698 }; 763 699 764 700 static int inno_dsidphy_probe(struct platform_device *pdev) ··· 849 767 }, { 850 768 .compatible = "rockchip,rk3368-dsi-dphy", 851 769 .data = &max_1ghz_video_phy_plat_data, 770 + }, { 771 + .compatible = "rockchip,rk3506-dsi-dphy", 772 + .data = &max_1_5ghz_video_phy_plat_data, 852 773 }, { 853 774 .compatible = "rockchip,rk3568-dsi-dphy", 854 775 .data = &max_2_5ghz_video_phy_plat_data,
+15
drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
··· 21 21 #define REF_CLOCK_100MHz (100 * HZ_PER_MHZ) 22 22 23 23 /* RK3528 COMBO PHY REG */ 24 + #define RK3528_PHYREG5 0x14 25 + #define RK3528_PHYREG5_GATE_TX_PCK_SEL BIT(3) 26 + #define RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF BIT(3) 24 27 #define RK3528_PHYREG6 0x18 25 28 #define RK3528_PHYREG6_PLL_KVCO GENMASK(12, 10) 26 29 #define RK3528_PHYREG6_PLL_KVCO_VALUE 0x2 ··· 105 102 106 103 #define RK3568_PHYREG18 0x44 107 104 #define RK3568_PHYREG18_PLL_LOOP 0x32 105 + 106 + #define RK3568_PHYREG30 0x74 107 + #define RK3568_PHYREG30_GATE_TX_PCK_SEL BIT(7) 108 + #define RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF BIT(7) 108 109 109 110 #define RK3568_PHYREG32 0x7C 110 111 #define RK3568_PHYREG32_SSC_MASK GENMASK(7, 4) ··· 511 504 case REF_CLOCK_100MHz: 512 505 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 513 506 if (priv->type == PHY_TYPE_PCIE) { 507 + /* Gate_tx_pck_sel length select for L1ss support */ 508 + rockchip_combphy_updatel(priv, RK3528_PHYREG5_GATE_TX_PCK_SEL, 509 + RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF, RK3528_PHYREG5); 510 + 514 511 /* PLL KVCO tuning fine */ 515 512 val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE); 516 513 rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val, ··· 668 657 case REF_CLOCK_100MHz: 669 658 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 670 659 if (priv->type == PHY_TYPE_PCIE) { 660 + /* Gate_tx_pck_sel length select for L1ss support */ 661 + rockchip_combphy_updatel(priv, RK3568_PHYREG30_GATE_TX_PCK_SEL, 662 + RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF, 663 + RK3568_PHYREG30); 671 664 /* PLL KVCO tuning fine */ 672 665 val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, 673 666 RK3568_PHYREG33_PLL_KVCO_VALUE);
+15 -12
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
··· 500 500 REG_SEQ0(CMN_REG(0043), 0x00), 501 501 REG_SEQ0(CMN_REG(0044), 0x46), 502 502 REG_SEQ0(CMN_REG(0045), 0x24), 503 - REG_SEQ0(CMN_REG(0046), 0xff), 504 503 REG_SEQ0(CMN_REG(0047), 0x00), 505 - REG_SEQ0(CMN_REG(0048), 0x44), 506 504 REG_SEQ0(CMN_REG(0049), 0xfa), 507 505 REG_SEQ0(CMN_REG(004a), 0x08), 508 506 REG_SEQ0(CMN_REG(004b), 0x00), ··· 573 575 REG_SEQ0(CMN_REG(0034), 0x00), 574 576 REG_SEQ0(CMN_REG(003d), 0x40), 575 577 REG_SEQ0(CMN_REG(0042), 0x78), 578 + REG_SEQ0(CMN_REG(0046), 0xdd), 579 + REG_SEQ0(CMN_REG(0048), 0x11), 576 580 REG_SEQ0(CMN_REG(004e), 0x34), 577 581 REG_SEQ0(CMN_REG(005c), 0x25), 578 582 REG_SEQ0(CMN_REG(005e), 0x4f), ··· 668 668 669 669 static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { 670 670 REG_SEQ0(LANE_REG(0312), 0x00), 671 - REG_SEQ0(LANE_REG(031e), 0x00), 672 671 REG_SEQ0(LANE_REG(0412), 0x00), 673 - REG_SEQ0(LANE_REG(041e), 0x00), 674 672 REG_SEQ0(LANE_REG(0512), 0x00), 675 - REG_SEQ0(LANE_REG(051e), 0x00), 676 673 REG_SEQ0(LANE_REG(0612), 0x00), 677 - REG_SEQ0(LANE_REG(061e), 0x08), 678 674 REG_SEQ0(LANE_REG(0303), 0x2f), 679 675 REG_SEQ0(LANE_REG(0403), 0x2f), 680 676 REG_SEQ0(LANE_REG(0503), 0x2f), ··· 683 687 REG_SEQ0(LANE_REG(0406), 0x1c), 684 688 REG_SEQ0(LANE_REG(0506), 0x1c), 685 689 REG_SEQ0(LANE_REG(0606), 0x1c), 690 + /* Keep Inter-Pair Skew in the limits */ 691 + REG_SEQ0(LANE_REG(031e), 0x02), 692 + REG_SEQ0(LANE_REG(041e), 0x02), 693 + REG_SEQ0(LANE_REG(051e), 0x02), 694 + REG_SEQ0(LANE_REG(061e), 0x0a), 686 695 }; 687 696 688 697 static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = { ··· 1038 1037 1039 1038 ret = rk_hdptx_post_enable_pll(hdptx); 1040 1039 if (!ret) 1041 - hdptx->hw_rate = hdptx->hdmi_cfg.tmds_char_rate; 1040 + hdptx->hw_rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, 1041 + hdptx->hdmi_cfg.bpc); 1042 1042 1043 1043 return ret; 1044 1044 } ··· 1897 1895 * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with 1898 1896 * a different rate argument. 1899 1897 */ 1900 - return hdptx->hdmi_cfg.tmds_char_rate; 1898 + return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, hdptx->hdmi_cfg.bpc); 1901 1899 } 1902 1900 1903 1901 static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate, 1904 1902 unsigned long parent_rate) 1905 1903 { 1906 1904 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); 1905 + unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8); 1907 1906 1908 1907 /* Revert any unlikely TMDS char rate change since round_rate() */ 1909 - if (hdptx->hdmi_cfg.tmds_char_rate != rate) { 1910 - dev_warn(hdptx->dev, "Reverting unexpected rate change from %lu to %llu\n", 1911 - rate, hdptx->hdmi_cfg.tmds_char_rate); 1912 - hdptx->hdmi_cfg.tmds_char_rate = rate; 1908 + if (hdptx->hdmi_cfg.tmds_char_rate != tmds_rate) { 1909 + dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n", 1910 + tmds_rate, hdptx->hdmi_cfg.tmds_char_rate); 1911 + hdptx->hdmi_cfg.tmds_char_rate = tmds_rate; 1913 1912 } 1914 1913 1915 1914 /*
+1 -1
drivers/phy/samsung/phy-exynos5-usbdrd.c
··· 1823 1823 phy_drd->orientation = orientation; 1824 1824 } 1825 1825 1826 - clk_bulk_disable(phy_drd->drv_data->n_clks, phy_drd->clks); 1826 + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); 1827 1827 1828 1828 return 0; 1829 1829 }
+28
drivers/phy/samsung/phy-gs101-ufs.c
··· 108 108 END_UFS_PHY_CFG, 109 109 }; 110 110 111 + static const struct samsung_ufs_phy_cfg tensor_gs101_post_h8_enter[] = { 112 + PHY_TRSV_REG_CFG_GS101(0x262, 0x08, PWR_MODE_ANY), 113 + PHY_TRSV_REG_CFG_GS101(0x265, 0x0A, PWR_MODE_ANY), 114 + PHY_COMN_REG_CFG(0x1, 0x8, PWR_MODE_ANY), 115 + PHY_COMN_REG_CFG(0x0, 0x86, PWR_MODE_ANY), 116 + PHY_COMN_REG_CFG(0x8, 0x60, PWR_MODE_HS_ANY), 117 + PHY_TRSV_REG_CFG_GS101(0x222, 0x08, PWR_MODE_HS_ANY), 118 + PHY_TRSV_REG_CFG_GS101(0x246, 0x01, PWR_MODE_HS_ANY), 119 + END_UFS_PHY_CFG, 120 + }; 121 + 122 + static const struct samsung_ufs_phy_cfg tensor_gs101_pre_h8_exit[] = { 123 + PHY_COMN_REG_CFG(0x0, 0xC6, PWR_MODE_ANY), 124 + PHY_COMN_REG_CFG(0x1, 0x0C, PWR_MODE_ANY), 125 + PHY_TRSV_REG_CFG_GS101(0x262, 0x00, PWR_MODE_ANY), 126 + PHY_TRSV_REG_CFG_GS101(0x265, 0x00, PWR_MODE_ANY), 127 + PHY_COMN_REG_CFG(0x8, 0xE0, PWR_MODE_HS_ANY), 128 + PHY_TRSV_REG_CFG_GS101(0x246, 0x03, PWR_MODE_HS_ANY), 129 + PHY_TRSV_REG_CFG_GS101(0x222, 0x18, PWR_MODE_HS_ANY), 130 + END_UFS_PHY_CFG, 131 + }; 132 + 111 133 static const struct samsung_ufs_phy_cfg *tensor_gs101_ufs_phy_cfgs[CFG_TAG_MAX] = { 112 134 [CFG_PRE_INIT] = tensor_gs101_pre_init_cfg, 113 135 [CFG_PRE_PWR_HS] = tensor_gs101_pre_pwr_hs_config, 114 136 [CFG_POST_PWR_HS] = tensor_gs101_post_pwr_hs_config, 137 + }; 138 + 139 + static const struct samsung_ufs_phy_cfg *tensor_gs101_hibern8_cfgs[] = { 140 + [CFG_POST_HIBERN8_ENTER] = tensor_gs101_post_h8_enter, 141 + [CFG_PRE_HIBERN8_EXIT] = tensor_gs101_pre_h8_exit, 115 142 }; 116 143 117 144 static const char * const tensor_gs101_ufs_phy_clks[] = { ··· 197 170 198 171 const struct samsung_ufs_phy_drvdata tensor_gs101_ufs_phy = { 199 172 .cfgs = tensor_gs101_ufs_phy_cfgs, 173 + .cfgs_hibern8 = tensor_gs101_hibern8_cfgs, 200 174 .isol = { 201 175 .offset = TENSOR_GS101_PHY_CTRL, 202 176 .mask = TENSOR_GS101_PHY_CTRL_MASK,
+40
drivers/phy/samsung/phy-samsung-ufs.c
··· 217 217 return 0; 218 218 } 219 219 220 + static int samsung_ufs_phy_notify_state(struct phy *phy, 221 + union phy_notify state) 222 + { 223 + struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy); 224 + const struct samsung_ufs_phy_cfg *cfg; 225 + int i, err = -EINVAL; 226 + 227 + if (!ufs_phy->cfgs_hibern8) 228 + return 0; 229 + 230 + if (state.ufs_state == PHY_UFS_HIBERN8_ENTER) 231 + cfg = ufs_phy->cfgs_hibern8[CFG_POST_HIBERN8_ENTER]; 232 + else if (state.ufs_state == PHY_UFS_HIBERN8_EXIT) 233 + cfg = ufs_phy->cfgs_hibern8[CFG_PRE_HIBERN8_EXIT]; 234 + else 235 + goto err_out; 236 + 237 + for_each_phy_cfg(cfg) { 238 + for_each_phy_lane(ufs_phy, i) { 239 + samsung_ufs_phy_config(ufs_phy, cfg, i); 240 + } 241 + } 242 + 243 + if (state.ufs_state == PHY_UFS_HIBERN8_EXIT) { 244 + for_each_phy_lane(ufs_phy, i) { 245 + if (ufs_phy->drvdata->wait_for_cdr) { 246 + err = ufs_phy->drvdata->wait_for_cdr(phy, i); 247 + if (err) 248 + goto err_out; 249 + } 250 + } 251 + } 252 + 253 + return 0; 254 + err_out: 255 + return err; 256 + } 257 + 220 258 static int samsung_ufs_phy_exit(struct phy *phy) 221 259 { 222 260 struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy); ··· 271 233 .power_off = samsung_ufs_phy_power_off, 272 234 .calibrate = samsung_ufs_phy_calibrate, 273 235 .set_mode = samsung_ufs_phy_set_mode, 236 + .notify_phystate = samsung_ufs_phy_notify_state, 274 237 .owner = THIS_MODULE, 275 238 }; 276 239 ··· 326 287 phy->dev = dev; 327 288 phy->drvdata = drvdata; 328 289 phy->cfgs = drvdata->cfgs; 290 + phy->cfgs_hibern8 = drvdata->cfgs_hibern8; 329 291 memcpy(&phy->isol, &drvdata->isol, sizeof(phy->isol)); 330 292 331 293 if (!of_property_read_u32_index(dev->of_node, "samsung,pmu-syscon", 1,
+7
drivers/phy/samsung/phy-samsung-ufs.h
··· 92 92 CFG_TAG_MAX, 93 93 }; 94 94 95 + enum { 96 + CFG_POST_HIBERN8_ENTER, 97 + CFG_PRE_HIBERN8_EXIT, 98 + }; 99 + 95 100 struct samsung_ufs_phy_cfg { 96 101 u32 off_0; 97 102 u32 off_1; ··· 113 108 114 109 struct samsung_ufs_phy_drvdata { 115 110 const struct samsung_ufs_phy_cfg **cfgs; 111 + const struct samsung_ufs_phy_cfg **cfgs_hibern8; 116 112 struct samsung_ufs_phy_pmu_isol isol; 117 113 const char * const *clk_list; 118 114 int num_clks; ··· 130 124 struct clk_bulk_data *clks; 131 125 const struct samsung_ufs_phy_drvdata *drvdata; 132 126 const struct samsung_ufs_phy_cfg * const *cfgs; 127 + const struct samsung_ufs_phy_cfg * const *cfgs_hibern8; 133 128 struct samsung_ufs_phy_pmu_isol isol; 134 129 u8 lane_cnt; 135 130 int ufs_phy_state;
-1
drivers/phy/sophgo/phy-cv1800-usb2.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/of.h> 13 13 #include <linux/of_address.h> 14 - #include <linux/of_gpio.h> 15 14 #include <linux/platform_device.h> 16 15 #include <linux/phy/phy.h> 17 16 #include <linux/regmap.h>
+1 -1
drivers/phy/ti/phy-gmii-sel.c
··· 341 341 if (priv->soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN) && 342 342 args->args_count < 2) 343 343 return ERR_PTR(-EINVAL); 344 - if (phy_id > priv->num_ports) 344 + if (phy_id < 1 || phy_id > priv->num_ports) 345 345 return ERR_PTR(-EINVAL); 346 346 if (phy_id != priv->if_phys[phy_id - 1].id) 347 347 return ERR_PTR(-EINVAL);
+19
include/linux/phy/phy.h
··· 53 53 PHY_MEDIA_DAC, 54 54 }; 55 55 56 + enum phy_ufs_state { 57 + PHY_UFS_HIBERN8_ENTER, 58 + PHY_UFS_HIBERN8_EXIT, 59 + }; 60 + 61 + union phy_notify { 62 + enum phy_ufs_state ufs_state; 63 + }; 64 + 56 65 /** 57 66 * union phy_configure_opts - Opaque generic phy configuration 58 67 * ··· 92 83 * @set_speed: set the speed of the phy (optional) 93 84 * @reset: resetting the phy 94 85 * @calibrate: calibrate the phy 86 + * @notify_phystate: notify and configure the phy for a particular state 95 87 * @release: ops to be performed while the consumer relinquishes the PHY 96 88 * @owner: the module owner containing the ops 97 89 */ ··· 142 132 int (*connect)(struct phy *phy, int port); 143 133 int (*disconnect)(struct phy *phy, int port); 144 134 135 + int (*notify_phystate)(struct phy *phy, union phy_notify state); 145 136 void (*release)(struct phy *phy); 146 137 struct module *owner; 147 138 }; ··· 266 255 int phy_calibrate(struct phy *phy); 267 256 int phy_notify_connect(struct phy *phy, int port); 268 257 int phy_notify_disconnect(struct phy *phy, int port); 258 + int phy_notify_state(struct phy *phy, union phy_notify state); 269 259 static inline int phy_get_bus_width(struct phy *phy) 270 260 { 271 261 return phy->attrs.bus_width; ··· 418 406 } 419 407 420 408 static inline int phy_notify_disconnect(struct phy *phy, int index) 409 + { 410 + if (!phy) 411 + return 0; 412 + return -ENOSYS; 413 + } 414 + 415 + static inline int phy_notify_state(struct phy *phy, union phy_notify state) 421 416 { 422 417 if (!phy) 423 418 return 0;