From ae38853249538719c12cb7e7bc302550f5513dae Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sat, 26 Sep 2020 22:58:44 +0200 Subject: [PATCH 01/72] phy: fsl-imx8mq-usb: Constify imx8mp_usb_phy_ops The only usage of imx8mp_usb_phy_ops is to assign its address to the data field in the of_device_id struct, which is a const void pointer. Make it const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200926205844.34218-1-rikard.falkeborn@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c index 62d6d6849ad6..47a0c09bc9fa 100644 --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c @@ -131,7 +131,7 @@ static const struct phy_ops imx8mq_usb_phy_ops = { .owner = THIS_MODULE, }; -static struct phy_ops imx8mp_usb_phy_ops = { +static const struct phy_ops imx8mp_usb_phy_ops = { .init = imx8mp_usb_phy_init, .power_on = imx8mq_phy_power_on, .power_off = imx8mq_phy_power_off, From c36f74566cef6b2a377c8830ee216677ddb12706 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 16 Oct 2020 22:46:10 +0200 Subject: [PATCH 02/72] MAINTAINERS: Add entry for Qualcomm IPQ4019 USB PHY Add maintainers entry for the Qualcomm IPQ4019 USB PHY driver. Signed-off-by: Robert Marko Cc: Luka Perkov Link: https://lore.kernel.org/r/20201016204610.2406075-1-robert.marko@sartura.hr Signed-off-by: Vinod Koul --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e73636b75f29..f01ce8f451c8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14547,6 +14547,14 @@ F: Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml F: drivers/mailbox/qcom-ipcc.c F: include/dt-bindings/mailbox/qcom-ipcc.h +QUALCOMM IPQ4019 USB PHY DRIVER +M: Robert Marko +M: Luka Perkov +L: linux-arm-msm@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/phy/qcom-usb-ipq4019-phy.yaml +F: drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c + QUALCOMM RMNET DRIVER M: Subash Abhinov Kasiviswanathan M: Sean Tranchetti From ee19f644c4594d1b8382f1538c19396f92c3c171 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 26 Sep 2020 01:58:27 +0200 Subject: [PATCH 03/72] dt-bindings: phy: Drop reset-gpios from marvell,mmp3-hsic-phy This has been added in error -- the PHY block doesn't have a reset pin. Signed-off-by: Lubomir Rintel Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20200925235828.228626-2-lkundrak@v3.sk Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml b/Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml index 00609ace677c..30e290c57930 100644 --- a/Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml +++ b/Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml @@ -18,27 +18,20 @@ properties: maxItems: 1 description: base address of the device - reset-gpios: - maxItems: 1 - description: GPIO connected to reset - "#phy-cells": const: 0 required: - compatible - reg - - reset-gpios - "#phy-cells" additionalProperties: false examples: - | - #include hsic-phy@f0001800 { compatible = "marvell,mmp3-hsic-phy"; reg = <0xf0001800 0x40>; - reset-gpios = <&gpio 63 GPIO_ACTIVE_HIGH>; #phy-cells = <0>; }; From a1b87f1aac4dba2bac0e0019a9c05f7efa36c37d Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 26 Sep 2020 01:58:28 +0200 Subject: [PATCH 04/72] dt-bindings: phy: Allow BSD licensing of marvell,mmp3-hsic-phy.yaml I wrote this binding and I'm fine with it being GPL + BSD dual-licensed, as is recommended for new DT bindings. Signed-off-by: Lubomir Rintel Acked-by: Rob Herring Link: https://lore.kernel.org/r/20200925235828.228626-3-lkundrak@v3.sk Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml b/Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml index 30e290c57930..ff255aa4cc10 100644 --- a/Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml +++ b/Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) # Copyright 2019 Lubomir Rintel %YAML 1.2 --- From 0347c69214f4b600f40c0dc58945dc2798e2b3d9 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 26 Sep 2020 01:58:29 +0200 Subject: [PATCH 05/72] phy: Add USB HSIC PHY driver for Marvell MMP3 SoC Add PHY driver for the HSICs found on Marvell MMP3 SoC. The driver is rather straightforward -- the PHY essentially just needs to be enabled. Signed-off-by: Lubomir Rintel Link: https://lore.kernel.org/r/20200925235828.228626-4-lkundrak@v3.sk Signed-off-by: Vinod Koul --- drivers/phy/marvell/Kconfig | 12 +++++ drivers/phy/marvell/Makefile | 1 + drivers/phy/marvell/phy-mmp3-hsic.c | 82 +++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 drivers/phy/marvell/phy-mmp3-hsic.c diff --git a/drivers/phy/marvell/Kconfig b/drivers/phy/marvell/Kconfig index 8f6273c837ec..6c96f2bf5266 100644 --- a/drivers/phy/marvell/Kconfig +++ b/drivers/phy/marvell/Kconfig @@ -116,3 +116,15 @@ config PHY_MMP3_USB The PHY driver will be used by Marvell udc/ehci/otg driver. To compile this driver as a module, choose M here. + +config PHY_MMP3_HSIC + tristate "Marvell MMP3 USB HSIC PHY Driver" + depends on MACH_MMP3_DT || COMPILE_TEST + select GENERIC_PHY + help + Enable this to support Marvell MMP3 USB HSIC PHY driver for + Marvell MMP3 SoC. This driver will be used my the Marvell EHCI + driver to initialize the interface to internal USB HSIC + components on MMP3-based boards. + + To compile this driver as a module, choose M here. diff --git a/drivers/phy/marvell/Makefile b/drivers/phy/marvell/Makefile index 5a106b1549f4..7f296ef02829 100644 --- a/drivers/phy/marvell/Makefile +++ b/drivers/phy/marvell/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o obj-$(CONFIG_PHY_MMP3_USB) += phy-mmp3-usb.o +obj-$(CONFIG_PHY_MMP3_HSIC) += phy-mmp3-hsic.o obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY) += phy-mvebu-a3700-comphy.o obj-$(CONFIG_PHY_MVEBU_A3700_UTMI) += phy-mvebu-a3700-utmi.o obj-$(CONFIG_PHY_MVEBU_A38X_COMPHY) += phy-armada38x-comphy.o diff --git a/drivers/phy/marvell/phy-mmp3-hsic.c b/drivers/phy/marvell/phy-mmp3-hsic.c new file mode 100644 index 000000000000..47c1e8894939 --- /dev/null +++ b/drivers/phy/marvell/phy-mmp3-hsic.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Lubomir Rintel + */ + +#include +#include +#include +#include +#include + +#define HSIC_CTRL 0x08 +#define HSIC_ENABLE BIT(7) +#define PLL_BYPASS BIT(4) + +static int mmp3_hsic_phy_init(struct phy *phy) +{ + void __iomem *base = (void __iomem *)phy_get_drvdata(phy); + u32 hsic_ctrl; + + hsic_ctrl = readl_relaxed(base + HSIC_CTRL); + hsic_ctrl |= HSIC_ENABLE; + hsic_ctrl |= PLL_BYPASS; + writel_relaxed(hsic_ctrl, base + HSIC_CTRL); + + return 0; +} + +static const struct phy_ops mmp3_hsic_phy_ops = { + .init = mmp3_hsic_phy_init, + .owner = THIS_MODULE, +}; + +static const struct of_device_id mmp3_hsic_phy_of_match[] = { + { .compatible = "marvell,mmp3-hsic-phy", }, + { }, +}; +MODULE_DEVICE_TABLE(of, mmp3_hsic_phy_of_match); + +static int mmp3_hsic_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct phy_provider *provider; + struct resource *resource; + void __iomem *base; + struct phy *phy; + + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, resource); + if (IS_ERR(base)) { + dev_err(dev, "failed to remap PHY regs\n"); + return PTR_ERR(base); + } + + phy = devm_phy_create(dev, NULL, &mmp3_hsic_phy_ops); + if (IS_ERR(phy)) { + dev_err(dev, "failed to create PHY\n"); + return PTR_ERR(phy); + } + + phy_set_drvdata(phy, (void *)base); + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (IS_ERR(provider)) { + dev_err(dev, "failed to register PHY provider\n"); + return PTR_ERR(provider); + } + + return 0; +} + +static struct platform_driver mmp3_hsic_phy_driver = { + .probe = mmp3_hsic_phy_probe, + .driver = { + .name = "mmp3-hsic-phy", + .of_match_table = mmp3_hsic_phy_of_match, + }, +}; +module_platform_driver(mmp3_hsic_phy_driver); + +MODULE_AUTHOR("Lubomir Rintel "); +MODULE_DESCRIPTION("Marvell MMP3 USB HSIC PHY Driver"); +MODULE_LICENSE("GPL"); From 5594b407a48b1fcf6da1ecbfe4a647f2ce3c284a Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Tue, 27 Oct 2020 22:30:29 +0530 Subject: [PATCH 06/72] dt-bindings: phy: qcom,qmp: Add SM8250 PCIe PHY bindings Add the below three PCIe PHYs found in SM8250 to the QMP binding: QMP GEN3x1 PHY - 1 lane QMP GEN3x2 PHY - 2 lanes QMP Modem PHY - 2 lanes Signed-off-by: Manivannan Sadhasivam Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201027170033.8475-2-manivannan.sadhasivam@linaro.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml index 185cdea9cf81..ec05db374645 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml @@ -31,6 +31,9 @@ properties: - qcom,sdm845-qmp-usb3-uni-phy - qcom,sm8150-qmp-ufs-phy - qcom,sm8250-qmp-ufs-phy + - qcom,sm8250-qmp-gen3x1-pcie-phy + - qcom,sm8250-qmp-gen3x2-pcie-phy + - qcom,sm8250-qmp-modem-pcie-phy reg: items: @@ -259,6 +262,9 @@ allOf: enum: - qcom,sdm845-qhp-pcie-phy - qcom,sdm845-qmp-pcie-phy + - qcom,sm8250-qmp-gen3x1-pcie-phy + - qcom,sm8250-qmp-gen3x2-pcie-phy + - qcom,sm8250-qmp-modem-pcie-phy then: properties: clocks: From 6edf7700a9dde8d3e494d1b390b5284329642a70 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Tue, 27 Oct 2020 22:30:30 +0530 Subject: [PATCH 07/72] phy: qcom-qmp: Add SM8250 PCIe QMP PHYs SM8250 has multiple different PHY versions: QMP GEN3x1 PHY - 1 lane QMP GEN3x2 PHY - 2 lanes QMP Modem PHY - 2 lanes Add support for these with relevant init sequence. In order to abstract the init sequence, this commit introduces secondary tables which can be used to factor out the unique sequence for each PHY while the former tables can have the common sequence. Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20201027170033.8475-3-manivannan.sadhasivam@linaro.org Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp.c | 281 +++++++++++++++++++++++++++- drivers/phy/qualcomm/phy-qcom-qmp.h | 18 ++ 2 files changed, 295 insertions(+), 4 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index 5d33ad4d06f2..5a941730377f 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -217,6 +217,13 @@ static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_READY_STATUS] = 0x160, }; +static const unsigned int sm8250_pcie_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_SW_RESET] = 0x00, + [QPHY_START_CTRL] = 0x44, + [QPHY_PCS_STATUS] = 0x14, + [QPHY_PCS_POWER_DOWN_CONTROL] = 0x40, +}; + static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_START_CTRL] = QPHY_V4_PCS_UFS_PHY_START, [QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_UFS_READY_STATUS, @@ -1824,6 +1831,149 @@ static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_tbl[] = { QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21), }; +static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_pcie_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x35), + QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1b), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x30), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0x77), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x12), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE, 0x33), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0f), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x05), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG2, 0x0f), +}; + +static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07), +}; + /* struct qmp_phy_cfg - per-PHY initialization config */ struct qmp_phy_cfg { /* phy-type - PCIE/UFS/USB */ @@ -1834,14 +1984,24 @@ struct qmp_phy_cfg { /* Init sequence for PHY blocks - serdes, tx, rx, pcs */ const struct qmp_phy_init_tbl *serdes_tbl; int serdes_tbl_num; + const struct qmp_phy_init_tbl *serdes_tbl_sec; + int serdes_tbl_num_sec; const struct qmp_phy_init_tbl *tx_tbl; int tx_tbl_num; + const struct qmp_phy_init_tbl *tx_tbl_sec; + int tx_tbl_num_sec; const struct qmp_phy_init_tbl *rx_tbl; int rx_tbl_num; + const struct qmp_phy_init_tbl *rx_tbl_sec; + int rx_tbl_num_sec; const struct qmp_phy_init_tbl *pcs_tbl; int pcs_tbl_num; + const struct qmp_phy_init_tbl *pcs_tbl_sec; + int pcs_tbl_num_sec; const struct qmp_phy_init_tbl *pcs_misc_tbl; int pcs_misc_tbl_num; + const struct qmp_phy_init_tbl *pcs_misc_tbl_sec; + int pcs_misc_tbl_num_sec; /* Init sequence for DP PHY block link rates */ const struct qmp_phy_init_tbl *serdes_tbl_rbr; @@ -2245,6 +2405,83 @@ static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = { .pwrdn_delay_max = 1005, /* us */ }; +static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = { + .type = PHY_TYPE_PCIE, + .nlanes = 1, + + .serdes_tbl = sm8250_qmp_pcie_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl), + .serdes_tbl_sec = sm8250_qmp_gen3x1_pcie_serdes_tbl, + .serdes_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_serdes_tbl), + .tx_tbl = sm8250_qmp_pcie_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl), + .rx_tbl = sm8250_qmp_pcie_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl), + .rx_tbl_sec = sm8250_qmp_gen3x1_pcie_rx_tbl, + .rx_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_rx_tbl), + .pcs_tbl = sm8250_qmp_pcie_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl), + .pcs_tbl_sec = sm8250_qmp_gen3x1_pcie_pcs_tbl, + .pcs_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_tbl), + .pcs_misc_tbl = sm8250_qmp_pcie_pcs_misc_tbl, + .pcs_misc_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl), + .pcs_misc_tbl_sec = sm8250_qmp_gen3x1_pcie_pcs_misc_tbl, + .pcs_misc_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_misc_tbl), + .clk_list = sdm845_pciephy_clk_l, + .num_clks = ARRAY_SIZE(sdm845_pciephy_clk_l), + .reset_list = sdm845_pciephy_reset_l, + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = sm8250_pcie_regs_layout, + + .start_ctrl = PCS_START | SERDES_START, + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, + + .has_pwrdn_delay = true, + .pwrdn_delay_min = 995, /* us */ + .pwrdn_delay_max = 1005, /* us */ +}; + +static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = { + .type = PHY_TYPE_PCIE, + .nlanes = 2, + + .serdes_tbl = sm8250_qmp_pcie_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl), + .tx_tbl = sm8250_qmp_pcie_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl), + .tx_tbl_sec = sm8250_qmp_gen3x2_pcie_tx_tbl, + .tx_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_tx_tbl), + .rx_tbl = sm8250_qmp_pcie_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl), + .rx_tbl_sec = sm8250_qmp_gen3x2_pcie_rx_tbl, + .rx_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_rx_tbl), + .pcs_tbl = sm8250_qmp_pcie_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl), + .pcs_tbl_sec = sm8250_qmp_gen3x2_pcie_pcs_tbl, + .pcs_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_tbl), + .pcs_misc_tbl = sm8250_qmp_pcie_pcs_misc_tbl, + .pcs_misc_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl), + .pcs_misc_tbl_sec = sm8250_qmp_gen3x2_pcie_pcs_misc_tbl, + .pcs_misc_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_misc_tbl), + .clk_list = sdm845_pciephy_clk_l, + .num_clks = ARRAY_SIZE(sdm845_pciephy_clk_l), + .reset_list = sdm845_pciephy_reset_l, + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = sm8250_pcie_regs_layout, + + .start_ctrl = PCS_START | SERDES_START, + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, + + .is_dual_lane_phy = true, + .has_pwrdn_delay = true, + .pwrdn_delay_min = 995, /* us */ + .pwrdn_delay_max = 1005, /* us */ +}; + static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = { .type = PHY_TYPE_USB3, .nlanes = 1, @@ -2629,6 +2866,9 @@ static int qcom_qmp_phy_serdes_init(struct qmp_phy *qphy) int ret; qcom_qmp_phy_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num); + if (cfg->serdes_tbl_sec) + qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl_sec, + cfg->serdes_tbl_num_sec); if (cfg->type == PHY_TYPE_DP) { switch (dp_opts->link_rate) { @@ -3117,10 +3357,19 @@ static int qcom_qmp_phy_power_on(struct phy *phy) /* Tx, Rx, and PCS configurations */ qcom_qmp_phy_configure_lane(tx, cfg->regs, cfg->tx_tbl, cfg->tx_tbl_num, 1); + if (cfg->tx_tbl_sec) + qcom_qmp_phy_configure_lane(tx, cfg->regs, cfg->tx_tbl_sec, + cfg->tx_tbl_num_sec, 1); + /* Configuration for other LANE for USB-DP combo PHY */ - if (cfg->is_dual_lane_phy) + if (cfg->is_dual_lane_phy) { qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs, cfg->tx_tbl, cfg->tx_tbl_num, 2); + if (cfg->tx_tbl_sec) + qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs, + cfg->tx_tbl_sec, + cfg->tx_tbl_num_sec, 2); + } /* Configure special DP tx tunings */ if (cfg->type == PHY_TYPE_DP) @@ -3128,16 +3377,28 @@ static int qcom_qmp_phy_power_on(struct phy *phy) qcom_qmp_phy_configure_lane(rx, cfg->regs, cfg->rx_tbl, cfg->rx_tbl_num, 1); + if (cfg->rx_tbl_sec) + qcom_qmp_phy_configure_lane(rx, cfg->regs, + cfg->rx_tbl_sec, cfg->rx_tbl_num_sec, 1); - if (cfg->is_dual_lane_phy) + if (cfg->is_dual_lane_phy) { qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs, cfg->rx_tbl, cfg->rx_tbl_num, 2); + if (cfg->rx_tbl_sec) + qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs, + cfg->rx_tbl_sec, + cfg->rx_tbl_num_sec, 2); + } /* Configure link rate, swing, etc. */ - if (cfg->type == PHY_TYPE_DP) + if (cfg->type == PHY_TYPE_DP) { qcom_qmp_phy_configure_dp_phy(qphy); - else + } else { qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num); + if (cfg->pcs_tbl_sec) + qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl_sec, + cfg->pcs_tbl_num_sec); + } ret = reset_control_deassert(qmp->ufs_reset); if (ret) @@ -3145,6 +3406,9 @@ static int qcom_qmp_phy_power_on(struct phy *phy) qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl, cfg->pcs_misc_tbl_num); + if (cfg->pcs_misc_tbl_sec) + qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl_sec, + cfg->pcs_misc_tbl_num_sec); /* * Pull out PHY from POWER DOWN state. @@ -3900,6 +4164,15 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = { }, { .compatible = "qcom,sm8250-qmp-usb3-uni-phy", .data = &sm8250_usb3_uniphy_cfg, + }, { + .compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy", + .data = &sm8250_qmp_gen3x1_pciephy_cfg, + }, { + .compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy", + .data = &sm8250_qmp_gen3x2_pciephy_cfg, + }, { + .compatible = "qcom,sm8250-qmp-modem-pcie-phy", + .data = &sm8250_qmp_gen3x2_pciephy_cfg, }, { }, }; diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h index b7c530088a6c..db92a461dd2e 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -403,6 +403,7 @@ #define QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0 0x028 #define QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1 0x030 #define QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1 0x034 +#define QSERDES_V4_COM_CLK_ENABLE1 0x048 #define QSERDES_V4_COM_SYSCLK_BUF_ENABLE 0x050 #define QSERDES_V4_COM_PLL_IVCO 0x058 #define QSERDES_V4_COM_CMN_IPTRIM 0x060 @@ -432,6 +433,7 @@ #define QSERDES_V4_COM_VCO_TUNE1_MODE1 0x118 #define QSERDES_V4_COM_VCO_TUNE2_MODE1 0x11c #define QSERDES_V4_COM_VCO_TUNE_INITVAL2 0x124 +#define QSERDES_V4_COM_CLK_SELECT 0x154 #define QSERDES_V4_COM_HSCLK_SEL 0x158 #define QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL 0x15c #define QSERDES_V4_COM_CORECLK_DIV_MODE1 0x16c @@ -471,12 +473,14 @@ #define QSERDES_V4_RX_UCDR_SB2_GAIN1 0x054 #define QSERDES_V4_RX_UCDR_SB2_GAIN2 0x058 #define QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE 0x060 +#define QSERDES_V4_RX_RCLK_AUXDATA_SEL 0x064 #define QSERDES_V4_RX_AC_JTAG_ENABLE 0x068 #define QSERDES_V4_RX_AC_JTAG_MODE 0x078 #define QSERDES_V4_RX_RX_TERM_BW 0x080 #define QSERDES_V4_RX_VGA_CAL_CNTRL1 0x0d4 #define QSERDES_V4_RX_VGA_CAL_CNTRL2 0x0d8 #define QSERDES_V4_RX_GM_CAL 0x0dc +#define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1 0x0e8 #define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2 0x0ec #define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3 0x0f0 #define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4 0x0f4 @@ -485,6 +489,7 @@ #define QSERDES_V4_RX_RX_IDAC_MEASURE_TIME 0x100 #define QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110 #define QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x114 +#define QSERDES_V4_RX_SIGDET_ENABLES 0x118 #define QSERDES_V4_RX_SIGDET_CNTRL 0x11c #define QSERDES_V4_RX_SIGDET_LVL 0x120 #define QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL 0x124 @@ -806,4 +811,17 @@ #define QPHY_V4_PCS_MISC_TYPEC_STATUS 0x10 #define QPHY_V4_PCS_MISC_PLACEHOLDER_STATUS 0x14 +/* Only for QMP V4 PHY - PCS_PCIE registers (same as PCS_MISC?) */ +#define QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2 0x0c +#define QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4 0x14 +#define QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x1c +#define QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L 0x40 +#define QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L 0x48 +#define QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1 0x50 +#define QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS 0x90 +#define QPHY_V4_PCS_PCIE_EQ_CONFIG2 0xa4 +#define QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE 0xb4 +#define QPHY_V4_PCS_PCIE_PRESET_P10_PRE 0xbc +#define QPHY_V4_PCS_PCIE_PRESET_P10_POST 0xe0 + #endif From 08d4deda6970a91313955934487a37077b1792cb Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:34 +0800 Subject: [PATCH 08/72] phy: allwinner: convert to devm_platform_ioremap_resource(_byname) Use devm_platform_ioremap_resource(_byname) to simplify code Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1604642930-29019-1-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/allwinner/phy-sun4i-usb.c | 8 ++------ drivers/phy/allwinner/phy-sun50i-usb3.c | 4 +--- drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 4 +--- drivers/phy/allwinner/phy-sun9i-usb.c | 4 +--- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index 651d5e2a25ce..406d5943f8a8 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -686,7 +686,6 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct phy_provider *phy_provider; - struct resource *res; int i, ret; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); @@ -700,8 +699,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) if (!data->cfg) return -EINVAL; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl"); - data->base = devm_ioremap_resource(dev, res); + data->base = devm_platform_ioremap_resource_byname(pdev, "phy_ctrl"); if (IS_ERR(data->base)) return PTR_ERR(data->base); @@ -796,9 +794,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */ snprintf(name, sizeof(name), "pmu%d", i); - res = platform_get_resource_byname(pdev, - IORESOURCE_MEM, name); - phy->pmu = devm_ioremap_resource(dev, res); + phy->pmu = devm_platform_ioremap_resource_byname(pdev, name); if (IS_ERR(phy->pmu)) return PTR_ERR(phy->pmu); } diff --git a/drivers/phy/allwinner/phy-sun50i-usb3.c b/drivers/phy/allwinner/phy-sun50i-usb3.c index b1c04f71a31d..84055b720016 100644 --- a/drivers/phy/allwinner/phy-sun50i-usb3.c +++ b/drivers/phy/allwinner/phy-sun50i-usb3.c @@ -134,7 +134,6 @@ static int sun50i_usb3_phy_probe(struct platform_device *pdev) struct sun50i_usb3_phy *phy; struct device *dev = &pdev->dev; struct phy_provider *phy_provider; - struct resource *res; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) @@ -153,8 +152,7 @@ static int sun50i_usb3_phy_probe(struct platform_device *pdev) return PTR_ERR(phy->reset); } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->regs = devm_ioremap_resource(dev, res); + phy->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy->regs)) return PTR_ERR(phy->regs); diff --git a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c index 1fa761ba6cbb..f0bc87d654d4 100644 --- a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c +++ b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c @@ -253,15 +253,13 @@ static int sun6i_dphy_probe(struct platform_device *pdev) { struct phy_provider *phy_provider; struct sun6i_dphy *dphy; - struct resource *res; void __iomem *regs; dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL); if (!dphy) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs = devm_ioremap_resource(&pdev->dev, res); + regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(regs)) { dev_err(&pdev->dev, "Couldn't map the DPHY encoder registers\n"); return PTR_ERR(regs); diff --git a/drivers/phy/allwinner/phy-sun9i-usb.c b/drivers/phy/allwinner/phy-sun9i-usb.c index fc6784dd7fa0..2f9e60c188b8 100644 --- a/drivers/phy/allwinner/phy-sun9i-usb.c +++ b/drivers/phy/allwinner/phy-sun9i-usb.c @@ -117,7 +117,6 @@ static int sun9i_usb_phy_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct phy_provider *phy_provider; - struct resource *res; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) @@ -156,8 +155,7 @@ static int sun9i_usb_phy_probe(struct platform_device *pdev) } } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->pmu = devm_ioremap_resource(dev, res); + phy->pmu = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy->pmu)) return PTR_ERR(phy->pmu); From 202de02556bb49ba35f5c7675934b9b14bbb2a56 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:35 +0800 Subject: [PATCH 09/72] phy: amlogic: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Reviewed-by: Remi Pommarel Reviewed-by: Martin Blumenstingl Link: https://lore.kernel.org/r/1604642930-29019-2-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-axg-pcie.c | 4 +--- drivers/phy/amlogic/phy-meson-g12a-usb2.c | 4 +--- drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c | 4 +--- drivers/phy/amlogic/phy-meson-gxl-usb2.c | 4 +--- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-axg-pcie.c b/drivers/phy/amlogic/phy-meson-axg-pcie.c index 377ed0dcd0d9..58a7507a8422 100644 --- a/drivers/phy/amlogic/phy-meson-axg-pcie.c +++ b/drivers/phy/amlogic/phy-meson-axg-pcie.c @@ -129,7 +129,6 @@ static int phy_axg_pcie_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phy_axg_pcie_priv *priv; struct device_node *np = dev->of_node; - struct resource *res; void __iomem *base; int ret; @@ -145,8 +144,7 @@ static int phy_axg_pcie_probe(struct platform_device *pdev) return ret; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb2.c b/drivers/phy/amlogic/phy-meson-g12a-usb2.c index b26e30e1afaf..9d1efa0d9394 100644 --- a/drivers/phy/amlogic/phy-meson-g12a-usb2.c +++ b/drivers/phy/amlogic/phy-meson-g12a-usb2.c @@ -292,7 +292,6 @@ static int phy_meson_g12a_usb2_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct phy_provider *phy_provider; - struct resource *res; struct phy_meson_g12a_usb2_priv *priv; struct phy *phy; void __iomem *base; @@ -305,8 +304,7 @@ static int phy_meson_g12a_usb2_probe(struct platform_device *pdev) priv->dev = dev; platform_set_drvdata(pdev, priv); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c index 08e322789e59..ebe3d0ddd304 100644 --- a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c +++ b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c @@ -386,7 +386,6 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct phy_g12a_usb3_pcie_priv *priv; - struct resource *res; struct phy_provider *phy_provider; void __iomem *base; int ret; @@ -395,8 +394,7 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/phy/amlogic/phy-meson-gxl-usb2.c b/drivers/phy/amlogic/phy-meson-gxl-usb2.c index 43ec9bf24abf..875afb2672c7 100644 --- a/drivers/phy/amlogic/phy-meson-gxl-usb2.c +++ b/drivers/phy/amlogic/phy-meson-gxl-usb2.c @@ -230,7 +230,6 @@ static int phy_meson_gxl_usb2_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct phy_provider *phy_provider; - struct resource *res; struct phy_meson_gxl_usb2_priv *priv; struct phy *phy; void __iomem *base; @@ -242,8 +241,7 @@ static int phy_meson_gxl_usb2_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); From f669bc8b9f7beb6b1936882a2c3670dc1bd985ba Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:36 +0800 Subject: [PATCH 10/72] phy: broadcom: convert to devm_platform_ioremap_resource(_byname) Use devm_platform_ioremap_resource(_byname) to simplify code Signed-off-by: Chunfeng Yun Reviewed-by: Florian Fainelli Cc: Al Cooper Link: https://lore.kernel.org/r/1604642930-29019-3-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/broadcom/phy-bcm-cygnus-pcie.c | 4 +--- drivers/phy/broadcom/phy-bcm-kona-usb2.c | 4 +--- drivers/phy/broadcom/phy-bcm-ns-usb2.c | 4 +--- drivers/phy/broadcom/phy-bcm-ns-usb3.c | 7 ++----- drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c | 13 ++++--------- drivers/phy/broadcom/phy-bcm-sr-pcie.c | 5 +---- drivers/phy/broadcom/phy-bcm-sr-usb.c | 4 +--- drivers/phy/broadcom/phy-brcm-sata.c | 8 ++------ 8 files changed, 13 insertions(+), 36 deletions(-) diff --git a/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c b/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c index b074682d9dd8..548e46776100 100644 --- a/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c +++ b/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c @@ -126,7 +126,6 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev) struct device_node *node = dev->of_node, *child; struct cygnus_pcie_phy_core *core; struct phy_provider *provider; - struct resource *res; unsigned cnt = 0; int ret; @@ -141,8 +140,7 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev) core->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - core->base = devm_ioremap_resource(dev, res); + core->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(core->base)) return PTR_ERR(core->base); diff --git a/drivers/phy/broadcom/phy-bcm-kona-usb2.c b/drivers/phy/broadcom/phy-bcm-kona-usb2.c index 6459296d9bf9..e9cc5f2cb89a 100644 --- a/drivers/phy/broadcom/phy-bcm-kona-usb2.c +++ b/drivers/phy/broadcom/phy-bcm-kona-usb2.c @@ -94,7 +94,6 @@ static int bcm_kona_usb2_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct bcm_kona_usb *phy; - struct resource *res; struct phy *gphy; struct phy_provider *phy_provider; @@ -102,8 +101,7 @@ static int bcm_kona_usb2_probe(struct platform_device *pdev) if (!phy) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->regs = devm_ioremap_resource(&pdev->dev, res); + phy->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy->regs)) return PTR_ERR(phy->regs); diff --git a/drivers/phy/broadcom/phy-bcm-ns-usb2.c b/drivers/phy/broadcom/phy-bcm-ns-usb2.c index 9f2f84d65dcd..4b015b8a71c3 100644 --- a/drivers/phy/broadcom/phy-bcm-ns-usb2.c +++ b/drivers/phy/broadcom/phy-bcm-ns-usb2.c @@ -83,7 +83,6 @@ static int bcm_ns_usb2_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct bcm_ns_usb2 *usb2; - struct resource *res; struct phy_provider *phy_provider; usb2 = devm_kzalloc(&pdev->dev, sizeof(*usb2), GFP_KERNEL); @@ -91,8 +90,7 @@ static int bcm_ns_usb2_probe(struct platform_device *pdev) return -ENOMEM; usb2->dev = dev; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmu"); - usb2->dmu = devm_ioremap_resource(dev, res); + usb2->dmu = devm_platform_ioremap_resource_byname(pdev, "dmu"); if (IS_ERR(usb2->dmu)) { dev_err(dev, "Failed to map DMU regs\n"); return PTR_ERR(usb2->dmu); diff --git a/drivers/phy/broadcom/phy-bcm-ns-usb3.c b/drivers/phy/broadcom/phy-bcm-ns-usb3.c index 47b029fbebbd..42baf4d6dd5d 100644 --- a/drivers/phy/broadcom/phy-bcm-ns-usb3.c +++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c @@ -305,7 +305,6 @@ static int bcm_ns_usb3_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const struct of_device_id *of_id; struct bcm_ns_usb3 *usb3; - struct resource *res; struct phy_provider *phy_provider; usb3 = devm_kzalloc(dev, sizeof(*usb3), GFP_KERNEL); @@ -319,15 +318,13 @@ static int bcm_ns_usb3_probe(struct platform_device *pdev) return -EINVAL; usb3->family = (enum bcm_ns_family)of_id->data; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmp"); - usb3->dmp = devm_ioremap_resource(dev, res); + usb3->dmp = devm_platform_ioremap_resource_byname(pdev, "dmp"); if (IS_ERR(usb3->dmp)) { dev_err(dev, "Failed to map DMP regs\n"); return PTR_ERR(usb3->dmp); } - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ccb-mii"); - usb3->ccb_mii = devm_ioremap_resource(dev, res); + usb3->ccb_mii = devm_platform_ioremap_resource_byname(pdev, "ccb-mii"); if (IS_ERR(usb3->ccb_mii)) { dev_err(dev, "Failed to map ChipCommon B MII regs\n"); return PTR_ERR(usb3->ccb_mii); diff --git a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c index 9630ac127366..65a399acc845 100644 --- a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c +++ b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c @@ -293,7 +293,6 @@ static int ns2_drd_phy_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct ns2_phy_driver *driver; struct ns2_phy_data *data; - struct resource *res; int ret; u32 val; @@ -307,23 +306,19 @@ static int ns2_drd_phy_probe(struct platform_device *pdev) if (!driver->data) return -ENOMEM; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "icfg"); - driver->icfgdrd_regs = devm_ioremap_resource(dev, res); + driver->icfgdrd_regs = devm_platform_ioremap_resource_byname(pdev, "icfg"); if (IS_ERR(driver->icfgdrd_regs)) return PTR_ERR(driver->icfgdrd_regs); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rst-ctrl"); - driver->idmdrd_rst_ctrl = devm_ioremap_resource(dev, res); + driver->idmdrd_rst_ctrl = devm_platform_ioremap_resource_byname(pdev, "rst-ctrl"); if (IS_ERR(driver->idmdrd_rst_ctrl)) return PTR_ERR(driver->idmdrd_rst_ctrl); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crmu-ctrl"); - driver->crmu_usb2_ctrl = devm_ioremap_resource(dev, res); + driver->crmu_usb2_ctrl = devm_platform_ioremap_resource_byname(pdev, "crmu-ctrl"); if (IS_ERR(driver->crmu_usb2_ctrl)) return PTR_ERR(driver->crmu_usb2_ctrl); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb2-strap"); - driver->usb2h_strap_reg = devm_ioremap_resource(dev, res); + driver->usb2h_strap_reg = devm_platform_ioremap_resource_byname(pdev, "usb2-strap"); if (IS_ERR(driver->usb2h_strap_reg)) return PTR_ERR(driver->usb2h_strap_reg); diff --git a/drivers/phy/broadcom/phy-bcm-sr-pcie.c b/drivers/phy/broadcom/phy-bcm-sr-pcie.c index 96a3af126a78..8a4aadf166cf 100644 --- a/drivers/phy/broadcom/phy-bcm-sr-pcie.c +++ b/drivers/phy/broadcom/phy-bcm-sr-pcie.c @@ -217,7 +217,6 @@ static int sr_pcie_phy_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; struct sr_pcie_phy_core *core; - struct resource *res; struct phy_provider *provider; unsigned int phy_idx = 0; @@ -226,9 +225,7 @@ static int sr_pcie_phy_probe(struct platform_device *pdev) return -ENOMEM; core->dev = dev; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - core->base = devm_ioremap_resource(core->dev, res); + core->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(core->base)) return PTR_ERR(core->base); diff --git a/drivers/phy/broadcom/phy-bcm-sr-usb.c b/drivers/phy/broadcom/phy-bcm-sr-usb.c index c3e99ad17487..0002da3b5b5d 100644 --- a/drivers/phy/broadcom/phy-bcm-sr-usb.c +++ b/drivers/phy/broadcom/phy-bcm-sr-usb.c @@ -300,14 +300,12 @@ static int bcm_usb_phy_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *dn = dev->of_node; const struct of_device_id *of_id; - struct resource *res; void __iomem *regs; int ret; enum bcm_usb_phy_version version; struct phy_provider *phy_provider; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs = devm_ioremap_resource(dev, res); + regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(regs)) return PTR_ERR(regs); diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c index 18251f232172..53942973f508 100644 --- a/drivers/phy/broadcom/phy-brcm-sata.c +++ b/drivers/phy/broadcom/phy-brcm-sata.c @@ -726,7 +726,6 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) struct device_node *dn = dev->of_node, *child; const struct of_device_id *of_id; struct brcm_sata_phy *priv; - struct resource *res; struct phy_provider *provider; int ret, count = 0; @@ -739,8 +738,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) dev_set_drvdata(dev, priv); priv->dev = dev; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); - priv->phy_base = devm_ioremap_resource(dev, res); + priv->phy_base = devm_platform_ioremap_resource_byname(pdev, "phy"); if (IS_ERR(priv->phy_base)) return PTR_ERR(priv->phy_base); @@ -751,9 +749,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) priv->version = BRCM_SATA_PHY_STB_28NM; if (priv->version == BRCM_SATA_PHY_IPROC_NS2) { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "phy-ctrl"); - priv->ctrl_base = devm_ioremap_resource(dev, res); + priv->ctrl_base = devm_platform_ioremap_resource_byname(pdev, "phy-ctrl"); if (IS_ERR(priv->ctrl_base)) return PTR_ERR(priv->ctrl_base); } From fa62909400fa5abc53cc76cb4917bb92b8bf3a2d Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:37 +0800 Subject: [PATCH 11/72] phy: cadence: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Acked-by: Peter Chen Link: https://lore.kernel.org/r/1604642930-29019-4-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/cadence/cdns-dphy.c | 4 +--- drivers/phy/cadence/phy-cadence-salvo.c | 4 +--- drivers/phy/cadence/phy-cadence-sierra.c | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c index 90c4e9b5aac8..ba042e39cfaf 100644 --- a/drivers/phy/cadence/cdns-dphy.c +++ b/drivers/phy/cadence/cdns-dphy.c @@ -314,7 +314,6 @@ static int cdns_dphy_probe(struct platform_device *pdev) { struct phy_provider *phy_provider; struct cdns_dphy *dphy; - struct resource *res; int ret; dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL); @@ -326,8 +325,7 @@ static int cdns_dphy_probe(struct platform_device *pdev) if (!dphy->ops) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dphy->regs = devm_ioremap_resource(&pdev->dev, res); + dphy->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(dphy->regs)) return PTR_ERR(dphy->regs); diff --git a/drivers/phy/cadence/phy-cadence-salvo.c b/drivers/phy/cadence/phy-cadence-salvo.c index 88e239adc3b8..51c0b98f5fd7 100644 --- a/drivers/phy/cadence/phy-cadence-salvo.c +++ b/drivers/phy/cadence/phy-cadence-salvo.c @@ -263,7 +263,6 @@ static int cdns_salvo_phy_probe(struct platform_device *pdev) struct phy_provider *phy_provider; struct device *dev = &pdev->dev; struct cdns_salvo_phy *salvo_phy; - struct resource *res; const struct of_device_id *match; struct cdns_salvo_data *data; @@ -281,8 +280,7 @@ static int cdns_salvo_phy_probe(struct platform_device *pdev) if (IS_ERR(salvo_phy->clk)) return PTR_ERR(salvo_phy->clk); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - salvo_phy->base = devm_ioremap_resource(dev, res); + salvo_phy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(salvo_phy->base)) return PTR_ERR(salvo_phy->base); diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c index 453ef26fa1c7..26a0badabe38 100644 --- a/drivers/phy/cadence/phy-cadence-sierra.c +++ b/drivers/phy/cadence/phy-cadence-sierra.c @@ -479,7 +479,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) const struct of_device_id *match; struct cdns_sierra_data *data; unsigned int id_value; - struct resource *res; int i, ret, node = 0; void __iomem *base; struct clk *clk; @@ -502,8 +501,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) sp->dev = dev; sp->init_data = data; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) { dev_err(dev, "missing \"reg\"\n"); return PTR_ERR(base); From 0b7c4c88b83f415d4c75ba4774e0bb7ed266c7c0 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:38 +0800 Subject: [PATCH 12/72] phy: freescale: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Reviewed-by: Peter Chen Link: https://lore.kernel.org/r/1604642930-29019-5-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c | 4 +--- drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c b/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c index 9f2c1da14f5a..a95572b397ca 100644 --- a/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c +++ b/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c @@ -434,7 +434,6 @@ static int mixel_dphy_probe(struct platform_device *pdev) struct device_node *np = dev->of_node; struct phy_provider *phy_provider; struct mixel_dphy_priv *priv; - struct resource *res; struct phy *phy; void __iomem *base; @@ -449,8 +448,7 @@ static int mixel_dphy_probe(struct platform_device *pdev) if (!priv->devdata) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c index 47a0c09bc9fa..a29b4a6f7c24 100644 --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c @@ -152,7 +152,6 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev) struct phy_provider *phy_provider; struct device *dev = &pdev->dev; struct imx8mq_usb_phy *imx_phy; - struct resource *res; const struct phy_ops *phy_ops; imx_phy = devm_kzalloc(dev, sizeof(*imx_phy), GFP_KERNEL); @@ -165,8 +164,7 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(imx_phy->clk); } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - imx_phy->base = devm_ioremap_resource(dev, res); + imx_phy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(imx_phy->base)) return PTR_ERR(imx_phy->base); From 6c9111bc9eef0ff0302a0963ff802d31e21bfe05 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:39 +0800 Subject: [PATCH 13/72] phy: lantiq: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1604642930-29019-6-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c b/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c index 22c5698123cf..ef93bf2cba10 100644 --- a/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c +++ b/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c @@ -402,7 +402,6 @@ static int ltq_vrx200_pcie_phy_probe(struct platform_device *pdev) struct ltq_vrx200_pcie_phy_priv *priv; struct device *dev = &pdev->dev; struct phy_provider *provider; - struct resource *res; void __iomem *base; int ret; @@ -410,8 +409,7 @@ static int ltq_vrx200_pcie_phy_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); From ee55b501bd8ceb12c30ff0c0240498a301e126db Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:40 +0800 Subject: [PATCH 14/72] phy: marvell: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Reviewed-by: Jisheng Zhang Link: https://lore.kernel.org/r/1604642930-29019-7-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/marvell/phy-armada375-usb2.c | 4 +--- drivers/phy/marvell/phy-berlin-usb.c | 4 +--- drivers/phy/marvell/phy-mmp3-usb.c | 4 +--- drivers/phy/marvell/phy-mvebu-sata.c | 4 +--- drivers/phy/marvell/phy-pxa-28nm-hsic.c | 4 +--- drivers/phy/marvell/phy-pxa-28nm-usb2.c | 4 +--- drivers/phy/marvell/phy-pxa-usb.c | 4 +--- 7 files changed, 7 insertions(+), 21 deletions(-) diff --git a/drivers/phy/marvell/phy-armada375-usb2.c b/drivers/phy/marvell/phy-armada375-usb2.c index fa5dc9462d09..b141e3cd8a94 100644 --- a/drivers/phy/marvell/phy-armada375-usb2.c +++ b/drivers/phy/marvell/phy-armada375-usb2.c @@ -105,15 +105,13 @@ static int armada375_usb_phy_probe(struct platform_device *pdev) struct phy *phy; struct phy_provider *phy_provider; void __iomem *usb_cluster_base; - struct resource *res; struct armada375_cluster_phy *cluster_phy; cluster_phy = devm_kzalloc(dev, sizeof(*cluster_phy), GFP_KERNEL); if (!cluster_phy) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - usb_cluster_base = devm_ioremap_resource(&pdev->dev, res); + usb_cluster_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(usb_cluster_base)) return PTR_ERR(usb_cluster_base); diff --git a/drivers/phy/marvell/phy-berlin-usb.c b/drivers/phy/marvell/phy-berlin-usb.c index a43df63007c5..78ef6ae72a9a 100644 --- a/drivers/phy/marvell/phy-berlin-usb.c +++ b/drivers/phy/marvell/phy-berlin-usb.c @@ -165,7 +165,6 @@ static int phy_berlin_usb_probe(struct platform_device *pdev) const struct of_device_id *match = of_match_device(phy_berlin_usb_of_match, &pdev->dev); struct phy_berlin_usb_priv *priv; - struct resource *res; struct phy *phy; struct phy_provider *phy_provider; @@ -173,8 +172,7 @@ static int phy_berlin_usb_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(&pdev->dev, res); + priv->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); diff --git a/drivers/phy/marvell/phy-mmp3-usb.c b/drivers/phy/marvell/phy-mmp3-usb.c index 499869595a58..04c0bada3519 100644 --- a/drivers/phy/marvell/phy-mmp3-usb.c +++ b/drivers/phy/marvell/phy-mmp3-usb.c @@ -246,7 +246,6 @@ MODULE_DEVICE_TABLE(of, mmp3_usb_phy_of_match); static int mmp3_usb_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct resource *resource; struct mmp3_usb_phy *mmp3_usb_phy; struct phy_provider *provider; @@ -254,8 +253,7 @@ static int mmp3_usb_phy_probe(struct platform_device *pdev) if (!mmp3_usb_phy) return -ENOMEM; - resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mmp3_usb_phy->base = devm_ioremap_resource(dev, resource); + mmp3_usb_phy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(mmp3_usb_phy->base)) { dev_err(dev, "failed to remap PHY regs\n"); return PTR_ERR(mmp3_usb_phy->base); diff --git a/drivers/phy/marvell/phy-mvebu-sata.c b/drivers/phy/marvell/phy-mvebu-sata.c index 3c01b5dceaae..51a4646e2933 100644 --- a/drivers/phy/marvell/phy-mvebu-sata.c +++ b/drivers/phy/marvell/phy-mvebu-sata.c @@ -80,7 +80,6 @@ static const struct phy_ops phy_mvebu_sata_ops = { static int phy_mvebu_sata_probe(struct platform_device *pdev) { struct phy_provider *phy_provider; - struct resource *res; struct priv *priv; struct phy *phy; @@ -88,8 +87,7 @@ static int phy_mvebu_sata_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(&pdev->dev, res); + priv->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); diff --git a/drivers/phy/marvell/phy-pxa-28nm-hsic.c b/drivers/phy/marvell/phy-pxa-28nm-hsic.c index 31b43d2ee39a..c5c100563f55 100644 --- a/drivers/phy/marvell/phy-pxa-28nm-hsic.c +++ b/drivers/phy/marvell/phy-pxa-28nm-hsic.c @@ -162,7 +162,6 @@ static int mv_hsic_phy_probe(struct platform_device *pdev) { struct phy_provider *phy_provider; struct mv_hsic_phy *mv_phy; - struct resource *r; mv_phy = devm_kzalloc(&pdev->dev, sizeof(*mv_phy), GFP_KERNEL); if (!mv_phy) @@ -176,8 +175,7 @@ static int mv_hsic_phy_probe(struct platform_device *pdev) return PTR_ERR(mv_phy->clk); } - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mv_phy->base = devm_ioremap_resource(&pdev->dev, r); + mv_phy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(mv_phy->base)) return PTR_ERR(mv_phy->base); diff --git a/drivers/phy/marvell/phy-pxa-28nm-usb2.c b/drivers/phy/marvell/phy-pxa-28nm-usb2.c index a175ae915f02..0b390b9d2ae1 100644 --- a/drivers/phy/marvell/phy-pxa-28nm-usb2.c +++ b/drivers/phy/marvell/phy-pxa-28nm-usb2.c @@ -294,7 +294,6 @@ static int mv_usb2_phy_probe(struct platform_device *pdev) { struct phy_provider *phy_provider; struct mv_usb2_phy *mv_phy; - struct resource *r; mv_phy = devm_kzalloc(&pdev->dev, sizeof(*mv_phy), GFP_KERNEL); if (!mv_phy) @@ -308,8 +307,7 @@ static int mv_usb2_phy_probe(struct platform_device *pdev) return PTR_ERR(mv_phy->clk); } - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mv_phy->base = devm_ioremap_resource(&pdev->dev, r); + mv_phy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(mv_phy->base)) return PTR_ERR(mv_phy->base); diff --git a/drivers/phy/marvell/phy-pxa-usb.c b/drivers/phy/marvell/phy-pxa-usb.c index 87ff7550b912..ffe889893ff4 100644 --- a/drivers/phy/marvell/phy-pxa-usb.c +++ b/drivers/phy/marvell/phy-pxa-usb.c @@ -286,7 +286,6 @@ MODULE_DEVICE_TABLE(of, pxa_usb_phy_of_match); static int pxa_usb_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct resource *resource; struct pxa_usb_phy *pxa_usb_phy; struct phy_provider *provider; const struct of_device_id *of_id; @@ -301,8 +300,7 @@ static int pxa_usb_phy_probe(struct platform_device *pdev) else pxa_usb_phy->version = PXA_USB_PHY_MMP2; - resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pxa_usb_phy->base = devm_ioremap_resource(dev, resource); + pxa_usb_phy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pxa_usb_phy->base)) { dev_err(dev, "failed to remap PHY regs\n"); return PTR_ERR(pxa_usb_phy->base); From 5d797059ff57b2213153523f4cf031a811e53dbf Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:41 +0800 Subject: [PATCH 15/72] phy: phy-xgene: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1604642930-29019-8-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/phy-xgene.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c index b88922e7de1d..f4cd590fbde7 100644 --- a/drivers/phy/phy-xgene.c +++ b/drivers/phy/phy-xgene.c @@ -1644,7 +1644,6 @@ static int xgene_phy_probe(struct platform_device *pdev) { struct phy_provider *phy_provider; struct xgene_phy_ctx *ctx; - struct resource *res; u32 default_spd[] = DEFAULT_SATA_SPD_SEL; u32 default_txboost_gain[] = DEFAULT_SATA_TXBOOST_GAIN; u32 default_txeye_direction[] = DEFAULT_SATA_TXEYEDIRECTION; @@ -1661,8 +1660,7 @@ static int xgene_phy_probe(struct platform_device *pdev) ctx->dev = &pdev->dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ctx->sds_base = devm_ioremap_resource(&pdev->dev, res); + ctx->sds_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(ctx->sds_base)) return PTR_ERR(ctx->sds_base); From 7458d650e256b2b418efa4c974585846da4358a6 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:42 +0800 Subject: [PATCH 16/72] phy: phy-mtk-ufs: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1604642930-29019-9-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/mediatek/phy-mtk-ufs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/phy/mediatek/phy-mtk-ufs.c b/drivers/phy/mediatek/phy-mtk-ufs.c index cf94f5c35dc5..769b00b038d8 100644 --- a/drivers/phy/mediatek/phy-mtk-ufs.c +++ b/drivers/phy/mediatek/phy-mtk-ufs.c @@ -195,7 +195,6 @@ static int ufs_mtk_phy_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phy *generic_phy; struct phy_provider *phy_provider; - struct resource *res; struct ufs_mtk_phy *phy; int ret; @@ -203,8 +202,7 @@ static int ufs_mtk_phy_probe(struct platform_device *pdev) if (!phy) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->mmio = devm_ioremap_resource(dev, res); + phy->mmio = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy->mmio)) return PTR_ERR(phy->mmio); From 8a7772cdd91de4eea6dcd9df9b6fce7f4c012208 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:43 +0800 Subject: [PATCH 17/72] phy: qualcomm: convert to devm_platform_ioremap_resource(_byname) Use devm_platform_ioremap_resource(_byname) to simplify code Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1604642930-29019-10-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-apq8064-sata.c | 4 +--- drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c | 4 +--- drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c | 4 +--- drivers/phy/qualcomm/phy-qcom-pcie2.c | 5 +---- drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 +--- 5 files changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c index ce91ae7f8dbd..d437a249cd73 100644 --- a/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c +++ b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c @@ -201,7 +201,6 @@ static int qcom_apq8064_sata_phy_probe(struct platform_device *pdev) { struct qcom_apq8064_sata_phy *phy; struct device *dev = &pdev->dev; - struct resource *res; struct phy_provider *phy_provider; struct phy *generic_phy; int ret; @@ -210,8 +209,7 @@ static int qcom_apq8064_sata_phy_probe(struct platform_device *pdev) if (!phy) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->mmio = devm_ioremap_resource(dev, res); + phy->mmio = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy->mmio)) return PTR_ERR(phy->mmio); diff --git a/drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c b/drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c index fc7f9df80a7b..d3e7d5e1d1b6 100644 --- a/drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c +++ b/drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c @@ -95,7 +95,6 @@ MODULE_DEVICE_TABLE(of, ipq4019_usb_phy_of_match); static int ipq4019_usb_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct resource *res; struct phy_provider *phy_provider; struct ipq4019_usb_phy *phy; @@ -104,8 +103,7 @@ static int ipq4019_usb_phy_probe(struct platform_device *pdev) return -ENOMEM; phy->dev = &pdev->dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->base = devm_ioremap_resource(&pdev->dev, res); + phy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy->base)) { dev_err(dev, "failed to remap register memory\n"); return PTR_ERR(phy->base); diff --git a/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c b/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c index 41a69f56b346..0fc2a1ed39b3 100644 --- a/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c +++ b/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c @@ -128,7 +128,6 @@ static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev) { struct qcom_ipq806x_sata_phy *phy; struct device *dev = &pdev->dev; - struct resource *res; struct phy_provider *phy_provider; struct phy *generic_phy; int ret; @@ -137,8 +136,7 @@ static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev) if (!phy) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->mmio = devm_ioremap_resource(dev, res); + phy->mmio = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy->mmio)) return PTR_ERR(phy->mmio); diff --git a/drivers/phy/qualcomm/phy-qcom-pcie2.c b/drivers/phy/qualcomm/phy-qcom-pcie2.c index 9dba3594e6d9..5407e59bb185 100644 --- a/drivers/phy/qualcomm/phy-qcom-pcie2.c +++ b/drivers/phy/qualcomm/phy-qcom-pcie2.c @@ -250,7 +250,6 @@ static int qcom_pcie2_phy_probe(struct platform_device *pdev) { struct phy_provider *phy_provider; struct qcom_phy *qphy; - struct resource *res; struct device *dev = &pdev->dev; struct phy *phy; int ret; @@ -260,9 +259,7 @@ static int qcom_pcie2_phy_probe(struct platform_device *pdev) return -ENOMEM; qphy->dev = dev; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - qphy->base = devm_ioremap_resource(dev, res); + qphy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(qphy->base)) return PTR_ERR(qphy->base); diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index 557547dabfd5..109792203baf 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -844,7 +844,6 @@ static int qusb2_phy_probe(struct platform_device *pdev) struct qusb2_phy *qphy; struct phy_provider *phy_provider; struct phy *generic_phy; - struct resource *res; int ret, i; int num; u32 value; @@ -855,8 +854,7 @@ static int qusb2_phy_probe(struct platform_device *pdev) return -ENOMEM; or = &qphy->overrides; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - qphy->base = devm_ioremap_resource(dev, res); + qphy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(qphy->base)) return PTR_ERR(qphy->base); From fc5662127a257eafcb37133fa272b1ab0813ae07 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:44 +0800 Subject: [PATCH 18/72] phy: phy-ralink-usb: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1604642930-29019-11-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/ralink/phy-ralink-usb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/phy/ralink/phy-ralink-usb.c b/drivers/phy/ralink/phy-ralink-usb.c index 95dfa9fd284d..2bd8ad2e76ed 100644 --- a/drivers/phy/ralink/phy-ralink-usb.c +++ b/drivers/phy/ralink/phy-ralink-usb.c @@ -170,7 +170,6 @@ MODULE_DEVICE_TABLE(of, ralink_usb_phy_of_match); static int ralink_usb_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct resource *res; struct phy_provider *phy_provider; const struct of_device_id *match; struct ralink_usb_phy *phy; @@ -194,8 +193,7 @@ static int ralink_usb_phy_probe(struct platform_device *pdev) /* The MT7628 and MT7688 require extra setup of PHY registers. */ if (of_device_is_compatible(dev->of_node, "mediatek,mt7628-usbphy")) { - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->base = devm_ioremap_resource(&pdev->dev, res); + phy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy->base)) { dev_err(dev, "failed to remap register memory\n"); return PTR_ERR(phy->base); From 0b5604affbec0241d72996924b2f5a33d96b860a Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:45 +0800 Subject: [PATCH 19/72] phy: renesas: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1604642930-29019-12-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/renesas/phy-rcar-gen2.c | 4 +--- drivers/phy/renesas/phy-rcar-gen3-pcie.c | 4 +--- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 4 +--- drivers/phy/renesas/phy-rcar-gen3-usb3.c | 4 +--- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/phy/renesas/phy-rcar-gen2.c b/drivers/phy/renesas/phy-rcar-gen2.c index 2e279ac0fa4d..c375a4676a3d 100644 --- a/drivers/phy/renesas/phy-rcar-gen2.c +++ b/drivers/phy/renesas/phy-rcar-gen2.c @@ -339,7 +339,6 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) struct rcar_gen2_phy_driver *drv; struct phy_provider *provider; struct device_node *np; - struct resource *res; void __iomem *base; struct clk *clk; const struct rcar_gen2_phy_data *data; @@ -357,8 +356,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) return PTR_ERR(clk); } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/phy/renesas/phy-rcar-gen3-pcie.c b/drivers/phy/renesas/phy-rcar-gen3-pcie.c index c4e4aa216936..4dc721eb9577 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-pcie.c +++ b/drivers/phy/renesas/phy-rcar-gen3-pcie.c @@ -76,7 +76,6 @@ static int rcar_gen3_phy_pcie_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phy_provider *provider; struct rcar_gen3_phy *phy; - struct resource *res; void __iomem *base; int error; @@ -86,8 +85,7 @@ static int rcar_gen3_phy_pcie_probe(struct platform_device *pdev) return -EINVAL; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index e34e4475027c..1898bbe7c8e5 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -611,7 +611,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rcar_gen3_chan *channel; struct phy_provider *provider; - struct resource *res; const struct phy_ops *phy_usb2_ops; int ret = 0, i; @@ -624,8 +623,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) if (!channel) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - channel->base = devm_ioremap_resource(dev, res); + channel->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(channel->base)) return PTR_ERR(channel->base); diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb3.c b/drivers/phy/renesas/phy-rcar-gen3-usb3.c index 566b4cf4ff38..f27d6f471629 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb3.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb3.c @@ -133,7 +133,6 @@ static int rcar_gen3_phy_usb3_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rcar_gen3_usb3 *r; struct phy_provider *provider; - struct resource *res; int ret = 0; struct clk *clk; @@ -146,8 +145,7 @@ static int rcar_gen3_phy_usb3_probe(struct platform_device *pdev) if (!r) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - r->base = devm_ioremap_resource(dev, res); + r->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(r->base)) return PTR_ERR(r->base); From 6824ebc047b9936bfe7b5885d85c1fe88dca014e Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:46 +0800 Subject: [PATCH 20/72] phy: rockchip: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1604642930-29019-13-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c index 9ca20c947283..a37f3f342642 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -1144,7 +1144,6 @@ static int inno_hdmi_phy_probe(struct platform_device *pdev) { struct inno_hdmi_phy *inno; struct phy_provider *phy_provider; - struct resource *res; void __iomem *regs; int ret; @@ -1158,8 +1157,7 @@ static int inno_hdmi_phy_probe(struct platform_device *pdev) if (!inno->plat_data || !inno->plat_data->ops) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs = devm_ioremap_resource(inno->dev, res); + regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(regs)) return PTR_ERR(regs); From 2f0c9fac3be6c834427f9d2af2107ebd6602d4b1 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:47 +0800 Subject: [PATCH 21/72] phy: samsung: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/1604642930-29019-14-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/samsung/phy-exynos-pcie.c | 7 ++----- drivers/phy/samsung/phy-exynos5-usbdrd.c | 4 +--- drivers/phy/samsung/phy-exynos5250-sata.c | 5 +---- drivers/phy/samsung/phy-samsung-usb2.c | 4 +--- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos-pcie.c b/drivers/phy/samsung/phy-exynos-pcie.c index 7e28b1aea0d1..c98fff5c1ac8 100644 --- a/drivers/phy/samsung/phy-exynos-pcie.c +++ b/drivers/phy/samsung/phy-exynos-pcie.c @@ -232,7 +232,6 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev) struct exynos_pcie_phy *exynos_phy; struct phy *generic_phy; struct phy_provider *phy_provider; - struct resource *res; const struct exynos_pcie_phy_data *drv_data; drv_data = of_device_get_match_data(dev); @@ -243,13 +242,11 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev) if (!exynos_phy) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - exynos_phy->phy_base = devm_ioremap_resource(dev, res); + exynos_phy->phy_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(exynos_phy->phy_base)) return PTR_ERR(exynos_phy->phy_base); - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - exynos_phy->blk_base = devm_ioremap_resource(dev, res); + exynos_phy->blk_base = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(exynos_phy->blk_base)) return PTR_ERR(exynos_phy->blk_base); diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index cfa9b8b7e5ac..ee0848fe8432 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -829,7 +829,6 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) struct device_node *node = dev->of_node; struct exynos5_usbdrd_phy *phy_drd; struct phy_provider *phy_provider; - struct resource *res; const struct exynos5_usbdrd_phy_drvdata *drv_data; struct regmap *reg_pmu; u32 pmu_offset; @@ -843,8 +842,7 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) dev_set_drvdata(dev, phy_drd); phy_drd->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy_drd->reg_phy = devm_ioremap_resource(dev, res); + phy_drd->reg_phy = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy_drd->reg_phy)) return PTR_ERR(phy_drd->reg_phy); diff --git a/drivers/phy/samsung/phy-exynos5250-sata.c b/drivers/phy/samsung/phy-exynos5250-sata.c index 4dd7324d91b2..9ec234243f7c 100644 --- a/drivers/phy/samsung/phy-exynos5250-sata.c +++ b/drivers/phy/samsung/phy-exynos5250-sata.c @@ -162,7 +162,6 @@ static int exynos_sata_phy_probe(struct platform_device *pdev) { struct exynos_sata_phy *sata_phy; struct device *dev = &pdev->dev; - struct resource *res; struct phy_provider *phy_provider; struct device_node *node; int ret = 0; @@ -171,9 +170,7 @@ static int exynos_sata_phy_probe(struct platform_device *pdev) if (!sata_phy) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - sata_phy->regs = devm_ioremap_resource(dev, res); + sata_phy->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(sata_phy->regs)) return PTR_ERR(sata_phy->regs); diff --git a/drivers/phy/samsung/phy-samsung-usb2.c b/drivers/phy/samsung/phy-samsung-usb2.c index a3ed3ff04690..f79f605cff79 100644 --- a/drivers/phy/samsung/phy-samsung-usb2.c +++ b/drivers/phy/samsung/phy-samsung-usb2.c @@ -143,7 +143,6 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev) const struct samsung_usb2_phy_config *cfg; struct device *dev = &pdev->dev; struct phy_provider *phy_provider; - struct resource *mem; struct samsung_usb2_phy_driver *drv; int i, ret; @@ -167,8 +166,7 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev) drv->cfg = cfg; drv->dev = dev; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - drv->reg_phy = devm_ioremap_resource(dev, mem); + drv->reg_phy = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(drv->reg_phy)) { dev_err(dev, "Failed to map register memory (phy)\n"); return PTR_ERR(drv->reg_phy); From 5a77b16c6b2b0eb5ab108d1933e99be769f5c90f Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:48 +0800 Subject: [PATCH 22/72] phy: phy-stm32-usbphyc: convert to devm_platform_ioremap_resource Use devm_platform_ioremap_resource to simplify code Signed-off-by: Chunfeng Yun Reviewed-by: Amelie Delaunay Link: https://lore.kernel.org/r/1604642930-29019-15-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/st/phy-stm32-usbphyc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c index 2b3639cba51a..0ab18f2078db 100644 --- a/drivers/phy/st/phy-stm32-usbphyc.c +++ b/drivers/phy/st/phy-stm32-usbphyc.c @@ -311,7 +311,6 @@ static int stm32_usbphyc_probe(struct platform_device *pdev) struct stm32_usbphyc *usbphyc; struct device *dev = &pdev->dev; struct device_node *child, *np = dev->of_node; - struct resource *res; struct phy_provider *phy_provider; u32 version; int ret, port = 0; @@ -322,8 +321,7 @@ static int stm32_usbphyc_probe(struct platform_device *pdev) usbphyc->dev = dev; dev_set_drvdata(dev, usbphyc); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - usbphyc->base = devm_ioremap_resource(dev, res); + usbphyc->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(usbphyc->base)) return PTR_ERR(usbphyc->base); From 9ab4212b0a363a1edc5a52f70843dc2a5cda200d Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:49 +0800 Subject: [PATCH 23/72] phy: tegra: convert to devm_platform_ioremap_resource(_byname) Use devm_platform_ioremap_resource(_byname) to simplify code Signed-off-by: Chunfeng Yun Cc: JC Kuo Link: https://lore.kernel.org/r/1604642930-29019-16-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/tegra/phy-tegra194-p2u.c | 4 +--- drivers/phy/tegra/xusb.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/phy/tegra/phy-tegra194-p2u.c b/drivers/phy/tegra/phy-tegra194-p2u.c index 7042bed9feaa..3ee02b9eb04f 100644 --- a/drivers/phy/tegra/phy-tegra194-p2u.c +++ b/drivers/phy/tegra/phy-tegra194-p2u.c @@ -72,14 +72,12 @@ static int tegra_p2u_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phy *generic_phy; struct tegra_p2u *phy; - struct resource *res; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctl"); - phy->base = devm_ioremap_resource(dev, res); + phy->base = devm_platform_ioremap_resource_byname(pdev, "ctl"); if (IS_ERR(phy->base)) return PTR_ERR(phy->base); diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index de4a46fe1763..067e71326826 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -1148,7 +1148,6 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) const struct tegra_xusb_padctl_soc *soc; struct tegra_xusb_padctl *padctl; const struct of_device_id *match; - struct resource *res; int err; /* for backwards compatibility with old device trees */ @@ -1173,8 +1172,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) INIT_LIST_HEAD(&padctl->pads); mutex_init(&padctl->lock); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - padctl->regs = devm_ioremap_resource(&pdev->dev, res); + padctl->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(padctl->regs)) { err = PTR_ERR(padctl->regs); goto remove; From 79caf207d6699419e83ac150accc5c80c5719b47 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Fri, 6 Nov 2020 14:08:50 +0800 Subject: [PATCH 24/72] phy: ti: convert to devm_platform_ioremap_resource(_byname) Use devm_platform_ioremap_resource(_byname) to simplify code Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1604642930-29019-17-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul --- drivers/phy/ti/phy-omap-control.c | 17 ++++++----------- drivers/phy/ti/phy-omap-usb2.c | 4 +--- drivers/phy/ti/phy-ti-pipe3.c | 15 ++++----------- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/drivers/phy/ti/phy-omap-control.c b/drivers/phy/ti/phy-omap-control.c index ccd0e4e00451..47482f106fab 100644 --- a/drivers/phy/ti/phy-omap-control.c +++ b/drivers/phy/ti/phy-omap-control.c @@ -268,7 +268,6 @@ MODULE_DEVICE_TABLE(of, omap_control_phy_id_table); static int omap_control_phy_probe(struct platform_device *pdev) { - struct resource *res; const struct of_device_id *of_id; struct omap_control_phy *control_phy; @@ -285,16 +284,13 @@ static int omap_control_phy_probe(struct platform_device *pdev) control_phy->type = *(enum omap_control_phy_type *)of_id->data; if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "otghs_control"); - control_phy->otghs_control = devm_ioremap_resource( - &pdev->dev, res); + control_phy->otghs_control = + devm_platform_ioremap_resource_byname(pdev, "otghs_control"); if (IS_ERR(control_phy->otghs_control)) return PTR_ERR(control_phy->otghs_control); } else { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "power"); - control_phy->power = devm_ioremap_resource(&pdev->dev, res); + control_phy->power = + devm_platform_ioremap_resource_byname(pdev, "power"); if (IS_ERR(control_phy->power)) { dev_err(&pdev->dev, "Couldn't get power register\n"); return PTR_ERR(control_phy->power); @@ -312,9 +308,8 @@ static int omap_control_phy_probe(struct platform_device *pdev) } if (control_phy->type == OMAP_CTRL_TYPE_PCIE) { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "pcie_pcs"); - control_phy->pcie_pcs = devm_ioremap_resource(&pdev->dev, res); + control_phy->pcie_pcs = + devm_platform_ioremap_resource_byname(pdev, "pcie_pcs"); if (IS_ERR(control_phy->pcie_pcs)) return PTR_ERR(control_phy->pcie_pcs); } diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c index 4fec90d2624f..ebceb1520ce8 100644 --- a/drivers/phy/ti/phy-omap-usb2.c +++ b/drivers/phy/ti/phy-omap-usb2.c @@ -366,7 +366,6 @@ static int omap_usb2_probe(struct platform_device *pdev) { struct omap_usb *phy; struct phy *generic_phy; - struct resource *res; struct phy_provider *phy_provider; struct usb_otg *otg; struct device_node *node = pdev->dev.of_node; @@ -403,8 +402,7 @@ static int omap_usb2_probe(struct platform_device *pdev) omap_usb2_init_errata(phy); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->phy_base = devm_ioremap_resource(&pdev->dev, res); + phy->phy_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy->phy_base)) return PTR_ERR(phy->phy_base); diff --git a/drivers/phy/ti/phy-ti-pipe3.c b/drivers/phy/ti/phy-ti-pipe3.c index e9332c90f75f..2cbc91e535d4 100644 --- a/drivers/phy/ti/phy-ti-pipe3.c +++ b/drivers/phy/ti/phy-ti-pipe3.c @@ -745,35 +745,28 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy) static int ti_pipe3_get_tx_rx_base(struct ti_pipe3 *phy) { - struct resource *res; struct device *dev = phy->dev; struct platform_device *pdev = to_platform_device(dev); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "phy_rx"); - phy->phy_rx = devm_ioremap_resource(dev, res); + phy->phy_rx = devm_platform_ioremap_resource_byname(pdev, "phy_rx"); if (IS_ERR(phy->phy_rx)) return PTR_ERR(phy->phy_rx); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "phy_tx"); - phy->phy_tx = devm_ioremap_resource(dev, res); + phy->phy_tx = devm_platform_ioremap_resource_byname(pdev, "phy_tx"); return PTR_ERR_OR_ZERO(phy->phy_tx); } static int ti_pipe3_get_pll_base(struct ti_pipe3 *phy) { - struct resource *res; struct device *dev = phy->dev; struct platform_device *pdev = to_platform_device(dev); if (phy->mode == PIPE3_MODE_PCIE) return 0; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "pll_ctrl"); - phy->pll_ctrl_base = devm_ioremap_resource(dev, res); + phy->pll_ctrl_base = + devm_platform_ioremap_resource_byname(pdev, "pll_ctrl"); return PTR_ERR_OR_ZERO(phy->pll_ctrl_base); } From ba2bf1f090ebdf36f02c6d31381a0685982ff7fe Mon Sep 17 00:00:00 2001 From: Swapnil Jakhade Date: Wed, 28 Oct 2020 16:22:41 +0100 Subject: [PATCH 25/72] dt-bindings: phy: Add Cadence Sierra PHY bindings in YAML format Add Cadence Sierra PHY bindings in YAML format. Signed-off-by: Swapnil Jakhade Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/1603898561-5142-1-git-send-email-sjakhade@cadence.com Signed-off-by: Vinod Koul --- .../bindings/phy/phy-cadence-sierra.txt | 70 -------- .../bindings/phy/phy-cadence-sierra.yaml | 152 ++++++++++++++++++ 2 files changed, 152 insertions(+), 70 deletions(-) delete mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt create mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt deleted file mode 100644 index 03f5939d3d19..000000000000 --- a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt +++ /dev/null @@ -1,70 +0,0 @@ -Cadence Sierra PHY ------------------------ - -Required properties: -- compatible: Must be "cdns,sierra-phy-t0" for Sierra in Cadence platform - Must be "ti,sierra-phy-t0" for Sierra in TI's J721E SoC. -- resets: Must contain an entry for each in reset-names. - See ../reset/reset.txt for details. -- reset-names: Must include "sierra_reset" and "sierra_apb". - "sierra_reset" must control the reset line to the PHY. - "sierra_apb" must control the reset line to the APB PHY - interface ("sierra_apb" is optional). -- reg: register range for the PHY. -- #address-cells: Must be 1 -- #size-cells: Must be 0 - -Optional properties: -- clocks: Must contain an entry in clock-names. - See ../clocks/clock-bindings.txt for details. -- clock-names: Must contain "cmn_refclk_dig_div" and - "cmn_refclk1_dig_div" for configuring the frequency of - the clock to the lanes. "phy_clk" is deprecated. -- cdns,autoconf: A boolean property whose presence indicates that the - PHY registers will be configured by hardware. If not - present, all sub-node optional properties must be - provided. - -Sub-nodes: - Each group of PHY lanes with a single master lane should be represented as - a sub-node. Note that the actual configuration of each lane is determined by - hardware strapping, and must match the configuration specified here. - -Sub-node required properties: -- #phy-cells: Generic PHY binding; must be 0. -- reg: The master lane number. This is the lowest numbered lane - in the lane group. -- resets: Must contain one entry which controls the reset line for the - master lane of the sub-node. - See ../reset/reset.txt for details. - -Sub-node optional properties: -- cdns,num-lanes: Number of lanes in this group. From 1 to 4. The - group is made up of consecutive lanes. -- cdns,phy-type: Can be PHY_TYPE_PCIE or PHY_TYPE_USB3, depending on - configuration of lanes. - -Example: - pcie_phy4: pcie-phy@fd240000 { - compatible = "cdns,sierra-phy-t0"; - reg = <0x0 0xfd240000 0x0 0x40000>; - resets = <&phyrst 0>, <&phyrst 1>; - reset-names = "sierra_reset", "sierra_apb"; - clocks = <&phyclock>; - clock-names = "phy_clk"; - #address-cells = <1>; - #size-cells = <0>; - pcie0_phy0: pcie-phy@0 { - reg = <0>; - resets = <&phyrst 2>; - cdns,num-lanes = <2>; - #phy-cells = <0>; - cdns,phy-type = ; - }; - pcie0_phy1: pcie-phy@2 { - reg = <2>; - resets = <&phyrst 4>; - cdns,num-lanes = <1>; - #phy-cells = <0>; - cdns,phy-type = ; - }; diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml new file mode 100644 index 000000000000..d210843863df --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml @@ -0,0 +1,152 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/phy/phy-cadence-sierra.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Cadence Sierra PHY binding + +description: + This binding describes the Cadence Sierra PHY. Sierra PHY supports multilink + multiprotocol combinations including protocols such as PCIe, USB etc. + +maintainers: + - Swapnil Jakhade + - Yuti Amonkar + +properties: + compatible: + enum: + - cdns,sierra-phy-t0 + - ti,sierra-phy-t0 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + resets: + minItems: 1 + maxItems: 2 + items: + - description: Sierra PHY reset. + - description: Sierra APB reset. This is optional. + + reset-names: + minItems: 1 + maxItems: 2 + items: + - const: sierra_reset + - const: sierra_apb + + reg: + maxItems: 1 + description: + Offset of the Sierra PHY configuration registers. + + reg-names: + const: serdes + + clocks: + maxItems: 2 + + clock-names: + items: + - const: cmn_refclk_dig_div + - const: cmn_refclk1_dig_div + + cdns,autoconf: + type: boolean + description: + A boolean property whose presence indicates that the PHY registers will be + configured by hardware. If not present, all sub-node optional properties + must be provided. + +patternProperties: + '^phy@[0-9a-f]$': + type: object + description: + Each group of PHY lanes with a single master lane should be represented as + a sub-node. Note that the actual configuration of each lane is determined + by hardware strapping, and must match the configuration specified here. + properties: + reg: + description: + The master lane number. This is the lowest numbered lane in the lane group. + minimum: 0 + maximum: 15 + + resets: + minItems: 1 + maxItems: 4 + description: + Contains list of resets, one per lane, to get all the link lanes out of reset. + + "#phy-cells": + const: 0 + + cdns,phy-type: + description: + Specifies the type of PHY for which the group of PHY lanes is used. + Refer include/dt-bindings/phy/phy.h. Constants from the header should be used. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [2, 4] + + cdns,num-lanes: + description: + Number of lanes in this group. The group is made up of consecutive lanes. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 16 + + required: + - reg + - resets + - "#phy-cells" + + additionalProperties: false + +required: + - compatible + - "#address-cells" + - "#size-cells" + - reg + - resets + - reset-names + +additionalProperties: false + +examples: + - | + #include + + bus { + #address-cells = <2>; + #size-cells = <2>; + + sierra-phy@fd240000 { + compatible = "cdns,sierra-phy-t0"; + reg = <0x0 0xfd240000 0x0 0x40000>; + resets = <&phyrst 0>, <&phyrst 1>; + reset-names = "sierra_reset", "sierra_apb"; + clocks = <&cmn_refclk_dig_div>, <&cmn_refclk1_dig_div>; + clock-names = "cmn_refclk_dig_div", "cmn_refclk1_dig_div"; + #address-cells = <1>; + #size-cells = <0>; + pcie0_phy0: phy@0 { + reg = <0>; + resets = <&phyrst 2>; + cdns,num-lanes = <2>; + #phy-cells = <0>; + cdns,phy-type = ; + }; + pcie0_phy1: phy@2 { + reg = <2>; + resets = <&phyrst 4>; + cdns,num-lanes = <1>; + #phy-cells = <0>; + cdns,phy-type = ; + }; + }; + }; From 3cc8e86721adbd24de7303bbb5a82464ba9e324a Mon Sep 17 00:00:00 2001 From: Yejune Deng Date: Tue, 3 Nov 2020 12:37:54 +0800 Subject: [PATCH 26/72] phy: amlogic: Replace devm_reset_control_array_get() devm_reset_control_array_get_exclusive() looks more readable Signed-off-by: Yejune Deng Reviewed-by: Martin Blumenstingl Link: https://lore.kernel.org/r/1604378274-6860-1-git-send-email-yejune.deng@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-axg-pcie.c | 2 +- drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c | 2 +- drivers/soc/amlogic/meson-ee-pwrc.c | 3 +-- drivers/soc/amlogic/meson-gx-pwrc-vpu.c | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-axg-pcie.c b/drivers/phy/amlogic/phy-meson-axg-pcie.c index 58a7507a8422..2299bab38e05 100644 --- a/drivers/phy/amlogic/phy-meson-axg-pcie.c +++ b/drivers/phy/amlogic/phy-meson-axg-pcie.c @@ -153,7 +153,7 @@ static int phy_axg_pcie_probe(struct platform_device *pdev) if (IS_ERR(priv->regmap)) return PTR_ERR(priv->regmap); - priv->reset = devm_reset_control_array_get(dev, false, false); + priv->reset = devm_reset_control_array_get_exclusive(dev); if (IS_ERR(priv->reset)) return PTR_ERR(priv->reset); diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c index ebe3d0ddd304..5b471ab80fe2 100644 --- a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c +++ b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c @@ -416,7 +416,7 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev) if (ret) goto err_disable_clk_ref; - priv->reset = devm_reset_control_array_get(dev, false, false); + priv->reset = devm_reset_control_array_get_exclusive(dev); if (IS_ERR(priv->reset)) return PTR_ERR(priv->reset); diff --git a/drivers/soc/amlogic/meson-ee-pwrc.c b/drivers/soc/amlogic/meson-ee-pwrc.c index 5164a4dc2352..551edd934ba1 100644 --- a/drivers/soc/amlogic/meson-ee-pwrc.c +++ b/drivers/soc/amlogic/meson-ee-pwrc.c @@ -412,8 +412,7 @@ static int meson_ee_pwrc_init_domain(struct platform_device *pdev, dev_warn(&pdev->dev, "Invalid resets count %d for domain %s\n", count, dom->desc.name); - dom->rstc = devm_reset_control_array_get(&pdev->dev, false, - false); + dom->rstc = devm_reset_control_array_get_exclusive(&pdev->dev) if (IS_ERR(dom->rstc)) return PTR_ERR(dom->rstc); } diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c index 21b4bc811c00..a4dba8a9cfbc 100644 --- a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c +++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c @@ -303,7 +303,7 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev) return PTR_ERR(regmap_hhi); } - rstc = devm_reset_control_array_get(&pdev->dev, false, false); + rstc = devm_reset_control_array_get_exclusive(&pdev->dev); if (IS_ERR(rstc)) { if (PTR_ERR(rstc) != -EPROBE_DEFER) dev_err(&pdev->dev, "failed to get reset lines\n"); From 86f1a6e6c5f700f27bbee046ad330b6a50707a24 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Mon, 9 Nov 2020 22:58:44 +0100 Subject: [PATCH 27/72] phy: tegra: Constify static device_type structs The only usage of tegra_xusb_pad_type and tegra_xusb_port_type is to assign their address to the type field in the device struct, which is a const pointer. Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20201109215844.167954-1-rikard.falkeborn@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/tegra/xusb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 067e71326826..ea9d93097ad8 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -146,7 +146,7 @@ static void tegra_xusb_pad_release(struct device *dev) pad->soc->ops->remove(pad); } -static struct device_type tegra_xusb_pad_type = { +static const struct device_type tegra_xusb_pad_type = { .release = tegra_xusb_pad_release, }; @@ -513,7 +513,7 @@ static void tegra_xusb_port_release(struct device *dev) port->ops->release(port); } -static struct device_type tegra_xusb_port_type = { +static const struct device_type tegra_xusb_port_type = { .release = tegra_xusb_port_release, }; From f98130b34515544d3004ea64ea1dc9db77e9c65a Mon Sep 17 00:00:00 2001 From: Amelie Delaunay Date: Tue, 10 Nov 2020 14:05:31 +0100 Subject: [PATCH 28/72] phy: stm32: don't print an error on probe deferral Change stm32-usbphyc driver to not print an error message when the device probe operation is deferred. Signed-off-by: Etienne Carriere Signed-off-by: Amelie Delaunay Link: https://lore.kernel.org/r/20201110130531.7610-1-amelie.delaunay@st.com Signed-off-by: Vinod Koul --- drivers/phy/st/phy-stm32-usbphyc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c index 0ab18f2078db..8ebfd567d407 100644 --- a/drivers/phy/st/phy-stm32-usbphyc.c +++ b/drivers/phy/st/phy-stm32-usbphyc.c @@ -326,11 +326,8 @@ static int stm32_usbphyc_probe(struct platform_device *pdev) return PTR_ERR(usbphyc->base); usbphyc->clk = devm_clk_get(dev, NULL); - if (IS_ERR(usbphyc->clk)) { - ret = PTR_ERR(usbphyc->clk); - dev_err(dev, "clk get failed: %d\n", ret); - return ret; - } + if (IS_ERR(usbphyc->clk)) + return dev_err_probe(dev, PTR_ERR(usbphyc->clk), "clk get_failed\n"); ret = clk_prepare_enable(usbphyc->clk); if (ret) { From 13ea8e0eee4580686a9d2993ac64938cb5141526 Mon Sep 17 00:00:00 2001 From: Amelie Delaunay Date: Tue, 10 Nov 2020 11:23:05 +0100 Subject: [PATCH 29/72] phy: stm32: defer probe for reset controller Change stm32-usbphyc driver to defer its probe when the expected reset control has its probe operation deferred. Signed-off-by: Etienne Carriere Signed-off-by: Amelie Delaunay Link: https://lore.kernel.org/r/20201110102305.27205-2-amelie.delaunay@st.com Signed-off-by: Vinod Koul --- drivers/phy/st/phy-stm32-usbphyc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c index 8ebfd567d407..a54317e96c41 100644 --- a/drivers/phy/st/phy-stm32-usbphyc.c +++ b/drivers/phy/st/phy-stm32-usbphyc.c @@ -340,6 +340,10 @@ static int stm32_usbphyc_probe(struct platform_device *pdev) reset_control_assert(usbphyc->rst); udelay(2); reset_control_deassert(usbphyc->rst); + } else { + ret = PTR_ERR(usbphyc->rst); + if (ret == -EPROBE_DEFER) + goto clk_disable; } usbphyc->switch_setup = -EINVAL; From 6d3b3f88423e4edc0fad5853c10558b42e1a91dd Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 22 Oct 2020 13:50:55 -0700 Subject: [PATCH 30/72] dt-bindings: phy: Allow defining the SATA AFE TX amplitude Document a new property which allows the selection of the SATA AFE TX amplitude in milli Volts. Possible values are 400, 500, 600 and 800mV. Acked-by: Rob Herring Signed-off-by: Florian Fainelli Link: https://lore.kernel.org/r/20201022205056.233879-2-f.fainelli@gmail.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/brcm-sata-phy.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt b/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt index c03ad2198410..e5abbace93a3 100644 --- a/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt +++ b/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt @@ -38,6 +38,9 @@ Sub-nodes optional properties: - brcm,rxaeq-value: when 'rxaeq-mode' is set to "manual", provides the RX equalizer value that should be used. Allowed range is 0..63. +- brcm,tx-amplitude-millivolt: transmit amplitude voltage in millivolt. + Possible values are 400, 500, 600 or 800 mV. + Example sata-phy@f0458100 { compatible = "brcm,bcm7445-sata-phy", "brcm,phy-sata3"; From 839034d8bd7f380b13b3493e057239f95bb8672a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 22 Oct 2020 13:50:56 -0700 Subject: [PATCH 31/72] phy: phy-brcm-sata: Allow configuration SATA AFE TX amplitude Read the 'brcm,tx-amplitude-millivolt' property from Device Tree and propagate its value into the appropriate test transmit register to change the TX amplitude. Signed-off-by: Florian Fainelli Link: https://lore.kernel.org/r/20201022205056.233879-3-f.fainelli@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/broadcom/phy-brcm-sata.c | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c index 53942973f508..3ecf41359591 100644 --- a/drivers/phy/broadcom/phy-brcm-sata.c +++ b/drivers/phy/broadcom/phy-brcm-sata.c @@ -65,6 +65,7 @@ struct brcm_sata_port { bool ssc_en; enum brcm_sata_phy_rxaeq_mode rxaeq_mode; u32 rxaeq_val; + u32 tx_amplitude_val; }; struct brcm_sata_phy { @@ -84,6 +85,10 @@ enum sata_phy_regs { BLOCK0_SPARE_OOB_CLK_SEL_MASK = 0x3, BLOCK0_SPARE_OOB_CLK_SEL_REFBY2 = 0x1, + BLOCK1_REG_BANK = 0x10, + BLOCK1_TEST_TX = 0x83, + BLOCK1_TEST_TX_AMP_SHIFT = 12, + PLL_REG_BANK_0 = 0x050, PLL_REG_BANK_0_PLLCONTROL_0 = 0x81, PLLCONTROL_0_FREQ_DET_RESTART = BIT(13), @@ -379,6 +384,29 @@ static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port) brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1, ~tmp, RXPMD_MON_CORRECT_EN | value); + tmp = GENMASK(15, 12); + switch (port->tx_amplitude_val) { + case 400: + value = BIT(12) | BIT(13); + break; + case 500: + value = BIT(13); + break; + case 600: + value = BIT(12); + break; + case 800: + value = 0; + break; + default: + value = tmp; + break; + } + + if (value != tmp) + brcm_sata_phy_wr(port, BLOCK1_REG_BANK, BLOCK1_TEST_TX, ~tmp, + value); + /* Turn on/off SSC */ brcm_sata_phy_wr(port, TX_REG_BANK, TX_ACTRL5, ~TX_ACTRL5_SSC_EN, port->ssc_en ? TX_ACTRL5_SSC_EN : 0); @@ -787,6 +815,10 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) if (port->rxaeq_mode == RXAEQ_MODE_MANUAL) of_property_read_u32(child, "brcm,rxaeq-value", &port->rxaeq_val); + + of_property_read_u32(child, "brcm,tx-amplitude-millivolt", + &port->tx_amplitude_val); + port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc"); if (IS_ERR(port->phy)) { dev_err(dev, "failed to create PHY\n"); From 50c0133cd154090446bc19e466df57502f422644 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Wed, 11 Nov 2020 10:37:08 +0000 Subject: [PATCH 32/72] phy: tegra: Don't warn on probe deferral Deferred probe is an expected return value for devm_regulator_bulk_get(). Given that the driver deals with it properly, there's no need to output a warning that may potentially confuse users. Signed-off-by: Jon Hunter Acked-by: Thierry Reding Acked-by: JC Kuo Link: https://lore.kernel.org/r/20201111103708.152566-1-jonathanh@nvidia.com Signed-off-by: Vinod Koul --- drivers/phy/tegra/xusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index ea9d93097ad8..40e03c931340 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -1198,7 +1198,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) err = devm_regulator_bulk_get(&pdev->dev, padctl->soc->num_supplies, padctl->supplies); if (err < 0) { - dev_err(&pdev->dev, "failed to get regulators: %d\n", err); + dev_err_probe(&pdev->dev, err, "failed to get regulators\n"); goto remove; } From 53cde0fe020fd9594820307661e9b9c42821722d Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 17 Nov 2020 15:26:17 +0530 Subject: [PATCH 33/72] phy: amlogic: Revert "phy: amlogic: Replace devm_reset_control_array_get()" This reverts commit 3cc8e86721ad ("phy: amlogic: Replace devm_reset_control_array_get()") as it caused build failure drivers/soc/amlogic/meson-ee-pwrc.c: In function 'meson_ee_pwrc_init_domain': drivers/soc/amlogic/meson-ee-pwrc.c:416:65: error: expected ';' before 'if' Reported-by: Stephen Rothwell Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-axg-pcie.c | 2 +- drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c | 2 +- drivers/soc/amlogic/meson-ee-pwrc.c | 3 ++- drivers/soc/amlogic/meson-gx-pwrc-vpu.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-axg-pcie.c b/drivers/phy/amlogic/phy-meson-axg-pcie.c index 2299bab38e05..58a7507a8422 100644 --- a/drivers/phy/amlogic/phy-meson-axg-pcie.c +++ b/drivers/phy/amlogic/phy-meson-axg-pcie.c @@ -153,7 +153,7 @@ static int phy_axg_pcie_probe(struct platform_device *pdev) if (IS_ERR(priv->regmap)) return PTR_ERR(priv->regmap); - priv->reset = devm_reset_control_array_get_exclusive(dev); + priv->reset = devm_reset_control_array_get(dev, false, false); if (IS_ERR(priv->reset)) return PTR_ERR(priv->reset); diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c index 5b471ab80fe2..ebe3d0ddd304 100644 --- a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c +++ b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c @@ -416,7 +416,7 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev) if (ret) goto err_disable_clk_ref; - priv->reset = devm_reset_control_array_get_exclusive(dev); + priv->reset = devm_reset_control_array_get(dev, false, false); if (IS_ERR(priv->reset)) return PTR_ERR(priv->reset); diff --git a/drivers/soc/amlogic/meson-ee-pwrc.c b/drivers/soc/amlogic/meson-ee-pwrc.c index 551edd934ba1..5164a4dc2352 100644 --- a/drivers/soc/amlogic/meson-ee-pwrc.c +++ b/drivers/soc/amlogic/meson-ee-pwrc.c @@ -412,7 +412,8 @@ static int meson_ee_pwrc_init_domain(struct platform_device *pdev, dev_warn(&pdev->dev, "Invalid resets count %d for domain %s\n", count, dom->desc.name); - dom->rstc = devm_reset_control_array_get_exclusive(&pdev->dev) + dom->rstc = devm_reset_control_array_get(&pdev->dev, false, + false); if (IS_ERR(dom->rstc)) return PTR_ERR(dom->rstc); } diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c index a4dba8a9cfbc..21b4bc811c00 100644 --- a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c +++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c @@ -303,7 +303,7 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev) return PTR_ERR(regmap_hhi); } - rstc = devm_reset_control_array_get_exclusive(&pdev->dev); + rstc = devm_reset_control_array_get(&pdev->dev, false, false); if (IS_ERR(rstc)) { if (PTR_ERR(rstc) != -EPROBE_DEFER) dev_err(&pdev->dev, "failed to get reset lines\n"); From 7af8109efad54ee015626e5dcac133a6f4e473da Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Tue, 10 Nov 2020 14:32:21 +0800 Subject: [PATCH 34/72] phy: sun4i-usb: remove enable_pmu_unk1 from sun50i_h6_cfg For the current code, enable_pmu_unk1 only works in non-a83t and non-h6 types. So let's delete it from the sun50i_h6_cfg. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/dc8cbb7b3cd59902a6719f207d18a232903fac8a.1604988979.git.frank@allwinnertech.com Signed-off-by: Vinod Koul --- drivers/phy/allwinner/phy-sun4i-usb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index 406d5943f8a8..788dd5cdbb7d 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -965,7 +965,6 @@ static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = { .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, - .enable_pmu_unk1 = true, .phy0_dual_route = true, .missing_phys = BIT(1) | BIT(2), }; From 36a94760c98954e50ea621f7a9603fee3621deb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 13 Nov 2020 12:34:23 +0100 Subject: [PATCH 35/72] phy: phy-bcm-ns-usb3: drop support for deprecated DT binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initially this PHY driver was implementing MDIO access on its own. It was caused by lack of proper hardware design understanding. It has been changed back in 2017. DT bindings were changed and driver was updated to use MDIO layer. It should be really safe now to drop the old deprecated code. All Linux stored DT files don't use it for 3,5 year. There is close to 0 chance there is any bootloader with its own DTB using old the binding. Signed-off-by: Rafał Miłecki Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/20201113113423.9466-1-zajec5@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/broadcom/phy-bcm-ns-usb3.c | 156 +------------------------ 1 file changed, 5 insertions(+), 151 deletions(-) diff --git a/drivers/phy/broadcom/phy-bcm-ns-usb3.c b/drivers/phy/broadcom/phy-bcm-ns-usb3.c index 42baf4d6dd5d..eb10ffa13a62 100644 --- a/drivers/phy/broadcom/phy-bcm-ns-usb3.c +++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c @@ -22,8 +22,6 @@ #include #include -#define BCM_NS_USB3_MII_MNG_TIMEOUT_US 1000 /* usecs */ - #define BCM_NS_USB3_PHY_BASE_ADDR_REG 0x1f #define BCM_NS_USB3_PHY_PLL30_BLOCK 0x8000 #define BCM_NS_USB3_PHY_TX_PMD_BLOCK 0x8040 @@ -51,11 +49,8 @@ struct bcm_ns_usb3 { struct device *dev; enum bcm_ns_family family; void __iomem *dmp; - void __iomem *ccb_mii; struct mdio_device *mdiodev; struct phy *phy; - - int (*phy_write)(struct bcm_ns_usb3 *usb3, u16 reg, u16 value); }; static const struct of_device_id bcm_ns_usb3_id_table[] = { @@ -69,13 +64,9 @@ static const struct of_device_id bcm_ns_usb3_id_table[] = { }, {}, }; -MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table); static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg, - u16 value) -{ - return usb3->phy_write(usb3, reg, value); -} + u16 value); static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3) { @@ -187,8 +178,8 @@ static const struct phy_ops ops = { * MDIO driver code **************************************************/ -static int bcm_ns_usb3_mdiodev_phy_write(struct bcm_ns_usb3 *usb3, u16 reg, - u16 value) +static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg, + u16 value) { struct mdio_device *mdiodev = usb3->mdiodev; @@ -229,8 +220,6 @@ static int bcm_ns_usb3_mdio_probe(struct mdio_device *mdiodev) return PTR_ERR(usb3->dmp); } - usb3->phy_write = bcm_ns_usb3_mdiodev_phy_write; - usb3->phy = devm_phy_create(dev, NULL, &ops); if (IS_ERR(usb3->phy)) { dev_err(dev, "Failed to create PHY\n"); @@ -254,142 +243,7 @@ static struct mdio_driver bcm_ns_usb3_mdio_driver = { .probe = bcm_ns_usb3_mdio_probe, }; -/************************************************** - * Platform driver code - **************************************************/ - -static int bcm_ns_usb3_wait_reg(struct bcm_ns_usb3 *usb3, void __iomem *addr, - u32 mask, u32 value, int usec) -{ - u32 val; - int ret; - - ret = readl_poll_timeout_atomic(addr, val, ((val & mask) == value), - 10, usec); - if (ret) - dev_err(usb3->dev, "Timeout waiting for register %p\n", addr); - - return ret; -} - -static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3) -{ - return bcm_ns_usb3_wait_reg(usb3, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL, - 0x0100, 0x0000, - BCM_NS_USB3_MII_MNG_TIMEOUT_US); -} - -static int bcm_ns_usb3_platform_phy_write(struct bcm_ns_usb3 *usb3, u16 reg, - u16 value) -{ - u32 tmp = 0; - int err; - - err = bcm_ns_usb3_mii_mng_wait_idle(usb3); - if (err < 0) { - dev_err(usb3->dev, "Couldn't write 0x%08x value\n", value); - return err; - } - - /* TODO: Use a proper MDIO bus layer */ - tmp |= 0x58020000; /* Magic value for MDIO PHY write */ - tmp |= reg << 18; - tmp |= value; - writel(tmp, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA); - - return bcm_ns_usb3_mii_mng_wait_idle(usb3); -} - -static int bcm_ns_usb3_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - const struct of_device_id *of_id; - struct bcm_ns_usb3 *usb3; - struct phy_provider *phy_provider; - - usb3 = devm_kzalloc(dev, sizeof(*usb3), GFP_KERNEL); - if (!usb3) - return -ENOMEM; - - usb3->dev = dev; - - of_id = of_match_device(bcm_ns_usb3_id_table, dev); - if (!of_id) - return -EINVAL; - usb3->family = (enum bcm_ns_family)of_id->data; - - usb3->dmp = devm_platform_ioremap_resource_byname(pdev, "dmp"); - if (IS_ERR(usb3->dmp)) { - dev_err(dev, "Failed to map DMP regs\n"); - return PTR_ERR(usb3->dmp); - } - - usb3->ccb_mii = devm_platform_ioremap_resource_byname(pdev, "ccb-mii"); - if (IS_ERR(usb3->ccb_mii)) { - dev_err(dev, "Failed to map ChipCommon B MII regs\n"); - return PTR_ERR(usb3->ccb_mii); - } - - /* Enable MDIO. Setting MDCDIV as 26 */ - writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL); - - /* Wait for MDIO? */ - udelay(2); - - usb3->phy_write = bcm_ns_usb3_platform_phy_write; - - usb3->phy = devm_phy_create(dev, NULL, &ops); - if (IS_ERR(usb3->phy)) { - dev_err(dev, "Failed to create PHY\n"); - return PTR_ERR(usb3->phy); - } - - phy_set_drvdata(usb3->phy, usb3); - platform_set_drvdata(pdev, usb3); - - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (!IS_ERR(phy_provider)) - dev_info(dev, "Registered Broadcom Northstar USB 3.0 PHY driver\n"); - - return PTR_ERR_OR_ZERO(phy_provider); -} - -static struct platform_driver bcm_ns_usb3_driver = { - .probe = bcm_ns_usb3_probe, - .driver = { - .name = "bcm_ns_usb3", - .of_match_table = bcm_ns_usb3_id_table, - }, -}; - -static int __init bcm_ns_usb3_module_init(void) -{ - int err; - - /* - * For backward compatibility we register as MDIO and platform driver. - * After getting MDIO binding commonly used (e.g. switching all DT files - * to use it) we should deprecate the old binding and eventually drop - * support for it. - */ - - err = mdio_driver_register(&bcm_ns_usb3_mdio_driver); - if (err) - return err; - - err = platform_driver_register(&bcm_ns_usb3_driver); - if (err) - mdio_driver_unregister(&bcm_ns_usb3_mdio_driver); - - return err; -} -module_init(bcm_ns_usb3_module_init); - -static void __exit bcm_ns_usb3_module_exit(void) -{ - platform_driver_unregister(&bcm_ns_usb3_driver); - mdio_driver_unregister(&bcm_ns_usb3_mdio_driver); -} -module_exit(bcm_ns_usb3_module_exit) +mdio_module_driver(bcm_ns_usb3_mdio_driver); MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table); From e1404d203139d871946df9091a6e042b1154bd63 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 16 Nov 2020 11:13:14 +0100 Subject: [PATCH 36/72] dt-bindings: phy: add Amlogic AXG MIPI D-PHY bindings The Amlogic AXg SoCs embeds a MIPI D-PHY to communicate with DSI panels, this adds the bindings. This D-PHY depends on a separate analog PHY. Signed-off-by: Neil Armstrong Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201116101315.71720-2-narmstrong@baylibre.com Signed-off-by: Vinod Koul --- .../bindings/phy/amlogic,axg-mipi-dphy.yaml | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/amlogic,axg-mipi-dphy.yaml diff --git a/Documentation/devicetree/bindings/phy/amlogic,axg-mipi-dphy.yaml b/Documentation/devicetree/bindings/phy/amlogic,axg-mipi-dphy.yaml new file mode 100644 index 000000000000..be485f500887 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/amlogic,axg-mipi-dphy.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2020 BayLibre, SAS +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/phy/amlogic,axg-mipi-dphy.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Amlogic AXG MIPI D-PHY + +maintainers: + - Neil Armstrong + +properties: + compatible: + enum: + - amlogic,axg-mipi-dphy + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: pclk + + resets: + maxItems: 1 + + reset-names: + items: + - const: phy + + "#phy-cells": + const: 0 + + phys: + maxItems: 1 + + phy-names: + items: + - const: analog + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - phys + - phy-names + - "#phy-cells" + +additionalProperties: false + +examples: + - | + phy@ff640000 { + compatible = "amlogic,axg-mipi-dphy"; + reg = <0xff640000 0x100>; + clocks = <&clk_mipi_dsi_phy>; + clock-names = "pclk"; + resets = <&reset_phy>; + reset-names = "phy"; + phys = <&mipi_pcie_analog_dphy>; + phy-names = "analog"; + #phy-cells = <0>; + }; From 450889074f4fafaff0ea82c2c4c7e0a93b3cd5c7 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 16 Nov 2020 11:16:45 +0100 Subject: [PATCH 37/72] dt-bindings: phy: amlogic,meson-axg-mipi-pcie-analog: remove reg attribute The PHY registers happens to be at the beginning of a large zone containing interleaved system registers (mainly clocks, power management, PHY control..), found in all Amlogic SoC so far. The goal is to model it the same way as the other "features" of this zone, like Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt and Documentation/devicetree/bindings/power/amlogic,meson-ee-pwrc.yaml and have a coherent bindings scheme over the Amlogic SoCs. This update the description, removed the reg attribute then updates the example accordingly. Signed-off-by: Neil Armstrong Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201116101647.73448-2-narmstrong@baylibre.com Signed-off-by: Vinod Koul --- .../phy/amlogic,meson-axg-mipi-pcie-analog.yaml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/amlogic,meson-axg-mipi-pcie-analog.yaml b/Documentation/devicetree/bindings/phy/amlogic,meson-axg-mipi-pcie-analog.yaml index 18c1ec5e19ad..702763a84dac 100644 --- a/Documentation/devicetree/bindings/phy/amlogic,meson-axg-mipi-pcie-analog.yaml +++ b/Documentation/devicetree/bindings/phy/amlogic,meson-axg-mipi-pcie-analog.yaml @@ -9,27 +9,32 @@ title: Amlogic AXG shared MIPI/PCIE analog PHY maintainers: - Remi Pommarel +description: |+ + The Everything-Else Power Domains node should be the child of a syscon + node with the required property: + + - compatible: Should be the following: + "amlogic,meson-gx-hhi-sysctrl", "simple-mfd", "syscon" + + Refer to the the bindings described in + Documentation/devicetree/bindings/mfd/syscon.yaml + properties: compatible: const: amlogic,axg-mipi-pcie-analog-phy - reg: - maxItems: 1 - "#phy-cells": const: 1 required: - compatible - - reg - "#phy-cells" additionalProperties: false examples: - | - mpphy: phy@0 { + mpphy: phy { compatible = "amlogic,axg-mipi-pcie-analog-phy"; - reg = <0x0 0xc>; #phy-cells = <1>; }; From 76aefb221146dbe0de124f566329c76d5dcf118a Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 16 Nov 2020 11:13:15 +0100 Subject: [PATCH 38/72] phy: amlogic: Add AXG MIPI D-PHY driver The Amlogic AXG SoCs embeds a MIPI D-PHY used to communicate with DSI panels. Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20201116101315.71720-3-narmstrong@baylibre.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/Kconfig | 12 + drivers/phy/amlogic/Makefile | 1 + drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c | 413 ++++++++++++++++++ 3 files changed, 426 insertions(+) create mode 100644 drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c diff --git a/drivers/phy/amlogic/Kconfig b/drivers/phy/amlogic/Kconfig index 617cf073e9aa..99e8a4c7f1f3 100644 --- a/drivers/phy/amlogic/Kconfig +++ b/drivers/phy/amlogic/Kconfig @@ -70,3 +70,15 @@ config PHY_MESON_AXG_MIPI_PCIE_ANALOG Enable this to support the Meson MIPI + PCIE analog PHY found in Meson AXG SoCs. If unsure, say N. + +config PHY_MESON_AXG_MIPI_DPHY + tristate "Meson AXG MIPI DPHY driver" + default ARCH_MESON + depends on OF && (ARCH_MESON || COMPILE_TEST) + select GENERIC_PHY + select REGMAP_MMIO + select GENERIC_PHY_MIPI_DPHY + help + Enable this to support the Meson MIPI DPHY found in Meson AXG + SoCs. + If unsure, say N. diff --git a/drivers/phy/amlogic/Makefile b/drivers/phy/amlogic/Makefile index 99702a45e9be..8fa07fbd0d92 100644 --- a/drivers/phy/amlogic/Makefile +++ b/drivers/phy/amlogic/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_PHY_MESON_G12A_USB2) += phy-meson-g12a-usb2.o obj-$(CONFIG_PHY_MESON_G12A_USB3_PCIE) += phy-meson-g12a-usb3-pcie.o obj-$(CONFIG_PHY_MESON_AXG_PCIE) += phy-meson-axg-pcie.o obj-$(CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG) += phy-meson-axg-mipi-pcie-analog.o +obj-$(CONFIG_PHY_MESON_AXG_MIPI_DPHY) += phy-meson-axg-mipi-dphy.o diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c new file mode 100644 index 000000000000..cd2332bf0e31 --- /dev/null +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c @@ -0,0 +1,413 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Meson AXG MIPI DPHY driver + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved + * Copyright (C) 2020 BayLibre, SAS + * Author: Neil Armstrong + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* [31] soft reset for the phy. + * 1: reset. 0: dessert the reset. + * [30] clock lane soft reset. + * [29] data byte lane 3 soft reset. + * [28] data byte lane 2 soft reset. + * [27] data byte lane 1 soft reset. + * [26] data byte lane 0 soft reset. + * [25] mipi dsi pll clock selection. + * 1: clock from fixed 850Mhz clock source. 0: from VID2 PLL. + * [12] mipi HSbyteclk enable. + * [11] mipi divider clk selection. + * 1: select the mipi DDRCLKHS from clock divider. + * 0: from PLL clock. + * [10] mipi clock divider control. + * 1: /4. 0: /2. + * [9] mipi divider output enable. + * [8] mipi divider counter enable. + * [7] PLL clock enable. + * [5] LPDT data endian. + * 1 = transfer the high bit first. 0 : transfer the low bit first. + * [4] HS data endian. + * [3] force data byte lane in stop mode. + * [2] force data byte lane 0 in receiver mode. + * [1] write 1 to sync the txclkesc input. the internal logic have to + * use txclkesc to decide Txvalid and Txready. + * [0] enalbe the MIPI DPHY TxDDRClk. + */ +#define MIPI_DSI_PHY_CTRL 0x0 + +/* [31] clk lane tx_hs_en control selection. + * 1: from register. 0: use clk lane state machine. + * [30] register bit for clock lane tx_hs_en. + * [29] clk lane tx_lp_en contrl selection. + * 1: from register. 0: from clk lane state machine. + * [28] register bit for clock lane tx_lp_en. + * [27] chan0 tx_hs_en control selection. + * 1: from register. 0: from chan0 state machine. + * [26] register bit for chan0 tx_hs_en. + * [25] chan0 tx_lp_en control selection. + * 1: from register. 0: from chan0 state machine. + * [24] register bit from chan0 tx_lp_en. + * [23] chan0 rx_lp_en control selection. + * 1: from register. 0: from chan0 state machine. + * [22] register bit from chan0 rx_lp_en. + * [21] chan0 contention detection enable control selection. + * 1: from register. 0: from chan0 state machine. + * [20] register bit from chan0 contention dectection enable. + * [19] chan1 tx_hs_en control selection. + * 1: from register. 0: from chan0 state machine. + * [18] register bit for chan1 tx_hs_en. + * [17] chan1 tx_lp_en control selection. + * 1: from register. 0: from chan0 state machine. + * [16] register bit from chan1 tx_lp_en. + * [15] chan2 tx_hs_en control selection. + * 1: from register. 0: from chan0 state machine. + * [14] register bit for chan2 tx_hs_en. + * [13] chan2 tx_lp_en control selection. + * 1: from register. 0: from chan0 state machine. + * [12] register bit from chan2 tx_lp_en. + * [11] chan3 tx_hs_en control selection. + * 1: from register. 0: from chan0 state machine. + * [10] register bit for chan3 tx_hs_en. + * [9] chan3 tx_lp_en control selection. + * 1: from register. 0: from chan0 state machine. + * [8] register bit from chan3 tx_lp_en. + * [4] clk chan power down. this bit is also used as the power down + * of the whole MIPI_DSI_PHY. + * [3] chan3 power down. + * [2] chan2 power down. + * [1] chan1 power down. + * [0] chan0 power down. + */ +#define MIPI_DSI_CHAN_CTRL 0x4 + +/* [24] rx turn watch dog triggered. + * [23] rx esc watchdog triggered. + * [22] mbias ready. + * [21] txclkesc synced and ready. + * [20:17] clk lane state. {mbias_ready, tx_stop, tx_ulps, tx_hs_active} + * [16:13] chan3 state{0, tx_stop, tx_ulps, tx_hs_active} + * [12:9] chan2 state.{0, tx_stop, tx_ulps, tx_hs_active} + * [8:5] chan1 state. {0, tx_stop, tx_ulps, tx_hs_active} + * [4:0] chan0 state. {TX_STOP, tx_ULPS, hs_active, direction, rxulpsesc} + */ +#define MIPI_DSI_CHAN_STS 0x8 + +/* [31:24] TCLK_PREPARE. + * [23:16] TCLK_ZERO. + * [15:8] TCLK_POST. + * [7:0] TCLK_TRAIL. + */ +#define MIPI_DSI_CLK_TIM 0xc + +/* [31:24] THS_PREPARE. + * [23:16] THS_ZERO. + * [15:8] THS_TRAIL. + * [7:0] THS_EXIT. + */ +#define MIPI_DSI_HS_TIM 0x10 + +/* [31:24] tTA_GET. + * [23:16] tTA_GO. + * [15:8] tTA_SURE. + * [7:0] tLPX. + */ +#define MIPI_DSI_LP_TIM 0x14 + +/* wait time to MIPI DIS analog ready. */ +#define MIPI_DSI_ANA_UP_TIM 0x18 + +/* TINIT. */ +#define MIPI_DSI_INIT_TIM 0x1c + +/* TWAKEUP. */ +#define MIPI_DSI_WAKEUP_TIM 0x20 + +/* when in RxULPS check state, after the the logic enable the analog, + * how long we should wait to check the lP state . + */ +#define MIPI_DSI_LPOK_TIM 0x24 + +/* Watchdog for RX low power state no finished. */ +#define MIPI_DSI_LP_WCHDOG 0x28 + +/* tMBIAS, after send power up signals to analog, + * how long we should wait for analog powered up. + */ +#define MIPI_DSI_ANA_CTRL 0x2c + +/* [31:8] reserved for future. + * [7:0] tCLK_PRE. + */ +#define MIPI_DSI_CLK_TIM1 0x30 + +/* watchdog for turn around waiting time. */ +#define MIPI_DSI_TURN_WCHDOG 0x34 + +/* When in RxULPS state, how frequency we should to check + * if the TX side out of ULPS state. + */ +#define MIPI_DSI_ULPS_CHECK 0x38 +#define MIPI_DSI_TEST_CTRL0 0x3c +#define MIPI_DSI_TEST_CTRL1 0x40 + +struct phy_meson_axg_mipi_dphy_priv { + struct device *dev; + struct regmap *regmap; + struct clk *clk; + struct reset_control *reset; + struct phy *analog; + struct phy_configure_opts_mipi_dphy config; +}; + +static const struct regmap_config phy_meson_axg_mipi_dphy_regmap_conf = { + .reg_bits = 8, + .val_bits = 32, + .reg_stride = 4, + .max_register = MIPI_DSI_TEST_CTRL1, +}; + +static int phy_meson_axg_mipi_dphy_init(struct phy *phy) +{ + struct phy_meson_axg_mipi_dphy_priv *priv = phy_get_drvdata(phy); + int ret; + + ret = phy_init(priv->analog); + if (ret) + return ret; + + ret = reset_control_reset(priv->reset); + if (ret) + return ret; + + return 0; +} + +static int phy_meson_axg_mipi_dphy_configure(struct phy *phy, + union phy_configure_opts *opts) +{ + struct phy_meson_axg_mipi_dphy_priv *priv = phy_get_drvdata(phy); + int ret; + + ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy); + if (ret) + return ret; + + ret = phy_configure(priv->analog, opts); + if (ret) + return ret; + + memcpy(&priv->config, opts, sizeof(priv->config)); + + return 0; +} + +static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy) +{ + struct phy_meson_axg_mipi_dphy_priv *priv = phy_get_drvdata(phy); + int ret; + unsigned long temp; + + ret = phy_power_on(priv->analog); + if (ret) + return ret; + + /* enable phy clock */ + regmap_write(priv->regmap, MIPI_DSI_PHY_CTRL, 0x1); + regmap_write(priv->regmap, MIPI_DSI_PHY_CTRL, + BIT(0) | /* enable the DSI PLL clock . */ + BIT(7) | /* enable pll clock which connected to DDR clock path */ + BIT(8)); /* enable the clock divider counter */ + + /* enable the divider clock out */ + regmap_update_bits(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(9), BIT(9)); + + /* enable the byte clock generation. */ + regmap_update_bits(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(12), BIT(12)); + regmap_update_bits(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(31), BIT(31)); + regmap_update_bits(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(31), 0); + + /* Calculate lanebyteclk period in ps */ + temp = (1000000 * 100) / (priv->config.hs_clk_rate / 1000); + temp = temp * 8 * 10; + + regmap_write(priv->regmap, MIPI_DSI_CLK_TIM, + DIV_ROUND_UP(priv->config.clk_trail, temp) | + (DIV_ROUND_UP(priv->config.clk_post + + priv->config.hs_trail, temp) << 8) | + (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) | + (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24)); + regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1, + DIV_ROUND_UP(priv->config.clk_pre, temp)); + + regmap_write(priv->regmap, MIPI_DSI_HS_TIM, + DIV_ROUND_UP(priv->config.hs_exit, temp) | + (DIV_ROUND_UP(priv->config.hs_trail, temp) << 8) | + (DIV_ROUND_UP(priv->config.hs_zero, temp) << 16) | + (DIV_ROUND_UP(priv->config.hs_prepare, temp) << 24)); + + regmap_write(priv->regmap, MIPI_DSI_LP_TIM, + DIV_ROUND_UP(priv->config.lpx, temp) | + (DIV_ROUND_UP(priv->config.ta_sure, temp) << 8) | + (DIV_ROUND_UP(priv->config.ta_go, temp) << 16) | + (DIV_ROUND_UP(priv->config.ta_get, temp) << 24)); + + regmap_write(priv->regmap, MIPI_DSI_ANA_UP_TIM, 0x0100); + regmap_write(priv->regmap, MIPI_DSI_INIT_TIM, + DIV_ROUND_UP(priv->config.init * NSEC_PER_MSEC, temp)); + regmap_write(priv->regmap, MIPI_DSI_WAKEUP_TIM, + DIV_ROUND_UP(priv->config.wakeup * NSEC_PER_MSEC, temp)); + regmap_write(priv->regmap, MIPI_DSI_LPOK_TIM, 0x7C); + regmap_write(priv->regmap, MIPI_DSI_ULPS_CHECK, 0x927C); + regmap_write(priv->regmap, MIPI_DSI_LP_WCHDOG, 0x1000); + regmap_write(priv->regmap, MIPI_DSI_TURN_WCHDOG, 0x1000); + + /* Powerup the analog circuit */ + switch (priv->config.lanes) { + case 1: + regmap_write(priv->regmap, MIPI_DSI_CHAN_CTRL, 0xe); + break; + case 2: + regmap_write(priv->regmap, MIPI_DSI_CHAN_CTRL, 0xc); + break; + case 3: + regmap_write(priv->regmap, MIPI_DSI_CHAN_CTRL, 0x8); + break; + case 4: + default: + regmap_write(priv->regmap, MIPI_DSI_CHAN_CTRL, 0); + break; + } + + /* Trigger a sync active for esc_clk */ + regmap_update_bits(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(1), BIT(1)); + + return 0; +} + +static int phy_meson_axg_mipi_dphy_power_off(struct phy *phy) +{ + struct phy_meson_axg_mipi_dphy_priv *priv = phy_get_drvdata(phy); + + regmap_write(priv->regmap, MIPI_DSI_CHAN_CTRL, 0xf); + regmap_write(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(31)); + + phy_power_off(priv->analog); + + return 0; +} + +static int phy_meson_axg_mipi_dphy_exit(struct phy *phy) +{ + struct phy_meson_axg_mipi_dphy_priv *priv = phy_get_drvdata(phy); + int ret; + + ret = phy_exit(priv->analog); + if (ret) + return ret; + + return reset_control_reset(priv->reset); +} + +static const struct phy_ops phy_meson_axg_mipi_dphy_ops = { + .configure = phy_meson_axg_mipi_dphy_configure, + .init = phy_meson_axg_mipi_dphy_init, + .exit = phy_meson_axg_mipi_dphy_exit, + .power_on = phy_meson_axg_mipi_dphy_power_on, + .power_off = phy_meson_axg_mipi_dphy_power_off, + .owner = THIS_MODULE, +}; + +static int phy_meson_axg_mipi_dphy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct phy_provider *phy_provider; + struct resource *res; + struct phy_meson_axg_mipi_dphy_priv *priv; + struct phy *phy; + void __iomem *base; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + platform_set_drvdata(pdev, priv); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + priv->regmap = devm_regmap_init_mmio(dev, base, + &phy_meson_axg_mipi_dphy_regmap_conf); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); + + priv->clk = devm_clk_get(dev, "pclk"); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + + priv->reset = devm_reset_control_get(dev, "phy"); + if (IS_ERR(priv->reset)) + return PTR_ERR(priv->reset); + + priv->analog = devm_phy_get(dev, "analog"); + if (IS_ERR(priv->analog)) + return PTR_ERR(priv->analog); + + ret = clk_prepare_enable(priv->clk); + if (ret) + return ret; + + ret = reset_control_deassert(priv->reset); + if (ret) + return ret; + + phy = devm_phy_create(dev, NULL, &phy_meson_axg_mipi_dphy_ops); + if (IS_ERR(phy)) { + ret = PTR_ERR(phy); + if (ret != -EPROBE_DEFER) + dev_err(dev, "failed to create PHY\n"); + + return ret; + } + + phy_set_drvdata(phy, priv); + + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id phy_meson_axg_mipi_dphy_of_match[] = { + { .compatible = "amlogic,axg-mipi-dphy", }, + { }, +}; +MODULE_DEVICE_TABLE(of, phy_meson_axg_mipi_dphy_of_match); + +static struct platform_driver phy_meson_axg_mipi_dphy_driver = { + .probe = phy_meson_axg_mipi_dphy_probe, + .driver = { + .name = "phy-meson-axg-mipi-dphy", + .of_match_table = phy_meson_axg_mipi_dphy_of_match, + }, +}; +module_platform_driver(phy_meson_axg_mipi_dphy_driver); + +MODULE_AUTHOR("Neil Armstrong "); +MODULE_DESCRIPTION("Meson AXG MIPI DPHY driver"); +MODULE_LICENSE("GPL v2"); From 87c3cdecb3d5150270f1529ac140e7d0c192ba9d Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 16 Nov 2020 11:16:46 +0100 Subject: [PATCH 39/72] dt-bindings: phy: amlogic,meson-axg-mipi-pcie-analog: remove phy cell parameter The Amlogic AXG MIPI + PCIe Analog PHY provides function for both PCIe and MIPI DSI at the same time, and is not exclusive. Thus remove the invalid phy cell parameter. Signed-off-by: Neil Armstrong Acked-by: Rob Herring Link: https://lore.kernel.org/r/20201116101647.73448-3-narmstrong@baylibre.com Signed-off-by: Vinod Koul --- .../bindings/phy/amlogic,meson-axg-mipi-pcie-analog.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/amlogic,meson-axg-mipi-pcie-analog.yaml b/Documentation/devicetree/bindings/phy/amlogic,meson-axg-mipi-pcie-analog.yaml index 702763a84dac..4d01f3124e1c 100644 --- a/Documentation/devicetree/bindings/phy/amlogic,meson-axg-mipi-pcie-analog.yaml +++ b/Documentation/devicetree/bindings/phy/amlogic,meson-axg-mipi-pcie-analog.yaml @@ -24,7 +24,7 @@ properties: const: amlogic,axg-mipi-pcie-analog-phy "#phy-cells": - const: 1 + const: 0 required: - compatible @@ -36,5 +36,5 @@ examples: - | mpphy: phy { compatible = "amlogic,axg-mipi-pcie-analog-phy"; - #phy-cells = <1>; + #phy-cells = <0>; }; From 8eff8b4e22d9885f1509a68bf9a7cc1961c5dee4 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 16 Nov 2020 11:16:47 +0100 Subject: [PATCH 40/72] phy: amlogic: phy-meson-axg-mipi-pcie-analog: add support for MIPI DSI analog The AXG Analog MIPI-DSI PHY also provides functions to the PCIe PHY, thus we need to have inclusive support for both interfaces at runtime. This fixes the regmap get from parent node, removes cell param to select a mode and implement runtime configuration & power on/off for both functions since they are not exclusive. Signed-off-by: Neil Armstrong Reviewed-by: Remi Pommarel Link: https://lore.kernel.org/r/20201116101647.73448-4-narmstrong@baylibre.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/Kconfig | 1 + .../amlogic/phy-meson-axg-mipi-pcie-analog.c | 212 ++++++++++++------ 2 files changed, 140 insertions(+), 73 deletions(-) diff --git a/drivers/phy/amlogic/Kconfig b/drivers/phy/amlogic/Kconfig index 99e8a4c7f1f3..db5d0cd757e3 100644 --- a/drivers/phy/amlogic/Kconfig +++ b/drivers/phy/amlogic/Kconfig @@ -66,6 +66,7 @@ config PHY_MESON_AXG_MIPI_PCIE_ANALOG depends on OF && (ARCH_MESON || COMPILE_TEST) select GENERIC_PHY select REGMAP_MMIO + select GENERIC_PHY_MIPI_DPHY help Enable this to support the Meson MIPI + PCIE analog PHY found in Meson AXG SoCs. diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c index 1431cbf885e1..6eb21551bdd9 100644 --- a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c @@ -4,9 +4,13 @@ * * Copyright (C) 2019 Remi Pommarel */ +#include +#include #include #include #include +#include +#include #include #include @@ -14,10 +18,10 @@ #define HHI_MIPI_CNTL0_COMMON_BLOCK GENMASK(31, 28) #define HHI_MIPI_CNTL0_ENABLE BIT(29) #define HHI_MIPI_CNTL0_BANDGAP BIT(26) -#define HHI_MIPI_CNTL0_DECODE_TO_RTERM GENMASK(15, 12) -#define HHI_MIPI_CNTL0_OUTPUT_EN BIT(3) +#define HHI_MIPI_CNTL0_DIF_REF_CTL1 GENMASK(25, 16) +#define HHI_MIPI_CNTL0_DIF_REF_CTL0 GENMASK(15, 0) -#define HHI_MIPI_CNTL1 0x01 +#define HHI_MIPI_CNTL1 0x04 #define HHI_MIPI_CNTL1_CH0_CML_PDR_EN BIT(12) #define HHI_MIPI_CNTL1_LP_ABILITY GENMASK(5, 4) #define HHI_MIPI_CNTL1_LP_RESISTER BIT(3) @@ -25,41 +29,146 @@ #define HHI_MIPI_CNTL1_INPUT_SEL BIT(1) #define HHI_MIPI_CNTL1_PRBS7_EN BIT(0) -#define HHI_MIPI_CNTL2 0x02 +#define HHI_MIPI_CNTL2 0x08 #define HHI_MIPI_CNTL2_CH_PU GENMASK(31, 25) #define HHI_MIPI_CNTL2_CH_CTL GENMASK(24, 19) #define HHI_MIPI_CNTL2_CH0_DIGDR_EN BIT(18) #define HHI_MIPI_CNTL2_CH_DIGDR_EN BIT(17) #define HHI_MIPI_CNTL2_LPULPS_EN BIT(16) -#define HHI_MIPI_CNTL2_CH_EN(n) BIT(15 - (n)) +#define HHI_MIPI_CNTL2_CH_EN GENMASK(15, 11) #define HHI_MIPI_CNTL2_CH0_LP_CTL GENMASK(10, 1) +#define DSI_LANE_0 (1 << 4) +#define DSI_LANE_1 (1 << 3) +#define DSI_LANE_CLK (1 << 2) +#define DSI_LANE_2 (1 << 1) +#define DSI_LANE_3 (1 << 0) +#define DSI_LANE_MASK (0x1F) + struct phy_axg_mipi_pcie_analog_priv { struct phy *phy; - unsigned int mode; struct regmap *regmap; + bool dsi_configured; + bool dsi_enabled; + bool powered; + struct phy_configure_opts_mipi_dphy config; }; -static const struct regmap_config phy_axg_mipi_pcie_analog_regmap_conf = { - .reg_bits = 8, - .val_bits = 32, - .reg_stride = 4, - .max_register = HHI_MIPI_CNTL2, -}; +static void phy_bandgap_enable(struct phy_axg_mipi_pcie_analog_priv *priv) +{ + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, + HHI_MIPI_CNTL0_BANDGAP, HHI_MIPI_CNTL0_BANDGAP); + + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, + HHI_MIPI_CNTL0_ENABLE, HHI_MIPI_CNTL0_ENABLE); +} + +static void phy_bandgap_disable(struct phy_axg_mipi_pcie_analog_priv *priv) +{ + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, + HHI_MIPI_CNTL0_BANDGAP, 0); + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, + HHI_MIPI_CNTL0_ENABLE, 0); +} + +static void phy_dsi_analog_enable(struct phy_axg_mipi_pcie_analog_priv *priv) +{ + u32 reg; + + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, + HHI_MIPI_CNTL0_DIF_REF_CTL1, + FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL1, 0x1b8)); + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, + BIT(31), BIT(31)); + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, + HHI_MIPI_CNTL0_DIF_REF_CTL0, + FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL0, 0x8)); + + regmap_write(priv->regmap, HHI_MIPI_CNTL1, 0x001e); + + regmap_write(priv->regmap, HHI_MIPI_CNTL2, + (0x26e0 << 16) | (0x459 << 0)); + + reg = DSI_LANE_CLK; + switch (priv->config.lanes) { + case 4: + reg |= DSI_LANE_3; + fallthrough; + case 3: + reg |= DSI_LANE_2; + fallthrough; + case 2: + reg |= DSI_LANE_1; + fallthrough; + case 1: + reg |= DSI_LANE_0; + break; + default: + reg = 0; + } + + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL2, + HHI_MIPI_CNTL2_CH_EN, + FIELD_PREP(HHI_MIPI_CNTL2_CH_EN, reg)); + + priv->dsi_enabled = true; +} + +static void phy_dsi_analog_disable(struct phy_axg_mipi_pcie_analog_priv *priv) +{ + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, + HHI_MIPI_CNTL0_DIF_REF_CTL1, + FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL1, 0)); + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, BIT(31), 0); + regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, + HHI_MIPI_CNTL0_DIF_REF_CTL1, 0); + + regmap_write(priv->regmap, HHI_MIPI_CNTL1, 0x6); + + regmap_write(priv->regmap, HHI_MIPI_CNTL2, 0x00200000); + + priv->dsi_enabled = false; +} + +static int phy_axg_mipi_pcie_analog_configure(struct phy *phy, + union phy_configure_opts *opts) +{ + struct phy_axg_mipi_pcie_analog_priv *priv = phy_get_drvdata(phy); + int ret; + + ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy); + if (ret) + return ret; + + memcpy(&priv->config, opts, sizeof(priv->config)); + + priv->dsi_configured = true; + + /* If PHY was already powered on, setup the DSI analog part */ + if (priv->powered) { + /* If reconfiguring, disable & reconfigure */ + if (priv->dsi_enabled) + phy_dsi_analog_disable(priv); + + usleep_range(100, 200); + + phy_dsi_analog_enable(priv); + } + + return 0; +} static int phy_axg_mipi_pcie_analog_power_on(struct phy *phy) { struct phy_axg_mipi_pcie_analog_priv *priv = phy_get_drvdata(phy); - /* MIPI not supported yet */ - if (priv->mode != PHY_TYPE_PCIE) - return -EINVAL; + phy_bandgap_enable(priv); - regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, - HHI_MIPI_CNTL0_BANDGAP, HHI_MIPI_CNTL0_BANDGAP); + if (priv->dsi_configured) + phy_dsi_analog_enable(priv); + + priv->powered = true; - regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, - HHI_MIPI_CNTL0_ENABLE, HHI_MIPI_CNTL0_ENABLE); return 0; } @@ -67,58 +176,23 @@ static int phy_axg_mipi_pcie_analog_power_off(struct phy *phy) { struct phy_axg_mipi_pcie_analog_priv *priv = phy_get_drvdata(phy); - /* MIPI not supported yet */ - if (priv->mode != PHY_TYPE_PCIE) - return -EINVAL; + phy_bandgap_disable(priv); - regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, - HHI_MIPI_CNTL0_BANDGAP, 0); - regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, - HHI_MIPI_CNTL0_ENABLE, 0); - return 0; -} + if (priv->dsi_enabled) + phy_dsi_analog_disable(priv); -static int phy_axg_mipi_pcie_analog_init(struct phy *phy) -{ - return 0; -} + priv->powered = false; -static int phy_axg_mipi_pcie_analog_exit(struct phy *phy) -{ return 0; } static const struct phy_ops phy_axg_mipi_pcie_analog_ops = { - .init = phy_axg_mipi_pcie_analog_init, - .exit = phy_axg_mipi_pcie_analog_exit, + .configure = phy_axg_mipi_pcie_analog_configure, .power_on = phy_axg_mipi_pcie_analog_power_on, .power_off = phy_axg_mipi_pcie_analog_power_off, .owner = THIS_MODULE, }; -static struct phy *phy_axg_mipi_pcie_analog_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct phy_axg_mipi_pcie_analog_priv *priv = dev_get_drvdata(dev); - unsigned int mode; - - if (args->args_count != 1) { - dev_err(dev, "invalid number of arguments\n"); - return ERR_PTR(-EINVAL); - } - - mode = args->args[0]; - - /* MIPI mode is not supported yet */ - if (mode != PHY_TYPE_PCIE) { - dev_err(dev, "invalid phy mode select argument\n"); - return ERR_PTR(-EINVAL); - } - - priv->mode = mode; - return priv->phy; -} - static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev) { struct phy_provider *phy; @@ -126,27 +200,20 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev) struct phy_axg_mipi_pcie_analog_priv *priv; struct device_node *np = dev->of_node; struct regmap *map; - struct resource *res; - void __iomem *base; int ret; priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); - if (IS_ERR(base)) { - dev_err(dev, "failed to get regmap base\n"); - return PTR_ERR(base); - } - - map = devm_regmap_init_mmio(dev, base, - &phy_axg_mipi_pcie_analog_regmap_conf); + /* Get the hhi system controller node */ + map = syscon_node_to_regmap(of_get_parent(dev->of_node)); if (IS_ERR(map)) { - dev_err(dev, "failed to get HHI regmap\n"); + dev_err(dev, + "failed to get HHI regmap\n"); return PTR_ERR(map); } + priv->regmap = map; priv->phy = devm_phy_create(dev, np, &phy_axg_mipi_pcie_analog_ops); @@ -160,8 +227,7 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev) phy_set_drvdata(priv->phy, priv); dev_set_drvdata(dev, priv); - phy = devm_of_phy_provider_register(dev, - phy_axg_mipi_pcie_analog_xlate); + phy = devm_of_phy_provider_register(dev, of_phy_simple_xlate); return PTR_ERR_OR_ZERO(phy); } From 864788c00fd75d76c1e3183ab54fcf4fac22f3b7 Mon Sep 17 00:00:00 2001 From: Amelie Delaunay Date: Mon, 16 Nov 2020 18:19:17 +0100 Subject: [PATCH 41/72] dt-bindings: phy: phy-stm32-usbphyc: convert bindings to json-schema Convert the STM32 USB PHY Controller (USBPHYC) bindings to DT schema format using json-schema. Signed-off-by: Amelie Delaunay Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201116171917.10447-1-amelie.delaunay@st.com Signed-off-by: Vinod Koul --- .../bindings/phy/phy-stm32-usbphyc.txt | 73 --------- .../bindings/phy/phy-stm32-usbphyc.yaml | 138 ++++++++++++++++++ 2 files changed, 138 insertions(+), 73 deletions(-) delete mode 100644 Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.txt create mode 100644 Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml diff --git a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.txt b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.txt deleted file mode 100644 index 725ae71ae653..000000000000 --- a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.txt +++ /dev/null @@ -1,73 +0,0 @@ -STMicroelectronics STM32 USB HS PHY controller - -The STM32 USBPHYC block contains a dual port High Speed UTMI+ PHY and a UTMI -switch. It controls PHY configuration and status, and the UTMI+ switch that -selects either OTG or HOST controller for the second PHY port. It also sets -PLL configuration. - -USBPHYC - |_ PLL - | - |_ PHY port#1 _________________ HOST controller - | _ | - | / 1|________________| - |_ PHY port#2 ----| |________________ - | \_0| | - |_ UTMI switch_______| OTG controller - - -Phy provider node -================= - -Required properties: -- compatible: must be "st,stm32mp1-usbphyc" -- reg: address and length of the usb phy control register set -- clocks: phandle + clock specifier for the PLL phy clock -- #address-cells: number of address cells for phys sub-nodes, must be <1> -- #size-cells: number of size cells for phys sub-nodes, must be <0> - -Optional properties: -- assigned-clocks: phandle + clock specifier for the PLL phy clock -- assigned-clock-parents: the PLL phy clock parent -- resets: phandle + reset specifier - -Required nodes: one sub-node per port the controller provides. - -Phy sub-nodes -============== - -Required properties: -- reg: phy port index -- phy-supply: phandle to the regulator providing 3V3 power to the PHY, - see phy-bindings.txt in the same directory. -- vdda1v1-supply: phandle to the regulator providing 1V1 power to the PHY -- vdda1v8-supply: phandle to the regulator providing 1V8 power to the PHY -- #phy-cells: see phy-bindings.txt in the same directory, must be <0> for PHY - port#1 and must be <1> for PHY port#2, to select USB controller - - -Example: - usbphyc: usb-phy@5a006000 { - compatible = "st,stm32mp1-usbphyc"; - reg = <0x5a006000 0x1000>; - clocks = <&rcc_clk USBPHY_K>; - resets = <&rcc_rst USBPHY_R>; - #address-cells = <1>; - #size-cells = <0>; - - usbphyc_port0: usb-phy@0 { - reg = <0>; - phy-supply = <&vdd_usb>; - vdda1v1-supply = <®11>; - vdda1v8-supply = <®18> - #phy-cells = <0>; - }; - - usbphyc_port1: usb-phy@1 { - reg = <1>; - phy-supply = <&vdd_usb>; - vdda1v1-supply = <®11>; - vdda1v8-supply = <®18> - #phy-cells = <1>; - }; - }; diff --git a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml new file mode 100644 index 000000000000..0ba61979b970 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml @@ -0,0 +1,138 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/phy-stm32-usbphyc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: STMicroelectronics STM32 USB HS PHY controller binding + +description: + + The STM32 USBPHYC block contains a dual port High Speed UTMI+ PHY and a UTMI + switch. It controls PHY configuration and status, and the UTMI+ switch that + selects either OTG or HOST controller for the second PHY port. It also sets + PLL configuration. + + USBPHYC + |_ PLL + | + |_ PHY port#1 _________________ HOST controller + | __ | + | / 1|________________| + |_ PHY port#2 ----| |________________ + | \_0| | + |_ UTMI switch_______| OTG controller + +maintainers: + - Amelie Delaunay + +properties: + compatible: + const: st,stm32mp1-usbphyc + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +#Required child nodes: + +patternProperties: + "^usb-phy@[0|1]$": + type: object + description: + Each port the controller provides must be represented as a sub-node. + + properties: + reg: + description: phy port index. + maxItems: 1 + + phy-supply: + description: regulator providing 3V3 power supply to the PHY. + + vdda1v1-supply: + description: regulator providing 1V1 power supply to the PLL block + + vdda1v8-supply: + description: regulator providing 1V8 power supply to the PLL block + + "#phy-cells": + enum: [ 0x0, 0x1 ] + + allOf: + - if: + properties: + reg: + const: 0 + then: + properties: + "#phy-cells": + const: 0 + else: + properties: + "#phy-cells": + const: 1 + description: + The value is used to select UTMI switch output. + 0 for OTG controller and 1 for Host controller. + + required: + - reg + - phy-supply + - vdda1v1-supply + - vdda1v8-supply + - "#phy-cells" + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - "#address-cells" + - "#size-cells" + - usb-phy@0 + - usb-phy@1 + +additionalProperties: false + +examples: + - | + #include + #include + usbphyc: usbphyc@5a006000 { + compatible = "st,stm32mp1-usbphyc"; + reg = <0x5a006000 0x1000>; + clocks = <&rcc USBPHY_K>; + resets = <&rcc USBPHY_R>; + #address-cells = <1>; + #size-cells = <0>; + + usbphyc_port0: usb-phy@0 { + reg = <0>; + phy-supply = <&vdd_usb>; + vdda1v1-supply = <®11>; + vdda1v8-supply = <®18>; + #phy-cells = <0>; + }; + + usbphyc_port1: usb-phy@1 { + reg = <1>; + phy-supply = <&vdd_usb>; + vdda1v1-supply = <®11>; + vdda1v8-supply = <®18>; + #phy-cells = <1>; + }; + }; +... From 496db029142f1392b8eebc19bcc49796feb7c8ba Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Fri, 20 Nov 2020 11:26:27 +0100 Subject: [PATCH 42/72] phy: samsung: phy-exynos-pcie: rework driver to support Exynos5433 PCIe PHY Exynos5440 SoC support has been dropped since commit 8c83315da1cf ("ARM: dts: exynos: Remove Exynos5440"). Rework this driver to support PCIe PHY variant found in the Exynos5433 SoCs. Signed-off-by: Jaehoon Chung [mszyprow: reworked the driver to support only Exynos5433 variant, rebased onto current kernel code, rewrote commit message] Signed-off-by: Marek Szyprowski Acked-by: Krzysztof Kozlowski Reviewed-by: Jingoo Han Link: https://lore.kernel.org/r/20201120102627.14450-1-m.szyprowski@samsung.com Signed-off-by: Vinod Koul --- drivers/phy/samsung/phy-exynos-pcie.c | 291 ++++++++++---------------- 1 file changed, 107 insertions(+), 184 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos-pcie.c b/drivers/phy/samsung/phy-exynos-pcie.c index c98fff5c1ac8..d91de323dd0e 100644 --- a/drivers/phy/samsung/phy-exynos-pcie.c +++ b/drivers/phy/samsung/phy-exynos-pcie.c @@ -4,70 +4,41 @@ * * Phy provider for PCIe controller on Exynos SoC series * - * Copyright (C) 2017 Samsung Electronics Co., Ltd. + * Copyright (C) 2017-2020 Samsung Electronics Co., Ltd. * Jaehoon Chung */ -#include #include -#include -#include #include -#include -#include #include #include #include #include -/* PCIe Purple registers */ -#define PCIE_PHY_GLOBAL_RESET 0x000 -#define PCIE_PHY_COMMON_RESET 0x004 -#define PCIE_PHY_CMN_REG 0x008 -#define PCIE_PHY_MAC_RESET 0x00c -#define PCIE_PHY_PLL_LOCKED 0x010 -#define PCIE_PHY_TRSVREG_RESET 0x020 -#define PCIE_PHY_TRSV_RESET 0x024 +#define PCIE_PHY_OFFSET(x) ((x) * 0x4) -/* PCIe PHY registers */ -#define PCIE_PHY_IMPEDANCE 0x004 -#define PCIE_PHY_PLL_DIV_0 0x008 -#define PCIE_PHY_PLL_BIAS 0x00c -#define PCIE_PHY_DCC_FEEDBACK 0x014 -#define PCIE_PHY_PLL_DIV_1 0x05c -#define PCIE_PHY_COMMON_POWER 0x064 -#define PCIE_PHY_COMMON_PD_CMN BIT(3) -#define PCIE_PHY_TRSV0_EMP_LVL 0x084 -#define PCIE_PHY_TRSV0_DRV_LVL 0x088 -#define PCIE_PHY_TRSV0_RXCDR 0x0ac -#define PCIE_PHY_TRSV0_POWER 0x0c4 -#define PCIE_PHY_TRSV0_PD_TSV BIT(7) -#define PCIE_PHY_TRSV0_LVCC 0x0dc -#define PCIE_PHY_TRSV1_EMP_LVL 0x144 -#define PCIE_PHY_TRSV1_RXCDR 0x16c -#define PCIE_PHY_TRSV1_POWER 0x184 -#define PCIE_PHY_TRSV1_PD_TSV BIT(7) -#define PCIE_PHY_TRSV1_LVCC 0x19c -#define PCIE_PHY_TRSV2_EMP_LVL 0x204 -#define PCIE_PHY_TRSV2_RXCDR 0x22c -#define PCIE_PHY_TRSV2_POWER 0x244 -#define PCIE_PHY_TRSV2_PD_TSV BIT(7) -#define PCIE_PHY_TRSV2_LVCC 0x25c -#define PCIE_PHY_TRSV3_EMP_LVL 0x2c4 -#define PCIE_PHY_TRSV3_RXCDR 0x2ec -#define PCIE_PHY_TRSV3_POWER 0x304 -#define PCIE_PHY_TRSV3_PD_TSV BIT(7) -#define PCIE_PHY_TRSV3_LVCC 0x31c +/* Sysreg FSYS register offsets and bits for Exynos5433 */ +#define PCIE_EXYNOS5433_PHY_MAC_RESET 0x0208 +#define PCIE_MAC_RESET_MASK 0xFF +#define PCIE_MAC_RESET BIT(4) +#define PCIE_EXYNOS5433_PHY_L1SUB_CM_CON 0x1010 +#define PCIE_REFCLK_GATING_EN BIT(0) +#define PCIE_EXYNOS5433_PHY_COMMON_RESET 0x1020 +#define PCIE_PHY_RESET BIT(0) +#define PCIE_EXYNOS5433_PHY_GLOBAL_RESET 0x1040 +#define PCIE_GLOBAL_RESET BIT(0) +#define PCIE_REFCLK BIT(1) +#define PCIE_REFCLK_MASK 0x16 +#define PCIE_APP_REQ_EXIT_L1_MODE BIT(5) -struct exynos_pcie_phy_data { - const struct phy_ops *ops; -}; +/* PMU PCIE PHY isolation control */ +#define EXYNOS5433_PMU_PCIE_PHY_OFFSET 0x730 /* For Exynos pcie phy */ struct exynos_pcie_phy { - const struct exynos_pcie_phy_data *drv_data; - void __iomem *phy_base; - void __iomem *blk_base; /* For exynos5440 */ + void __iomem *base; + struct regmap *pmureg; + struct regmap *fsysreg; }; static void exynos_pcie_phy_writel(void __iomem *base, u32 val, u32 offset) @@ -75,153 +46,103 @@ static void exynos_pcie_phy_writel(void __iomem *base, u32 val, u32 offset) writel(val, base + offset); } -static u32 exynos_pcie_phy_readl(void __iomem *base, u32 offset) -{ - return readl(base + offset); -} - -/* For Exynos5440 specific functions */ -static int exynos5440_pcie_phy_init(struct phy *phy) +/* Exynos5433 specific functions */ +static int exynos5433_pcie_phy_init(struct phy *phy) { struct exynos_pcie_phy *ep = phy_get_drvdata(phy); - /* DCC feedback control off */ - exynos_pcie_phy_writel(ep->phy_base, 0x29, PCIE_PHY_DCC_FEEDBACK); + regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_COMMON_RESET, + PCIE_PHY_RESET, 1); + regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_MAC_RESET, + PCIE_MAC_RESET, 0); - /* set TX/RX impedance */ - exynos_pcie_phy_writel(ep->phy_base, 0xd5, PCIE_PHY_IMPEDANCE); + /* PHY refclk 24MHz */ + regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_GLOBAL_RESET, + PCIE_REFCLK_MASK, PCIE_REFCLK); + regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_GLOBAL_RESET, + PCIE_GLOBAL_RESET, 0); - /* set 50Mhz PHY clock */ - exynos_pcie_phy_writel(ep->phy_base, 0x14, PCIE_PHY_PLL_DIV_0); - exynos_pcie_phy_writel(ep->phy_base, 0x12, PCIE_PHY_PLL_DIV_1); - /* set TX Differential output for lane 0 */ - exynos_pcie_phy_writel(ep->phy_base, 0x7f, PCIE_PHY_TRSV0_DRV_LVL); + exynos_pcie_phy_writel(ep->base, 0x11, PCIE_PHY_OFFSET(0x3)); - /* set TX Pre-emphasis Level Control for lane 0 to minimum */ - exynos_pcie_phy_writel(ep->phy_base, 0x0, PCIE_PHY_TRSV0_EMP_LVL); + /* band gap reference on */ + exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x20)); + exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x4b)); - /* set RX clock and data recovery bandwidth */ - exynos_pcie_phy_writel(ep->phy_base, 0xe7, PCIE_PHY_PLL_BIAS); - exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV0_RXCDR); - exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV1_RXCDR); - exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV2_RXCDR); - exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV3_RXCDR); + /* jitter tunning */ + exynos_pcie_phy_writel(ep->base, 0x34, PCIE_PHY_OFFSET(0x4)); + exynos_pcie_phy_writel(ep->base, 0x02, PCIE_PHY_OFFSET(0x7)); + exynos_pcie_phy_writel(ep->base, 0x41, PCIE_PHY_OFFSET(0x21)); + exynos_pcie_phy_writel(ep->base, 0x7F, PCIE_PHY_OFFSET(0x14)); + exynos_pcie_phy_writel(ep->base, 0xC0, PCIE_PHY_OFFSET(0x15)); + exynos_pcie_phy_writel(ep->base, 0x61, PCIE_PHY_OFFSET(0x36)); - /* change TX Pre-emphasis Level Control for lanes */ - exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV0_EMP_LVL); - exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV1_EMP_LVL); - exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV2_EMP_LVL); - exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV3_EMP_LVL); + /* D0 uninit.. */ + exynos_pcie_phy_writel(ep->base, 0x44, PCIE_PHY_OFFSET(0x3D)); - /* set LVCC */ - exynos_pcie_phy_writel(ep->phy_base, 0x20, PCIE_PHY_TRSV0_LVCC); - exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV1_LVCC); - exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV2_LVCC); - exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV3_LVCC); + /* 24MHz */ + exynos_pcie_phy_writel(ep->base, 0x94, PCIE_PHY_OFFSET(0x8)); + exynos_pcie_phy_writel(ep->base, 0xA7, PCIE_PHY_OFFSET(0x9)); + exynos_pcie_phy_writel(ep->base, 0x93, PCIE_PHY_OFFSET(0xA)); + exynos_pcie_phy_writel(ep->base, 0x6B, PCIE_PHY_OFFSET(0xC)); + exynos_pcie_phy_writel(ep->base, 0xA5, PCIE_PHY_OFFSET(0xF)); + exynos_pcie_phy_writel(ep->base, 0x34, PCIE_PHY_OFFSET(0x16)); + exynos_pcie_phy_writel(ep->base, 0xA3, PCIE_PHY_OFFSET(0x17)); + exynos_pcie_phy_writel(ep->base, 0xA7, PCIE_PHY_OFFSET(0x1A)); + exynos_pcie_phy_writel(ep->base, 0x71, PCIE_PHY_OFFSET(0x23)); + exynos_pcie_phy_writel(ep->base, 0x4C, PCIE_PHY_OFFSET(0x24)); - /* pulse for common reset */ - exynos_pcie_phy_writel(ep->blk_base, 1, PCIE_PHY_COMMON_RESET); - udelay(500); - exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_COMMON_RESET); + exynos_pcie_phy_writel(ep->base, 0x0E, PCIE_PHY_OFFSET(0x26)); + exynos_pcie_phy_writel(ep->base, 0x14, PCIE_PHY_OFFSET(0x7)); + exynos_pcie_phy_writel(ep->base, 0x48, PCIE_PHY_OFFSET(0x43)); + exynos_pcie_phy_writel(ep->base, 0x44, PCIE_PHY_OFFSET(0x44)); + exynos_pcie_phy_writel(ep->base, 0x03, PCIE_PHY_OFFSET(0x45)); + exynos_pcie_phy_writel(ep->base, 0xA7, PCIE_PHY_OFFSET(0x48)); + exynos_pcie_phy_writel(ep->base, 0x13, PCIE_PHY_OFFSET(0x54)); + exynos_pcie_phy_writel(ep->base, 0x04, PCIE_PHY_OFFSET(0x31)); + exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x32)); + regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_COMMON_RESET, + PCIE_PHY_RESET, 0); + regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_MAC_RESET, + PCIE_MAC_RESET_MASK, PCIE_MAC_RESET); return 0; } -static int exynos5440_pcie_phy_power_on(struct phy *phy) -{ - struct exynos_pcie_phy *ep = phy_get_drvdata(phy); - u32 val; - - exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_COMMON_RESET); - exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_CMN_REG); - exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_TRSVREG_RESET); - exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_TRSV_RESET); - - val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_COMMON_POWER); - val &= ~PCIE_PHY_COMMON_PD_CMN; - exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_COMMON_POWER); - - val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV0_POWER); - val &= ~PCIE_PHY_TRSV0_PD_TSV; - exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV0_POWER); - - val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV1_POWER); - val &= ~PCIE_PHY_TRSV1_PD_TSV; - exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV1_POWER); - - val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV2_POWER); - val &= ~PCIE_PHY_TRSV2_PD_TSV; - exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV2_POWER); - - val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV3_POWER); - val &= ~PCIE_PHY_TRSV3_PD_TSV; - exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV3_POWER); - - return 0; -} - -static int exynos5440_pcie_phy_power_off(struct phy *phy) -{ - struct exynos_pcie_phy *ep = phy_get_drvdata(phy); - u32 val; - - if (readl_poll_timeout(ep->phy_base + PCIE_PHY_PLL_LOCKED, val, - (val != 0), 1, 500)) { - dev_err(&phy->dev, "PLL Locked: 0x%x\n", val); - return -ETIMEDOUT; - } - - val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_COMMON_POWER); - val |= PCIE_PHY_COMMON_PD_CMN; - exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_COMMON_POWER); - - val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV0_POWER); - val |= PCIE_PHY_TRSV0_PD_TSV; - exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV0_POWER); - - val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV1_POWER); - val |= PCIE_PHY_TRSV1_PD_TSV; - exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV1_POWER); - - val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV2_POWER); - val |= PCIE_PHY_TRSV2_PD_TSV; - exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV2_POWER); - - val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV3_POWER); - val |= PCIE_PHY_TRSV3_PD_TSV; - exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV3_POWER); - - return 0; -} - -static int exynos5440_pcie_phy_reset(struct phy *phy) +static int exynos5433_pcie_phy_power_on(struct phy *phy) { struct exynos_pcie_phy *ep = phy_get_drvdata(phy); - exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_MAC_RESET); - exynos_pcie_phy_writel(ep->blk_base, 1, PCIE_PHY_GLOBAL_RESET); - exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_GLOBAL_RESET); - + regmap_update_bits(ep->pmureg, EXYNOS5433_PMU_PCIE_PHY_OFFSET, + BIT(0), 1); + regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_GLOBAL_RESET, + PCIE_APP_REQ_EXIT_L1_MODE, 0); + regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_L1SUB_CM_CON, + PCIE_REFCLK_GATING_EN, 0); return 0; } -static const struct phy_ops exynos5440_phy_ops = { - .init = exynos5440_pcie_phy_init, - .power_on = exynos5440_pcie_phy_power_on, - .power_off = exynos5440_pcie_phy_power_off, - .reset = exynos5440_pcie_phy_reset, +static int exynos5433_pcie_phy_power_off(struct phy *phy) +{ + struct exynos_pcie_phy *ep = phy_get_drvdata(phy); + + regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_L1SUB_CM_CON, + PCIE_REFCLK_GATING_EN, PCIE_REFCLK_GATING_EN); + regmap_update_bits(ep->pmureg, EXYNOS5433_PMU_PCIE_PHY_OFFSET, + BIT(0), 0); + return 0; +} + +static const struct phy_ops exynos5433_phy_ops = { + .init = exynos5433_pcie_phy_init, + .power_on = exynos5433_pcie_phy_power_on, + .power_off = exynos5433_pcie_phy_power_off, .owner = THIS_MODULE, }; -static const struct exynos_pcie_phy_data exynos5440_pcie_phy_data = { - .ops = &exynos5440_phy_ops, -}; - static const struct of_device_id exynos_pcie_phy_match[] = { { - .compatible = "samsung,exynos5440-pcie-phy", - .data = &exynos5440_pcie_phy_data, + .compatible = "samsung,exynos5433-pcie-phy", }, {}, }; @@ -232,27 +153,30 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev) struct exynos_pcie_phy *exynos_phy; struct phy *generic_phy; struct phy_provider *phy_provider; - const struct exynos_pcie_phy_data *drv_data; - - drv_data = of_device_get_match_data(dev); - if (!drv_data) - return -ENODEV; exynos_phy = devm_kzalloc(dev, sizeof(*exynos_phy), GFP_KERNEL); if (!exynos_phy) return -ENOMEM; - exynos_phy->phy_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(exynos_phy->phy_base)) - return PTR_ERR(exynos_phy->phy_base); + exynos_phy->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(exynos_phy->base)) + return PTR_ERR(exynos_phy->base); - exynos_phy->blk_base = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(exynos_phy->blk_base)) - return PTR_ERR(exynos_phy->blk_base); + exynos_phy->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, + "samsung,pmu-syscon"); + if (IS_ERR(exynos_phy->pmureg)) { + dev_err(&pdev->dev, "PMU regmap lookup failed.\n"); + return PTR_ERR(exynos_phy->pmureg); + } - exynos_phy->drv_data = drv_data; + exynos_phy->fsysreg = syscon_regmap_lookup_by_phandle(dev->of_node, + "samsung,fsys-sysreg"); + if (IS_ERR(exynos_phy->fsysreg)) { + dev_err(&pdev->dev, "FSYS sysreg regmap lookup failed.\n"); + return PTR_ERR(exynos_phy->fsysreg); + } - generic_phy = devm_phy_create(dev, dev->of_node, drv_data->ops); + generic_phy = devm_phy_create(dev, dev->of_node, &exynos5433_phy_ops); if (IS_ERR(generic_phy)) { dev_err(dev, "failed to create PHY\n"); return PTR_ERR(generic_phy); @@ -272,5 +196,4 @@ static struct platform_driver exynos_pcie_phy_driver = { .suppress_bind_attrs = true, } }; - builtin_platform_driver(exynos_pcie_phy_driver); From 768a711e2d4b5e348962254a1c4f9fbfb6f13904 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 20 Nov 2020 16:04:01 +0530 Subject: [PATCH 43/72] phy: samsung: phy-exynos-pcie: fix typo 'tunning' Fix the typo s/tunning/tuning Fixes: 496db029142f ("phy: samsung: phy-exynos-pcie: rework driver to support Exynos5433 PCIe PHY") Signed-off-by: Vinod Koul --- drivers/phy/samsung/phy-exynos-pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/samsung/phy-exynos-pcie.c b/drivers/phy/samsung/phy-exynos-pcie.c index d91de323dd0e..578cfe07d07a 100644 --- a/drivers/phy/samsung/phy-exynos-pcie.c +++ b/drivers/phy/samsung/phy-exynos-pcie.c @@ -69,7 +69,7 @@ static int exynos5433_pcie_phy_init(struct phy *phy) exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x20)); exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x4b)); - /* jitter tunning */ + /* jitter tuning */ exynos_pcie_phy_writel(ep->base, 0x34, PCIE_PHY_OFFSET(0x4)); exynos_pcie_phy_writel(ep->base, 0x02, PCIE_PHY_OFFSET(0x7)); exynos_pcie_phy_writel(ep->base, 0x41, PCIE_PHY_OFFSET(0x21)); From 4086afa2a16279392e453605aac09728e60d9316 Mon Sep 17 00:00:00 2001 From: Wan Ahmad Zainie Date: Mon, 16 Nov 2020 20:08:30 +0800 Subject: [PATCH 44/72] dt-bindings: phy: Add Intel Keem Bay USB PHY bindings Binding description for Intel Keem Bay USB PHY. Signed-off-by: Wan Ahmad Zainie Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201116120831.32641-2-wan.ahmad.zainie.wan.mohamad@intel.com Signed-off-by: Vinod Koul --- .../bindings/phy/intel,phy-keembay-usb.yaml | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/intel,phy-keembay-usb.yaml diff --git a/Documentation/devicetree/bindings/phy/intel,phy-keembay-usb.yaml b/Documentation/devicetree/bindings/phy/intel,phy-keembay-usb.yaml new file mode 100644 index 000000000000..a217bb8ac5bc --- /dev/null +++ b/Documentation/devicetree/bindings/phy/intel,phy-keembay-usb.yaml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/intel,phy-keembay-usb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Intel Keem Bay USB PHY bindings + +maintainers: + - Wan Ahmad Zainie + +properties: + compatible: + const: intel,keembay-usb-phy + + reg: + items: + - description: USB APB CPR (clock, power, reset) register + - description: USB APB slave register + + reg-names: + items: + - const: cpr-apb-base + - const: slv-apb-base + + '#phy-cells': + const: 0 + +required: + - compatible + - reg + - '#phy-cells' + +additionalProperties: false + +examples: + - | + usb-phy@20400000 { + compatible = "intel,keembay-usb-phy"; + reg = <0x20400000 0x1c>, + <0x20480000 0xd0>; + reg-names = "cpr-apb-base", "slv-apb-base"; + #phy-cells = <0>; + }; From bf4d01e107e3fdc03104fa0db96d8d2721529eb6 Mon Sep 17 00:00:00 2001 From: Wan Ahmad Zainie Date: Mon, 16 Nov 2020 20:08:31 +0800 Subject: [PATCH 45/72] phy: intel: Add Keem Bay USB PHY support Add PHY driver for the USB3.1 and USB 2.0 PHYs found on Intel Keem Bay SoC. This driver takes care of enabling the required USB susbsystem (USS) clocks, initializing the PHYs and turning on/off the USB dwc3 core. Signed-off-by: Wan Ahmad Zainie Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20201116120831.32641-3-wan.ahmad.zainie.wan.mohamad@intel.com Signed-off-by: Vinod Koul --- drivers/phy/intel/Kconfig | 12 + drivers/phy/intel/Makefile | 1 + drivers/phy/intel/phy-intel-keembay-usb.c | 301 ++++++++++++++++++++++ 3 files changed, 314 insertions(+) create mode 100644 drivers/phy/intel/phy-intel-keembay-usb.c diff --git a/drivers/phy/intel/Kconfig b/drivers/phy/intel/Kconfig index 58ec695c92ec..f72c699a3e02 100644 --- a/drivers/phy/intel/Kconfig +++ b/drivers/phy/intel/Kconfig @@ -14,6 +14,18 @@ config PHY_INTEL_KEEMBAY_EMMC To compile this driver as a module, choose M here: the module will be called phy-keembay-emmc.ko. +config PHY_INTEL_KEEMBAY_USB + tristate "Intel Keem Bay USB PHY driver" + depends on ARCH_KEEMBAY || COMPILE_TEST + depends on HAS_IOMEM + select GENERIC_PHY + select REGMAP_MMIO + help + Choose this option if you have an Intel Keem Bay SoC. + + To compile this driver as a module, choose M here: the module + will be called phy-keembay-usb.ko. + config PHY_INTEL_LGM_COMBO bool "Intel Lightning Mountain ComboPHY driver" depends on X86 || COMPILE_TEST diff --git a/drivers/phy/intel/Makefile b/drivers/phy/intel/Makefile index a5e0af5ccd75..14550981a707 100644 --- a/drivers/phy/intel/Makefile +++ b/drivers/phy/intel/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PHY_INTEL_KEEMBAY_EMMC) += phy-intel-keembay-emmc.o +obj-$(CONFIG_PHY_INTEL_KEEMBAY_USB) += phy-intel-keembay-usb.o obj-$(CONFIG_PHY_INTEL_LGM_COMBO) += phy-intel-lgm-combo.o obj-$(CONFIG_PHY_INTEL_LGM_EMMC) += phy-intel-lgm-emmc.o diff --git a/drivers/phy/intel/phy-intel-keembay-usb.c b/drivers/phy/intel/phy-intel-keembay-usb.c new file mode 100644 index 000000000000..c8b05f7b2445 --- /dev/null +++ b/drivers/phy/intel/phy-intel-keembay-usb.c @@ -0,0 +1,301 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Intel Keem Bay USB PHY driver + * Copyright (C) 2020 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* USS (USB Subsystem) clock control registers */ +#define USS_CPR_CLK_EN 0x00 +#define USS_CPR_CLK_SET 0x04 +#define USS_CPR_CLK_CLR 0x08 +#define USS_CPR_RST_EN 0x10 +#define USS_CPR_RST_SET 0x14 +#define USS_CPR_RST_CLR 0x18 + +/* USS clock/reset bit fields */ +#define USS_CPR_PHY_TST BIT(6) +#define USS_CPR_LOW_JIT BIT(5) +#define USS_CPR_CORE BIT(4) +#define USS_CPR_SUSPEND BIT(3) +#define USS_CPR_ALT_REF BIT(2) +#define USS_CPR_REF BIT(1) +#define USS_CPR_SYS BIT(0) +#define USS_CPR_MASK GENMASK(6, 0) + +/* USS APB slave registers */ +#define USS_USB_CTRL_CFG0 0x10 +#define VCC_RESET_N_MASK BIT(31) + +#define USS_USB_PHY_CFG0 0x30 +#define POR_MASK BIT(15) +#define PHY_RESET_MASK BIT(14) +#define PHY_REF_USE_PAD_MASK BIT(5) + +#define USS_USB_PHY_CFG6 0x64 +#define PHY0_SRAM_EXT_LD_DONE_MASK BIT(23) + +#define USS_USB_PARALLEL_IF_CTRL 0xa0 +#define USB_PHY_CR_PARA_SEL_MASK BIT(2) + +#define USS_USB_TSET_SIGNALS_AND_GLOB 0xac +#define USB_PHY_CR_PARA_CLK_EN_MASK BIT(7) + +#define USS_USB_STATUS_REG 0xb8 +#define PHY0_SRAM_INIT_DONE_MASK BIT(3) + +#define USS_USB_TIEOFFS_CONSTANTS_REG1 0xc0 +#define IDDQ_ENABLE_MASK BIT(10) + +struct keembay_usb_phy { + struct device *dev; + struct regmap *regmap_cpr; + struct regmap *regmap_slv; +}; + +static const struct regmap_config keembay_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = USS_USB_TIEOFFS_CONSTANTS_REG1, +}; + +static int keembay_usb_clocks_on(struct keembay_usb_phy *priv) +{ + int ret; + + ret = regmap_update_bits(priv->regmap_cpr, USS_CPR_CLK_SET, + USS_CPR_MASK, USS_CPR_MASK); + if (ret) { + dev_err(priv->dev, "error clock set: %d\n", ret); + return ret; + } + + ret = regmap_update_bits(priv->regmap_cpr, USS_CPR_RST_SET, + USS_CPR_MASK, USS_CPR_MASK); + if (ret) { + dev_err(priv->dev, "error reset set: %d\n", ret); + return ret; + } + + ret = regmap_update_bits(priv->regmap_slv, + USS_USB_TIEOFFS_CONSTANTS_REG1, + IDDQ_ENABLE_MASK, + FIELD_PREP(IDDQ_ENABLE_MASK, 0)); + if (ret) { + dev_err(priv->dev, "error iddq disable: %d\n", ret); + return ret; + } + + /* Wait 30us to ensure all analog blocks are powered up. */ + usleep_range(30, 60); + + ret = regmap_update_bits(priv->regmap_slv, USS_USB_PHY_CFG0, + PHY_REF_USE_PAD_MASK, + FIELD_PREP(PHY_REF_USE_PAD_MASK, 1)); + if (ret) + dev_err(priv->dev, "error ref clock select: %d\n", ret); + + return ret; +} + +static int keembay_usb_core_off(struct keembay_usb_phy *priv) +{ + int ret; + + ret = regmap_update_bits(priv->regmap_slv, USS_USB_CTRL_CFG0, + VCC_RESET_N_MASK, + FIELD_PREP(VCC_RESET_N_MASK, 0)); + if (ret) + dev_err(priv->dev, "error core reset: %d\n", ret); + + return ret; +} + +static int keembay_usb_core_on(struct keembay_usb_phy *priv) +{ + int ret; + + ret = regmap_update_bits(priv->regmap_slv, USS_USB_CTRL_CFG0, + VCC_RESET_N_MASK, + FIELD_PREP(VCC_RESET_N_MASK, 1)); + if (ret) + dev_err(priv->dev, "error core on: %d\n", ret); + + return ret; +} + +static int keembay_usb_phys_on(struct keembay_usb_phy *priv) +{ + int ret; + + ret = regmap_update_bits(priv->regmap_slv, USS_USB_PHY_CFG0, + POR_MASK | PHY_RESET_MASK, + FIELD_PREP(POR_MASK | PHY_RESET_MASK, 0)); + if (ret) + dev_err(priv->dev, "error phys on: %d\n", ret); + + return ret; +} + +static int keembay_usb_phy_init(struct phy *phy) +{ + struct keembay_usb_phy *priv = phy_get_drvdata(phy); + u32 val; + int ret; + + ret = keembay_usb_core_off(priv); + if (ret) + return ret; + + /* + * According to Keem Bay datasheet, wait minimum 20us after clock + * enable before bringing PHYs out of reset. + */ + usleep_range(20, 40); + + ret = keembay_usb_phys_on(priv); + if (ret) + return ret; + + ret = regmap_update_bits(priv->regmap_slv, + USS_USB_TSET_SIGNALS_AND_GLOB, + USB_PHY_CR_PARA_CLK_EN_MASK, + FIELD_PREP(USB_PHY_CR_PARA_CLK_EN_MASK, 0)); + if (ret) { + dev_err(priv->dev, "error cr clock disable: %d\n", ret); + return ret; + } + + /* + * According to Keem Bay datasheet, wait 2us after disabling the + * clock into the USB 3.x parallel interface. + */ + udelay(2); + + ret = regmap_update_bits(priv->regmap_slv, + USS_USB_PARALLEL_IF_CTRL, + USB_PHY_CR_PARA_SEL_MASK, + FIELD_PREP(USB_PHY_CR_PARA_SEL_MASK, 1)); + if (ret) { + dev_err(priv->dev, "error cr select: %d\n", ret); + return ret; + } + + ret = regmap_update_bits(priv->regmap_slv, + USS_USB_TSET_SIGNALS_AND_GLOB, + USB_PHY_CR_PARA_CLK_EN_MASK, + FIELD_PREP(USB_PHY_CR_PARA_CLK_EN_MASK, 1)); + if (ret) { + dev_err(priv->dev, "error cr clock enable: %d\n", ret); + return ret; + } + + ret = regmap_read_poll_timeout(priv->regmap_slv, USS_USB_STATUS_REG, + val, val & PHY0_SRAM_INIT_DONE_MASK, + USEC_PER_MSEC, 10 * USEC_PER_MSEC); + if (ret) { + dev_err(priv->dev, "SRAM init not done: %d\n", ret); + return ret; + } + + ret = regmap_update_bits(priv->regmap_slv, USS_USB_PHY_CFG6, + PHY0_SRAM_EXT_LD_DONE_MASK, + FIELD_PREP(PHY0_SRAM_EXT_LD_DONE_MASK, 1)); + if (ret) { + dev_err(priv->dev, "error SRAM init done set: %d\n", ret); + return ret; + } + + /* + * According to Keem Bay datasheet, wait 20us after setting the + * SRAM load done bit, before releasing the controller reset. + */ + usleep_range(20, 40); + + return keembay_usb_core_on(priv); +} + +static const struct phy_ops ops = { + .init = keembay_usb_phy_init, + .owner = THIS_MODULE, +}; + +static int keembay_usb_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct keembay_usb_phy *priv; + struct phy *generic_phy; + struct phy_provider *phy_provider; + void __iomem *base; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + base = devm_platform_ioremap_resource_byname(pdev, "cpr-apb-base"); + if (IS_ERR(base)) + return PTR_ERR(base); + + priv->regmap_cpr = devm_regmap_init_mmio(dev, base, + &keembay_regmap_config); + if (IS_ERR(priv->regmap_cpr)) + return PTR_ERR(priv->regmap_cpr); + + base = devm_platform_ioremap_resource_byname(pdev, "slv-apb-base"); + if (IS_ERR(base)) + return PTR_ERR(base); + + priv->regmap_slv = devm_regmap_init_mmio(dev, base, + &keembay_regmap_config); + if (IS_ERR(priv->regmap_slv)) + return PTR_ERR(priv->regmap_slv); + + generic_phy = devm_phy_create(dev, dev->of_node, &ops); + if (IS_ERR(generic_phy)) + return dev_err_probe(dev, PTR_ERR(generic_phy), + "failed to create PHY\n"); + + phy_set_drvdata(generic_phy, priv); + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (IS_ERR(phy_provider)) + return dev_err_probe(dev, PTR_ERR(phy_provider), + "failed to register phy provider\n"); + + /* Setup USB subsystem clocks */ + ret = keembay_usb_clocks_on(priv); + if (ret) + return ret; + + /* and turn on the DWC3 core, prior to DWC3 driver init. */ + return keembay_usb_core_on(priv); +} + +static const struct of_device_id keembay_usb_phy_dt_ids[] = { + { .compatible = "intel,keembay-usb-phy" }, + {} +}; +MODULE_DEVICE_TABLE(of, keembay_usb_phy_dt_ids); + +static struct platform_driver keembay_usb_phy_driver = { + .probe = keembay_usb_phy_probe, + .driver = { + .name = "keembay-usb-phy", + .of_match_table = keembay_usb_phy_dt_ids, + }, +}; +module_platform_driver(keembay_usb_phy_driver); + +MODULE_AUTHOR("Wan Ahmad Zainie "); +MODULE_DESCRIPTION("Intel Keem Bay USB PHY driver"); +MODULE_LICENSE("GPL v2"); From 27076a7358b5e170b7cba80b43b4e49ac3e279fc Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Sat, 21 Nov 2020 16:50:34 +0100 Subject: [PATCH 46/72] dt-bindings: phy: Add binding for Mediatek MT7621 PCIe PHY Add bindings to describe Mediatek MT7621 PCIe PHY. Signed-off-by: Sergio Paracuellos Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20201121155037.21354-2-sergio.paracuellos@gmail.com Signed-off-by: Vinod Koul --- .../bindings/phy/mediatek,mt7621-pci-phy.yaml | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/mediatek,mt7621-pci-phy.yaml diff --git a/Documentation/devicetree/bindings/phy/mediatek,mt7621-pci-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,mt7621-pci-phy.yaml new file mode 100644 index 000000000000..0ccaded3f245 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/mediatek,mt7621-pci-phy.yaml @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/phy/mediatek,mt7621-pci-phy.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Mediatek Mt7621 PCIe PHY Device Tree Bindings + +maintainers: + - Sergio Paracuellos + +properties: + compatible: + const: mediatek,mt7621-pci-phy + + reg: + maxItems: 1 + + "#phy-cells": + const: 1 + description: selects if the phy is dual-ported + +required: + - compatible + - reg + - "#phy-cells" + +additionalProperties: false + +examples: + - | + pcie0_phy: pcie-phy@1e149000 { + compatible = "mediatek,mt7621-pci-phy"; + reg = <0x1e149000 0x0700>; + #phy-cells = <1>; + }; From d87da32372a03ce121fc65ccd2c9a43edf56b364 Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Sat, 21 Nov 2020 16:50:35 +0100 Subject: [PATCH 47/72] phy: ralink: Add PHY driver for MT7621 PCIe PHY This patch adds a driver for the PCIe PHY of MT7621 SoC. Signed-off-by: Sergio Paracuellos Link: https://lore.kernel.org/r/20201121155037.21354-3-sergio.paracuellos@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/ralink/Kconfig | 8 + drivers/phy/ralink/Makefile | 1 + drivers/phy/ralink/phy-mt7621-pci.c | 352 ++++++++++++++++++++++++++++ 3 files changed, 361 insertions(+) create mode 100644 drivers/phy/ralink/phy-mt7621-pci.c diff --git a/drivers/phy/ralink/Kconfig b/drivers/phy/ralink/Kconfig index da982c9cffb3..2fabb14d2998 100644 --- a/drivers/phy/ralink/Kconfig +++ b/drivers/phy/ralink/Kconfig @@ -2,6 +2,14 @@ # # PHY drivers for Ralink platforms. # +config PHY_MT7621_PCI + tristate "MediaTek MT7621 PCI PHY Driver" + depends on (RALINK || COMPILE_TEST) && OF + select GENERIC_PHY + select REGMAP_MMIO + help + Say 'Y' here to add support for MediaTek MT7621 PCI PHY driver, + config PHY_RALINK_USB tristate "Ralink USB PHY driver" depends on RALINK || COMPILE_TEST diff --git a/drivers/phy/ralink/Makefile b/drivers/phy/ralink/Makefile index d8d3ffcf0a15..cda2a4a7ca5e 100644 --- a/drivers/phy/ralink/Makefile +++ b/drivers/phy/ralink/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_PHY_MT7621_PCI) += phy-mt7621-pci.o obj-$(CONFIG_PHY_RALINK_USB) += phy-ralink-usb.o diff --git a/drivers/phy/ralink/phy-mt7621-pci.c b/drivers/phy/ralink/phy-mt7621-pci.c new file mode 100644 index 000000000000..db79088d5362 --- /dev/null +++ b/drivers/phy/ralink/phy-mt7621-pci.c @@ -0,0 +1,352 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Mediatek MT7621 PCI PHY Driver + * Author: Sergio Paracuellos + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RG_PE1_PIPE_REG 0x02c +#define RG_PE1_PIPE_RST BIT(12) +#define RG_PE1_PIPE_CMD_FRC BIT(4) + +#define RG_P0_TO_P1_WIDTH 0x100 +#define RG_PE1_H_LCDDS_REG 0x49c +#define RG_PE1_H_LCDDS_PCW GENMASK(30, 0) + +#define RG_PE1_FRC_H_XTAL_REG 0x400 +#define RG_PE1_FRC_H_XTAL_TYPE BIT(8) +#define RG_PE1_H_XTAL_TYPE GENMASK(10, 9) + +#define RG_PE1_FRC_PHY_REG 0x000 +#define RG_PE1_FRC_PHY_EN BIT(4) +#define RG_PE1_PHY_EN BIT(5) + +#define RG_PE1_H_PLL_REG 0x490 +#define RG_PE1_H_PLL_BC GENMASK(23, 22) +#define RG_PE1_H_PLL_BP GENMASK(21, 18) +#define RG_PE1_H_PLL_IR GENMASK(15, 12) +#define RG_PE1_H_PLL_IC GENMASK(11, 8) +#define RG_PE1_H_PLL_PREDIV GENMASK(7, 6) +#define RG_PE1_PLL_DIVEN GENMASK(3, 1) + +#define RG_PE1_H_PLL_FBKSEL_REG 0x4bc +#define RG_PE1_H_PLL_FBKSEL GENMASK(5, 4) + +#define RG_PE1_H_LCDDS_SSC_PRD_REG 0x4a4 +#define RG_PE1_H_LCDDS_SSC_PRD GENMASK(15, 0) + +#define RG_PE1_H_LCDDS_SSC_DELTA_REG 0x4a8 +#define RG_PE1_H_LCDDS_SSC_DELTA GENMASK(11, 0) +#define RG_PE1_H_LCDDS_SSC_DELTA1 GENMASK(27, 16) + +#define RG_PE1_LCDDS_CLK_PH_INV_REG 0x4a0 +#define RG_PE1_LCDDS_CLK_PH_INV BIT(5) + +#define RG_PE1_H_PLL_BR_REG 0x4ac +#define RG_PE1_H_PLL_BR GENMASK(18, 16) + +#define RG_PE1_MSTCKDIV_REG 0x414 +#define RG_PE1_MSTCKDIV GENMASK(7, 6) + +#define RG_PE1_FRC_MSTCKDIV BIT(5) + +#define XTAL_MASK GENMASK(7, 6) + +#define MAX_PHYS 2 + +/** + * struct mt7621_pci_phy - Mt7621 Pcie PHY core + * @dev: pointer to device + * @regmap: kernel regmap pointer + * @phy: pointer to the kernel PHY device + * @port_base: base register + * @has_dual_port: if the phy has dual ports. + * @bypass_pipe_rst: mark if 'mt7621_bypass_pipe_rst' + * needs to be executed. Depends on chip revision. + */ +struct mt7621_pci_phy { + struct device *dev; + struct regmap *regmap; + struct phy *phy; + void __iomem *port_base; + bool has_dual_port; + bool bypass_pipe_rst; +}; + +static inline void mt7621_phy_rmw(struct mt7621_pci_phy *phy, + u32 reg, u32 clr, u32 set) +{ + u32 val; + + /* + * We cannot use 'regmap_write_bits' here because internally + * 'set' is masked before is set to the value that will be + * written to the register. That way results in no reliable + * pci setup. Avoid to mask 'set' before set value to 'val' + * completely avoid the problem. + */ + regmap_read(phy->regmap, reg, &val); + val &= ~clr; + val |= set; + regmap_write(phy->regmap, reg, val); +} + +static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy) +{ + mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_RST); + mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_CMD_FRC); + + if (phy->has_dual_port) { + mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH, + 0, RG_PE1_PIPE_RST); + mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH, + 0, RG_PE1_PIPE_CMD_FRC); + } +} + +static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy) +{ + struct device *dev = phy->dev; + u32 xtal_mode; + + xtal_mode = FIELD_GET(XTAL_MASK, rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0)); + + /* Set PCIe Port PHY to disable SSC */ + /* Debug Xtal Type */ + mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG, + RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE, + RG_PE1_FRC_H_XTAL_TYPE | + FIELD_PREP(RG_PE1_H_XTAL_TYPE, 0x00)); + + /* disable port */ + mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG, RG_PE1_PHY_EN, + RG_PE1_FRC_PHY_EN); + + if (phy->has_dual_port) { + mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, + RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); + } + + if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */ + /* Set Pre-divider ratio (for host mode) */ + mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, RG_PE1_H_PLL_PREDIV, + FIELD_PREP(RG_PE1_H_PLL_PREDIV, 0x01)); + + dev_dbg(dev, "Xtal is 40MHz\n"); + } else if (xtal_mode >= 6) { /* 25MHz Xal */ + mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, RG_PE1_H_PLL_PREDIV, + FIELD_PREP(RG_PE1_H_PLL_PREDIV, 0x00)); + + /* Select feedback clock */ + mt7621_phy_rmw(phy, RG_PE1_H_PLL_FBKSEL_REG, + RG_PE1_H_PLL_FBKSEL, + FIELD_PREP(RG_PE1_H_PLL_FBKSEL, 0x01)); + + /* DDS NCPO PCW (for host mode) */ + mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG, + RG_PE1_H_LCDDS_SSC_PRD, + FIELD_PREP(RG_PE1_H_LCDDS_SSC_PRD, 0x00)); + + /* DDS SSC dither period control */ + mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG, + RG_PE1_H_LCDDS_SSC_PRD, + FIELD_PREP(RG_PE1_H_LCDDS_SSC_PRD, 0x18d)); + + /* DDS SSC dither amplitude control */ + mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG, + RG_PE1_H_LCDDS_SSC_DELTA | + RG_PE1_H_LCDDS_SSC_DELTA1, + FIELD_PREP(RG_PE1_H_LCDDS_SSC_DELTA, 0x4a) | + FIELD_PREP(RG_PE1_H_LCDDS_SSC_DELTA1, 0x4a)); + + dev_dbg(dev, "Xtal is 25MHz\n"); + } else { /* 20MHz Xtal */ + mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, RG_PE1_H_PLL_PREDIV, + FIELD_PREP(RG_PE1_H_PLL_PREDIV, 0x00)); + + dev_dbg(dev, "Xtal is 20MHz\n"); + } + + /* DDS clock inversion */ + mt7621_phy_rmw(phy, RG_PE1_LCDDS_CLK_PH_INV_REG, + RG_PE1_LCDDS_CLK_PH_INV, RG_PE1_LCDDS_CLK_PH_INV); + + /* Set PLL bits */ + mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, + RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR | + RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN, + FIELD_PREP(RG_PE1_H_PLL_BC, 0x02) | + FIELD_PREP(RG_PE1_H_PLL_BP, 0x06) | + FIELD_PREP(RG_PE1_H_PLL_IR, 0x02) | + FIELD_PREP(RG_PE1_H_PLL_IC, 0x01) | + FIELD_PREP(RG_PE1_PLL_DIVEN, 0x02)); + + mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG, RG_PE1_H_PLL_BR, + FIELD_PREP(RG_PE1_H_PLL_BR, 0x00)); + + if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */ + /* set force mode enable of da_pe1_mstckdiv */ + mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG, + RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV, + FIELD_PREP(RG_PE1_MSTCKDIV, 0x01) | + RG_PE1_FRC_MSTCKDIV); + } +} + +static int mt7621_pci_phy_init(struct phy *phy) +{ + struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); + + if (mphy->bypass_pipe_rst) + mt7621_bypass_pipe_rst(mphy); + + mt7621_set_phy_for_ssc(mphy); + + return 0; +} + +static int mt7621_pci_phy_power_on(struct phy *phy) +{ + struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); + + /* Enable PHY and disable force mode */ + mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG, + RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN); + + if (mphy->has_dual_port) { + mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, + RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN); + } + + return 0; +} + +static int mt7621_pci_phy_power_off(struct phy *phy) +{ + struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); + + /* Disable PHY */ + mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG, + RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); + + if (mphy->has_dual_port) { + mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, + RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); + } + + return 0; +} + +static int mt7621_pci_phy_exit(struct phy *phy) +{ + return 0; +} + +static const struct phy_ops mt7621_pci_phy_ops = { + .init = mt7621_pci_phy_init, + .exit = mt7621_pci_phy_exit, + .power_on = mt7621_pci_phy_power_on, + .power_off = mt7621_pci_phy_power_off, + .owner = THIS_MODULE, +}; + +static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev, + struct of_phandle_args *args) +{ + struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev); + + if (WARN_ON(args->args[0] >= MAX_PHYS)) + return ERR_PTR(-ENODEV); + + mt7621_phy->has_dual_port = args->args[0]; + + dev_info(dev, "PHY for 0x%08x (dual port = %d)\n", + (unsigned int)mt7621_phy->port_base, mt7621_phy->has_dual_port); + + return mt7621_phy->phy; +} + +static const struct soc_device_attribute mt7621_pci_quirks_match[] = { + { .soc_id = "mt7621", .revision = "E2" } +}; + +static const struct regmap_config mt7621_pci_phy_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x700, +}; + +static int mt7621_pci_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct soc_device_attribute *attr; + struct phy_provider *provider; + struct mt7621_pci_phy *phy; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + attr = soc_device_match(mt7621_pci_quirks_match); + if (attr) + phy->bypass_pipe_rst = true; + + phy->dev = dev; + platform_set_drvdata(pdev, phy); + + phy->port_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(phy->port_base)) { + dev_err(dev, "failed to remap phy regs\n"); + return PTR_ERR(phy->port_base); + } + + phy->regmap = devm_regmap_init_mmio(phy->dev, phy->port_base, + &mt7621_pci_phy_regmap_config); + if (IS_ERR(phy->regmap)) + return PTR_ERR(phy->regmap); + + phy->phy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops); + if (IS_ERR(phy)) { + dev_err(dev, "failed to create phy\n"); + return PTR_ERR(phy); + } + + phy_set_drvdata(phy->phy, phy); + + provider = devm_of_phy_provider_register(dev, mt7621_pcie_phy_of_xlate); + + return PTR_ERR_OR_ZERO(provider); +} + +static const struct of_device_id mt7621_pci_phy_ids[] = { + { .compatible = "mediatek,mt7621-pci-phy" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mt7621_pci_ids); + +static struct platform_driver mt7621_pci_phy_driver = { + .probe = mt7621_pci_phy_probe, + .driver = { + .name = "mt7621-pci-phy", + .of_match_table = of_match_ptr(mt7621_pci_phy_ids), + }, +}; + +builtin_platform_driver(mt7621_pci_phy_driver); + +MODULE_AUTHOR("Sergio Paracuellos "); +MODULE_DESCRIPTION("MediaTek MT7621 PCIe PHY driver"); +MODULE_LICENSE("GPL v2"); From 370c10afc14c79ff08406f99a95de7123178af48 Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Sat, 21 Nov 2020 16:50:36 +0100 Subject: [PATCH 48/72] MAINTAINERS: add MT7621 PHY PCI maintainer Adding myself as maintainer for mt7621 pci phy driver. Signed-off-by: Sergio Paracuellos Link: https://lore.kernel.org/r/20201121155037.21354-4-sergio.paracuellos@gmail.com Signed-off-by: Vinod Koul --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index f01ce8f451c8..c07967b9a654 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11108,6 +11108,12 @@ S: Maintained F: Documentation/devicetree/bindings/i2c/i2c-mt7621.txt F: drivers/i2c/busses/i2c-mt7621.c +MEDIATEK MT7621 PHY PCI DRIVER +M: Sergio Paracuellos +S: Maintained +F: Documentation/devicetree/bindings/phy/mediatek,mt7621-pci-phy.yaml +F: drivers/phy/ralink/phy-mt7621-pci.c + MEDIATEK NAND CONTROLLER DRIVER L: linux-mtd@lists.infradead.org S: Orphan From 53e7c92c7fa0077f507951206bb329aadab785fb Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Sat, 21 Nov 2020 16:50:37 +0100 Subject: [PATCH 49/72] staging: mt7621-pci-phy: remove driver from staging Remove this driver from staging because it has been moved into its properly place in the kernel. Signed-off-by: Sergio Paracuellos Acked-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20201121155037.21354-5-sergio.paracuellos@gmail.com Signed-off-by: Vinod Koul --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/mt7621-pci-phy/Kconfig | 8 - drivers/staging/mt7621-pci-phy/Makefile | 2 - drivers/staging/mt7621-pci-phy/TODO | 4 - .../mediatek,mt7621-pci-phy.yaml | 36 -- .../staging/mt7621-pci-phy/pci-mt7621-phy.c | 373 ------------------ 7 files changed, 426 deletions(-) delete mode 100644 drivers/staging/mt7621-pci-phy/Kconfig delete mode 100644 drivers/staging/mt7621-pci-phy/Makefile delete mode 100644 drivers/staging/mt7621-pci-phy/TODO delete mode 100644 drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.yaml delete mode 100644 drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 2d0310448eba..8a03ba56def5 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -94,8 +94,6 @@ source "drivers/staging/pi433/Kconfig" source "drivers/staging/mt7621-pci/Kconfig" -source "drivers/staging/mt7621-pci-phy/Kconfig" - source "drivers/staging/mt7621-pinctrl/Kconfig" source "drivers/staging/mt7621-dma/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 757a892ab5b9..39319161301c 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -37,7 +37,6 @@ obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ obj-$(CONFIG_PI433) += pi433/ obj-$(CONFIG_PCI_MT7621) += mt7621-pci/ -obj-$(CONFIG_PCI_MT7621_PHY) += mt7621-pci-phy/ obj-$(CONFIG_PINCTRL_RT2880) += mt7621-pinctrl/ obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ obj-$(CONFIG_DMA_RALINK) += ralink-gdma/ diff --git a/drivers/staging/mt7621-pci-phy/Kconfig b/drivers/staging/mt7621-pci-phy/Kconfig deleted file mode 100644 index 263e0a91c424..000000000000 --- a/drivers/staging/mt7621-pci-phy/Kconfig +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config PCI_MT7621_PHY - tristate "MediaTek MT7621 PCI PHY Driver" - depends on RALINK && OF - select GENERIC_PHY - help - Say 'Y' here to add support for MediaTek MT7621 PCI PHY driver, - diff --git a/drivers/staging/mt7621-pci-phy/Makefile b/drivers/staging/mt7621-pci-phy/Makefile deleted file mode 100644 index b4d99b9119e0..000000000000 --- a/drivers/staging/mt7621-pci-phy/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_PCI_MT7621_PHY) += pci-mt7621-phy.o diff --git a/drivers/staging/mt7621-pci-phy/TODO b/drivers/staging/mt7621-pci-phy/TODO deleted file mode 100644 index a255e8f753eb..000000000000 --- a/drivers/staging/mt7621-pci-phy/TODO +++ /dev/null @@ -1,4 +0,0 @@ - -- general code review and cleanup - -Cc: NeilBrown and Sergio Paracuellos diff --git a/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.yaml b/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.yaml deleted file mode 100644 index cf32bbc45b5d..000000000000 --- a/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.yaml +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -%YAML 1.2 ---- -$id: "http://devicetree.org/schemas/phy/mediatek,mt7621-pci-phy.yaml#" -$schema: "http://devicetree.org/meta-schemas/core.yaml#" - -title: Mediatek Mt7621 PCIe PHY Device Tree Bindings - -maintainers: - - Sergio Paracuellos - -properties: - compatible: - const: mediatek,mt7621-pci-phy - - reg: - maxItems: 1 - - "#phy-cells": - const: 1 - description: selects if the phy is dual-ported - -required: - - compatible - - reg - - "#phy-cells" - -additionalProperties: false - -examples: - - | - pcie0_phy: pcie-phy@1e149000 { - compatible = "mediatek,mt7621-pci-phy"; - reg = <0x1e149000 0x0700>; - #phy-cells = <1>; - }; diff --git a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c deleted file mode 100644 index 57743fd22be4..000000000000 --- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c +++ /dev/null @@ -1,373 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Mediatek MT7621 PCI PHY Driver - * Author: Sergio Paracuellos - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define RG_PE1_PIPE_REG 0x02c -#define RG_PE1_PIPE_RST BIT(12) -#define RG_PE1_PIPE_CMD_FRC BIT(4) - -#define RG_P0_TO_P1_WIDTH 0x100 -#define RG_PE1_H_LCDDS_REG 0x49c -#define RG_PE1_H_LCDDS_PCW GENMASK(30, 0) -#define RG_PE1_H_LCDDS_PCW_VAL(x) ((0x7fffffff & (x)) << 0) - -#define RG_PE1_FRC_H_XTAL_REG 0x400 -#define RG_PE1_FRC_H_XTAL_TYPE BIT(8) -#define RG_PE1_H_XTAL_TYPE GENMASK(10, 9) -#define RG_PE1_H_XTAL_TYPE_VAL(x) ((0x3 & (x)) << 9) - -#define RG_PE1_FRC_PHY_REG 0x000 -#define RG_PE1_FRC_PHY_EN BIT(4) -#define RG_PE1_PHY_EN BIT(5) - -#define RG_PE1_H_PLL_REG 0x490 -#define RG_PE1_H_PLL_BC GENMASK(23, 22) -#define RG_PE1_H_PLL_BC_VAL(x) ((0x3 & (x)) << 22) -#define RG_PE1_H_PLL_BP GENMASK(21, 18) -#define RG_PE1_H_PLL_BP_VAL(x) ((0xf & (x)) << 18) -#define RG_PE1_H_PLL_IR GENMASK(15, 12) -#define RG_PE1_H_PLL_IR_VAL(x) ((0xf & (x)) << 12) -#define RG_PE1_H_PLL_IC GENMASK(11, 8) -#define RG_PE1_H_PLL_IC_VAL(x) ((0xf & (x)) << 8) -#define RG_PE1_H_PLL_PREDIV GENMASK(7, 6) -#define RG_PE1_H_PLL_PREDIV_VAL(x) ((0x3 & (x)) << 6) -#define RG_PE1_PLL_DIVEN GENMASK(3, 1) -#define RG_PE1_PLL_DIVEN_VAL(x) ((0x7 & (x)) << 1) - -#define RG_PE1_H_PLL_FBKSEL_REG 0x4bc -#define RG_PE1_H_PLL_FBKSEL GENMASK(5, 4) -#define RG_PE1_H_PLL_FBKSEL_VAL(x) ((0x3 & (x)) << 4) - -#define RG_PE1_H_LCDDS_SSC_PRD_REG 0x4a4 -#define RG_PE1_H_LCDDS_SSC_PRD GENMASK(15, 0) -#define RG_PE1_H_LCDDS_SSC_PRD_VAL(x) ((0xffff & (x)) << 0) - -#define RG_PE1_H_LCDDS_SSC_DELTA_REG 0x4a8 -#define RG_PE1_H_LCDDS_SSC_DELTA GENMASK(11, 0) -#define RG_PE1_H_LCDDS_SSC_DELTA_VAL(x) ((0xfff & (x)) << 0) -#define RG_PE1_H_LCDDS_SSC_DELTA1 GENMASK(27, 16) -#define RG_PE1_H_LCDDS_SSC_DELTA1_VAL(x) ((0xff & (x)) << 16) - -#define RG_PE1_LCDDS_CLK_PH_INV_REG 0x4a0 -#define RG_PE1_LCDDS_CLK_PH_INV BIT(5) - -#define RG_PE1_H_PLL_BR_REG 0x4ac -#define RG_PE1_H_PLL_BR GENMASK(18, 16) -#define RG_PE1_H_PLL_BR_VAL(x) ((0x7 & (x)) << 16) - -#define RG_PE1_MSTCKDIV_REG 0x414 -#define RG_PE1_MSTCKDIV GENMASK(7, 6) -#define RG_PE1_MSTCKDIV_VAL(x) ((0x3 & (x)) << 6) - -#define RG_PE1_FRC_MSTCKDIV BIT(5) - -#define XTAL_MODE_SEL_SHIFT 6 -#define XTAL_MODE_SEL_MASK 0x7 - -#define MAX_PHYS 2 - -/** - * struct mt7621_pci_phy - Mt7621 Pcie PHY core - * @dev: pointer to device - * @regmap: kernel regmap pointer - * @phy: pointer to the kernel PHY device - * @port_base: base register - * @has_dual_port: if the phy has dual ports. - * @bypass_pipe_rst: mark if 'mt7621_bypass_pipe_rst' - * needs to be executed. Depends on chip revision. - */ -struct mt7621_pci_phy { - struct device *dev; - struct regmap *regmap; - struct phy *phy; - void __iomem *port_base; - bool has_dual_port; - bool bypass_pipe_rst; -}; - -static inline u32 phy_read(struct mt7621_pci_phy *phy, u32 reg) -{ - u32 val; - - regmap_read(phy->regmap, reg, &val); - - return val; -} - -static inline void phy_write(struct mt7621_pci_phy *phy, u32 val, u32 reg) -{ - regmap_write(phy->regmap, reg, val); -} - -static inline void mt7621_phy_rmw(struct mt7621_pci_phy *phy, - u32 reg, u32 clr, u32 set) -{ - u32 val = phy_read(phy, reg); - - val &= ~clr; - val |= set; - phy_write(phy, val, reg); -} - -static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy) -{ - mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_RST); - mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_CMD_FRC); - - if (phy->has_dual_port) { - mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH, - 0, RG_PE1_PIPE_RST); - mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH, - 0, RG_PE1_PIPE_CMD_FRC); - } -} - -static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy) -{ - struct device *dev = phy->dev; - u32 xtal_mode; - - xtal_mode = (rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0) - >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK; - - /* Set PCIe Port PHY to disable SSC */ - /* Debug Xtal Type */ - mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG, - RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE, - RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00)); - - /* disable port */ - mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG, - RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); - - if (phy->has_dual_port) { - mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, - RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); - } - - if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */ - /* Set Pre-divider ratio (for host mode) */ - mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, - RG_PE1_H_PLL_PREDIV, - RG_PE1_H_PLL_PREDIV_VAL(0x01)); - dev_info(dev, "Xtal is 40MHz\n"); - } else if (xtal_mode >= 6) { /* 25MHz Xal */ - mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, - RG_PE1_H_PLL_PREDIV, - RG_PE1_H_PLL_PREDIV_VAL(0x00)); - /* Select feedback clock */ - mt7621_phy_rmw(phy, RG_PE1_H_PLL_FBKSEL_REG, - RG_PE1_H_PLL_FBKSEL, - RG_PE1_H_PLL_FBKSEL_VAL(0x01)); - /* DDS NCPO PCW (for host mode) */ - mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG, - RG_PE1_H_LCDDS_SSC_PRD, - RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000)); - /* DDS SSC dither period control */ - mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG, - RG_PE1_H_LCDDS_SSC_PRD, - RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d)); - /* DDS SSC dither amplitude control */ - mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG, - RG_PE1_H_LCDDS_SSC_DELTA | - RG_PE1_H_LCDDS_SSC_DELTA1, - RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a) | - RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a)); - dev_info(dev, "Xtal is 25MHz\n"); - } else { /* 20MHz Xtal */ - mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, - RG_PE1_H_PLL_PREDIV, - RG_PE1_H_PLL_PREDIV_VAL(0x00)); - - dev_info(dev, "Xtal is 20MHz\n"); - } - - /* DDS clock inversion */ - mt7621_phy_rmw(phy, RG_PE1_LCDDS_CLK_PH_INV_REG, - RG_PE1_LCDDS_CLK_PH_INV, RG_PE1_LCDDS_CLK_PH_INV); - - /* Set PLL bits */ - mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, - RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR | - RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN, - RG_PE1_H_PLL_BC_VAL(0x02) | RG_PE1_H_PLL_BP_VAL(0x06) | - RG_PE1_H_PLL_IR_VAL(0x02) | RG_PE1_H_PLL_IC_VAL(0x01) | - RG_PE1_PLL_DIVEN_VAL(0x02)); - - mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG, - RG_PE1_H_PLL_BR, RG_PE1_H_PLL_BR_VAL(0x00)); - - if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */ - /* set force mode enable of da_pe1_mstckdiv */ - mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG, - RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV, - RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV); - } -} - -static int mt7621_pci_phy_init(struct phy *phy) -{ - struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); - - if (mphy->bypass_pipe_rst) - mt7621_bypass_pipe_rst(mphy); - - mt7621_set_phy_for_ssc(mphy); - - return 0; -} - -static int mt7621_pci_phy_power_on(struct phy *phy) -{ - struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); - - /* Enable PHY and disable force mode */ - mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG, - RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN); - - if (mphy->has_dual_port) { - mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, - RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN); - } - - return 0; -} - -static int mt7621_pci_phy_power_off(struct phy *phy) -{ - struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); - - /* Disable PHY */ - mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG, - RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); - - if (mphy->has_dual_port) { - mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, - RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); - } - - return 0; -} - -static int mt7621_pci_phy_exit(struct phy *phy) -{ - return 0; -} - -static const struct phy_ops mt7621_pci_phy_ops = { - .init = mt7621_pci_phy_init, - .exit = mt7621_pci_phy_exit, - .power_on = mt7621_pci_phy_power_on, - .power_off = mt7621_pci_phy_power_off, - .owner = THIS_MODULE, -}; - -static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev); - - if (WARN_ON(args->args[0] >= MAX_PHYS)) - return ERR_PTR(-ENODEV); - - mt7621_phy->has_dual_port = args->args[0]; - - dev_info(dev, "PHY for 0x%08x (dual port = %d)\n", - (unsigned int)mt7621_phy->port_base, mt7621_phy->has_dual_port); - - return mt7621_phy->phy; -} - -static const struct soc_device_attribute mt7621_pci_quirks_match[] = { - { .soc_id = "mt7621", .revision = "E2" } -}; - -static const struct regmap_config mt7621_pci_phy_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = 0x700, -}; - -static int mt7621_pci_phy_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - const struct soc_device_attribute *attr; - struct phy_provider *provider; - struct mt7621_pci_phy *phy; - struct resource *res; - - phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENOMEM; - - attr = soc_device_match(mt7621_pci_quirks_match); - if (attr) - phy->bypass_pipe_rst = true; - - phy->dev = dev; - platform_set_drvdata(pdev, phy); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "failed to get address resource\n"); - return -ENXIO; - } - - phy->port_base = devm_ioremap_resource(dev, res); - if (IS_ERR(phy->port_base)) { - dev_err(dev, "failed to remap phy regs\n"); - return PTR_ERR(phy->port_base); - } - - phy->regmap = devm_regmap_init_mmio(phy->dev, phy->port_base, - &mt7621_pci_phy_regmap_config); - if (IS_ERR(phy->regmap)) - return PTR_ERR(phy->regmap); - - phy->phy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops); - if (IS_ERR(phy)) { - dev_err(dev, "failed to create phy\n"); - return PTR_ERR(phy); - } - - phy_set_drvdata(phy->phy, phy); - - provider = devm_of_phy_provider_register(dev, mt7621_pcie_phy_of_xlate); - - return PTR_ERR_OR_ZERO(provider); -} - -static const struct of_device_id mt7621_pci_phy_ids[] = { - { .compatible = "mediatek,mt7621-pci-phy" }, - {}, -}; -MODULE_DEVICE_TABLE(of, mt7621_pci_ids); - -static struct platform_driver mt7621_pci_phy_driver = { - .probe = mt7621_pci_phy_probe, - .driver = { - .name = "mt7621-pci-phy", - .of_match_table = of_match_ptr(mt7621_pci_phy_ids), - }, -}; - -builtin_platform_driver(mt7621_pci_phy_driver); - -MODULE_AUTHOR("Sergio Paracuellos "); -MODULE_DESCRIPTION("MediaTek MT7621 PCIe PHY driver"); -MODULE_LICENSE("GPL v2"); From 81b534f7e9b27309b99ac2b870518c17381d2912 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 20 Nov 2020 09:56:36 +0100 Subject: [PATCH 50/72] phy: samsung: Add support for the Exynos5420 variant of the USB2 PHY Exynos5420 differs a bit from Exynos5250 in USB2 PHY related registers in the PMU region. Add a variant for the Exynos5420 case. Till now, USB2 PHY worked only because the bootloader enabled the PHY, but then driver messed USB 3.0 DRD related registers during the suspend/resume cycle. Signed-off-by: Marek Szyprowski Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20201120085637.7299-2-m.szyprowski@samsung.com Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/samsung-phy.txt | 1 + drivers/phy/samsung/Kconfig | 7 ++- drivers/phy/samsung/phy-exynos5250-usb2.c | 48 +++++++++++++------ drivers/phy/samsung/phy-samsung-usb2.c | 6 +++ drivers/phy/samsung/phy-samsung-usb2.h | 1 + 5 files changed, 48 insertions(+), 15 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 7510830a79bd..8f51aee91101 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -47,6 +47,7 @@ Required properties: - "samsung,exynos4210-usb2-phy" - "samsung,exynos4x12-usb2-phy" - "samsung,exynos5250-usb2-phy" + - "samsung,exynos5420-usb2-phy" - "samsung,s5pv210-usb2-phy" - reg : a list of registers used by phy driver - first and obligatory is the location of phy modules registers diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig index e20d2fcc9fe7..0f51d3bf38cc 100644 --- a/drivers/phy/samsung/Kconfig +++ b/drivers/phy/samsung/Kconfig @@ -64,7 +64,12 @@ config PHY_EXYNOS4X12_USB2 config PHY_EXYNOS5250_USB2 bool depends on PHY_SAMSUNG_USB2 - default SOC_EXYNOS5250 || SOC_EXYNOS5420 + default SOC_EXYNOS5250 + +config PHY_EXYNOS5420_USB2 + bool + depends on PHY_SAMSUNG_USB2 + default SOC_EXYNOS5420 config PHY_S5PV210_USB2 bool "Support for S5PV210" diff --git a/drivers/phy/samsung/phy-exynos5250-usb2.c b/drivers/phy/samsung/phy-exynos5250-usb2.c index 4f53b711fd6f..e198010e1bfd 100644 --- a/drivers/phy/samsung/phy-exynos5250-usb2.c +++ b/drivers/phy/samsung/phy-exynos5250-usb2.c @@ -117,9 +117,9 @@ /* Isolation, configured in the power management unit */ #define EXYNOS_5250_USB_ISOL_OTG_OFFSET 0x704 -#define EXYNOS_5250_USB_ISOL_OTG BIT(0) #define EXYNOS_5250_USB_ISOL_HOST_OFFSET 0x708 -#define EXYNOS_5250_USB_ISOL_HOST BIT(0) +#define EXYNOS_5420_USB_ISOL_HOST_OFFSET 0x70C +#define EXYNOS_5250_USB_ISOL_ENABLE BIT(0) /* Mode swtich register */ #define EXYNOS_5250_MODE_SWITCH_OFFSET 0x230 @@ -132,7 +132,6 @@ enum exynos4x12_phy_id { EXYNOS5250_HOST, EXYNOS5250_HSIC0, EXYNOS5250_HSIC1, - EXYNOS5250_NUM_PHYS, }; /* @@ -176,20 +175,19 @@ static void exynos5250_isol(struct samsung_usb2_phy_instance *inst, bool on) { struct samsung_usb2_phy_driver *drv = inst->drv; u32 offset; - u32 mask; + u32 mask = EXYNOS_5250_USB_ISOL_ENABLE; - switch (inst->cfg->id) { - case EXYNOS5250_DEVICE: + if (drv->cfg == &exynos5250_usb2_phy_config && + inst->cfg->id == EXYNOS5250_DEVICE) offset = EXYNOS_5250_USB_ISOL_OTG_OFFSET; - mask = EXYNOS_5250_USB_ISOL_OTG; - break; - case EXYNOS5250_HOST: + else if (drv->cfg == &exynos5250_usb2_phy_config && + inst->cfg->id == EXYNOS5250_HOST) offset = EXYNOS_5250_USB_ISOL_HOST_OFFSET; - mask = EXYNOS_5250_USB_ISOL_HOST; - break; - default: + else if (drv->cfg == &exynos5420_usb2_phy_config && + inst->cfg->id == EXYNOS5250_HOST) + offset = EXYNOS_5420_USB_ISOL_HOST_OFFSET; + else return; - } regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); } @@ -390,9 +388,31 @@ static const struct samsung_usb2_common_phy exynos5250_phys[] = { }, }; +static const struct samsung_usb2_common_phy exynos5420_phys[] = { + { + .label = "host", + .id = EXYNOS5250_HOST, + .power_on = exynos5250_power_on, + .power_off = exynos5250_power_off, + }, + { + .label = "hsic", + .id = EXYNOS5250_HSIC0, + .power_on = exynos5250_power_on, + .power_off = exynos5250_power_off, + }, +}; + const struct samsung_usb2_phy_config exynos5250_usb2_phy_config = { .has_mode_switch = 1, - .num_phys = EXYNOS5250_NUM_PHYS, + .num_phys = ARRAY_SIZE(exynos5250_phys), .phys = exynos5250_phys, .rate_to_clk = exynos5250_rate_to_clk, }; + +const struct samsung_usb2_phy_config exynos5420_usb2_phy_config = { + .has_mode_switch = 1, + .num_phys = ARRAY_SIZE(exynos5420_phys), + .phys = exynos5420_phys, + .rate_to_clk = exynos5250_rate_to_clk, +}; diff --git a/drivers/phy/samsung/phy-samsung-usb2.c b/drivers/phy/samsung/phy-samsung-usb2.c index f79f605cff79..3908153f2ce5 100644 --- a/drivers/phy/samsung/phy-samsung-usb2.c +++ b/drivers/phy/samsung/phy-samsung-usb2.c @@ -128,6 +128,12 @@ static const struct of_device_id samsung_usb2_phy_of_match[] = { .data = &exynos5250_usb2_phy_config, }, #endif +#ifdef CONFIG_PHY_EXYNOS5420_USB2 + { + .compatible = "samsung,exynos5420-usb2-phy", + .data = &exynos5420_usb2_phy_config, + }, +#endif #ifdef CONFIG_PHY_S5PV210_USB2 { .compatible = "samsung,s5pv210-usb2-phy", diff --git a/drivers/phy/samsung/phy-samsung-usb2.h b/drivers/phy/samsung/phy-samsung-usb2.h index 77fb23bc218f..ebaf43bfc5a2 100644 --- a/drivers/phy/samsung/phy-samsung-usb2.h +++ b/drivers/phy/samsung/phy-samsung-usb2.h @@ -66,5 +66,6 @@ extern const struct samsung_usb2_phy_config exynos3250_usb2_phy_config; extern const struct samsung_usb2_phy_config exynos4210_usb2_phy_config; extern const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config; extern const struct samsung_usb2_phy_config exynos5250_usb2_phy_config; +extern const struct samsung_usb2_phy_config exynos5420_usb2_phy_config; extern const struct samsung_usb2_phy_config s5pv210_usb2_phy_config; #endif From 4eed2812de6addc934497688503568435a540b51 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 20 Nov 2020 16:03:47 +0100 Subject: [PATCH 51/72] phy: amlogic: meson-axg-mipi-pcie-analog: replace DSI_LANE definitions with BIT() macro For consistency, replace DSI_LANE definitions with BIT() macro and remove the unused DSI_LANE_MASK definition. Suggested-by: Vinod Koul Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20201120150347.3914901-1-narmstrong@baylibre.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c index 6eb21551bdd9..1027ece6ca12 100644 --- a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c @@ -38,12 +38,11 @@ #define HHI_MIPI_CNTL2_CH_EN GENMASK(15, 11) #define HHI_MIPI_CNTL2_CH0_LP_CTL GENMASK(10, 1) -#define DSI_LANE_0 (1 << 4) -#define DSI_LANE_1 (1 << 3) -#define DSI_LANE_CLK (1 << 2) -#define DSI_LANE_2 (1 << 1) -#define DSI_LANE_3 (1 << 0) -#define DSI_LANE_MASK (0x1F) +#define DSI_LANE_0 BIT(4) +#define DSI_LANE_1 BIT(3) +#define DSI_LANE_CLK BIT(2) +#define DSI_LANE_2 BIT(1) +#define DSI_LANE_3 BIT(0) struct phy_axg_mipi_pcie_analog_priv { struct phy *phy; From 122586d62206c68e061f0329443ff65985e1aae5 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 20 Nov 2020 16:38:55 +0100 Subject: [PATCH 52/72] phy: amlogic: phy-meson-gxl-usb2: keep ID pull-up even in Host mode In order to keep OTG ID detection even when in Host mode, the ID line of the PHY (if the current phy is an OTG one) pull-up should be kept enable in both modes. This fixes OTG switch on GXL, GXM & AXG platforms, otherwise once switched to Host, the ID detection doesn't work anymore to switch back to Device. Signed-off-by: Neil Armstrong Reviewed-by: Kevin Hilman Reviewed-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20201120153855.3920757-1-narmstrong@baylibre.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-gxl-usb2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/phy/amlogic/phy-meson-gxl-usb2.c b/drivers/phy/amlogic/phy-meson-gxl-usb2.c index 875afb2672c7..2b3c0d730f20 100644 --- a/drivers/phy/amlogic/phy-meson-gxl-usb2.c +++ b/drivers/phy/amlogic/phy-meson-gxl-usb2.c @@ -158,7 +158,8 @@ static int phy_meson_gxl_usb2_set_mode(struct phy *phy, U2P_R0_DM_PULLDOWN); regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN, U2P_R0_DP_PULLDOWN); - regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, 0); + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, + U2P_R0_ID_PULLUP); break; case PHY_MODE_USB_DEVICE: From 15ee6277817f9eda605937c254dc8f15f1305c1f Mon Sep 17 00:00:00 2001 From: Yejune Deng Date: Wed, 18 Nov 2020 10:36:35 +0800 Subject: [PATCH 53/72] phy: amlogic: replace devm_reset_control_array_get() devm_reset_control_array_get_exclusive() looks more readable Signed-off-by: Yejune Deng Reviewed-by: Martin Blumenstingl Reviewed-by: Philipp Zabel Link: https://lore.kernel.org/r/1605666995-16462-1-git-send-email-yejune.deng@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-axg-pcie.c | 2 +- drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-axg-pcie.c b/drivers/phy/amlogic/phy-meson-axg-pcie.c index 58a7507a8422..2299bab38e05 100644 --- a/drivers/phy/amlogic/phy-meson-axg-pcie.c +++ b/drivers/phy/amlogic/phy-meson-axg-pcie.c @@ -153,7 +153,7 @@ static int phy_axg_pcie_probe(struct platform_device *pdev) if (IS_ERR(priv->regmap)) return PTR_ERR(priv->regmap); - priv->reset = devm_reset_control_array_get(dev, false, false); + priv->reset = devm_reset_control_array_get_exclusive(dev); if (IS_ERR(priv->reset)) return PTR_ERR(priv->reset); diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c index ebe3d0ddd304..5b471ab80fe2 100644 --- a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c +++ b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c @@ -416,7 +416,7 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev) if (ret) goto err_disable_clk_ref; - priv->reset = devm_reset_control_array_get(dev, false, false); + priv->reset = devm_reset_control_array_get_exclusive(dev); if (IS_ERR(priv->reset)) return PTR_ERR(priv->reset); From 4ea0bf2a52f1eea76578eac5a9148d95f5e181c0 Mon Sep 17 00:00:00 2001 From: JC Kuo Date: Tue, 17 Nov 2020 16:38:03 +0800 Subject: [PATCH 54/72] phy: tegra: xusb: Fix usb_phy device driver field In commit "phy: tegra: xusb: Add usb-phy support", an OTG capable PHY device, such as phy-usb2.0 device of Jetson-TX1 platform, will be bound to the tegra-xusb-padctl driver by the following line in tegra_xusb_setup_usb_role_switch(). port->usb_phy.dev->driver = port->padctl->dev->driver; With this, dev_pm_ops set of tegra-xusb-padctl driver will be invoked for the OTG capable PHY incorrectly as below logs show. This commit fixes the issue by assigning an empty driver to it. [ 153.451108] tegra-xusb-padctl phy-usb2.0: > tegra_xusb_padctl_suspend_noirq(dev=ffff000080917000) [ 153.460353] tegra-xusb-padctl phy-usb2.0: driver: ffff8000114453e0 (tegra_xusb_padctl_driver) [ 153.469245] tegra-xusb-padctl phy-usb2.0: padctl: ffff0000829f6480 [ 153.475772] tegra-xusb-padctl phy-usb2.0: soc: ef7bdd7fffffffff (0xef7bdd7fffffffff) [ 153.484061] Unable to handle kernel paging request at virtual address 007bdd800000004f [ 153.492132] Mem abort info: [ 153.495083] ESR = 0x96000004 [ 153.498308] EC = 0x25: DABT (current EL), IL = 32 bits [ 153.503771] SET = 0, FnV = 0 [ 153.506979] EA = 0, S1PTW = 0 [ 153.510260] Data abort info: [ 153.513200] ISV = 0, ISS = 0x00000004 [ 153.517181] CM = 0, WnR = 0 [ 153.520302] [007bdd800000004f] address between user and kernel address ranges [ 153.527600] Internal error: Oops: 96000004 [#1] PREEMPT SMP [ 153.533231] Modules linked in: nouveau panel_simple tegra_video(C) tegra_drm drm_ttm_helper videobuf2_dma_contig ttm videobuf2_memops cec videobuf2_v4l2 videobuf2_common drm_kms_helper v4l2_fwnode videodev drm mc snd_hda_codec_hdmi cdc_ether usbnet snd_hda_tegra r8152 crct10dif_ce snd_hda_codec snd_hda_core tegra_xudc host1x lp855x_bl at24 ip_tables x_tables ipv6 [ 153.566417] CPU: 0 PID: 300 Comm: systemd-sleep Tainted: G C 5.10.0-rc3-next-20201113-00019-g5c064d5372b0-dirty #624 [ 153.578283] Hardware name: NVIDIA Jetson TX1 Developer Kit (DT) [ 153.584281] pstate: 40000005 (nZcv daif -PAN -UAO -TCO BTYPE=--) [ 153.590381] pc : tegra_xusb_padctl_suspend_noirq+0x88/0x100 [ 153.596016] lr : tegra_xusb_padctl_suspend_noirq+0x80/0x100 [ 153.601632] sp : ffff8000120dbb60 [ 153.604999] x29: ffff8000120dbb60 x28: ffff000080a1df00 [ 153.610430] x27: 0000000000000002 x26: ffff8000106f8540 [ 153.615858] x25: ffff8000113ac4a4 x24: ffff80001148c198 [ 153.621277] x23: ffff800010c4538c x22: 0000000000000002 [ 153.626692] x21: ffff800010ccde80 x20: ffff0000829f6480 [ 153.632107] x19: ffff000080917000 x18: 0000000000000030 [ 153.637521] x17: 0000000000000000 x16: 0000000000000000 [ 153.642933] x15: ffff000080a1e380 x14: 74636461702d6273 [ 153.648346] x13: ffff8000113ad058 x12: 0000000000000f39 [ 153.653759] x11: 0000000000000513 x10: ffff800011405058 [ 153.659176] x9 : 00000000fffff000 x8 : ffff8000113ad058 [ 153.664590] x7 : ffff800011405058 x6 : 0000000000000000 [ 153.670002] x5 : 0000000000000000 x4 : ffff0000fe908bc0 [ 153.675414] x3 : ffff0000fe910228 x2 : 162ef67e0581e700 [ 153.680826] x1 : 162ef67e0581e700 x0 : ef7bdd7fffffffff [ 153.686241] Call trace: [ 153.688769] tegra_xusb_padctl_suspend_noirq+0x88/0x100 [ 153.694077] __device_suspend_noirq+0x68/0x1cc [ 153.698594] dpm_noirq_suspend_devices+0x10c/0x1d0 [ 153.703456] dpm_suspend_noirq+0x28/0xa0 [ 153.707461] suspend_devices_and_enter+0x234/0x4bc [ 153.712314] pm_suspend+0x1e4/0x270 [ 153.715868] state_store+0x8c/0x110 [ 153.719440] kobj_attr_store+0x1c/0x30 [ 153.723259] sysfs_kf_write+0x4c/0x7c [ 153.726981] kernfs_fop_write+0x124/0x240 [ 153.731065] vfs_write+0xe4/0x204 [ 153.734449] ksys_write+0x6c/0x100 [ 153.737925] __arm64_sys_write+0x20/0x30 [ 153.741931] el0_svc_common.constprop.0+0x78/0x1a0 [ 153.746789] do_el0_svc+0x24/0x90 [ 153.750181] el0_sync_handler+0x254/0x260 [ 153.754251] el0_sync+0x174/0x180 [ 153.757663] Code: aa0303e2 94000f64 f9405680 b40000e0 (f9402803) [ 153.763826] ---[ end trace 81543a3394cb409d ]--- Fixes: e8f7d2f409a1 ("phy: tegra: xusb: Add usb-phy support") Signed-off-by: JC Kuo Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20201117083803.185209-1-jckuo@nvidia.com Signed-off-by: Vinod Koul --- drivers/phy/tegra/xusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 40e03c931340..a6e8afe7c5ee 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -688,7 +688,7 @@ static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port) * reference to retrieve usb-phy details. */ port->usb_phy.dev = &lane->pad->lanes[port->index]->dev; - port->usb_phy.dev->driver = port->padctl->dev->driver; + port->usb_phy.dev->driver = port->dev.driver; port->usb_phy.otg->usb_phy = &port->usb_phy; port->usb_phy.otg->set_peripheral = tegra_xusb_set_peripheral; port->usb_phy.otg->set_host = tegra_xusb_set_host; From d7bb92e3c908a9df47bd3a306f6fc3e009babc5b Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Wed, 25 Nov 2020 15:37:45 +0800 Subject: [PATCH 55/72] phy: mediatek: Make PHY_MTK_{XSPHY, TPHY} depend on HAS_IOMEM and OF_ADDRESS to fix build errors devm_ioremap_resource() will be not built in lib/devres.c if CONFIG_HAS_IOMEM is not set, of_address_to_resource() will be not built in drivers/of/address.c if CONFIG_OF_ADDRESS is not set, and then there exists two build errors about undefined reference to "devm_ioremap_resource" and "of_address_to_resource" in phy-mtk-xsphy.c under COMPILE_TEST and CONFIG_PHY_MTK_XSPHY, make PHY_MTK_XSPHY depend on HAS_IOMEM and OF_ADDRESS to fix it. The above issue is reported by kernel test robot , through the discussion in the v1 patch, as Chunfeng said we need also do this for config PHY_MTK_TPHY: drivers/phy/mediatek/phy-mtk-tphy.c:1157: retval = of_address_to_resource(child_np, 0, &res); drivers/phy/mediatek/phy-mtk-tphy.c:1123: tphy->sif_base = devm_ioremap_resource(dev, sif_res); drivers/phy/mediatek/phy-mtk-tphy.c:1164: instance->port_base = devm_ioremap_resource(&phy->dev, &res); Reported-by: kernel test robot Signed-off-by: Tiezhu Yang Acked-by: Randy Dunlap Acked-by: Chunfeng Yun Link: https://lore.kernel.org/r/1606289865-692-1-git-send-email-yangtiezhu@loongson.cn Signed-off-by: Vinod Koul --- drivers/phy/mediatek/Kconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig index 50c5e9306e19..f44800b6a948 100644 --- a/drivers/phy/mediatek/Kconfig +++ b/drivers/phy/mediatek/Kconfig @@ -5,7 +5,8 @@ config PHY_MTK_TPHY tristate "MediaTek T-PHY Driver" depends on ARCH_MEDIATEK || COMPILE_TEST - depends on OF + depends on OF && OF_ADDRESS + depends on HAS_IOMEM select GENERIC_PHY help Say 'Y' here to add support for MediaTek T-PHY driver, @@ -29,7 +30,8 @@ config PHY_MTK_UFS config PHY_MTK_XSPHY tristate "MediaTek XS-PHY Driver" depends on ARCH_MEDIATEK || COMPILE_TEST - depends on OF + depends on OF && OF_ADDRESS + depends on HAS_IOMEM select GENERIC_PHY help Enable this to support the SuperSpeedPlus XS-PHY transceiver for From 0e055d179ea9368f882d2060b0d82341ee90bae3 Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Tue, 1 Dec 2020 12:20:50 +0100 Subject: [PATCH 56/72] phy: ralink: phy-mt7621-pci: drop 'COMPILE_TEST' from Kconfig This driver includes the following two files directly: - mt7621.h - ralink_regs.h Compilation for its related platform properly works because its real path is included in 'arch/mips/ralink/Platform' as cflags. This driver depends on RALINK but also is enabled for COMPILE_TEST where nothing about its platform is known and this directly included files are not found at all breaking compilation. If we want 'COMPILE_TEST' we have to change cflags also inside 'phy/ralink' subdirectory Makefile which seems that does not like to linux-phy maintainers. Hence remove COMPILE_TEST from Kconfig to avoid the problem. Fixes: d87da32372a0 ("phy: ralink: Add PHY driver for MT7621 PCIe PHY") Reported-by: Stephen Rothwell Signed-off-by: Sergio Paracuellos Link: https://lore.kernel.org/r/20201201112051.17463-2-sergio.paracuellos@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/ralink/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/ralink/Kconfig b/drivers/phy/ralink/Kconfig index 2fabb14d2998..ecc309ba9fee 100644 --- a/drivers/phy/ralink/Kconfig +++ b/drivers/phy/ralink/Kconfig @@ -4,7 +4,7 @@ # config PHY_MT7621_PCI tristate "MediaTek MT7621 PCI PHY Driver" - depends on (RALINK || COMPILE_TEST) && OF + depends on RALINK && OF select GENERIC_PHY select REGMAP_MMIO help From 8145dcb07d0c8bdb1e8e76a5df18779431f7af8e Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Tue, 1 Dec 2020 12:20:51 +0100 Subject: [PATCH 57/72] phy: ralink: phy-mt7621-pci: set correct name in MODULE_DEVICE_TABLE macro Correct name passed into 'MODULE_DEVICE_TABLE' which was wrong and was showing a warning when the driver is enabled for 'COMPILE_TEST'. Signed-off-by: Sergio Paracuellos Link: https://lore.kernel.org/r/20201201112051.17463-3-sergio.paracuellos@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/ralink/phy-mt7621-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/ralink/phy-mt7621-pci.c b/drivers/phy/ralink/phy-mt7621-pci.c index db79088d5362..9a610b414b1f 100644 --- a/drivers/phy/ralink/phy-mt7621-pci.c +++ b/drivers/phy/ralink/phy-mt7621-pci.c @@ -335,7 +335,7 @@ static const struct of_device_id mt7621_pci_phy_ids[] = { { .compatible = "mediatek,mt7621-pci-phy" }, {}, }; -MODULE_DEVICE_TABLE(of, mt7621_pci_ids); +MODULE_DEVICE_TABLE(of, mt7621_pci_phy_ids); static struct platform_driver mt7621_pci_phy_driver = { .probe = mt7621_pci_phy_probe, From 3eaf2da98993ecdf6e46a2b27cd31ef84a12e45f Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 2 Dec 2020 07:47:59 +0100 Subject: [PATCH 58/72] phy: samsung: Merge Kconfig for Exynos5420 and Exynos5250 Exynos5420 variant of USB2 PHY is handled by the same code as the Exynos5250 one. Introducing a separate Kconfig symbol for it was an over-engineering, which turned out to cause build break for certain configurations: ERROR: modpost: "exynos5420_usb2_phy_config" [drivers/phy/samsung/phy-exynos-usb2.ko] undefined! Fix this by removing PHY_EXYNOS5420_USB2 symbol and using PHY_EXYNOS5250_USB2 also for Exynos5420 SoCs. Reported-by: Markus Reichl Fixes: 81b534f7e9b2 ("phy: samsung: Add support for the Exynos5420 variant of the USB2 PHY") Signed-off-by: Marek Szyprowski Acked-by: Krzysztof Kozlowski Reviewed-by: Jaehoon Chung Link: https://lore.kernel.org/r/20201202064759.24300-1-m.szyprowski@samsung.com Signed-off-by: Vinod Koul --- drivers/phy/samsung/Kconfig | 7 +------ drivers/phy/samsung/phy-samsung-usb2.c | 2 -- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig index 0f51d3bf38cc..e20d2fcc9fe7 100644 --- a/drivers/phy/samsung/Kconfig +++ b/drivers/phy/samsung/Kconfig @@ -64,12 +64,7 @@ config PHY_EXYNOS4X12_USB2 config PHY_EXYNOS5250_USB2 bool depends on PHY_SAMSUNG_USB2 - default SOC_EXYNOS5250 - -config PHY_EXYNOS5420_USB2 - bool - depends on PHY_SAMSUNG_USB2 - default SOC_EXYNOS5420 + default SOC_EXYNOS5250 || SOC_EXYNOS5420 config PHY_S5PV210_USB2 bool "Support for S5PV210" diff --git a/drivers/phy/samsung/phy-samsung-usb2.c b/drivers/phy/samsung/phy-samsung-usb2.c index 3908153f2ce5..ec2befabeea6 100644 --- a/drivers/phy/samsung/phy-samsung-usb2.c +++ b/drivers/phy/samsung/phy-samsung-usb2.c @@ -127,8 +127,6 @@ static const struct of_device_id samsung_usb2_phy_of_match[] = { .compatible = "samsung,exynos5250-usb2-phy", .data = &exynos5250_usb2_phy_config, }, -#endif -#ifdef CONFIG_PHY_EXYNOS5420_USB2 { .compatible = "samsung,exynos5420-usb2-phy", .data = &exynos5420_usb2_phy_config, From ab7dd2008b29e48cff216aa984902d59b583d36d Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Tue, 24 Nov 2020 19:11:27 +0800 Subject: [PATCH 59/72] phy/rockchip: Make PHY_ROCKCHIP_INNO_HDMI depend on HAS_IOMEM to fix build error devm_ioremap_resource() will be not built in lib/devres.c if CONFIG_HAS_IOMEM is not set, and then there exists a build error about undefined reference to "devm_ioremap_resource" in the file phy-rockchip-inno-hdmi.c under COMPILE_TEST and CONFIG_PHY_ROCKCHIP_INNO_HDMI, make PHY_ROCKCHIP_INNO_HDMI depend on HAS_IOMEM to fix it. Reported-by: kernel test robot Signed-off-by: Tiezhu Yang Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/1606216287-14648-1-git-send-email-yangtiezhu@loongson.cn Signed-off-by: Vinod Koul --- drivers/phy/rockchip/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index c2f22f90736c..159285f42e5c 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -32,6 +32,7 @@ config PHY_ROCKCHIP_INNO_HDMI tristate "Rockchip INNO HDMI PHY Driver" depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF depends on COMMON_CLK + depends on HAS_IOMEM select GENERIC_PHY help Enable this to support the Rockchip Innosilicon HDMI PHY. From f5f6e01f9164040ba120f30522efdb4deceb529a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 4 Dec 2020 14:56:43 +0100 Subject: [PATCH 60/72] phy: mediatek: allow compile-testing the hdmi phy Compile-testing the DRM_MEDIATEK_HDMI driver shows two missing dependencies, one results in a link failure: arm-linux-gnueabi-ld: drivers/phy/mediatek/phy-mtk-hdmi.o: in function `mtk_hdmi_phy_probe': phy-mtk-hdmi.c:(.text+0xd8): undefined reference to `__clk_get_name' arm-linux-gnueabi-ld: phy-mtk-hdmi.c:(.text+0x12c): undefined reference to `devm_clk_register' arm-linux-gnueabi-ld: phy-mtk-hdmi.c:(.text+0x250): undefined reference to `of_clk_add_provider' arm-linux-gnueabi-ld: phy-mtk-hdmi.c:(.text+0x298): undefined reference to `of_clk_src_simple_get' The other one is a harmless warning: WARNING: unmet direct dependencies detected for PHY_MTK_HDMI Depends on [n]: ARCH_MEDIATEK [=n] && OF [=y] Selected by [y]: - DRM_MEDIATEK_HDMI [=y] && HAS_IOMEM [=y] && DRM_MEDIATEK [=y] Fix these by adding dependencies on CONFIG_OF and CONFIG_COMMON_CLK. With that done, there is also no reason against adding CONFIG_COMPILE_TEST. Fixes: b28be59a2e26 ("phy: mediatek: Move mtk_hdmi_phy driver into drivers/phy/mediatek folder") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20201204135650.2744481-1-arnd@kernel.org Signed-off-by: Vinod Koul --- drivers/phy/mediatek/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig index f44800b6a948..789614116f1d 100644 --- a/drivers/phy/mediatek/Kconfig +++ b/drivers/phy/mediatek/Kconfig @@ -40,7 +40,9 @@ config PHY_MTK_XSPHY config PHY_MTK_HDMI tristate "MediaTek HDMI-PHY Driver" - depends on ARCH_MEDIATEK && OF + depends on ARCH_MEDIATEK || COMPILE_TEST + depends on COMMON_CLK + depends on OF select GENERIC_PHY help Support HDMI PHY for Mediatek SoCs. From 51e339deab1e51443f6ac3b1bd5cd6cc8e8fe1d9 Mon Sep 17 00:00:00 2001 From: Wang Li Date: Thu, 26 Nov 2020 10:44:12 +0800 Subject: [PATCH 61/72] phy: renesas: rcar-gen3-usb2: disable runtime pm in case of failure pm_runtime_enable() will decrease power disable depth. Thus a pairing increment is needed on the error handling path to keep it balanced. Fixes: 5d8042e95fd4 ("phy: rcar-gen3-usb2: Add support for r8a77470") Reported-by: Hulk Robot Signed-off-by: Wang Li Link: https://lore.kernel.org/r/20201126024412.4046845-1-wangli74@huawei.com Signed-off-by: Vinod Koul --- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index 1898bbe7c8e5..fbc55232120e 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -654,8 +654,10 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) */ pm_runtime_enable(dev); phy_usb2_ops = of_device_get_match_data(dev); - if (!phy_usb2_ops) - return -EINVAL; + if (!phy_usb2_ops) { + ret = -EINVAL; + goto error; + } mutex_init(&channel->lock); for (i = 0; i < NUM_OF_PHYS; i++) { From 8b5c2b45b8f0a11c9072da0f7baf9ee986d3151e Mon Sep 17 00:00:00 2001 From: Chris Ruehl Date: Sun, 29 Nov 2020 13:44:14 +0800 Subject: [PATCH 62/72] phy: rockchip: set pulldown for strobe line in dts This patch add support to set the internal pulldown via dt property and allow simplify the board design for the trace from emmc-phy to the eMMC chipset. Default to not set the pull-down. This patch was inspired from the 4.4 tree of the Rockchip SDK, where it is enabled unconditional. The patch had been tested with our rk3399 customized board. Signed-off-by: Chris Ruehl Link: https://lore.kernel.org/r/20201129054416.3980-2-chris.ruehl@gtsys.com.hk Signed-off-by: Vinod Koul --- drivers/phy/rockchip/phy-rockchip-emmc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/phy/rockchip/phy-rockchip-emmc.c b/drivers/phy/rockchip/phy-rockchip-emmc.c index 2dc19ddd120f..48e2d75b1004 100644 --- a/drivers/phy/rockchip/phy-rockchip-emmc.c +++ b/drivers/phy/rockchip/phy-rockchip-emmc.c @@ -67,6 +67,10 @@ #define PHYCTRL_OTAPDLYENA_SHIFT 0xb #define PHYCTRL_OTAPDLYSEL_MASK 0xf #define PHYCTRL_OTAPDLYSEL_SHIFT 0x7 +#define PHYCTRL_REN_STRB_DISABLE 0x0 +#define PHYCTRL_REN_STRB_ENABLE 0x1 +#define PHYCTRL_REN_STRB_MASK 0x1 +#define PHYCTRL_REN_STRB_SHIFT 0x9 #define PHYCTRL_IS_CALDONE(x) \ ((((x) >> PHYCTRL_CALDONE_SHIFT) & \ @@ -80,6 +84,7 @@ struct rockchip_emmc_phy { struct regmap *reg_base; struct clk *emmcclk; unsigned int drive_impedance; + unsigned int enable_strobe_pulldown; }; static int rockchip_emmc_phy_power(struct phy *phy, bool on_off) @@ -295,6 +300,13 @@ static int rockchip_emmc_phy_power_on(struct phy *phy) PHYCTRL_OTAPDLYSEL_MASK, PHYCTRL_OTAPDLYSEL_SHIFT)); + /* Internal pull-down for strobe line */ + regmap_write(rk_phy->reg_base, + rk_phy->reg_offset + GRF_EMMCPHY_CON2, + HIWORD_UPDATE(rk_phy->enable_strobe_pulldown, + PHYCTRL_REN_STRB_MASK, + PHYCTRL_REN_STRB_SHIFT)); + /* Power up emmc phy analog blocks */ return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_ON); } @@ -359,10 +371,14 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev) rk_phy->reg_offset = reg_offset; rk_phy->reg_base = grf; rk_phy->drive_impedance = PHYCTRL_DR_50OHM; + rk_phy->enable_strobe_pulldown = PHYCTRL_REN_STRB_DISABLE; if (!of_property_read_u32(dev->of_node, "drive-impedance-ohm", &val)) rk_phy->drive_impedance = convert_drive_impedance_ohm(pdev, val); + if (of_property_read_bool(dev->of_node, "enable-strobe-pulldown")) + rk_phy->enable_strobe_pulldown = PHYCTRL_REN_STRB_ENABLE; + generic_phy = devm_phy_create(dev, dev->of_node, &ops); if (IS_ERR(generic_phy)) { dev_err(dev, "failed to create PHY\n"); From f34e43f123825a39190b978a433423c2e2030830 Mon Sep 17 00:00:00 2001 From: Chris Ruehl Date: Sun, 29 Nov 2020 13:44:15 +0800 Subject: [PATCH 63/72] devicetree: phy: rockchip-emmc: pulldown property Update the documentation and add the bool property enable-strobe-pulldown used to enable the internal pull-down for the strobe line. Signed-off-by: Chris Ruehl Link: https://lore.kernel.org/r/20201129054416.3980-3-chris.ruehl@gtsys.com.hk Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt index e728786f21e0..3e4d2d79a65d 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt @@ -16,6 +16,8 @@ Optional properties: - drive-impedance-ohm: Specifies the drive impedance in Ohm. Possible values are 33, 40, 50, 66 and 100. If not set, the default value of 50 will be applied. + - enable-strobe-pulldown: Enable internal pull-down for the strobe line. + If not set, pull-down is not used. Example: From 85e6225f401f95478ad52d77a6834a6ee1db8c32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=90=B0=E6=9D=B0=20=28Zhou=20Yanjie=29?= Date: Mon, 16 Nov 2020 22:19:04 +0800 Subject: [PATCH 64/72] USB: PHY: JZ4770: Remove unnecessary function calls. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove unnecessary "of_match_ptr()", because Ingenic SoCs all depend on Device Tree. Suggested-by: Paul Cercueil Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/20201116141906.11758-2-zhouyanjie@wanyeetech.com Signed-off-by: Vinod Koul --- drivers/usb/phy/phy-jz4770.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy-jz4770.c b/drivers/usb/phy/phy-jz4770.c index f6d3731581eb..4025da20b3fd 100644 --- a/drivers/usb/phy/phy-jz4770.c +++ b/drivers/usb/phy/phy-jz4770.c @@ -350,7 +350,7 @@ static struct platform_driver ingenic_phy_driver = { .probe = jz4770_phy_probe, .driver = { .name = "jz4770-phy", - .of_match_table = of_match_ptr(ingenic_usb_phy_of_matches), + .of_match_table = ingenic_usb_phy_of_matches, }, }; module_platform_driver(ingenic_phy_driver); From 4f6ecfaf3e22a70d905a627a0e84e9edb2b32835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=90=B0=E6=9D=B0=20=28Zhou=20Yanjie=29?= Date: Mon, 16 Nov 2020 22:19:05 +0800 Subject: [PATCH 65/72] dt-bindings: USB: Add bindings for Ingenic JZ4775 and X2000. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move Ingenic USB PHY bindings from Documentation/devicetree/bindings/usb to Documentation/devicetree/bindings/phy, and add bindings for JZ4775 SoC and X2000 SoC. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Rob Herring Acked-by: Stephen Boyd Link: https://lore.kernel.org/r/20201116141906.11758-3-zhouyanjie@wanyeetech.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/clock/ingenic,cgu.yaml | 2 +- .../{usb/ingenic,jz4770-phy.yaml => phy/ingenic,phy-usb.yaml} | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) rename Documentation/devicetree/bindings/{usb/ingenic,jz4770-phy.yaml => phy/ingenic,phy-usb.yaml} (89%) diff --git a/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml b/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml index 5dd7ea8a78e4..c65b9458c0b6 100644 --- a/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml +++ b/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml @@ -92,7 +92,7 @@ required: patternProperties: "^usb-phy@[a-f0-9]+$": - allOf: [ $ref: "../usb/ingenic,jz4770-phy.yaml#" ] + allOf: [ $ref: "../phy/ingenic,phy-usb.yaml#" ] additionalProperties: false diff --git a/Documentation/devicetree/bindings/usb/ingenic,jz4770-phy.yaml b/Documentation/devicetree/bindings/phy/ingenic,phy-usb.yaml similarity index 89% rename from Documentation/devicetree/bindings/usb/ingenic,jz4770-phy.yaml rename to Documentation/devicetree/bindings/phy/ingenic,phy-usb.yaml index 2d61166ea5cf..0fd93d71fe5a 100644 --- a/Documentation/devicetree/bindings/usb/ingenic,jz4770-phy.yaml +++ b/Documentation/devicetree/bindings/phy/ingenic,phy-usb.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/usb/ingenic,jz4770-phy.yaml# +$id: http://devicetree.org/schemas/phy/ingenic,phy-usb.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Ingenic SoCs USB PHY devicetree bindings @@ -17,9 +17,11 @@ properties: compatible: enum: - ingenic,jz4770-phy + - ingenic,jz4775-phy - ingenic,jz4780-phy - ingenic,x1000-phy - ingenic,x1830-phy + - ingenic,x2000-phy reg: maxItems: 1 From 31de313dfdcf6971b0a1c30f86eabaa1eede74b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=90=B0=E6=9D=B0=20=28Zhou=20Yanjie=29?= Date: Mon, 16 Nov 2020 22:19:06 +0800 Subject: [PATCH 66/72] PHY: Ingenic: Add USB PHY driver using generic PHY framework. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Used the generic PHY framework API to create the PHY, this driver supoorts USB OTG PHY used in JZ4770 SoC, JZ4775 SoC, JZ4780 SoC, X1000 SoC, X1830 SoC and X2000 SoC. Co-developed-by: 漆鹏振 (Qi Pengzhen) Signed-off-by: 漆鹏振 (Qi Pengzhen) Signed-off-by: 周琰杰 (Zhou Yanjie) Tested-by: 周正 (Zhou Zheng) Tested-by: H. Nikolaus Schaller Reviewed-by: Paul Cercueil Link: https://lore.kernel.org/r/20201116141906.11758-4-zhouyanjie@wanyeetech.com Signed-off-by: Vinod Koul --- drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 1 + drivers/phy/ingenic/Kconfig | 12 + drivers/phy/ingenic/Makefile | 2 + drivers/phy/ingenic/phy-ingenic-usb.c | 412 ++++++++++++++++++++++++++ 5 files changed, 428 insertions(+) create mode 100644 drivers/phy/ingenic/Kconfig create mode 100644 drivers/phy/ingenic/Makefile create mode 100644 drivers/phy/ingenic/phy-ingenic-usb.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 01b53f86004c..00dabe5fab8a 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -66,6 +66,7 @@ source "drivers/phy/broadcom/Kconfig" source "drivers/phy/cadence/Kconfig" source "drivers/phy/freescale/Kconfig" source "drivers/phy/hisilicon/Kconfig" +source "drivers/phy/ingenic/Kconfig" source "drivers/phy/lantiq/Kconfig" source "drivers/phy/marvell/Kconfig" source "drivers/phy/mediatek/Kconfig" diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 6eb2916773c5..32261e164abd 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -15,6 +15,7 @@ obj-y += allwinner/ \ cadence/ \ freescale/ \ hisilicon/ \ + ingenic/ \ intel/ \ lantiq/ \ marvell/ \ diff --git a/drivers/phy/ingenic/Kconfig b/drivers/phy/ingenic/Kconfig new file mode 100644 index 000000000000..912b14e512cb --- /dev/null +++ b/drivers/phy/ingenic/Kconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Phy drivers for Ingenic platforms +# +config PHY_INGENIC_USB + tristate "Ingenic SoCs USB PHY Driver" + depends on MIPS || COMPILE_TEST + depends on USB_SUPPORT + select GENERIC_PHY + help + This driver provides USB PHY support for the USB controller found + on the JZ-series and X-series SoCs from Ingenic. diff --git a/drivers/phy/ingenic/Makefile b/drivers/phy/ingenic/Makefile new file mode 100644 index 000000000000..65d5ea00fc9d --- /dev/null +++ b/drivers/phy/ingenic/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-y += phy-ingenic-usb.o diff --git a/drivers/phy/ingenic/phy-ingenic-usb.c b/drivers/phy/ingenic/phy-ingenic-usb.c new file mode 100644 index 000000000000..4d1587d82286 --- /dev/null +++ b/drivers/phy/ingenic/phy-ingenic-usb.c @@ -0,0 +1,412 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Ingenic SoCs USB PHY driver + * Copyright (c) Paul Cercueil + * Copyright (c) 漆鹏振 (Qi Pengzhen) + * Copyright (c) 周琰杰 (Zhou Yanjie) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* OTGPHY register offsets */ +#define REG_USBPCR_OFFSET 0x00 +#define REG_USBRDT_OFFSET 0x04 +#define REG_USBVBFIL_OFFSET 0x08 +#define REG_USBPCR1_OFFSET 0x0c + +/* bits within the USBPCR register */ +#define USBPCR_USB_MODE BIT(31) +#define USBPCR_AVLD_REG BIT(30) +#define USBPCR_COMMONONN BIT(25) +#define USBPCR_VBUSVLDEXT BIT(24) +#define USBPCR_VBUSVLDEXTSEL BIT(23) +#define USBPCR_POR BIT(22) +#define USBPCR_SIDDQ BIT(21) +#define USBPCR_OTG_DISABLE BIT(20) +#define USBPCR_TXPREEMPHTUNE BIT(6) + +#define USBPCR_IDPULLUP_MASK GENMASK(29, 28) +#define USBPCR_IDPULLUP_ALWAYS 0x2 +#define USBPCR_IDPULLUP_SUSPEND 0x1 +#define USBPCR_IDPULLUP_OTG 0x0 + +#define USBPCR_COMPDISTUNE_MASK GENMASK(19, 17) +#define USBPCR_COMPDISTUNE_DFT 0x4 + +#define USBPCR_OTGTUNE_MASK GENMASK(16, 14) +#define USBPCR_OTGTUNE_DFT 0x4 + +#define USBPCR_SQRXTUNE_MASK GENMASK(13, 11) +#define USBPCR_SQRXTUNE_DCR_20PCT 0x7 +#define USBPCR_SQRXTUNE_DFT 0x3 + +#define USBPCR_TXFSLSTUNE_MASK GENMASK(10, 7) +#define USBPCR_TXFSLSTUNE_DCR_50PPT 0xf +#define USBPCR_TXFSLSTUNE_DCR_25PPT 0x7 +#define USBPCR_TXFSLSTUNE_DFT 0x3 +#define USBPCR_TXFSLSTUNE_INC_25PPT 0x1 +#define USBPCR_TXFSLSTUNE_INC_50PPT 0x0 + +#define USBPCR_TXHSXVTUNE_MASK GENMASK(5, 4) +#define USBPCR_TXHSXVTUNE_DFT 0x3 +#define USBPCR_TXHSXVTUNE_DCR_15MV 0x1 + +#define USBPCR_TXRISETUNE_MASK GENMASK(5, 4) +#define USBPCR_TXRISETUNE_DFT 0x3 + +#define USBPCR_TXVREFTUNE_MASK GENMASK(3, 0) +#define USBPCR_TXVREFTUNE_INC_75PPT 0xb +#define USBPCR_TXVREFTUNE_INC_25PPT 0x7 +#define USBPCR_TXVREFTUNE_DFT 0x5 + +/* bits within the USBRDTR register */ +#define USBRDT_UTMI_RST BIT(27) +#define USBRDT_HB_MASK BIT(26) +#define USBRDT_VBFIL_LD_EN BIT(25) +#define USBRDT_IDDIG_EN BIT(24) +#define USBRDT_IDDIG_REG BIT(23) +#define USBRDT_VBFIL_EN BIT(2) + +/* bits within the USBPCR1 register */ +#define USBPCR1_BVLD_REG BIT(31) +#define USBPCR1_DPPD BIT(29) +#define USBPCR1_DMPD BIT(28) +#define USBPCR1_USB_SEL BIT(28) +#define USBPCR1_PORT_RST BIT(21) +#define USBPCR1_WORD_IF_16BIT BIT(19) + +enum ingenic_usb_phy_version { + ID_JZ4770, + ID_JZ4775, + ID_JZ4780, + ID_X1000, + ID_X1830, + ID_X2000, +}; + +struct ingenic_soc_info { + enum ingenic_usb_phy_version version; + + void (*usb_phy_init)(struct phy *phy); +}; + +struct ingenic_usb_phy { + const struct ingenic_soc_info *soc_info; + + struct phy *phy; + void __iomem *base; + struct clk *clk; + struct regulator *vcc_supply; +}; + +static int ingenic_usb_phy_init(struct phy *phy) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + int err; + u32 reg; + + err = clk_prepare_enable(priv->clk); + if (err) { + dev_err(&phy->dev, "Unable to start clock: %d\n", err); + return err; + } + + priv->soc_info->usb_phy_init(phy); + + /* Wait for PHY to reset */ + usleep_range(30, 300); + reg = readl(priv->base + REG_USBPCR_OFFSET); + writel(reg & ~USBPCR_POR, priv->base + REG_USBPCR_OFFSET); + usleep_range(300, 1000); + + return 0; +} + +static int ingenic_usb_phy_exit(struct phy *phy) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + + clk_disable_unprepare(priv->clk); + regulator_disable(priv->vcc_supply); + + return 0; +} + +static int ingenic_usb_phy_power_on(struct phy *phy) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + int err; + + err = regulator_enable(priv->vcc_supply); + if (err) { + dev_err(&phy->dev, "Unable to enable VCC: %d\n", err); + return err; + } + + return 0; +} + +static int ingenic_usb_phy_power_off(struct phy *phy) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + + regulator_disable(priv->vcc_supply); + + return 0; +} + +static int ingenic_usb_phy_set_mode(struct phy *phy, + enum phy_mode mode, int submode) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + u32 reg; + + switch (mode) { + case PHY_MODE_USB_HOST: + reg = readl(priv->base + REG_USBPCR_OFFSET); + u32p_replace_bits(®, 1, USBPCR_USB_MODE); + u32p_replace_bits(®, 0, USBPCR_VBUSVLDEXT); + u32p_replace_bits(®, 0, USBPCR_VBUSVLDEXTSEL); + u32p_replace_bits(®, 0, USBPCR_OTG_DISABLE); + writel(reg, priv->base + REG_USBPCR_OFFSET); + + break; + case PHY_MODE_USB_DEVICE: + reg = readl(priv->base + REG_USBPCR_OFFSET); + u32p_replace_bits(®, 0, USBPCR_USB_MODE); + u32p_replace_bits(®, 1, USBPCR_VBUSVLDEXT); + u32p_replace_bits(®, 1, USBPCR_VBUSVLDEXTSEL); + u32p_replace_bits(®, 1, USBPCR_OTG_DISABLE); + writel(reg, priv->base + REG_USBPCR_OFFSET); + + break; + case PHY_MODE_USB_OTG: + reg = readl(priv->base + REG_USBPCR_OFFSET); + u32p_replace_bits(®, 1, USBPCR_USB_MODE); + u32p_replace_bits(®, 1, USBPCR_VBUSVLDEXT); + u32p_replace_bits(®, 1, USBPCR_VBUSVLDEXTSEL); + u32p_replace_bits(®, 0, USBPCR_OTG_DISABLE); + writel(reg, priv->base + REG_USBPCR_OFFSET); + + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct phy_ops ingenic_usb_phy_ops = { + .init = ingenic_usb_phy_init, + .exit = ingenic_usb_phy_exit, + .power_on = ingenic_usb_phy_power_on, + .power_off = ingenic_usb_phy_power_off, + .set_mode = ingenic_usb_phy_set_mode, + .owner = THIS_MODULE, +}; + +static void jz4770_usb_phy_init(struct phy *phy) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + u32 reg; + + reg = USBPCR_AVLD_REG | USBPCR_COMMONONN | USBPCR_POR | + FIELD_PREP(USBPCR_IDPULLUP_MASK, USBPCR_IDPULLUP_ALWAYS) | + FIELD_PREP(USBPCR_COMPDISTUNE_MASK, USBPCR_COMPDISTUNE_DFT) | + FIELD_PREP(USBPCR_OTGTUNE_MASK, USBPCR_OTGTUNE_DFT) | + FIELD_PREP(USBPCR_SQRXTUNE_MASK, USBPCR_SQRXTUNE_DFT) | + FIELD_PREP(USBPCR_TXFSLSTUNE_MASK, USBPCR_TXFSLSTUNE_DFT) | + FIELD_PREP(USBPCR_TXRISETUNE_MASK, USBPCR_TXRISETUNE_DFT) | + FIELD_PREP(USBPCR_TXVREFTUNE_MASK, USBPCR_TXVREFTUNE_DFT); + writel(reg, priv->base + REG_USBPCR_OFFSET); +} + +static void jz4775_usb_phy_init(struct phy *phy) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + u32 reg; + + reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_USB_SEL | + USBPCR1_WORD_IF_16BIT; + writel(reg, priv->base + REG_USBPCR1_OFFSET); + + reg = USBPCR_COMMONONN | USBPCR_POR | + FIELD_PREP(USBPCR_TXVREFTUNE_MASK, USBPCR_TXVREFTUNE_INC_75PPT); + writel(reg, priv->base + REG_USBPCR_OFFSET); +} + +static void jz4780_usb_phy_init(struct phy *phy) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + u32 reg; + + reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_USB_SEL | + USBPCR1_WORD_IF_16BIT; + writel(reg, priv->base + REG_USBPCR1_OFFSET); + + reg = USBPCR_TXPREEMPHTUNE | USBPCR_COMMONONN | USBPCR_POR; + writel(reg, priv->base + REG_USBPCR_OFFSET); +} + +static void x1000_usb_phy_init(struct phy *phy) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + u32 reg; + + reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_WORD_IF_16BIT; + writel(reg, priv->base + REG_USBPCR1_OFFSET); + + reg = USBPCR_TXPREEMPHTUNE | USBPCR_COMMONONN | USBPCR_POR | + FIELD_PREP(USBPCR_SQRXTUNE_MASK, USBPCR_SQRXTUNE_DCR_20PCT) | + FIELD_PREP(USBPCR_TXHSXVTUNE_MASK, USBPCR_TXHSXVTUNE_DCR_15MV) | + FIELD_PREP(USBPCR_TXVREFTUNE_MASK, USBPCR_TXVREFTUNE_INC_25PPT); + writel(reg, priv->base + REG_USBPCR_OFFSET); +} + +static void x1830_usb_phy_init(struct phy *phy) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + u32 reg; + + /* rdt */ + writel(USBRDT_VBFIL_EN | USBRDT_UTMI_RST, priv->base + REG_USBRDT_OFFSET); + + reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_WORD_IF_16BIT | + USBPCR1_DMPD | USBPCR1_DPPD; + writel(reg, priv->base + REG_USBPCR1_OFFSET); + + reg = USBPCR_VBUSVLDEXT | USBPCR_TXPREEMPHTUNE | USBPCR_COMMONONN | USBPCR_POR | + FIELD_PREP(USBPCR_IDPULLUP_MASK, USBPCR_IDPULLUP_OTG); + writel(reg, priv->base + REG_USBPCR_OFFSET); +} + +static void x2000_usb_phy_init(struct phy *phy) +{ + struct ingenic_usb_phy *priv = phy_get_drvdata(phy); + u32 reg; + + reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_DPPD | USBPCR1_DMPD; + writel(reg & ~USBPCR1_PORT_RST, priv->base + REG_USBPCR1_OFFSET); + + reg = USBPCR_POR | FIELD_PREP(USBPCR_IDPULLUP_MASK, USBPCR_IDPULLUP_OTG); + writel(reg, priv->base + REG_USBPCR_OFFSET); +} + +static const struct ingenic_soc_info jz4770_soc_info = { + .version = ID_JZ4770, + + .usb_phy_init = jz4770_usb_phy_init, +}; + +static const struct ingenic_soc_info jz4775_soc_info = { + .version = ID_JZ4775, + + .usb_phy_init = jz4775_usb_phy_init, +}; + +static const struct ingenic_soc_info jz4780_soc_info = { + .version = ID_JZ4780, + + .usb_phy_init = jz4780_usb_phy_init, +}; + +static const struct ingenic_soc_info x1000_soc_info = { + .version = ID_X1000, + + .usb_phy_init = x1000_usb_phy_init, +}; + +static const struct ingenic_soc_info x1830_soc_info = { + .version = ID_X1830, + + .usb_phy_init = x1830_usb_phy_init, +}; + +static const struct ingenic_soc_info x2000_soc_info = { + .version = ID_X2000, + + .usb_phy_init = x2000_usb_phy_init, +}; + +static int ingenic_usb_phy_probe(struct platform_device *pdev) +{ + struct ingenic_usb_phy *priv; + struct phy_provider *provider; + struct device *dev = &pdev->dev; + int err; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->soc_info = device_get_match_data(dev); + if (!priv->soc_info) { + dev_err(dev, "Error: No device match found\n"); + return -ENODEV; + } + + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) { + dev_err(dev, "Failed to map registers\n"); + return PTR_ERR(priv->base); + } + + priv->clk = devm_clk_get(dev, NULL); + if (IS_ERR(priv->clk)) { + err = PTR_ERR(priv->clk); + if (err != -EPROBE_DEFER) + dev_err(dev, "Failed to get clock\n"); + return err; + } + + priv->vcc_supply = devm_regulator_get(dev, "vcc"); + if (IS_ERR(priv->vcc_supply)) { + err = PTR_ERR(priv->vcc_supply); + if (err != -EPROBE_DEFER) + dev_err(dev, "Failed to get regulator\n"); + return err; + } + + priv->phy = devm_phy_create(dev, NULL, &ingenic_usb_phy_ops); + if (IS_ERR(priv)) + return PTR_ERR(priv); + + phy_set_drvdata(priv->phy, priv); + + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(provider); +} + +static const struct of_device_id ingenic_usb_phy_of_matches[] = { + { .compatible = "ingenic,jz4770-phy", .data = &jz4770_soc_info }, + { .compatible = "ingenic,jz4775-phy", .data = &jz4775_soc_info }, + { .compatible = "ingenic,jz4780-phy", .data = &jz4780_soc_info }, + { .compatible = "ingenic,x1000-phy", .data = &x1000_soc_info }, + { .compatible = "ingenic,x1830-phy", .data = &x1830_soc_info }, + { .compatible = "ingenic,x2000-phy", .data = &x2000_soc_info }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ingenic_usb_phy_of_matches); + +static struct platform_driver ingenic_usb_phy_driver = { + .probe = ingenic_usb_phy_probe, + .driver = { + .name = "ingenic-usb-phy", + .of_match_table = ingenic_usb_phy_of_matches, + }, +}; +module_platform_driver(ingenic_usb_phy_driver); + +MODULE_AUTHOR("周琰杰 (Zhou Yanjie) "); +MODULE_AUTHOR("漆鹏振 (Qi Pengzhen) "); +MODULE_AUTHOR("Paul Cercueil "); +MODULE_DESCRIPTION("Ingenic SoCs USB PHY driver"); +MODULE_LICENSE("GPL"); From a8cef928276bbf8254d0067cda21dbe6210ea1aa Mon Sep 17 00:00:00 2001 From: Chris Ruehl Date: Wed, 2 Dec 2020 16:25:06 +0800 Subject: [PATCH 67/72] phy: rockchip-emmc: output tap delay dt property Update the rockchip-emmc phy to set the otapdlysec register with a dt property. This was mentioned from Brian Norris when he sent the path to set the default value in the driver. This patch add a dt property 'output-tapdelay-select' u32 and allow to set the 0x0-0xf. If not set in dts, the old default 0x4 applies. Tested with our customized rk3399 to tune the eMMC. Signed-off-by: Chris Ruehl Link: https://lore.kernel.org/r/20201202082507.3536-2-chris.ruehl@gtsys.com.hk Signed-off-by: Vinod Koul --- drivers/phy/rockchip/phy-rockchip-emmc.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/phy/rockchip/phy-rockchip-emmc.c b/drivers/phy/rockchip/phy-rockchip-emmc.c index 48e2d75b1004..1e424f263e7a 100644 --- a/drivers/phy/rockchip/phy-rockchip-emmc.c +++ b/drivers/phy/rockchip/phy-rockchip-emmc.c @@ -65,6 +65,8 @@ #define PHYCTRL_OTAPDLYENA 0x1 #define PHYCTRL_OTAPDLYENA_MASK 0x1 #define PHYCTRL_OTAPDLYENA_SHIFT 0xb +#define PHYCTRL_OTAPDLYSEL_DEFAULT 0x4 +#define PHYCTRL_OTAPDLYSEL_MAXVALUE 0xf #define PHYCTRL_OTAPDLYSEL_MASK 0xf #define PHYCTRL_OTAPDLYSEL_SHIFT 0x7 #define PHYCTRL_REN_STRB_DISABLE 0x0 @@ -85,6 +87,7 @@ struct rockchip_emmc_phy { struct clk *emmcclk; unsigned int drive_impedance; unsigned int enable_strobe_pulldown; + unsigned int output_tapdelay_select; }; static int rockchip_emmc_phy_power(struct phy *phy, bool on_off) @@ -296,7 +299,7 @@ static int rockchip_emmc_phy_power_on(struct phy *phy) /* Output tap delay */ regmap_write(rk_phy->reg_base, rk_phy->reg_offset + GRF_EMMCPHY_CON0, - HIWORD_UPDATE(4, + HIWORD_UPDATE(rk_phy->output_tapdelay_select, PHYCTRL_OTAPDLYSEL_MASK, PHYCTRL_OTAPDLYSEL_SHIFT)); @@ -372,6 +375,7 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev) rk_phy->reg_base = grf; rk_phy->drive_impedance = PHYCTRL_DR_50OHM; rk_phy->enable_strobe_pulldown = PHYCTRL_REN_STRB_DISABLE; + rk_phy->output_tapdelay_select = PHYCTRL_OTAPDLYSEL_DEFAULT; if (!of_property_read_u32(dev->of_node, "drive-impedance-ohm", &val)) rk_phy->drive_impedance = convert_drive_impedance_ohm(pdev, val); @@ -379,6 +383,13 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev) if (of_property_read_bool(dev->of_node, "enable-strobe-pulldown")) rk_phy->enable_strobe_pulldown = PHYCTRL_REN_STRB_ENABLE; + if (!of_property_read_u32(dev->of_node, "output-tapdelay-select", &val)) { + if (val <= PHYCTRL_OTAPDLYSEL_MAXVALUE) + rk_phy->output_tapdelay_select = val; + else + dev_err(dev, "output-tapdelay-select exceeds limit, apply default\n"); + } + generic_phy = devm_phy_create(dev, dev->of_node, &ops); if (IS_ERR(generic_phy)) { dev_err(dev, "failed to create PHY\n"); From 86e21677e775bcf10d676e0e93710ce17d52fdb7 Mon Sep 17 00:00:00 2001 From: Chris Ruehl Date: Wed, 2 Dec 2020 16:25:07 +0800 Subject: [PATCH 68/72] devicetree: phy: rockchip-emmc add output-tapdelay-select Update the rockchip-emmc-phy.txt and add the u32 property 'output-tapdelay-select'. This allow to set the otapdlysec register. Tested with our customized rk3399 board to tune eMMC. Signed-off-by: Chris Ruehl Link: https://lore.kernel.org/r/20201202082507.3536-3-chris.ruehl@gtsys.com.hk Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt index 3e4d2d79a65d..00aa2d349e55 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt @@ -18,6 +18,9 @@ Optional properties: If not set, the default value of 50 will be applied. - enable-strobe-pulldown: Enable internal pull-down for the strobe line. If not set, pull-down is not used. + - output-tapdelay-select: Specifies the phyctrl_otapdlysec register. + If not set, the register defaults to 0x4. + Maximum value 0xf. Example: From af89e575152a9b6d4a3e0e5e35bf6b7075905276 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 4 Dec 2020 11:35:31 -0800 Subject: [PATCH 69/72] dt-bindings: phy: Convert Broadcom SATA PHY to YAML Update the Broadcom SATA PHY Device Tree binding to a YAML format. Suggested-by: Vinod Koul Signed-off-by: Florian Fainelli Link: https://lore.kernel.org/r/20201204193532.1934108-1-f.fainelli@gmail.com Signed-off-by: Vinod Koul --- .../bindings/phy/brcm,sata-phy.yaml | 148 ++++++++++++++++++ .../devicetree/bindings/phy/brcm-sata-phy.txt | 61 -------- 2 files changed, 148 insertions(+), 61 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml delete mode 100644 Documentation/devicetree/bindings/phy/brcm-sata-phy.txt diff --git a/Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml b/Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml new file mode 100644 index 000000000000..58c3ef8004ad --- /dev/null +++ b/Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml @@ -0,0 +1,148 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/phy/brcm,sata-phy.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Broadcom SATA3 PHY + +maintainers: + - Florian Fainelli + +properties: + $nodename: + pattern: "^sata[-|_]phy(@.*)?$" + + compatible: + oneOf: + - items: + - enum: + - brcm,bcm7216-sata-phy + - brcm,bcm7425-sata-phy + - brcm,bcm7445-sata-phy + - brcm,bcm63138-sata-phy + - const: brcm,phy-sata3 + - items: + - const: brcm,iproc-nsp-sata-phy + - items: + - const: brcm,iproc-ns2-sata-phy + - items: + - const: brcm,iproc-sr-sata-phy + + reg: + minItems: 1 + maxItems: 2 + + reg-names: + minItems: 1 + maxItems: 2 + items: + - const: phy + - const: phy-ctrl + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +patternProperties: + "^sata-phy@[0-9]+$": + type: object + description: | + Each port's PHY should be represented as a sub-node. + + properties: + reg: + description: The SATA PHY port number + maxItems: 1 + + "#phy-cells": + const: 0 + + "brcm,enable-ssc": + $ref: /schemas/types.yaml#/definitions/flag + description: | + Use spread spectrum clocking (SSC) on this port + This property is not applicable for "brcm,iproc-ns2-sata-phy", + "brcm,iproc-nsp-sata-phy" and "brcm,iproc-sr-sata-phy". + + "brcm,rxaeq-mode": + $ref: /schemas/types.yaml#/definitions/string + description: + String that indicates the desired RX equalizer mode. + enum: + - off + - auto + - manual + + "brcm,rxaeq-value": + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + When 'brcm,rxaeq-mode' is set to "manual", provides the RX + equalizer value that should be used. + minimum: 0 + maximum: 63 + + "brcm,tx-amplitude-millivolt": + description: | + Transmit amplitude voltage in millivolt. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [400, 500, 600, 800] + + required: + - reg + - "#phy-cells" + + additionalProperties: false + +if: + properties: + compatible: + items: + const: brcm,iproc-ns2-sata-phy +then: + properties: + reg: + maxItems: 2 + reg-names: + items: + - const: "phy" + - const: "phy-ctrl" +else: + properties: + reg: + maxItems: 1 + reg-names: + maxItems: 1 + items: + - const: "phy" + +required: + - compatible + - "#address-cells" + - "#size-cells" + - reg + - reg-names + +additionalProperties: false + +examples: + - | + sata_phy@f0458100 { + compatible = "brcm,bcm7445-sata-phy", "brcm,phy-sata3"; + reg = <0xf0458100 0x1e00>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + + sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + + sata-phy@1 { + reg = <1>; + #phy-cells = <0>; + }; + }; diff --git a/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt b/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt deleted file mode 100644 index e5abbace93a3..000000000000 --- a/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt +++ /dev/null @@ -1,61 +0,0 @@ -* Broadcom SATA3 PHY - -Required properties: -- compatible: should be one or more of - "brcm,bcm7216-sata-phy" - "brcm,bcm7425-sata-phy" - "brcm,bcm7445-sata-phy" - "brcm,iproc-ns2-sata-phy" - "brcm,iproc-nsp-sata-phy" - "brcm,phy-sata3" - "brcm,iproc-sr-sata-phy" - "brcm,bcm63138-sata-phy" -- address-cells: should be 1 -- size-cells: should be 0 -- reg: register ranges for the PHY PCB interface -- reg-names: should be "phy" and "phy-ctrl" - The "phy-ctrl" registers are only required for - "brcm,iproc-ns2-sata-phy" and "brcm,iproc-sr-sata-phy". - -Sub-nodes: - Each port's PHY should be represented as a sub-node. - -Sub-nodes required properties: -- reg: the PHY number -- phy-cells: generic PHY binding; must be 0 - -Sub-nodes optional properties: -- brcm,enable-ssc: use spread spectrum clocking (SSC) on this port - This property is not applicable for "brcm,iproc-ns2-sata-phy", - "brcm,iproc-nsp-sata-phy" and "brcm,iproc-sr-sata-phy". - -- brcm,rxaeq-mode: string that indicates the desired RX equalizer - mode, possible values are: - "off" (equivalent to not specifying the property) - "auto" - "manual" (brcm,rxaeq-value is used in that case) - -- brcm,rxaeq-value: when 'rxaeq-mode' is set to "manual", provides the RX - equalizer value that should be used. Allowed range is 0..63. - -- brcm,tx-amplitude-millivolt: transmit amplitude voltage in millivolt. - Possible values are 400, 500, 600 or 800 mV. - -Example - sata-phy@f0458100 { - compatible = "brcm,bcm7445-sata-phy", "brcm,phy-sata3"; - reg = <0xf0458100 0x1e00>, <0xf045804c 0x10>; - reg-names = "phy"; - #address-cells = <1>; - #size-cells = <0>; - - sata-phy@0 { - reg = <0>; - #phy-cells = <0>; - }; - - sata-phy@1 { - reg = <1>; - #phy-cells = <0>; - }; - }; From 18b648322d44e8d8950de8aa31dba9bad0a33b89 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Sat, 5 Dec 2020 14:41:46 +0530 Subject: [PATCH 70/72] phy: mediatek: statify mtk_hdmi_phy_driver mtk_hdmi_phy_driver is not declared as static, so statify it. drivers/phy/mediatek/phy-mtk-hdmi.c:204:24: warning: symbol 'mtk_hdmi_phy_driver' was not declared. Should it be static? Acked-by: Chun-Kuang Hu Link: https://lore.kernel.org/r/20201205091146.3184305-1-vkoul@kernel.org Signed-off-by: Vinod Koul --- drivers/phy/mediatek/phy-mtk-hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c index 47c029d4b270..c5c61f5a9ea0 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi.c @@ -201,7 +201,7 @@ static const struct of_device_id mtk_hdmi_phy_match[] = { {}, }; -struct platform_driver mtk_hdmi_phy_driver = { +static struct platform_driver mtk_hdmi_phy_driver = { .probe = mtk_hdmi_phy_probe, .driver = { .name = "mediatek-hdmi-phy", From 1dfd7b7849ea8bdbbe26d280d7b43c4ae66e730f Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 8 Dec 2020 10:23:00 +0530 Subject: [PATCH 71/72] phy: ingenic: depend on HAS_IOMEM The driver uses devm_ioremap_resource() which will not be built if CONFIG_HAS_IOMEM is not selected, so add depends on it to fix the build failure on few archs s390-linux-ld: drivers/phy/ingenic/phy-ingenic-usb.o: in function `ingenic_usb_phy_probe': >> phy-ingenic-usb.c:(.text+0xb66): undefined reference to `devm_platform_ioremap_resource' Reported-by: kernel test robot Link: https://lore.kernel.org/r/20201208045300.3637026-1-vkoul@kernel.org Signed-off-by: Vinod Koul --- drivers/phy/ingenic/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/ingenic/Kconfig b/drivers/phy/ingenic/Kconfig index 912b14e512cb..f23cc109324b 100644 --- a/drivers/phy/ingenic/Kconfig +++ b/drivers/phy/ingenic/Kconfig @@ -6,6 +6,7 @@ config PHY_INGENIC_USB tristate "Ingenic SoCs USB PHY Driver" depends on MIPS || COMPILE_TEST depends on USB_SUPPORT + depends on HAS_IOMEM select GENERIC_PHY help This driver provides USB PHY support for the USB controller found From b097efba9580d1f7cbc80cda84e768983e3de541 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 7 Dec 2020 15:09:37 +0000 Subject: [PATCH 72/72] drm/mediatek: avoid dereferencing a null hdmi_phy on an error message Currently there is a null pointer check for hdmi_phy that implies it may be null, however a dev_err messages dereferences this potential null pointer. Avoid a null pointer dereference by only emitting the dev_err message if hdmi_phy is non-null. It is a moot point if the error message needs to be printed at all, but since this is a relatively new piece of code it may be useful to keep the message in for the moment in case there are unforseen errors that need to be reported. Fixes: be28b6507c46 ("drm/mediatek: separate hdmi phy to different file") Signed-off-by: Colin Ian King Addresses-Coverity: ("Dereference after null check") Link: https://lore.kernel.org/r/20201207150937.170435-1-colin.king@canonical.com [vkoul: fix indent of return call] Signed-off-by: Vinod Koul --- drivers/phy/mediatek/phy-mtk-hdmi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c index c5c61f5a9ea0..45be8aa724f3 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi.c @@ -84,8 +84,9 @@ mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy) hdmi_phy->conf->hdmi_phy_disable_tmds) return &mtk_hdmi_phy_dev_ops; - dev_err(hdmi_phy->dev, "Failed to get dev ops of phy\n"); - return NULL; + if (hdmi_phy) + dev_err(hdmi_phy->dev, "Failed to get dev ops of phy\n"); + return NULL; } static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy,