All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kishon Vijay Abraham I <kishon@ti.com>
To: "Bryan O'Donoghue" <bryan.odonoghue@linaro.org>,
	<linux-arm-msm@vger.kernel.org>, <linux-usb@vger.kernel.org>,
	<gregkh@linuxfoundation.org>, <jackp@codeaurora.org>,
	<balbi@kernel.org>, <bjorn.andersson@linaro.org>,
	<robh@kernel.org>
Cc: <linux-kernel@vger.kernel.org>,
	Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>,
	Jorge Ramirez-Ortiz <jorge.ramirez.ortiz@gmail.com>,
	"Sriharsha Allenki's" <sallenki@codeaurora.org>,
	Andy Gross <agross@kernel.org>,
	Philipp Zabel <p.zabel@pengutronix.de>
Subject: Re: [PATCH v7 05/18] phy: qualcomm: usb: Add SuperSpeed PHY driver
Date: Mon, 9 Mar 2020 16:19:20 +0530	[thread overview]
Message-ID: <03b4e0cd-bd1d-29fc-7cb7-f06bba5783ee@ti.com> (raw)
In-Reply-To: <20200303171159.246992-6-bryan.odonoghue@linaro.org>

Hi,

On 03/03/20 10:41 pm, Bryan O'Donoghue wrote:
> From: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
> 
> Controls Qualcomm's SS PHY 1.0.0 implemented on various SoCs on both the
> 20nm and 28nm process nodes.
> 
> Based on Sriharsha Allenki's <sallenki@codeaurora.org> original code.
> 
> [bod: Removed dependency on extcon.
>       Switched to gpio-usb-conn to handle VBUS On/Off
>       Switched to usb-role-switch to bind gpio-usb-conn to DWC3]
> Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
> Cc: Jorge Ramirez-Ortiz <jorge.ramirez.ortiz@gmail.com>
> Cc: Sriharsha Allenki's <sallenki@codeaurora.org>
> Cc: Andy Gross <agross@kernel.org>
> Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> Cc: linux-arm-msm@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>

I only have 02, 03, and 05 of this patch series. Can you split the
series and send all the patches targeted to PHY tree separately?

Thanks
Kishon

> ---
>  drivers/phy/qualcomm/Kconfig           |   9 +
>  drivers/phy/qualcomm/Makefile          |   1 +
>  drivers/phy/qualcomm/phy-qcom-usb-ss.c | 246 +++++++++++++++++++++++++
>  3 files changed, 256 insertions(+)
>  create mode 100644 drivers/phy/qualcomm/phy-qcom-usb-ss.c
> 
> diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig
> index 9c56a7216f72..98674ed094d9 100644
> --- a/drivers/phy/qualcomm/Kconfig
> +++ b/drivers/phy/qualcomm/Kconfig
> @@ -102,3 +102,12 @@ config PHY_QCOM_USB_HS_28NM
>  	  High-Speed PHY driver. This driver supports the Hi-Speed PHY which
>  	  is usually paired with either the ChipIdea or Synopsys DWC3 USB
>  	  IPs on MSM SOCs.
> +
> +config PHY_QCOM_USB_SS
> +	tristate "Qualcomm USB Super-Speed PHY driver"
> +	depends on ARCH_QCOM || COMPILE_TEST
> +	depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in
> +	select GENERIC_PHY
> +	help
> +	  Enable this to support the Super-Speed USB transceiver on various
> +	  Qualcomm chipsets.
> diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile
> index a4dab5329de0..1f14aeacbd70 100644
> --- a/drivers/phy/qualcomm/Makefile
> +++ b/drivers/phy/qualcomm/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_PHY_QCOM_UFS_20NM)		+= phy-qcom-ufs-qmp-20nm.o
>  obj-$(CONFIG_PHY_QCOM_USB_HS) 		+= phy-qcom-usb-hs.o
>  obj-$(CONFIG_PHY_QCOM_USB_HSIC) 	+= phy-qcom-usb-hsic.o
>  obj-$(CONFIG_PHY_QCOM_USB_HS_28NM)	+= phy-qcom-usb-hs-28nm.o
> +obj-$(CONFIG_PHY_QCOM_USB_SS)		+= phy-qcom-usb-ss.o
> diff --git a/drivers/phy/qualcomm/phy-qcom-usb-ss.c b/drivers/phy/qualcomm/phy-qcom-usb-ss.c
> new file mode 100644
> index 000000000000..a3a6d3ce7ea1
> --- /dev/null
> +++ b/drivers/phy/qualcomm/phy-qcom-usb-ss.c
> @@ -0,0 +1,246 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2012-2014,2017 The Linux Foundation. All rights reserved.
> + * Copyright (c) 2018-2020, Linaro Limited
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
> +#include <linux/slab.h>
> +
> +#define PHY_CTRL0			0x6C
> +#define PHY_CTRL1			0x70
> +#define PHY_CTRL2			0x74
> +#define PHY_CTRL4			0x7C
> +
> +/* PHY_CTRL bits */
> +#define REF_PHY_EN			BIT(0)
> +#define LANE0_PWR_ON			BIT(2)
> +#define SWI_PCS_CLK_SEL			BIT(4)
> +#define TST_PWR_DOWN			BIT(4)
> +#define PHY_RESET			BIT(7)
> +
> +#define NUM_BULK_CLKS			3
> +#define NUM_BULK_REGS			2
> +
> +struct ssphy_priv {
> +	void __iomem *base;
> +	struct device *dev;
> +	struct reset_control *reset_com;
> +	struct reset_control *reset_phy;
> +	struct regulator_bulk_data regs[NUM_BULK_REGS];
> +	struct clk_bulk_data clks[NUM_BULK_CLKS];
> +	enum phy_mode mode;
> +};
> +
> +static inline void qcom_ssphy_updatel(void __iomem *addr, u32 mask, u32 val)
> +{
> +	writel((readl(addr) & ~mask) | val, addr);
> +}
> +
> +static int qcom_ssphy_do_reset(struct ssphy_priv *priv)
> +{
> +	int ret;
> +
> +	if (!priv->reset_com) {
> +		qcom_ssphy_updatel(priv->base + PHY_CTRL1, PHY_RESET,
> +				   PHY_RESET);
> +		usleep_range(10, 20);
> +		qcom_ssphy_updatel(priv->base + PHY_CTRL1, PHY_RESET, 0);
> +	} else {
> +		ret = reset_control_assert(priv->reset_com);
> +		if (ret) {
> +			dev_err(priv->dev, "Failed to assert reset com\n");
> +			return ret;
> +		}
> +
> +		ret = reset_control_assert(priv->reset_phy);
> +		if (ret) {
> +			dev_err(priv->dev, "Failed to assert reset phy\n");
> +			return ret;
> +		}
> +
> +		usleep_range(10, 20);
> +
> +		ret = reset_control_deassert(priv->reset_com);
> +		if (ret) {
> +			dev_err(priv->dev, "Failed to deassert reset com\n");
> +			return ret;
> +		}
> +
> +		ret = reset_control_deassert(priv->reset_phy);
> +		if (ret) {
> +			dev_err(priv->dev, "Failed to deassert reset phy\n");
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_ssphy_power_on(struct phy *phy)
> +{
> +	struct ssphy_priv *priv = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = regulator_bulk_enable(NUM_BULK_REGS, priv->regs);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_bulk_prepare_enable(NUM_BULK_CLKS, priv->clks);
> +	if (ret)
> +		goto err_disable_regulator;
> +
> +	ret = qcom_ssphy_do_reset(priv);
> +	if (ret)
> +		goto err_disable_clock;
> +
> +	writeb(SWI_PCS_CLK_SEL, priv->base + PHY_CTRL0);
> +	qcom_ssphy_updatel(priv->base + PHY_CTRL4, LANE0_PWR_ON, LANE0_PWR_ON);
> +	qcom_ssphy_updatel(priv->base + PHY_CTRL2, REF_PHY_EN, REF_PHY_EN);
> +	qcom_ssphy_updatel(priv->base + PHY_CTRL4, TST_PWR_DOWN, 0);
> +
> +	return 0;
> +err_disable_clock:
> +	clk_bulk_disable_unprepare(NUM_BULK_CLKS, priv->clks);
> +err_disable_regulator:
> +	regulator_bulk_disable(NUM_BULK_REGS, priv->regs);
> +
> +	return ret;
> +}
> +
> +static int qcom_ssphy_power_off(struct phy *phy)
> +{
> +	struct ssphy_priv *priv = phy_get_drvdata(phy);
> +
> +	qcom_ssphy_updatel(priv->base + PHY_CTRL4, LANE0_PWR_ON, 0);
> +	qcom_ssphy_updatel(priv->base + PHY_CTRL2, REF_PHY_EN, 0);
> +	qcom_ssphy_updatel(priv->base + PHY_CTRL4, TST_PWR_DOWN, TST_PWR_DOWN);
> +
> +	clk_bulk_disable_unprepare(NUM_BULK_CLKS, priv->clks);
> +	regulator_bulk_disable(NUM_BULK_REGS, priv->regs);
> +
> +	return 0;
> +}
> +
> +static int qcom_ssphy_init_clock(struct ssphy_priv *priv)
> +{
> +	priv->clks[0].id = "ref";
> +	priv->clks[1].id = "ahb";
> +	priv->clks[2].id = "pipe";
> +
> +	return devm_clk_bulk_get(priv->dev, NUM_BULK_CLKS, priv->clks);
> +}
> +
> +static int qcom_ssphy_init_regulator(struct ssphy_priv *priv)
> +{
> +	int ret;
> +
> +	priv->regs[0].supply = "vdd";
> +	priv->regs[1].supply = "vdda1p8";
> +	ret = devm_regulator_bulk_get(priv->dev, NUM_BULK_REGS, priv->regs);
> +	if (ret) {
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(priv->dev, "Failed to get regulators\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +static int qcom_ssphy_init_reset(struct ssphy_priv *priv)
> +{
> +	priv->reset_com = devm_reset_control_get_optional_exclusive(priv->dev, "com");
> +	if (IS_ERR(priv->reset_com)) {
> +		dev_err(priv->dev, "Failed to get reset control com\n");
> +		return PTR_ERR(priv->reset_com);
> +	}
> +
> +	if (priv->reset_com) {
> +		/* if reset_com is present, reset_phy is no longer optional */
> +		priv->reset_phy = devm_reset_control_get_exclusive(priv->dev, "phy");
> +		if (IS_ERR(priv->reset_phy)) {
> +			dev_err(priv->dev, "Failed to get reset control phy\n");
> +			return PTR_ERR(priv->reset_phy);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops qcom_ssphy_ops = {
> +	.power_off = qcom_ssphy_power_off,
> +	.power_on = qcom_ssphy_power_on,
> +	.owner = THIS_MODULE,
> +};
> +
> +static int qcom_ssphy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct phy_provider *provider;
> +	struct ssphy_priv *priv;
> +	struct phy *phy;
> +	int ret;
> +
> +	priv = devm_kzalloc(dev, sizeof(struct ssphy_priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->dev = dev;
> +	priv->mode = PHY_MODE_INVALID;
> +
> +	priv->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(priv->base))
> +		return PTR_ERR(priv->base);
> +
> +	ret = qcom_ssphy_init_clock(priv);
> +	if (ret)
> +		return ret;
> +
> +	ret = qcom_ssphy_init_reset(priv);
> +	if (ret)
> +		return ret;
> +
> +	ret = qcom_ssphy_init_regulator(priv);
> +	if (ret)
> +		return ret;
> +
> +	phy = devm_phy_create(dev, dev->of_node, &qcom_ssphy_ops);
> +	if (IS_ERR(phy)) {
> +		dev_err(dev, "Failed to create the SS phy\n");
> +		return PTR_ERR(phy);
> +	}
> +
> +	phy_set_drvdata(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 qcom_ssphy_match[] = {
> +	{ .compatible = "qcom,usb-ss-28nm-phy", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, qcom_ssphy_match);
> +
> +static struct platform_driver qcom_ssphy_driver = {
> +	.probe		= qcom_ssphy_probe,
> +	.driver = {
> +		.name	= "qcom-usb-ssphy",
> +		.of_match_table = qcom_ssphy_match,
> +	},
> +};
> +module_platform_driver(qcom_ssphy_driver);
> +
> +MODULE_DESCRIPTION("Qualcomm SuperSpeed USB PHY driver");
> +MODULE_LICENSE("GPL v2");
> 

  reply	other threads:[~2020-03-09 10:45 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-03 17:11 [PATCH v7 00/18] Enable Qualcomm QCS 404 HS/SS USB Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 01/18] dt-bindings: phy: remove qcom-dwc3-usb-phy Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 02/18] dt-bindings: phy: Add Qualcomm Synopsys Hi-Speed USB PHY binding Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 03/18] phy: qualcomm: Add Synopsys 28nm Hi-Speed USB PHY driver Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 04/18] dt-bindings: Add Qualcomm USB SuperSpeed PHY bindings Bryan O'Donoghue
2020-03-04 16:17   ` Rob Herring
2020-03-03 17:11 ` [PATCH v7 05/18] phy: qualcomm: usb: Add SuperSpeed PHY driver Bryan O'Donoghue
2020-03-09 10:49   ` Kishon Vijay Abraham I [this message]
2020-03-03 17:11 ` [PATCH v7 06/18] usb: dwc3: Registering a role switch in the DRD code Bryan O'Donoghue
2020-03-07  7:20   ` Bjorn Andersson
2020-03-03 17:11 ` [PATCH v7 07/18] dt-bindings: usb: dwc3: Add a gpio-usb-connector example Bryan O'Donoghue
2020-03-04 14:57   ` Rob Herring
2020-03-04 16:24     ` Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 08/18] dt-bindings: usb: dwc3: Add a usb-role-switch to the example Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 09/18] usb: dwc3: qcom: Add support for usb-conn-gpio connectors Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 10/18] usb: dwc3: " Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 11/18] usb: dwc3: Add support for a role-switch notifier Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 12/18] usb: dwc3: qcom: Enable gpio-usb-conn based role-switching Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 13/18] arm64: dts: qcom: qcs404: Add USB devices and PHYs Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 14/18] arm64: dts: qcom: qcs404-evb: Define VBUS pins Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 15/18] arm64: dts: qcom: qcs404-evb: Define USB ID pin Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 16/18] arm64: dts: qcom: qcs404-evb: Describe external VBUS regulator Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 17/18] arm64: dts: qcom: qcs404-evb: Raise vreg_l12_3p3 minimum voltage Bryan O'Donoghue
2020-03-03 17:11 ` [PATCH v7 18/18] arm64: dts: qcom: qcs404-evb: Enable USB controllers Bryan O'Donoghue
2020-03-08  5:23 ` [PATCH v7 00/18] Enable Qualcomm QCS 404 HS/SS USB Bjorn Andersson
2020-03-09  0:02   ` Bryan O'Donoghue

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=03b4e0cd-bd1d-29fc-7cb7-f06bba5783ee@ti.com \
    --to=kishon@ti.com \
    --cc=agross@kernel.org \
    --cc=balbi@kernel.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=bryan.odonoghue@linaro.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jackp@codeaurora.org \
    --cc=jorge.ramirez-ortiz@linaro.org \
    --cc=jorge.ramirez.ortiz@gmail.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=p.zabel@pengutronix.de \
    --cc=robh@kernel.org \
    --cc=sallenki@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.