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

Merge tag 'phy-for-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into char-misc-next

Kishon writes:

phy: for 5.5

*) Add a new PHY driver for USB3 PHY on Allwinner H6 SoC
*) Add a new PHY driver for Innosilicon Video Combo PHY(MIPI/LVDS/TTL)
*) Add support in xusb-tegra210 PHY driver to get USB device mode functional
in Tegra 210
*) Add support for SM8150 QMP UFS PHY in phy-qcom-qmp PHY driver
*) Fix smatch warning (array off by one) in phy-rcar-gen2 PHY driver
*) Enable mac tx internal delay for rgmii-rxid in phy-gmii-sel driver
*) Fix phy-qcom-usb-hs from registering multiple extcon notifiers during PHY
power cycle
*) Use devm_platform_ioremap_resource() in phy-mvebu-a3700-utmi,
phy-hisi-inno-usb2, phy-histb-combphy and regulator_bulk_set_supply_names()
in xusb to simplify code
*) Remove unused variable in xusb-tegra210 and phy-dm816x-usb
*) Fix sparse warnings in phy-brcm-usb-init

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

* tag 'phy-for-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy: (28 commits)
phy: phy-rockchip-inno-usb2: add phy description for px30
phy: qcom-usb-hs: Fix extcon double register after power cycle
phy: renesas: phy-rcar-gen2: Fix the array off by one warning
phy: lantiq: vrx200-pcie: fix error return code in ltq_vrx200_pcie_phy_power_on()
dt-bindings: phy: add yaml binding for rockchip,px30-dsi-dphy
phy/rockchip: Add support for Innosilicon MIPI/LVDS/TTL PHY
phy: add PHY_MODE_LVDS
phy: allwinner: add phy driver for USB3 PHY on Allwinner H6 SoC
dt-bindings: Add bindings for USB3 phy on Allwinner H6
phy: qcom-qmp: Add SM8150 QMP UFS PHY support
dt-bindings: phy-qcom-qmp: Add sm8150 UFS phy compatible string
phy: ti: gmii-sel: fix mac tx internal delay for rgmii-rxid
phy: tegra: use regulator_bulk_set_supply_names()
phy: ti: dm816x: remove set but not used variable 'phy_data'
phy: renesas: rcar-gen3-usb2: Fix sysfs interface of "role"
phy: tegra: xusb: Add vbus override support on Tegra186
phy: tegra: xusb: Add vbus override support on Tegra210
phy: tegra: xusb: Add usb3 port fake support on Tegra210
phy: tegra: xusb: Add XUSB dual mode support on Tegra210
dt-bindings: rcar-gen3-phy-usb3: Add r8a774b1 support
...

+1645 -42
+47
Documentation/devicetree/bindings/phy/allwinner,sun50i-h6-usb3-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + # Copyright 2019 Ondrej Jirman <megous@megous.com> 3 + %YAML 1.2 4 + --- 5 + $id: "http://devicetree.org/schemas/phy/allwinner,sun50i-h6-usb3-phy.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: Allwinner H6 USB3 PHY 9 + 10 + maintainers: 11 + - Ondrej Jirman <megous@megous.com> 12 + 13 + properties: 14 + compatible: 15 + enum: 16 + - allwinner,sun50i-h6-usb3-phy 17 + 18 + reg: 19 + maxItems: 1 20 + 21 + clocks: 22 + maxItems: 1 23 + 24 + resets: 25 + maxItems: 1 26 + 27 + "#phy-cells": 28 + const: 0 29 + 30 + required: 31 + - compatible 32 + - reg 33 + - clocks 34 + - resets 35 + - "#phy-cells" 36 + 37 + examples: 38 + - | 39 + #include <dt-bindings/clock/sun50i-h6-ccu.h> 40 + #include <dt-bindings/reset/sun50i-h6-ccu.h> 41 + phy@5210000 { 42 + compatible = "allwinner,sun50i-h6-usb3-phy"; 43 + reg = <0x5210000 0x10000>; 44 + clocks = <&ccu CLK_USB_PHY1>; 45 + resets = <&ccu RST_USB_PHY1>; 46 + #phy-cells = <0>; 47 + };
+1
Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt
··· 2 2 3 3 Required properties (phy (parent) node): 4 4 - compatible : should be one of the listed compatibles: 5 + * "rockchip,px30-usb2phy" 5 6 * "rockchip,rk3228-usb2phy" 6 7 * "rockchip,rk3328-usb2phy" 7 8 * "rockchip,rk3366-usb2phy"
+6 -1
Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
··· 14 14 "qcom,msm8998-qmp-pcie-phy" for PCIe QMP phy on msm8998, 15 15 "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845, 16 16 "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845, 17 - "qcom,sdm845-qmp-ufs-phy" for UFS QMP phy on sdm845. 17 + "qcom,sdm845-qmp-ufs-phy" for UFS QMP phy on sdm845, 18 + "qcom,sm8150-qmp-ufs-phy" for UFS QMP phy on sm8150. 18 19 19 20 - reg: 20 21 - index 0: address and length of register set for PHY's common ··· 58 57 "aux", "cfg_ahb", "ref", "com_aux". 59 58 For "qcom,sdm845-qmp-ufs-phy" must contain: 60 59 "ref", "ref_aux". 60 + For "qcom,sm8150-qmp-ufs-phy" must contain: 61 + "ref", "ref_aux". 61 62 62 63 - resets: a list of phandles and reset controller specifier pairs, 63 64 one for each entry in reset-names. ··· 85 82 For "qcom,sdm845-qmp-usb3-uni-phy" must contain: 86 83 "phy", "common". 87 84 For "qcom,sdm845-qmp-ufs-phy": must contain: 85 + "ufsphy". 86 + For "qcom,sm8150-qmp-ufs-phy": must contain: 88 87 "ufsphy". 89 88 90 89 - vdda-phy-supply: Phandle to a regulator supply to PHY core block.
+2
Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
··· 10 10 SoC. 11 11 "renesas,usb2-phy-r8a774a1" if the device is a part of an R8A774A1 12 12 SoC. 13 + "renesas,usb2-phy-r8a774b1" if the device is a part of an R8A774B1 14 + SoC. 13 15 "renesas,usb2-phy-r8a774c0" if the device is a part of an R8A774C0 14 16 SoC. 15 17 "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795
+2
Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt
··· 9 9 Required properties: 10 10 - compatible: "renesas,r8a774a1-usb3-phy" if the device is a part of an R8A774A1 11 11 SoC. 12 + "renesas,r8a774b1-usb3-phy" if the device is a part of an R8A774B1 13 + SoC. 12 14 "renesas,r8a7795-usb3-phy" if the device is a part of an R8A7795 13 15 SoC. 14 16 "renesas,r8a7796-usb3-phy" if the device is a part of an R8A7796
+75
Documentation/devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/rockchip,px30-dsi-dphy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Rockchip MIPI DPHY with additional LVDS/TTL modes 8 + 9 + maintainers: 10 + - Heiko Stuebner <heiko@sntech.de> 11 + 12 + properties: 13 + "#phy-cells": 14 + const: 0 15 + 16 + "#clock-cells": 17 + const: 0 18 + 19 + compatible: 20 + enum: 21 + - rockchip,px30-dsi-dphy 22 + - rockchip,rk3128-dsi-dphy 23 + - rockchip,rk3368-dsi-dphy 24 + 25 + reg: 26 + maxItems: 1 27 + 28 + clocks: 29 + items: 30 + - description: PLL reference clock 31 + - description: Module clock 32 + 33 + clock-names: 34 + items: 35 + - const: ref 36 + - const: pclk 37 + 38 + power-domains: 39 + maxItems: 1 40 + description: phandle to the associated power domain 41 + 42 + resets: 43 + items: 44 + - description: exclusive PHY reset line 45 + 46 + reset-names: 47 + items: 48 + - const: apb 49 + 50 + required: 51 + - "#phy-cells" 52 + - "#clock-cells" 53 + - compatible 54 + - reg 55 + - clocks 56 + - clock-names 57 + - resets 58 + - reset-names 59 + 60 + additionalProperties: false 61 + 62 + examples: 63 + - | 64 + dsi_dphy: phy@ff2e0000 { 65 + compatible = "rockchip,px30-video-phy"; 66 + reg = <0x0 0xff2e0000 0x0 0x10000>; 67 + clocks = <&pmucru 13>, <&cru 12>; 68 + clock-names = "ref", "pclk"; 69 + #clock-cells = <0>; 70 + resets = <&cru 12>; 71 + reset-names = "apb"; 72 + #phy-cells = <0>; 73 + }; 74 + 75 + ...
+11
drivers/phy/allwinner/Kconfig
··· 45 45 sun9i SoCs. 46 46 47 47 This driver controls each individual USB 2 host PHY. 48 + 49 + config PHY_SUN50I_USB3 50 + tristate "Allwinner H6 SoC USB3 PHY driver" 51 + depends on ARCH_SUNXI && HAS_IOMEM && OF 52 + depends on RESET_CONTROLLER 53 + select GENERIC_PHY 54 + help 55 + Enable this to support the USB3.0-capable transceiver that is 56 + part of Allwinner H6 SoC. 57 + 58 + This driver controls each individual USB 2+3 host PHY combo.
+1
drivers/phy/allwinner/Makefile
··· 2 2 obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o 3 3 obj-$(CONFIG_PHY_SUN6I_MIPI_DPHY) += phy-sun6i-mipi-dphy.o 4 4 obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o 5 + obj-$(CONFIG_PHY_SUN50I_USB3) += phy-sun50i-usb3.o
+190
drivers/phy/allwinner/phy-sun50i-usb3.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Allwinner sun50i(H6) USB 3.0 phy driver 4 + * 5 + * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io> 6 + * 7 + * Based on phy-sun9i-usb.c, which is: 8 + * 9 + * Copyright (C) 2014-2015 Chen-Yu Tsai <wens@csie.org> 10 + * 11 + * Based on code from Allwinner BSP, which is: 12 + * 13 + * Copyright (c) 2010-2015 Allwinner Technology Co., Ltd. 14 + */ 15 + 16 + #include <linux/clk.h> 17 + #include <linux/err.h> 18 + #include <linux/io.h> 19 + #include <linux/module.h> 20 + #include <linux/phy/phy.h> 21 + #include <linux/platform_device.h> 22 + #include <linux/reset.h> 23 + 24 + /* Interface Status and Control Registers */ 25 + #define SUNXI_ISCR 0x00 26 + #define SUNXI_PIPE_CLOCK_CONTROL 0x14 27 + #define SUNXI_PHY_TUNE_LOW 0x18 28 + #define SUNXI_PHY_TUNE_HIGH 0x1c 29 + #define SUNXI_PHY_EXTERNAL_CONTROL 0x20 30 + 31 + /* USB2.0 Interface Status and Control Register */ 32 + #define SUNXI_ISCR_FORCE_VBUS (3 << 12) 33 + 34 + /* PIPE Clock Control Register */ 35 + #define SUNXI_PCC_PIPE_CLK_OPEN (1 << 6) 36 + 37 + /* PHY External Control Register */ 38 + #define SUNXI_PEC_EXTERN_VBUS (3 << 1) 39 + #define SUNXI_PEC_SSC_EN (1 << 24) 40 + #define SUNXI_PEC_REF_SSP_EN (1 << 26) 41 + 42 + /* PHY Tune High Register */ 43 + #define SUNXI_TX_DEEMPH_3P5DB(n) ((n) << 19) 44 + #define SUNXI_TX_DEEMPH_3P5DB_MASK GENMASK(24, 19) 45 + #define SUNXI_TX_DEEMPH_6DB(n) ((n) << 13) 46 + #define SUNXI_TX_DEEMPH_6GB_MASK GENMASK(18, 13) 47 + #define SUNXI_TX_SWING_FULL(n) ((n) << 6) 48 + #define SUNXI_TX_SWING_FULL_MASK GENMASK(12, 6) 49 + #define SUNXI_LOS_BIAS(n) ((n) << 3) 50 + #define SUNXI_LOS_BIAS_MASK GENMASK(5, 3) 51 + #define SUNXI_TXVBOOSTLVL(n) ((n) << 0) 52 + #define SUNXI_TXVBOOSTLVL_MASK GENMASK(0, 2) 53 + 54 + struct sun50i_usb3_phy { 55 + struct phy *phy; 56 + void __iomem *regs; 57 + struct reset_control *reset; 58 + struct clk *clk; 59 + }; 60 + 61 + static void sun50i_usb3_phy_open(struct sun50i_usb3_phy *phy) 62 + { 63 + u32 val; 64 + 65 + val = readl(phy->regs + SUNXI_PHY_EXTERNAL_CONTROL); 66 + val |= SUNXI_PEC_EXTERN_VBUS; 67 + val |= SUNXI_PEC_SSC_EN | SUNXI_PEC_REF_SSP_EN; 68 + writel(val, phy->regs + SUNXI_PHY_EXTERNAL_CONTROL); 69 + 70 + val = readl(phy->regs + SUNXI_PIPE_CLOCK_CONTROL); 71 + val |= SUNXI_PCC_PIPE_CLK_OPEN; 72 + writel(val, phy->regs + SUNXI_PIPE_CLOCK_CONTROL); 73 + 74 + val = readl(phy->regs + SUNXI_ISCR); 75 + val |= SUNXI_ISCR_FORCE_VBUS; 76 + writel(val, phy->regs + SUNXI_ISCR); 77 + 78 + /* 79 + * All the magic numbers written to the PHY_TUNE_{LOW_HIGH} 80 + * registers are directly taken from the BSP USB3 driver from 81 + * Allwiner. 82 + */ 83 + writel(0x0047fc87, phy->regs + SUNXI_PHY_TUNE_LOW); 84 + 85 + val = readl(phy->regs + SUNXI_PHY_TUNE_HIGH); 86 + val &= ~(SUNXI_TXVBOOSTLVL_MASK | SUNXI_LOS_BIAS_MASK | 87 + SUNXI_TX_SWING_FULL_MASK | SUNXI_TX_DEEMPH_6GB_MASK | 88 + SUNXI_TX_DEEMPH_3P5DB_MASK); 89 + val |= SUNXI_TXVBOOSTLVL(0x7); 90 + val |= SUNXI_LOS_BIAS(0x7); 91 + val |= SUNXI_TX_SWING_FULL(0x55); 92 + val |= SUNXI_TX_DEEMPH_6DB(0x20); 93 + val |= SUNXI_TX_DEEMPH_3P5DB(0x15); 94 + writel(val, phy->regs + SUNXI_PHY_TUNE_HIGH); 95 + } 96 + 97 + static int sun50i_usb3_phy_init(struct phy *_phy) 98 + { 99 + struct sun50i_usb3_phy *phy = phy_get_drvdata(_phy); 100 + int ret; 101 + 102 + ret = clk_prepare_enable(phy->clk); 103 + if (ret) 104 + return ret; 105 + 106 + ret = reset_control_deassert(phy->reset); 107 + if (ret) { 108 + clk_disable_unprepare(phy->clk); 109 + return ret; 110 + } 111 + 112 + sun50i_usb3_phy_open(phy); 113 + return 0; 114 + } 115 + 116 + static int sun50i_usb3_phy_exit(struct phy *_phy) 117 + { 118 + struct sun50i_usb3_phy *phy = phy_get_drvdata(_phy); 119 + 120 + reset_control_assert(phy->reset); 121 + clk_disable_unprepare(phy->clk); 122 + 123 + return 0; 124 + } 125 + 126 + static const struct phy_ops sun50i_usb3_phy_ops = { 127 + .init = sun50i_usb3_phy_init, 128 + .exit = sun50i_usb3_phy_exit, 129 + .owner = THIS_MODULE, 130 + }; 131 + 132 + static int sun50i_usb3_phy_probe(struct platform_device *pdev) 133 + { 134 + struct sun50i_usb3_phy *phy; 135 + struct device *dev = &pdev->dev; 136 + struct phy_provider *phy_provider; 137 + struct resource *res; 138 + 139 + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); 140 + if (!phy) 141 + return -ENOMEM; 142 + 143 + phy->clk = devm_clk_get(dev, NULL); 144 + if (IS_ERR(phy->clk)) { 145 + if (PTR_ERR(phy->clk) != -EPROBE_DEFER) 146 + dev_err(dev, "failed to get phy clock\n"); 147 + return PTR_ERR(phy->clk); 148 + } 149 + 150 + phy->reset = devm_reset_control_get(dev, NULL); 151 + if (IS_ERR(phy->reset)) { 152 + dev_err(dev, "failed to get reset control\n"); 153 + return PTR_ERR(phy->reset); 154 + } 155 + 156 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 157 + phy->regs = devm_ioremap_resource(dev, res); 158 + if (IS_ERR(phy->regs)) 159 + return PTR_ERR(phy->regs); 160 + 161 + phy->phy = devm_phy_create(dev, NULL, &sun50i_usb3_phy_ops); 162 + if (IS_ERR(phy->phy)) { 163 + dev_err(dev, "failed to create PHY\n"); 164 + return PTR_ERR(phy->phy); 165 + } 166 + 167 + phy_set_drvdata(phy->phy, phy); 168 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 169 + 170 + return PTR_ERR_OR_ZERO(phy_provider); 171 + } 172 + 173 + static const struct of_device_id sun50i_usb3_phy_of_match[] = { 174 + { .compatible = "allwinner,sun50i-h6-usb3-phy" }, 175 + { }, 176 + }; 177 + MODULE_DEVICE_TABLE(of, sun50i_usb3_phy_of_match); 178 + 179 + static struct platform_driver sun50i_usb3_phy_driver = { 180 + .probe = sun50i_usb3_phy_probe, 181 + .driver = { 182 + .of_match_table = sun50i_usb3_phy_of_match, 183 + .name = "sun50i-usb3-phy", 184 + } 185 + }; 186 + module_platform_driver(sun50i_usb3_phy_driver); 187 + 188 + MODULE_DESCRIPTION("Allwinner H6 USB 3.0 phy driver"); 189 + MODULE_AUTHOR("Icenowy Zheng <icenowy@aosc.io>"); 190 + MODULE_LICENSE("GPL");
+5 -5
drivers/phy/broadcom/phy-brcm-usb-init.c
··· 126 126 USB_CTRL_SELECTOR_COUNT, 127 127 }; 128 128 129 - #define USB_CTRL_REG(base, reg) ((void *)base + USB_CTRL_##reg) 130 - #define USB_XHCI_EC_REG(base, reg) ((void *)base + USB_XHCI_EC_##reg) 129 + #define USB_CTRL_REG(base, reg) ((void __iomem *)base + USB_CTRL_##reg) 130 + #define USB_XHCI_EC_REG(base, reg) ((void __iomem *)base + USB_XHCI_EC_##reg) 131 131 #define USB_CTRL_MASK(reg, field) \ 132 132 USB_CTRL_##reg##_##field##_MASK 133 133 #define USB_CTRL_MASK_FAMILY(params, reg, field) \ ··· 416 416 u32 reg_offset, u32 field) 417 417 { 418 418 u32 mask; 419 - void *reg; 419 + void __iomem *reg; 420 420 421 421 mask = params->usb_reg_bits_map[field]; 422 422 reg = params->ctrl_regs + reg_offset; ··· 428 428 u32 reg_offset, u32 field) 429 429 { 430 430 u32 mask; 431 - void *reg; 431 + void __iomem *reg; 432 432 433 433 mask = params->usb_reg_bits_map[field]; 434 434 reg = params->ctrl_regs + reg_offset; ··· 707 707 void __iomem *xhci_ec_base = params->xhci_ec_regs; 708 708 u32 val; 709 709 710 - if (params->family_id != 0x74371000 || xhci_ec_base == 0) 710 + if (params->family_id != 0x74371000 || !xhci_ec_base) 711 711 return; 712 712 brcmusb_writel(0xa20c, USB_XHCI_EC_REG(xhci_ec_base, IRAADR)); 713 713 val = brcmusb_readl(USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
+1 -3
drivers/phy/hisilicon/phy-hisi-inno-usb2.c
··· 114 114 struct hisi_inno_phy_priv *priv; 115 115 struct phy_provider *provider; 116 116 struct device_node *child; 117 - struct resource *res; 118 117 int i = 0; 119 118 int ret; 120 119 ··· 121 122 if (!priv) 122 123 return -ENOMEM; 123 124 124 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 125 - priv->mmio = devm_ioremap_resource(dev, res); 125 + priv->mmio = devm_platform_ioremap_resource(pdev, 0); 126 126 if (IS_ERR(priv->mmio)) { 127 127 ret = PTR_ERR(priv->mmio); 128 128 return ret;
+1 -3
drivers/phy/hisilicon/phy-histb-combphy.c
··· 195 195 struct histb_combphy_priv *priv; 196 196 struct device_node *np = dev->of_node; 197 197 struct histb_combphy_mode *mode; 198 - struct resource *res; 199 198 u32 vals[3]; 200 199 int ret; 201 200 ··· 202 203 if (!priv) 203 204 return -ENOMEM; 204 205 205 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 206 - priv->mmio = devm_ioremap_resource(dev, res); 206 + priv->mmio = devm_platform_ioremap_resource(pdev, 0); 207 207 if (IS_ERR(priv->mmio)) { 208 208 ret = PTR_ERR(priv->mmio); 209 209 return ret;
+2 -1
drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c
··· 323 323 goto err_disable_pdi_clk; 324 324 325 325 /* Check if we are in "startup ready" status */ 326 - if (ltq_vrx200_pcie_phy_wait_for_pll(phy) != 0) 326 + ret = ltq_vrx200_pcie_phy_wait_for_pll(phy); 327 + if (ret) 327 328 goto err_disable_phy_clk; 328 329 329 330 ltq_vrx200_pcie_phy_apply_workarounds(phy);
+1 -8
drivers/phy/marvell/phy-mvebu-a3700-utmi.c
··· 216 216 struct device *dev = &pdev->dev; 217 217 struct mvebu_a3700_utmi *utmi; 218 218 struct phy_provider *provider; 219 - struct resource *res; 220 219 221 220 utmi = devm_kzalloc(dev, sizeof(*utmi), GFP_KERNEL); 222 221 if (!utmi) 223 222 return -ENOMEM; 224 223 225 224 /* Get UTMI memory region */ 226 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 227 - if (!res) { 228 - dev_err(dev, "Missing UTMI PHY memory resource\n"); 229 - return -ENODEV; 230 - } 231 - 232 - utmi->regs = devm_ioremap_resource(dev, res); 225 + utmi->regs = devm_platform_ioremap_resource(pdev, 0); 233 226 if (IS_ERR(utmi->regs)) 234 227 return PTR_ERR(utmi->regs); 235 228
+1 -1
drivers/phy/phy-xgene.c
··· 1342 1342 static void xgene_phy_force_lat_summer_cal(struct xgene_phy_ctx *ctx, int lane) 1343 1343 { 1344 1344 int i; 1345 - struct { 1345 + static const struct { 1346 1346 u32 reg; 1347 1347 u32 val; 1348 1348 } serdes_reg[] = {
+120
drivers/phy/qualcomm/phy-qcom-qmp.c
··· 165 165 [QPHY_PCS_READY_STATUS] = 0x160, 166 166 }; 167 167 168 + static const unsigned int sm8150_ufsphy_regs_layout[] = { 169 + [QPHY_START_CTRL] = 0x00, 170 + [QPHY_PCS_READY_STATUS] = 0x180, 171 + }; 172 + 168 173 static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = { 169 174 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c), 170 175 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10), ··· 884 879 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13), 885 880 }; 886 881 882 + static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = { 883 + QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x01), 884 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9), 885 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11), 886 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00), 887 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01), 888 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02), 889 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f), 890 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00), 891 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11), 892 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82), 893 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06), 894 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16), 895 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36), 896 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff), 897 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c), 898 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac), 899 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e), 900 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98), 901 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06), 902 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16), 903 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36), 904 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32), 905 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f), 906 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd), 907 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23), 908 + 909 + /* Rate B */ 910 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06), 911 + }; 912 + 913 + static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = { 914 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06), 915 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03), 916 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01), 917 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00), 918 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05), 919 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c), 920 + }; 921 + 922 + static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = { 923 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24), 924 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f), 925 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), 926 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18), 927 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a), 928 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b), 929 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1), 930 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), 931 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80), 932 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c), 933 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04), 934 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b), 935 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), 936 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), 937 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d), 938 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00), 939 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10), 940 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0), 941 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00), 942 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36), 943 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36), 944 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6), 945 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b), 946 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d), 947 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0), 948 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8), 949 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8), 950 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b), 951 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1), 952 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0), 953 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8), 954 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8), 955 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b), 956 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1), 957 + 958 + }; 959 + 960 + static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = { 961 + QMP_PHY_INIT_CFG(QPHY_V4_RX_SIGDET_CTRL2, 0x6d), 962 + QMP_PHY_INIT_CFG(QPHY_V4_TX_LARGE_AMP_DRV_LVL, 0x0a), 963 + QMP_PHY_INIT_CFG(QPHY_V4_TX_SMALL_AMP_DRV_LVL, 0x02), 964 + QMP_PHY_INIT_CFG(QPHY_V4_TX_MID_TERM_CTRL1, 0x43), 965 + QMP_PHY_INIT_CFG(QPHY_V4_DEBUG_BUS_CLKSEL, 0x1f), 966 + QMP_PHY_INIT_CFG(QPHY_V4_RX_MIN_HIBERN8_TIME, 0xff), 967 + QMP_PHY_INIT_CFG(QPHY_V4_MULTI_LANE_CTRL1, 0x02), 968 + }; 887 969 888 970 /* struct qmp_phy_cfg - per-PHY initialization config */ 889 971 struct qmp_phy_cfg { ··· 1366 1274 .pwrdn_ctrl = SW_PWRDN, 1367 1275 1368 1276 .is_dual_lane_phy = true, 1277 + }; 1278 + 1279 + static const struct qmp_phy_cfg sm8150_ufsphy_cfg = { 1280 + .type = PHY_TYPE_UFS, 1281 + .nlanes = 2, 1282 + 1283 + .serdes_tbl = sm8150_ufsphy_serdes_tbl, 1284 + .serdes_tbl_num = ARRAY_SIZE(sm8150_ufsphy_serdes_tbl), 1285 + .tx_tbl = sm8150_ufsphy_tx_tbl, 1286 + .tx_tbl_num = ARRAY_SIZE(sm8150_ufsphy_tx_tbl), 1287 + .rx_tbl = sm8150_ufsphy_rx_tbl, 1288 + .rx_tbl_num = ARRAY_SIZE(sm8150_ufsphy_rx_tbl), 1289 + .pcs_tbl = sm8150_ufsphy_pcs_tbl, 1290 + .pcs_tbl_num = ARRAY_SIZE(sm8150_ufsphy_pcs_tbl), 1291 + .clk_list = sdm845_ufs_phy_clk_l, 1292 + .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), 1293 + .vreg_list = qmp_phy_vreg_l, 1294 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1295 + .regs = sm8150_ufsphy_regs_layout, 1296 + 1297 + .start_ctrl = SERDES_START, 1298 + .pwrdn_ctrl = SW_PWRDN, 1299 + 1300 + .is_dual_lane_phy = true, 1301 + .no_pcs_sw_reset = true, 1369 1302 }; 1370 1303 1371 1304 static void qcom_qmp_phy_configure(void __iomem *base, ··· 2115 1998 }, { 2116 1999 .compatible = "qcom,msm8998-qmp-usb3-phy", 2117 2000 .data = &msm8998_usb3phy_cfg, 2001 + }, { 2002 + .compatible = "qcom,sm8150-qmp-ufs-phy", 2003 + .data = &sm8150_ufsphy_cfg, 2118 2004 }, 2119 2005 { }, 2120 2006 };
+96
drivers/phy/qualcomm/phy-qcom-qmp.h
··· 313 313 #define QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG4 0x5c 314 314 #define QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG5 0x60 315 315 316 + /* Only for QMP V4 PHY - QSERDES COM registers */ 317 + #define QSERDES_V4_COM_PLL_IVCO 0x058 318 + #define QSERDES_V4_COM_CMN_IPTRIM 0x060 319 + #define QSERDES_V4_COM_CP_CTRL_MODE0 0x074 320 + #define QSERDES_V4_COM_CP_CTRL_MODE1 0x078 321 + #define QSERDES_V4_COM_PLL_RCTRL_MODE0 0x07c 322 + #define QSERDES_V4_COM_PLL_RCTRL_MODE1 0x080 323 + #define QSERDES_V4_COM_PLL_CCTRL_MODE0 0x084 324 + #define QSERDES_V4_COM_PLL_CCTRL_MODE1 0x088 325 + #define QSERDES_V4_COM_SYSCLK_EN_SEL 0x094 326 + #define QSERDES_V4_COM_LOCK_CMP_EN 0x0a4 327 + #define QSERDES_V4_COM_LOCK_CMP1_MODE0 0x0ac 328 + #define QSERDES_V4_COM_LOCK_CMP2_MODE0 0x0b0 329 + #define QSERDES_V4_COM_LOCK_CMP1_MODE1 0x0b4 330 + #define QSERDES_V4_COM_DEC_START_MODE0 0x0bc 331 + #define QSERDES_V4_COM_LOCK_CMP2_MODE1 0x0b8 332 + #define QSERDES_V4_COM_DEC_START_MODE1 0x0c4 333 + #define QSERDES_V4_COM_VCO_TUNE_MAP 0x10c 334 + #define QSERDES_V4_COM_VCO_TUNE_INITVAL2 0x124 335 + #define QSERDES_V4_COM_HSCLK_SEL 0x158 336 + #define QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL 0x15c 337 + #define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x1ac 338 + #define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x1b0 339 + #define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x1b4 340 + #define QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL 0x1bc 341 + #define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x1b8 342 + 343 + /* Only for QMP V4 PHY - TX registers */ 344 + #define QSERDES_V4_TX_LANE_MODE_1 0x84 345 + #define QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1 0xd8 346 + #define QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1 0xdC 347 + #define QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1 0xe0 348 + #define QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1 0xe4 349 + #define QSERDES_V4_TX_TRAN_DRVR_EMP_EN 0xb8 350 + 351 + /* Only for QMP V4 PHY - RX registers */ 352 + #define QSERDES_V4_RX_UCDR_FO_GAIN 0x008 353 + #define QSERDES_V4_RX_UCDR_SO_GAIN 0x014 354 + #define QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN 0x030 355 + #define QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034 356 + #define QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW 0x03c 357 + #define QSERDES_V4_RX_UCDR_PI_CONTROLS 0x044 358 + #define QSERDES_V4_RX_UCDR_PI_CTRL2 0x048 359 + #define QSERDES_V4_RX_AC_JTAG_ENABLE 0x068 360 + #define QSERDES_V4_RX_AC_JTAG_MODE 0x078 361 + #define QSERDES_V4_RX_RX_TERM_BW 0x080 362 + #define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2 0x0ec 363 + #define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3 0x0f0 364 + #define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4 0x0f4 365 + #define QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW 0x0f8 366 + #define QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH 0x0fc 367 + #define QSERDES_V4_RX_RX_IDAC_MEASURE_TIME 0x100 368 + #define QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x114 369 + #define QSERDES_V4_RX_SIGDET_CNTRL 0x11c 370 + #define QSERDES_V4_RX_SIGDET_LVL 0x120 371 + #define QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL 0x124 372 + #define QSERDES_V4_RX_RX_BAND 0x128 373 + #define QSERDES_V4_RX_RX_MODE_00_LOW 0x170 374 + #define QSERDES_V4_RX_RX_MODE_00_HIGH 0x174 375 + #define QSERDES_V4_RX_RX_MODE_00_HIGH2 0x178 376 + #define QSERDES_V4_RX_RX_MODE_00_HIGH3 0x17c 377 + #define QSERDES_V4_RX_RX_MODE_00_HIGH4 0x180 378 + #define QSERDES_V4_RX_RX_MODE_01_LOW 0x184 379 + #define QSERDES_V4_RX_RX_MODE_01_HIGH 0x188 380 + #define QSERDES_V4_RX_RX_MODE_01_HIGH2 0x18c 381 + #define QSERDES_V4_RX_RX_MODE_01_HIGH3 0x190 382 + #define QSERDES_V4_RX_RX_MODE_01_HIGH4 0x194 383 + #define QSERDES_V4_RX_RX_MODE_10_LOW 0x198 384 + #define QSERDES_V4_RX_RX_MODE_10_HIGH 0x19c 385 + #define QSERDES_V4_RX_RX_MODE_10_HIGH2 0x1a0 386 + #define QSERDES_V4_RX_RX_MODE_10_HIGH3 0x1a4 387 + #define QSERDES_V4_RX_RX_MODE_10_HIGH4 0x1a8 388 + #define QSERDES_V4_RX_DCC_CTRL1 0x1bc 389 + 390 + /* Only for QMP V4 PHY - PCS registers */ 391 + #define QPHY_V4_PHY_START 0x000 392 + #define QPHY_V4_POWER_DOWN_CONTROL 0x004 393 + #define QPHY_V4_SW_RESET 0x008 394 + #define QPHY_V4_TIMER_20US_CORECLK_STEPS_MSB 0x00c 395 + #define QPHY_V4_TIMER_20US_CORECLK_STEPS_LSB 0x010 396 + #define QPHY_V4_PLL_CNTL 0x02c 397 + #define QPHY_V4_TX_LARGE_AMP_DRV_LVL 0x030 398 + #define QPHY_V4_TX_SMALL_AMP_DRV_LVL 0x038 399 + #define QPHY_V4_BIST_FIXED_PAT_CTRL 0x060 400 + #define QPHY_V4_TX_HSGEAR_CAPABILITY 0x074 401 + #define QPHY_V4_RX_HSGEAR_CAPABILITY 0x0b4 402 + #define QPHY_V4_DEBUG_BUS_CLKSEL 0x124 403 + #define QPHY_V4_LINECFG_DISABLE 0x148 404 + #define QPHY_V4_RX_MIN_HIBERN8_TIME 0x150 405 + #define QPHY_V4_RX_SIGDET_CTRL2 0x158 406 + #define QPHY_V4_TX_PWM_GEAR_BAND 0x160 407 + #define QPHY_V4_TX_HS_GEAR_BAND 0x168 408 + #define QPHY_V4_PCS_READY_STATUS 0x180 409 + #define QPHY_V4_TX_MID_TERM_CTRL1 0x1d8 410 + #define QPHY_V4_MULTI_LANE_CTRL1 0x1e0 411 + 316 412 #endif
+5 -2
drivers/phy/qualcomm/phy-qcom-usb-hs.c
··· 158 158 /* setup initial state */ 159 159 qcom_usb_hs_phy_vbus_notifier(&uphy->vbus_notify, state, 160 160 uphy->vbus_edev); 161 - ret = devm_extcon_register_notifier(&ulpi->dev, uphy->vbus_edev, 162 - EXTCON_USB, &uphy->vbus_notify); 161 + ret = extcon_register_notifier(uphy->vbus_edev, EXTCON_USB, 162 + &uphy->vbus_notify); 163 163 if (ret) 164 164 goto err_ulpi; 165 165 } ··· 180 180 { 181 181 struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy); 182 182 183 + if (uphy->vbus_edev) 184 + extcon_unregister_notifier(uphy->vbus_edev, EXTCON_USB, 185 + &uphy->vbus_notify); 183 186 regulator_disable(uphy->v3p3); 184 187 regulator_disable(uphy->v1p8); 185 188 clk_disable_unprepare(uphy->sleep_clk);
+4 -1
drivers/phy/renesas/phy-rcar-gen2.c
··· 71 71 struct rcar_gen2_phy_data { 72 72 const struct phy_ops *gen2_phy_ops; 73 73 const u32 (*select_value)[PHYS_PER_CHANNEL]; 74 + const u32 num_channels; 74 75 }; 75 76 76 77 static int rcar_gen2_phy_init(struct phy *p) ··· 272 271 static const struct rcar_gen2_phy_data rcar_gen2_usb_phy_data = { 273 272 .gen2_phy_ops = &rcar_gen2_phy_ops, 274 273 .select_value = pci_select_value, 274 + .num_channels = ARRAY_SIZE(pci_select_value), 275 275 }; 276 276 277 277 static const struct rcar_gen2_phy_data rz_g1c_usb_phy_data = { 278 278 .gen2_phy_ops = &rz_g1c_phy_ops, 279 279 .select_value = usb20_select_value, 280 + .num_channels = ARRAY_SIZE(usb20_select_value), 280 281 }; 281 282 282 283 static const struct of_device_id rcar_gen2_phy_match_table[] = { ··· 392 389 channel->selected_phy = -1; 393 390 394 391 error = of_property_read_u32(np, "reg", &channel_num); 395 - if (error || channel_num > 2) { 392 + if (error || channel_num >= data->num_channels) { 396 393 dev_err(dev, "Invalid \"reg\" property\n"); 397 394 of_node_put(np); 398 395 return error;
+4 -3
drivers/phy/renesas/phy-rcar-gen3-usb2.c
··· 21 21 #include <linux/platform_device.h> 22 22 #include <linux/pm_runtime.h> 23 23 #include <linux/regulator/consumer.h> 24 + #include <linux/string.h> 24 25 #include <linux/usb/of.h> 25 26 #include <linux/workqueue.h> 26 27 ··· 321 320 if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch)) 322 321 return -EIO; 323 322 324 - if (!strncmp(buf, "host", strlen("host"))) 323 + if (sysfs_streq(buf, "host")) 325 324 new_mode = PHY_MODE_USB_HOST; 326 - else if (!strncmp(buf, "peripheral", strlen("peripheral"))) 325 + else if (sysfs_streq(buf, "peripheral")) 327 326 new_mode = PHY_MODE_USB_DEVICE; 328 327 else 329 328 return -EINVAL; ··· 615 614 return PTR_ERR(channel->base); 616 615 617 616 /* call request_irq for OTG */ 618 - irq = platform_get_irq(pdev, 0); 617 + irq = platform_get_irq_optional(pdev, 0); 619 618 if (irq >= 0) { 620 619 INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); 621 620 irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq,
+8
drivers/phy/rockchip/Kconfig
··· 35 35 help 36 36 Support for Rockchip USB2.0 PHY with Innosilicon IP block. 37 37 38 + config PHY_ROCKCHIP_INNO_DSIDPHY 39 + tristate "Rockchip Innosilicon MIPI/LVDS/TTL PHY driver" 40 + depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF 41 + select GENERIC_PHY 42 + help 43 + Enable this to support the Rockchip MIPI/LVDS/TTL PHY with 44 + Innosilicon IP block. 45 + 38 46 config PHY_ROCKCHIP_PCIE 39 47 tristate "Rockchip PCIe PHY Driver" 40 48 depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
+1
drivers/phy/rockchip/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o 3 3 obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o 4 + obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o 4 5 obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o 5 6 obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o 6 7 obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
+805
drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2018 Rockchip Electronics Co. Ltd. 4 + * 5 + * Author: Wyon Bi <bivvy.bi@rock-chips.com> 6 + */ 7 + 8 + #include <linux/kernel.h> 9 + #include <linux/clk.h> 10 + #include <linux/iopoll.h> 11 + #include <linux/clk-provider.h> 12 + #include <linux/delay.h> 13 + #include <linux/init.h> 14 + #include <linux/module.h> 15 + #include <linux/of_device.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/reset.h> 18 + #include <linux/phy/phy.h> 19 + #include <linux/pm_runtime.h> 20 + #include <linux/mfd/syscon.h> 21 + 22 + #define PSEC_PER_SEC 1000000000000LL 23 + 24 + #define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l))) 25 + 26 + /* 27 + * The offset address[7:0] is distributed two parts, one from the bit7 to bit5 28 + * is the first address, the other from the bit4 to bit0 is the second address. 29 + * when you configure the registers, you must set both of them. The Clock Lane 30 + * and Data Lane use the same registers with the same second address, but the 31 + * first address is different. 32 + */ 33 + #define FIRST_ADDRESS(x) (((x) & 0x7) << 5) 34 + #define SECOND_ADDRESS(x) (((x) & 0x1f) << 0) 35 + #define PHY_REG(first, second) (FIRST_ADDRESS(first) | \ 36 + SECOND_ADDRESS(second)) 37 + 38 + /* Analog Register Part: reg00 */ 39 + #define BANDGAP_POWER_MASK BIT(7) 40 + #define BANDGAP_POWER_DOWN BIT(7) 41 + #define BANDGAP_POWER_ON 0 42 + #define LANE_EN_MASK GENMASK(6, 2) 43 + #define LANE_EN_CK BIT(6) 44 + #define LANE_EN_3 BIT(5) 45 + #define LANE_EN_2 BIT(4) 46 + #define LANE_EN_1 BIT(3) 47 + #define LANE_EN_0 BIT(2) 48 + #define POWER_WORK_MASK GENMASK(1, 0) 49 + #define POWER_WORK_ENABLE UPDATE(1, 1, 0) 50 + #define POWER_WORK_DISABLE UPDATE(2, 1, 0) 51 + /* Analog Register Part: reg01 */ 52 + #define REG_SYNCRST_MASK BIT(2) 53 + #define REG_SYNCRST_RESET BIT(2) 54 + #define REG_SYNCRST_NORMAL 0 55 + #define REG_LDOPD_MASK BIT(1) 56 + #define REG_LDOPD_POWER_DOWN BIT(1) 57 + #define REG_LDOPD_POWER_ON 0 58 + #define REG_PLLPD_MASK BIT(0) 59 + #define REG_PLLPD_POWER_DOWN BIT(0) 60 + #define REG_PLLPD_POWER_ON 0 61 + /* Analog Register Part: reg03 */ 62 + #define REG_FBDIV_HI_MASK BIT(5) 63 + #define REG_FBDIV_HI(x) UPDATE((x >> 8), 5, 5) 64 + #define REG_PREDIV_MASK GENMASK(4, 0) 65 + #define REG_PREDIV(x) UPDATE(x, 4, 0) 66 + /* Analog Register Part: reg04 */ 67 + #define REG_FBDIV_LO_MASK GENMASK(7, 0) 68 + #define REG_FBDIV_LO(x) UPDATE(x, 7, 0) 69 + /* Analog Register Part: reg05 */ 70 + #define SAMPLE_CLOCK_PHASE_MASK GENMASK(6, 4) 71 + #define SAMPLE_CLOCK_PHASE(x) UPDATE(x, 6, 4) 72 + #define CLOCK_LANE_SKEW_PHASE_MASK GENMASK(2, 0) 73 + #define CLOCK_LANE_SKEW_PHASE(x) UPDATE(x, 2, 0) 74 + /* Analog Register Part: reg06 */ 75 + #define DATA_LANE_3_SKEW_PHASE_MASK GENMASK(6, 4) 76 + #define DATA_LANE_3_SKEW_PHASE(x) UPDATE(x, 6, 4) 77 + #define DATA_LANE_2_SKEW_PHASE_MASK GENMASK(2, 0) 78 + #define DATA_LANE_2_SKEW_PHASE(x) UPDATE(x, 2, 0) 79 + /* Analog Register Part: reg07 */ 80 + #define DATA_LANE_1_SKEW_PHASE_MASK GENMASK(6, 4) 81 + #define DATA_LANE_1_SKEW_PHASE(x) UPDATE(x, 6, 4) 82 + #define DATA_LANE_0_SKEW_PHASE_MASK GENMASK(2, 0) 83 + #define DATA_LANE_0_SKEW_PHASE(x) UPDATE(x, 2, 0) 84 + /* Analog Register Part: reg08 */ 85 + #define SAMPLE_CLOCK_DIRECTION_MASK BIT(4) 86 + #define SAMPLE_CLOCK_DIRECTION_REVERSE BIT(4) 87 + #define SAMPLE_CLOCK_DIRECTION_FORWARD 0 88 + /* Digital Register Part: reg00 */ 89 + #define REG_DIG_RSTN_MASK BIT(0) 90 + #define REG_DIG_RSTN_NORMAL BIT(0) 91 + #define REG_DIG_RSTN_RESET 0 92 + /* Digital Register Part: reg01 */ 93 + #define INVERT_TXCLKESC_MASK BIT(1) 94 + #define INVERT_TXCLKESC_ENABLE BIT(1) 95 + #define INVERT_TXCLKESC_DISABLE 0 96 + #define INVERT_TXBYTECLKHS_MASK BIT(0) 97 + #define INVERT_TXBYTECLKHS_ENABLE BIT(0) 98 + #define INVERT_TXBYTECLKHS_DISABLE 0 99 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg05 */ 100 + #define T_LPX_CNT_MASK GENMASK(5, 0) 101 + #define T_LPX_CNT(x) UPDATE(x, 5, 0) 102 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg06 */ 103 + #define T_HS_PREPARE_CNT_MASK GENMASK(6, 0) 104 + #define T_HS_PREPARE_CNT(x) UPDATE(x, 6, 0) 105 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg07 */ 106 + #define T_HS_ZERO_CNT_MASK GENMASK(5, 0) 107 + #define T_HS_ZERO_CNT(x) UPDATE(x, 5, 0) 108 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg08 */ 109 + #define T_HS_TRAIL_CNT_MASK GENMASK(6, 0) 110 + #define T_HS_TRAIL_CNT(x) UPDATE(x, 6, 0) 111 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg09 */ 112 + #define T_HS_EXIT_CNT_MASK GENMASK(4, 0) 113 + #define T_HS_EXIT_CNT(x) UPDATE(x, 4, 0) 114 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0a */ 115 + #define T_CLK_POST_CNT_MASK GENMASK(3, 0) 116 + #define T_CLK_POST_CNT(x) UPDATE(x, 3, 0) 117 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0c */ 118 + #define LPDT_TX_PPI_SYNC_MASK BIT(2) 119 + #define LPDT_TX_PPI_SYNC_ENABLE BIT(2) 120 + #define LPDT_TX_PPI_SYNC_DISABLE 0 121 + #define T_WAKEUP_CNT_HI_MASK GENMASK(1, 0) 122 + #define T_WAKEUP_CNT_HI(x) UPDATE(x, 1, 0) 123 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0d */ 124 + #define T_WAKEUP_CNT_LO_MASK GENMASK(7, 0) 125 + #define T_WAKEUP_CNT_LO(x) UPDATE(x, 7, 0) 126 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0e */ 127 + #define T_CLK_PRE_CNT_MASK GENMASK(3, 0) 128 + #define T_CLK_PRE_CNT(x) UPDATE(x, 3, 0) 129 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg10 */ 130 + #define T_TA_GO_CNT_MASK GENMASK(5, 0) 131 + #define T_TA_GO_CNT(x) UPDATE(x, 5, 0) 132 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg11 */ 133 + #define T_TA_SURE_CNT_MASK GENMASK(5, 0) 134 + #define T_TA_SURE_CNT(x) UPDATE(x, 5, 0) 135 + /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg12 */ 136 + #define T_TA_WAIT_CNT_MASK GENMASK(5, 0) 137 + #define T_TA_WAIT_CNT(x) UPDATE(x, 5, 0) 138 + /* LVDS Register Part: reg00 */ 139 + #define LVDS_DIGITAL_INTERNAL_RESET_MASK BIT(2) 140 + #define LVDS_DIGITAL_INTERNAL_RESET_DISABLE BIT(2) 141 + #define LVDS_DIGITAL_INTERNAL_RESET_ENABLE 0 142 + /* LVDS Register Part: reg01 */ 143 + #define LVDS_DIGITAL_INTERNAL_ENABLE_MASK BIT(7) 144 + #define LVDS_DIGITAL_INTERNAL_ENABLE BIT(7) 145 + #define LVDS_DIGITAL_INTERNAL_DISABLE 0 146 + /* LVDS Register Part: reg03 */ 147 + #define MODE_ENABLE_MASK GENMASK(2, 0) 148 + #define TTL_MODE_ENABLE BIT(2) 149 + #define LVDS_MODE_ENABLE BIT(1) 150 + #define MIPI_MODE_ENABLE BIT(0) 151 + /* LVDS Register Part: reg0b */ 152 + #define LVDS_LANE_EN_MASK GENMASK(7, 3) 153 + #define LVDS_DATA_LANE0_EN BIT(7) 154 + #define LVDS_DATA_LANE1_EN BIT(6) 155 + #define LVDS_DATA_LANE2_EN BIT(5) 156 + #define LVDS_DATA_LANE3_EN BIT(4) 157 + #define LVDS_CLK_LANE_EN BIT(3) 158 + #define LVDS_PLL_POWER_MASK BIT(2) 159 + #define LVDS_PLL_POWER_OFF BIT(2) 160 + #define LVDS_PLL_POWER_ON 0 161 + #define LVDS_BANDGAP_POWER_MASK BIT(0) 162 + #define LVDS_BANDGAP_POWER_DOWN BIT(0) 163 + #define LVDS_BANDGAP_POWER_ON 0 164 + 165 + #define DSI_PHY_RSTZ 0xa0 166 + #define PHY_ENABLECLK BIT(2) 167 + #define DSI_PHY_STATUS 0xb0 168 + #define PHY_LOCK BIT(0) 169 + 170 + struct mipi_dphy_timing { 171 + unsigned int clkmiss; 172 + unsigned int clkpost; 173 + unsigned int clkpre; 174 + unsigned int clkprepare; 175 + unsigned int clksettle; 176 + unsigned int clktermen; 177 + unsigned int clktrail; 178 + unsigned int clkzero; 179 + unsigned int dtermen; 180 + unsigned int eot; 181 + unsigned int hsexit; 182 + unsigned int hsprepare; 183 + unsigned int hszero; 184 + unsigned int hssettle; 185 + unsigned int hsskip; 186 + unsigned int hstrail; 187 + unsigned int init; 188 + unsigned int lpx; 189 + unsigned int taget; 190 + unsigned int tago; 191 + unsigned int tasure; 192 + unsigned int wakeup; 193 + }; 194 + 195 + struct inno_dsidphy { 196 + struct device *dev; 197 + struct clk *ref_clk; 198 + struct clk *pclk_phy; 199 + struct clk *pclk_host; 200 + void __iomem *phy_base; 201 + void __iomem *host_base; 202 + struct reset_control *rst; 203 + enum phy_mode mode; 204 + 205 + struct { 206 + struct clk_hw hw; 207 + u8 prediv; 208 + u16 fbdiv; 209 + unsigned long rate; 210 + } pll; 211 + }; 212 + 213 + enum { 214 + REGISTER_PART_ANALOG, 215 + REGISTER_PART_DIGITAL, 216 + REGISTER_PART_CLOCK_LANE, 217 + REGISTER_PART_DATA0_LANE, 218 + REGISTER_PART_DATA1_LANE, 219 + REGISTER_PART_DATA2_LANE, 220 + REGISTER_PART_DATA3_LANE, 221 + REGISTER_PART_LVDS, 222 + }; 223 + 224 + static inline struct inno_dsidphy *hw_to_inno(struct clk_hw *hw) 225 + { 226 + return container_of(hw, struct inno_dsidphy, pll.hw); 227 + } 228 + 229 + static void phy_update_bits(struct inno_dsidphy *inno, 230 + u8 first, u8 second, u8 mask, u8 val) 231 + { 232 + u32 reg = PHY_REG(first, second) << 2; 233 + unsigned int tmp, orig; 234 + 235 + orig = readl(inno->phy_base + reg); 236 + tmp = orig & ~mask; 237 + tmp |= val & mask; 238 + writel(tmp, inno->phy_base + reg); 239 + } 240 + 241 + static void mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing, 242 + unsigned long period) 243 + { 244 + /* Global Operation Timing Parameters */ 245 + timing->clkmiss = 0; 246 + timing->clkpost = 70000 + 52 * period; 247 + timing->clkpre = 8 * period; 248 + timing->clkprepare = 65000; 249 + timing->clksettle = 95000; 250 + timing->clktermen = 0; 251 + timing->clktrail = 80000; 252 + timing->clkzero = 260000; 253 + timing->dtermen = 0; 254 + timing->eot = 0; 255 + timing->hsexit = 120000; 256 + timing->hsprepare = 65000 + 4 * period; 257 + timing->hszero = 145000 + 6 * period; 258 + timing->hssettle = 85000 + 6 * period; 259 + timing->hsskip = 40000; 260 + timing->hstrail = max(8 * period, 60000 + 4 * period); 261 + timing->init = 100000000; 262 + timing->lpx = 60000; 263 + timing->taget = 5 * timing->lpx; 264 + timing->tago = 4 * timing->lpx; 265 + timing->tasure = 2 * timing->lpx; 266 + timing->wakeup = 1000000000; 267 + } 268 + 269 + static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno) 270 + { 271 + struct mipi_dphy_timing gotp; 272 + const struct { 273 + unsigned long rate; 274 + u8 hs_prepare; 275 + u8 clk_lane_hs_zero; 276 + u8 data_lane_hs_zero; 277 + u8 hs_trail; 278 + } timings[] = { 279 + { 110000000, 0x20, 0x16, 0x02, 0x22}, 280 + { 150000000, 0x06, 0x16, 0x03, 0x45}, 281 + { 200000000, 0x18, 0x17, 0x04, 0x0b}, 282 + { 250000000, 0x05, 0x17, 0x05, 0x16}, 283 + { 300000000, 0x51, 0x18, 0x06, 0x2c}, 284 + { 400000000, 0x64, 0x19, 0x07, 0x33}, 285 + { 500000000, 0x20, 0x1b, 0x07, 0x4e}, 286 + { 600000000, 0x6a, 0x1d, 0x08, 0x3a}, 287 + { 700000000, 0x3e, 0x1e, 0x08, 0x6a}, 288 + { 800000000, 0x21, 0x1f, 0x09, 0x29}, 289 + {1000000000, 0x09, 0x20, 0x09, 0x27}, 290 + }; 291 + u32 t_txbyteclkhs, t_txclkesc, ui; 292 + u32 txbyteclkhs, txclkesc, esc_clk_div; 293 + u32 hs_exit, clk_post, clk_pre, wakeup, lpx, ta_go, ta_sure, ta_wait; 294 + u32 hs_prepare, hs_trail, hs_zero, clk_lane_hs_zero, data_lane_hs_zero; 295 + unsigned int i; 296 + 297 + /* Select MIPI mode */ 298 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x03, 299 + MODE_ENABLE_MASK, MIPI_MODE_ENABLE); 300 + /* Configure PLL */ 301 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x03, 302 + REG_PREDIV_MASK, REG_PREDIV(inno->pll.prediv)); 303 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x03, 304 + REG_FBDIV_HI_MASK, REG_FBDIV_HI(inno->pll.fbdiv)); 305 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x04, 306 + REG_FBDIV_LO_MASK, REG_FBDIV_LO(inno->pll.fbdiv)); 307 + /* Enable PLL and LDO */ 308 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x01, 309 + REG_LDOPD_MASK | REG_PLLPD_MASK, 310 + REG_LDOPD_POWER_ON | REG_PLLPD_POWER_ON); 311 + /* Reset analog */ 312 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x01, 313 + REG_SYNCRST_MASK, REG_SYNCRST_RESET); 314 + udelay(1); 315 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x01, 316 + REG_SYNCRST_MASK, REG_SYNCRST_NORMAL); 317 + /* Reset digital */ 318 + phy_update_bits(inno, REGISTER_PART_DIGITAL, 0x00, 319 + REG_DIG_RSTN_MASK, REG_DIG_RSTN_RESET); 320 + udelay(1); 321 + phy_update_bits(inno, REGISTER_PART_DIGITAL, 0x00, 322 + REG_DIG_RSTN_MASK, REG_DIG_RSTN_NORMAL); 323 + 324 + txbyteclkhs = inno->pll.rate / 8; 325 + t_txbyteclkhs = div_u64(PSEC_PER_SEC, txbyteclkhs); 326 + 327 + esc_clk_div = DIV_ROUND_UP(txbyteclkhs, 20000000); 328 + txclkesc = txbyteclkhs / esc_clk_div; 329 + t_txclkesc = div_u64(PSEC_PER_SEC, txclkesc); 330 + 331 + ui = div_u64(PSEC_PER_SEC, inno->pll.rate); 332 + 333 + memset(&gotp, 0, sizeof(gotp)); 334 + mipi_dphy_timing_get_default(&gotp, ui); 335 + 336 + /* 337 + * The value of counter for HS Ths-exit 338 + * Ths-exit = Tpin_txbyteclkhs * value 339 + */ 340 + hs_exit = DIV_ROUND_UP(gotp.hsexit, t_txbyteclkhs); 341 + /* 342 + * The value of counter for HS Tclk-post 343 + * Tclk-post = Tpin_txbyteclkhs * value 344 + */ 345 + clk_post = DIV_ROUND_UP(gotp.clkpost, t_txbyteclkhs); 346 + /* 347 + * The value of counter for HS Tclk-pre 348 + * Tclk-pre = Tpin_txbyteclkhs * value 349 + */ 350 + clk_pre = DIV_ROUND_UP(gotp.clkpre, t_txbyteclkhs); 351 + 352 + /* 353 + * The value of counter for HS Tlpx Time 354 + * Tlpx = Tpin_txbyteclkhs * (2 + value) 355 + */ 356 + lpx = DIV_ROUND_UP(gotp.lpx, t_txbyteclkhs); 357 + if (lpx >= 2) 358 + lpx -= 2; 359 + 360 + /* 361 + * The value of counter for HS Tta-go 362 + * Tta-go for turnaround 363 + * Tta-go = Ttxclkesc * value 364 + */ 365 + ta_go = DIV_ROUND_UP(gotp.tago, t_txclkesc); 366 + /* 367 + * The value of counter for HS Tta-sure 368 + * Tta-sure for turnaround 369 + * Tta-sure = Ttxclkesc * value 370 + */ 371 + ta_sure = DIV_ROUND_UP(gotp.tasure, t_txclkesc); 372 + /* 373 + * The value of counter for HS Tta-wait 374 + * Tta-wait for turnaround 375 + * Tta-wait = Ttxclkesc * value 376 + */ 377 + ta_wait = DIV_ROUND_UP(gotp.taget, t_txclkesc); 378 + 379 + for (i = 0; i < ARRAY_SIZE(timings); i++) 380 + if (inno->pll.rate <= timings[i].rate) 381 + break; 382 + 383 + if (i == ARRAY_SIZE(timings)) 384 + --i; 385 + 386 + hs_prepare = timings[i].hs_prepare; 387 + hs_trail = timings[i].hs_trail; 388 + clk_lane_hs_zero = timings[i].clk_lane_hs_zero; 389 + data_lane_hs_zero = timings[i].data_lane_hs_zero; 390 + wakeup = 0x3ff; 391 + 392 + for (i = REGISTER_PART_CLOCK_LANE; i <= REGISTER_PART_DATA3_LANE; i++) { 393 + if (i == REGISTER_PART_CLOCK_LANE) 394 + hs_zero = clk_lane_hs_zero; 395 + else 396 + hs_zero = data_lane_hs_zero; 397 + 398 + phy_update_bits(inno, i, 0x05, T_LPX_CNT_MASK, 399 + T_LPX_CNT(lpx)); 400 + phy_update_bits(inno, i, 0x06, T_HS_PREPARE_CNT_MASK, 401 + T_HS_PREPARE_CNT(hs_prepare)); 402 + phy_update_bits(inno, i, 0x07, T_HS_ZERO_CNT_MASK, 403 + T_HS_ZERO_CNT(hs_zero)); 404 + phy_update_bits(inno, i, 0x08, T_HS_TRAIL_CNT_MASK, 405 + T_HS_TRAIL_CNT(hs_trail)); 406 + phy_update_bits(inno, i, 0x09, T_HS_EXIT_CNT_MASK, 407 + T_HS_EXIT_CNT(hs_exit)); 408 + phy_update_bits(inno, i, 0x0a, T_CLK_POST_CNT_MASK, 409 + T_CLK_POST_CNT(clk_post)); 410 + phy_update_bits(inno, i, 0x0e, T_CLK_PRE_CNT_MASK, 411 + T_CLK_PRE_CNT(clk_pre)); 412 + phy_update_bits(inno, i, 0x0c, T_WAKEUP_CNT_HI_MASK, 413 + T_WAKEUP_CNT_HI(wakeup >> 8)); 414 + phy_update_bits(inno, i, 0x0d, T_WAKEUP_CNT_LO_MASK, 415 + T_WAKEUP_CNT_LO(wakeup)); 416 + phy_update_bits(inno, i, 0x10, T_TA_GO_CNT_MASK, 417 + T_TA_GO_CNT(ta_go)); 418 + phy_update_bits(inno, i, 0x11, T_TA_SURE_CNT_MASK, 419 + T_TA_SURE_CNT(ta_sure)); 420 + phy_update_bits(inno, i, 0x12, T_TA_WAIT_CNT_MASK, 421 + T_TA_WAIT_CNT(ta_wait)); 422 + } 423 + 424 + /* Enable all lanes on analog part */ 425 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00, 426 + LANE_EN_MASK, LANE_EN_CK | LANE_EN_3 | LANE_EN_2 | 427 + LANE_EN_1 | LANE_EN_0); 428 + } 429 + 430 + static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno) 431 + { 432 + u8 prediv = 2; 433 + u16 fbdiv = 28; 434 + 435 + /* Sample clock reverse direction */ 436 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x08, 437 + SAMPLE_CLOCK_DIRECTION_MASK, 438 + SAMPLE_CLOCK_DIRECTION_REVERSE); 439 + 440 + /* Select LVDS mode */ 441 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x03, 442 + MODE_ENABLE_MASK, LVDS_MODE_ENABLE); 443 + /* Configure PLL */ 444 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x03, 445 + REG_PREDIV_MASK, REG_PREDIV(prediv)); 446 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x03, 447 + REG_FBDIV_HI_MASK, REG_FBDIV_HI(fbdiv)); 448 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x04, 449 + REG_FBDIV_LO_MASK, REG_FBDIV_LO(fbdiv)); 450 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x08, 0xff, 0xfc); 451 + /* Enable PLL and Bandgap */ 452 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x0b, 453 + LVDS_PLL_POWER_MASK | LVDS_BANDGAP_POWER_MASK, 454 + LVDS_PLL_POWER_ON | LVDS_BANDGAP_POWER_ON); 455 + 456 + msleep(20); 457 + 458 + /* Reset LVDS digital logic */ 459 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x00, 460 + LVDS_DIGITAL_INTERNAL_RESET_MASK, 461 + LVDS_DIGITAL_INTERNAL_RESET_ENABLE); 462 + udelay(1); 463 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x00, 464 + LVDS_DIGITAL_INTERNAL_RESET_MASK, 465 + LVDS_DIGITAL_INTERNAL_RESET_DISABLE); 466 + /* Enable LVDS digital logic */ 467 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x01, 468 + LVDS_DIGITAL_INTERNAL_ENABLE_MASK, 469 + LVDS_DIGITAL_INTERNAL_ENABLE); 470 + /* Enable LVDS analog driver */ 471 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x0b, 472 + LVDS_LANE_EN_MASK, LVDS_CLK_LANE_EN | 473 + LVDS_DATA_LANE0_EN | LVDS_DATA_LANE1_EN | 474 + LVDS_DATA_LANE2_EN | LVDS_DATA_LANE3_EN); 475 + } 476 + 477 + static int inno_dsidphy_power_on(struct phy *phy) 478 + { 479 + struct inno_dsidphy *inno = phy_get_drvdata(phy); 480 + 481 + clk_prepare_enable(inno->pclk_phy); 482 + pm_runtime_get_sync(inno->dev); 483 + 484 + /* Bandgap power on */ 485 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00, 486 + BANDGAP_POWER_MASK, BANDGAP_POWER_ON); 487 + /* Enable power work */ 488 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00, 489 + POWER_WORK_MASK, POWER_WORK_ENABLE); 490 + 491 + switch (inno->mode) { 492 + case PHY_MODE_MIPI_DPHY: 493 + inno_dsidphy_mipi_mode_enable(inno); 494 + break; 495 + case PHY_MODE_LVDS: 496 + inno_dsidphy_lvds_mode_enable(inno); 497 + break; 498 + default: 499 + return -EINVAL; 500 + } 501 + 502 + return 0; 503 + } 504 + 505 + static int inno_dsidphy_power_off(struct phy *phy) 506 + { 507 + struct inno_dsidphy *inno = phy_get_drvdata(phy); 508 + 509 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00, LANE_EN_MASK, 0); 510 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x01, 511 + REG_LDOPD_MASK | REG_PLLPD_MASK, 512 + REG_LDOPD_POWER_DOWN | REG_PLLPD_POWER_DOWN); 513 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00, 514 + POWER_WORK_MASK, POWER_WORK_DISABLE); 515 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00, 516 + BANDGAP_POWER_MASK, BANDGAP_POWER_DOWN); 517 + 518 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x0b, LVDS_LANE_EN_MASK, 0); 519 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x01, 520 + LVDS_DIGITAL_INTERNAL_ENABLE_MASK, 521 + LVDS_DIGITAL_INTERNAL_DISABLE); 522 + phy_update_bits(inno, REGISTER_PART_LVDS, 0x0b, 523 + LVDS_PLL_POWER_MASK | LVDS_BANDGAP_POWER_MASK, 524 + LVDS_PLL_POWER_OFF | LVDS_BANDGAP_POWER_DOWN); 525 + 526 + pm_runtime_put(inno->dev); 527 + clk_disable_unprepare(inno->pclk_phy); 528 + 529 + return 0; 530 + } 531 + 532 + static int inno_dsidphy_set_mode(struct phy *phy, enum phy_mode mode, 533 + int submode) 534 + { 535 + struct inno_dsidphy *inno = phy_get_drvdata(phy); 536 + 537 + switch (mode) { 538 + case PHY_MODE_MIPI_DPHY: 539 + case PHY_MODE_LVDS: 540 + inno->mode = mode; 541 + break; 542 + default: 543 + return -EINVAL; 544 + } 545 + 546 + return 0; 547 + } 548 + 549 + static const struct phy_ops inno_dsidphy_ops = { 550 + .set_mode = inno_dsidphy_set_mode, 551 + .power_on = inno_dsidphy_power_on, 552 + .power_off = inno_dsidphy_power_off, 553 + .owner = THIS_MODULE, 554 + }; 555 + 556 + static unsigned long inno_dsidphy_pll_round_rate(struct inno_dsidphy *inno, 557 + unsigned long prate, 558 + unsigned long rate, 559 + u8 *prediv, u16 *fbdiv) 560 + { 561 + unsigned long best_freq = 0; 562 + unsigned long fref, fout; 563 + u8 min_prediv, max_prediv; 564 + u8 _prediv, best_prediv = 1; 565 + u16 _fbdiv, best_fbdiv = 1; 566 + u32 min_delta = UINT_MAX; 567 + 568 + /* 569 + * The PLL output frequency can be calculated using a simple formula: 570 + * PLL_Output_Frequency = (FREF / PREDIV * FBDIV) / 2 571 + * PLL_Output_Frequency: it is equal to DDR-Clock-Frequency * 2 572 + */ 573 + fref = prate / 2; 574 + if (rate > 1000000000UL) 575 + fout = 1000000000UL; 576 + else 577 + fout = rate; 578 + 579 + /* 5Mhz < Fref / prediv < 40MHz */ 580 + min_prediv = DIV_ROUND_UP(fref, 40000000); 581 + max_prediv = fref / 5000000; 582 + 583 + for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) { 584 + u64 tmp; 585 + u32 delta; 586 + 587 + tmp = (u64)fout * _prediv; 588 + do_div(tmp, fref); 589 + _fbdiv = tmp; 590 + 591 + /* 592 + * The possible settings of feedback divider are 593 + * 12, 13, 14, 16, ~ 511 594 + */ 595 + if (_fbdiv == 15) 596 + continue; 597 + 598 + if (_fbdiv < 12 || _fbdiv > 511) 599 + continue; 600 + 601 + tmp = (u64)_fbdiv * fref; 602 + do_div(tmp, _prediv); 603 + 604 + delta = abs(fout - tmp); 605 + if (!delta) { 606 + best_prediv = _prediv; 607 + best_fbdiv = _fbdiv; 608 + best_freq = tmp; 609 + break; 610 + } else if (delta < min_delta) { 611 + best_prediv = _prediv; 612 + best_fbdiv = _fbdiv; 613 + best_freq = tmp; 614 + min_delta = delta; 615 + } 616 + } 617 + 618 + if (best_freq) { 619 + *prediv = best_prediv; 620 + *fbdiv = best_fbdiv; 621 + } 622 + 623 + return best_freq; 624 + } 625 + 626 + static long inno_dsidphy_pll_clk_round_rate(struct clk_hw *hw, 627 + unsigned long rate, 628 + unsigned long *prate) 629 + { 630 + struct inno_dsidphy *inno = hw_to_inno(hw); 631 + unsigned long fout; 632 + u16 fbdiv = 1; 633 + u8 prediv = 1; 634 + 635 + fout = inno_dsidphy_pll_round_rate(inno, *prate, rate, 636 + &prediv, &fbdiv); 637 + 638 + return fout; 639 + } 640 + 641 + static int inno_dsidphy_pll_clk_set_rate(struct clk_hw *hw, 642 + unsigned long rate, 643 + unsigned long parent_rate) 644 + { 645 + struct inno_dsidphy *inno = hw_to_inno(hw); 646 + unsigned long fout; 647 + u16 fbdiv = 1; 648 + u8 prediv = 1; 649 + 650 + fout = inno_dsidphy_pll_round_rate(inno, parent_rate, rate, 651 + &prediv, &fbdiv); 652 + 653 + dev_dbg(inno->dev, "fin=%lu, fout=%lu, prediv=%u, fbdiv=%u\n", 654 + parent_rate, fout, prediv, fbdiv); 655 + 656 + inno->pll.prediv = prediv; 657 + inno->pll.fbdiv = fbdiv; 658 + inno->pll.rate = fout; 659 + 660 + return 0; 661 + } 662 + 663 + static unsigned long 664 + inno_dsidphy_pll_clk_recalc_rate(struct clk_hw *hw, unsigned long prate) 665 + { 666 + struct inno_dsidphy *inno = hw_to_inno(hw); 667 + 668 + /* PLL_Output_Frequency = (FREF / PREDIV * FBDIV) / 2 */ 669 + return (prate / inno->pll.prediv * inno->pll.fbdiv) / 2; 670 + } 671 + 672 + static const struct clk_ops inno_dsidphy_pll_clk_ops = { 673 + .round_rate = inno_dsidphy_pll_clk_round_rate, 674 + .set_rate = inno_dsidphy_pll_clk_set_rate, 675 + .recalc_rate = inno_dsidphy_pll_clk_recalc_rate, 676 + }; 677 + 678 + static int inno_dsidphy_pll_register(struct inno_dsidphy *inno) 679 + { 680 + struct device *dev = inno->dev; 681 + struct clk *clk; 682 + const char *parent_name; 683 + struct clk_init_data init; 684 + int ret; 685 + 686 + parent_name = __clk_get_name(inno->ref_clk); 687 + 688 + init.name = "mipi_dphy_pll"; 689 + ret = of_property_read_string(dev->of_node, "clock-output-names", 690 + &init.name); 691 + if (ret < 0) 692 + dev_dbg(dev, "phy should set clock-output-names property\n"); 693 + 694 + init.ops = &inno_dsidphy_pll_clk_ops; 695 + init.parent_names = &parent_name; 696 + init.num_parents = 1; 697 + init.flags = 0; 698 + 699 + inno->pll.hw.init = &init; 700 + clk = devm_clk_register(dev, &inno->pll.hw); 701 + if (IS_ERR(clk)) { 702 + ret = PTR_ERR(clk); 703 + dev_err(dev, "failed to register PLL: %d\n", ret); 704 + return ret; 705 + } 706 + 707 + return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, 708 + &inno->pll.hw); 709 + } 710 + 711 + static int inno_dsidphy_probe(struct platform_device *pdev) 712 + { 713 + struct device *dev = &pdev->dev; 714 + struct inno_dsidphy *inno; 715 + struct phy_provider *phy_provider; 716 + struct phy *phy; 717 + int ret; 718 + 719 + inno = devm_kzalloc(dev, sizeof(*inno), GFP_KERNEL); 720 + if (!inno) 721 + return -ENOMEM; 722 + 723 + inno->dev = dev; 724 + platform_set_drvdata(pdev, inno); 725 + 726 + inno->phy_base = devm_platform_ioremap_resource(pdev, 0); 727 + if (!inno->phy_base) 728 + return -ENOMEM; 729 + 730 + inno->ref_clk = devm_clk_get(dev, "ref"); 731 + if (IS_ERR(inno->ref_clk)) { 732 + ret = PTR_ERR(inno->ref_clk); 733 + dev_err(dev, "failed to get ref clock: %d\n", ret); 734 + return ret; 735 + } 736 + 737 + inno->pclk_phy = devm_clk_get(dev, "pclk"); 738 + if (IS_ERR(inno->pclk_phy)) { 739 + ret = PTR_ERR(inno->pclk_phy); 740 + dev_err(dev, "failed to get phy pclk: %d\n", ret); 741 + return ret; 742 + } 743 + 744 + inno->rst = devm_reset_control_get(dev, "apb"); 745 + if (IS_ERR(inno->rst)) { 746 + ret = PTR_ERR(inno->rst); 747 + dev_err(dev, "failed to get system reset control: %d\n", ret); 748 + return ret; 749 + } 750 + 751 + phy = devm_phy_create(dev, NULL, &inno_dsidphy_ops); 752 + if (IS_ERR(phy)) { 753 + ret = PTR_ERR(phy); 754 + dev_err(dev, "failed to create phy: %d\n", ret); 755 + return ret; 756 + } 757 + 758 + phy_set_drvdata(phy, inno); 759 + 760 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 761 + if (IS_ERR(phy_provider)) { 762 + ret = PTR_ERR(phy_provider); 763 + dev_err(dev, "failed to register phy provider: %d\n", ret); 764 + return ret; 765 + } 766 + 767 + ret = inno_dsidphy_pll_register(inno); 768 + if (ret) 769 + return ret; 770 + 771 + pm_runtime_enable(dev); 772 + 773 + return 0; 774 + } 775 + 776 + static int inno_dsidphy_remove(struct platform_device *pdev) 777 + { 778 + struct inno_dsidphy *inno = platform_get_drvdata(pdev); 779 + 780 + pm_runtime_disable(inno->dev); 781 + 782 + return 0; 783 + } 784 + 785 + static const struct of_device_id inno_dsidphy_of_match[] = { 786 + { .compatible = "rockchip,px30-dsi-dphy", }, 787 + { .compatible = "rockchip,rk3128-dsi-dphy", }, 788 + { .compatible = "rockchip,rk3368-dsi-dphy", }, 789 + {} 790 + }; 791 + MODULE_DEVICE_TABLE(of, inno_dsidphy_of_match); 792 + 793 + static struct platform_driver inno_dsidphy_driver = { 794 + .driver = { 795 + .name = "inno-dsidphy", 796 + .of_match_table = of_match_ptr(inno_dsidphy_of_match), 797 + }, 798 + .probe = inno_dsidphy_probe, 799 + .remove = inno_dsidphy_remove, 800 + }; 801 + module_platform_driver(inno_dsidphy_driver); 802 + 803 + MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>"); 804 + MODULE_DESCRIPTION("Innosilicon MIPI/LVDS/TTL Video Combo PHY driver"); 805 + MODULE_LICENSE("GPL v2");
+1
drivers/phy/rockchip/phy-rockchip-inno-usb2.c
··· 1423 1423 }; 1424 1424 1425 1425 static const struct of_device_id rockchip_usb2phy_dt_match[] = { 1426 + { .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs }, 1426 1427 { .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs }, 1427 1428 { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs }, 1428 1429 { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
+23
drivers/phy/tegra/xusb-tegra186.c
··· 857 857 { 858 858 } 859 859 860 + static int tegra186_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl, 861 + bool status) 862 + { 863 + u32 value; 864 + 865 + dev_dbg(padctl->dev, "%s vbus override\n", status ? "set" : "clear"); 866 + 867 + value = padctl_readl(padctl, USB2_VBUS_ID); 868 + 869 + if (status) { 870 + value |= VBUS_OVERRIDE; 871 + value &= ~ID_OVERRIDE(~0); 872 + value |= ID_OVERRIDE_FLOATING; 873 + } else { 874 + value &= ~VBUS_OVERRIDE; 875 + } 876 + 877 + padctl_writel(padctl, value, USB2_VBUS_ID); 878 + 879 + return 0; 880 + } 881 + 860 882 static const struct tegra_xusb_padctl_ops tegra186_xusb_padctl_ops = { 861 883 .probe = tegra186_xusb_padctl_probe, 862 884 .remove = tegra186_xusb_padctl_remove, 885 + .vbus_override = tegra186_xusb_padctl_vbus_override, 863 886 }; 864 887 865 888 static const char * const tegra186_xusb_padctl_supply_names[] = {
+132 -5
drivers/phy/tegra/xusb-tegra210.c
··· 39 39 #define XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB 0x1 40 40 41 41 #define XUSB_PADCTL_USB2_PORT_CAP 0x008 42 + #define XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_DISABLED(x) (0x0 << ((x) * 4)) 42 43 #define XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_HOST(x) (0x1 << ((x) * 4)) 44 + #define XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_DEVICE(x) (0x2 << ((x) * 4)) 45 + #define XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_OTG(x) (0x3 << ((x) * 4)) 43 46 #define XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_MASK(x) (0x3 << ((x) * 4)) 44 47 45 48 #define XUSB_PADCTL_SS_PORT_MAP 0x014 ··· 50 47 #define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_SHIFT(x) ((x) * 5) 51 48 #define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(x) (0x7 << ((x) * 5)) 52 49 #define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(x, v) (((v) & 0x7) << ((x) * 5)) 50 + #define XUSB_PADCTL_SS_PORT_MAP_PORT_DISABLED 0x7 53 51 54 52 #define XUSB_PADCTL_ELPG_PROGRAM1 0x024 55 53 #define XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_VCORE_DOWN (1 << 31) ··· 65 61 #define XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(x) (1 << (1 + (x))) 66 62 #define XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(x) (1 << (8 + (x))) 67 63 64 + #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL0(x) (0x080 + (x) * 0x40) 65 + #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL0_ZIP (1 << 18) 66 + #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL0_ZIN (1 << 22) 67 + 68 68 #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(x) (0x084 + (x) * 0x40) 69 69 #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_SHIFT 7 70 70 #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_MASK 0x3 71 + #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_VAL 0x1 71 72 #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_FIX18 (1 << 6) 72 73 73 74 #define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x088 + (x) * 0x40) ··· 230 221 231 222 #define XUSB_PADCTL_UPHY_USB3_PADX_ECTL6(x) (0xa74 + (x) * 0x40) 232 223 #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL6_RX_EQ_CTRL_H_VAL 0xfcf01368 224 + 225 + #define XUSB_PADCTL_USB2_VBUS_ID 0xc60 226 + #define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON (1 << 14) 227 + #define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT 18 228 + #define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK 0xf 229 + #define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING 8 233 230 234 231 struct tegra210_xusb_fuse_calibration { 235 232 u32 hs_curr_level[4]; ··· 955 940 956 941 priv = to_tegra210_xusb_padctl(padctl); 957 942 943 + if (port->usb3_port_fake != -1) { 944 + value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP); 945 + value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK( 946 + port->usb3_port_fake); 947 + value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP( 948 + port->usb3_port_fake, index); 949 + padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP); 950 + 951 + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); 952 + value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_VCORE_DOWN( 953 + port->usb3_port_fake); 954 + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); 955 + 956 + usleep_range(100, 200); 957 + 958 + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); 959 + value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN_EARLY( 960 + port->usb3_port_fake); 961 + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); 962 + 963 + usleep_range(100, 200); 964 + 965 + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); 966 + value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN( 967 + port->usb3_port_fake); 968 + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); 969 + } 970 + 958 971 value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); 959 972 value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_MASK << 960 973 XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT) | ··· 1000 957 1001 958 value = padctl_readl(padctl, XUSB_PADCTL_USB2_PORT_CAP); 1002 959 value &= ~XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_MASK(index); 1003 - value |= XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_HOST(index); 960 + if (port->mode == USB_DR_MODE_UNKNOWN) 961 + value |= XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_DISABLED(index); 962 + else if (port->mode == USB_DR_MODE_PERIPHERAL) 963 + value |= XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_DEVICE(index); 964 + else if (port->mode == USB_DR_MODE_HOST) 965 + value |= XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_HOST(index); 966 + else if (port->mode == USB_DR_MODE_OTG) 967 + value |= XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_OTG(index); 1004 968 padctl_writel(padctl, value, XUSB_PADCTL_USB2_PORT_CAP); 1005 969 1006 970 value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); ··· 1039 989 XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); 1040 990 value &= ~(XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_MASK << 1041 991 XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_SHIFT); 1042 - value |= XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_FIX18; 992 + if (port->mode == USB_DR_MODE_HOST) 993 + value |= XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_FIX18; 994 + else 995 + value |= 996 + XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_VAL << 997 + XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_SHIFT; 1043 998 padctl_writel(padctl, value, 1044 999 XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); 1045 1000 ··· 1116 1061 } 1117 1062 1118 1063 mutex_lock(&padctl->lock); 1064 + 1065 + if (port->usb3_port_fake != -1) { 1066 + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); 1067 + value |= XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN_EARLY( 1068 + port->usb3_port_fake); 1069 + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); 1070 + 1071 + usleep_range(100, 200); 1072 + 1073 + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); 1074 + value |= XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN( 1075 + port->usb3_port_fake); 1076 + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); 1077 + 1078 + usleep_range(250, 350); 1079 + 1080 + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); 1081 + value |= XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_VCORE_DOWN( 1082 + port->usb3_port_fake); 1083 + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); 1084 + 1085 + value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP); 1086 + value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(port->usb3_port_fake, 1087 + XUSB_PADCTL_SS_PORT_MAP_PORT_DISABLED); 1088 + padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP); 1089 + } 1119 1090 1120 1091 if (WARN_ON(pad->enable == 0)) 1121 1092 goto out; ··· 1306 1225 struct tegra_xusb_hsic_lane *hsic = to_hsic_lane(lane); 1307 1226 struct tegra_xusb_hsic_pad *pad = to_hsic_pad(lane->pad); 1308 1227 struct tegra_xusb_padctl *padctl = lane->pad->padctl; 1309 - struct tegra210_xusb_padctl *priv; 1310 1228 unsigned int index = lane->index; 1311 1229 u32 value; 1312 1230 int err; 1313 - 1314 - priv = to_tegra210_xusb_padctl(padctl); 1315 1231 1316 1232 err = regulator_enable(pad->supply); 1317 1233 if (err) ··· 2023 1945 .map = tegra210_usb3_port_map, 2024 1946 }; 2025 1947 1948 + static int tegra210_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl, 1949 + bool status) 1950 + { 1951 + u32 value; 1952 + 1953 + dev_dbg(padctl->dev, "%s vbus override\n", status ? "set" : "clear"); 1954 + 1955 + value = padctl_readl(padctl, XUSB_PADCTL_USB2_VBUS_ID); 1956 + 1957 + if (status) { 1958 + value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON; 1959 + value &= ~(XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK << 1960 + XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT); 1961 + value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING << 1962 + XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT; 1963 + } else { 1964 + value &= ~XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON; 1965 + } 1966 + 1967 + padctl_writel(padctl, value, XUSB_PADCTL_USB2_VBUS_ID); 1968 + 1969 + return 0; 1970 + } 1971 + 1972 + static int tegra210_utmi_port_reset(struct phy *phy) 1973 + { 1974 + struct tegra_xusb_padctl *padctl; 1975 + struct tegra_xusb_lane *lane; 1976 + u32 value; 1977 + 1978 + lane = phy_get_drvdata(phy); 1979 + padctl = lane->pad->padctl; 1980 + 1981 + value = padctl_readl(padctl, 1982 + XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL0(lane->index)); 1983 + 1984 + if ((value & XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL0_ZIP) || 1985 + (value & XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL0_ZIN)) { 1986 + tegra210_xusb_padctl_vbus_override(padctl, false); 1987 + tegra210_xusb_padctl_vbus_override(padctl, true); 1988 + return 1; 1989 + } 1990 + 1991 + return 0; 1992 + } 1993 + 2026 1994 static int 2027 1995 tegra210_xusb_read_fuse_calibration(struct tegra210_xusb_fuse_calibration *fuse) 2028 1996 { ··· 2131 2007 .remove = tegra210_xusb_padctl_remove, 2132 2008 .usb3_set_lfps_detect = tegra210_usb3_set_lfps_detect, 2133 2009 .hsic_set_idle = tegra210_hsic_set_idle, 2010 + .vbus_override = tegra210_xusb_padctl_vbus_override, 2011 + .utmi_port_reset = tegra210_utmi_port_reset, 2134 2012 }; 2135 2013 2136 2014 static const char * const tegra210_xusb_padctl_supply_names[] = { ··· 2162 2036 .ops = &tegra210_xusb_padctl_ops, 2163 2037 .supply_names = tegra210_xusb_padctl_supply_names, 2164 2038 .num_supplies = ARRAY_SIZE(tegra210_xusb_padctl_supply_names), 2039 + .need_fake_usb3_port = true, 2165 2040 }; 2166 2041 EXPORT_SYMBOL_GPL(tegra210_xusb_padctl_soc); 2167 2042
+90 -3
drivers/phy/tegra/xusb.c
··· 800 800 } 801 801 } 802 802 803 + static int tegra_xusb_find_unused_usb3_port(struct tegra_xusb_padctl *padctl) 804 + { 805 + struct device_node *np; 806 + unsigned int i; 807 + 808 + for (i = 0; i < padctl->soc->ports.usb3.count; i++) { 809 + np = tegra_xusb_find_port_node(padctl, "usb3", i); 810 + if (!np || !of_device_is_available(np)) 811 + return i; 812 + } 813 + 814 + return -ENODEV; 815 + } 816 + 817 + static bool tegra_xusb_port_is_companion(struct tegra_xusb_usb2_port *usb2) 818 + { 819 + unsigned int i; 820 + struct tegra_xusb_usb3_port *usb3; 821 + struct tegra_xusb_padctl *padctl = usb2->base.padctl; 822 + 823 + for (i = 0; i < padctl->soc->ports.usb3.count; i++) { 824 + usb3 = tegra_xusb_find_usb3_port(padctl, i); 825 + if (usb3 && usb3->port == usb2->base.index) 826 + return true; 827 + } 828 + 829 + return false; 830 + } 831 + 832 + static int tegra_xusb_update_usb3_fake_port(struct tegra_xusb_usb2_port *usb2) 833 + { 834 + int fake; 835 + 836 + /* Disable usb3_port_fake usage by default and assign if needed */ 837 + usb2->usb3_port_fake = -1; 838 + 839 + if ((usb2->mode == USB_DR_MODE_OTG || 840 + usb2->mode == USB_DR_MODE_PERIPHERAL) && 841 + !tegra_xusb_port_is_companion(usb2)) { 842 + fake = tegra_xusb_find_unused_usb3_port(usb2->base.padctl); 843 + if (fake < 0) { 844 + dev_err(&usb2->base.dev, "no unused USB3 ports available\n"); 845 + return -ENODEV; 846 + } 847 + 848 + dev_dbg(&usb2->base.dev, "Found unused usb3 port: %d\n", fake); 849 + usb2->usb3_port_fake = fake; 850 + } 851 + 852 + return 0; 853 + } 854 + 803 855 static int tegra_xusb_setup_ports(struct tegra_xusb_padctl *padctl) 804 856 { 805 857 struct tegra_xusb_port *port; 858 + struct tegra_xusb_usb2_port *usb2; 806 859 unsigned int i; 807 860 int err = 0; 808 861 ··· 883 830 err = tegra_xusb_add_usb3_port(padctl, i); 884 831 if (err < 0) 885 832 goto remove_ports; 833 + } 834 + 835 + if (padctl->soc->need_fake_usb3_port) { 836 + for (i = 0; i < padctl->soc->ports.usb2.count; i++) { 837 + usb2 = tegra_xusb_find_usb2_port(padctl, i); 838 + if (!usb2) 839 + continue; 840 + 841 + err = tegra_xusb_update_usb3_fake_port(usb2); 842 + if (err < 0) 843 + goto remove_ports; 844 + } 886 845 } 887 846 888 847 list_for_each_entry(port, &padctl->ports, list) { ··· 927 862 struct tegra_xusb_padctl *padctl; 928 863 const struct of_device_id *match; 929 864 struct resource *res; 930 - unsigned int i; 931 865 int err; 932 866 933 867 /* for backwards compatibility with old device trees */ ··· 971 907 goto remove; 972 908 } 973 909 974 - for (i = 0; i < padctl->soc->num_supplies; i++) 975 - padctl->supplies[i].supply = padctl->soc->supply_names[i]; 910 + regulator_bulk_set_supply_names(padctl->supplies, 911 + padctl->soc->supply_names, 912 + padctl->soc->num_supplies); 976 913 977 914 err = devm_regulator_bulk_get(&pdev->dev, padctl->soc->num_supplies, 978 915 padctl->supplies); ··· 1120 1055 return -ENOSYS; 1121 1056 } 1122 1057 EXPORT_SYMBOL_GPL(tegra_xusb_padctl_usb3_set_lfps_detect); 1058 + 1059 + int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl, 1060 + bool val) 1061 + { 1062 + if (padctl->soc->ops->vbus_override) 1063 + return padctl->soc->ops->vbus_override(padctl, val); 1064 + 1065 + return -ENOTSUPP; 1066 + } 1067 + EXPORT_SYMBOL_GPL(tegra_xusb_padctl_set_vbus_override); 1068 + 1069 + int tegra_phy_xusb_utmi_port_reset(struct phy *phy) 1070 + { 1071 + struct tegra_xusb_lane *lane = phy_get_drvdata(phy); 1072 + struct tegra_xusb_padctl *padctl = lane->pad->padctl; 1073 + 1074 + if (padctl->soc->ops->utmi_port_reset) 1075 + return padctl->soc->ops->utmi_port_reset(phy); 1076 + 1077 + return -ENOTSUPP; 1078 + } 1079 + EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_port_reset); 1123 1080 1124 1081 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 1125 1082 MODULE_DESCRIPTION("Tegra XUSB Pad Controller driver");
+4
drivers/phy/tegra/xusb.h
··· 291 291 struct regulator *supply; 292 292 enum usb_dr_mode mode; 293 293 bool internal; 294 + int usb3_port_fake; 294 295 }; 295 296 296 297 static inline struct tegra_xusb_usb2_port * ··· 373 372 unsigned int index, bool idle); 374 373 int (*usb3_set_lfps_detect)(struct tegra_xusb_padctl *padctl, 375 374 unsigned int index, bool enable); 375 + int (*vbus_override)(struct tegra_xusb_padctl *padctl, bool set); 376 + int (*utmi_port_reset)(struct phy *phy); 376 377 }; 377 378 378 379 struct tegra_xusb_padctl_soc { ··· 392 389 393 390 const char * const *supply_names; 394 391 unsigned int num_supplies; 392 + bool need_fake_usb3_port; 395 393 }; 396 394 397 395 struct tegra_xusb_padctl {
-3
drivers/phy/ti/phy-dm816x-usb.c
··· 189 189 struct phy_provider *phy_provider; 190 190 struct usb_otg *otg; 191 191 const struct of_device_id *of_id; 192 - const struct usb_phy_data *phy_data; 193 192 int error; 194 193 195 194 of_id = of_match_device(of_match_ptr(dm816x_usb_phy_id_table), ··· 218 219 phy->usbphy_ctrl = (res->start & 0xff) + 4; 219 220 if (phy->usbphy_ctrl == 0x2c) 220 221 phy->instance = 1; 221 - 222 - phy_data = of_id->data; 223 222 224 223 otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); 225 224 if (!otg)
+1 -1
drivers/phy/ti/phy-gmii-sel.c
··· 69 69 break; 70 70 71 71 case PHY_INTERFACE_MODE_RGMII: 72 + case PHY_INTERFACE_MODE_RGMII_RXID: 72 73 gmii_sel_mode = AM33XX_GMII_SEL_MODE_RGMII; 73 74 break; 74 75 75 76 case PHY_INTERFACE_MODE_RGMII_ID: 76 - case PHY_INTERFACE_MODE_RGMII_RXID: 77 77 case PHY_INTERFACE_MODE_RGMII_TXID: 78 78 gmii_sel_mode = AM33XX_GMII_SEL_MODE_RGMII; 79 79 rgmii_id = 1;
+2 -1
include/linux/phy/phy.h
··· 38 38 PHY_MODE_PCIE, 39 39 PHY_MODE_ETHERNET, 40 40 PHY_MODE_MIPI_DPHY, 41 - PHY_MODE_SATA 41 + PHY_MODE_SATA, 42 + PHY_MODE_LVDS, 42 43 }; 43 44 44 45 /**
+3 -1
include/linux/phy/tegra/xusb.h
··· 18 18 unsigned int port, bool idle); 19 19 int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl, 20 20 unsigned int port, bool enable); 21 - 21 + int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl, 22 + bool val); 23 + int tegra_phy_xusb_utmi_port_reset(struct phy *phy); 22 24 #endif /* PHY_TEGRA_XUSB_H */