Commit 8053d2ff authored by Linus Torvalds's avatar Linus Torvalds

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

Pull generic phy updates from Vinod Koul:
 "New HW Support:
   - Support for Embedded DisplayPort and DisplayPort submodes and
     driver support on Qualcomm X1E80100 edp driver
   - Qualcomm QMP UFS PHY for SM8475, QMP USB phy for QDU1000/QRU1000
     and eusb2-repeater for SMB2360
   - Samsung HDMI PHY for i.MX8MP, gs101 UFS phy
   - Mediatek XFI T-PHY support for mt7988
   - Rockchip usbdp combo phy driver

  Updates:
   - Qualcomm x4 lane EP support for sa8775p, v4 ad v6 support for
     X1E80100, SM8650 tables for UFS Gear 4 & 5 and correct voltage
     swing tables
   - Freescale imx8m-pci pcie link-up updates
   - Rockchip rx-common-refclk-mode support
   - More platform remove callback returning void conversions"

* tag 'phy-for-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (43 commits)
  dt-bindings: phy: qcom,usb-snps-femto-v2: use correct fallback for sc8180x
  dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: fix msm899[68] power-domains
  dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: fix x1e80100-gen3x2 schema
  phy: qcpm-qmp-usb: Add support for QDU1000/QRU1000
  dt-bindings: phy: qcom,qmp-usb: Add QDU1000 USB3 PHY
  dt-bindings: phy: qcom,usb-snps-femto-v2: Add bindings for QDU1000
  phy: qcom-qmp-pcie: add x4 lane EP support for sa8775p
  phy: samsung-ufs: ufs: exit on first reported error
  phy: samsung-ufs: ufs: remove superfluous mfd/syscon.h header
  phy: rockchip: fix CONFIG_TYPEC dependency
  phy: rockchip: usbdp: fix uninitialized variable
  phy: rockchip-snps-pcie3: add support for rockchip,rx-common-refclk-mode
  dt-bindings: phy: rockchip,pcie3-phy: add rockchip,rx-common-refclk-mode
  phy: rockchip: add usbdp combo phy driver
  dt-bindings: phy: add rockchip usbdp combo phy document
  phy: add driver for MediaTek XFI T-PHY
  dt-bindings: phy: mediatek,mt7988-xfi-tphy: add new bindings
  phy: freescale: fsl-samsung-hdmi: Convert to platform remove callback returning void
  phy: qcom: qmp-ufs: update SM8650 tables for Gear 4 & 5
  MAINTAINERS: Add phy-gs101-ufs file to Tensor GS101.
  ...
