Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1616891 > unrolled thread
| Started by | Vivek Gautam <vivek.gautam@codeaurora.org> |
|---|---|
| First post | 2017-04-05 14:40 +0200 |
| Last post | 2017-04-06 01:00 +0200 |
| Articles | 7 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH V7 0/4] phy: USB and PCIe phy drivers for Qcom chipsets Vivek Gautam <vivek.gautam@codeaurora.org> - 2017-04-05 14:40 +0200
[PATCH V7 2/4] phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips Vivek Gautam <vivek.gautam@codeaurora.org> - 2017-04-05 14:40 +0200
[PATCH V7 3/4] dt-bindings: phy: Add support for QMP phy Vivek Gautam <vivek.gautam@codeaurora.org> - 2017-04-05 14:40 +0200
Re: [PATCH V7 3/4] dt-bindings: phy: Add support for QMP phy Stephen Boyd <sboyd@codeaurora.org> - 2017-04-06 01:00 +0200
Re: [PATCH V7 0/4] phy: USB and PCIe phy drivers for Qcom chipsets Kishon Vijay Abraham I <kishon@ti.com> - 2017-04-05 15:50 +0200
Re: [PATCH V7 0/4] phy: USB and PCIe phy drivers for Qcom chipsets Vivek Gautam <vivek.gautam@codeaurora.org> - 2017-04-05 17:30 +0200
Re: [PATCH V7 4/4] phy: qcom-qmp: new qmp phy driver for qcom-chipsets Stephen Boyd <sboyd@codeaurora.org> - 2017-04-06 01:00 +0200
| From | Vivek Gautam <vivek.gautam@codeaurora.org> |
|---|---|
| Date | 2017-04-05 14:40 +0200 |
| Subject | [PATCH V7 0/4] phy: USB and PCIe phy drivers for Qcom chipsets |
| Message-ID | <tsSo9-2BK-9@gated-at.bofh.it> |
This patch series adds couple of PHY drivers for Qualcomm chipsets.
a) qcom-qusb2 phy driver: that provides High Speed USB functionality.
b) qcom-qmp phy driver: that is a combo phy providing support for
USB3, PCIe, UFS and few other controllers.
The patches are based on next branch of linux-phy tree.
These patches have been tested on Dragon board db820c hardware with
required set of dt patches and the patches to get rpm up on msm8996.
Couple of other patches [1, 2] fixing DMA config for XHCI are also
pulled in for testing.
A branch based on torvald's master is available in github [3].
Changes since v6:
- Rebased on phy/next and *not* including phy grouping series[4].
- qusb2-phy: addressed Stephen's comment.
- Dropped pm8994_s2 corner regulator from QUSB2 phy bindings.
- qmp-phy: none on functionality side.
Changes since v5:
- Addressed review comments from Bjorn:
- Removed instances of readl/wirtel_relaxed calls from the drivers.
Instead, using simple readl/writel. Inserting a readl after a writel
to ensure the write is through to the device.
- Replaced regulator handling with regulator_bulk_** apis. This helps
in cutting down a lot of regulator handling code.
- Fixed minor return statements.
Changes since v4:
- Addressed comment to add child nodes for qmp phy driver. Each phy lane
now has a separate child node under the main qmp node.
- Modified the clock and reset initialization and enable methods.
Different phys - pcie, usb and later ufs, have varying number of clocks
and resets that are mandatory. So adding provision for clocks and reset
lists helps in requesting all mandatory resources for individual phys
and handle their failure cases accordingly.
Changes since v3:
- Addressed review comments given by Rob and Stephen for qusb2 phy
and qmp phy bindings respectively.
- Addressed review comments given by Stephen and Bjorn for qmp phy driver.
Changes since v2:
- Addressed review comments given by Rob and Stephen for bindings.
- Addressed the review comments given by Stephen for the qusb2 and qmp
phy drivers.
Changes since v1:
- Moved device tree binding documentation to separate patches, as suggested
by Rob.
- Addressed review comment regarding qfprom accesses by qusb2 phy driver,
given by Rob.
- Addressed review comments from Kishon.
- Addressed review comments from Srinivas for QMP phy driver.
- Addressed kbuild warning.
Please see individual patches for detailed changelogs.
[1] https://patchwork.kernel.org/patch/9567767/
[2] https://patchwork.kernel.org/patch/9567779/
[3] https://github.com/vivekgautam1/linux/tree/linux-v4.11-rc5-qmp-phy-db820c
[4] https://lkml.org/lkml/2017/3/20/407
Vivek Gautam (4):
dt-bindings: phy: Add support for QUSB2 phy
phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips
dt-bindings: phy: Add support for QMP phy
phy: qcom-qmp: new qmp phy driver for qcom-chipsets
.../devicetree/bindings/phy/qcom-qmp-phy.txt | 106 ++
.../devicetree/bindings/phy/qcom-qusb2-phy.txt | 43 +
drivers/phy/Kconfig | 18 +
drivers/phy/Makefile | 2 +
drivers/phy/phy-qcom-qmp.c | 1153 ++++++++++++++++++++
drivers/phy/phy-qcom-qusb2.c | 491 +++++++++
6 files changed, 1813 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
create mode 100644 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
create mode 100644 drivers/phy/phy-qcom-qmp.c
create mode 100644 drivers/phy/phy-qcom-qusb2.c
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [next] | [standalone]
| From | Vivek Gautam <vivek.gautam@codeaurora.org> |
|---|---|
| Date | 2017-04-05 14:40 +0200 |
| Subject | [PATCH V7 2/4] phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips |
| Message-ID | <tsSoa-2BK-13@gated-at.bofh.it> |
| In reply to | #1616891 |
PHY transceiver driver for QUSB2 phy controller that provides
HighSpeed functionality for DWC3 controller present on
Qualcomm chipsets.
Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
---
Changes since v6:
- Dropped 'vdd-phy' from list of regulators.
- Rebased on phy/next and *not* including phy grouping series.
Changes since v5:
- Rebased on top of phy grouping series. So the driver now sits in
drivers/phy/qualcomm/
- Removed instances of readl_relaxed() and writel_relaxed(), and using
readl() and writel() instead.
- Replaced regulator handling with regulator_bulk() apis, so that
qusb2_phy_toggle_power() method is completely dropped.
- Removed memory barriers from the driver. Instead, using readl() over
the register to ensure that the write is through to the device.
- Fixed nits about return statement from probe() and qusb2_phy_poweron().
Changes since v4:
- Updated the copyright year to 2017.
- Removed unnecessary of_match_ptr() cast for the match table,
since the driver is compiled for CONFIG_OF.
Changes since v3:
- Added 'Reviewed-by' from Stephen.
- Fixed debug message for qusb2_phy_set_tune2_param().
- Replaced devm_reset_control_get() with devm_reset_control_get_by_index()
since we are requesting only one reset.
- Updated devm_nvmem_cell_get() with a NULL cell id.
- Made error labels more idiomatic.
- Refactored qusb2_setbits() and qusb2_clrbits() a little bit to accept
base address and register offset as two separate arguments.
Changes since v2:
- Removed selecting 'RESET_CONTROLLER' config.
- Added error handling for clk_prepare_enable paths.
- Removed explicitly setting ref_clk rate to 19.2 MHz. Don't need to
do that since 'xo' is modeled as parent to this clock.
- Removed 'ref_clk_src' handling. Driver doesn't need to request and
handle this clock.
- Moved nvmem_cell_get() to probe function.
- Simplified phy pll status handling.
- Using of_device_get_match_data() to get match data.
- Uniformly using lowercase for hex numbers.
- Fixed sparse warnings.
- Using shorter variable names in structure and in functions.
- Handling various comment style shortcomings.
Changes since v1:
- removed reference to clk_enabled/pwr_enabled.
- moved clock and regulator enable code to phy_power_on/off() callbacks.
- fixed return on EPROBE_DEFER in qusb2_phy_probe().
- fixed phy create and phy register ordering.
- removed references to non-lkml links from commit message.
- took care of other minor nits.
- Fixed coccinelle warnings -
'PTR_ERR applied after initialization to constant'
- Addressed review comment, regarding qfprom access for tune2 param value.
This driver is now based on qfprom patch[1] that allows byte access now.
drivers/phy/Kconfig | 10 +
drivers/phy/Makefile | 1 +
drivers/phy/phy-qcom-qusb2.c | 491 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 502 insertions(+)
create mode 100644 drivers/phy/phy-qcom-qusb2.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index dc5277ad1b5a..ccc9178e32cd 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -439,6 +439,16 @@ config PHY_STIH407_USB
Enable this support to enable the picoPHY device used by USB2
and USB3 controllers on STMicroelectronics STiH407 SoC families.
+config PHY_QCOM_QUSB2
+ tristate "Qualcomm QUSB2 PHY Driver"
+ depends on OF && (ARCH_QCOM || COMPILE_TEST)
+ select GENERIC_PHY
+ help
+ Enable this to support the HighSpeed QUSB2 PHY transceiver for USB
+ controllers on Qualcomm chips. This driver supports the high-speed
+ PHY which is usually paired with either the ChipIdea or Synopsys DWC3
+ USB IPs on MSM SOCs.
+
config PHY_QCOM_UFS
tristate "Qualcomm UFS PHY driver"
depends on OF && ARCH_QCOM
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index e7b0feb1e125..0375c6a32697 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
+obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o
diff --git a/drivers/phy/phy-qcom-qusb2.c b/drivers/phy/phy-qcom-qusb2.c
new file mode 100644
index 000000000000..045b0743a033
--- /dev/null
+++ b/drivers/phy/phy-qcom-qusb2.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#define QUSB2PHY_PLL_TEST 0x04
+#define CLK_REF_SEL BIT(7)
+
+#define QUSB2PHY_PLL_TUNE 0x08
+#define QUSB2PHY_PLL_USER_CTL1 0x0c
+#define QUSB2PHY_PLL_USER_CTL2 0x10
+#define QUSB2PHY_PLL_AUTOPGM_CTL1 0x1c
+#define QUSB2PHY_PLL_PWR_CTRL 0x18
+
+#define QUSB2PHY_PLL_STATUS 0x38
+#define PLL_LOCKED BIT(5)
+
+#define QUSB2PHY_PORT_TUNE1 0x80
+#define QUSB2PHY_PORT_TUNE2 0x84
+#define QUSB2PHY_PORT_TUNE3 0x88
+#define QUSB2PHY_PORT_TUNE4 0x8c
+#define QUSB2PHY_PORT_TUNE5 0x90
+#define QUSB2PHY_PORT_TEST2 0x9c
+
+#define QUSB2PHY_PORT_POWERDOWN 0xb4
+#define CLAMP_N_EN BIT(5)
+#define FREEZIO_N BIT(1)
+#define POWER_DOWN BIT(0)
+
+#define QUSB2PHY_REFCLK_ENABLE BIT(0)
+
+#define PHY_CLK_SCHEME_SEL BIT(0)
+
+struct qusb2_phy_init_tbl {
+ unsigned int offset;
+ unsigned int val;
+};
+#define QUSB2_PHY_INIT_CFG(o, v) \
+ { \
+ .offset = o, \
+ .val = v, \
+ }
+
+static const struct qusb2_phy_init_tbl msm8996_init_tbl[] = {
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE1, 0xf8),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE2, 0xb3),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE3, 0x83),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE4, 0xc0),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TEST2, 0x14),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
+};
+
+struct qusb2_phy_cfg {
+ const struct qusb2_phy_init_tbl *tbl;
+ /* number of entries in the table */
+ unsigned int tbl_num;
+ /* offset to PHY_CLK_SCHEME register in TCSR map */
+ unsigned int clk_scheme_offset;
+};
+
+static const struct qusb2_phy_cfg msm8996_phy_cfg = {
+ .tbl = msm8996_init_tbl,
+ .tbl_num = ARRAY_SIZE(msm8996_init_tbl),
+};
+
+static const char * const qusb2_phy_vreg_names[] = {
+ "vdda-pll", "vdda-phy-dpdm",
+};
+#define QUSB2_NUM_VREGS ARRAY_SIZE(qusb2_phy_vreg_names)
+
+/**
+ * struct qusb2_phy - structure holding qusb2 phy attributes
+ *
+ * @phy: generic phy
+ * @base: iomapped memory space for qubs2 phy
+ *
+ * @cfg_ahb_clk: AHB2PHY interface clock
+ * @ref_clk: phy reference clock
+ * @iface_clk: phy interface clock
+ * @phy_reset: phy reset control
+ * @vregs: regulator supplies bulk data
+ *
+ * @tcsr: TCSR syscon register map
+ * @cell: nvmem cell containing phy tuning value
+ *
+ * @cfg: phy config data
+ * @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
+ */
+struct qusb2_phy {
+ struct phy *phy;
+ void __iomem *base;
+
+ struct clk *cfg_ahb_clk;
+ struct clk *ref_clk;
+ struct clk *iface_clk;
+ struct reset_control *phy_reset;
+ struct regulator_bulk_data vregs[QUSB2_NUM_VREGS];
+
+ struct regmap *tcsr;
+ struct nvmem_cell *cell;
+
+ const struct qusb2_phy_cfg *cfg;
+ bool has_se_clk_scheme;
+};
+
+static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
+{
+ u32 reg;
+
+ reg = readl(base + offset);
+ reg |= val;
+ writel(reg, base + offset);
+
+ /* Ensure above write is completed */
+ readl(base + offset);
+}
+
+static inline void qusb2_clrbits(void __iomem *base, u32 offset, u32 val)
+{
+ u32 reg;
+
+ reg = readl(base + offset);
+ reg &= ~val;
+ writel(reg, base + offset);
+
+ /* Ensure above write is completed */
+ readl(base + offset);
+}
+
+static inline void qcom_qusb2_phy_configure(void __iomem *base,
+ const struct qusb2_phy_init_tbl tbl[],
+ int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ writel(tbl[i].val, base + tbl[i].offset);
+}
+
+/*
+ * Fetches HS Tx tuning value from nvmem and sets the
+ * QUSB2PHY_PORT_TUNE2 register.
+ * For error case, skip setting the value and use the default value.
+ */
+static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy)
+{
+ struct device *dev = &qphy->phy->dev;
+ u8 *val;
+
+ /*
+ * Read efuse register having TUNE2 parameter's high nibble.
+ * If efuse register shows value as 0x0, or if we fail to find
+ * a valid efuse register settings, then use default value
+ * as 0xB for high nibble that we have already set while
+ * configuring phy.
+ */
+ val = nvmem_cell_read(qphy->cell, NULL);
+ if (IS_ERR(val) || !val[0]) {
+ dev_dbg(dev, "failed to read a valid hs-tx trim value\n");
+ return;
+ }
+
+ /* Fused TUNE2 value is the higher nibble only */
+ qusb2_setbits(qphy->base, QUSB2PHY_PORT_TUNE2, val[0] << 0x4);
+}
+
+static int qusb2_phy_poweron(struct phy *phy)
+{
+ struct qusb2_phy *qphy = phy_get_drvdata(phy);
+ int num = ARRAY_SIZE(qphy->vregs);
+ int ret;
+
+ dev_vdbg(&phy->dev, "%s(): Powering-on QUSB2 phy\n", __func__);
+
+ /* turn on regulator supplies */
+ ret = regulator_bulk_enable(num, qphy->vregs);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(qphy->iface_clk);
+ if (ret) {
+ dev_err(&phy->dev, "failed to enable iface_clk, %d\n", ret);
+ regulator_bulk_disable(num, qphy->vregs);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int qusb2_phy_poweroff(struct phy *phy)
+{
+ struct qusb2_phy *qphy = phy_get_drvdata(phy);
+
+ clk_disable_unprepare(qphy->iface_clk);
+
+ regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
+
+ return 0;
+}
+
+static int qusb2_phy_init(struct phy *phy)
+{
+ struct qusb2_phy *qphy = phy_get_drvdata(phy);
+ unsigned int val;
+ unsigned int clk_scheme;
+ int ret;
+
+ dev_vdbg(&phy->dev, "%s(): Initializing QUSB2 phy\n", __func__);
+
+ /* enable ahb interface clock to program phy */
+ ret = clk_prepare_enable(qphy->cfg_ahb_clk);
+ if (ret) {
+ dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret);
+ return ret;
+ }
+
+ /* Perform phy reset */
+ ret = reset_control_assert(qphy->phy_reset);
+ if (ret) {
+ dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret);
+ goto disable_ahb_clk;
+ }
+
+ /* 100 us delay to keep PHY in reset mode */
+ usleep_range(100, 150);
+
+ ret = reset_control_deassert(qphy->phy_reset);
+ if (ret) {
+ dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret);
+ goto disable_ahb_clk;
+ }
+
+ /* Disable the PHY */
+ qusb2_setbits(qphy->base, QUSB2PHY_PORT_POWERDOWN,
+ CLAMP_N_EN | FREEZIO_N | POWER_DOWN);
+
+ /* save reset value to override reference clock scheme later */
+ val = readl(qphy->base + QUSB2PHY_PLL_TEST);
+
+ qcom_qusb2_phy_configure(qphy->base, qphy->cfg->tbl,
+ qphy->cfg->tbl_num);
+
+ /* Set efuse value for tuning the PHY */
+ qusb2_phy_set_tune2_param(qphy);
+
+ /* Enable the PHY */
+ qusb2_clrbits(qphy->base, QUSB2PHY_PORT_POWERDOWN, POWER_DOWN);
+
+ /* Required to get phy pll lock successfully */
+ usleep_range(150, 160);
+
+ /* Default is single-ended clock on msm8996 */
+ qphy->has_se_clk_scheme = true;
+ /*
+ * read TCSR_PHY_CLK_SCHEME register to check if single-ended
+ * clock scheme is selected. If yes, then disable differential
+ * ref_clk and use single-ended clock, otherwise use differential
+ * ref_clk only.
+ */
+ if (qphy->tcsr) {
+ ret = regmap_read(qphy->tcsr, qphy->cfg->clk_scheme_offset,
+ &clk_scheme);
+ if (ret) {
+ dev_err(&phy->dev, "failed to read clk scheme reg\n");
+ goto assert_phy_reset;
+ }
+
+ /* is it a differential clock scheme ? */
+ if (!(clk_scheme & PHY_CLK_SCHEME_SEL)) {
+ dev_vdbg(&phy->dev, "%s(): select differential clk\n",
+ __func__);
+ qphy->has_se_clk_scheme = false;
+ } else {
+ dev_vdbg(&phy->dev, "%s(): select single-ended clk\n",
+ __func__);
+ }
+ }
+
+ if (!qphy->has_se_clk_scheme) {
+ val &= ~CLK_REF_SEL;
+ ret = clk_prepare_enable(qphy->ref_clk);
+ if (ret) {
+ dev_err(&phy->dev, "failed to enable ref clk, %d\n",
+ ret);
+ goto assert_phy_reset;
+ }
+ } else {
+ val |= CLK_REF_SEL;
+ }
+
+ writel(val, qphy->base + QUSB2PHY_PLL_TEST);
+
+ /* ensure above write is through */
+ readl(qphy->base + QUSB2PHY_PLL_TEST);
+
+ /* Required to get phy pll lock successfully */
+ usleep_range(100, 110);
+
+ val = readb(qphy->base + QUSB2PHY_PLL_STATUS);
+ if (!(val & PLL_LOCKED)) {
+ dev_err(&phy->dev,
+ "QUSB2PHY pll lock failed: status reg = %x\n", val);
+ ret = -EBUSY;
+ goto disable_ref_clk;
+ }
+
+ return 0;
+
+disable_ref_clk:
+ if (!qphy->has_se_clk_scheme)
+ clk_disable_unprepare(qphy->ref_clk);
+assert_phy_reset:
+ reset_control_assert(qphy->phy_reset);
+disable_ahb_clk:
+ clk_disable_unprepare(qphy->cfg_ahb_clk);
+ return ret;
+}
+
+static int qusb2_phy_exit(struct phy *phy)
+{
+ struct qusb2_phy *qphy = phy_get_drvdata(phy);
+
+ /* Disable the PHY */
+ qusb2_setbits(qphy->base, QUSB2PHY_PORT_POWERDOWN,
+ CLAMP_N_EN | FREEZIO_N | POWER_DOWN);
+
+ if (!qphy->has_se_clk_scheme)
+ clk_disable_unprepare(qphy->ref_clk);
+
+ reset_control_assert(qphy->phy_reset);
+
+ clk_disable_unprepare(qphy->cfg_ahb_clk);
+
+ return 0;
+}
+
+static const struct phy_ops qusb2_phy_gen_ops = {
+ .init = qusb2_phy_init,
+ .exit = qusb2_phy_exit,
+ .power_on = qusb2_phy_poweron,
+ .power_off = qusb2_phy_poweroff,
+ .owner = THIS_MODULE,
+};
+
+static const struct of_device_id qusb2_phy_of_match_table[] = {
+ {
+ .compatible = "qcom,msm8996-qusb2-phy",
+ .data = &msm8996_phy_cfg,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, qusb2_phy_of_match_table);
+
+static int qusb2_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct qusb2_phy *qphy;
+ struct phy_provider *phy_provider;
+ struct phy *generic_phy;
+ struct resource *res;
+ int ret, i;
+ int num;
+
+ qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
+ if (!qphy)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ qphy->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(qphy->base))
+ return PTR_ERR(qphy->base);
+
+ qphy->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb");
+ if (IS_ERR(qphy->cfg_ahb_clk)) {
+ ret = PTR_ERR(qphy->cfg_ahb_clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "failed to get cfg ahb clk, %d\n", ret);
+ return ret;
+ }
+
+ qphy->ref_clk = devm_clk_get(dev, "ref");
+ if (IS_ERR(qphy->ref_clk)) {
+ ret = PTR_ERR(qphy->ref_clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "failed to get ref clk, %d\n", ret);
+ return ret;
+ }
+
+ qphy->iface_clk = devm_clk_get(dev, "iface");
+ if (IS_ERR(qphy->iface_clk)) {
+ ret = PTR_ERR(qphy->iface_clk);
+ if (ret == -EPROBE_DEFER)
+ return ret;
+ qphy->iface_clk = NULL;
+ dev_dbg(dev, "failed to get iface clk, %d\n", ret);
+ }
+
+ qphy->phy_reset = devm_reset_control_get_by_index(&pdev->dev, 0);
+ if (IS_ERR(qphy->phy_reset)) {
+ dev_err(dev, "failed to get phy core reset\n");
+ return PTR_ERR(qphy->phy_reset);
+ }
+
+ num = ARRAY_SIZE(qphy->vregs);
+ for (i = 0; i < num; i++)
+ qphy->vregs[i].supply = qusb2_phy_vreg_names[i];
+
+ ret = devm_regulator_bulk_get(dev, num, qphy->vregs);
+ if (ret) {
+ dev_err(dev, "failed to get regulator supplies\n");
+ return ret;
+ }
+
+ /* Get the specific init parameters of QMP phy */
+ qphy->cfg = of_device_get_match_data(dev);
+
+ qphy->tcsr = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "qcom,tcsr-syscon");
+ if (IS_ERR(qphy->tcsr)) {
+ dev_dbg(dev, "failed to lookup TCSR regmap\n");
+ qphy->tcsr = NULL;
+ }
+
+ qphy->cell = devm_nvmem_cell_get(dev, NULL);
+ if (IS_ERR(qphy->cell)) {
+ if (PTR_ERR(qphy->cell) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ qphy->cell = NULL;
+ dev_dbg(dev, "failed to lookup tune2 hstx trim value\n");
+ }
+
+ generic_phy = devm_phy_create(dev, NULL, &qusb2_phy_gen_ops);
+ if (IS_ERR(generic_phy)) {
+ ret = PTR_ERR(generic_phy);
+ dev_err(dev, "failed to create phy, %d\n", ret);
+ return ret;
+ }
+ qphy->phy = generic_phy;
+
+ dev_set_drvdata(dev, qphy);
+ phy_set_drvdata(generic_phy, qphy);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (!IS_ERR(phy_provider))
+ dev_info(dev, "Registered Qcom-QUSB2 phy\n");
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static struct platform_driver qusb2_phy_driver = {
+ .probe = qusb2_phy_probe,
+ .driver = {
+ .name = "qcom-qusb2-phy",
+ .of_match_table = qusb2_phy_of_match_table,
+ },
+};
+
+module_platform_driver(qusb2_phy_driver);
+
+MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
+MODULE_DESCRIPTION("Qualcomm QUSB2 PHY driver");
+MODULE_LICENSE("GPL v2");
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Vivek Gautam <vivek.gautam@codeaurora.org> |
|---|---|
| Date | 2017-04-05 14:40 +0200 |
| Subject | [PATCH V7 3/4] dt-bindings: phy: Add support for QMP phy |
| Message-ID | <tsSoa-2BK-23@gated-at.bofh.it> |
| In reply to | #1616891 |
Qualcomm chipsets have QMP phy controller that provides
support to a number of controller, viz. PCIe, UFS, and USB.
Adding dt binding information for the same.
Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Acked-by: Rob Herring <robh@kernel.org>
---
Changes since v6:
- none.
Changes since v5:
- Added Rob's 'Ack' for the new child nodes based bindings.
- Dropped leading 0 from the address in 'reg' property.
- Fixed '@xyz' part of the node name with correct address.
Changes since v4:
- Added bindings for child nodes. Each phy lane is represented by child
node with its own register space (for tx, rx and pcs blocks), and clocks
and resets for power control facility.
- Removed register space and lane offsets for tx, rx and pcs blocks from
qmp phy node.
- #phy-cells is now part of each child node and thus must be 0.
- Added information on list of mandatory clocks and resets for each phy.
Changes since v3:
- Added #clock-cells = <1>, indicating that phy is a clock provider.
Changes since v2:
- Removed binding for "ref_clk_src" since we don't request this
clock in the driver.
- Addressed s/ref_clk/ref. Don't need to add '_clk' suffix to clock names.
- Using 'phy' for the node name.
Changes since v1:
- New patch, forked out of the original driver patch:
"phy: qcom-qmp: new qmp phy driver for qcom-chipsets"
- Added 'Acked-by' from Rob.
- Updated bindings to include mem resource as a list of
offset - length pair for serdes block and for each lane.
- Added a new binding for 'lane-offsets' that contains offsets
to tx, rx and pcs blocks from each lane base address.
.../devicetree/bindings/phy/qcom-qmp-phy.txt | 106 +++++++++++++++++++++
1 file changed, 106 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
new file mode 100644
index 000000000000..e11c563a65ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -0,0 +1,106 @@
+Qualcomm QMP PHY controller
+===========================
+
+QMP phy controller supports physical layer functionality for a number of
+controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
+
+Required properties:
+ - compatible: compatible list, contains:
+ "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
+ "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996.
+
+ - reg: offset and length of register set for PHY's common serdes block.
+
+ - #clock-cells: must be 1
+ - Phy pll outputs a bunch of clocks for Tx, Rx and Pipe
+ interface (for pipe based PHYs). These clock are then gate-controlled
+ by gcc.
+ - #address-cells: must be 1
+ - #size-cells: must be 1
+ - ranges: must be present
+
+ - clocks: a list of phandles and clock-specifier pairs,
+ one for each entry in clock-names.
+ - clock-names: "cfg_ahb" for phy config clock,
+ "aux" for phy aux clock,
+ "ref" for 19.2 MHz ref clk,
+ For "qcom,msm8996-qmp-pcie-phy" must contain:
+ "aux", "cfg_ahb", "ref".
+ For "qcom,msm8996-qmp-usb3-phy" must contain:
+ "aux", "cfg_ahb", "ref".
+
+ - resets: a list of phandles and reset controller specifier pairs,
+ one for each entry in reset-names.
+ - reset-names: "phy" for reset of phy block,
+ "common" for phy common block reset,
+ "cfg" for phy's ahb cfg block reset (Optional).
+ For "qcom,msm8996-qmp-pcie-phy" must contain:
+ "phy", "common", "cfg".
+ For "qcom,msm8996-qmp-usb3-phy" must contain
+ "phy", "common".
+
+ - vdda-phy-supply: Phandle to a regulator supply to PHY core block.
+ - vdda-pll-supply: Phandle to 1.8V regulator supply to PHY refclk pll block.
+
+Optional properties:
+ - vddp-ref-clk-supply: Phandle to a regulator supply to any specific refclk
+ pll block.
+
+Required nodes:
+ - Each device node of QMP phy is required to have as many child nodes as
+ the number of lanes the PHY has.
+
+Required properties for child node:
+ - reg: list of offset and length pairs of register sets for PHY blocks -
+ tx, rx and pcs.
+
+ - #phy-cells: must be 0
+
+ - clocks: a list of phandles and clock-specifier pairs,
+ one for each entry in clock-names.
+ - clock-names: Must contain following for pcie and usb qmp phys:
+ "pipe<lane-number>" for pipe clock specific to each lane.
+
+ - resets: a list of phandles and reset controller specifier pairs,
+ one for each entry in reset-names.
+ - reset-names: Must contain following for pcie qmp phys:
+ "lane<lane-number>" for reset specific to each lane.
+
+Example:
+ phy@34000 {
+ compatible = "qcom,msm8996-qmp-pcie-phy";
+ reg = <0x34000 0x488>;
+ #clock-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
+ <&gcc GCC_PCIE_PHY_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_CLKREF_CLK>;
+ clock-names = "aux", "cfg_ahb", "ref";
+
+ vdda-phy-supply = <&pm8994_l28>;
+ vdda-pll-supply = <&pm8994_l12>;
+
+ resets = <&gcc GCC_PCIE_PHY_BCR>,
+ <&gcc GCC_PCIE_PHY_COM_BCR>,
+ <&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>;
+ reset-names = "phy", "common", "cfg";
+
+ pciephy_0: lane@35000 {
+ reg = <0x35000 0x130>,
+ <0x35200 0x200>,
+ <0x35400 0x1dc>;
+ #phy-cells = <0>;
+
+ clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
+ clock-names = "pipe0";
+ resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+ reset-names = "lane0";
+ };
+
+ pciephy_1: lane@36000 {
+ ...
+ ...
+ };
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2017-04-06 01:00 +0200 |
| Subject | Re: [PATCH V7 3/4] dt-bindings: phy: Add support for QMP phy |
| Message-ID | <tt249-dB-1@gated-at.bofh.it> |
| In reply to | #1616896 |
On 04/05, Vivek Gautam wrote: > Qualcomm chipsets have QMP phy controller that provides > support to a number of controller, viz. PCIe, UFS, and USB. > Adding dt binding information for the same. > > Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org> > Acked-by: Rob Herring <robh@kernel.org> > --- Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Kishon Vijay Abraham I <kishon@ti.com> |
|---|---|
| Date | 2017-04-05 15:50 +0200 |
| Message-ID | <tsTtV-3hW-51@gated-at.bofh.it> |
| In reply to | #1616891 |
Hi Vivek, On Wednesday 05 April 2017 06:02 PM, Vivek Gautam wrote: > This patch series adds couple of PHY drivers for Qualcomm chipsets. > a) qcom-qusb2 phy driver: that provides High Speed USB functionality. > b) qcom-qmp phy driver: that is a combo phy providing support for > USB3, PCIe, UFS and few other controllers. > > The patches are based on next branch of linux-phy tree. > > These patches have been tested on Dragon board db820c hardware with > required set of dt patches and the patches to get rpm up on msm8996. > Couple of other patches [1, 2] fixing DMA config for XHCI are also > pulled in for testing. > A branch based on torvald's master is available in github [3]. I get a bunch of checkpatch errors/warnings when I run checkpatch with --strict option. Those look simple enough to be fixed. Can you respin your series fixing those? Thanks Kishon > > Changes since v6: > - Rebased on phy/next and *not* including phy grouping series[4]. > - qusb2-phy: addressed Stephen's comment. > - Dropped pm8994_s2 corner regulator from QUSB2 phy bindings. > - qmp-phy: none on functionality side. > > Changes since v5: > - Addressed review comments from Bjorn: > - Removed instances of readl/wirtel_relaxed calls from the drivers. > Instead, using simple readl/writel. Inserting a readl after a writel > to ensure the write is through to the device. > - Replaced regulator handling with regulator_bulk_** apis. This helps > in cutting down a lot of regulator handling code. > - Fixed minor return statements. > > Changes since v4: > - Addressed comment to add child nodes for qmp phy driver. Each phy lane > now has a separate child node under the main qmp node. > - Modified the clock and reset initialization and enable methods. > Different phys - pcie, usb and later ufs, have varying number of clocks > and resets that are mandatory. So adding provision for clocks and reset > lists helps in requesting all mandatory resources for individual phys > and handle their failure cases accordingly. > > Changes since v3: > - Addressed review comments given by Rob and Stephen for qusb2 phy > and qmp phy bindings respectively. > - Addressed review comments given by Stephen and Bjorn for qmp phy driver. > > Changes since v2: > - Addressed review comments given by Rob and Stephen for bindings. > - Addressed the review comments given by Stephen for the qusb2 and qmp > phy drivers. > > Changes since v1: > - Moved device tree binding documentation to separate patches, as suggested > by Rob. > - Addressed review comment regarding qfprom accesses by qusb2 phy driver, > given by Rob. > - Addressed review comments from Kishon. > - Addressed review comments from Srinivas for QMP phy driver. > - Addressed kbuild warning. > > Please see individual patches for detailed changelogs. > > [1] https://patchwork.kernel.org/patch/9567767/ > [2] https://patchwork.kernel.org/patch/9567779/ > [3] https://github.com/vivekgautam1/linux/tree/linux-v4.11-rc5-qmp-phy-db820c > [4] https://lkml.org/lkml/2017/3/20/407 > > Vivek Gautam (4): > dt-bindings: phy: Add support for QUSB2 phy > phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips > dt-bindings: phy: Add support for QMP phy > phy: qcom-qmp: new qmp phy driver for qcom-chipsets > > .../devicetree/bindings/phy/qcom-qmp-phy.txt | 106 ++ > .../devicetree/bindings/phy/qcom-qusb2-phy.txt | 43 + > drivers/phy/Kconfig | 18 + > drivers/phy/Makefile | 2 + > drivers/phy/phy-qcom-qmp.c | 1153 ++++++++++++++++++++ > drivers/phy/phy-qcom-qusb2.c | 491 +++++++++ > 6 files changed, 1813 insertions(+) > create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt > create mode 100644 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt > create mode 100644 drivers/phy/phy-qcom-qmp.c > create mode 100644 drivers/phy/phy-qcom-qusb2.c >
[toc] | [prev] | [next] | [standalone]
| From | Vivek Gautam <vivek.gautam@codeaurora.org> |
|---|---|
| Date | 2017-04-05 17:30 +0200 |
| Message-ID | <tsV2H-4nq-39@gated-at.bofh.it> |
| In reply to | #1616949 |
Hi Kishon, On Wed, Apr 5, 2017 at 7:08 PM, Kishon Vijay Abraham I <kishon@ti.com> wrote: > Hi Vivek, > > On Wednesday 05 April 2017 06:02 PM, Vivek Gautam wrote: >> This patch series adds couple of PHY drivers for Qualcomm chipsets. >> a) qcom-qusb2 phy driver: that provides High Speed USB functionality. >> b) qcom-qmp phy driver: that is a combo phy providing support for >> USB3, PCIe, UFS and few other controllers. >> >> The patches are based on next branch of linux-phy tree. >> >> These patches have been tested on Dragon board db820c hardware with >> required set of dt patches and the patches to get rpm up on msm8996. >> Couple of other patches [1, 2] fixing DMA config for XHCI are also >> pulled in for testing. >> A branch based on torvald's master is available in github [3]. > > I get a bunch of checkpatch errors/warnings when I run checkpatch with --strict > option. Those look simple enough to be fixed. Can you respin your series fixing > those? Sure, I am on it. Thanks for pointing out. Regards Vivek > > Thanks > Kishon > >> >> Changes since v6: >> - Rebased on phy/next and *not* including phy grouping series[4]. >> - qusb2-phy: addressed Stephen's comment. >> - Dropped pm8994_s2 corner regulator from QUSB2 phy bindings. >> - qmp-phy: none on functionality side. >> >> Changes since v5: >> - Addressed review comments from Bjorn: >> - Removed instances of readl/wirtel_relaxed calls from the drivers. >> Instead, using simple readl/writel. Inserting a readl after a writel >> to ensure the write is through to the device. >> - Replaced regulator handling with regulator_bulk_** apis. This helps >> in cutting down a lot of regulator handling code. >> - Fixed minor return statements. >> >> Changes since v4: >> - Addressed comment to add child nodes for qmp phy driver. Each phy lane >> now has a separate child node under the main qmp node. >> - Modified the clock and reset initialization and enable methods. >> Different phys - pcie, usb and later ufs, have varying number of clocks >> and resets that are mandatory. So adding provision for clocks and reset >> lists helps in requesting all mandatory resources for individual phys >> and handle their failure cases accordingly. >> >> Changes since v3: >> - Addressed review comments given by Rob and Stephen for qusb2 phy >> and qmp phy bindings respectively. >> - Addressed review comments given by Stephen and Bjorn for qmp phy driver. >> >> Changes since v2: >> - Addressed review comments given by Rob and Stephen for bindings. >> - Addressed the review comments given by Stephen for the qusb2 and qmp >> phy drivers. >> >> Changes since v1: >> - Moved device tree binding documentation to separate patches, as suggested >> by Rob. >> - Addressed review comment regarding qfprom accesses by qusb2 phy driver, >> given by Rob. >> - Addressed review comments from Kishon. >> - Addressed review comments from Srinivas for QMP phy driver. >> - Addressed kbuild warning. >> >> Please see individual patches for detailed changelogs. >> >> [1] https://patchwork.kernel.org/patch/9567767/ >> [2] https://patchwork.kernel.org/patch/9567779/ >> [3] https://github.com/vivekgautam1/linux/tree/linux-v4.11-rc5-qmp-phy-db820c >> [4] https://lkml.org/lkml/2017/3/20/407 >> >> Vivek Gautam (4): >> dt-bindings: phy: Add support for QUSB2 phy >> phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips >> dt-bindings: phy: Add support for QMP phy >> phy: qcom-qmp: new qmp phy driver for qcom-chipsets >> >> .../devicetree/bindings/phy/qcom-qmp-phy.txt | 106 ++ >> .../devicetree/bindings/phy/qcom-qusb2-phy.txt | 43 + >> drivers/phy/Kconfig | 18 + >> drivers/phy/Makefile | 2 + >> drivers/phy/phy-qcom-qmp.c | 1153 ++++++++++++++++++++ >> drivers/phy/phy-qcom-qusb2.c | 491 +++++++++ >> 6 files changed, 1813 insertions(+) >> create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt >> create mode 100644 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt >> create mode 100644 drivers/phy/phy-qcom-qmp.c >> create mode 100644 drivers/phy/phy-qcom-qusb2.c >> > -- > To unsubscribe from this list: send the line "unsubscribe linux-usb" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2017-04-06 01:00 +0200 |
| Subject | Re: [PATCH V7 4/4] phy: qcom-qmp: new qmp phy driver for qcom-chipsets |
| Message-ID | <tt24a-dB-17@gated-at.bofh.it> |
| In reply to | #1616891 |
On 04/05, Vivek Gautam wrote: > Qualcomm SOCs have QMP phy controller that provides support > to a number of controller, viz. PCIe, UFS, and USB. > Add a new driver, based on generic phy framework, for this > phy controller. > > Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org> > Tested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > --- Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web