* [PATCH v4 01/16] phy: qcom-qmp: Fix phy pipe clock gating
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-03 11:28 ` [PATCH v4 02/16] phy: qcom-qmp: Adapt to clk_bulk_* APIs Manu Gautam
` (14 subsequent siblings)
15 siblings, 0 replies; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Vivek Gautam,
Manu Gautam, Varadarajan Narayanan, Krzysztof Kozlowski,
Fengguang Wu, Wei Yongjun, open list:GENERIC PHY FRAMEWORK
From: Vivek Gautam <vivek.gautam@codeaurora.org>
Pipe clock comes out of the phy and is available as long as
the phy is turned on. Clock controller fails to gate this
clock after the phy is turned off and generates a warning.
/ # [ 33.048561] gcc_usb3_phy_pipe_clk status stuck at 'on'
[ 33.048585] ------------[ cut here ]------------
[ 33.052621] WARNING: CPU: 1 PID: 18 at ../drivers/clk/qcom/clk-branch.c:97 clk_branch_wait+0xf0/0x108
[ 33.057384] Modules linked in:
[ 33.066497] CPU: 1 PID: 18 Comm: kworker/1:0 Tainted: G W 4.12.0-rc7-00024-gfe926e34c36d-dirty #96
[ 33.069451] Hardware name: Qualcomm Technologies, Inc. DB820c (DT)
...
[ 33.278565] [<ffff00000849b27c>] clk_branch_wait+0xf0/0x108
[ 33.286375] [<ffff00000849b2f4>] clk_branch2_disable+0x28/0x34
[ 33.291761] [<ffff0000084868dc>] clk_core_disable+0x5c/0x88
[ 33.297660] [<ffff000008487d68>] clk_core_disable_lock+0x20/0x34
[ 33.303129] [<ffff000008487d98>] clk_disable+0x1c/0x24
[ 33.309384] [<ffff0000083ccd78>] qcom_qmp_phy_poweroff+0x20/0x48
[ 33.314328] [<ffff0000083c53f4>] phy_power_off+0x80/0xdc
[ 33.320492] [<ffff00000875c950>] dwc3_core_exit+0x94/0xa0
[ 33.325784] [<ffff00000875c9ac>] dwc3_suspend_common+0x50/0x60
[ 33.331080] [<ffff00000875ca04>] dwc3_runtime_suspend+0x48/0x6c
[ 33.336810] [<ffff0000085b82f4>] pm_generic_runtime_suspend+0x28/0x38
[ 33.342627] [<ffff0000085bace0>] __rpm_callback+0x150/0x254
[ 33.349222] [<ffff0000085bae08>] rpm_callback+0x24/0x78
[ 33.354604] [<ffff0000085b9fd8>] rpm_suspend+0xe0/0x4e4
[ 33.359813] [<ffff0000085bb784>] pm_runtime_work+0xdc/0xf0
[ 33.365028] [<ffff0000080d7b30>] process_one_work+0x12c/0x28c
[ 33.370576] [<ffff0000080d7ce8>] worker_thread+0x58/0x3b8
[ 33.376393] [<ffff0000080dd4a8>] kthread+0x100/0x12c
[ 33.381776] [<ffff0000080836c0>] ret_from_fork+0x10/0x50
Fix this by disabling it as the first thing in phy_exit().
Fixes: e78f3d15e115 ("phy: qcom-qmp: new qmp phy driver for qcom-chipsets")
Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qmp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index e17f035..2526971 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -751,8 +751,6 @@ static int qcom_qmp_phy_poweroff(struct phy *phy)
struct qmp_phy *qphy = phy_get_drvdata(phy);
struct qcom_qmp *qmp = qphy->qmp;
- clk_disable_unprepare(qphy->pipe_clk);
-
regulator_bulk_disable(qmp->cfg->num_vregs, qmp->vregs);
return 0;
@@ -936,6 +934,8 @@ static int qcom_qmp_phy_exit(struct phy *phy)
const struct qmp_phy_cfg *cfg = qmp->cfg;
int i = cfg->num_clks;
+ clk_disable_unprepare(qphy->pipe_clk);
+
/* PHY reset */
qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 02/16] phy: qcom-qmp: Adapt to clk_bulk_* APIs
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
2018-01-03 11:28 ` [PATCH v4 01/16] phy: qcom-qmp: Fix phy pipe clock gating Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-03 11:28 ` [PATCH v4 03/16] phy: qcom-qmp: Power-on PHY before initialization Manu Gautam
` (13 subsequent siblings)
15 siblings, 0 replies; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Vivek Gautam,
Manu Gautam, Varadarajan Narayanan, smuthayy, Fengguang Wu,
Wei Yongjun, open list:GENERIC PHY FRAMEWORK
From: Vivek Gautam <vivek.gautam@codeaurora.org>
Move from using array of clocks to clk_bulk_* APIs that
are available now.
Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qmp.c | 50 ++++++++++++-------------------------
1 file changed, 16 insertions(+), 34 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 2526971..5fed1ae 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -555,7 +555,7 @@ struct qcom_qmp {
struct device *dev;
void __iomem *serdes;
- struct clk **clks;
+ struct clk_bulk_data *clks;
struct reset_control **resets;
struct regulator_bulk_data *vregs;
@@ -857,22 +857,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
void __iomem *pcs = qphy->pcs;
void __iomem *status;
unsigned int mask, val;
- int ret, i;
+ int ret;
dev_vdbg(qmp->dev, "Initializing QMP phy\n");
- for (i = 0; i < qmp->cfg->num_clks; i++) {
- ret = clk_prepare_enable(qmp->clks[i]);
- if (ret) {
- dev_err(qmp->dev, "failed to enable %s clk, err=%d\n",
- qmp->cfg->clk_list[i], ret);
- goto err_clk;
- }
+ ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
+ if (ret) {
+ dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
+ return ret;
}
ret = qcom_qmp_phy_com_init(qmp);
if (ret)
- goto err_clk;
+ goto err_com_init;
if (cfg->has_lane_rst) {
ret = reset_control_deassert(qphy->lane_rst);
@@ -920,9 +917,8 @@ static int qcom_qmp_phy_init(struct phy *phy)
reset_control_assert(qphy->lane_rst);
err_lane_rst:
qcom_qmp_phy_com_exit(qmp);
-err_clk:
- while (--i >= 0)
- clk_disable_unprepare(qmp->clks[i]);
+err_com_init:
+ clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
return ret;
}
@@ -932,7 +928,6 @@ static int qcom_qmp_phy_exit(struct phy *phy)
struct qmp_phy *qphy = phy_get_drvdata(phy);
struct qcom_qmp *qmp = qphy->qmp;
const struct qmp_phy_cfg *cfg = qmp->cfg;
- int i = cfg->num_clks;
clk_disable_unprepare(qphy->pipe_clk);
@@ -950,8 +945,7 @@ static int qcom_qmp_phy_exit(struct phy *phy)
qcom_qmp_phy_com_exit(qmp);
- while (--i >= 0)
- clk_disable_unprepare(qmp->clks[i]);
+ clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
return 0;
}
@@ -1000,29 +994,17 @@ static int qcom_qmp_phy_reset_init(struct device *dev)
static int qcom_qmp_phy_clk_init(struct device *dev)
{
struct qcom_qmp *qmp = dev_get_drvdata(dev);
- int ret, i;
+ int num = qmp->cfg->num_clks;
+ int i;
- qmp->clks = devm_kcalloc(dev, qmp->cfg->num_clks,
- sizeof(*qmp->clks), GFP_KERNEL);
+ qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
if (!qmp->clks)
return -ENOMEM;
- for (i = 0; i < qmp->cfg->num_clks; i++) {
- struct clk *_clk;
- const char *name = qmp->cfg->clk_list[i];
-
- _clk = devm_clk_get(dev, name);
- if (IS_ERR(_clk)) {
- ret = PTR_ERR(_clk);
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "failed to get %s clk, %d\n",
- name, ret);
- return ret;
- }
- qmp->clks[i] = _clk;
- }
+ for (i = 0; i < num; i++)
+ qmp->clks[i].id = qmp->cfg->clk_list[i];
- return 0;
+ return devm_clk_bulk_get(dev, num, qmp->clks);
}
/*
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 03/16] phy: qcom-qmp: Power-on PHY before initialization
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
2018-01-03 11:28 ` [PATCH v4 01/16] phy: qcom-qmp: Fix phy pipe clock gating Manu Gautam
2018-01-03 11:28 ` [PATCH v4 02/16] phy: qcom-qmp: Adapt to clk_bulk_* APIs Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-12 8:27 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 04/16] phy: qcom-qusb2: " Manu Gautam
` (12 subsequent siblings)
15 siblings, 1 reply; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
Vivek Gautam, Varadarajan Narayanan, Yoshihiro Shimoda,
Fengguang Wu, Wei Yongjun, open list:GENERIC PHY FRAMEWORK
PHY regulators which are enabled from power_on() must be ON
before turning-on clocks and initializing it as part of init().
As most of the core drivers perform power_on() after init(), move
PHY regulators enable to com_init() and use power_on() to
only enable pipe_clk. This pipe_clk is output from PHY and some
core drivers e.g. PCIe follow specific sequence after phy_init()
that mandates pipe_clk to be enabled from power_on() only.
On similar lines move clk_enable from init() to com_init() which
executes once for multi lane PHYs.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qmp.c | 61 +++++++++++++++----------------------
1 file changed, 24 insertions(+), 37 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 5fed1ae..1b82cea 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -724,36 +724,13 @@ static int qcom_qmp_phy_poweron(struct phy *phy)
{
struct qmp_phy *qphy = phy_get_drvdata(phy);
struct qcom_qmp *qmp = qphy->qmp;
- int num = qmp->cfg->num_vregs;
int ret;
- dev_vdbg(&phy->dev, "Powering on QMP phy\n");
-
- /* turn on regulator supplies */
- ret = regulator_bulk_enable(num, qmp->vregs);
- if (ret) {
- dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
- return ret;
- }
-
ret = clk_prepare_enable(qphy->pipe_clk);
- if (ret) {
+ if (ret)
dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
- regulator_bulk_disable(num, qmp->vregs);
- return ret;
- }
- return 0;
-}
-
-static int qcom_qmp_phy_poweroff(struct phy *phy)
-{
- struct qmp_phy *qphy = phy_get_drvdata(phy);
- struct qcom_qmp *qmp = qphy->qmp;
-
- regulator_bulk_disable(qmp->cfg->num_vregs, qmp->vregs);
-
- return 0;
+ return ret;
}
static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
@@ -768,6 +745,19 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
return 0;
}
+ /* turn on regulator supplies */
+ ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
+ if (ret) {
+ dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
+ goto err_reg_enable;
+ }
+
+ ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
+ if (ret) {
+ dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
+ goto err_clk_enable;
+ }
+
for (i = 0; i < cfg->num_resets; i++) {
ret = reset_control_deassert(qmp->resets[i]);
if (ret) {
@@ -812,6 +802,10 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
err_rst:
while (--i >= 0)
reset_control_assert(qmp->resets[i]);
+ clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
+err_clk_enable:
+ regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
+err_reg_enable:
mutex_unlock(&qmp->phy_mutex);
return ret;
@@ -841,6 +835,10 @@ static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp)
while (--i >= 0)
reset_control_assert(qmp->resets[i]);
+ clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
+
+ regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
+
mutex_unlock(&qmp->phy_mutex);
return 0;
@@ -861,15 +859,9 @@ static int qcom_qmp_phy_init(struct phy *phy)
dev_vdbg(qmp->dev, "Initializing QMP phy\n");
- ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
- if (ret) {
- dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
- return ret;
- }
-
ret = qcom_qmp_phy_com_init(qmp);
if (ret)
- goto err_com_init;
+ return ret;
if (cfg->has_lane_rst) {
ret = reset_control_deassert(qphy->lane_rst);
@@ -917,8 +909,6 @@ static int qcom_qmp_phy_init(struct phy *phy)
reset_control_assert(qphy->lane_rst);
err_lane_rst:
qcom_qmp_phy_com_exit(qmp);
-err_com_init:
- clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
return ret;
}
@@ -945,8 +935,6 @@ static int qcom_qmp_phy_exit(struct phy *phy)
qcom_qmp_phy_com_exit(qmp);
- clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
-
return 0;
}
@@ -1060,7 +1048,6 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
.init = qcom_qmp_phy_init,
.exit = qcom_qmp_phy_exit,
.power_on = qcom_qmp_phy_poweron,
- .power_off = qcom_qmp_phy_poweroff,
.owner = THIS_MODULE,
};
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 04/16] phy: qcom-qusb2: Power-on PHY before initialization
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (2 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 03/16] phy: qcom-qmp: Power-on PHY before initialization Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-12 8:29 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence Manu Gautam
` (11 subsequent siblings)
15 siblings, 1 reply; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
Vivek Gautam, Krzysztof Kozlowski, Viresh Kumar,
open list:GENERIC PHY FRAMEWORK
PHY must be powered on before turning ON clocks and
attempting to initialize it. Driver is exposing
separate init and power_on routines for this.
Apparently USB dwc3 core driver performs power-on
after init. Also, poweron and init for QUSB2 PHY
need to be executed together always, hence remove
poweron callback from phy_ops and explicitly perform
this from init, similar changes needed for poweroff.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qusb2.c | 47 +++++++++++------------------------
1 file changed, 15 insertions(+), 32 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 6c57524..4a5b2a1 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -195,54 +195,31 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy)
qusb2_setbits(qphy->base, QUSB2PHY_PORT_TUNE2, val[0] << 0x4);
}
-static int qusb2_phy_poweron(struct phy *phy)
+static int qusb2_phy_init(struct phy *phy)
{
struct qusb2_phy *qphy = phy_get_drvdata(phy);
- int num = ARRAY_SIZE(qphy->vregs);
+ unsigned int val;
+ unsigned int clk_scheme;
int ret;
- dev_vdbg(&phy->dev, "%s(): Powering-on QUSB2 phy\n", __func__);
+ dev_vdbg(&phy->dev, "%s(): Initializing QUSB2 phy\n", __func__);
/* turn on regulator supplies */
- ret = regulator_bulk_enable(num, qphy->vregs);
+ ret = regulator_bulk_enable(ARRAY_SIZE(qphy->vregs), 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;
+ goto poweroff_phy;
}
- 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;
+ goto disable_iface_clk;
}
/* Perform phy reset */
@@ -344,6 +321,11 @@ static int qusb2_phy_init(struct phy *phy)
reset_control_assert(qphy->phy_reset);
disable_ahb_clk:
clk_disable_unprepare(qphy->cfg_ahb_clk);
+disable_iface_clk:
+ clk_disable_unprepare(qphy->iface_clk);
+poweroff_phy:
+ regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
+
return ret;
}
@@ -361,6 +343,9 @@ static int qusb2_phy_exit(struct phy *phy)
reset_control_assert(qphy->phy_reset);
clk_disable_unprepare(qphy->cfg_ahb_clk);
+ clk_disable_unprepare(qphy->iface_clk);
+
+ regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
return 0;
}
@@ -368,8 +353,6 @@ static int qusb2_phy_exit(struct phy *phy)
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,
};
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (3 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 04/16] phy: qcom-qusb2: " Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-12 8:44 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 06/16] phy: qcom-qmp: Move SERDES/PCS START after PHY reset Manu Gautam
` (10 subsequent siblings)
15 siblings, 1 reply; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
Vivek Gautam, Varadarajan Narayanan, Viresh Kumar, Wei Yongjun,
Fengguang Wu, open list:GENERIC PHY FRAMEWORK
PHY block or asynchronous reset requires signal
to be asserted before de-asserting. Driver is only
de-asserting signal which is already low, hence
reset operation is a no-op. Fix this by asserting
signal first. Also, resetting requires PHY clocks
to be turned ON only after reset is finished. Fix
that as well.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qmp.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 1b82cea..ecff261 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -752,13 +752,16 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
goto err_reg_enable;
}
- ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
- if (ret) {
- dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
- goto err_clk_enable;
+ for (i = 0; i < cfg->num_resets; i++) {
+ ret = reset_control_assert(qmp->resets[i]);
+ if (ret) {
+ dev_err(qmp->dev, "%s reset assert failed\n",
+ cfg->reset_list[i]);
+ goto err_rst_assert;
+ }
}
- for (i = 0; i < cfg->num_resets; i++) {
+ for (i = cfg->num_resets - 1; i >= 0; i--) {
ret = reset_control_deassert(qmp->resets[i]);
if (ret) {
dev_err(qmp->dev, "%s reset deassert failed\n",
@@ -767,6 +770,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
}
}
+ ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
+ if (ret) {
+ dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
+ goto err_rst;
+ }
+
if (cfg->has_phy_com_ctrl)
qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
SW_PWRDN);
@@ -791,7 +800,7 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
if (ret) {
dev_err(qmp->dev,
"phy common block init timed-out\n");
- goto err_rst;
+ goto err_com_init;
}
}
@@ -799,11 +808,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
return 0;
+err_com_init:
+ clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
err_rst:
- while (--i >= 0)
+ while (++i < cfg->num_resets)
reset_control_assert(qmp->resets[i]);
- clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
-err_clk_enable:
+err_rst_assert:
regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
err_reg_enable:
mutex_unlock(&qmp->phy_mutex);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 06/16] phy: qcom-qmp: Move SERDES/PCS START after PHY reset
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (4 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-03 11:28 ` [PATCH v4 07/16] phy: qcom-qusb2: Add support for different register layouts Manu Gautam
` (9 subsequent siblings)
15 siblings, 0 replies; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
Vivek Gautam, Varadarajan Narayanan, Wei Yongjun, Fengguang Wu,
open list:GENERIC PHY FRAMEWORK
Driver is currently performing PHY reset after starting
SERDES/PCS. As per hardware datasheet reset must be done
before starting PHY. Hence, update the sequence.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qmp.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index ecff261..edb6bbe 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -896,12 +896,12 @@ static int qcom_qmp_phy_init(struct phy *phy)
if (cfg->has_pwrdn_delay)
usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
- /* start SerDes and Phy-Coding-Sublayer */
- qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
-
/* Pull PHY out of reset state */
qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
+ /* start SerDes and Phy-Coding-Sublayer */
+ qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
+
status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
mask = cfg->mask_pcs_ready;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 07/16] phy: qcom-qusb2: Add support for different register layouts
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (5 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 06/16] phy: qcom-qmp: Move SERDES/PCS START after PHY reset Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-12 9:18 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 08/16] dt-bindings: phy-qcom-qusb2: Update binding for QUSB2 V2 version Manu Gautam
` (8 subsequent siblings)
15 siblings, 1 reply; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
Vivek Gautam, Yoshihiro Shimoda, Heiko Stuebner,
open list:GENERIC PHY FRAMEWORK
New version of QUSB2 PHY has some registers offset changed.
Add support to have register layout for a target and update
the same in phy_configuration.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qusb2.c | 149 +++++++++++++++++++++++++---------
1 file changed, 109 insertions(+), 40 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 4a5b2a1..b65635f 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -37,17 +37,10 @@
#define QUSB2PHY_PLL_AUTOPGM_CTL1 0x1c
#define QUSB2PHY_PLL_PWR_CTRL 0x18
-#define QUSB2PHY_PLL_STATUS 0x38
+/* QUSB2PHY_PLL_STATUS register bits */
#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
+/* QUSB2PHY_PORT_POWERDOWN register bits */
#define CLAMP_N_EN BIT(5)
#define FREEZIO_N BIT(1)
#define POWER_DOWN BIT(0)
@@ -59,6 +52,11 @@
struct qusb2_phy_init_tbl {
unsigned int offset;
unsigned int val;
+ /*
+ * register part of layout ?
+ * if yes, then offset gives index in the reg-layout
+ */
+ int in_layout;
};
#define QUSB2_PHY_INIT_CFG(o, v) \
@@ -67,15 +65,50 @@ struct qusb2_phy_init_tbl {
.val = v, \
}
+#define QUSB2_PHY_INIT_CFG_L(o, v) \
+ { \
+ .offset = o, \
+ .val = v, \
+ .in_layout = 1, \
+ }
+
+/* set of registers with offsets different per-PHY */
+enum qusb2phy_reg_layout {
+ QUSB2PHY_PLL_STATUS,
+ QUSB2PHY_PORT_TUNE1,
+ QUSB2PHY_PORT_TUNE2,
+ QUSB2PHY_PORT_TUNE3,
+ QUSB2PHY_PORT_TUNE4,
+ QUSB2PHY_PORT_TUNE5,
+ QUSB2PHY_PORT_TEST1,
+ QUSB2PHY_PORT_TEST2,
+ QUSB2PHY_PORT_POWERDOWN,
+ QUSB2PHY_INTR_CTRL,
+};
+
+static const unsigned int msm8996_regs_layout[] = {
+ [QUSB2PHY_PLL_STATUS] = 0x38,
+ [QUSB2PHY_PORT_TUNE1] = 0x80,
+ [QUSB2PHY_PORT_TUNE2] = 0x84,
+ [QUSB2PHY_PORT_TUNE3] = 0x88,
+ [QUSB2PHY_PORT_TUNE4] = 0x8c,
+ [QUSB2PHY_PORT_TUNE5] = 0x90,
+ [QUSB2PHY_PORT_TEST2] = 0x9c,
+ [QUSB2PHY_PORT_POWERDOWN] = 0xb4,
+};
+
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_L(QUSB2PHY_PORT_TUNE1, 0xf8),
+ QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3),
+ QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x83),
+ QUSB2_PHY_INIT_CFG_L(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_L(QUSB2PHY_PORT_TEST2, 0x14),
+
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
};
@@ -86,11 +119,27 @@ struct qusb2_phy_cfg {
unsigned int tbl_num;
/* offset to PHY_CLK_SCHEME register in TCSR map */
unsigned int clk_scheme_offset;
+
+ /* array of registers with different offsets */
+ const unsigned int *regs;
+ unsigned int mask_core_ready;
+ unsigned int disable_ctrl;
+
+ /* true if PHY has PLL_TEST register to select clk_scheme */
+ bool has_pll_test;
+
+ /* true if TUNE1 register must be updated by fused value, else TUNE2 */
+ bool update_tune1_with_efuse;
};
static const struct qusb2_phy_cfg msm8996_phy_cfg = {
- .tbl = msm8996_init_tbl,
- .tbl_num = ARRAY_SIZE(msm8996_init_tbl),
+ .tbl = msm8996_init_tbl,
+ .tbl_num = ARRAY_SIZE(msm8996_init_tbl),
+ .regs = msm8996_regs_layout,
+
+ .has_pll_test = true,
+ .disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
+ .mask_core_ready = PLL_LOCKED,
};
static const char * const qusb2_phy_vreg_names[] = {
@@ -160,26 +209,32 @@ static inline void qusb2_clrbits(void __iomem *base, u32 offset, u32 val)
static inline
void qcom_qusb2_phy_configure(void __iomem *base,
+ const unsigned int *regs,
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);
+ for (i = 0; i < num; i++) {
+ if (tbl[i].in_layout)
+ writel(tbl[i].val, base + regs[tbl[i].offset]);
+ else
+ writel(tbl[i].val, base + tbl[i].offset);
+ }
}
/*
* Fetches HS Tx tuning value from nvmem and sets the
- * QUSB2PHY_PORT_TUNE2 register.
+ * QUSB2PHY_PORT_TUNE1/2 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;
+ const struct qusb2_phy_cfg *cfg = qphy->cfg;
u8 *val;
/*
- * Read efuse register having TUNE2 parameter's high nibble.
+ * Read efuse register having TUNE2/1 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
@@ -191,14 +246,21 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy)
return;
}
- /* Fused TUNE2 value is the higher nibble only */
- qusb2_setbits(qphy->base, QUSB2PHY_PORT_TUNE2, val[0] << 0x4);
+ /* Fused TUNE1/2 value is the higher nibble only */
+ if (cfg->update_tune1_with_efuse)
+ qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
+ val[0] << 0x4);
+ else
+ qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
+ val[0] << 0x4);
+
}
static int qusb2_phy_init(struct phy *phy)
{
struct qusb2_phy *qphy = phy_get_drvdata(phy);
- unsigned int val;
+ const struct qusb2_phy_cfg *cfg = qphy->cfg;
+ unsigned int val = 0;
unsigned int clk_scheme;
int ret;
@@ -239,20 +301,23 @@ static int qusb2_phy_init(struct phy *phy)
}
/* Disable the PHY */
- qusb2_setbits(qphy->base, QUSB2PHY_PORT_POWERDOWN,
- CLAMP_N_EN | FREEZIO_N | POWER_DOWN);
+ qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
+ qphy->cfg->disable_ctrl);
- /* save reset value to override reference clock scheme later */
- val = readl(qphy->base + QUSB2PHY_PLL_TEST);
+ if (cfg->has_pll_test) {
+ /* 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);
+ qcom_qusb2_phy_configure(qphy->base, cfg->regs, cfg->tbl,
+ 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);
+ qusb2_clrbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
+ POWER_DOWN);
/* Required to get phy pll lock successfully */
usleep_range(150, 160);
@@ -285,27 +350,31 @@ static int qusb2_phy_init(struct phy *phy)
}
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);
+ if (cfg->has_pll_test) {
+ if (!qphy->has_se_clk_scheme)
+ val &= ~CLK_REF_SEL;
+ else
+ val |= CLK_REF_SEL;
+
+ writel(val, qphy->base + QUSB2PHY_PLL_TEST);
- /* ensure above write is through */
- readl(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)) {
+ val = readb(qphy->base + cfg->regs[QUSB2PHY_PLL_STATUS]);
+ if (!(val & cfg->mask_core_ready)) {
dev_err(&phy->dev,
"QUSB2PHY pll lock failed: status reg = %x\n", val);
ret = -EBUSY;
@@ -334,8 +403,8 @@ 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);
+ qusb2_setbits(qphy->base, qphy->cfg->regs[QUSB2PHY_PORT_POWERDOWN],
+ qphy->cfg->disable_ctrl);
if (!qphy->has_se_clk_scheme)
clk_disable_unprepare(qphy->ref_clk);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 08/16] dt-bindings: phy-qcom-qusb2: Update binding for QUSB2 V2 version
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (6 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 07/16] phy: qcom-qusb2: Add support for different register layouts Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-03 11:28 ` [PATCH v4 09/16] phy: qcom-qusb2: Add support " Manu Gautam
` (7 subsequent siblings)
15 siblings, 0 replies; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam, Rob Herring,
Mark Rutland, Vivek Gautam, Stephen Boyd,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
Update generic compatible string for QUSB2 V2 PHY. This will allow
all targets using QUSB2 V2 use same string.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index aa0fcb0..42c9742 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -4,7 +4,10 @@ Qualcomm QUSB2 phy controller
QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm chipsets.
Required properties:
- - compatible: compatible list, contains "qcom,msm8996-qusb2-phy".
+ - compatible: compatible list, contains
+ "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
+ "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+
- reg: offset and length of the PHY register set.
- #phy-cells: must be 0.
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 09/16] phy: qcom-qusb2: Add support for QUSB2 V2 version
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (7 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 08/16] dt-bindings: phy-qcom-qusb2: Update binding for QUSB2 V2 version Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-12 9:29 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 10/16] phy: qcom-qmp: Move register offsets to header file Manu Gautam
` (6 subsequent siblings)
15 siblings, 1 reply; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
Vivek Gautam, Yoshihiro Shimoda, Jaehoon Chung,
open list:GENERIC PHY FRAMEWORK
Use register layout to add additional registers present
on QUSB2 PHY V2 version for PHY initialization.
Other than new registers on V2, following two register's
offset and bit definitions are different: POWERDOWN control
and PLL_STATUS.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qusb2.c | 64 +++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index b65635f..8d0579e 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -40,15 +40,34 @@
/* QUSB2PHY_PLL_STATUS register bits */
#define PLL_LOCKED BIT(5)
+/* QUSB2PHY_PLL_COMMON_STATUS_ONE register bits */
+#define CORE_READY_STATUS BIT(0)
+
/* QUSB2PHY_PORT_POWERDOWN register bits */
#define CLAMP_N_EN BIT(5)
#define FREEZIO_N BIT(1)
#define POWER_DOWN BIT(0)
+/* QUSB2PHY_PWR_CTRL1 register bits */
+#define PWR_CTRL1_VREF_SUPPLY_TRIM BIT(5)
+#define PWR_CTRL1_CLAMP_N_EN BIT(1)
+
#define QUSB2PHY_REFCLK_ENABLE BIT(0)
#define PHY_CLK_SCHEME_SEL BIT(0)
+#define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO 0x04
+#define QUSB2PHY_PLL_CLOCK_INVERTERS 0x18c
+#define QUSB2PHY_PLL_CMODE 0x2c
+#define QUSB2PHY_PLL_LOCK_DELAY 0x184
+#define QUSB2PHY_PLL_DIGITAL_TIMERS_TWO 0xb4
+#define QUSB2PHY_PLL_BIAS_CONTROL_1 0x194
+#define QUSB2PHY_PLL_BIAS_CONTROL_2 0x198
+#define QUSB2PHY_PWR_CTRL2 0x214
+#define QUSB2PHY_IMP_CTRL1 0x220
+#define QUSB2PHY_IMP_CTRL2 0x224
+#define QUSB2PHY_CHG_CTRL2 0x23c
+
struct qusb2_phy_init_tbl {
unsigned int offset;
unsigned int val;
@@ -113,6 +132,38 @@ enum qusb2phy_reg_layout {
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
};
+static const unsigned int qusb2_v2_regs_layout[] = {
+ [QUSB2PHY_PLL_STATUS] = 0x1a0,
+ [QUSB2PHY_PORT_TUNE1] = 0x240,
+ [QUSB2PHY_PORT_TUNE2] = 0x244,
+ [QUSB2PHY_PORT_TUNE3] = 0x248,
+ [QUSB2PHY_PORT_TUNE4] = 0x24c,
+ [QUSB2PHY_PORT_TUNE5] = 0x250,
+ [QUSB2PHY_PORT_TEST2] = 0x258,
+ [QUSB2PHY_PORT_POWERDOWN] = 0x210,
+};
+
+static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = {
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_1, 0x40),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_2, 0x20),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_PWR_CTRL2, 0x21),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL1, 0x0),
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
+
+ QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x30),
+ QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x29),
+ QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0xca),
+ QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x04),
+ QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x03),
+
+ QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
+};
+
struct qusb2_phy_cfg {
const struct qusb2_phy_init_tbl *tbl;
/* number of entries in the table */
@@ -142,6 +193,16 @@ struct qusb2_phy_cfg {
.mask_core_ready = PLL_LOCKED,
};
+static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
+ .tbl = qusb2_v2_init_tbl,
+ .tbl_num = ARRAY_SIZE(qusb2_v2_init_tbl),
+ .regs = qusb2_v2_regs_layout,
+
+ .disable_ctrl = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
+ POWER_DOWN),
+ .mask_core_ready = CORE_READY_STATUS,
+};
+
static const char * const qusb2_phy_vreg_names[] = {
"vdda-pll", "vdda-phy-dpdm",
};
@@ -429,6 +490,9 @@ static int qusb2_phy_exit(struct phy *phy)
{
.compatible = "qcom,msm8996-qusb2-phy",
.data = &msm8996_phy_cfg,
+ }, {
+ .compatible = "qcom,qusb2-v2-phy",
+ .data = &qusb2_v2_phy_cfg,
},
{ },
};
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 10/16] phy: qcom-qmp: Move register offsets to header file
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (8 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 09/16] phy: qcom-qusb2: Add support " Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-12 6:26 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 11/16] phy: qcom-qmp: Add register offsets for QMP V3 PHY Manu Gautam
` (5 subsequent siblings)
15 siblings, 1 reply; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
Vivek Gautam, Varadarajan Narayanan, smuthayy, Wei Yongjun,
Fengguang Wu, open list
New revision (v3) of QMP PHY uses different offsets
for almost all of the registers. Hence, move these
definitions to header file so that updated offsets
can be added for QMP v3.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qmp.c | 119 +------------------------------
drivers/phy/qualcomm/phy-qcom-qmp.h | 137 ++++++++++++++++++++++++++++++++++++
2 files changed, 138 insertions(+), 118 deletions(-)
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp.h
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index edb6bbe..2a1117b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -31,124 +31,7 @@
#include <dt-bindings/phy/phy.h>
-/* QMP PHY QSERDES COM registers */
-#define QSERDES_COM_BG_TIMER 0x00c
-#define QSERDES_COM_SSC_EN_CENTER 0x010
-#define QSERDES_COM_SSC_ADJ_PER1 0x014
-#define QSERDES_COM_SSC_ADJ_PER2 0x018
-#define QSERDES_COM_SSC_PER1 0x01c
-#define QSERDES_COM_SSC_PER2 0x020
-#define QSERDES_COM_SSC_STEP_SIZE1 0x024
-#define QSERDES_COM_SSC_STEP_SIZE2 0x028
-#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x034
-#define QSERDES_COM_CLK_ENABLE1 0x038
-#define QSERDES_COM_SYS_CLK_CTRL 0x03c
-#define QSERDES_COM_SYSCLK_BUF_ENABLE 0x040
-#define QSERDES_COM_PLL_IVCO 0x048
-#define QSERDES_COM_LOCK_CMP1_MODE0 0x04c
-#define QSERDES_COM_LOCK_CMP2_MODE0 0x050
-#define QSERDES_COM_LOCK_CMP3_MODE0 0x054
-#define QSERDES_COM_LOCK_CMP1_MODE1 0x058
-#define QSERDES_COM_LOCK_CMP2_MODE1 0x05c
-#define QSERDES_COM_LOCK_CMP3_MODE1 0x060
-#define QSERDES_COM_BG_TRIM 0x070
-#define QSERDES_COM_CLK_EP_DIV 0x074
-#define QSERDES_COM_CP_CTRL_MODE0 0x078
-#define QSERDES_COM_CP_CTRL_MODE1 0x07c
-#define QSERDES_COM_PLL_RCTRL_MODE0 0x084
-#define QSERDES_COM_PLL_RCTRL_MODE1 0x088
-#define QSERDES_COM_PLL_CCTRL_MODE0 0x090
-#define QSERDES_COM_PLL_CCTRL_MODE1 0x094
-#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0x0a8
-#define QSERDES_COM_SYSCLK_EN_SEL 0x0ac
-#define QSERDES_COM_RESETSM_CNTRL 0x0b4
-#define QSERDES_COM_RESTRIM_CTRL 0x0bc
-#define QSERDES_COM_RESCODE_DIV_NUM 0x0c4
-#define QSERDES_COM_LOCK_CMP_EN 0x0c8
-#define QSERDES_COM_LOCK_CMP_CFG 0x0cc
-#define QSERDES_COM_DEC_START_MODE0 0x0d0
-#define QSERDES_COM_DEC_START_MODE1 0x0d4
-#define QSERDES_COM_DIV_FRAC_START1_MODE0 0x0dc
-#define QSERDES_COM_DIV_FRAC_START2_MODE0 0x0e0
-#define QSERDES_COM_DIV_FRAC_START3_MODE0 0x0e4
-#define QSERDES_COM_DIV_FRAC_START1_MODE1 0x0e8
-#define QSERDES_COM_DIV_FRAC_START2_MODE1 0x0ec
-#define QSERDES_COM_DIV_FRAC_START3_MODE1 0x0f0
-#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x108
-#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x10c
-#define QSERDES_COM_INTEGLOOP_GAIN0_MODE1 0x110
-#define QSERDES_COM_INTEGLOOP_GAIN1_MODE1 0x114
-#define QSERDES_COM_VCO_TUNE_CTRL 0x124
-#define QSERDES_COM_VCO_TUNE_MAP 0x128
-#define QSERDES_COM_VCO_TUNE1_MODE0 0x12c
-#define QSERDES_COM_VCO_TUNE2_MODE0 0x130
-#define QSERDES_COM_VCO_TUNE1_MODE1 0x134
-#define QSERDES_COM_VCO_TUNE2_MODE1 0x138
-#define QSERDES_COM_VCO_TUNE_TIMER1 0x144
-#define QSERDES_COM_VCO_TUNE_TIMER2 0x148
-#define QSERDES_COM_BG_CTRL 0x170
-#define QSERDES_COM_CLK_SELECT 0x174
-#define QSERDES_COM_HSCLK_SEL 0x178
-#define QSERDES_COM_CORECLK_DIV 0x184
-#define QSERDES_COM_CORE_CLK_EN 0x18c
-#define QSERDES_COM_C_READY_STATUS 0x190
-#define QSERDES_COM_CMN_CONFIG 0x194
-#define QSERDES_COM_SVS_MODE_CLK_SEL 0x19c
-#define QSERDES_COM_DEBUG_BUS0 0x1a0
-#define QSERDES_COM_DEBUG_BUS1 0x1a4
-#define QSERDES_COM_DEBUG_BUS2 0x1a8
-#define QSERDES_COM_DEBUG_BUS3 0x1ac
-#define QSERDES_COM_DEBUG_BUS_SEL 0x1b0
-#define QSERDES_COM_CORECLK_DIV_MODE1 0x1bc
-
-/* QMP PHY TX registers */
-#define QSERDES_TX_RES_CODE_LANE_OFFSET 0x054
-#define QSERDES_TX_DEBUG_BUS_SEL 0x064
-#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x068
-#define QSERDES_TX_LANE_MODE 0x094
-#define QSERDES_TX_RCV_DETECT_LVL_2 0x0ac
-
-/* QMP PHY RX registers */
-#define QSERDES_RX_UCDR_SO_GAIN_HALF 0x010
-#define QSERDES_RX_UCDR_SO_GAIN 0x01c
-#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN 0x040
-#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE 0x048
-#define QSERDES_RX_RX_TERM_BW 0x090
-#define QSERDES_RX_RX_EQ_GAIN1_LSB 0x0c4
-#define QSERDES_RX_RX_EQ_GAIN1_MSB 0x0c8
-#define QSERDES_RX_RX_EQ_GAIN2_LSB 0x0cc
-#define QSERDES_RX_RX_EQ_GAIN2_MSB 0x0d0
-#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d8
-#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 0x0dc
-#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 0x0e0
-#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x108
-#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x10c
-#define QSERDES_RX_SIGDET_ENABLES 0x110
-#define QSERDES_RX_SIGDET_CNTRL 0x114
-#define QSERDES_RX_SIGDET_LVL 0x118
-#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL 0x11c
-#define QSERDES_RX_RX_BAND 0x120
-#define QSERDES_RX_RX_INTERFACE_MODE 0x12c
-
-/* QMP PHY PCS registers */
-#define QPHY_POWER_DOWN_CONTROL 0x04
-#define QPHY_TXDEEMPH_M6DB_V0 0x24
-#define QPHY_TXDEEMPH_M3P5DB_V0 0x28
-#define QPHY_ENDPOINT_REFCLK_DRIVE 0x54
-#define QPHY_RX_IDLE_DTCT_CNTRL 0x58
-#define QPHY_POWER_STATE_CONFIG1 0x60
-#define QPHY_POWER_STATE_CONFIG2 0x64
-#define QPHY_POWER_STATE_CONFIG4 0x6c
-#define QPHY_LOCK_DETECT_CONFIG1 0x80
-#define QPHY_LOCK_DETECT_CONFIG2 0x84
-#define QPHY_LOCK_DETECT_CONFIG3 0x88
-#define QPHY_PWRUP_RESET_DLY_TIME_AUXCLK 0xa0
-#define QPHY_LP_WAKEUP_DLY_TIME_AUXCLK 0xa4
-#define QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB 0x1A8
-#define QPHY_OSC_DTCT_ACTIONS 0x1AC
-#define QPHY_RX_SIGDET_LVL 0x1D8
-#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1DC
-#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1E0
+#include "phy-qcom-qmp.h"
/* QPHY_SW_RESET bit */
#define SW_RESET BIT(0)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
new file mode 100644
index 0000000..d930ca7
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+#ifndef QCOM_PHY_QMP_H_
+#define QCOM_PHY_QMP_H_
+
+/* Only for QMP V2 PHY - QSERDES COM registers */
+#define QSERDES_COM_BG_TIMER 0x00c
+#define QSERDES_COM_SSC_EN_CENTER 0x010
+#define QSERDES_COM_SSC_ADJ_PER1 0x014
+#define QSERDES_COM_SSC_ADJ_PER2 0x018
+#define QSERDES_COM_SSC_PER1 0x01c
+#define QSERDES_COM_SSC_PER2 0x020
+#define QSERDES_COM_SSC_STEP_SIZE1 0x024
+#define QSERDES_COM_SSC_STEP_SIZE2 0x028
+#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x034
+#define QSERDES_COM_CLK_ENABLE1 0x038
+#define QSERDES_COM_SYS_CLK_CTRL 0x03c
+#define QSERDES_COM_SYSCLK_BUF_ENABLE 0x040
+#define QSERDES_COM_PLL_IVCO 0x048
+#define QSERDES_COM_LOCK_CMP1_MODE0 0x04c
+#define QSERDES_COM_LOCK_CMP2_MODE0 0x050
+#define QSERDES_COM_LOCK_CMP3_MODE0 0x054
+#define QSERDES_COM_LOCK_CMP1_MODE1 0x058
+#define QSERDES_COM_LOCK_CMP2_MODE1 0x05c
+#define QSERDES_COM_LOCK_CMP3_MODE1 0x060
+#define QSERDES_COM_BG_TRIM 0x070
+#define QSERDES_COM_CLK_EP_DIV 0x074
+#define QSERDES_COM_CP_CTRL_MODE0 0x078
+#define QSERDES_COM_CP_CTRL_MODE1 0x07c
+#define QSERDES_COM_PLL_RCTRL_MODE0 0x084
+#define QSERDES_COM_PLL_RCTRL_MODE1 0x088
+#define QSERDES_COM_PLL_CCTRL_MODE0 0x090
+#define QSERDES_COM_PLL_CCTRL_MODE1 0x094
+#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0x0a8
+#define QSERDES_COM_SYSCLK_EN_SEL 0x0ac
+#define QSERDES_COM_RESETSM_CNTRL 0x0b4
+#define QSERDES_COM_RESTRIM_CTRL 0x0bc
+#define QSERDES_COM_RESCODE_DIV_NUM 0x0c4
+#define QSERDES_COM_LOCK_CMP_EN 0x0c8
+#define QSERDES_COM_LOCK_CMP_CFG 0x0cc
+#define QSERDES_COM_DEC_START_MODE0 0x0d0
+#define QSERDES_COM_DEC_START_MODE1 0x0d4
+#define QSERDES_COM_DIV_FRAC_START1_MODE0 0x0dc
+#define QSERDES_COM_DIV_FRAC_START2_MODE0 0x0e0
+#define QSERDES_COM_DIV_FRAC_START3_MODE0 0x0e4
+#define QSERDES_COM_DIV_FRAC_START1_MODE1 0x0e8
+#define QSERDES_COM_DIV_FRAC_START2_MODE1 0x0ec
+#define QSERDES_COM_DIV_FRAC_START3_MODE1 0x0f0
+#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x108
+#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x10c
+#define QSERDES_COM_INTEGLOOP_GAIN0_MODE1 0x110
+#define QSERDES_COM_INTEGLOOP_GAIN1_MODE1 0x114
+#define QSERDES_COM_VCO_TUNE_CTRL 0x124
+#define QSERDES_COM_VCO_TUNE_MAP 0x128
+#define QSERDES_COM_VCO_TUNE1_MODE0 0x12c
+#define QSERDES_COM_VCO_TUNE2_MODE0 0x130
+#define QSERDES_COM_VCO_TUNE1_MODE1 0x134
+#define QSERDES_COM_VCO_TUNE2_MODE1 0x138
+#define QSERDES_COM_VCO_TUNE_TIMER1 0x144
+#define QSERDES_COM_VCO_TUNE_TIMER2 0x148
+#define QSERDES_COM_BG_CTRL 0x170
+#define QSERDES_COM_CLK_SELECT 0x174
+#define QSERDES_COM_HSCLK_SEL 0x178
+#define QSERDES_COM_CORECLK_DIV 0x184
+#define QSERDES_COM_CORE_CLK_EN 0x18c
+#define QSERDES_COM_C_READY_STATUS 0x190
+#define QSERDES_COM_CMN_CONFIG 0x194
+#define QSERDES_COM_SVS_MODE_CLK_SEL 0x19c
+#define QSERDES_COM_DEBUG_BUS0 0x1a0
+#define QSERDES_COM_DEBUG_BUS1 0x1a4
+#define QSERDES_COM_DEBUG_BUS2 0x1a8
+#define QSERDES_COM_DEBUG_BUS3 0x1ac
+#define QSERDES_COM_DEBUG_BUS_SEL 0x1b0
+#define QSERDES_COM_CORECLK_DIV_MODE1 0x1bc
+
+/* Only for QMP V2 PHY - TX registers */
+#define QSERDES_TX_RES_CODE_LANE_OFFSET 0x054
+#define QSERDES_TX_DEBUG_BUS_SEL 0x064
+#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x068
+#define QSERDES_TX_LANE_MODE 0x094
+#define QSERDES_TX_RCV_DETECT_LVL_2 0x0ac
+
+/* Only for QMP V2 PHY - RX registers */
+#define QSERDES_RX_UCDR_SO_GAIN_HALF 0x010
+#define QSERDES_RX_UCDR_SO_GAIN 0x01c
+#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN 0x040
+#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE 0x048
+#define QSERDES_RX_RX_TERM_BW 0x090
+#define QSERDES_RX_RX_EQ_GAIN1_LSB 0x0c4
+#define QSERDES_RX_RX_EQ_GAIN1_MSB 0x0c8
+#define QSERDES_RX_RX_EQ_GAIN2_LSB 0x0cc
+#define QSERDES_RX_RX_EQ_GAIN2_MSB 0x0d0
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d8
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 0x0dc
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 0x0e0
+#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x108
+#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x10c
+#define QSERDES_RX_SIGDET_ENABLES 0x110
+#define QSERDES_RX_SIGDET_CNTRL 0x114
+#define QSERDES_RX_SIGDET_LVL 0x118
+#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL 0x11c
+#define QSERDES_RX_RX_BAND 0x120
+#define QSERDES_RX_RX_INTERFACE_MODE 0x12c
+
+/* Only for QMP V2 PHY - PCS registers */
+#define QPHY_POWER_DOWN_CONTROL 0x04
+#define QPHY_TXDEEMPH_M6DB_V0 0x24
+#define QPHY_TXDEEMPH_M3P5DB_V0 0x28
+#define QPHY_ENDPOINT_REFCLK_DRIVE 0x54
+#define QPHY_RX_IDLE_DTCT_CNTRL 0x58
+#define QPHY_POWER_STATE_CONFIG1 0x60
+#define QPHY_POWER_STATE_CONFIG2 0x64
+#define QPHY_POWER_STATE_CONFIG4 0x6c
+#define QPHY_LOCK_DETECT_CONFIG1 0x80
+#define QPHY_LOCK_DETECT_CONFIG2 0x84
+#define QPHY_LOCK_DETECT_CONFIG3 0x88
+#define QPHY_PWRUP_RESET_DLY_TIME_AUXCLK 0xa0
+#define QPHY_LP_WAKEUP_DLY_TIME_AUXCLK 0xa4
+#define QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB 0x1A8
+#define QPHY_OSC_DTCT_ACTIONS 0x1AC
+#define QPHY_RX_SIGDET_LVL 0x1D8
+#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1DC
+#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1E0
+
+#endif
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 11/16] phy: qcom-qmp: Add register offsets for QMP V3 PHY
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (9 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 10/16] phy: qcom-qmp: Move register offsets to header file Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-03 11:28 ` [PATCH v4 12/16] dt-bindings: phy-qcom-qmp: Update bindings for QMP V3 USB PHY Manu Gautam
` (4 subsequent siblings)
15 siblings, 0 replies; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
open list:GENERIC PHY FRAMEWORK
Registers offsets for QMP V3 PHY are changed from
previous versions (1/2), update same in header file.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qmp.h | 149 ++++++++++++++++++++++++++++++++++++
1 file changed, 149 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index d930ca7..f7d4c2a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -134,4 +134,153 @@
#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1DC
#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1E0
+/* Only for QMP V3 PHY - DP COM registers */
+#define QPHY_V3_DP_COM_PHY_MODE_CTRL 0x00
+#define QPHY_V3_DP_COM_SW_RESET 0x04
+#define QPHY_V3_DP_COM_POWER_DOWN_CTRL 0x08
+#define QPHY_V3_DP_COM_SWI_CTRL 0x0c
+#define QPHY_V3_DP_COM_TYPEC_CTRL 0x10
+#define QPHY_V3_DP_COM_TYPEC_PWRDN_CTRL 0x14
+#define QPHY_V3_DP_COM_RESET_OVRD_CTRL 0x1c
+
+/* Only for QMP V3 PHY - QSERDES COM registers */
+#define QSERDES_V3_COM_BG_TIMER 0x00c
+#define QSERDES_V3_COM_SSC_EN_CENTER 0x010
+#define QSERDES_V3_COM_SSC_ADJ_PER1 0x014
+#define QSERDES_V3_COM_SSC_ADJ_PER2 0x018
+#define QSERDES_V3_COM_SSC_PER1 0x01c
+#define QSERDES_V3_COM_SSC_PER2 0x020
+#define QSERDES_V3_COM_SSC_STEP_SIZE1 0x024
+#define QSERDES_V3_COM_SSC_STEP_SIZE2 0x028
+#define QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN 0x034
+#define QSERDES_V3_COM_CLK_ENABLE1 0x038
+#define QSERDES_V3_COM_SYS_CLK_CTRL 0x03c
+#define QSERDES_V3_COM_SYSCLK_BUF_ENABLE 0x040
+#define QSERDES_V3_COM_PLL_IVCO 0x048
+#define QSERDES_V3_COM_LOCK_CMP1_MODE0 0x098
+#define QSERDES_V3_COM_LOCK_CMP2_MODE0 0x09c
+#define QSERDES_V3_COM_LOCK_CMP3_MODE0 0x0a0
+#define QSERDES_V3_COM_LOCK_CMP1_MODE1 0x0a4
+#define QSERDES_V3_COM_LOCK_CMP2_MODE1 0x0a8
+#define QSERDES_V3_COM_LOCK_CMP3_MODE1 0x0ac
+#define QSERDES_V3_COM_CLK_EP_DIV 0x05c
+#define QSERDES_V3_COM_CP_CTRL_MODE0 0x060
+#define QSERDES_V3_COM_CP_CTRL_MODE1 0x064
+#define QSERDES_V3_COM_PLL_RCTRL_MODE0 0x068
+#define QSERDES_V3_COM_PLL_RCTRL_MODE1 0x06c
+#define QSERDES_V3_COM_PLL_CCTRL_MODE0 0x070
+#define QSERDES_V3_COM_PLL_CCTRL_MODE1 0x074
+#define QSERDES_V3_COM_SYSCLK_EN_SEL 0x080
+#define QSERDES_V3_COM_RESETSM_CNTRL 0x088
+#define QSERDES_V3_COM_RESETSM_CNTRL2 0x08c
+#define QSERDES_V3_COM_LOCK_CMP_EN 0x090
+#define QSERDES_V3_COM_LOCK_CMP_CFG 0x094
+#define QSERDES_V3_COM_DEC_START_MODE0 0x0b0
+#define QSERDES_V3_COM_DEC_START_MODE1 0x0b4
+#define QSERDES_V3_COM_DIV_FRAC_START1_MODE0 0x0b8
+#define QSERDES_V3_COM_DIV_FRAC_START2_MODE0 0x0bc
+#define QSERDES_V3_COM_DIV_FRAC_START3_MODE0 0x0c0
+#define QSERDES_V3_COM_DIV_FRAC_START1_MODE1 0x0c4
+#define QSERDES_V3_COM_DIV_FRAC_START2_MODE1 0x0c8
+#define QSERDES_V3_COM_DIV_FRAC_START3_MODE1 0x0cc
+#define QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0 0x0d8
+#define QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0 0x0dc
+#define QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1 0x0e0
+#define QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1 0x0e4
+#define QSERDES_V3_COM_VCO_TUNE_CTRL 0x0ec
+#define QSERDES_V3_COM_VCO_TUNE_MAP 0x0f0
+#define QSERDES_V3_COM_VCO_TUNE1_MODE0 0x0f4
+#define QSERDES_V3_COM_VCO_TUNE2_MODE0 0x0f8
+#define QSERDES_V3_COM_VCO_TUNE1_MODE1 0x0fc
+#define QSERDES_V3_COM_VCO_TUNE2_MODE1 0x100
+#define QSERDES_V3_COM_VCO_TUNE_TIMER1 0x11c
+#define QSERDES_V3_COM_VCO_TUNE_TIMER2 0x120
+#define QSERDES_V3_COM_CLK_SELECT 0x138
+#define QSERDES_V3_COM_HSCLK_SEL 0x13c
+#define QSERDES_V3_COM_CORECLK_DIV_MODE0 0x148
+#define QSERDES_V3_COM_CORECLK_DIV_MODE1 0x14c
+#define QSERDES_V3_COM_CORE_CLK_EN 0x154
+#define QSERDES_V3_COM_C_READY_STATUS 0x158
+#define QSERDES_V3_COM_CMN_CONFIG 0x15c
+#define QSERDES_V3_COM_SVS_MODE_CLK_SEL 0x164
+#define QSERDES_V3_COM_DEBUG_BUS0 0x168
+#define QSERDES_V3_COM_DEBUG_BUS1 0x16c
+#define QSERDES_V3_COM_DEBUG_BUS2 0x170
+#define QSERDES_V3_COM_DEBUG_BUS3 0x174
+#define QSERDES_V3_COM_DEBUG_BUS_SEL 0x178
+
+/* Only for QMP V3 PHY - TX registers */
+#define QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX 0x044
+#define QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX 0x048
+#define QSERDES_V3_TX_DEBUG_BUS_SEL 0x058
+#define QSERDES_V3_TX_HIGHZ_DRVR_EN 0x060
+#define QSERDES_V3_TX_LANE_MODE_1 0x08c
+#define QSERDES_V3_TX_RCV_DETECT_LVL_2 0x0a4
+
+/* Only for QMP V3 PHY - RX registers */
+#define QSERDES_V3_RX_UCDR_SO_GAIN_HALF 0x00c
+#define QSERDES_V3_RX_UCDR_SO_GAIN 0x014
+#define QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN 0x030
+#define QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034
+#define QSERDES_V3_RX_RX_TERM_BW 0x07c
+#define QSERDES_V3_RX_RX_EQ_GAIN2_LSB 0x0c8
+#define QSERDES_V3_RX_RX_EQ_GAIN2_MSB 0x0cc
+#define QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d4
+#define QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3 0x0d8
+#define QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4 0x0dc
+#define QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x0f8
+#define QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x0fc
+#define QSERDES_V3_RX_SIGDET_ENABLES 0x100
+#define QSERDES_V3_RX_SIGDET_CNTRL 0x104
+#define QSERDES_V3_RX_SIGDET_LVL 0x108
+#define QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL 0x10c
+#define QSERDES_V3_RX_RX_BAND 0x110
+#define QSERDES_V3_RX_RX_INTERFACE_MODE 0x11c
+
+/* Only for QMP V3 PHY - PCS registers */
+#define QPHY_V3_PCS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V3_PCS_TXMGN_V0 0x00c
+#define QPHY_V3_PCS_TXMGN_V1 0x010
+#define QPHY_V3_PCS_TXMGN_V2 0x014
+#define QPHY_V3_PCS_TXMGN_V3 0x018
+#define QPHY_V3_PCS_TXMGN_V4 0x01c
+#define QPHY_V3_PCS_TXMGN_LS 0x020
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_V0 0x024
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0 0x028
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_V1 0x02c
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1 0x030
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_V2 0x034
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2 0x038
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_V3 0x03c
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3 0x040
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_V4 0x044
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4 0x048
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_LS 0x04c
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS 0x050
+#define QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE 0x054
+#define QPHY_V3_PCS_RX_IDLE_DTCT_CNTRL 0x058
+#define QPHY_V3_PCS_RATE_SLEW_CNTRL 0x05c
+#define QPHY_V3_PCS_POWER_STATE_CONFIG1 0x060
+#define QPHY_V3_PCS_POWER_STATE_CONFIG2 0x064
+#define QPHY_V3_PCS_POWER_STATE_CONFIG4 0x06c
+#define QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L 0x070
+#define QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H 0x074
+#define QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L 0x078
+#define QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H 0x07c
+#define QPHY_V3_PCS_LOCK_DETECT_CONFIG1 0x080
+#define QPHY_V3_PCS_LOCK_DETECT_CONFIG2 0x084
+#define QPHY_V3_PCS_LOCK_DETECT_CONFIG3 0x088
+#define QPHY_V3_PCS_TSYNC_RSYNC_TIME 0x08c
+#define QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK 0x0a0
+#define QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK 0x0a4
+#define QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK 0x0b0
+#define QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME 0x0b8
+#define QPHY_V3_PCS_RXEQTRAINING_RUN_TIME 0x0bc
+#define QPHY_V3_PCS_FLL_CNTRL1 0x0c4
+#define QPHY_V3_PCS_FLL_CNTRL2 0x0c8
+#define QPHY_V3_PCS_FLL_CNT_VAL_L 0x0cc
+#define QPHY_V3_PCS_FLL_CNT_VAL_H_TOL 0x0d0
+#define QPHY_V3_PCS_FLL_MAN_CODE 0x0d4
+#define QPHY_V3_PCS_RX_SIGDET_LVL 0x1d8
+
#endif
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 12/16] dt-bindings: phy-qcom-qmp: Update bindings for QMP V3 USB PHY
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (10 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 11/16] phy: qcom-qmp: Add register offsets for QMP V3 PHY Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-03 11:28 ` [PATCH v4 13/16] phy: qcom-qmp: Add support for QMP V3 USB3 PHY Manu Gautam
` (3 subsequent siblings)
15 siblings, 0 replies; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam, Rob Herring,
Mark Rutland, Vivek Gautam, Varadarajan Narayanan, Stephen Boyd,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
Update compatible string and clock names for QMP version V3
USB PHY.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index b6a9f2b..dcf1b8f 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -8,7 +8,8 @@ Required properties:
- compatible: compatible list, contains:
"qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074
"qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
- "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996.
+ "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996,
+ "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
- reg: offset and length of register set for PHY's common serdes block.
@@ -25,10 +26,13 @@ Required properties:
- clock-names: "cfg_ahb" for phy config clock,
"aux" for phy aux clock,
"ref" for 19.2 MHz ref clk,
+ "com_aux" for phy common block aux clock,
For "qcom,msm8996-qmp-pcie-phy" must contain:
"aux", "cfg_ahb", "ref".
For "qcom,msm8996-qmp-usb3-phy" must contain:
"aux", "cfg_ahb", "ref".
+ For "qcom,qmp-v3-usb3-phy" must contain:
+ "aux", "cfg_ahb", "ref", "com_aux".
- resets: a list of phandles and reset controller specifier pairs,
one for each entry in reset-names.
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 13/16] phy: qcom-qmp: Add support for QMP V3 USB3 PHY
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (11 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 12/16] dt-bindings: phy-qcom-qmp: Update bindings for QMP V3 USB PHY Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-03 11:28 ` [PATCH v4 14/16] phy: Add USB speed related PHY modes Manu Gautam
` (2 subsequent siblings)
15 siblings, 0 replies; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
Vivek Gautam, Varadarajan Narayanan, Stephen Boyd, Wei Yongjun,
Fengguang Wu, open list:GENERIC PHY FRAMEWORK
QMP V3 USB3 PHY is a DisplayPort (DP) and USB combo PHY
with dual RX/TX lanes to support type-c. There is a
separate block DP_COM for configuration related to type-c
or DP. Add support for dp_com region and secondary rx/tx
lanes initialization.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qmp.c | 223 +++++++++++++++++++++++++++++++++++-
1 file changed, 220 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 2a1117b..55b8397 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -47,6 +47,21 @@
/* QPHY_COM_PCS_READY_STATUS bit */
#define PCS_READY BIT(0)
+/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
+/* DP PHY soft reset */
+#define SW_DPPHY_RESET BIT(0)
+/* mux to select DP PHY reset control, 0:HW control, 1: software reset */
+#define SW_DPPHY_RESET_MUX BIT(1)
+/* USB3 PHY soft reset */
+#define SW_USB3PHY_RESET BIT(2)
+/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
+#define SW_USB3PHY_RESET_MUX BIT(3)
+
+/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
+#define USB3_MODE BIT(0) /* enables USB3 mode */
+#define DP_MODE BIT(1) /* enables DP mode */
+
+
#define PHY_INIT_COMPLETE_TIMEOUT 1000
#define POWER_DOWN_DELAY_US_MIN 10
#define POWER_DOWN_DELAY_US_MAX 11
@@ -122,6 +137,12 @@ enum qphy_reg_layout {
[QPHY_PCS_READY_STATUS] = 0x17c,
};
+static const unsigned int qmp_v3_usb3phy_regs_layout[] = {
+ [QPHY_SW_RESET] = 0x00,
+ [QPHY_START_CTRL] = 0x08,
+ [QPHY_PCS_READY_STATUS] = 0x174,
+};
+
static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
@@ -350,6 +371,112 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
};
+static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
+ QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
+ /* FLL settings */
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
+
+ /* Lock Det settings */
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
+
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0xba),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x1d),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
+
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
+};
+
/* struct qmp_phy_cfg - per-PHY initialization config */
struct qmp_phy_cfg {
/* phy-type - PCIE/UFS/USB */
@@ -394,6 +521,12 @@ struct qmp_phy_cfg {
/* power_down delay in usec */
int pwrdn_delay_min;
int pwrdn_delay_max;
+
+ /* true, if PHY has a separate DP_COM control block */
+ bool has_phy_dp_com_ctrl;
+ /* Register offset of secondary tx/rx lanes for USB DP combo PHY */
+ unsigned int tx_b_lane_offset;
+ unsigned int rx_b_lane_offset;
};
/**
@@ -424,6 +557,7 @@ struct qmp_phy {
*
* @dev: device
* @serdes: iomapped memory space for phy's serdes
+ * @dp_com: iomapped memory space for phy's dp_com control block
*
* @clks: array of clocks required by phy
* @resets: array of resets required by phy
@@ -437,6 +571,7 @@ struct qmp_phy {
struct qcom_qmp {
struct device *dev;
void __iomem *serdes;
+ void __iomem *dp_com;
struct clk_bulk_data *clks;
struct reset_control **resets;
@@ -478,6 +613,10 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
"aux", "cfg_ahb", "ref",
};
+static const char * const qmp_v3_phy_clk_l[] = {
+ "aux", "cfg_ahb", "ref", "com_aux",
+};
+
/* list of resets */
static const char * const msm8996_pciephy_reset_l[] = {
"phy", "common", "cfg",
@@ -584,6 +723,38 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
.pwrdn_delay_max = 1005, /* us */
};
+static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
+ .type = PHY_TYPE_USB3,
+ .nlanes = 1,
+
+ .serdes_tbl = qmp_v3_usb3_serdes_tbl,
+ .serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl),
+ .tx_tbl = qmp_v3_usb3_tx_tbl,
+ .tx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_tx_tbl),
+ .rx_tbl = qmp_v3_usb3_rx_tbl,
+ .rx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_rx_tbl),
+ .pcs_tbl = qmp_v3_usb3_pcs_tbl,
+ .pcs_tbl_num = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl),
+ .clk_list = qmp_v3_phy_clk_l,
+ .num_clks = ARRAY_SIZE(qmp_v3_phy_clk_l),
+ .reset_list = msm8996_usb3phy_reset_l,
+ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = msm8996_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(msm8996_phy_vreg_l),
+ .regs = qmp_v3_usb3phy_regs_layout,
+
+ .start_ctrl = SERDES_START | PCS_START,
+ .pwrdn_ctrl = SW_PWRDN,
+ .mask_pcs_ready = PHYSTATUS,
+
+ .pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
+ .pwrdn_delay_max = POWER_DOWN_DELAY_US_MAX,
+
+ .has_phy_dp_com_ctrl = true,
+ .tx_b_lane_offset = 0x400,
+ .rx_b_lane_offset = 0x400,
+};
+
static void qcom_qmp_phy_configure(void __iomem *base,
const unsigned int *regs,
const struct qmp_phy_init_tbl tbl[],
@@ -620,6 +791,7 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
void __iomem *serdes = qmp->serdes;
+ void __iomem *dp_com = qmp->dp_com;
int ret, i;
mutex_lock(&qmp->phy_mutex);
@@ -663,6 +835,23 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
SW_PWRDN);
+ if (cfg->has_phy_dp_com_ctrl) {
+ qphy_setbits(dp_com, QPHY_V3_DP_COM_POWER_DOWN_CTRL,
+ SW_PWRDN);
+ /* override hardware control for reset of qmp phy */
+ qphy_setbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
+ SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
+ SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
+
+ qphy_setbits(dp_com, QPHY_V3_DP_COM_PHY_MODE_CTRL,
+ USB3_MODE | DP_MODE);
+
+ /* bring both QMP USB and QMP DP PHYs PCS block out of reset */
+ qphy_clrbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
+ SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
+ SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
+ }
+
/* Serdes configuration */
qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl,
cfg->serdes_tbl_num);
@@ -746,6 +935,7 @@ static int qcom_qmp_phy_init(struct phy *phy)
void __iomem *tx = qphy->tx;
void __iomem *rx = qphy->rx;
void __iomem *pcs = qphy->pcs;
+ void __iomem *dp_com = qmp->dp_com;
void __iomem *status;
unsigned int mask, val;
int ret;
@@ -767,7 +957,16 @@ static int qcom_qmp_phy_init(struct phy *phy)
/* Tx, Rx, and PCS configurations */
qcom_qmp_phy_configure(tx, cfg->regs, cfg->tx_tbl, cfg->tx_tbl_num);
+ /* Configuration for other LANE for USB-DP combo PHY */
+ if (cfg->has_phy_dp_com_ctrl)
+ qcom_qmp_phy_configure(tx + cfg->tx_b_lane_offset, cfg->regs,
+ cfg->tx_tbl, cfg->tx_tbl_num);
+
qcom_qmp_phy_configure(rx, cfg->regs, cfg->rx_tbl, cfg->rx_tbl_num);
+ if (cfg->has_phy_dp_com_ctrl)
+ qcom_qmp_phy_configure(rx + cfg->rx_b_lane_offset, cfg->regs,
+ cfg->rx_tbl, cfg->rx_tbl_num);
+
qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
/*
@@ -781,6 +980,8 @@ static int qcom_qmp_phy_init(struct phy *phy)
/* Pull PHY out of reset state */
qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
+ if (cfg->has_phy_dp_com_ctrl)
+ qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
/* start SerDes and Phy-Coding-Sublayer */
qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
@@ -1031,6 +1232,9 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
}, {
.compatible = "qcom,ipq8074-qmp-pcie-phy",
.data = &ipq8074_pciephy_cfg,
+ }, {
+ .compatible = "qcom,qmp-v3-usb3-phy",
+ .data = &qmp_v3_usb3phy_cfg,
},
{ },
};
@@ -1054,6 +1258,11 @@ static int qcom_qmp_phy_probe(struct platform_device *pdev)
qmp->dev = dev;
dev_set_drvdata(dev, qmp);
+ /* Get the specific init parameters of QMP phy */
+ qmp->cfg = of_device_get_match_data(dev);
+ if (!qmp->cfg)
+ return -EINVAL;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
@@ -1062,10 +1271,18 @@ static int qcom_qmp_phy_probe(struct platform_device *pdev)
/* per PHY serdes; usually located at base address */
qmp->serdes = base;
- mutex_init(&qmp->phy_mutex);
+ /* per PHY dp_com; if PHY has dp_com control block */
+ if (qmp->cfg->has_phy_dp_com_ctrl) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "dp_com");
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
- /* Get the specific init parameters of QMP phy */
- qmp->cfg = of_device_get_match_data(dev);
+ qmp->dp_com = base;
+ }
+
+ mutex_init(&qmp->phy_mutex);
ret = qcom_qmp_phy_clk_init(dev);
if (ret)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 14/16] phy: Add USB speed related PHY modes
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (12 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 13/16] phy: qcom-qmp: Add support for QMP V3 USB3 PHY Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-05 11:01 ` Kishon Vijay Abraham I
2018-01-03 11:28 ` [PATCH v4 15/16] phy: qcom-qusb2: Add support for runtime PM Manu Gautam
2018-01-03 11:28 ` [PATCH v4 16/16] phy: qcom-qmp: " Manu Gautam
15 siblings, 1 reply; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
open list:GENERIC PHY FRAMEWORK
Add following USB speed related PHY modes:
LS (Low Speed), FS (Full Speed), HS (High Speed), SS (Super Speed)
Speed related information is required by some QCOM PHY drivers
to program PHY monitor resume/remote-wakeup events in suspended
state. Speed is needed in order to set correct polarity of wakeup
events for detection. E.g. QUSB2 PHY monitors DP/DM line state
depending on whether speed is LS or FS/HS to detect resume.
Similarly QMP USB3 PHY in SS mode should monitor RX terminations
attach/detach and LFPS events depending on SSPHY is active or not.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/phy-core.c | 15 +++++++++++++++
include/linux/phy/phy.h | 32 ++++++++++++++++++++++++--------
2 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index b4964b0..e4f0525 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -357,6 +357,21 @@ int phy_set_mode(struct phy *phy, enum phy_mode mode)
}
EXPORT_SYMBOL_GPL(phy_set_mode);
+enum phy_mode phy_get_mode(struct phy *phy)
+{
+ enum phy_mode ret;
+
+ if (!phy || !phy->ops->get_mode)
+ return PHY_MODE_INVALID;
+
+ mutex_lock(&phy->mutex);
+ ret = phy->ops->get_mode(phy);
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_get_mode);
+
int phy_reset(struct phy *phy)
{
int ret;
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index d8da3e5..4a5cbd0 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -25,7 +25,15 @@
enum phy_mode {
PHY_MODE_INVALID,
PHY_MODE_USB_HOST,
+ PHY_MODE_USB_HOST_LS,
+ PHY_MODE_USB_HOST_FS,
+ PHY_MODE_USB_HOST_HS,
+ PHY_MODE_USB_HOST_SS,
PHY_MODE_USB_DEVICE,
+ PHY_MODE_USB_DEVICE_LS,
+ PHY_MODE_USB_DEVICE_FS,
+ PHY_MODE_USB_DEVICE_HS,
+ PHY_MODE_USB_DEVICE_SS,
PHY_MODE_USB_OTG,
PHY_MODE_SGMII,
PHY_MODE_10GKR,
@@ -40,19 +48,21 @@ enum phy_mode {
* @power_on: powering on the phy
* @power_off: powering off the phy
* @set_mode: set the mode of the phy
+ * @get_mode: get current mode of PHY
* @reset: resetting the phy
* @calibrate: calibrate the phy
* @owner: the module owner containing the ops
*/
struct phy_ops {
- int (*init)(struct phy *phy);
- int (*exit)(struct phy *phy);
- int (*power_on)(struct phy *phy);
- int (*power_off)(struct phy *phy);
- int (*set_mode)(struct phy *phy, enum phy_mode mode);
- int (*reset)(struct phy *phy);
- int (*calibrate)(struct phy *phy);
- struct module *owner;
+ int (*init)(struct phy *phy);
+ int (*exit)(struct phy *phy);
+ int (*power_on)(struct phy *phy);
+ int (*power_off)(struct phy *phy);
+ int (*set_mode)(struct phy *phy, enum phy_mode mode);
+ enum phy_mode (*get_mode)(struct phy *phy);
+ int (*reset)(struct phy *phy);
+ int (*calibrate)(struct phy *phy);
+ struct module *owner;
};
/**
@@ -144,6 +154,7 @@ static inline void *phy_get_drvdata(struct phy *phy)
int phy_power_on(struct phy *phy);
int phy_power_off(struct phy *phy);
int phy_set_mode(struct phy *phy, enum phy_mode mode);
+enum phy_mode phy_get_mode(struct phy *phy);
int phy_reset(struct phy *phy);
int phy_calibrate(struct phy *phy);
static inline int phy_get_bus_width(struct phy *phy)
@@ -260,6 +271,11 @@ static inline int phy_set_mode(struct phy *phy, enum phy_mode mode)
return -ENOSYS;
}
+static inline enum phy_mode phy_get_mode(struct phy *phy)
+{
+ return PHY_MODE_INVALID;
+}
+
static inline int phy_reset(struct phy *phy)
{
if (!phy)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 15/16] phy: qcom-qusb2: Add support for runtime PM
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (13 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 14/16] phy: Add USB speed related PHY modes Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
2018-01-03 11:28 ` [PATCH v4 16/16] phy: qcom-qmp: " Manu Gautam
15 siblings, 0 replies; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
Vivek Gautam, Jaehoon Chung, Heiko Stuebner,
open list:GENERIC PHY FRAMEWORK
Disable clocks and enable DP/DM wakeup interrupts when
suspending PHY.
Core driver should notify speed to PHY driver to enable
appropriate DP/DM wakeup interrupts polarity in suspend state.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qusb2.c | 184 ++++++++++++++++++++++++++++++++++
1 file changed, 184 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 8d0579e..3a9e4bd 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -56,6 +56,18 @@
#define PHY_CLK_SCHEME_SEL BIT(0)
+/* QUSB2PHY_INTR_CTRL register bits */
+#define DMSE_INTR_HIGH_SEL BIT(4)
+#define DPSE_INTR_HIGH_SEL BIT(3)
+#define CHG_DET_INTR_EN BIT(2)
+#define DMSE_INTR_EN BIT(1)
+#define DPSE_INTR_EN BIT(0)
+
+/* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE register bits */
+#define CORE_PLL_EN_FROM_RESET BIT(4)
+#define CORE_RESET BIT(5)
+#define CORE_RESET_MUX BIT(6)
+
#define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO 0x04
#define QUSB2PHY_PLL_CLOCK_INVERTERS 0x18c
#define QUSB2PHY_PLL_CMODE 0x2c
@@ -93,6 +105,7 @@ struct qusb2_phy_init_tbl {
/* set of registers with offsets different per-PHY */
enum qusb2phy_reg_layout {
+ QUSB2PHY_PLL_CORE_INPUT_OVERRIDE,
QUSB2PHY_PLL_STATUS,
QUSB2PHY_PORT_TUNE1,
QUSB2PHY_PORT_TUNE2,
@@ -112,8 +125,10 @@ enum qusb2phy_reg_layout {
[QUSB2PHY_PORT_TUNE3] = 0x88,
[QUSB2PHY_PORT_TUNE4] = 0x8c,
[QUSB2PHY_PORT_TUNE5] = 0x90,
+ [QUSB2PHY_PORT_TEST1] = 0xb8,
[QUSB2PHY_PORT_TEST2] = 0x9c,
[QUSB2PHY_PORT_POWERDOWN] = 0xb4,
+ [QUSB2PHY_INTR_CTRL] = 0xbc,
};
static const struct qusb2_phy_init_tbl msm8996_init_tbl[] = {
@@ -133,14 +148,17 @@ enum qusb2phy_reg_layout {
};
static const unsigned int qusb2_v2_regs_layout[] = {
+ [QUSB2PHY_PLL_CORE_INPUT_OVERRIDE] = 0xa8,
[QUSB2PHY_PLL_STATUS] = 0x1a0,
[QUSB2PHY_PORT_TUNE1] = 0x240,
[QUSB2PHY_PORT_TUNE2] = 0x244,
[QUSB2PHY_PORT_TUNE3] = 0x248,
[QUSB2PHY_PORT_TUNE4] = 0x24c,
[QUSB2PHY_PORT_TUNE5] = 0x250,
+ [QUSB2PHY_PORT_TEST1] = 0x254,
[QUSB2PHY_PORT_TEST2] = 0x258,
[QUSB2PHY_PORT_POWERDOWN] = 0x210,
+ [QUSB2PHY_INTR_CTRL] = 0x230,
};
static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = {
@@ -175,12 +193,16 @@ struct qusb2_phy_cfg {
const unsigned int *regs;
unsigned int mask_core_ready;
unsigned int disable_ctrl;
+ unsigned int autoresume_en;
/* true if PHY has PLL_TEST register to select clk_scheme */
bool has_pll_test;
/* true if TUNE1 register must be updated by fused value, else TUNE2 */
bool update_tune1_with_efuse;
+
+ /* true if PHY has PLL_CORE_INPUT_OVERRIDE register to reset PLL */
+ bool has_pll_override;
};
static const struct qusb2_phy_cfg msm8996_phy_cfg = {
@@ -191,6 +213,7 @@ struct qusb2_phy_cfg {
.has_pll_test = true,
.disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
.mask_core_ready = PLL_LOCKED,
+ .autoresume_en = BIT(3),
};
static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
@@ -201,6 +224,8 @@ struct qusb2_phy_cfg {
.disable_ctrl = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
POWER_DOWN),
.mask_core_ready = CORE_READY_STATUS,
+ .has_pll_override = true,
+ .autoresume_en = BIT(0),
};
static const char * const qusb2_phy_vreg_names[] = {
@@ -226,6 +251,8 @@ struct qusb2_phy_cfg {
*
* @cfg: phy config data
* @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
+ * @phy_initialized: indicate if PHY has been initialized
+ * @mode: current PHY mode
*/
struct qusb2_phy {
struct phy *phy;
@@ -242,6 +269,8 @@ struct qusb2_phy {
const struct qusb2_phy_cfg *cfg;
bool has_se_clk_scheme;
+ bool phy_initialized;
+ enum phy_mode mode;
};
static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
@@ -317,6 +346,140 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy)
}
+static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
+{
+ struct qusb2_phy *qphy = phy_get_drvdata(phy);
+
+ qphy->mode = mode;
+
+ return 0;
+}
+
+static enum phy_mode qusb2_phy_get_mode(struct phy *phy)
+{
+ struct qusb2_phy *qphy = phy_get_drvdata(phy);
+
+ return qphy->mode;
+}
+
+static int __maybe_unused qusb2_phy_runtime_suspend(struct device *dev)
+{
+ struct qusb2_phy *qphy = dev_get_drvdata(dev);
+ const struct qusb2_phy_cfg *cfg = qphy->cfg;
+ u32 intr_mask;
+
+ dev_vdbg(dev, "Suspending QUSB2 Phy, mode:%d\n", qphy->mode);
+
+ if (!qphy->phy_initialized) {
+ dev_vdbg(dev, "PHY not initialized, bailing out\n");
+ return 0;
+ }
+
+ /*
+ * Enable DP/DM interrupts to detect line state changes based on current
+ * speed. In other words, enable the triggers _opposite_ of what the
+ * current D+/D- levels are e.g. if currently D+ high, D- low
+ * (HS 'J'/Suspend), configure the mask to trigger on D+ low OR D- high
+ */
+ intr_mask = DPSE_INTR_EN | DMSE_INTR_EN;
+ switch (qphy->mode) {
+ case PHY_MODE_USB_HOST_HS:
+ case PHY_MODE_USB_HOST_FS:
+ case PHY_MODE_USB_DEVICE_HS:
+ case PHY_MODE_USB_DEVICE_FS:
+ intr_mask |= DMSE_INTR_HIGH_SEL;
+ break;
+ case PHY_MODE_USB_HOST_LS:
+ case PHY_MODE_USB_DEVICE_LS:
+ intr_mask |= DPSE_INTR_HIGH_SEL;
+ break;
+ default:
+ /* No device connected, enable both DP/DM high interrupt */
+ intr_mask |= DMSE_INTR_HIGH_SEL;
+ intr_mask |= DPSE_INTR_HIGH_SEL;
+ break;
+ }
+
+ writel(intr_mask, qphy->base + cfg->regs[QUSB2PHY_INTR_CTRL]);
+
+ /* hold core PLL into reset */
+ if (cfg->has_pll_override) {
+ qusb2_setbits(qphy->base,
+ cfg->regs[QUSB2PHY_PLL_CORE_INPUT_OVERRIDE],
+ CORE_PLL_EN_FROM_RESET | CORE_RESET |
+ CORE_RESET_MUX);
+ }
+
+ /* enable phy auto-resume only if device is connected on bus */
+ if (qphy->mode != PHY_MODE_INVALID) {
+ qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TEST1],
+ cfg->autoresume_en);
+ /* Autoresume bit has to be toggled in order to enable it */
+ qusb2_clrbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TEST1],
+ cfg->autoresume_en);
+ }
+
+ if (!qphy->has_se_clk_scheme)
+ clk_disable_unprepare(qphy->ref_clk);
+
+ clk_disable_unprepare(qphy->cfg_ahb_clk);
+ clk_disable_unprepare(qphy->iface_clk);
+
+ return 0;
+}
+
+static int __maybe_unused qusb2_phy_runtime_resume(struct device *dev)
+{
+ struct qusb2_phy *qphy = dev_get_drvdata(dev);
+ const struct qusb2_phy_cfg *cfg = qphy->cfg;
+ int ret;
+
+ dev_vdbg(dev, "Resuming QUSB2 phy, mode:%d\n", qphy->mode);
+
+ if (!qphy->phy_initialized) {
+ dev_vdbg(dev, "PHY not initialized, bailing out\n");
+ return 0;
+ }
+
+ ret = clk_prepare_enable(qphy->iface_clk);
+ if (ret) {
+ dev_err(dev, "failed to enable iface_clk, %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(qphy->cfg_ahb_clk);
+ if (ret) {
+ dev_err(dev, "failed to enable cfg ahb clock, %d\n", ret);
+ goto disable_iface_clk;
+ }
+
+ if (!qphy->has_se_clk_scheme) {
+ clk_prepare_enable(qphy->ref_clk);
+ if (ret) {
+ dev_err(dev, "failed to enable ref clk, %d\n", ret);
+ goto disable_ahb_clk;
+ }
+ }
+
+ writel(0x0, qphy->base + cfg->regs[QUSB2PHY_INTR_CTRL]);
+
+ /* bring core PLL out of reset */
+ if (cfg->has_pll_override) {
+ qusb2_clrbits(qphy->base,
+ cfg->regs[QUSB2PHY_PLL_CORE_INPUT_OVERRIDE],
+ CORE_RESET | CORE_RESET_MUX);
+ }
+
+ return 0;
+
+disable_ahb_clk:
+ clk_disable_unprepare(qphy->cfg_ahb_clk);
+disable_iface_clk:
+ clk_disable_unprepare(qphy->iface_clk);
+
+ return ret;
+}
+
static int qusb2_phy_init(struct phy *phy)
{
struct qusb2_phy *qphy = phy_get_drvdata(phy);
@@ -441,6 +604,7 @@ static int qusb2_phy_init(struct phy *phy)
ret = -EBUSY;
goto disable_ref_clk;
}
+ qphy->phy_initialized = true;
return 0;
@@ -477,12 +641,16 @@ static int qusb2_phy_exit(struct phy *phy)
regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
+ qphy->phy_initialized = false;
+
return 0;
}
static const struct phy_ops qusb2_phy_gen_ops = {
.init = qusb2_phy_init,
.exit = qusb2_phy_exit,
+ .set_mode = qusb2_phy_set_mode,
+ .get_mode = qusb2_phy_get_mode,
.owner = THIS_MODULE,
};
@@ -498,6 +666,11 @@ static int qusb2_phy_exit(struct phy *phy)
};
MODULE_DEVICE_TABLE(of, qusb2_phy_of_match_table);
+static const struct dev_pm_ops qusb2_phy_pm_ops = {
+ SET_RUNTIME_PM_OPS(qusb2_phy_runtime_suspend,
+ qusb2_phy_runtime_resume, NULL)
+};
+
static int qusb2_phy_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -575,11 +748,19 @@ static int qusb2_phy_probe(struct platform_device *pdev)
qphy->cell = NULL;
dev_dbg(dev, "failed to lookup tune2 hstx trim value\n");
}
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ /*
+ * Prevent runtime pm from being ON by default. Users can enable
+ * it using power/control in sysfs.
+ */
+ pm_runtime_forbid(dev);
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);
+ pm_runtime_disable(dev);
return ret;
}
qphy->phy = generic_phy;
@@ -590,6 +771,8 @@ static int qusb2_phy_probe(struct platform_device *pdev)
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");
+ else
+ pm_runtime_disable(dev);
return PTR_ERR_OR_ZERO(phy_provider);
}
@@ -598,6 +781,7 @@ static int qusb2_phy_probe(struct platform_device *pdev)
.probe = qusb2_phy_probe,
.driver = {
.name = "qcom-qusb2-phy",
+ .pm = &qusb2_phy_pm_ops,
.of_match_table = qusb2_phy_of_match_table,
},
};
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v4 16/16] phy: qcom-qmp: Add support for runtime PM
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
` (14 preceding siblings ...)
2018-01-03 11:28 ` [PATCH v4 15/16] phy: qcom-qusb2: Add support for runtime PM Manu Gautam
@ 2018-01-03 11:28 ` Manu Gautam
15 siblings, 0 replies; 26+ messages in thread
From: Manu Gautam @ 2018-01-03 11:28 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, Manu Gautam,
Vivek Gautam, Varadarajan Narayanan, Wei Yongjun, Fengguang Wu,
open list:GENERIC PHY FRAMEWORK
Disable clocks and enable PHY autonomous mode to detect
wakeup events when PHY is suspended.
Core driver should notify speed to PHY driver to enable
LFPS and/or RX_DET interrupts.
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
---
drivers/phy/qualcomm/phy-qcom-qmp.c | 186 +++++++++++++++++++++++++++++++++++-
drivers/phy/qualcomm/phy-qcom-qmp.h | 3 +
2 files changed, 188 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 55b8397..ad3251b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -61,6 +61,19 @@
#define USB3_MODE BIT(0) /* enables USB3 mode */
#define DP_MODE BIT(1) /* enables DP mode */
+/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
+#define ARCVR_DTCT_EN BIT(0)
+#define ALFPS_DTCT_EN BIT(1)
+#define ARCVR_DTCT_EVENT_SEL BIT(4)
+
+/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
+#define IRQ_CLEAR BIT(0)
+
+/* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
+#define RCVR_DETECT BIT(0)
+
+/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
+#define CLAMP_EN BIT(0) /* enables i/o clamp_n */
#define PHY_INIT_COMPLETE_TIMEOUT 1000
#define POWER_DOWN_DELAY_US_MIN 10
@@ -108,6 +121,9 @@ enum qphy_reg_layout {
QPHY_SW_RESET,
QPHY_START_CTRL,
QPHY_PCS_READY_STATUS,
+ QPHY_PCS_AUTONOMOUS_MODE_CTRL,
+ QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
+ QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
};
static const unsigned int pciephy_regs_layout[] = {
@@ -135,12 +151,18 @@ enum qphy_reg_layout {
[QPHY_SW_RESET] = 0x00,
[QPHY_START_CTRL] = 0x08,
[QPHY_PCS_READY_STATUS] = 0x17c,
+ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x0d8,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178,
};
static const unsigned int qmp_v3_usb3phy_regs_layout[] = {
[QPHY_SW_RESET] = 0x00,
[QPHY_START_CTRL] = 0x08,
[QPHY_PCS_READY_STATUS] = 0x174,
+ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = 0x0dc,
+ [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
};
static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
@@ -536,6 +558,7 @@ struct qmp_phy_cfg {
* @tx: iomapped memory space for lane's tx
* @rx: iomapped memory space for lane's rx
* @pcs: iomapped memory space for lane's pcs
+ * @pcs_misc: iomapped memory space for lane's pcs_misc
* @pipe_clk: pipe lock
* @index: lane index
* @qmp: QMP phy to which this lane belongs
@@ -546,6 +569,7 @@ struct qmp_phy {
void __iomem *tx;
void __iomem *rx;
void __iomem *pcs;
+ void __iomem *pcs_misc;
struct clk *pipe_clk;
unsigned int index;
struct qcom_qmp *qmp;
@@ -567,6 +591,8 @@ struct qmp_phy {
* @phys: array of per-lane phy descriptors
* @phy_mutex: mutex lock for PHY common block initialization
* @init_count: phy common block initialization count
+ * @phy_initialized: indicate if PHY has been initialized
+ * @mode: current PHY mode
*/
struct qcom_qmp {
struct device *dev;
@@ -582,6 +608,8 @@ struct qcom_qmp {
struct mutex phy_mutex;
int init_count;
+ bool phy_initialized;
+ enum phy_mode mode;
};
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
@@ -995,6 +1023,7 @@ static int qcom_qmp_phy_init(struct phy *phy)
dev_err(qmp->dev, "phy initialization timed-out\n");
goto err_pcs_ready;
}
+ qmp->phy_initialized = true;
return ret;
@@ -1029,6 +1058,136 @@ static int qcom_qmp_phy_exit(struct phy *phy)
qcom_qmp_phy_com_exit(qmp);
+ qmp->phy_initialized = false;
+
+ return 0;
+}
+
+static int qcom_qmp_phy_set_mode(struct phy *phy, enum phy_mode mode)
+{
+ struct qmp_phy *qphy = phy_get_drvdata(phy);
+ struct qcom_qmp *qmp = qphy->qmp;
+
+ qmp->mode = mode;
+
+ return 0;
+}
+
+static enum phy_mode qcom_qmp_phy_get_mode(struct phy *phy)
+{
+ struct qmp_phy *qphy = phy_get_drvdata(phy);
+ struct qcom_qmp *qmp = qphy->qmp;
+
+ return qmp->mode;
+}
+
+static void qcom_qmp_phy_enable_autonomous_mode(struct qmp_phy *qphy)
+{
+ struct qcom_qmp *qmp = qphy->qmp;
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ void __iomem *pcs = qphy->pcs;
+ void __iomem *pcs_misc = qphy->pcs_misc;
+ u32 intr_mask;
+
+ if (qmp->mode == PHY_MODE_USB_HOST_SS ||
+ qmp->mode == PHY_MODE_USB_DEVICE_SS)
+ intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
+ else
+ intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
+
+ /* Clear any pending interrupts status */
+ qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+ /* Writing 1 followed by 0 clears the interrupt */
+ qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+
+ qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
+ ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);
+
+ /* Enable required PHY autonomous mode interrupts */
+ qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
+
+ /* Enable i/o clamp_n for autonomous mode */
+ if (pcs_misc)
+ qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
+}
+
+static void qcom_qmp_phy_disable_autonomous_mode(struct qmp_phy *qphy)
+{
+ struct qcom_qmp *qmp = qphy->qmp;
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ void __iomem *pcs = qphy->pcs;
+ void __iomem *pcs_misc = qphy->pcs_misc;
+
+ /* Disable i/o clamp_n on resume for normal mode */
+ if (pcs_misc)
+ qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
+
+ qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
+ ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
+
+ qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+ /* Writing 1 followed by 0 clears the interrupt */
+ qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+}
+
+static int __maybe_unused qcom_qmp_phy_runtime_suspend(struct device *dev)
+{
+ struct qcom_qmp *qmp = dev_get_drvdata(dev);
+ struct qmp_phy *qphy = qmp->phys[0];
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+
+ dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
+
+ /* Supported only for USB3 PHY */
+ if (cfg->type != PHY_TYPE_USB3)
+ return 0;
+
+ if (!qmp->phy_initialized) {
+ dev_vdbg(dev, "PHY not initialized, bailing out\n");
+ return 0;
+ }
+
+ qcom_qmp_phy_enable_autonomous_mode(qphy);
+
+ clk_disable_unprepare(qphy->pipe_clk);
+ clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
+
+ return 0;
+}
+
+static int __maybe_unused qcom_qmp_phy_runtime_resume(struct device *dev)
+{
+ struct qcom_qmp *qmp = dev_get_drvdata(dev);
+ struct qmp_phy *qphy = qmp->phys[0];
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ int ret = 0;
+
+ dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
+
+ /* Supported only for USB3 PHY */
+ if (cfg->type != PHY_TYPE_USB3)
+ return 0;
+
+ if (!qmp->phy_initialized) {
+ dev_vdbg(dev, "PHY not initialized, bailing out\n");
+ return 0;
+ }
+
+ ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
+ if (ret) {
+ dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(qphy->pipe_clk);
+ if (ret) {
+ dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
+ clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
+ return ret;
+ }
+
+ qcom_qmp_phy_disable_autonomous_mode(qphy);
+
return 0;
}
@@ -1142,6 +1301,8 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
.init = qcom_qmp_phy_init,
.exit = qcom_qmp_phy_exit,
.power_on = qcom_qmp_phy_poweron,
+ .set_mode = qcom_qmp_phy_set_mode,
+ .get_mode = qcom_qmp_phy_get_mode,
.owner = THIS_MODULE,
};
@@ -1160,7 +1321,8 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
/*
* Get memory resources for each phy lane:
- * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
+ * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2; and
+ * pcs_misc (optional) -> 3.
*/
qphy->tx = of_iomap(np, 0);
if (!qphy->tx)
@@ -1174,6 +1336,10 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
if (!qphy->pcs)
return -ENOMEM;
+ qphy->pcs_misc = of_iomap(np, 3);
+ if (!qphy->pcs_misc)
+ dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
+
/*
* Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
* based phys, so they essentially have pipe clock. So,
@@ -1240,6 +1406,11 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
};
MODULE_DEVICE_TABLE(of, qcom_qmp_phy_of_match_table);
+static const struct dev_pm_ops qcom_qmp_phy_pm_ops = {
+ SET_RUNTIME_PM_OPS(qcom_qmp_phy_runtime_suspend,
+ qcom_qmp_phy_runtime_resume, NULL)
+};
+
static int qcom_qmp_phy_probe(struct platform_device *pdev)
{
struct qcom_qmp *qmp;
@@ -1308,12 +1479,21 @@ static int qcom_qmp_phy_probe(struct platform_device *pdev)
return -ENOMEM;
id = 0;
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ /*
+ * Prevent runtime pm from being ON by default. Users can enable
+ * it using power/control in sysfs.
+ */
+ pm_runtime_forbid(dev);
+
for_each_available_child_of_node(dev->of_node, child) {
/* Create per-lane phy */
ret = qcom_qmp_phy_create(dev, child, id);
if (ret) {
dev_err(dev, "failed to create lane%d phy, %d\n",
id, ret);
+ pm_runtime_disable(dev);
return ret;
}
@@ -1325,6 +1505,7 @@ static int qcom_qmp_phy_probe(struct platform_device *pdev)
if (ret) {
dev_err(qmp->dev,
"failed to register pipe clock source\n");
+ pm_runtime_disable(dev);
return ret;
}
id++;
@@ -1333,6 +1514,8 @@ static int qcom_qmp_phy_probe(struct platform_device *pdev)
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (!IS_ERR(phy_provider))
dev_info(dev, "Registered Qcom-QMP phy\n");
+ else
+ pm_runtime_disable(dev);
return PTR_ERR_OR_ZERO(phy_provider);
}
@@ -1341,6 +1524,7 @@ static int qcom_qmp_phy_probe(struct platform_device *pdev)
.probe = qcom_qmp_phy_probe,
.driver = {
.name = "qcom-qmp-phy",
+ .pm = &qcom_qmp_phy_pm_ops,
.of_match_table = qcom_qmp_phy_of_match_table,
},
};
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index f7d4c2a..264b5c4 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -283,4 +283,7 @@
#define QPHY_V3_PCS_FLL_MAN_CODE 0x0d4
#define QPHY_V3_PCS_RX_SIGDET_LVL 0x1d8
+/* Only for QMP V3 PHY - PCS_MISC registers */
+#define QPHY_V3_PCS_MISC_CLAMP_ENABLE 0x0c
+
#endif
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v4 14/16] phy: Add USB speed related PHY modes
2018-01-03 11:28 ` [PATCH v4 14/16] phy: Add USB speed related PHY modes Manu Gautam
@ 2018-01-05 11:01 ` Kishon Vijay Abraham I
2018-01-08 4:46 ` Manu Gautam
0 siblings, 1 reply; 26+ messages in thread
From: Kishon Vijay Abraham I @ 2018-01-05 11:01 UTC (permalink / raw)
To: Manu Gautam
Cc: Felipe Balbi, linux-arm-msm, linux-usb, open list:GENERIC PHY FRAMEWORK
Hi,
On Wednesday 03 January 2018 04:58 PM, Manu Gautam wrote:
> Add following USB speed related PHY modes:
> LS (Low Speed), FS (Full Speed), HS (High Speed), SS (Super Speed)
>
> Speed related information is required by some QCOM PHY drivers
> to program PHY monitor resume/remote-wakeup events in suspended
> state. Speed is needed in order to set correct polarity of wakeup
> events for detection. E.g. QUSB2 PHY monitors DP/DM line state
> depending on whether speed is LS or FS/HS to detect resume.
> Similarly QMP USB3 PHY in SS mode should monitor RX terminations
> attach/detach and LFPS events depending on SSPHY is active or not.
>
> Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
> ---
> drivers/phy/phy-core.c | 15 +++++++++++++++
> include/linux/phy/phy.h | 32 ++++++++++++++++++++++++--------
> 2 files changed, 39 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
> index b4964b0..e4f0525 100644
> --- a/drivers/phy/phy-core.c
> +++ b/drivers/phy/phy-core.c
> @@ -357,6 +357,21 @@ int phy_set_mode(struct phy *phy, enum phy_mode mode)
> }
> EXPORT_SYMBOL_GPL(phy_set_mode);
>
> +enum phy_mode phy_get_mode(struct phy *phy)
> +{
> + enum phy_mode ret;
> +
> + if (!phy || !phy->ops->get_mode)
> + return PHY_MODE_INVALID;
> +
> + mutex_lock(&phy->mutex);
> + ret = phy->ops->get_mode(phy);
Since get_mode only has to return the phy mode, there is no need for an ops
here. Just add phy_mode in phy_attrs in set_mode and return it here.
Thanks
Kishon
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 14/16] phy: Add USB speed related PHY modes
2018-01-05 11:01 ` Kishon Vijay Abraham I
@ 2018-01-08 4:46 ` Manu Gautam
0 siblings, 0 replies; 26+ messages in thread
From: Manu Gautam @ 2018-01-08 4:46 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Felipe Balbi, linux-arm-msm, linux-usb, open list:GENERIC PHY FRAMEWORK
Hi,
On 1/5/2018 4:31 PM, Kishon Vijay Abraham I wrote:
>> +enum phy_mode phy_get_mode(struct phy *phy)
>> +{
>> + enum phy_mode ret;
>> +
>> + if (!phy || !phy->ops->get_mode)
>> + return PHY_MODE_INVALID;
>> +
>> + mutex_lock(&phy->mutex);
>> + ret = phy->ops->get_mode(phy);
> Since get_mode only has to return the phy mode, there is no need for an ops
> here. Just add phy_mode in phy_attrs in set_mode and return it here.
Sure, will re-send patch set with this change.
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 10/16] phy: qcom-qmp: Move register offsets to header file
2018-01-03 11:28 ` [PATCH v4 10/16] phy: qcom-qmp: Move register offsets to header file Manu Gautam
@ 2018-01-12 6:26 ` Vivek Gautam
0 siblings, 0 replies; 26+ messages in thread
From: Vivek Gautam @ 2018-01-12 6:26 UTC (permalink / raw)
To: Manu Gautam
Cc: Kishon Vijay Abraham I, Felipe Balbi, linux-arm-msm,
Linux USB Mailing List, Varadarajan Narayanan, smuthayy,
Wei Yongjun, Fengguang Wu, open list
Hi Manu,
On Wed, Jan 3, 2018 at 4:58 PM, Manu Gautam <mgautam@codeaurora.org> wrote:
> New revision (v3) of QMP PHY uses different offsets
> for almost all of the registers. Hence, move these
> definitions to header file so that updated offsets
> can be added for QMP v3.
>
> Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
> ---
> drivers/phy/qualcomm/phy-qcom-qmp.c | 119 +------------------------------
> drivers/phy/qualcomm/phy-qcom-qmp.h | 137 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 138 insertions(+), 118 deletions(-)
> create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp.h
>
[snip]
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
> new file mode 100644
> index 0000000..d930ca7
> --- /dev/null
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
> @@ -0,0 +1,137 @@
> +/*
> + * Copyright (c) 2017, 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.
> + *
> + */
nit: "SPDX-License" identifier now? That's less number of lines too :)
And when you are doing that, can you please consider moving
phy-qcom-qmp and phy-qcom-qusb2 as well to the new SPDX license
identifier. That will be cleaner.
Thanks!
> +
> +#ifndef QCOM_PHY_QMP_H_
> +#define QCOM_PHY_QMP_H_
> +
> +/* Only for QMP V2 PHY - QSERDES COM registers */
> +#define QSERDES_COM_BG_TIMER 0x00c
> +#define QSERDES_COM_SSC_EN_CENTER 0x010
> +#define QSERDES_COM_SSC_ADJ_PER1 0x014
> +#define QSERDES_COM_SSC_ADJ_PER2 0x018
> +#define QSERDES_COM_SSC_PER1 0x01c
> +#define QSERDES_COM_SSC_PER2 0x020
> +#define QSERDES_COM_SSC_STEP_SIZE1 0x024
> +#define QSERDES_COM_SSC_STEP_SIZE2 0x028
> +#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x034
> +#define QSERDES_COM_CLK_ENABLE1 0x038
> +#define QSERDES_COM_SYS_CLK_CTRL 0x03c
> +#define QSERDES_COM_SYSCLK_BUF_ENABLE 0x040
> +#define QSERDES_COM_PLL_IVCO 0x048
> +#define QSERDES_COM_LOCK_CMP1_MODE0 0x04c
> +#define QSERDES_COM_LOCK_CMP2_MODE0 0x050
> +#define QSERDES_COM_LOCK_CMP3_MODE0 0x054
> +#define QSERDES_COM_LOCK_CMP1_MODE1 0x058
> +#define QSERDES_COM_LOCK_CMP2_MODE1 0x05c
> +#define QSERDES_COM_LOCK_CMP3_MODE1 0x060
> +#define QSERDES_COM_BG_TRIM 0x070
> +#define QSERDES_COM_CLK_EP_DIV 0x074
> +#define QSERDES_COM_CP_CTRL_MODE0 0x078
> +#define QSERDES_COM_CP_CTRL_MODE1 0x07c
> +#define QSERDES_COM_PLL_RCTRL_MODE0 0x084
> +#define QSERDES_COM_PLL_RCTRL_MODE1 0x088
> +#define QSERDES_COM_PLL_CCTRL_MODE0 0x090
> +#define QSERDES_COM_PLL_CCTRL_MODE1 0x094
> +#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0x0a8
> +#define QSERDES_COM_SYSCLK_EN_SEL 0x0ac
> +#define QSERDES_COM_RESETSM_CNTRL 0x0b4
> +#define QSERDES_COM_RESTRIM_CTRL 0x0bc
> +#define QSERDES_COM_RESCODE_DIV_NUM 0x0c4
> +#define QSERDES_COM_LOCK_CMP_EN 0x0c8
> +#define QSERDES_COM_LOCK_CMP_CFG 0x0cc
> +#define QSERDES_COM_DEC_START_MODE0 0x0d0
> +#define QSERDES_COM_DEC_START_MODE1 0x0d4
> +#define QSERDES_COM_DIV_FRAC_START1_MODE0 0x0dc
> +#define QSERDES_COM_DIV_FRAC_START2_MODE0 0x0e0
> +#define QSERDES_COM_DIV_FRAC_START3_MODE0 0x0e4
> +#define QSERDES_COM_DIV_FRAC_START1_MODE1 0x0e8
> +#define QSERDES_COM_DIV_FRAC_START2_MODE1 0x0ec
> +#define QSERDES_COM_DIV_FRAC_START3_MODE1 0x0f0
> +#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x108
> +#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x10c
> +#define QSERDES_COM_INTEGLOOP_GAIN0_MODE1 0x110
> +#define QSERDES_COM_INTEGLOOP_GAIN1_MODE1 0x114
> +#define QSERDES_COM_VCO_TUNE_CTRL 0x124
> +#define QSERDES_COM_VCO_TUNE_MAP 0x128
> +#define QSERDES_COM_VCO_TUNE1_MODE0 0x12c
> +#define QSERDES_COM_VCO_TUNE2_MODE0 0x130
> +#define QSERDES_COM_VCO_TUNE1_MODE1 0x134
> +#define QSERDES_COM_VCO_TUNE2_MODE1 0x138
> +#define QSERDES_COM_VCO_TUNE_TIMER1 0x144
> +#define QSERDES_COM_VCO_TUNE_TIMER2 0x148
> +#define QSERDES_COM_BG_CTRL 0x170
> +#define QSERDES_COM_CLK_SELECT 0x174
> +#define QSERDES_COM_HSCLK_SEL 0x178
> +#define QSERDES_COM_CORECLK_DIV 0x184
> +#define QSERDES_COM_CORE_CLK_EN 0x18c
> +#define QSERDES_COM_C_READY_STATUS 0x190
> +#define QSERDES_COM_CMN_CONFIG 0x194
> +#define QSERDES_COM_SVS_MODE_CLK_SEL 0x19c
> +#define QSERDES_COM_DEBUG_BUS0 0x1a0
> +#define QSERDES_COM_DEBUG_BUS1 0x1a4
> +#define QSERDES_COM_DEBUG_BUS2 0x1a8
> +#define QSERDES_COM_DEBUG_BUS3 0x1ac
> +#define QSERDES_COM_DEBUG_BUS_SEL 0x1b0
> +#define QSERDES_COM_CORECLK_DIV_MODE1 0x1bc
> +
> +/* Only for QMP V2 PHY - TX registers */
> +#define QSERDES_TX_RES_CODE_LANE_OFFSET 0x054
> +#define QSERDES_TX_DEBUG_BUS_SEL 0x064
> +#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x068
> +#define QSERDES_TX_LANE_MODE 0x094
> +#define QSERDES_TX_RCV_DETECT_LVL_2 0x0ac
> +
> +/* Only for QMP V2 PHY - RX registers */
> +#define QSERDES_RX_UCDR_SO_GAIN_HALF 0x010
> +#define QSERDES_RX_UCDR_SO_GAIN 0x01c
> +#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN 0x040
> +#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE 0x048
> +#define QSERDES_RX_RX_TERM_BW 0x090
> +#define QSERDES_RX_RX_EQ_GAIN1_LSB 0x0c4
> +#define QSERDES_RX_RX_EQ_GAIN1_MSB 0x0c8
> +#define QSERDES_RX_RX_EQ_GAIN2_LSB 0x0cc
> +#define QSERDES_RX_RX_EQ_GAIN2_MSB 0x0d0
> +#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d8
> +#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 0x0dc
> +#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 0x0e0
> +#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x108
> +#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x10c
> +#define QSERDES_RX_SIGDET_ENABLES 0x110
> +#define QSERDES_RX_SIGDET_CNTRL 0x114
> +#define QSERDES_RX_SIGDET_LVL 0x118
> +#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL 0x11c
> +#define QSERDES_RX_RX_BAND 0x120
> +#define QSERDES_RX_RX_INTERFACE_MODE 0x12c
> +
> +/* Only for QMP V2 PHY - PCS registers */
> +#define QPHY_POWER_DOWN_CONTROL 0x04
> +#define QPHY_TXDEEMPH_M6DB_V0 0x24
> +#define QPHY_TXDEEMPH_M3P5DB_V0 0x28
> +#define QPHY_ENDPOINT_REFCLK_DRIVE 0x54
> +#define QPHY_RX_IDLE_DTCT_CNTRL 0x58
> +#define QPHY_POWER_STATE_CONFIG1 0x60
> +#define QPHY_POWER_STATE_CONFIG2 0x64
> +#define QPHY_POWER_STATE_CONFIG4 0x6c
> +#define QPHY_LOCK_DETECT_CONFIG1 0x80
> +#define QPHY_LOCK_DETECT_CONFIG2 0x84
> +#define QPHY_LOCK_DETECT_CONFIG3 0x88
> +#define QPHY_PWRUP_RESET_DLY_TIME_AUXCLK 0xa0
> +#define QPHY_LP_WAKEUP_DLY_TIME_AUXCLK 0xa4
> +#define QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB 0x1A8
> +#define QPHY_OSC_DTCT_ACTIONS 0x1AC
> +#define QPHY_RX_SIGDET_LVL 0x1D8
> +#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1DC
> +#define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1E0
> +
> +#endif
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 03/16] phy: qcom-qmp: Power-on PHY before initialization
2018-01-03 11:28 ` [PATCH v4 03/16] phy: qcom-qmp: Power-on PHY before initialization Manu Gautam
@ 2018-01-12 8:27 ` Vivek Gautam
0 siblings, 0 replies; 26+ messages in thread
From: Vivek Gautam @ 2018-01-12 8:27 UTC (permalink / raw)
To: Manu Gautam
Cc: Kishon Vijay Abraham I, Felipe Balbi, linux-arm-msm,
Linux USB Mailing List, Varadarajan Narayanan, Yoshihiro Shimoda,
Fengguang Wu, Wei Yongjun, open list:GENERIC PHY FRAMEWORK,
Subhash Jadavani
On Wed, Jan 3, 2018 at 4:58 PM, Manu Gautam <mgautam@codeaurora.org> wrote:
> PHY regulators which are enabled from power_on() must be ON
> before turning-on clocks and initializing it as part of init().
> As most of the core drivers perform power_on() after init(), move
> PHY regulators enable to com_init() and use power_on() to
> only enable pipe_clk. This pipe_clk is output from PHY and some
> core drivers e.g. PCIe follow specific sequence after phy_init()
> that mandates pipe_clk to be enabled from power_on() only.
> On similar lines move clk_enable from init() to com_init() which
> executes once for multi lane PHYs.
>
> Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
> ---
Adding Subhash Jadvani to look at this change from UFS perspective.
> drivers/phy/qualcomm/phy-qcom-qmp.c | 61 +++++++++++++++----------------------
> 1 file changed, 24 insertions(+), 37 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
> index 5fed1ae..1b82cea 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
> @@ -724,36 +724,13 @@ static int qcom_qmp_phy_poweron(struct phy *phy)
> {
> struct qmp_phy *qphy = phy_get_drvdata(phy);
> struct qcom_qmp *qmp = qphy->qmp;
> - int num = qmp->cfg->num_vregs;
> int ret;
>
> - dev_vdbg(&phy->dev, "Powering on QMP phy\n");
> -
> - /* turn on regulator supplies */
> - ret = regulator_bulk_enable(num, qmp->vregs);
> - if (ret) {
> - dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
> - return ret;
> - }
> -
> ret = clk_prepare_enable(qphy->pipe_clk);
> - if (ret) {
> + if (ret)
> dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
> - regulator_bulk_disable(num, qmp->vregs);
> - return ret;
> - }
>
> - return 0;
> -}
> -
> -static int qcom_qmp_phy_poweroff(struct phy *phy)
> -{
> - struct qmp_phy *qphy = phy_get_drvdata(phy);
> - struct qcom_qmp *qmp = qphy->qmp;
> -
> - regulator_bulk_disable(qmp->cfg->num_vregs, qmp->vregs);
> -
> - return 0;
> + return ret;
> }
>
> static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
> @@ -768,6 +745,19 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
> return 0;
> }
>
> + /* turn on regulator supplies */
> + ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
> + if (ret) {
> + dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
> + goto err_reg_enable;
> + }
> +
> + ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
> + if (ret) {
> + dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
> + goto err_clk_enable;
> + }
> +
> for (i = 0; i < cfg->num_resets; i++) {
> ret = reset_control_deassert(qmp->resets[i]);
> if (ret) {
> @@ -812,6 +802,10 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
> err_rst:
> while (--i >= 0)
> reset_control_assert(qmp->resets[i]);
> + clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
> +err_clk_enable:
> + regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
> +err_reg_enable:
> mutex_unlock(&qmp->phy_mutex);
>
> return ret;
> @@ -841,6 +835,10 @@ static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp)
> while (--i >= 0)
> reset_control_assert(qmp->resets[i]);
>
> + clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
> +
> + regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
> +
> mutex_unlock(&qmp->phy_mutex);
>
> return 0;
> @@ -861,15 +859,9 @@ static int qcom_qmp_phy_init(struct phy *phy)
>
> dev_vdbg(qmp->dev, "Initializing QMP phy\n");
>
> - ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
> - if (ret) {
> - dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
> - return ret;
> - }
> -
> ret = qcom_qmp_phy_com_init(qmp);
> if (ret)
> - goto err_com_init;
> + return ret;
>
> if (cfg->has_lane_rst) {
> ret = reset_control_deassert(qphy->lane_rst);
> @@ -917,8 +909,6 @@ static int qcom_qmp_phy_init(struct phy *phy)
> reset_control_assert(qphy->lane_rst);
> err_lane_rst:
> qcom_qmp_phy_com_exit(qmp);
> -err_com_init:
> - clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
>
> return ret;
> }
> @@ -945,8 +935,6 @@ static int qcom_qmp_phy_exit(struct phy *phy)
>
> qcom_qmp_phy_com_exit(qmp);
>
> - clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
> -
> return 0;
> }
>
> @@ -1060,7 +1048,6 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
> .init = qcom_qmp_phy_init,
> .exit = qcom_qmp_phy_exit,
> .power_on = qcom_qmp_phy_poweron,
> - .power_off = qcom_qmp_phy_poweroff,
> .owner = THIS_MODULE,
> };
>
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 04/16] phy: qcom-qusb2: Power-on PHY before initialization
2018-01-03 11:28 ` [PATCH v4 04/16] phy: qcom-qusb2: " Manu Gautam
@ 2018-01-12 8:29 ` Vivek Gautam
0 siblings, 0 replies; 26+ messages in thread
From: Vivek Gautam @ 2018-01-12 8:29 UTC (permalink / raw)
To: Manu Gautam
Cc: Kishon Vijay Abraham I, Felipe Balbi, linux-arm-msm,
Linux USB Mailing List, Krzysztof Kozlowski, Viresh Kumar,
open list:GENERIC PHY FRAMEWORK
On Wed, Jan 3, 2018 at 4:58 PM, Manu Gautam <mgautam@codeaurora.org> wrote:
> PHY must be powered on before turning ON clocks and
> attempting to initialize it. Driver is exposing
> separate init and power_on routines for this.
> Apparently USB dwc3 core driver performs power-on
> after init. Also, poweron and init for QUSB2 PHY
> need to be executed together always, hence remove
> poweron callback from phy_ops and explicitly perform
> this from init, similar changes needed for poweroff.
>
> Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
> ---
Looks good.
Reviewed-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Thanks
Vivek
> drivers/phy/qualcomm/phy-qcom-qusb2.c | 47 +++++++++++------------------------
> 1 file changed, 15 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
> index 6c57524..4a5b2a1 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
> @@ -195,54 +195,31 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy)
> qusb2_setbits(qphy->base, QUSB2PHY_PORT_TUNE2, val[0] << 0x4);
> }
>
> -static int qusb2_phy_poweron(struct phy *phy)
> +static int qusb2_phy_init(struct phy *phy)
> {
> struct qusb2_phy *qphy = phy_get_drvdata(phy);
> - int num = ARRAY_SIZE(qphy->vregs);
> + unsigned int val;
> + unsigned int clk_scheme;
> int ret;
>
> - dev_vdbg(&phy->dev, "%s(): Powering-on QUSB2 phy\n", __func__);
> + dev_vdbg(&phy->dev, "%s(): Initializing QUSB2 phy\n", __func__);
>
> /* turn on regulator supplies */
> - ret = regulator_bulk_enable(num, qphy->vregs);
> + ret = regulator_bulk_enable(ARRAY_SIZE(qphy->vregs), 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;
> + goto poweroff_phy;
> }
>
> - 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;
> + goto disable_iface_clk;
> }
>
> /* Perform phy reset */
> @@ -344,6 +321,11 @@ static int qusb2_phy_init(struct phy *phy)
> reset_control_assert(qphy->phy_reset);
> disable_ahb_clk:
> clk_disable_unprepare(qphy->cfg_ahb_clk);
> +disable_iface_clk:
> + clk_disable_unprepare(qphy->iface_clk);
> +poweroff_phy:
> + regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
> +
> return ret;
> }
>
> @@ -361,6 +343,9 @@ static int qusb2_phy_exit(struct phy *phy)
> reset_control_assert(qphy->phy_reset);
>
> clk_disable_unprepare(qphy->cfg_ahb_clk);
> + clk_disable_unprepare(qphy->iface_clk);
> +
> + regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
>
> return 0;
> }
> @@ -368,8 +353,6 @@ static int qusb2_phy_exit(struct phy *phy)
> 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,
> };
>
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence
2018-01-03 11:28 ` [PATCH v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence Manu Gautam
@ 2018-01-12 8:44 ` Vivek Gautam
2018-01-12 8:46 ` Manu Gautam
0 siblings, 1 reply; 26+ messages in thread
From: Vivek Gautam @ 2018-01-12 8:44 UTC (permalink / raw)
To: Manu Gautam
Cc: Kishon Vijay Abraham I, Felipe Balbi, linux-arm-msm,
Linux USB Mailing List, Varadarajan Narayanan, Viresh Kumar,
Wei Yongjun, Fengguang Wu, open list:GENERIC PHY FRAMEWORK
On Wed, Jan 3, 2018 at 4:58 PM, Manu Gautam <mgautam@codeaurora.org> wrote:
> PHY block or asynchronous reset requires signal
> to be asserted before de-asserting. Driver is only
> de-asserting signal which is already low, hence
> reset operation is a no-op. Fix this by asserting
> signal first. Also, resetting requires PHY clocks
> to be turned ON only after reset is finished. Fix
> that as well.
>
> Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
> ---
> drivers/phy/qualcomm/phy-qcom-qmp.c | 28 +++++++++++++++++++---------
> 1 file changed, 19 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
> index 1b82cea..ecff261 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
> @@ -752,13 +752,16 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
> goto err_reg_enable;
> }
>
> - ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
> - if (ret) {
> - dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
> - goto err_clk_enable;
> + for (i = 0; i < cfg->num_resets; i++) {
> + ret = reset_control_assert(qmp->resets[i]);
> + if (ret) {
> + dev_err(qmp->dev, "%s reset assert failed\n",
> + cfg->reset_list[i]);
> + goto err_rst_assert;
> + }
> }
>
> - for (i = 0; i < cfg->num_resets; i++) {
> + for (i = cfg->num_resets - 1; i >= 0; i--) {
Do we a dependency on the order in which these resets are
applied?
If not then we can use the 'bulk reset' APIs as well.
With that bulk reset change you can add my review.
Reviewed-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Thanks
Vivek
> ret = reset_control_deassert(qmp->resets[i]);
> if (ret) {
> dev_err(qmp->dev, "%s reset deassert failed\n",
> @@ -767,6 +770,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
> }
> }
>
> + ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
> + if (ret) {
> + dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
> + goto err_rst;
> + }
> +
> if (cfg->has_phy_com_ctrl)
> qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
> SW_PWRDN);
> @@ -791,7 +800,7 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
> if (ret) {
> dev_err(qmp->dev,
> "phy common block init timed-out\n");
> - goto err_rst;
> + goto err_com_init;
> }
> }
>
> @@ -799,11 +808,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>
> return 0;
>
> +err_com_init:
> + clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
> err_rst:
> - while (--i >= 0)
> + while (++i < cfg->num_resets)
> reset_control_assert(qmp->resets[i]);
> - clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
> -err_clk_enable:
> +err_rst_assert:
> regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
> err_reg_enable:
> mutex_unlock(&qmp->phy_mutex);
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence
2018-01-12 8:44 ` Vivek Gautam
@ 2018-01-12 8:46 ` Manu Gautam
2018-01-12 9:12 ` Vivek Gautam
0 siblings, 1 reply; 26+ messages in thread
From: Manu Gautam @ 2018-01-12 8:46 UTC (permalink / raw)
To: Vivek Gautam
Cc: Kishon Vijay Abraham I, Felipe Balbi, linux-arm-msm,
Linux USB Mailing List, Varadarajan Narayanan, Viresh Kumar,
Wei Yongjun, Fengguang Wu, open list:GENERIC PHY FRAMEWORK
Hi Vivek,
On 1/12/2018 2:14 PM, Vivek Gautam wrote:
> On Wed, Jan 3, 2018 at 4:58 PM, Manu Gautam <mgautam@codeaurora.org> wrote:
>> PHY block or asynchronous reset requires signal
>> to be asserted before de-asserting. Driver is only
>> de-asserting signal which is already low, hence
>> reset operation is a no-op. Fix this by asserting
>> signal first. Also, resetting requires PHY clocks
>> to be turned ON only after reset is finished. Fix
>> that as well.
>>
>> Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
>> ---
>> drivers/phy/qualcomm/phy-qcom-qmp.c | 28 +++++++++++++++++++---------
>> 1 file changed, 19 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
>> index 1b82cea..ecff261 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
>> @@ -752,13 +752,16 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>> goto err_reg_enable;
>> }
>>
>> - ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
>> - if (ret) {
>> - dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
>> - goto err_clk_enable;
>> + for (i = 0; i < cfg->num_resets; i++) {
>> + ret = reset_control_assert(qmp->resets[i]);
>> + if (ret) {
>> + dev_err(qmp->dev, "%s reset assert failed\n",
>> + cfg->reset_list[i]);
>> + goto err_rst_assert;
>> + }
>> }
>>
>> - for (i = 0; i < cfg->num_resets; i++) {
>> + for (i = cfg->num_resets - 1; i >= 0; i--) {
> Do we a dependency on the order in which these resets are
> applied?
> If not then we can use the 'bulk reset' APIs as well.
We need to follow an order for assert and opposite order for
de-assert, hence cant use 'bulk reset' APIs.
>
> With that bulk reset change you can add my review.
>
> Reviewed-by: Vivek Gautam <vivek.gautam@codeaurora.org>
>
> Thanks
> Vivek
>
>> ret = reset_control_deassert(qmp->resets[i]);
>> if (ret) {
>> dev_err(qmp->dev, "%s reset deassert failed\n",
>> @@ -767,6 +770,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>> }
>> }
>>
>> + ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
>> + if (ret) {
>> + dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
>> + goto err_rst;
>> + }
>> +
>> if (cfg->has_phy_com_ctrl)
>> qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
>> SW_PWRDN);
>> @@ -791,7 +800,7 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>> if (ret) {
>> dev_err(qmp->dev,
>> "phy common block init timed-out\n");
>> - goto err_rst;
>> + goto err_com_init;
>> }
>> }
>>
>> @@ -799,11 +808,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>>
>> return 0;
>>
>> +err_com_init:
>> + clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
>> err_rst:
>> - while (--i >= 0)
>> + while (++i < cfg->num_resets)
>> reset_control_assert(qmp->resets[i]);
>> - clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
>> -err_clk_enable:
>> +err_rst_assert:
>> regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
>> err_reg_enable:
>> mutex_unlock(&qmp->phy_mutex);
>> --
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
>> a Linux Foundation Collaborative Project
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence
2018-01-12 8:46 ` Manu Gautam
@ 2018-01-12 9:12 ` Vivek Gautam
0 siblings, 0 replies; 26+ messages in thread
From: Vivek Gautam @ 2018-01-12 9:12 UTC (permalink / raw)
To: Manu Gautam
Cc: Kishon Vijay Abraham I, Felipe Balbi, linux-arm-msm,
Linux USB Mailing List, Varadarajan Narayanan, Viresh Kumar,
Wei Yongjun, Fengguang Wu, open list:GENERIC PHY FRAMEWORK
On Fri, Jan 12, 2018 at 2:16 PM, Manu Gautam <mgautam@codeaurora.org> wrote:
> Hi Vivek,
>
>
> On 1/12/2018 2:14 PM, Vivek Gautam wrote:
>> On Wed, Jan 3, 2018 at 4:58 PM, Manu Gautam <mgautam@codeaurora.org> wrote:
>>> PHY block or asynchronous reset requires signal
>>> to be asserted before de-asserting. Driver is only
>>> de-asserting signal which is already low, hence
>>> reset operation is a no-op. Fix this by asserting
>>> signal first. Also, resetting requires PHY clocks
>>> to be turned ON only after reset is finished. Fix
>>> that as well.
>>>
>>> Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
>>> ---
>>> drivers/phy/qualcomm/phy-qcom-qmp.c | 28 +++++++++++++++++++---------
>>> 1 file changed, 19 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
>>> index 1b82cea..ecff261 100644
>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
>>> @@ -752,13 +752,16 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>>> goto err_reg_enable;
>>> }
>>>
>>> - ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
>>> - if (ret) {
>>> - dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
>>> - goto err_clk_enable;
>>> + for (i = 0; i < cfg->num_resets; i++) {
>>> + ret = reset_control_assert(qmp->resets[i]);
>>> + if (ret) {
>>> + dev_err(qmp->dev, "%s reset assert failed\n",
>>> + cfg->reset_list[i]);
>>> + goto err_rst_assert;
>>> + }
>>> }
>>>
>>> - for (i = 0; i < cfg->num_resets; i++) {
>>> + for (i = cfg->num_resets - 1; i >= 0; i--) {
>> Do we a dependency on the order in which these resets are
>> applied?
>> If not then we can use the 'bulk reset' APIs as well.
>
> We need to follow an order for assert and opposite order for
> de-assert, hence cant use 'bulk reset' APIs.
Okay, you can add my review then.
Thanks.
>
>>
>> With that bulk reset change you can add my review.
>>
>> Reviewed-by: Vivek Gautam <vivek.gautam@codeaurora.org>
>>
>> Thanks
>> Vivek
>>
>>> ret = reset_control_deassert(qmp->resets[i]);
>>> if (ret) {
>>> dev_err(qmp->dev, "%s reset deassert failed\n",
>>> @@ -767,6 +770,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>>> }
>>> }
>>>
>>> + ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
>>> + if (ret) {
>>> + dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
>>> + goto err_rst;
>>> + }
>>> +
>>> if (cfg->has_phy_com_ctrl)
>>> qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
>>> SW_PWRDN);
>>> @@ -791,7 +800,7 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>>> if (ret) {
>>> dev_err(qmp->dev,
>>> "phy common block init timed-out\n");
>>> - goto err_rst;
>>> + goto err_com_init;
>>> }
>>> }
>>>
>>> @@ -799,11 +808,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>>>
>>> return 0;
>>>
>>> +err_com_init:
>>> + clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
>>> err_rst:
>>> - while (--i >= 0)
>>> + while (++i < cfg->num_resets)
>>> reset_control_assert(qmp->resets[i]);
>>> - clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
>>> -err_clk_enable:
>>> +err_rst_assert:
>>> regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
>>> err_reg_enable:
>>> mutex_unlock(&qmp->phy_mutex);
>>> --
>>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
>>> a Linux Foundation Collaborative Project
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>>
>
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 07/16] phy: qcom-qusb2: Add support for different register layouts
2018-01-03 11:28 ` [PATCH v4 07/16] phy: qcom-qusb2: Add support for different register layouts Manu Gautam
@ 2018-01-12 9:18 ` Vivek Gautam
0 siblings, 0 replies; 26+ messages in thread
From: Vivek Gautam @ 2018-01-12 9:18 UTC (permalink / raw)
To: Manu Gautam
Cc: Kishon Vijay Abraham I, Felipe Balbi, linux-arm-msm,
Linux USB Mailing List, Yoshihiro Shimoda, Heiko Stuebner,
open list:GENERIC PHY FRAMEWORK
On Wed, Jan 3, 2018 at 4:58 PM, Manu Gautam <mgautam@codeaurora.org> wrote:
> New version of QUSB2 PHY has some registers offset changed.
> Add support to have register layout for a target and update
> the same in phy_configuration.
>
> Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
> ---
LGTM.
Reviewed-by: Vivek Gautam <vivek.gautam@codeaurora.org>
> drivers/phy/qualcomm/phy-qcom-qusb2.c | 149 +++++++++++++++++++++++++---------
> 1 file changed, 109 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
> index 4a5b2a1..b65635f 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
> @@ -37,17 +37,10 @@
> #define QUSB2PHY_PLL_AUTOPGM_CTL1 0x1c
> #define QUSB2PHY_PLL_PWR_CTRL 0x18
>
> -#define QUSB2PHY_PLL_STATUS 0x38
> +/* QUSB2PHY_PLL_STATUS register bits */
> #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
> +/* QUSB2PHY_PORT_POWERDOWN register bits */
> #define CLAMP_N_EN BIT(5)
> #define FREEZIO_N BIT(1)
> #define POWER_DOWN BIT(0)
> @@ -59,6 +52,11 @@
> struct qusb2_phy_init_tbl {
> unsigned int offset;
> unsigned int val;
> + /*
> + * register part of layout ?
> + * if yes, then offset gives index in the reg-layout
> + */
> + int in_layout;
> };
>
> #define QUSB2_PHY_INIT_CFG(o, v) \
> @@ -67,15 +65,50 @@ struct qusb2_phy_init_tbl {
> .val = v, \
> }
>
> +#define QUSB2_PHY_INIT_CFG_L(o, v) \
> + { \
> + .offset = o, \
> + .val = v, \
> + .in_layout = 1, \
> + }
> +
> +/* set of registers with offsets different per-PHY */
> +enum qusb2phy_reg_layout {
> + QUSB2PHY_PLL_STATUS,
> + QUSB2PHY_PORT_TUNE1,
> + QUSB2PHY_PORT_TUNE2,
> + QUSB2PHY_PORT_TUNE3,
> + QUSB2PHY_PORT_TUNE4,
> + QUSB2PHY_PORT_TUNE5,
> + QUSB2PHY_PORT_TEST1,
> + QUSB2PHY_PORT_TEST2,
> + QUSB2PHY_PORT_POWERDOWN,
> + QUSB2PHY_INTR_CTRL,
> +};
> +
> +static const unsigned int msm8996_regs_layout[] = {
> + [QUSB2PHY_PLL_STATUS] = 0x38,
> + [QUSB2PHY_PORT_TUNE1] = 0x80,
> + [QUSB2PHY_PORT_TUNE2] = 0x84,
> + [QUSB2PHY_PORT_TUNE3] = 0x88,
> + [QUSB2PHY_PORT_TUNE4] = 0x8c,
> + [QUSB2PHY_PORT_TUNE5] = 0x90,
> + [QUSB2PHY_PORT_TEST2] = 0x9c,
> + [QUSB2PHY_PORT_POWERDOWN] = 0xb4,
> +};
> +
> 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_L(QUSB2PHY_PORT_TUNE1, 0xf8),
> + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3),
> + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x83),
> + QUSB2_PHY_INIT_CFG_L(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_L(QUSB2PHY_PORT_TEST2, 0x14),
> +
> QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f),
> QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
> };
> @@ -86,11 +119,27 @@ struct qusb2_phy_cfg {
> unsigned int tbl_num;
> /* offset to PHY_CLK_SCHEME register in TCSR map */
> unsigned int clk_scheme_offset;
> +
> + /* array of registers with different offsets */
> + const unsigned int *regs;
> + unsigned int mask_core_ready;
> + unsigned int disable_ctrl;
> +
> + /* true if PHY has PLL_TEST register to select clk_scheme */
> + bool has_pll_test;
> +
> + /* true if TUNE1 register must be updated by fused value, else TUNE2 */
> + bool update_tune1_with_efuse;
> };
>
> static const struct qusb2_phy_cfg msm8996_phy_cfg = {
> - .tbl = msm8996_init_tbl,
> - .tbl_num = ARRAY_SIZE(msm8996_init_tbl),
> + .tbl = msm8996_init_tbl,
> + .tbl_num = ARRAY_SIZE(msm8996_init_tbl),
> + .regs = msm8996_regs_layout,
> +
> + .has_pll_test = true,
> + .disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
> + .mask_core_ready = PLL_LOCKED,
> };
>
> static const char * const qusb2_phy_vreg_names[] = {
> @@ -160,26 +209,32 @@ static inline void qusb2_clrbits(void __iomem *base, u32 offset, u32 val)
>
> static inline
> void qcom_qusb2_phy_configure(void __iomem *base,
> + const unsigned int *regs,
> 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);
> + for (i = 0; i < num; i++) {
> + if (tbl[i].in_layout)
> + writel(tbl[i].val, base + regs[tbl[i].offset]);
> + else
> + writel(tbl[i].val, base + tbl[i].offset);
> + }
> }
>
> /*
> * Fetches HS Tx tuning value from nvmem and sets the
> - * QUSB2PHY_PORT_TUNE2 register.
> + * QUSB2PHY_PORT_TUNE1/2 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;
> + const struct qusb2_phy_cfg *cfg = qphy->cfg;
> u8 *val;
>
> /*
> - * Read efuse register having TUNE2 parameter's high nibble.
> + * Read efuse register having TUNE2/1 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
> @@ -191,14 +246,21 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy)
> return;
> }
>
> - /* Fused TUNE2 value is the higher nibble only */
> - qusb2_setbits(qphy->base, QUSB2PHY_PORT_TUNE2, val[0] << 0x4);
> + /* Fused TUNE1/2 value is the higher nibble only */
> + if (cfg->update_tune1_with_efuse)
> + qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
> + val[0] << 0x4);
> + else
> + qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
> + val[0] << 0x4);
> +
> }
>
> static int qusb2_phy_init(struct phy *phy)
> {
> struct qusb2_phy *qphy = phy_get_drvdata(phy);
> - unsigned int val;
> + const struct qusb2_phy_cfg *cfg = qphy->cfg;
> + unsigned int val = 0;
> unsigned int clk_scheme;
> int ret;
>
> @@ -239,20 +301,23 @@ static int qusb2_phy_init(struct phy *phy)
> }
>
> /* Disable the PHY */
> - qusb2_setbits(qphy->base, QUSB2PHY_PORT_POWERDOWN,
> - CLAMP_N_EN | FREEZIO_N | POWER_DOWN);
> + qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
> + qphy->cfg->disable_ctrl);
>
> - /* save reset value to override reference clock scheme later */
> - val = readl(qphy->base + QUSB2PHY_PLL_TEST);
> + if (cfg->has_pll_test) {
> + /* 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);
> + qcom_qusb2_phy_configure(qphy->base, cfg->regs, cfg->tbl,
> + 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);
> + qusb2_clrbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
> + POWER_DOWN);
>
> /* Required to get phy pll lock successfully */
> usleep_range(150, 160);
> @@ -285,27 +350,31 @@ static int qusb2_phy_init(struct phy *phy)
> }
>
> 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);
> + if (cfg->has_pll_test) {
> + if (!qphy->has_se_clk_scheme)
> + val &= ~CLK_REF_SEL;
> + else
> + val |= CLK_REF_SEL;
> +
> + writel(val, qphy->base + QUSB2PHY_PLL_TEST);
>
> - /* ensure above write is through */
> - readl(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)) {
> + val = readb(qphy->base + cfg->regs[QUSB2PHY_PLL_STATUS]);
> + if (!(val & cfg->mask_core_ready)) {
> dev_err(&phy->dev,
> "QUSB2PHY pll lock failed: status reg = %x\n", val);
> ret = -EBUSY;
> @@ -334,8 +403,8 @@ 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);
> + qusb2_setbits(qphy->base, qphy->cfg->regs[QUSB2PHY_PORT_POWERDOWN],
> + qphy->cfg->disable_ctrl);
>
> if (!qphy->has_se_clk_scheme)
> clk_disable_unprepare(qphy->ref_clk);
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v4 09/16] phy: qcom-qusb2: Add support for QUSB2 V2 version
2018-01-03 11:28 ` [PATCH v4 09/16] phy: qcom-qusb2: Add support " Manu Gautam
@ 2018-01-12 9:29 ` Vivek Gautam
0 siblings, 0 replies; 26+ messages in thread
From: Vivek Gautam @ 2018-01-12 9:29 UTC (permalink / raw)
To: Manu Gautam
Cc: Kishon Vijay Abraham I, Felipe Balbi, linux-arm-msm,
Linux USB Mailing List, Yoshihiro Shimoda, Jaehoon Chung,
open list:GENERIC PHY FRAMEWORK
On Wed, Jan 3, 2018 at 4:58 PM, Manu Gautam <mgautam@codeaurora.org> wrote:
> Use register layout to add additional registers present
> on QUSB2 PHY V2 version for PHY initialization.
> Other than new registers on V2, following two register's
> offset and bit definitions are different: POWERDOWN control
> and PLL_STATUS.
>
> Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
> ---
> drivers/phy/qualcomm/phy-qcom-qusb2.c | 64 +++++++++++++++++++++++++++++++++++
> 1 file changed, 64 insertions(+)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
> index b65635f..8d0579e 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
> @@ -40,15 +40,34 @@
> /* QUSB2PHY_PLL_STATUS register bits */
> #define PLL_LOCKED BIT(5)
>
> +/* QUSB2PHY_PLL_COMMON_STATUS_ONE register bits */
> +#define CORE_READY_STATUS BIT(0)
> +
> /* QUSB2PHY_PORT_POWERDOWN register bits */
> #define CLAMP_N_EN BIT(5)
> #define FREEZIO_N BIT(1)
> #define POWER_DOWN BIT(0)
>
> +/* QUSB2PHY_PWR_CTRL1 register bits */
> +#define PWR_CTRL1_VREF_SUPPLY_TRIM BIT(5)
> +#define PWR_CTRL1_CLAMP_N_EN BIT(1)
> +
> #define QUSB2PHY_REFCLK_ENABLE BIT(0)
>
> #define PHY_CLK_SCHEME_SEL BIT(0)
>
> +#define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO 0x04
> +#define QUSB2PHY_PLL_CLOCK_INVERTERS 0x18c
> +#define QUSB2PHY_PLL_CMODE 0x2c
> +#define QUSB2PHY_PLL_LOCK_DELAY 0x184
> +#define QUSB2PHY_PLL_DIGITAL_TIMERS_TWO 0xb4
> +#define QUSB2PHY_PLL_BIAS_CONTROL_1 0x194
> +#define QUSB2PHY_PLL_BIAS_CONTROL_2 0x198
> +#define QUSB2PHY_PWR_CTRL2 0x214
> +#define QUSB2PHY_IMP_CTRL1 0x220
> +#define QUSB2PHY_IMP_CTRL2 0x224
> +#define QUSB2PHY_CHG_CTRL2 0x23c
nit: Replace these tabs with simple spaces.
Rest all look good.
Reviewed-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Thanks
Vivek
> +
> struct qusb2_phy_init_tbl {
> unsigned int offset;
> unsigned int val;
> @@ -113,6 +132,38 @@ enum qusb2phy_reg_layout {
> QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
> };
>
> +static const unsigned int qusb2_v2_regs_layout[] = {
> + [QUSB2PHY_PLL_STATUS] = 0x1a0,
> + [QUSB2PHY_PORT_TUNE1] = 0x240,
> + [QUSB2PHY_PORT_TUNE2] = 0x244,
> + [QUSB2PHY_PORT_TUNE3] = 0x248,
> + [QUSB2PHY_PORT_TUNE4] = 0x24c,
> + [QUSB2PHY_PORT_TUNE5] = 0x250,
> + [QUSB2PHY_PORT_TEST2] = 0x258,
> + [QUSB2PHY_PORT_POWERDOWN] = 0x210,
> +};
> +
> +static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = {
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03),
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a),
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19),
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_1, 0x40),
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_2, 0x20),
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_PWR_CTRL2, 0x21),
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL1, 0x0),
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
> +
> + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x30),
> + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x29),
> + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0xca),
> + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x04),
> + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x03),
> +
> + QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
> +};
> +
> struct qusb2_phy_cfg {
> const struct qusb2_phy_init_tbl *tbl;
> /* number of entries in the table */
> @@ -142,6 +193,16 @@ struct qusb2_phy_cfg {
> .mask_core_ready = PLL_LOCKED,
> };
>
> +static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
> + .tbl = qusb2_v2_init_tbl,
> + .tbl_num = ARRAY_SIZE(qusb2_v2_init_tbl),
> + .regs = qusb2_v2_regs_layout,
> +
> + .disable_ctrl = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
> + POWER_DOWN),
> + .mask_core_ready = CORE_READY_STATUS,
> +};
> +
> static const char * const qusb2_phy_vreg_names[] = {
> "vdda-pll", "vdda-phy-dpdm",
> };
> @@ -429,6 +490,9 @@ static int qusb2_phy_exit(struct phy *phy)
> {
> .compatible = "qcom,msm8996-qusb2-phy",
> .data = &msm8996_phy_cfg,
> + }, {
> + .compatible = "qcom,qusb2-v2-phy",
> + .data = &qusb2_v2_phy_cfg,
> },
> { },
> };
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2018-01-12 9:29 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <1514978930-31341-1-git-send-email-mgautam@codeaurora.org>
2018-01-03 11:28 ` [PATCH v4 01/16] phy: qcom-qmp: Fix phy pipe clock gating Manu Gautam
2018-01-03 11:28 ` [PATCH v4 02/16] phy: qcom-qmp: Adapt to clk_bulk_* APIs Manu Gautam
2018-01-03 11:28 ` [PATCH v4 03/16] phy: qcom-qmp: Power-on PHY before initialization Manu Gautam
2018-01-12 8:27 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 04/16] phy: qcom-qusb2: " Manu Gautam
2018-01-12 8:29 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence Manu Gautam
2018-01-12 8:44 ` Vivek Gautam
2018-01-12 8:46 ` Manu Gautam
2018-01-12 9:12 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 06/16] phy: qcom-qmp: Move SERDES/PCS START after PHY reset Manu Gautam
2018-01-03 11:28 ` [PATCH v4 07/16] phy: qcom-qusb2: Add support for different register layouts Manu Gautam
2018-01-12 9:18 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 08/16] dt-bindings: phy-qcom-qusb2: Update binding for QUSB2 V2 version Manu Gautam
2018-01-03 11:28 ` [PATCH v4 09/16] phy: qcom-qusb2: Add support " Manu Gautam
2018-01-12 9:29 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 10/16] phy: qcom-qmp: Move register offsets to header file Manu Gautam
2018-01-12 6:26 ` Vivek Gautam
2018-01-03 11:28 ` [PATCH v4 11/16] phy: qcom-qmp: Add register offsets for QMP V3 PHY Manu Gautam
2018-01-03 11:28 ` [PATCH v4 12/16] dt-bindings: phy-qcom-qmp: Update bindings for QMP V3 USB PHY Manu Gautam
2018-01-03 11:28 ` [PATCH v4 13/16] phy: qcom-qmp: Add support for QMP V3 USB3 PHY Manu Gautam
2018-01-03 11:28 ` [PATCH v4 14/16] phy: Add USB speed related PHY modes Manu Gautam
2018-01-05 11:01 ` Kishon Vijay Abraham I
2018-01-08 4:46 ` Manu Gautam
2018-01-03 11:28 ` [PATCH v4 15/16] phy: qcom-qusb2: Add support for runtime PM Manu Gautam
2018-01-03 11:28 ` [PATCH v4 16/16] phy: qcom-qmp: " Manu Gautam
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).