parents d4e034b4 960b3f02
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/fsl,imx8mp-hdmi-phy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8MP HDMI PHY
maintainers:
- Lucas Stach <l.stach@pengutronix.de>
properties:
compatible:
enum:
- fsl,imx8mp-hdmi-phy
reg:
maxItems: 1
"#clock-cells":
const: 0
clocks:
maxItems: 2
clock-names:
items:
- const: apb
- const: ref
"#phy-cells":
const: 0
power-domains:
maxItems: 1
required:
- compatible
- reg
- "#clock-cells"
- clocks
- clock-names
- "#phy-cells"
- power-domains
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx8mp-clock.h>
#include <dt-bindings/power/imx8mp-power.h>
phy@32fdff00 {
compatible = "fsl,imx8mp-hdmi-phy";
reg = <0x32fdff00 0x100>;
clocks = <&clk IMX8MP_CLK_HDMI_APB>,
<&clk IMX8MP_CLK_HDMI_24M>;
clock-names = "apb", "ref";
power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>;
#clock-cells = <0>;
#phy-cells = <0>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/mediatek,mt7988-xfi-tphy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek MT7988 XFI T-PHY
maintainers:
- Daniel Golle <daniel@makrotopia.org>
description:
The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes
used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in
MediaTek's 10G-capabale MT7988 SoC.
In MediaTek's SDK sources, this unit is referred to as "pextp".
properties:
compatible:
const: mediatek,mt7988-xfi-tphy
reg:
maxItems: 1
clocks:
items:
- description: XFI PHY clock
- description: XFI register clock
clock-names:
items:
- const: xfipll
- const: topxtal
resets:
items:
- description: Reset controller corresponding to the phy instance.
mediatek,usxgmii-performance-errata:
$ref: /schemas/types.yaml#/definitions/flag
description:
One instance of the T-PHY on MT7988 suffers from a performance
problem in 10GBase-R mode which needs a work-around in the driver.
This flag enables a work-around ajusting an analog phy setting and
is required for XFI Port0 of the MT7988 SoC to be in compliance with
the SFP specification.
"#phy-cells":
const: 0
required:
- compatible
- reg
- clocks
- clock-names
- resets
- "#phy-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
phy@11f20000 {
compatible = "mediatek,mt7988-xfi-tphy";
reg = <0 0x11f20000 0 0x10000>;
clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>,
<&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
clock-names = "xfipll", "topxtal";
resets = <&watchdog 14>;
mediatek,usxgmii-performance-errata;
#phy-cells = <0>;
};
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/phy-rockchip-usbdp.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Rockchip USBDP Combo PHY with Samsung IP block
maintainers:
- Frank Wang <frank.wang@rock-chips.com>
- Zhang Yubing <yubing.zhang@rock-chips.com>
properties:
compatible:
enum:
- rockchip,rk3588-usbdp-phy
reg:
maxItems: 1
"#phy-cells":
description: |
Cell allows setting the type of the PHY. Possible values are:
- PHY_TYPE_USB3
- PHY_TYPE_DP
const: 1
clocks:
maxItems: 4
clock-names:
items:
- const: refclk
- const: immortal
- const: pclk
- const: utmi
resets:
maxItems: 5
reset-names:
items:
- const: init
- const: cmn
- const: lane
- const: pcs_apb
- const: pma_apb
rockchip,dp-lane-mux:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 2
maxItems: 4
items:
maximum: 3
description:
An array of physical Type-C lanes indexes. Position of an entry
determines the DisplayPort (DP) lane index, while the value of an entry
indicates physical Type-C lane. The supported DP lanes number are 2 or 4.
e.g. for 2 lanes DP lanes map, we could have "rockchip,dp-lane-mux = <2,
3>;", assuming DP lane0 on Type-C phy lane2, DP lane1 on Type-C phy
lane3. For 4 lanes DP lanes map, we could have "rockchip,dp-lane-mux =
<0, 1, 2, 3>;", assuming DP lane0 on Type-C phy lane0, DP lane1 on Type-C
phy lane1, DP lane2 on Type-C phy lane2, DP lane3 on Type-C phy lane3. If
DP lanes are mapped by DisplayPort Alt mode, this property is not needed.
rockchip,u2phy-grf:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to the syscon managing the 'usb2 phy general register files'.
rockchip,usb-grf:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to the syscon managing the 'usb general register files'.
rockchip,usbdpphy-grf:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to the syscon managing the 'usbdp phy general register files'.
rockchip,vo-grf:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to the syscon managing the 'video output general register files'.
When select the DP lane mapping will request its phandle.
sbu1-dc-gpios:
description:
GPIO connected to the SBU1 line of the USB-C connector via a big resistor
(~100K) to apply a DC offset for signalling the connector orientation.
maxItems: 1
sbu2-dc-gpios:
description:
GPIO connected to the SBU2 line of the USB-C connector via a big resistor
(~100K) to apply a DC offset for signalling the connector orientation.
maxItems: 1
orientation-switch:
description: Flag the port as possible handler of orientation switching
type: boolean
mode-switch:
description: Flag the port as possible handler of altmode switching
type: boolean
port:
$ref: /schemas/graph.yaml#/properties/port
description:
A port node to link the PHY to a TypeC controller for the purpose of
handling orientation switching.
required:
- compatible
- reg
- clocks
- clock-names
- resets
- reset-names
- "#phy-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/rockchip,rk3588-cru.h>
#include <dt-bindings/reset/rockchip,rk3588-cru.h>
usbdp_phy0: phy@fed80000 {
compatible = "rockchip,rk3588-usbdp-phy";
reg = <0xfed80000 0x10000>;
#phy-cells = <1>;
clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
<&cru CLK_USBDP_PHY0_IMMORTAL>,
<&cru PCLK_USBDPPHY0>,
<&u2phy0>;
clock-names = "refclk", "immortal", "pclk", "utmi";
resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
<&cru SRST_USBDP_COMBO_PHY0_CMN>,
<&cru SRST_USBDP_COMBO_PHY0_LANE>,
<&cru SRST_USBDP_COMBO_PHY0_PCS>,
<&cru SRST_P_USBDPPHY0>;
reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
rockchip,u2phy-grf = <&usb2phy0_grf>;
rockchip,usb-grf = <&usb_grf>;
rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
rockchip,vo-grf = <&vo0_grf>;
};
...@@ -21,6 +21,7 @@ properties: ...@@ -21,6 +21,7 @@ properties:
- qcom,sc8180x-edp-phy - qcom,sc8180x-edp-phy
- qcom,sc8280xp-dp-phy - qcom,sc8280xp-dp-phy
- qcom,sc8280xp-edp-phy - qcom,sc8280xp-edp-phy
- qcom,x1e80100-dp-phy
reg: reg:
items: items:
......
...@@ -88,11 +88,11 @@ properties: ...@@ -88,11 +88,11 @@ properties:
- description: offset of PCIe 4-lane configuration register - description: offset of PCIe 4-lane configuration register
- description: offset of configuration bit for this PHY - description: offset of configuration bit for this PHY
"#clock-cells": "#clock-cells": true
const: 0
clock-output-names: clock-output-names:
maxItems: 1 minItems: 1
maxItems: 2
"#phy-cells": "#phy-cells":
const: 0 const: 0
...@@ -198,7 +198,6 @@ allOf: ...@@ -198,7 +198,6 @@ allOf:
enum: enum:
- qcom,sm8550-qmp-gen4x2-pcie-phy - qcom,sm8550-qmp-gen4x2-pcie-phy
- qcom,sm8650-qmp-gen4x2-pcie-phy - qcom,sm8650-qmp-gen4x2-pcie-phy
- qcom,x1e80100-qmp-gen3x2-pcie-phy
- qcom,x1e80100-qmp-gen4x2-pcie-phy - qcom,x1e80100-qmp-gen4x2-pcie-phy
then: then:
properties: properties:
...@@ -213,6 +212,27 @@ allOf: ...@@ -213,6 +212,27 @@ allOf:
reset-names: reset-names:
maxItems: 1 maxItems: 1
- if:
properties:
compatible:
contains:
enum:
- qcom,sm8450-qmp-gen4x2-pcie-phy
- qcom,sm8550-qmp-gen4x2-pcie-phy
- qcom,sm8650-qmp-gen4x2-pcie-phy
then:
properties:
clock-output-names:
minItems: 2
"#clock-cells":
const: 1
else:
properties:
clock-output-names:
maxItems: 1
"#clock-cells":
const: 0
examples: examples:
- | - |
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h> #include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
......
...@@ -32,6 +32,7 @@ properties: ...@@ -32,6 +32,7 @@ properties:
- qcom,sm8250-qmp-ufs-phy - qcom,sm8250-qmp-ufs-phy
- qcom,sm8350-qmp-ufs-phy - qcom,sm8350-qmp-ufs-phy
- qcom,sm8450-qmp-ufs-phy - qcom,sm8450-qmp-ufs-phy
- qcom,sm8475-qmp-ufs-phy
- qcom,sm8550-qmp-ufs-phy - qcom,sm8550-qmp-ufs-phy
- qcom,sm8650-qmp-ufs-phy - qcom,sm8650-qmp-ufs-phy
...@@ -71,7 +72,6 @@ required: ...@@ -71,7 +72,6 @@ required:
- reg - reg
- clocks - clocks
- clock-names - clock-names
- power-domains
- resets - resets
- reset-names - reset-names
- vdda-phy-supply - vdda-phy-supply
...@@ -86,6 +86,7 @@ allOf: ...@@ -86,6 +86,7 @@ allOf:
enum: enum:
- qcom,msm8998-qmp-ufs-phy - qcom,msm8998-qmp-ufs-phy
- qcom,sa8775p-qmp-ufs-phy - qcom,sa8775p-qmp-ufs-phy
- qcom,sc7180-qmp-ufs-phy
- qcom,sc7280-qmp-ufs-phy - qcom,sc7280-qmp-ufs-phy
- qcom,sc8180x-qmp-ufs-phy - qcom,sc8180x-qmp-ufs-phy
- qcom,sc8280xp-qmp-ufs-phy - qcom,sc8280xp-qmp-ufs-phy
...@@ -98,6 +99,7 @@ allOf: ...@@ -98,6 +99,7 @@ allOf:
- qcom,sm8250-qmp-ufs-phy - qcom,sm8250-qmp-ufs-phy
- qcom,sm8350-qmp-ufs-phy - qcom,sm8350-qmp-ufs-phy
- qcom,sm8450-qmp-ufs-phy - qcom,sm8450-qmp-ufs-phy
- qcom,sm8475-qmp-ufs-phy
- qcom,sm8550-qmp-ufs-phy - qcom,sm8550-qmp-ufs-phy
- qcom,sm8650-qmp-ufs-phy - qcom,sm8650-qmp-ufs-phy
then: then:
...@@ -127,6 +129,21 @@ allOf: ...@@ -127,6 +129,21 @@ allOf:
- const: ref - const: ref
- const: qref - const: qref
- if:
properties:
compatible:
contains:
enum:
- qcom,msm8996-qmp-ufs-phy
- qcom,msm8998-qmp-ufs-phy
then:
properties:
power-domains:
false
else:
required:
- power-domains
additionalProperties: false additionalProperties: false
examples: examples:
......
...@@ -20,6 +20,7 @@ properties: ...@@ -20,6 +20,7 @@ properties:
- qcom,ipq8074-qmp-usb3-phy - qcom,ipq8074-qmp-usb3-phy
- qcom,ipq9574-qmp-usb3-phy - qcom,ipq9574-qmp-usb3-phy
- qcom,msm8996-qmp-usb3-phy - qcom,msm8996-qmp-usb3-phy
- com,qdu1000-qmp-usb3-uni-phy
- qcom,sa8775p-qmp-usb3-uni-phy - qcom,sa8775p-qmp-usb3-uni-phy
- qcom,sc8280xp-qmp-usb3-uni-phy - qcom,sc8280xp-qmp-usb3-uni-phy
- qcom,sdm845-qmp-usb3-uni-phy - qcom,sdm845-qmp-usb3-uni-phy
...@@ -109,6 +110,7 @@ allOf: ...@@ -109,6 +110,7 @@ allOf:
compatible: compatible:
contains: contains:
enum: enum:
- qcom,qdu1000-qmp-usb3-uni-phy
- qcom,sa8775p-qmp-usb3-uni-phy - qcom,sa8775p-qmp-usb3-uni-phy
- qcom,sc8280xp-qmp-usb3-uni-phy - qcom,sc8280xp-qmp-usb3-uni-phy
- qcom,sm8150-qmp-usb3-uni-phy - qcom,sm8150-qmp-usb3-uni-phy
......
...@@ -20,7 +20,9 @@ properties: ...@@ -20,7 +20,9 @@ properties:
- enum: - enum:
- qcom,pm7550ba-eusb2-repeater - qcom,pm7550ba-eusb2-repeater
- const: qcom,pm8550b-eusb2-repeater - const: qcom,pm8550b-eusb2-repeater
- const: qcom,pm8550b-eusb2-repeater - enum:
- qcom,pm8550b-eusb2-repeater
- qcom,smb2360-eusb2-repeater
reg: reg:
maxItems: 1 maxItems: 1
......
...@@ -15,9 +15,6 @@ description: | ...@@ -15,9 +15,6 @@ description: |
properties: properties:
compatible: compatible:
oneOf: oneOf:
- enum:
- qcom,sc8180x-usb-hs-phy
- qcom,usb-snps-femto-v2-phy
- items: - items:
- enum: - enum:
- qcom,sa8775p-usb-hs-phy - qcom,sa8775p-usb-hs-phy
...@@ -25,7 +22,9 @@ properties: ...@@ -25,7 +22,9 @@ properties:
- const: qcom,usb-snps-hs-5nm-phy - const: qcom,usb-snps-hs-5nm-phy
- items: - items:
- enum: - enum:
- qcom,qdu1000-usb-hs-phy
- qcom,sc7280-usb-hs-phy - qcom,sc7280-usb-hs-phy
- qcom,sc8180x-usb-hs-phy
- qcom,sdx55-usb-hs-phy - qcom,sdx55-usb-hs-phy
- qcom,sdx65-usb-hs-phy - qcom,sdx65-usb-hs-phy
- qcom,sm6375-usb-hs-phy - qcom,sm6375-usb-hs-phy
......
...@@ -54,6 +54,16 @@ properties: ...@@ -54,6 +54,16 @@ properties:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the syscon managing the pipe "general register files" description: phandle to the syscon managing the pipe "general register files"
rockchip,rx-common-refclk-mode:
description: which lanes (by position) should be configured to run in
RX common reference clock mode. 0 means disabled, 1 means enabled.
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 16
items:
minimum: 0
maximum: 1
required: required:
- compatible - compatible
- reg - reg
......
...@@ -15,6 +15,7 @@ properties: ...@@ -15,6 +15,7 @@ properties:
compatible: compatible:
enum: enum:
- google,gs101-ufs-phy
- samsung,exynos7-ufs-phy - samsung,exynos7-ufs-phy
- samsung,exynosautov9-ufs-phy - samsung,exynosautov9-ufs-phy
- tesla,fsd-ufs-phy - tesla,fsd-ufs-phy
......
...@@ -9312,6 +9312,7 @@ S: Maintained ...@@ -9312,6 +9312,7 @@ S: Maintained
F: Documentation/devicetree/bindings/clock/google,gs101-clock.yaml F: Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
F: arch/arm64/boot/dts/exynos/google/ F: arch/arm64/boot/dts/exynos/google/
F: drivers/clk/samsung/clk-gs101.c F: drivers/clk/samsung/clk-gs101.c
F: drivers/phy/samsung/phy-gs101-ufs.c
F: include/dt-bindings/clock/google,gs101.h F: include/dt-bindings/clock/google,gs101.h
K: [gG]oogle.?[tT]ensor K: [gG]oogle.?[tT]ensor
...@@ -13987,6 +13988,7 @@ L: netdev@vger.kernel.org ...@@ -13987,6 +13988,7 @@ L: netdev@vger.kernel.org
S: Maintained S: Maintained
F: drivers/net/phy/mediatek-ge-soc.c F: drivers/net/phy/mediatek-ge-soc.c
F: drivers/net/phy/mediatek-ge.c F: drivers/net/phy/mediatek-ge.c
F: drivers/phy/mediatek/phy-mtk-xfi-tphy.c
MEDIATEK I2C CONTROLLER DRIVER MEDIATEK I2C CONTROLLER DRIVER
M: Qii Wang <qii.wang@mediatek.com> M: Qii Wang <qii.wang@mediatek.com>
......
...@@ -35,6 +35,12 @@ config PHY_FSL_IMX8M_PCIE ...@@ -35,6 +35,12 @@ config PHY_FSL_IMX8M_PCIE
Enable this to add support for the PCIE PHY as found on Enable this to add support for the PCIE PHY as found on
i.MX8M family of SOCs. i.MX8M family of SOCs.
config PHY_FSL_SAMSUNG_HDMI_PHY
tristate "Samsung HDMI PHY support"
depends on OF && HAS_IOMEM && COMMON_CLK
help
Enable this to add support for the Samsung HDMI PHY in i.MX8MP.
endif endif
config PHY_FSL_LYNX_28G config PHY_FSL_LYNX_28G
......
...@@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY) += phy-fsl-imx8qm-lvds-phy.o ...@@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY) += phy-fsl-imx8qm-lvds-phy.o
obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY) += phy-fsl-imx8-mipi-dphy.o obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY) += phy-fsl-imx8-mipi-dphy.o
obj-$(CONFIG_PHY_FSL_IMX8M_PCIE) += phy-fsl-imx8m-pcie.o obj-$(CONFIG_PHY_FSL_IMX8M_PCIE) += phy-fsl-imx8m-pcie.o
obj-$(CONFIG_PHY_FSL_LYNX_28G) += phy-fsl-lynx-28g.o obj-$(CONFIG_PHY_FSL_LYNX_28G) += phy-fsl-lynx-28g.o
obj-$(CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY) += phy-fsl-samsung-hdmi.o
This diff is collapsed.
...@@ -13,6 +13,17 @@ config PHY_MTK_PCIE ...@@ -13,6 +13,17 @@ config PHY_MTK_PCIE
callback for PCIe GEN3 port, it supports software efuse callback for PCIe GEN3 port, it supports software efuse
initialization. initialization.
config PHY_MTK_XFI_TPHY
tristate "MediaTek 10GE SerDes XFI T-PHY driver"
depends on ARCH_MEDIATEK || COMPILE_TEST
depends on OF
select GENERIC_PHY
help
Say 'Y' here to add support for MediaTek XFI T-PHY driver.
The driver provides access to the Ethernet SerDes T-PHY supporting
1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
config PHY_MTK_TPHY config PHY_MTK_TPHY
tristate "MediaTek T-PHY Driver" tristate "MediaTek T-PHY Driver"
depends on ARCH_MEDIATEK || COMPILE_TEST depends on ARCH_MEDIATEK || COMPILE_TEST
......
...@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE) += phy-mtk-pcie.o ...@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE) += phy-mtk-pcie.o
obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o
obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o
obj-$(CONFIG_PHY_MTK_XFI_TPHY) += phy-mtk-xfi-tphy.o
phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o
phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o
......
This diff is collapsed.
...@@ -20,7 +20,12 @@ ...@@ -20,7 +20,12 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
static struct class *phy_class; static void phy_release(struct device *dev);
static const struct class phy_class = {
.name = "phy",
.dev_release = phy_release,
};
static struct dentry *phy_debugfs_root; static struct dentry *phy_debugfs_root;
static DEFINE_MUTEX(phy_provider_mutex); static DEFINE_MUTEX(phy_provider_mutex);
static LIST_HEAD(phy_provider_list); static LIST_HEAD(phy_provider_list);
...@@ -753,7 +758,7 @@ struct phy *of_phy_simple_xlate(struct device *dev, ...@@ -753,7 +758,7 @@ struct phy *of_phy_simple_xlate(struct device *dev,
struct phy *phy; struct phy *phy;
struct class_dev_iter iter; struct class_dev_iter iter;
class_dev_iter_init(&iter, phy_class, NULL, NULL); class_dev_iter_init(&iter, &phy_class, NULL, NULL);
while ((dev = class_dev_iter_next(&iter))) { while ((dev = class_dev_iter_next(&iter))) {
phy = to_phy(dev); phy = to_phy(dev);
if (args->np != phy->dev.of_node) if (args->np != phy->dev.of_node)
...@@ -1016,7 +1021,7 @@ struct phy *phy_create(struct device *dev, struct device_node *node, ...@@ -1016,7 +1021,7 @@ struct phy *phy_create(struct device *dev, struct device_node *node,
device_initialize(&phy->dev); device_initialize(&phy->dev);
mutex_init(&phy->mutex); mutex_init(&phy->mutex);
phy->dev.class = phy_class; phy->dev.class = &phy_class;
phy->dev.parent = dev; phy->dev.parent = dev;
phy->dev.of_node = node ?: dev->of_node; phy->dev.of_node = node ?: dev->of_node;
phy->id = id; phy->id = id;
...@@ -1285,14 +1290,13 @@ static void phy_release(struct device *dev) ...@@ -1285,14 +1290,13 @@ static void phy_release(struct device *dev)
static int __init phy_core_init(void) static int __init phy_core_init(void)
{ {
phy_class = class_create("phy"); int err;
if (IS_ERR(phy_class)) {
pr_err("failed to create phy class --> %ld\n",
PTR_ERR(phy_class));
return PTR_ERR(phy_class);
}
phy_class->dev_release = phy_release; err = class_register(&phy_class);
if (err) {
pr_err("failed to register phy class");
return err;
}
phy_debugfs_root = debugfs_create_dir("phy", NULL); phy_debugfs_root = debugfs_create_dir("phy", NULL);
...@@ -1303,6 +1307,6 @@ device_initcall(phy_core_init); ...@@ -1303,6 +1307,6 @@ device_initcall(phy_core_init);
static void __exit phy_core_exit(void) static void __exit phy_core_exit(void)
{ {
debugfs_remove_recursive(phy_debugfs_root); debugfs_remove_recursive(phy_debugfs_root);
class_destroy(phy_class); class_unregister(&phy_class);
} }
module_exit(phy_core_exit); module_exit(phy_core_exit);
This diff is collapsed.
...@@ -88,6 +88,12 @@ static const u32 pm8550b_init_tbl[NUM_TUNE_FIELDS] = { ...@@ -88,6 +88,12 @@ static const u32 pm8550b_init_tbl[NUM_TUNE_FIELDS] = {
[TUNE_USB2_PREEM] = 0x5, [TUNE_USB2_PREEM] = 0x5,
}; };
static const u32 smb2360_init_tbl[NUM_TUNE_FIELDS] = {
[TUNE_IUSB2] = 0x5,
[TUNE_SQUELCH_U] = 0x3,
[TUNE_USB2_PREEM] = 0x2,
};
static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = {
.init_tbl = pm8550b_init_tbl, .init_tbl = pm8550b_init_tbl,
.init_tbl_num = ARRAY_SIZE(pm8550b_init_tbl), .init_tbl_num = ARRAY_SIZE(pm8550b_init_tbl),
...@@ -95,6 +101,13 @@ static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { ...@@ -95,6 +101,13 @@ static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = {
.num_vregs = ARRAY_SIZE(pm8550b_vreg_l), .num_vregs = ARRAY_SIZE(pm8550b_vreg_l),
}; };
static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = {
.init_tbl = smb2360_init_tbl,
.init_tbl_num = ARRAY_SIZE(smb2360_init_tbl),
.vreg_list = pm8550b_vreg_l,
.num_vregs = ARRAY_SIZE(pm8550b_vreg_l),
};
static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr) static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr)
{ {
int num = rptr->cfg->num_vregs; int num = rptr->cfg->num_vregs;
...@@ -271,6 +284,10 @@ static const struct of_device_id eusb2_repeater_of_match_table[] = { ...@@ -271,6 +284,10 @@ static const struct of_device_id eusb2_repeater_of_match_table[] = {
.compatible = "qcom,pm8550b-eusb2-repeater", .compatible = "qcom,pm8550b-eusb2-repeater",
.data = &pm8550b_eusb2_cfg, .data = &pm8550b_eusb2_cfg,
}, },
{
.compatible = "qcom,smb2360-eusb2-repeater",
.data = &smb2360_eusb2_cfg,
},
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, eusb2_repeater_of_match_table); MODULE_DEVICE_TABLE(of, eusb2_repeater_of_match_table);
......
...@@ -1382,6 +1382,13 @@ static const u8 qmp_dp_v5_voltage_swing_hbr_rbr[4][4] = { ...@@ -1382,6 +1382,13 @@ static const u8 qmp_dp_v5_voltage_swing_hbr_rbr[4][4] = {
{ 0x3f, 0xff, 0xff, 0xff } { 0x3f, 0xff, 0xff, 0xff }
}; };
static const u8 qmp_dp_v6_voltage_swing_hbr_rbr[4][4] = {
{ 0x27, 0x2f, 0x36, 0x3f },
{ 0x31, 0x3e, 0x3f, 0xff },
{ 0x36, 0x3f, 0xff, 0xff },
{ 0x3f, 0xff, 0xff, 0xff }
};
static const u8 qmp_dp_v6_pre_emphasis_hbr_rbr[4][4] = { static const u8 qmp_dp_v6_pre_emphasis_hbr_rbr[4][4] = {
{ 0x20, 0x2d, 0x34, 0x3a }, { 0x20, 0x2d, 0x34, 0x3a },
{ 0x20, 0x2e, 0x35, 0xff }, { 0x20, 0x2e, 0x35, 0xff },
...@@ -2001,6 +2008,51 @@ static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = { ...@@ -2001,6 +2008,51 @@ static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = {
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
}; };
static const struct qmp_phy_cfg sm8650_usb3dpphy_cfg = {
.offsets = &qmp_combo_offsets_v3,
.serdes_tbl = sm8550_usb3_serdes_tbl,
.serdes_tbl_num = ARRAY_SIZE(sm8550_usb3_serdes_tbl),
.tx_tbl = sm8550_usb3_tx_tbl,
.tx_tbl_num = ARRAY_SIZE(sm8550_usb3_tx_tbl),
.rx_tbl = sm8550_usb3_rx_tbl,
.rx_tbl_num = ARRAY_SIZE(sm8550_usb3_rx_tbl),
.pcs_tbl = sm8550_usb3_pcs_tbl,
.pcs_tbl_num = ARRAY_SIZE(sm8550_usb3_pcs_tbl),
.pcs_usb_tbl = sm8550_usb3_pcs_usb_tbl,
.pcs_usb_tbl_num = ARRAY_SIZE(sm8550_usb3_pcs_usb_tbl),
.dp_serdes_tbl = qmp_v6_dp_serdes_tbl,
.dp_serdes_tbl_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl),
.dp_tx_tbl = qmp_v6_dp_tx_tbl,
.dp_tx_tbl_num = ARRAY_SIZE(qmp_v6_dp_tx_tbl),
.serdes_tbl_rbr = qmp_v6_dp_serdes_tbl_rbr,
.serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_rbr),
.serdes_tbl_hbr = qmp_v6_dp_serdes_tbl_hbr,
.serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr),
.serdes_tbl_hbr2 = qmp_v6_dp_serdes_tbl_hbr2,
.serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr2),
.serdes_tbl_hbr3 = qmp_v6_dp_serdes_tbl_hbr3,
.serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr3),
.swing_hbr_rbr = &qmp_dp_v6_voltage_swing_hbr_rbr,
.pre_emphasis_hbr_rbr = &qmp_dp_v6_pre_emphasis_hbr_rbr,
.swing_hbr3_hbr2 = &qmp_dp_v5_voltage_swing_hbr3_hbr2,
.pre_emphasis_hbr3_hbr2 = &qmp_dp_v5_pre_emphasis_hbr3_hbr2,
.dp_aux_init = qmp_v4_dp_aux_init,
.configure_dp_tx = qmp_v4_configure_dp_tx,
.configure_dp_phy = qmp_v4_configure_dp_phy,
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
.regs = qmp_v6_usb3phy_regs_layout,
.reset_list = msm8996_usb3phy_reset_l,
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
};
static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp) static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp)
{ {
const struct qmp_phy_cfg *cfg = qmp->cfg; const struct qmp_phy_cfg *cfg = qmp->cfg;
...@@ -2437,8 +2489,6 @@ static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp) ...@@ -2437,8 +2489,6 @@ static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp)
writel(0x20, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); writel(0x20, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]);
return 0; return 0;
return 0;
} }
/* /*
...@@ -3631,7 +3681,7 @@ static const struct of_device_id qmp_combo_of_match_table[] = { ...@@ -3631,7 +3681,7 @@ static const struct of_device_id qmp_combo_of_match_table[] = {
}, },
{ {
.compatible = "qcom,sm8650-qmp-usb3-dp-phy", .compatible = "qcom,sm8650-qmp-usb3-dp-phy",
.data = &sm8550_usb3dpphy_cfg, .data = &sm8650_usb3dpphy_cfg,
}, },
{ {
.compatible = "qcom,x1e80100-qmp-usb3-dp-phy", .compatible = "qcom,x1e80100-qmp-usb3-dp-phy",
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <dt-bindings/phy/phy-qcom-qmp.h>
#include "phy-qcom-qmp-common.h" #include "phy-qcom-qmp-common.h"
#include "phy-qcom-qmp.h" #include "phy-qcom-qmp.h"
...@@ -2246,6 +2248,7 @@ static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x4_pcie_pcs_alt_tbl[] = { ...@@ -2246,6 +2248,7 @@ static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x4_pcie_pcs_alt_tbl[] = {
}; };
static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x4_pcie_serdes_alt_tbl[] = { static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x4_pcie_serdes_alt_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f), QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36), QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36), QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
...@@ -2272,7 +2275,6 @@ static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x4_pcie_rc_serdes_alt_tbl[] ...@@ -2272,7 +2275,6 @@ static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x4_pcie_rc_serdes_alt_tbl[]
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07), QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x97), QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x97),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x0c), QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x0c),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90), QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06), QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06), QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
...@@ -2389,6 +2391,9 @@ struct qmp_phy_cfg { ...@@ -2389,6 +2391,9 @@ struct qmp_phy_cfg {
/* QMP PHY pipe clock interface rate */ /* QMP PHY pipe clock interface rate */
unsigned long pipe_clock_rate; unsigned long pipe_clock_rate;
/* QMP PHY AUX clock interface rate */
unsigned long aux_clock_rate;
}; };
struct qmp_pcie { struct qmp_pcie {
...@@ -2420,6 +2425,7 @@ struct qmp_pcie { ...@@ -2420,6 +2425,7 @@ struct qmp_pcie {
int mode; int mode;
struct clk_fixed_rate pipe_clk_fixed; struct clk_fixed_rate pipe_clk_fixed;
struct clk_fixed_rate aux_clk_fixed;
}; };
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
...@@ -3135,6 +3141,9 @@ static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = { ...@@ -3135,6 +3141,9 @@ static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = {
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS_4_20, .phy_status = PHYSTATUS_4_20,
/* 20MHz PHY AUX Clock */
.aux_clock_rate = 20000000,
}; };
static const struct qmp_phy_cfg sm8550_qmp_gen3x2_pciephy_cfg = { static const struct qmp_phy_cfg sm8550_qmp_gen3x2_pciephy_cfg = {
...@@ -3192,6 +3201,9 @@ static const struct qmp_phy_cfg sm8550_qmp_gen4x2_pciephy_cfg = { ...@@ -3192,6 +3201,9 @@ static const struct qmp_phy_cfg sm8550_qmp_gen4x2_pciephy_cfg = {
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS_4_20, .phy_status = PHYSTATUS_4_20,
.has_nocsr_reset = true, .has_nocsr_reset = true,
/* 20MHz PHY AUX Clock */
.aux_clock_rate = 20000000,
}; };
static const struct qmp_phy_cfg sm8650_qmp_gen4x2_pciephy_cfg = { static const struct qmp_phy_cfg sm8650_qmp_gen4x2_pciephy_cfg = {
...@@ -3222,6 +3234,9 @@ static const struct qmp_phy_cfg sm8650_qmp_gen4x2_pciephy_cfg = { ...@@ -3222,6 +3234,9 @@ static const struct qmp_phy_cfg sm8650_qmp_gen4x2_pciephy_cfg = {
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS_4_20, .phy_status = PHYSTATUS_4_20,
.has_nocsr_reset = true, .has_nocsr_reset = true,
/* 20MHz PHY AUX Clock */
.aux_clock_rate = 20000000,
}; };
static const struct qmp_phy_cfg sa8775p_qmp_gen4x2_pciephy_cfg = { static const struct qmp_phy_cfg sa8775p_qmp_gen4x2_pciephy_cfg = {
...@@ -3291,6 +3306,13 @@ static const struct qmp_phy_cfg sa8775p_qmp_gen4x4_pciephy_cfg = { ...@@ -3291,6 +3306,13 @@ static const struct qmp_phy_cfg sa8775p_qmp_gen4x4_pciephy_cfg = {
.pcs_misc_num = ARRAY_SIZE(sa8775p_qmp_gen4_pcie_rc_pcs_misc_tbl), .pcs_misc_num = ARRAY_SIZE(sa8775p_qmp_gen4_pcie_rc_pcs_misc_tbl),
}, },
.tbls_ep = &(const struct qmp_phy_cfg_tbls) {
.serdes = sa8775p_qmp_gen4x2_pcie_ep_serdes_alt_tbl,
.serdes_num = ARRAY_SIZE(sa8775p_qmp_gen4x2_pcie_ep_serdes_alt_tbl),
.pcs_misc = sm8450_qmp_gen4x2_pcie_ep_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_ep_pcs_misc_tbl),
},
.reset_list = sdm845_pciephy_reset_l, .reset_list = sdm845_pciephy_reset_l,
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l, .vreg_list = qmp_phy_vreg_l,
...@@ -3664,7 +3686,7 @@ static int phy_pipe_clk_register(struct qmp_pcie *qmp, struct device_node *np) ...@@ -3664,7 +3686,7 @@ static int phy_pipe_clk_register(struct qmp_pcie *qmp, struct device_node *np)
struct clk_init_data init = { }; struct clk_init_data init = { };
int ret; int ret;
ret = of_property_read_string(np, "clock-output-names", &init.name); ret = of_property_read_string_index(np, "clock-output-names", 0, &init.name);
if (ret) { if (ret) {
dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np); dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
return ret; return ret;
...@@ -3683,14 +3705,87 @@ static int phy_pipe_clk_register(struct qmp_pcie *qmp, struct device_node *np) ...@@ -3683,14 +3705,87 @@ static int phy_pipe_clk_register(struct qmp_pcie *qmp, struct device_node *np)
fixed->hw.init = &init; fixed->hw.init = &init;
ret = devm_clk_hw_register(qmp->dev, &fixed->hw); return devm_clk_hw_register(qmp->dev, &fixed->hw);
if (ret) }
/*
* Register a fixed rate PHY aux clock.
*
* The <s>_phy_aux_clksrc generated by PHY goes to the GCC that gate
* controls it. The <s>_phy_aux_clk coming out of the GCC is requested
* by the PHY driver for its operations.
* We register the <s>_phy_aux_clksrc here. The gcc driver takes care
* of assigning this <s>_phy_aux_clksrc as parent to <s>_phy_aux_clk.
* Below picture shows this relationship.
*
* +---------------+
* | PHY block |<<---------------------------------------------+
* | | |
* | +-------+ | +-----+ |
* I/P---^-->| PLL |---^--->phy_aux_clksrc--->| GCC |--->phy_aux_clk---+
* clk | +-------+ | +-----+
* +---------------+
*/
static int phy_aux_clk_register(struct qmp_pcie *qmp, struct device_node *np)
{
struct clk_fixed_rate *fixed = &qmp->aux_clk_fixed;
struct clk_init_data init = { };
int ret;
ret = of_property_read_string_index(np, "clock-output-names", 1, &init.name);
if (ret) {
dev_err(qmp->dev, "%pOFn: No clock-output-names index 1\n", np);
return ret; return ret;
}
init.ops = &clk_fixed_rate_ops;
fixed->fixed_rate = qmp->cfg->aux_clock_rate;
fixed->hw.init = &init;
return devm_clk_hw_register(qmp->dev, &fixed->hw);
}
static struct clk_hw *qmp_pcie_clk_hw_get(struct of_phandle_args *clkspec, void *data)
{
struct qmp_pcie *qmp = data;
/* Support legacy bindings */
if (!clkspec->args_count)
return &qmp->pipe_clk_fixed.hw;
ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw); switch (clkspec->args[0]) {
case QMP_PCIE_PIPE_CLK:
return &qmp->pipe_clk_fixed.hw;
case QMP_PCIE_PHY_AUX_CLK:
return &qmp->aux_clk_fixed.hw;
}
return ERR_PTR(-EINVAL);
}
static int qmp_pcie_register_clocks(struct qmp_pcie *qmp, struct device_node *np)
{
int ret;
ret = phy_pipe_clk_register(qmp, np);
if (ret) if (ret)
return ret; return ret;
if (qmp->cfg->aux_clock_rate) {
ret = phy_aux_clk_register(qmp, np);
if (ret)
return ret;
ret = of_clk_add_hw_provider(np, qmp_pcie_clk_hw_get, qmp);
if (ret)
return ret;
} else {
ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &qmp->pipe_clk_fixed.hw);
if (ret)
return ret;
}
/* /*
* Roll a devm action because the clock provider is the child node, but * Roll a devm action because the clock provider is the child node, but
* the child node is not actually a device. * the child node is not actually a device.
...@@ -3899,7 +3994,7 @@ static int qmp_pcie_probe(struct platform_device *pdev) ...@@ -3899,7 +3994,7 @@ static int qmp_pcie_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_node_put; goto err_node_put;
ret = phy_pipe_clk_register(qmp, np); ret = qmp_pcie_register_clocks(qmp, np);
if (ret) if (ret)
goto err_node_put; goto err_node_put;
......
...@@ -30,5 +30,9 @@ ...@@ -30,5 +30,9 @@
#define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1 0x1f4 #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1 0x1f4
#define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1 0x1fc #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1 0x1fc
#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME 0x220 #define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME 0x220
#define QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S4 0x240
#define QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S5 0x244
#define QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S6 0x248
#define QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S7 0x24c
#endif #endif
...@@ -25,12 +25,15 @@ ...@@ -25,12 +25,15 @@
#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4 0xf0 #define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4 0xf0
#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS 0xf4 #define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS 0xf4
#define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL 0x178 #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL 0x178
#define QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4 0x1ac
#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x1bc #define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x1bc
#define QSERDES_UFS_V6_RX_INTERFACE_MODE 0x1e0 #define QSERDES_UFS_V6_RX_INTERFACE_MODE 0x1e0
#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3 0x1c4 #define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3 0x1c4
#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0 0x208 #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0 0x208
#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1 0x20c #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1 0x20c
#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2 0x210
#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3 0x214 #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3 0x214
#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4 0x218
#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6 0x220 #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6 0x220
#define QSERDES_UFS_V6_RX_MODE_RATE2_B3 0x238 #define QSERDES_UFS_V6_RX_MODE_RATE2_B3 0x238
#define QSERDES_UFS_V6_RX_MODE_RATE2_B6 0x244 #define QSERDES_UFS_V6_RX_MODE_RATE2_B6 0x244
...@@ -38,6 +41,9 @@ ...@@ -38,6 +41,9 @@
#define QSERDES_UFS_V6_RX_MODE_RATE3_B4 0x260 #define QSERDES_UFS_V6_RX_MODE_RATE3_B4 0x260
#define QSERDES_UFS_V6_RX_MODE_RATE3_B5 0x264 #define QSERDES_UFS_V6_RX_MODE_RATE3_B5 0x264
#define QSERDES_UFS_V6_RX_MODE_RATE3_B8 0x270 #define QSERDES_UFS_V6_RX_MODE_RATE3_B8 0x270
#define QSERDES_UFS_V6_RX_MODE_RATE4_B0 0x274
#define QSERDES_UFS_V6_RX_MODE_RATE4_B1 0x278
#define QSERDES_UFS_V6_RX_MODE_RATE4_B2 0x27c
#define QSERDES_UFS_V6_RX_MODE_RATE4_B3 0x280 #define QSERDES_UFS_V6_RX_MODE_RATE4_B3 0x280
#define QSERDES_UFS_V6_RX_MODE_RATE4_B4 0x284 #define QSERDES_UFS_V6_RX_MODE_RATE4_B4 0x284
#define QSERDES_UFS_V6_RX_MODE_RATE4_B6 0x28c #define QSERDES_UFS_V6_RX_MODE_RATE4_B6 0x28c
......
...@@ -722,6 +722,38 @@ static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_pcs[] = { ...@@ -722,6 +722,38 @@ static const struct qmp_phy_init_tbl sm8350_ufsphy_g4_pcs[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a), QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a),
}; };
static const struct qmp_phy_init_tbl sm8475_ufsphy_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x82),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x18),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0xff),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0c),
};
static const struct qmp_phy_init_tbl sm8475_ufsphy_g4_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x98),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x18),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x32),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x0f),
};
static const struct qmp_phy_init_tbl sm8475_ufsphy_g4_pcs[] = {
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x0b),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
};
static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = { static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9), QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16), QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
...@@ -830,17 +862,20 @@ static const struct qmp_phy_init_tbl sm8650_ufsphy_serdes[] = { ...@@ -830,17 +862,20 @@ static const struct qmp_phy_init_tbl sm8650_ufsphy_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11), QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01), QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f), QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44), QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO_MODE1, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x0a),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x17),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00), QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41), QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a), QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18), QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14), QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f), QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06), QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c), QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a), QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18), QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14), QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99), QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
...@@ -848,17 +883,28 @@ static const struct qmp_phy_init_tbl sm8650_ufsphy_serdes[] = { ...@@ -848,17 +883,28 @@ static const struct qmp_phy_init_tbl sm8650_ufsphy_serdes[] = {
}; };
static const struct qmp_phy_init_tbl sm8650_ufsphy_tx[] = { static const struct qmp_phy_init_tbl sm8650_ufsphy_tx[] = {
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x01),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
}; };
static const struct qmp_phy_init_tbl sm8650_ufsphy_rx[] = { static const struct qmp_phy_init_tbl sm8650_ufsphy_rx[] = {
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0f), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x3e),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xce),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xce),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2, 0x18),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
...@@ -866,23 +912,41 @@ static const struct qmp_phy_init_tbl sm8650_ufsphy_rx[] = { ...@@ -866,23 +912,41 @@ static const struct qmp_phy_init_tbl sm8650_ufsphy_rx[] = {
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B0, 0x24),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B1, 0x24),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B2, 0x20),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_SATURATION, 0x1f), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_SATURATION, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CTRL1, 0x94), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CTRL1, 0x94),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_TERM_BW_CTRL0, 0xfa), QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_TERM_BW_CTRL0, 0xfa),
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
}; };
static const struct qmp_phy_init_tbl sm8650_ufsphy_pcs[] = { static const struct qmp_phy_init_tbl sm8650_ufsphy_pcs[] = {
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x00), QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PCS_CTRL1, 0xc1), QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PCS_CTRL1, 0xc1),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33), QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x68),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S4, 0x0e),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S5, 0x12),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S6, 0x15),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S7, 0x19),
};
static const struct qmp_phy_init_tbl sm8650_ufsphy_g4_pcs[] = {
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x13),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04), QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04), QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f), };
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02), static const struct qmp_phy_init_tbl sm8650_ufsphy_g5_pcs[] = {
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x05),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x05),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4d),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
}; };
struct qmp_ufs_offsets { struct qmp_ufs_offsets {
...@@ -1346,6 +1410,42 @@ static const struct qmp_phy_cfg sm8450_ufsphy_cfg = { ...@@ -1346,6 +1410,42 @@ static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
.regs = ufsphy_v5_regs_layout, .regs = ufsphy_v5_regs_layout,
}; };
static const struct qmp_phy_cfg sm8475_ufsphy_cfg = {
.lanes = 2,
.offsets = &qmp_ufs_offsets_v6,
.max_supported_gear = UFS_HS_G4,
.tbls = {
.serdes = sm8475_ufsphy_serdes,
.serdes_num = ARRAY_SIZE(sm8475_ufsphy_serdes),
.tx = sm8550_ufsphy_tx,
.tx_num = ARRAY_SIZE(sm8550_ufsphy_tx),
.rx = sm8550_ufsphy_rx,
.rx_num = ARRAY_SIZE(sm8550_ufsphy_rx),
.pcs = sm8550_ufsphy_pcs,
.pcs_num = ARRAY_SIZE(sm8550_ufsphy_pcs),
},
.tbls_hs_b = {
.serdes = sm8550_ufsphy_hs_b_serdes,
.serdes_num = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
},
.tbls_hs_overlay[0] = {
.serdes = sm8475_ufsphy_g4_serdes,
.serdes_num = ARRAY_SIZE(sm8475_ufsphy_g4_serdes),
.tx = sm8550_ufsphy_g4_tx,
.tx_num = ARRAY_SIZE(sm8550_ufsphy_g4_tx),
.rx = sm8550_ufsphy_g4_rx,
.rx_num = ARRAY_SIZE(sm8550_ufsphy_g4_rx),
.pcs = sm8475_ufsphy_g4_pcs,
.pcs_num = ARRAY_SIZE(sm8475_ufsphy_g4_pcs),
.max_gear = UFS_HS_G4,
},
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
.regs = ufsphy_v6_regs_layout,
};
static const struct qmp_phy_cfg sm8550_ufsphy_cfg = { static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
.lanes = 2, .lanes = 2,
...@@ -1407,6 +1507,17 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = { ...@@ -1407,6 +1507,17 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
.pcs = sm8650_ufsphy_pcs, .pcs = sm8650_ufsphy_pcs,
.pcs_num = ARRAY_SIZE(sm8650_ufsphy_pcs), .pcs_num = ARRAY_SIZE(sm8650_ufsphy_pcs),
}, },
.tbls_hs_overlay[0] = {
.pcs = sm8650_ufsphy_g4_pcs,
.pcs_num = ARRAY_SIZE(sm8650_ufsphy_g4_pcs),
.max_gear = UFS_HS_G4,
},
.tbls_hs_overlay[1] = {
.pcs = sm8650_ufsphy_g5_pcs,
.pcs_num = ARRAY_SIZE(sm8650_ufsphy_g5_pcs),
.max_gear = UFS_HS_G5,
},
.vreg_list = qmp_phy_vreg_l, .vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
.regs = ufsphy_v6_regs_layout, .regs = ufsphy_v6_regs_layout,
...@@ -1941,6 +2052,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = { ...@@ -1941,6 +2052,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = {
}, { }, {
.compatible = "qcom,sm8450-qmp-ufs-phy", .compatible = "qcom,sm8450-qmp-ufs-phy",
.data = &sm8450_ufsphy_cfg, .data = &sm8450_ufsphy_cfg,
}, {
.compatible = "qcom,sm8475-qmp-ufs-phy",
.data = &sm8475_ufsphy_cfg,
}, { }, {
.compatible = "qcom,sm8550-qmp-ufs-phy", .compatible = "qcom,sm8550-qmp-ufs-phy",
.data = &sm8550_ufsphy_cfg, .data = &sm8550_ufsphy_cfg,
......
...@@ -337,6 +337,29 @@ static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl[] = { ...@@ -337,6 +337,29 @@ static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V2_PCS_POWER_STATE_CONFIG2, 0x08), QMP_PHY_INIT_CFG(QPHY_V2_PCS_POWER_STATE_CONFIG2, 0x08),
}; };
static const struct qmp_phy_init_tbl qdu1000_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xc4),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x89),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
};
static const struct qmp_phy_init_tbl qdu1000_usb3_uniphy_pcs_usb_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_POWER_STATE_CONFIG1, 0x6f),
};
static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = { static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14), QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
...@@ -1400,6 +1423,27 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = { ...@@ -1400,6 +1423,27 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
.regs = qmp_v2_usb3phy_regs_layout, .regs = qmp_v2_usb3phy_regs_layout,
}; };
static const struct qmp_phy_cfg qdu1000_usb3_uniphy_cfg = {
.offsets = &qmp_usb_offsets_v5,
.serdes_tbl = sm8150_usb3_uniphy_serdes_tbl,
.serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_uniphy_serdes_tbl),
.tx_tbl = sm8350_usb3_uniphy_tx_tbl,
.tx_tbl_num = ARRAY_SIZE(sm8350_usb3_uniphy_tx_tbl),
.rx_tbl = sm8350_usb3_uniphy_rx_tbl,
.rx_tbl_num = ARRAY_SIZE(sm8350_usb3_uniphy_rx_tbl),
.pcs_tbl = qdu1000_usb3_uniphy_pcs_tbl,
.pcs_tbl_num = ARRAY_SIZE(qdu1000_usb3_uniphy_pcs_tbl),
.pcs_usb_tbl = qdu1000_usb3_uniphy_pcs_usb_tbl,
.pcs_usb_tbl_num = ARRAY_SIZE(qdu1000_usb3_uniphy_pcs_usb_tbl),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
.regs = qmp_v4_usb3phy_regs_layout,
.pcs_usb_offset = 0x1000,
.has_pwrdn_delay = true,
};
static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = { static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = {
.offsets = &qmp_usb_offsets_v5, .offsets = &qmp_usb_offsets_v5,
...@@ -2202,6 +2246,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = { ...@@ -2202,6 +2246,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = {
}, { }, {
.compatible = "qcom,msm8996-qmp-usb3-phy", .compatible = "qcom,msm8996-qmp-usb3-phy",
.data = &msm8996_usb3phy_cfg, .data = &msm8996_usb3phy_cfg,
}, {
.compatible = "qcom,qdu1000-qmp-usb3-uni-phy",
.data = &qdu1000_usb3_uniphy_cfg,
}, { }, {
.compatible = "qcom,sa8775p-qmp-usb3-uni-phy", .compatible = "qcom,sa8775p-qmp-usb3-uni-phy",
.data = &sa8775p_usb3_uniphy_cfg, .data = &sa8775p_usb3_uniphy_cfg,
......
...@@ -116,3 +116,15 @@ config PHY_ROCKCHIP_USB ...@@ -116,3 +116,15 @@ config PHY_ROCKCHIP_USB
select GENERIC_PHY select GENERIC_PHY
help help
Enable this to support the Rockchip USB 2.0 PHY. Enable this to support the Rockchip USB 2.0 PHY.
config PHY_ROCKCHIP_USBDP
tristate "Rockchip USBDP COMBO PHY Driver"
depends on ARCH_ROCKCHIP && OF
depends on TYPEC
select GENERIC_PHY
help
Enable this to support the Rockchip USB3.0/DP combo PHY with
Samsung IP block. This is required for USB3 support on RK3588.
To compile this driver as a module, choose M here: the module
will be called phy-rockchip-usbdp
...@@ -12,3 +12,4 @@ obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX) += phy-rockchip-samsung-hdptx.o ...@@ -12,3 +12,4 @@ obj-$(CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX) += phy-rockchip-samsung-hdptx.o
obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o
obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
obj-$(CONFIG_PHY_ROCKCHIP_USBDP) += phy-rockchip-usbdp.o
...@@ -248,7 +248,7 @@ static int rockchip_combphy_exit(struct phy *phy) ...@@ -248,7 +248,7 @@ static int rockchip_combphy_exit(struct phy *phy)
return 0; return 0;
} }
static const struct phy_ops rochchip_combphy_ops = { static const struct phy_ops rockchip_combphy_ops = {
.init = rockchip_combphy_init, .init = rockchip_combphy_init,
.exit = rockchip_combphy_exit, .exit = rockchip_combphy_exit,
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -364,7 +364,7 @@ static int rockchip_combphy_probe(struct platform_device *pdev) ...@@ -364,7 +364,7 @@ static int rockchip_combphy_probe(struct platform_device *pdev)
return ret; return ret;
} }
priv->phy = devm_phy_create(dev, NULL, &rochchip_combphy_ops); priv->phy = devm_phy_create(dev, NULL, &rockchip_combphy_ops);
if (IS_ERR(priv->phy)) { if (IS_ERR(priv->phy)) {
dev_err(dev, "failed to create combphy\n"); dev_err(dev, "failed to create combphy\n");
return PTR_ERR(priv->phy); return PTR_ERR(priv->phy);
......
...@@ -35,11 +35,17 @@ ...@@ -35,11 +35,17 @@
#define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0 #define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0
#define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904 #define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904
#define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04 #define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04
#define RK3588_PCIE3PHY_GRF_PHY0_LN0_CON1 0x1004
#define RK3588_PCIE3PHY_GRF_PHY0_LN1_CON1 0x1104
#define RK3588_PCIE3PHY_GRF_PHY1_LN0_CON1 0x2004
#define RK3588_PCIE3PHY_GRF_PHY1_LN1_CON1 0x2104
#define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0)) #define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0))
#define RK3588_BIFURCATION_LANE_0_1 BIT(0) #define RK3588_BIFURCATION_LANE_0_1 BIT(0)
#define RK3588_BIFURCATION_LANE_2_3 BIT(1) #define RK3588_BIFURCATION_LANE_2_3 BIT(1)
#define RK3588_LANE_AGGREGATION BIT(2) #define RK3588_LANE_AGGREGATION BIT(2)
#define RK3588_RX_CMN_REFCLK_MODE_EN ((BIT(7) << 16) | BIT(7))
#define RK3588_RX_CMN_REFCLK_MODE_DIS (BIT(7) << 16)
#define RK3588_PCIE1LN_SEL_EN (GENMASK(1, 0) << 16) #define RK3588_PCIE1LN_SEL_EN (GENMASK(1, 0) << 16)
#define RK3588_PCIE30_PHY_MODE_EN (GENMASK(2, 0) << 16) #define RK3588_PCIE30_PHY_MODE_EN (GENMASK(2, 0) << 16)
...@@ -60,6 +66,7 @@ struct rockchip_p3phy_priv { ...@@ -60,6 +66,7 @@ struct rockchip_p3phy_priv {
int num_clks; int num_clks;
int num_lanes; int num_lanes;
u32 lanes[4]; u32 lanes[4];
u32 rx_cmn_refclk_mode[4];
}; };
struct rockchip_p3phy_ops { struct rockchip_p3phy_ops {
...@@ -137,6 +144,19 @@ static int rockchip_p3phy_rk3588_init(struct rockchip_p3phy_priv *priv) ...@@ -137,6 +144,19 @@ static int rockchip_p3phy_rk3588_init(struct rockchip_p3phy_priv *priv)
u8 mode = RK3588_LANE_AGGREGATION; /* default */ u8 mode = RK3588_LANE_AGGREGATION; /* default */
int ret; int ret;
regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY0_LN0_CON1,
priv->rx_cmn_refclk_mode[0] ? RK3588_RX_CMN_REFCLK_MODE_EN :
RK3588_RX_CMN_REFCLK_MODE_DIS);
regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY0_LN1_CON1,
priv->rx_cmn_refclk_mode[1] ? RK3588_RX_CMN_REFCLK_MODE_EN :
RK3588_RX_CMN_REFCLK_MODE_DIS);
regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY1_LN0_CON1,
priv->rx_cmn_refclk_mode[2] ? RK3588_RX_CMN_REFCLK_MODE_EN :
RK3588_RX_CMN_REFCLK_MODE_DIS);
regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY1_LN1_CON1,
priv->rx_cmn_refclk_mode[3] ? RK3588_RX_CMN_REFCLK_MODE_EN :
RK3588_RX_CMN_REFCLK_MODE_DIS);
/* Deassert PCIe PMA output clamp mode */ /* Deassert PCIe PMA output clamp mode */
regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, BIT(8) | BIT(24)); regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, BIT(8) | BIT(24));
...@@ -182,7 +202,7 @@ static const struct rockchip_p3phy_ops rk3588_ops = { ...@@ -182,7 +202,7 @@ static const struct rockchip_p3phy_ops rk3588_ops = {
.phy_init = rockchip_p3phy_rk3588_init, .phy_init = rockchip_p3phy_rk3588_init,
}; };
static int rochchip_p3phy_init(struct phy *phy) static int rockchip_p3phy_init(struct phy *phy)
{ {
struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy);
int ret; int ret;
...@@ -205,7 +225,7 @@ static int rochchip_p3phy_init(struct phy *phy) ...@@ -205,7 +225,7 @@ static int rochchip_p3phy_init(struct phy *phy)
return ret; return ret;
} }
static int rochchip_p3phy_exit(struct phy *phy) static int rockchip_p3phy_exit(struct phy *phy)
{ {
struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy);
...@@ -214,9 +234,9 @@ static int rochchip_p3phy_exit(struct phy *phy) ...@@ -214,9 +234,9 @@ static int rochchip_p3phy_exit(struct phy *phy)
return 0; return 0;
} }
static const struct phy_ops rochchip_p3phy_ops = { static const struct phy_ops rockchip_p3phy_ops = {
.init = rochchip_p3phy_init, .init = rockchip_p3phy_init,
.exit = rochchip_p3phy_exit, .exit = rockchip_p3phy_exit,
.set_mode = rockchip_p3phy_set_mode, .set_mode = rockchip_p3phy_set_mode,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -275,7 +295,24 @@ static int rockchip_p3phy_probe(struct platform_device *pdev) ...@@ -275,7 +295,24 @@ static int rockchip_p3phy_probe(struct platform_device *pdev)
return priv->num_lanes; return priv->num_lanes;
} }
priv->phy = devm_phy_create(dev, NULL, &rochchip_p3phy_ops); ret = of_property_read_variable_u32_array(dev->of_node,
"rockchip,rx-common-refclk-mode",
priv->rx_cmn_refclk_mode, 1,
ARRAY_SIZE(priv->rx_cmn_refclk_mode));
/*
* if no rockchip,rx-common-refclk-mode, assume enabled for all lanes in
* order to be DT backwards compatible. (Since HW reset val is enabled.)
*/
if (ret == -EINVAL) {
for (int i = 0; i < ARRAY_SIZE(priv->rx_cmn_refclk_mode); i++)
priv->rx_cmn_refclk_mode[i] = 1;
} else if (ret < 0) {
dev_err(dev, "failed to read rockchip,rx-common-refclk-mode property %d\n",
ret);
return ret;
}
priv->phy = devm_phy_create(dev, NULL, &rockchip_p3phy_ops);
if (IS_ERR(priv->phy)) { if (IS_ERR(priv->phy)) {
dev_err(dev, "failed to create combphy\n"); dev_err(dev, "failed to create combphy\n");
return PTR_ERR(priv->phy); return PTR_ERR(priv->phy);
......
This diff is collapsed.
...@@ -3,6 +3,7 @@ obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o ...@@ -3,6 +3,7 @@ obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o
obj-$(CONFIG_PHY_SAMSUNG_UFS) += phy-exynos-ufs.o obj-$(CONFIG_PHY_SAMSUNG_UFS) += phy-exynos-ufs.o
phy-exynos-ufs-y += phy-gs101-ufs.o
phy-exynos-ufs-y += phy-samsung-ufs.o phy-exynos-ufs-y += phy-samsung-ufs.o
phy-exynos-ufs-y += phy-exynos7-ufs.o phy-exynos-ufs-y += phy-exynos7-ufs.o
phy-exynos-ufs-y += phy-exynosautov9-ufs.o phy-exynos-ufs-y += phy-exynosautov9-ufs.o
......
...@@ -82,4 +82,5 @@ const struct samsung_ufs_phy_drvdata exynos7_ufs_phy = { ...@@ -82,4 +82,5 @@ const struct samsung_ufs_phy_drvdata exynos7_ufs_phy = {
.clk_list = exynos7_ufs_phy_clks, .clk_list = exynos7_ufs_phy_clks,
.num_clks = ARRAY_SIZE(exynos7_ufs_phy_clks), .num_clks = ARRAY_SIZE(exynos7_ufs_phy_clks),
.cdr_lock_status_offset = EXYNOS7_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS, .cdr_lock_status_offset = EXYNOS7_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS,
.wait_for_cdr = samsung_ufs_phy_wait_for_lock_acq,
}; };
...@@ -71,4 +71,5 @@ const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy = { ...@@ -71,4 +71,5 @@ const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy = {
.clk_list = exynosautov9_ufs_phy_clks, .clk_list = exynosautov9_ufs_phy_clks,
.num_clks = ARRAY_SIZE(exynosautov9_ufs_phy_clks), .num_clks = ARRAY_SIZE(exynosautov9_ufs_phy_clks),
.cdr_lock_status_offset = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS, .cdr_lock_status_offset = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS,
.wait_for_cdr = samsung_ufs_phy_wait_for_lock_acq,
}; };
...@@ -60,4 +60,5 @@ const struct samsung_ufs_phy_drvdata fsd_ufs_phy = { ...@@ -60,4 +60,5 @@ const struct samsung_ufs_phy_drvdata fsd_ufs_phy = {
.clk_list = fsd_ufs_phy_clks, .clk_list = fsd_ufs_phy_clks,
.num_clks = ARRAY_SIZE(fsd_ufs_phy_clks), .num_clks = ARRAY_SIZE(fsd_ufs_phy_clks),
.cdr_lock_status_offset = FSD_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS, .cdr_lock_status_offset = FSD_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS,
.wait_for_cdr = samsung_ufs_phy_wait_for_lock_acq,
}; };
// SPDX-License-Identifier: GPL-2.0-only
/*
* UFS PHY driver data for Google Tensor gs101 SoC
*
* Copyright (C) 2024 Linaro Ltd
* Author: Peter Griffin <peter.griffin@linaro.org>
*/
#include "phy-samsung-ufs.h"
#define TENSOR_GS101_PHY_CTRL 0x3ec8
#define TENSOR_GS101_PHY_CTRL_MASK 0x1
#define TENSOR_GS101_PHY_CTRL_EN BIT(0)
#define PHY_GS101_LANE_OFFSET 0x200
#define TRSV_REG338 0x338
#define LN0_MON_RX_CAL_DONE BIT(3)
#define TRSV_REG339 0x339
#define LN0_MON_RX_CDR_FLD_CK_MODE_DONE BIT(3)
#define TRSV_REG222 0x222
#define LN0_OVRD_RX_CDR_EN BIT(4)
#define LN0_RX_CDR_EN BIT(3)
#define PHY_PMA_TRSV_ADDR(reg, lane) (PHY_APB_ADDR((reg) + \
((lane) * PHY_GS101_LANE_OFFSET)))
#define PHY_TRSV_REG_CFG_GS101(o, v, d) \
PHY_TRSV_REG_CFG_OFFSET(o, v, d, PHY_GS101_LANE_OFFSET)
/* Calibration for phy initialization */
static const struct samsung_ufs_phy_cfg tensor_gs101_pre_init_cfg[] = {
PHY_COMN_REG_CFG(0x43, 0x10, PWR_MODE_ANY),
PHY_COMN_REG_CFG(0x3C, 0x14, PWR_MODE_ANY),
PHY_COMN_REG_CFG(0x46, 0x48, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x200, 0x00, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x201, 0x06, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x202, 0x06, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x203, 0x0a, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x204, 0x00, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x205, 0x11, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x207, 0x0c, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2E1, 0xc0, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x22D, 0xb8, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x234, 0x60, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x238, 0x13, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x239, 0x48, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x23A, 0x01, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x23B, 0x25, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x23C, 0x2a, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x23D, 0x01, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x23E, 0x13, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x23F, 0x13, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x240, 0x4a, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x243, 0x40, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x244, 0x02, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x25D, 0x00, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x25E, 0x3f, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x25F, 0xff, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x273, 0x33, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x274, 0x50, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x284, 0x02, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x285, 0x02, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2A2, 0x04, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x25D, 0x01, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2FA, 0x01, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x286, 0x03, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x287, 0x03, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x288, 0x03, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x289, 0x03, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2B3, 0x04, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2B6, 0x0b, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2B7, 0x0b, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2B8, 0x0b, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2B9, 0x0b, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2BA, 0x0b, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2BB, 0x06, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2BC, 0x06, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2BD, 0x06, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x29E, 0x06, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2E4, 0x1a, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2ED, 0x25, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x269, 0x1a, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x2F4, 0x2f, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x34B, 0x01, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x34C, 0x23, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x34D, 0x23, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x34E, 0x45, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x34F, 0x00, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x350, 0x31, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x351, 0x00, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x352, 0x02, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x353, 0x00, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x354, 0x01, PWR_MODE_ANY),
PHY_COMN_REG_CFG(0x43, 0x18, PWR_MODE_ANY),
PHY_COMN_REG_CFG(0x43, 0x00, PWR_MODE_ANY),
END_UFS_PHY_CFG,
};
static const struct samsung_ufs_phy_cfg tensor_gs101_pre_pwr_hs_config[] = {
PHY_TRSV_REG_CFG_GS101(0x369, 0x11, PWR_MODE_ANY),
PHY_TRSV_REG_CFG_GS101(0x246, 0x03, PWR_MODE_ANY),
};
/* Calibration for HS mode series A/B */
static const struct samsung_ufs_phy_cfg tensor_gs101_post_pwr_hs_config[] = {
PHY_COMN_REG_CFG(0x8, 0x60, PWR_MODE_PWM_ANY),
PHY_TRSV_REG_CFG_GS101(0x222, 0x08, PWR_MODE_PWM_ANY),
PHY_TRSV_REG_CFG_GS101(0x246, 0x01, PWR_MODE_ANY),
END_UFS_PHY_CFG,
};
static const struct samsung_ufs_phy_cfg *tensor_gs101_ufs_phy_cfgs[CFG_TAG_MAX] = {
[CFG_PRE_INIT] = tensor_gs101_pre_init_cfg,
[CFG_PRE_PWR_HS] = tensor_gs101_pre_pwr_hs_config,
[CFG_POST_PWR_HS] = tensor_gs101_post_pwr_hs_config,
};
static const char * const tensor_gs101_ufs_phy_clks[] = {
"ref_clk",
};
static int gs101_phy_wait_for_calibration(struct phy *phy, u8 lane)
{
struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
const unsigned int timeout_us = 40000;
const unsigned int sleep_us = 40;
u32 val;
u32 off;
int err;
off = PHY_PMA_TRSV_ADDR(TRSV_REG338, lane);
err = readl_poll_timeout(ufs_phy->reg_pma + off,
val, (val & LN0_MON_RX_CAL_DONE),
sleep_us, timeout_us);
if (err) {
dev_err(ufs_phy->dev,
"failed to get phy cal done %d\n", err);
}
return err;
}
#define DELAY_IN_US 40
#define RETRY_CNT 100
static int gs101_phy_wait_for_cdr_lock(struct phy *phy, u8 lane)
{
struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
u32 val;
int i;
for (i = 0; i < RETRY_CNT; i++) {
udelay(DELAY_IN_US);
val = readl(ufs_phy->reg_pma +
PHY_PMA_TRSV_ADDR(TRSV_REG339, lane));
if (val & LN0_MON_RX_CDR_FLD_CK_MODE_DONE)
return 0;
udelay(DELAY_IN_US);
/* Override and enable clock data recovery */
writel(LN0_OVRD_RX_CDR_EN, ufs_phy->reg_pma +
PHY_PMA_TRSV_ADDR(TRSV_REG222, lane));
writel(LN0_OVRD_RX_CDR_EN | LN0_RX_CDR_EN,
ufs_phy->reg_pma + PHY_PMA_TRSV_ADDR(TRSV_REG222, lane));
}
dev_err(ufs_phy->dev, "failed to get cdr lock\n");
return -ETIMEDOUT;
}
const struct samsung_ufs_phy_drvdata tensor_gs101_ufs_phy = {
.cfgs = tensor_gs101_ufs_phy_cfgs,
.isol = {
.offset = TENSOR_GS101_PHY_CTRL,
.mask = TENSOR_GS101_PHY_CTRL_MASK,
.en = TENSOR_GS101_PHY_CTRL_EN,
},
.clk_list = tensor_gs101_ufs_phy_clks,
.num_clks = ARRAY_SIZE(tensor_gs101_ufs_phy_clks),
.wait_for_cal = gs101_phy_wait_for_calibration,
.wait_for_cdr = gs101_phy_wait_for_cdr_lock,
};
...@@ -13,11 +13,11 @@ ...@@ -13,11 +13,11 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iopoll.h> #include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/soc/samsung/exynos-pmu.h>
#include "phy-samsung-ufs.h" #include "phy-samsung-ufs.h"
...@@ -45,7 +45,7 @@ static void samsung_ufs_phy_config(struct samsung_ufs_phy *phy, ...@@ -45,7 +45,7 @@ static void samsung_ufs_phy_config(struct samsung_ufs_phy *phy,
} }
} }
static int samsung_ufs_phy_wait_for_lock_acq(struct phy *phy) int samsung_ufs_phy_wait_for_lock_acq(struct phy *phy, u8 lane)
{ {
struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy); struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
const unsigned int timeout_us = 100000; const unsigned int timeout_us = 100000;
...@@ -97,8 +97,21 @@ static int samsung_ufs_phy_calibrate(struct phy *phy) ...@@ -97,8 +97,21 @@ static int samsung_ufs_phy_calibrate(struct phy *phy)
} }
} }
if (ufs_phy->ufs_phy_state == CFG_POST_PWR_HS) for_each_phy_lane(ufs_phy, i) {
err = samsung_ufs_phy_wait_for_lock_acq(phy); if (ufs_phy->ufs_phy_state == CFG_PRE_INIT &&
ufs_phy->drvdata->wait_for_cal) {
err = ufs_phy->drvdata->wait_for_cal(phy, i);
if (err)
goto out;
}
if (ufs_phy->ufs_phy_state == CFG_POST_PWR_HS &&
ufs_phy->drvdata->wait_for_cdr) {
err = ufs_phy->drvdata->wait_for_cdr(phy, i);
if (err)
goto out;
}
}
/** /**
* In Samsung ufshci, PHY need to be calibrated at different * In Samsung ufshci, PHY need to be calibrated at different
...@@ -255,8 +268,8 @@ static int samsung_ufs_phy_probe(struct platform_device *pdev) ...@@ -255,8 +268,8 @@ static int samsung_ufs_phy_probe(struct platform_device *pdev)
goto out; goto out;
} }
phy->reg_pmu = syscon_regmap_lookup_by_phandle( phy->reg_pmu = exynos_get_pmu_regmap_by_phandle(dev->of_node,
dev->of_node, "samsung,pmu-syscon"); "samsung,pmu-syscon");
if (IS_ERR(phy->reg_pmu)) { if (IS_ERR(phy->reg_pmu)) {
err = PTR_ERR(phy->reg_pmu); err = PTR_ERR(phy->reg_pmu);
dev_err(dev, "failed syscon remap for pmu\n"); dev_err(dev, "failed syscon remap for pmu\n");
...@@ -302,6 +315,9 @@ static int samsung_ufs_phy_probe(struct platform_device *pdev) ...@@ -302,6 +315,9 @@ static int samsung_ufs_phy_probe(struct platform_device *pdev)
static const struct of_device_id samsung_ufs_phy_match[] = { static const struct of_device_id samsung_ufs_phy_match[] = {
{ {
.compatible = "google,gs101-ufs-phy",
.data = &tensor_gs101_ufs_phy,
}, {
.compatible = "samsung,exynos7-ufs-phy", .compatible = "samsung,exynos7-ufs-phy",
.data = &exynos7_ufs_phy, .data = &exynos7_ufs_phy,
}, { }, {
......
...@@ -112,6 +112,9 @@ struct samsung_ufs_phy_drvdata { ...@@ -112,6 +112,9 @@ struct samsung_ufs_phy_drvdata {
const char * const *clk_list; const char * const *clk_list;
int num_clks; int num_clks;
u32 cdr_lock_status_offset; u32 cdr_lock_status_offset;
/* SoC's specific operations */
int (*wait_for_cal)(struct phy *phy, u8 lane);
int (*wait_for_cdr)(struct phy *phy, u8 lane);
}; };
struct samsung_ufs_phy { struct samsung_ufs_phy {
...@@ -139,8 +142,11 @@ static inline void samsung_ufs_phy_ctrl_isol( ...@@ -139,8 +142,11 @@ static inline void samsung_ufs_phy_ctrl_isol(
phy->isol.mask, isol ? 0 : phy->isol.en); phy->isol.mask, isol ? 0 : phy->isol.en);
} }
int samsung_ufs_phy_wait_for_lock_acq(struct phy *phy, u8 lane);
extern const struct samsung_ufs_phy_drvdata exynos7_ufs_phy; extern const struct samsung_ufs_phy_drvdata exynos7_ufs_phy;
extern const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy; extern const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy;
extern const struct samsung_ufs_phy_drvdata fsd_ufs_phy; extern const struct samsung_ufs_phy_drvdata fsd_ufs_phy;
extern const struct samsung_ufs_phy_drvdata tensor_gs101_ufs_phy;
#endif /* _PHY_SAMSUNG_UFS_ */ #endif /* _PHY_SAMSUNG_UFS_ */
...@@ -995,15 +995,13 @@ static int xpsgtr_probe(struct platform_device *pdev) ...@@ -995,15 +995,13 @@ static int xpsgtr_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int xpsgtr_remove(struct platform_device *pdev) static void xpsgtr_remove(struct platform_device *pdev)
{ {
struct xpsgtr_dev *gtr_dev = platform_get_drvdata(pdev); struct xpsgtr_dev *gtr_dev = platform_get_drvdata(pdev);
pm_runtime_disable(gtr_dev->dev); pm_runtime_disable(gtr_dev->dev);
pm_runtime_put_noidle(gtr_dev->dev); pm_runtime_put_noidle(gtr_dev->dev);
pm_runtime_set_suspended(gtr_dev->dev); pm_runtime_set_suspended(gtr_dev->dev);
return 0;
} }
static const struct of_device_id xpsgtr_of_match[] = { static const struct of_device_id xpsgtr_of_match[] = {
...@@ -1015,7 +1013,7 @@ MODULE_DEVICE_TABLE(of, xpsgtr_of_match); ...@@ -1015,7 +1013,7 @@ MODULE_DEVICE_TABLE(of, xpsgtr_of_match);
static struct platform_driver xpsgtr_driver = { static struct platform_driver xpsgtr_driver = {
.probe = xpsgtr_probe, .probe = xpsgtr_probe,
.remove = xpsgtr_remove, .remove_new = xpsgtr_remove,
.driver = { .driver = {
.name = "xilinx-psgtr", .name = "xilinx-psgtr",
.of_match_table = xpsgtr_of_match, .of_match_table = xpsgtr_of_match,
......
...@@ -17,4 +17,8 @@ ...@@ -17,4 +17,8 @@
#define QMP_USB43DP_USB3_PHY 0 #define QMP_USB43DP_USB3_PHY 0
#define QMP_USB43DP_DP_PHY 1 #define QMP_USB43DP_DP_PHY 1
/* QMP PCIE PHYs */
#define QMP_PCIE_PIPE_CLK 0
#define QMP_PCIE_PHY_AUX_CLK 1
#endif /* _DT_BINDINGS_PHY_QMP */ #endif /* _DT_BINDINGS_PHY_QMP */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment