[PATCH v5 06/17] phy: qcom-qmp: Move SERDES/PCS START after PHY reset

2018-01-16 Thread Manu Gautam
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 <mgau...@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



[PATCH v5 09/17] phy: qcom-qusb2: Add support for QUSB2 V2 version

2018-01-16 Thread Manu Gautam
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 <mgau...@codeaurora.org>
Reviewed-by: Vivek Gautam <vivek.gau...@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..9b0d1ff 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_DELAY0x184
+#define QUSB2PHY_PLL_DIGITAL_TIMERS_TWO0xb4
+#define QUSB2PHY_PLL_BIAS_CONTROL_10x194
+#define QUSB2PHY_PLL_BIAS_CONTROL_20x198
+#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   = _phy_cfg,
+   }, {
+   .compatible = "qcom,qusb2-v2-phy",
+   .data   = _v2_phy_cfg,
},
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v5 10/17] phy: qcom-qmp: Move register offsets to header file

2018-01-16 Thread Manu Gautam
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 <mgau...@codeaurora.org>
Reviewed-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 119 +
 drivers/phy/qualcomm/phy-qcom-qmp.h | 128 
 2 files changed, 129 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 
 
-/* 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_EN0x034
-#define QSERDES_COM_CLK_ENABLE10x038
-#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_MODE00x04c
-#define QSERDES_COM_LOCK_CMP2_MODE00x050
-#define QSERDES_COM_LOCK_CMP3_MODE00x054
-#define QSERDES_COM_LOCK_CMP1_MODE10x058
-#define QSERDES_COM_LOCK_CMP2_MODE10x05c
-#define QSERDES_COM_LOCK_CMP3_MODE10x060
-#define QSERDES_COM_BG_TRIM0x070
-#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_MODE00x084
-#define QSERDES_COM_PLL_RCTRL_MODE10x088
-#define QSERDES_COM_PLL_CCTRL_MODE00x090
-#define QSERDES_COM_PLL_CCTRL_MODE10x094
-#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM0x0a8
-#define QSERDES_COM_SYSCLK_EN_SEL  0x0ac
-#define QSERDES_COM_RESETSM_CNTRL  0x0b4
-#define QSERDES_COM_RESTRIM_CTRL   0x0bc
-#define QSERDES_COM_RESCODE_DIV_NUM0x0c4
-#define QSERDES_COM_LOCK_CMP_EN0x0c8
-#define QSERDES_COM_LOCK_CMP_CFG   0x0cc
-#define QSERDES_COM_DEC_START_MODE00x0d0
-#define QSERDES_COM_DEC_START_MODE10x0d4
-#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_MODE00x12c
-#define QSERDES_COM_VCO_TUNE2_MODE00x130
-#define QSERDES_COM_VCO_TUNE1_MODE10x134
-#define QSERDES_COM_VCO_TUNE2_MODE10x138
-#define QSERDES_COM_VCO_TUNE_TIMER10x144
-#define QSERDES_COM_VCO_TUNE_TIMER20x148
-#define QSERDES_COM_BG_CTRL0x170
-#define QSERDES_COM_CLK_SELECT 0x174
-#define QSERDES_COM_HSCLK_SEL  0x178
-#define QSERDES_COM_CORECLK_DIV0x184
-#define QSERDES_COM_CORE_CLK_EN0x18c
-#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 0x

[PATCH v5 11/17] phy: qcom-qmp: Add register offsets for QMP V3 PHY

2018-01-16 Thread Manu Gautam
Registers offsets for QMP V3 PHY are changed from
previous versions (1/2), update same in header file.

Signed-off-by: Manu Gautam <mgau...@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 84d7038..944269a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -125,4 +125,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_RESET0x04
+#define QPHY_V3_DP_COM_POWER_DOWN_CTRL 0x08
+#define QPHY_V3_DP_COM_SWI_CTRL0x0c
+#define QPHY_V3_DP_COM_TYPEC_CTRL  0x10
+#define QPHY_V3_DP_COM_TYPEC_PWRDN_CTRL0x14
+#define QPHY_V3_DP_COM_RESET_OVRD_CTRL 0x1c
+
+/* Only for QMP V3 PHY - QSERDES COM registers */
+#define QSERDES_V3_COM_BG_TIMER0x00c
+#define QSERDES_V3_COM_SSC_EN_CENTER   0x010
+#define QSERDES_V3_COM_SSC_ADJ_PER10x014
+#define QSERDES_V3_COM_SSC_ADJ_PER20x018
+#define QSERDES_V3_COM_SSC_PER10x01c
+#define QSERDES_V3_COM_SSC_PER20x020
+#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_CTRL0x03c
+#define QSERDES_V3_COM_SYSCLK_BUF_ENABLE   0x040
+#define QSERDES_V3_COM_PLL_IVCO0x048
+#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_CFG0x094
+#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_MAP0x0f0
+#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_SEL0x164
+#define QSERDES_V3_COM_DEBUG_BUS0  0x168
+#define QSERDES_V3_COM_DEBUG_BUS1 

[PATCH v5 13/17] phy: qcom-qmp: Add support for QMP V3 USB3 PHY

2018-01-16 Thread Manu Gautam
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 <mgau...@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_MODEBIT(1) /* enables DP 
mode */
+
+
 #define PHY_INIT_COMPLETE_TIMEOUT  1000
 #define POWER_DOWN_DELAY_US_MIN10
 #define POWER_DOWN_DELAY_US_MAX11
@@ -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_in

[PATCH v5 15/17] phy: qcom-qusb2: Add support for runtime PM

2018-01-16 Thread Manu Gautam
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 <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 176 ++
 1 file changed, 176 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 9b0d1ff..f1e4a64 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_ENBIT(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,133 @@ 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 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;
+   u

[PATCH v5 07/17] phy: qcom-qusb2: Add support for different register layouts

2018-01-16 Thread Manu Gautam
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 <mgau...@codeaurora.org>
Reviewed-by: Vivek Gautam <vivek.gau...@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_STATUS0x38
+/* QUSB2PHY_PLL_STATUS register bits */
 #define PLL_LOCKED BIT(5)
 
-#define QUSB2PHY_PORT_TUNE10x80
-#define QUSB2PHY_PORT_TUNE20x84
-#define QUSB2PHY_PORT_TUNE30x88
-#define QUSB2PHY_PORT_TUNE40x8c
-#define QUSB2PHY_PORT_TUNE50x90
-#define QUSB2PHY_PORT_TEST20x9c
-
-#define QUSB2PHY_PORT_POWERDOWN0xb4
+/* 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,
  

[PATCH v5 12/17] dt-bindings: phy-qcom-qmp: Update bindings for QMP V3 USB PHY

2018-01-16 Thread Manu Gautam
Update compatible string and clock names for QMP version V3
USB PHY.

Acked-by: Rob Herring <r...@kernel.org>
Signed-off-by: Manu Gautam <mgau...@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



Re: [PATCH v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence

2018-01-12 Thread Manu Gautam
Hi Vivek,


On 1/12/2018 2:14 PM, Vivek Gautam wrote:
> On Wed, Jan 3, 2018 at 4:58 PM, Manu Gautam <mgau...@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 <mgau...@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.gau...@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(>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 majord...@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



Re: [PATCH] usb: gadget: uvc:change the UVC_NUM_REQUESTS value

2017-12-25 Thread Manu Gautam
Hi,


On 12/26/2017 8:22 AM, Lipengcheng wrote:
> The value is 4, it can cache four descriptors. When streaming_interval = 1,
> it can tolerate 500us. Some busy scenes, it may be more than 500us because
> cpu scheduling is not timely. There will have some problems. It is better
> set to eight.
>
> Signed-off-by: Pengcheng Li 
> ---
>  drivers/usb/gadget/function/uvc.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/usb/gadget/function/uvc.h 
> b/drivers/usb/gadget/function/uvc.h
> index a64e07e..901487e 100644
> --- a/drivers/usb/gadget/function/uvc.h
> +++ b/drivers/usb/gadget/function/uvc.h
> @@ -90,7 +90,7 @@ extern unsigned int uvc_gadget_trace_param;
>   * Driver specific constants
>   */
>
> -#define UVC_NUM_REQUESTS   4
> +#define UVC_NUM_REQUESTS   8

Can we rather make it 16?
I ran into similar issue on QCOM platform with DWC3 and with 8 requests also 
data loss
was observed. 16 requests (i.e. ~2msec) worked fine.

>  #define UVC_MAX_REQUEST_SIZE   64
>  #define UVC_MAX_EVENTS 4
>
> --
> 2.7.4
>
> N�r��y���b�X��ǧv�^�)޺{.n�+{�^n�r���z���h&���G���h�(�階�ݢj"���m�z�ޖ���f���h���~�mml==

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 14/16] phy: Add notify_speed callback

2017-12-28 Thread Manu Gautam
Hi,


On 12/28/2017 4:34 PM, Kishon Vijay Abraham I wrote:
> Hi,
>
[snip]
>
>>> I'd prefer adding modes in enum phy_mode according to speed and using 
>>> phy_set_mode.
>> yeah, that also seems good idea. How about something like this:
>>
>> --- a/include/linux/phy/phy.h
>> +++ b/include/linux/phy/phy.h
>> @@ -23,12 +23,16 @@
>>  struct phy;
>>  
>>  enum phy_mode {
>> -PHY_MODE_INVALID,
>> -PHY_MODE_USB_HOST,
>> -PHY_MODE_USB_DEVICE,
>> -PHY_MODE_USB_OTG,
>> -PHY_MODE_SGMII,
>> -PHY_MODE_10GKR,
>> +PHY_MODE_INVALID= 0,
>> +PHY_MODE_USB_HOST   = BIT(0),
>> +PHY_MODE_USB_DEVICE = BIT(1),
>> +PHY_MODE_USB_OTG,   = BIT(2),
>> +PHY_MODE_SGMII  = BIT(3),
>> +PHY_MODE_10GKR  = BIT(4),
>> +PHY_MODE_USB_LS = BIT(5),
>> +PHY_MODE_USB_FS = BIT(6),
>> +PHY_MODE_USB_HS = BIT(7),
>> +PHY_MODE_USB_SS = BIT(8),
>>  };
>>
>>
>> This way I don't need to duplicate USB speed enums for host/device or otg 
>> modes.
> no.. let's keep enum. It's lot more cleaner IMO.

In that case all PHY drivers would need to consider these speed enums. E.g.

if (mode == HOST) check in PHY driver would need to be changed to:
if (mode == HOST || mode == HOST_LS || mode == HOST_FS || mode == HOST_HS ||
    mode == HOST_SS

This looks clumsy.
Where as if bits to used then there is no need for such changes.

>
> Thanks
> Kishon
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majord...@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



Re: [PATCH v3 14/16] phy: Add notify_speed callback

2018-01-01 Thread Manu Gautam
Hi,


On 12/29/2017 11:58 AM, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Friday 29 December 2017 09:54 AM, Manu Gautam wrote:
>> Hi,
[snip]
>
> suggest using switch in such case.. and not all PHY drivers do specific
> configurations for specific speeds.
>> This looks clumsy.
>> Where as if bits to used then there is no need for such changes.
> really? using bits should only make it more clumsy.

Thanks for your feedback. I will update this in next patchset.


> -Kishon

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 04/16] phy: qcom-qusb2: Power-on PHY before initialization

2018-01-03 Thread Manu Gautam
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 <mgau...@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(>dev, "%s(): Powering-on QUSB2 phy\n", __func__);
+   dev_vdbg(>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(>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(>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(>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



[PATCH v4 01/16] phy: qcom-qmp: Fix phy pipe clock gating

2018-01-03 Thread Manu Gautam
From: Vivek Gautam <vivek.gau...@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: GW   
4.12.0-rc7-00024-gfe926e34c36d-dirty #96
[   33.069451] Hardware name: Qualcomm Technologies, Inc. DB820c (DT)
...
[   33.278565] [] clk_branch_wait+0xf0/0x108
[   33.286375] [] clk_branch2_disable+0x28/0x34
[   33.291761] [] clk_core_disable+0x5c/0x88
[   33.297660] [] clk_core_disable_lock+0x20/0x34
[   33.303129] [] clk_disable+0x1c/0x24
[   33.309384] [] qcom_qmp_phy_poweroff+0x20/0x48
[   33.314328] [] phy_power_off+0x80/0xdc
[   33.320492] [] dwc3_core_exit+0x94/0xa0
[   33.325784] [] dwc3_suspend_common+0x50/0x60
[   33.331080] [] dwc3_runtime_suspend+0x48/0x6c
[   33.336810] [] pm_generic_runtime_suspend+0x28/0x38
[   33.342627] [] __rpm_callback+0x150/0x254
[   33.349222] [] rpm_callback+0x24/0x78
[   33.354604] [] rpm_suspend+0xe0/0x4e4
[   33.359813] [] pm_runtime_work+0xdc/0xf0
[   33.365028] [] process_one_work+0x12c/0x28c
[   33.370576] [] worker_thread+0x58/0x3b8
[   33.376393] [] kthread+0x100/0x12c
[   33.381776] [] 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.gau...@codeaurora.org>
Signed-off-by: Manu Gautam <mgau...@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



[PATCH v4 03/16] phy: qcom-qmp: Power-on PHY before initialization

2018-01-03 Thread Manu Gautam
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 <mgau...@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(>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(>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(>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



[PATCH v4 02/16] phy: qcom-qmp: Adapt to clk_bulk_* APIs

2018-01-03 Thread Manu Gautam
From: Vivek Gautam <vivek.gau...@codeaurora.org>

Move from using array of clocks to clk_bulk_* APIs that
are available now.

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
Signed-off-by: Manu Gautam <mgau...@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



[PATCH v4 15/16] phy: qcom-qusb2: Add support for runtime PM

2018-01-03 Thread Manu Gautam
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 <mgau...@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_ENBIT(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)
+
 #defineQUSB2PHY_PLL_ANALOG_CONTROLS_TWO0x04
 #defineQUSB2PHY_PLL_CLOCK_INVERTERS0x18c
 #defineQUSB2PHY_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 __

[PATCH v4 13/16] phy: qcom-qmp: Add support for QMP V3 USB3 PHY

2018-01-03 Thread Manu Gautam
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 <mgau...@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_MODEBIT(1) /* enables DP 
mode */
+
+
 #define PHY_INIT_COMPLETE_TIMEOUT  1000
 #define POWER_DOWN_DELAY_US_MIN10
 #define POWER_DOWN_DELAY_US_MAX11
@@ -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_in

[PATCH v4 11/16] phy: qcom-qmp: Add register offsets for QMP V3 PHY

2018-01-03 Thread Manu Gautam
Registers offsets for QMP V3 PHY are changed from
previous versions (1/2), update same in header file.

Signed-off-by: Manu Gautam <mgau...@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_RESET0x04
+#define QPHY_V3_DP_COM_POWER_DOWN_CTRL 0x08
+#define QPHY_V3_DP_COM_SWI_CTRL0x0c
+#define QPHY_V3_DP_COM_TYPEC_CTRL  0x10
+#define QPHY_V3_DP_COM_TYPEC_PWRDN_CTRL0x14
+#define QPHY_V3_DP_COM_RESET_OVRD_CTRL 0x1c
+
+/* Only for QMP V3 PHY - QSERDES COM registers */
+#define QSERDES_V3_COM_BG_TIMER0x00c
+#define QSERDES_V3_COM_SSC_EN_CENTER   0x010
+#define QSERDES_V3_COM_SSC_ADJ_PER10x014
+#define QSERDES_V3_COM_SSC_ADJ_PER20x018
+#define QSERDES_V3_COM_SSC_PER10x01c
+#define QSERDES_V3_COM_SSC_PER20x020
+#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_CTRL0x03c
+#define QSERDES_V3_COM_SYSCLK_BUF_ENABLE   0x040
+#define QSERDES_V3_COM_PLL_IVCO0x048
+#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_CFG0x094
+#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_MAP0x0f0
+#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_SEL0x164
+#define QSERDES_V3_COM_DEBUG_BUS0  0x168
+#define QSERDES_V3_COM_DEBUG_BUS1 

[PATCH v4 10/16] phy: qcom-qmp: Move register offsets to header file

2018-01-03 Thread Manu Gautam
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 <mgau...@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 
 
-/* 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_EN0x034
-#define QSERDES_COM_CLK_ENABLE10x038
-#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_MODE00x04c
-#define QSERDES_COM_LOCK_CMP2_MODE00x050
-#define QSERDES_COM_LOCK_CMP3_MODE00x054
-#define QSERDES_COM_LOCK_CMP1_MODE10x058
-#define QSERDES_COM_LOCK_CMP2_MODE10x05c
-#define QSERDES_COM_LOCK_CMP3_MODE10x060
-#define QSERDES_COM_BG_TRIM0x070
-#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_MODE00x084
-#define QSERDES_COM_PLL_RCTRL_MODE10x088
-#define QSERDES_COM_PLL_CCTRL_MODE00x090
-#define QSERDES_COM_PLL_CCTRL_MODE10x094
-#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM0x0a8
-#define QSERDES_COM_SYSCLK_EN_SEL  0x0ac
-#define QSERDES_COM_RESETSM_CNTRL  0x0b4
-#define QSERDES_COM_RESTRIM_CTRL   0x0bc
-#define QSERDES_COM_RESCODE_DIV_NUM0x0c4
-#define QSERDES_COM_LOCK_CMP_EN0x0c8
-#define QSERDES_COM_LOCK_CMP_CFG   0x0cc
-#define QSERDES_COM_DEC_START_MODE00x0d0
-#define QSERDES_COM_DEC_START_MODE10x0d4
-#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_MODE00x12c
-#define QSERDES_COM_VCO_TUNE2_MODE00x130
-#define QSERDES_COM_VCO_TUNE1_MODE10x134
-#define QSERDES_COM_VCO_TUNE2_MODE10x138
-#define QSERDES_COM_VCO_TUNE_TIMER10x144
-#define QSERDES_COM_VCO_TUNE_TIMER20x148
-#define QSERDES_COM_BG_CTRL0x170
-#define QSERDES_COM_CLK_SELECT 0x174
-#define QSERDES_COM_HSCLK_SEL  0x178
-#define QSERDES_COM_CORECLK_DIV0x184
-#define QSERDES_COM_CORE_CLK_EN0x18c
-#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
-#

[PATCH v4 09/16] phy: qcom-qusb2: Add support for QUSB2 V2 version

2018-01-03 Thread Manu Gautam
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 <mgau...@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)
 
+#defineQUSB2PHY_PLL_ANALOG_CONTROLS_TWO0x04
+#defineQUSB2PHY_PLL_CLOCK_INVERTERS0x18c
+#defineQUSB2PHY_PLL_CMODE  0x2c
+#defineQUSB2PHY_PLL_LOCK_DELAY 0x184
+#defineQUSB2PHY_PLL_DIGITAL_TIMERS_TWO 0xb4
+#defineQUSB2PHY_PLL_BIAS_CONTROL_1 0x194
+#defineQUSB2PHY_PLL_BIAS_CONTROL_2 0x198
+#defineQUSB2PHY_PWR_CTRL2  0x214
+#defineQUSB2PHY_IMP_CTRL1  0x220
+#defineQUSB2PHY_IMP_CTRL2  0x224
+#defineQUSB2PHY_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   = _phy_cfg,
+   }, {
+   .compatible = "qcom,qusb2-v2-phy",
+   .data   = _v2_phy_cfg,
},
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 08/16] dt-bindings: phy-qcom-qusb2: Update binding for QUSB2 V2 version

2018-01-03 Thread Manu Gautam
Update generic compatible string for QUSB2 V2 PHY. This will allow
all targets using QUSB2 V2 use same string.

Acked-by: Rob Herring <r...@kernel.org>
Signed-off-by: Manu Gautam <mgau...@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



[PATCH v4 12/16] dt-bindings: phy-qcom-qmp: Update bindings for QMP V3 USB PHY

2018-01-03 Thread Manu Gautam
Update compatible string and clock names for QMP version V3
USB PHY.

Acked-by: Rob Herring <r...@kernel.org>
Signed-off-by: Manu Gautam <mgau...@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



[PATCH v4 07/16] phy: qcom-qusb2: Add support for different register layouts

2018-01-03 Thread Manu Gautam
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 <mgau...@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_STATUS0x38
+/* QUSB2PHY_PLL_STATUS register bits */
 #define PLL_LOCKED BIT(5)
 
-#define QUSB2PHY_PORT_TUNE10x80
-#define QUSB2PHY_PORT_TUNE20x84
-#define QUSB2PHY_PORT_TUNE30x88
-#define QUSB2PHY_PORT_TUNE40x8c
-#define QUSB2PHY_PORT_TUNE50x90
-#define QUSB2PHY_PORT_TEST20x9c
-
-#define QUSB2PHY_PORT_POWERDOWN0xb4
+/* 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)
 {
   

[PATCH v4 06/16] phy: qcom-qmp: Move SERDES/PCS START after PHY reset

2018-01-03 Thread Manu Gautam
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 <mgau...@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



[PATCH v4 16/16] phy: qcom-qmp: Add support for runtime PM

2018-01-03 Thread Manu Gautam
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 <mgau...@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_MODEBIT(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_DETECTBIT(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_MIN10
@@ -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)
+   

[PATCH v4 14/16] phy: Add USB speed related PHY modes

2018-01-03 Thread Manu Gautam
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 <mgau...@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(>mutex);
+   ret = phy->ops->get_mode(phy);
+   mutex_unlock(>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



[PATCH v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence

2018-01-03 Thread Manu Gautam
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 <mgau...@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(>phy_mutex);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 2/2] Embedded USB Debugger (EUD) driver

2018-09-05 Thread Manu Gautam
Hi,


On 9/5/2018 3:04 AM, Prakruthi Deepak Heragu wrote:
> Add support for control peripheral of EUD (Embedded USB Debugger) to
> listen to events such as USB attach/detach, charger enable/disable, pet
> EUD to indicate software is functional.
>
> Signed-off-by: Satya Durga Srinivasu Prabhala 
> Signed-off-by: Prakruthi Deepak Heragu 
> ---
>  drivers/soc/qcom/Kconfig  |  12 ++
>  drivers/soc/qcom/Makefile |   1 +
>  drivers/soc/qcom/eud.c| 338 
> ++
>  3 files changed, 351 insertions(+)
>  create mode 100644 drivers/soc/qcom/eud.c
>
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
[snip]
> +
> +#define EUD_ENABLE_CMD 1
> +#define EUD_DISABLE_CMD 0

Why not use module param as boolean? I mean zero to disable and non-zero to 
enable?
> +
> +#define EUD_REG_INT1_EN_MASK 0x0024
> +#define EUD_REG_INT_STATUS_1 0x0044
> +#define EUD_REG_CTL_OUT_10x0074
> +#define EUD_REG_VBUS_INT_CLR 0x0080
> +#define EUD_REG_CHGR_INT_CLR 0x0084
> +#define EUD_REG_CSR_EUD_EN   0x1014
> +#define EUD_REG_SW_ATTACH_DET0x1018
> +
> +#define EUD_INT_VBUS BIT(2)
> +#define EUD_INT_CHGR BIT(3)
> +#define EUD_INT_SAFE_MODEBIT(4)
> +
> +struct eud_chip {
> + struct device   *dev;
> + int eud_irq;
> + unsigned intextcon_id;
> + unsigned intint_status;
> + boolusb_attach;
> + boolchgr_enable;
> + void __iomem*eud_reg_base;
> + struct extcon_dev   *extcon;
> + struct work_struct  eud_work;
> +};
> +
> +static const unsigned int eud_extcon_cable[] = {
> + EXTCON_USB,
> + EXTCON_CHG_USB_SDP,
> + EXTCON_NONE,
> +};
> +
> +/*
> + * On the kernel command line specify eud.enable=1 to enable EUD.
> + * EUD is disabled by default.
> + */
> +static int enable;
> +static bool eud_ready;
> +static struct eud_chip *eud_private;
> +
> +static void enable_eud(struct eud_chip *priv)
> +{
> + struct power_supply *usb_psy = NULL;
> + union power_supply_propval pval = {0};
> + union power_supply_propval tval = {0};
> + int ret;
> +
> + usb_psy = power_supply_get_by_name("usb");
> + if (!usb_psy)
> + return;
> +
> + ret = power_supply_get_property(usb_psy,
> + POWER_SUPPLY_PROP_PRESENT, );
> + if (ret)
> + return;
> +
> + ret = power_supply_get_property(usb_psy,
> + POWER_SUPPLY_PROP_REAL_TYPE, );
> + if (ret)
> + return;
> +

if(!pval.intval || (tval.intval != POWER_SUPPLY_TYPE_USB &&
tval.intval != POWER_SUPPLY_TYPE_USB_CDP))
    return;

/* following if-else can be removed */
 

> + if (pval.intval && (tval.intval == POWER_SUPPLY_TYPE_USB ||
> + tval.intval == POWER_SUPPLY_TYPE_USB_CDP)) {
> + /* write into CSR to enable EUD */
> + writel_relaxed(BIT(0), priv->eud_reg_base + EUD_REG_CSR_EUD_EN);
> + /* Enable vbus, chgr & safe mode warning interrupts */
> + writel_relaxed(EUD_INT_VBUS | EUD_INT_CHGR | EUD_INT_SAFE_MODE,
> + priv->eud_reg_base + EUD_REG_INT1_EN_MASK);
> +
> + /* Ensure Register Writes Complete */
> + wmb();
> +
> + /*
> +  * Set the default cable state to usb connect and charger
> +  * enable
> +  */
> + ret = extcon_set_state_sync(priv->extcon, EXTCON_USB, true);
> + if (ret)
> + return;
> + ret = extcon_set_state_sync(priv->extcon,
> + EXTCON_CHG_USB_SDP, true);
> + if (ret)
> + return;
> + } else {
> + return;
> + }
> +
> +}
> +
> +static void disable_eud(struct eud_chip *priv)
> +{
> + /* write into CSR to disable EUD */
> + writel_relaxed(0, priv->eud_reg_base + EUD_REG_CSR_EUD_EN);
> +}
> +
> +static int param_eud_set(const char *val, const struct kernel_param *kp)
> +{
> + int enable = 0;
> +
> + if (sscanf(val, "%du", ) != 1)
> + return -EINVAL;
> +
> + if (enable != EUD_ENABLE_CMD && enable != EUD_DISABLE_CMD)
> + return -EINVAL;
Do we really need to worry about it? 'enable' could just be treated as bool

[snip]
> +
> +
> +static irqreturn_t handle_eud_irq(int irq, void *data)
> +{
> + struct eud_chip *chip = data;
> + u32 reg;
> +
> + /* read status register and find out which interrupt triggered */
> + reg = readl_relaxed(chip->eud_reg_base + EUD_REG_INT_STATUS_1);
> + if (reg & EUD_INT_VBUS) {
> + chip->int_status = EUD_INT_VBUS;
> + usb_attach_detach(chip);
> + } else if (reg & EUD_INT_CHGR) {
> + chip->int_status = EUD_INT_CHGR;
> + 

Re: [PATCH 2/2] usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume

2018-01-22 Thread Manu Gautam
Hi,


On 1/22/2018 6:31 PM, Roger Quadros wrote:
> Adding/removing host/gadget controller before .pm_complete()
> causes a lock-up. Let's prevent any dual-role state change
> between .pm_prepare() and .pm_complete() to fix this.

What kind of lock-up are you seeing? Some hardware lockup or software deadlock?
IMO using a freezable_wq for drd_work should address that?


>
> Signed-off-by: Roger Quadros 
> ---
>  drivers/usb/dwc3/core.c | 31 +++
>  drivers/usb/dwc3/core.h |  5 +
>  drivers/usb/dwc3/drd.c  | 10 ++
>  3 files changed, 42 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 42379cc..85388dd 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -1414,6 +1414,33 @@ static int dwc3_runtime_idle(struct device *dev)
>  #endif /* CONFIG_PM */
>  
>  #ifdef CONFIG_PM_SLEEP
> +static int dwc3_prepare(struct device *dev)
> +{
> + struct dwc3 *dwc = dev_get_drvdata(dev);
> + unsigned long   flags;
> +
> + if (dwc->dr_mode == USB_DR_MODE_OTG) {
> + spin_lock_irqsave(>lock, flags);
> + dwc->dr_keep_role = true;
> + spin_unlock_irqrestore(>lock, flags);
> + }
> +
> + return 0;
> +}
> +
> +static void dwc3_complete(struct device *dev)
> +{
> + struct dwc3 *dwc = dev_get_drvdata(dev);
> + unsigned long   flags;
> +
> + if (dwc->dr_mode == USB_DR_MODE_OTG) {
> + spin_lock_irqsave(>lock, flags);
> + dwc->dr_keep_role = false;
> + spin_unlock_irqrestore(>lock, flags);
> + dwc3_drd_update(dwc);
> + }
> +}
> +
>  static int dwc3_suspend(struct device *dev)
>  {
>   struct dwc3 *dwc = dev_get_drvdata(dev);
> @@ -1451,6 +1478,10 @@ static const struct dev_pm_ops dwc3_dev_pm_ops = {
>   SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
>   SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
>   dwc3_runtime_idle)
> +#ifdef CONFIG_PM_SLEEP
> + .prepare = dwc3_prepare,
> + .complete = dwc3_complete,
> +#endif
>  };
>  
>  #ifdef CONFIG_OF
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 4a4a4c9..f5eb474 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -786,6 +786,7 @@ struct dwc3_scratchpad_array {
>   * @dr_mode: requested mode of operation
>   * @current_dr_role: current role of operation when in dual-role mode
>   * @desired_dr_role: desired role of operation when in dual-role mode
> + * @dr_keep_role: keep the current dual-role irrespective of ID changes
>   * @edev: extcon handle
>   * @edev_nb: extcon notifier
>   * @hsphy_mode: UTMI phy mode, one of following:
> @@ -901,6 +902,7 @@ struct dwc3 {
>   enum usb_dr_modedr_mode;
>   u32 current_dr_role;
>   u32 desired_dr_role;
> + booldr_keep_role;
>   struct extcon_dev   *edev;
>   struct notifier_block   edev_nb;
>   enum usb_phy_interface  hsphy_mode;
> @@ -1227,11 +1229,14 @@ static inline int 
> dwc3_send_gadget_generic_command(struct dwc3 *dwc,
>  #if IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
>  int dwc3_drd_init(struct dwc3 *dwc);
>  void dwc3_drd_exit(struct dwc3 *dwc);
> +void dwc3_drd_update(struct dwc3 *dwc);
>  #else
>  static inline int dwc3_drd_init(struct dwc3 *dwc)
>  { return 0; }
>  static inline void dwc3_drd_exit(struct dwc3 *dwc)
>  { }
> +static inline void dwc3_drd_update(struct dwc3 *dwc);
> +{ }
>  #endif
>  
>  /* power management interface */
> diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
> index cc8ab9a..177a8be 100644
> --- a/drivers/usb/dwc3/drd.c
> +++ b/drivers/usb/dwc3/drd.c
> @@ -13,7 +13,7 @@
>  #include "core.h"
>  #include "gadget.h"
>  
> -static void dwc3_drd_update(struct dwc3 *dwc)
> +void dwc3_drd_update(struct dwc3 *dwc)
>  {
>   int id;
>  
> @@ -31,9 +31,11 @@ static int dwc3_drd_notifier(struct notifier_block *nb,
>  {
>   struct dwc3 *dwc = container_of(nb, struct dwc3, edev_nb);
>  
> - dwc3_set_mode(dwc, event ?
> -   DWC3_GCTL_PRTCAP_HOST :
> -   DWC3_GCTL_PRTCAP_DEVICE);
> + if (!dwc->dr_keep_role) {
> + dwc3_set_mode(dwc, event ?
> +   DWC3_GCTL_PRTCAP_HOST :
> +   DWC3_GCTL_PRTCAP_DEVICE);
> + }
>  
>   return NOTIFY_DONE;
>  }

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v1 2/2] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-03-13 Thread Manu Gautam
DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
Some of its uses are described below resulting in need to
have a separate glue driver instead of using dwc3-of-simple:
 - It exposes register interface to override vbus-override
   and lane0-pwr-present signals going to hardware. These
   must be updated in peripheral mode for DWC3 if vbus lines
   are not connected to hardware block. Otherwise RX termination
   in SS mode or DP pull-up is not applied by device controller.
 - pwr_events_irq_stat support to ensure USB2 PHY is in L2 state
   before glue driver can turn-off clocks and suspend PHY.
 - Support for wakeup interrupts lines that are asserted whenever
   there is any wakeup event on USB3 or USB2 bus.
 - Support to replace pip3 clock going to DWC3 with utmi clock
   for hardware configuration where SSPHY is not used with DWC3.

Other than above hardware features in Qscratch wrapper there
are some limitations on QCOM SOCs that require special handling
of power management e.g. suspending PHY using GUSB2PHYCFG
register and ensuring PHY enters L2 before turning off clocks etc.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/usb/dwc3/Kconfig  |  11 +
 drivers/usb/dwc3/Makefile |   1 +
 drivers/usb/dwc3/dwc3-of-simple.c |   1 -
 drivers/usb/dwc3/dwc3-qcom.c  | 635 ++
 4 files changed, 647 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/dwc3/dwc3-qcom.c

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index ab8c0e0..f5bb4f1 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -106,4 +106,15 @@ config USB_DWC3_ST
  inside (i.e. STiH407).
  Say 'Y' or 'M' if you have one such device.
 
+config USB_DWC3_QCOM
+   tristate "Qualcomm Platform"
+   depends on ARCH_QCOM || COMPILE_TEST
+   depends on OF
+   default USB_DWC3
+   help
+ Some Qualcomm SoCs use DesignWare Core IP for USB2/3
+ functionality.
+
+ Say 'Y' or 'M' if you have one such device.
+
 endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 7ac7250..c3ce697 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -48,3 +48,4 @@ obj-$(CONFIG_USB_DWC3_PCI)+= dwc3-pci.o
 obj-$(CONFIG_USB_DWC3_KEYSTONE)+= dwc3-keystone.o
 obj-$(CONFIG_USB_DWC3_OF_SIMPLE)   += dwc3-of-simple.o
 obj-$(CONFIG_USB_DWC3_ST)  += dwc3-st.o
+obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index cb2ee96..0fd0e8e 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -208,7 +208,6 @@ static int dwc3_of_simple_runtime_resume(struct device *dev)
 };
 
 static const struct of_device_id of_dwc3_simple_match[] = {
-   { .compatible = "qcom,dwc3" },
{ .compatible = "rockchip,rk3399-dwc3" },
{ .compatible = "xlnx,zynqmp-dwc3" },
{ .compatible = "cavium,octeon-7130-usb-uctl" },
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
new file mode 100644
index 000..917199e
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -0,0 +1,635 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Inspired by dwc3-of-simple.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "core.h"
+#include "io.h"
+
+/* USB QSCRATCH Hardware registers */
+#define QSCRATCH_HS_PHY_CTRL   0x10
+#define UTMI_OTG_VBUS_VALIDBIT(20)
+#define SW_SESSVLD_SEL BIT(28)
+
+#define QSCRATCH_SS_PHY_CTRL   0x30
+#define LANE0_PWR_PRESENT  BIT(24)
+
+#define QSCRATCH_GENERAL_CFG   0x08
+#define PIPE_UTMI_CLK_SEL  BIT(0)
+#define PIPE3_PHYSTATUS_SW BIT(3)
+#define PIPE_UTMI_CLK_DIS  BIT(8)
+
+#define PWR_EVNT_IRQ_STAT_REG  0x58
+#define PWR_EVNT_LPM_IN_L2_MASKBIT(4)
+#define PWR_EVNT_LPM_OUT_L2_MASK   BIT(5)
+
+#define HSPHY_L2_ENTER_TIMEOUT_US  5000
+
+struct dwc3_qcom {
+   struct device   *dev;
+   void __iomem*qscratch_base;
+   struct platform_device  *dwc3;
+   struct clk  **clks;
+   int num_clocks;
+   struct reset_control*resets;
+
+   int dp_hs_phy_irq;
+   int dm_hs_phy_irq;
+   int ss_phy_irq;
+
+   struct extcon_dev   *edev;
+   struct extcon_dev   *host_edev;
+   struct notifier_block   vbus_nb;
+   struct no

[PATCH v1 1/2] dt-bindings: usb: Update documentation for Qualcomm DWC3 driver

2018-03-13 Thread Manu Gautam
Existing documentation has lot of incorrect information as it
was originally added for a driver that no longer exists.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 .../devicetree/bindings/usb/qcom,dwc3.txt  | 87 +++---
 1 file changed, 59 insertions(+), 28 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt 
b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
index bc8a2fa..df312f7 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
@@ -1,54 +1,85 @@
 Qualcomm SuperSpeed DWC3 USB SoC controller
 
 Required properties:
-- compatible:  should contain "qcom,dwc3"
-- clocks:  A list of phandle + clock-specifier pairs for the
-   clocks listed in clock-names
-- clock-names: Should contain the following:
-  "core"   Master/Core clock, have to be >= 125 MHz for SS
-   operation and >= 60MHz for HS operation
-
-Optional clocks:
-  "iface"  System bus AXI clock.  Not present on all platforms
-  "sleep"  Sleep clock, used when USB3 core goes into low
-   power mode (U3).
+- compatible:  should contain "qcom,dwc3"
+- reg: offset and length of register set for QSCRATCH wrapper
+- reg-names:   should be "qscratch"
+- power-domains:   specifies a phandle to PM domain provider node
+- clocks:  list of phandle + clock-specifier pairs
+- assigned-clocks: should be:
+   MOCK_UTMI_CLK
+   MASTER_CLK
+- assigned-clock-rates: should be:
+19.2Mhz (19200) for MOCK_UTMI_CLK
+>=125Mhz (12500) for MASTER_CLK in SS mode
+>=60Mhz (6000) for MASTER_CLK in HS mode
+
+Optional properties:
+- resets:  list of phandle and reset specifier pairs
+- interrupts:  specifies interrupts from controller wrapper used
+   to wakeup from low power/susepnd state. Must contain
+   one or more entry for interrupt-names property
+- interrupt-names: Must include the following entries:
+   - "hs_phy_irq": The interrupt that is asserted when a
+  wakeup event is received on USB2 bus
+   - "ss_phy_irq": The interrupt that is asserted when a
+  wakeup event is received on USB3 bus
+   - "dm_hs_phy_irq" and "dp_hs_phy_irq": Separate
+  interrupts for any wakeup event on DM and DP lines
+- qcom,select-utmi-as-pipe-clk: if present, disable USB3 pipe_clk requirement.
+   Used when dwc3 operates without SSPHY and only
+   HS/FS/LS modes are supported.
 
 Required child node:
 A child node must exist to represent the core DWC3 IP block. The name of
 the node is not important. The content of the node is defined in dwc3.txt.
 
 Phy documentation is provided in the following places:
-Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt
+Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt   - USB3 QMP PHY
+Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt - USB2 QUSB2 PHY
 
 Example device nodes:
 
hs_phy: phy@100f8800 {
-   compatible = "qcom,dwc3-hs-usb-phy";
-   reg = <0x100f8800 0x30>;
-   clocks = < USB30_0_UTMI_CLK>;
-   clock-names = "ref";
-   #phy-cells = <0>;
-
+   compatible = "qcom,qusb2-v2-phy";
+   ...
};
 
ss_phy: phy@100f8830 {
-   compatible = "qcom,dwc3-ss-usb-phy";
-   reg = <0x100f8830 0x30>;
-   clocks = < USB30_0_MASTER_CLK>;
-   clock-names = "ref";
-   #phy-cells = <0>;
-
+   compatible = "qcom,qmp-v3-usb3-phy";
+   ...
};
 
-   usb3_0: usb30@0 {
+   usb3_0: usb30@a6f8800 {
compatible = "qcom,dwc3";
+   reg = <0xa6f8800 0x400>;
+   reg-names = "qscratch";
#address-cells = <1>;
#size-cells = <1>;
-   clocks = < USB30_0_MASTER_CLK>;
-   clock-names = "core";
-
ranges;
 
+

Re: [PATCH v1 2/2] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-03-13 Thread Manu Gautam
Hi,


On 3/13/2018 4:38 PM, Felipe Balbi wrote:
> Hi,
>
> +Andy
>
> Manu Gautam <mgau...@codeaurora.org> writes:
>> DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
>> Some of its uses are described below resulting in need to
>> have a separate glue driver instead of using dwc3-of-simple:
>>  - It exposes register interface to override vbus-override
>>and lane0-pwr-present signals going to hardware. These
>>must be updated in peripheral mode for DWC3 if vbus lines
>>are not connected to hardware block. Otherwise RX termination
>>in SS mode or DP pull-up is not applied by device controller.
> right, core needs to know that VBUS is above 4.4V. Why wasn't this a
> problem when the original glue layer was first published?

Thanks for reviewing.
Original glue layer supported only host mode, hence this wasn't needed.

>
>>  - pwr_events_irq_stat support to ensure USB2 PHY is in L2 state
>>before glue driver can turn-off clocks and suspend PHY.
> Core manages PHY suspend automatically. Isn't that working for you? Why?

Yes, it is not supported with QUSB2 PHY (usb2-phy on Qualcomm SOCs).
Issue is that If core suspends USB2 PHY (say in host mode if some SS device 
connected),
USB2 PHY stops responding to any attach event as it can't exit suspend state by 
itself.
But in case of driver suspend, along with PHY suspend wakeup events are enabled.
Glue driver can register for wakeup interrupts to exit suspend.

>
>>  - Support for wakeup interrupts lines that are asserted whenever
>>there is any wakeup event on USB3 or USB2 bus.
> ok
>
>>  - Support to replace pip3 clock going to DWC3 with utmi clock
>>for hardware configuration where SSPHY is not used with DWC3.
> Is that SW configurable? Really? In any case seems like this and SESSVLD
> valid should be handled using Hans' and Heikki's mux support.

Yes, with this we can use dwc3 without using SSPHY. Please point me to
those patches. There are only bunch of register writes in glue wrapper to
achieve the same.

>
>> Other than above hardware features in Qscratch wrapper there
>> are some limitations on QCOM SOCs that require special handling
>> of power management e.g. suspending PHY using GUSB2PHYCFG
>> register and ensuring PHY enters L2 before turning off clocks etc.
>>
>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>> ---
>>  drivers/usb/dwc3/Kconfig  |  11 +
>>  drivers/usb/dwc3/Makefile |   1 +
>>  drivers/usb/dwc3/dwc3-of-simple.c |   1 -
>>  drivers/usb/dwc3/dwc3-qcom.c  | 635 
>> ++
>>  4 files changed, 647 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/usb/dwc3/dwc3-qcom.c
>>
>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>> index ab8c0e0..f5bb4f1 100644
>> --- a/drivers/usb/dwc3/Kconfig
>> +++ b/drivers/usb/dwc3/Kconfig
>> @@ -106,4 +106,15 @@ config USB_DWC3_ST
>>inside (i.e. STiH407).
>>Say 'Y' or 'M' if you have one such device.
>>  
>> +config USB_DWC3_QCOM
>> +tristate "Qualcomm Platform"
>> +depends on ARCH_QCOM || COMPILE_TEST
>> +depends on OF
>> +default USB_DWC3
>> +help
>> +  Some Qualcomm SoCs use DesignWare Core IP for USB2/3
>> +  functionality.
>> +
>> +  Say 'Y' or 'M' if you have one such device.
>> +
>>  endif
>> diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
>> index 7ac7250..c3ce697 100644
>> --- a/drivers/usb/dwc3/Makefile
>> +++ b/drivers/usb/dwc3/Makefile
>> @@ -48,3 +48,4 @@ obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o
>>  obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o
>>  obj-$(CONFIG_USB_DWC3_OF_SIMPLE)+= dwc3-of-simple.o
>>  obj-$(CONFIG_USB_DWC3_ST)   += dwc3-st.o
>> +obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o
>> diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
>> b/drivers/usb/dwc3/dwc3-of-simple.c
>> index cb2ee96..0fd0e8e 100644
>> --- a/drivers/usb/dwc3/dwc3-of-simple.c
>> +++ b/drivers/usb/dwc3/dwc3-of-simple.c
>> @@ -208,7 +208,6 @@ static int dwc3_of_simple_runtime_resume(struct device 
>> *dev)
>>  };
>>  
>>  static const struct of_device_id of_dwc3_simple_match[] = {
>> -{ .compatible = "qcom,dwc3" },
>>  { .compatible = "rockchip,rk3399-dwc3" },
>>  { .compatible = "xlnx,zynqmp-dwc3" },
>>  { .compatible = "cavium,octeon-7130-usb-uctl" },
>> diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
>> new file 

[PATCH] phy: core: Allow phy_pm_runtime_xxx API calls with NULL phy

2018-03-16 Thread Manu Gautam
phy_init() and phy_exit() calls, and phy_power_on() and
phy_power_off() already accept NULL as valid PHY refernece
and act as NOP. Extend same concept to phy runtime_pm APIs
to keep drivers (e.g. dwc3) code simple while dealing with
optional PHYs.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/phy-core.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 09ac8af..48b9615 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -153,6 +153,9 @@ int phy_pm_runtime_get(struct phy *phy)
 {
int ret;
 
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(>dev))
return -ENOTSUPP;
 
@@ -168,6 +171,9 @@ int phy_pm_runtime_get_sync(struct phy *phy)
 {
int ret;
 
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(>dev))
return -ENOTSUPP;
 
@@ -181,6 +187,9 @@ int phy_pm_runtime_get_sync(struct phy *phy)
 
 int phy_pm_runtime_put(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(>dev))
return -ENOTSUPP;
 
@@ -190,6 +199,9 @@ int phy_pm_runtime_put(struct phy *phy)
 
 int phy_pm_runtime_put_sync(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(>dev))
return -ENOTSUPP;
 
@@ -199,6 +211,9 @@ int phy_pm_runtime_put_sync(struct phy *phy)
 
 void phy_pm_runtime_allow(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(>dev))
return;
 
@@ -208,6 +223,9 @@ void phy_pm_runtime_allow(struct phy *phy)
 
 void phy_pm_runtime_forbid(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(>dev))
return;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-16 Thread Manu Gautam
QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
to take place. This lock is output from PHY to GCC clock_ctl and then
fed back to QMP PHY and is output from PHY only after PHY is reset
and initialized, hence it can't be enabled too early in initialization
sequence.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 6470c5d..73aa282 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -797,8 +797,13 @@ static int qcom_qmp_phy_poweron(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 ret;
 
+   /* Not needed for USB3 PHY as pipe_clk is enabled from phy_init */
+   if (cfg->type == PHY_TYPE_USB3)
+   return 0;
+
ret = clk_prepare_enable(qphy->pipe_clk);
if (ret)
dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
@@ -1008,6 +1013,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
mask = cfg->mask_pcs_ready;
 
+   /* USB3 PHY requires pipe_clk for PLL lock and calibration */
+   if (cfg->type == PHY_TYPE_USB3) {
+   ret = clk_prepare_enable(qphy->pipe_clk);
+   if (ret)
+   dev_err(qmp->dev, "pipe_clk enable err=%d\n", ret);
+   /*
+* Ignore this error as pipe_clk might take some time to get
+* enabled. In any case following check for PHY PLL lock would
+* timeout below if there is a fatal error and clock is not fed
+* to PHY
+*/
+   }
+
ret = readl_poll_timeout(status, val, !(val & mask), 1,
 PHY_INIT_COMPLETE_TIMEOUT);
if (ret) {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 2/6] phy: qcom-qusb2: Fix crash if nvmem cell not specified

2018-03-16 Thread Manu Gautam
Driver currently crashes due to NULL pointer deference
while updating PHY tune register if nvmem cell is NULL.
Since, fused value for Tune1/2 register is optional,
we'd rather bail out.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 94afeac..40fdef8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -315,6 +315,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
const struct qusb2_phy_cfg *cfg = qphy->cfg;
u8 *val;
 
+   /* efuse register is optional */
+   if (!qphy->cell)
+   return;
+
/*
 * Read efuse register having TUNE2/1 parameter's high nibble.
 * If efuse register shows value as 0x0, or if we fail to find
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 3/6] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-03-16 Thread Manu Gautam
Update compatible strings for USB3 PHYs on SDM845.
One is QMPv3 DisplayPort-USB combo PHY and other one
is USB UNI PHY which is single lane USB3 PHY without
DP capability.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index dcf1b8f..cef8765 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -9,7 +9,9 @@ Required properties:
   "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,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
+  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy,
+  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
+  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845.
 
  - reg: offset and length of register set for PHY's common serdes block.
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 4/6] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-03-16 Thread Manu Gautam
QMP V3 UNI PHY is a single lane USB3 PHY without support
for DisplayPort (DP).
Main difference from DP combo QMPv3 PHY is that UNI PHY
doesn't have dual RX/TX lanes and no separate DP_COM
block for configuration related to type-c or DP.
While at it, fix has_pwrdn_delay attribute for USB-DP
PHY configuration.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 148 
 drivers/phy/qualcomm/phy-qcom-qmp.h |   5 ++
 2 files changed, 153 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 73aa282..689951d 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -490,6 +490,118 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
 };
 
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+   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, 0x06),
+   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_uniphy_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, 0xc6),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+   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, 0x1c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_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

[PATCH 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-16 Thread Manu Gautam
Update compatible strings for USB2 PHYs on sdm845.
There are two QUSB2 PHYs present on sdm845. Few PHY registers
programming is different for these PHYs related to electrical
parameters, otherwise both are same.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index 42c9742..20deaeb 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -6,7 +6,9 @@ QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm 
chipsets.
 Required properties:
  - compatible: compatible list, contains
   "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
-  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY,
+  "qcom,sdm845-1-qusb2-phy" for primary PHY on sdm845,
+  "qcom,sdm845-2-qusb2-phy" for secondary PHY on sdm845.
 
  - 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



[PATCH 6/6] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-03-16 Thread Manu Gautam
There are two QUSB2 PHYs present on sdm845. Update PHY
registers programming for both the PHYs related to
electrical parameters to improve eye diagram.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 40fdef8..1a608a9 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -174,6 +174,27 @@ enum qusb2phy_reg_layout {
QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
 };
 
+static const struct qusb2_phy_init_tbl sdm845_init_tbl_1[] = {
+   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, 0x8),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
+
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x45),
+   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 */
@@ -220,6 +241,18 @@ struct qusb2_phy_cfg {
.autoresume_en= BIT(0),
 };
 
+static const struct qusb2_phy_cfg sdm845_phy_cfg_1 = {
+   .tbl= sdm845_init_tbl_1,
+   .tbl_num= ARRAY_SIZE(sdm845_init_tbl_1),
+   .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,
+   .has_pll_override = true,
+   .autoresume_en= BIT(0),
+};
+
 static const char * const qusb2_phy_vreg_names[] = {
"vdda-pll", "vdda-phy-dpdm",
 };
@@ -649,6 +682,12 @@ static int qusb2_phy_exit(struct phy *phy)
}, {
.compatible = "qcom,qusb2-v2-phy",
.data   = _v2_phy_cfg,
+   }, {
+   .compatible = "qcom,sdm845-1-qusb2-phy",
+   .data   = _phy_cfg_1,
+   }, {
+   .compatible = "qcom,sdm845-2-qusb2-phy",
+   .data   = _v2_phy_cfg,
},
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 2/2] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-03-15 Thread Manu Gautam
Hi,


On 3/14/2018 2:20 PM, Felipe Balbi wrote:
> Hi,
>
> Manu Gautam <mgau...@codeaurora.org> writes:
>
[snip]
>>>>  - Support to replace pip3 clock going to DWC3 with utmi clock
>>>>for hardware configuration where SSPHY is not used with DWC3.
>>> Is that SW configurable? Really? In any case seems like this and SESSVLD
>>> valid should be handled using Hans' and Heikki's mux support.
>> Yes, with this we can use dwc3 without using SSPHY. Please point me to
>> those patches. There are only bunch of register writes in glue wrapper to
>> achieve the same.
> https://www.spinics.net/lists/linux-usb/msg160868.html

I looked at the patchset and thinking that adding mux for this may
not be of much help here. Qscratch is part of dwc3 wrapper
and uses same clock domain for its registers. Hence, I can't
have a separate mux driver for same. Will have to register
mux controller from this driver for these and use only in this driver
as I dont expect any other client for same. So, can I proceed with
existing logic?

>
>>>> +static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
>>>> +{
>>>> +  struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
>>> nope! Glue shouldn't touch dwc3 at all.
>> Other than PHY handles, need this to fail runtime suspend if dwc3 hasn't
>> probed yet.
> Will that even happen? You should pm_runtime_forbid() by default,
> anyway and expect it to be enabled via sysfs later, no?

It happens if I enable runtime_pm from probe which is the case right now.
I will disable it from probe as you suggested.
In any case dwc3 uses pm_runtime_forbid and expects it to be enabled from sysfs,
so I dont get any benefit of enabling it from glue driver probe.

Other than this, I need to access 'dwc->xhci' to resume root hub on remote 
wakeup.
That I missed to mention earlier.

>
>>>> +  dwc3_qcom_suspend_hsphy(qcom);
>>>> +
>>>> +  if (dwc->usb2_generic_phy)
>>>> +  phy_pm_runtime_put_sync(dwc->usb2_generic_phy);
>>>> +  if (dwc->usb3_generic_phy)
>>>> +  phy_pm_runtime_put_sync(dwc->usb3_generic_phy);
>>> core.c should do this.
>> Recommended sequence from h/w programming guide is that:
>> 1. PHY autosuspend must be left disabled - 
>> snps,dis_u2_susphy_quirk/dis_enblslpm_quirk
>> 2. During runtime-suspend (say on xhci bus_suspend) , PHY should be suspended
>>     using GUSB2PHYCFG register
> this is something that dwc3 core can do on its own suspend implementation.
>
>> 3. Wait until pwr_event_irq_stat in qscratch reflects PHY transition to L2.
> this is interesting part. Is this register accessible by the PHY driver?
> Seems like that would be the best place to stuff this...

This register is in controller wrapper which PHY driver can't access.
Also clock domain is different.

>
>> 3. USB2 PHY driver can suspend - enable wakeup events and turns off clocks 
>> etc.
> ... together with this.
>
>> 4. dwc3 glue driver can suspend.
>>
>> Since, pwr_event_irq stat can't be checked in core driver, I added this 
>> handling
>> in glue driver. Alternative approach I can think of is to let dwc3 core 
>> suspend
>> PHY using GUSBPHYCFG register on suspend,  add some delay before
>> suspending PHY. Glue driver can check for pwr_event_irq stat and throw a
>> warning if PHY not in L2.
> almost :-) core_suspend fiddles with GUSB2PHYCFG for suspend and calls
> phy_suspend() (or whatever the function is called heh), that will go to
> your phy driver's suspend callback, which checks pwr_event_irq_stat and
> then pm_runtime_put() to schedule ->runtime_suspend() so that can enable
> wakeups and switch off clocks.

Since phy driver can not access pwr_event_irq_stat, should I just use some delay
and assume PHY gets suspended?

>
>>>> +  irq = platform_get_irq_byname(pdev, "dp_hs_phy_irq");
>>>> +  if (irq > 0) {
>>>> +  irq_set_status_flags(irq, IRQ_NOAUTOEN);
>>> why do you need to set this flag?
>> These wakeup_irqs should be enabled only during suspend. With this flag I
>> don't need to disable irq immediately after requesting it.
> oh, okay. You may want to add a comment here :-)
Sure.

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v4 2/7] phy: qcom-qmp: Enable pipe_clk before PHY initialization

2018-04-11 Thread Manu Gautam
Hi,


On 4/11/2018 12:02 AM, Stephen Boyd wrote:
> Quoting Doug Anderson (2018-04-10 08:05:27)
>> On Mon, Apr 9, 2018 at 11:36 PM, Manu Gautam <mgau...@codeaurora.org> wrote:
>>> On 3/30/2018 2:24 AM, Doug Anderson wrote:
>>>> Oh!  This is what you did in the previous version of the patch, then you 
>>>> said:
>>>>
>>>> "That is still needed as PHY might take some time to generate pipe_clk
>>>> after its PLL is locked".
>>>>
>>>> It's really going to take more than the 200 us that the clock driver
>>>> is giving it?  If so, I'd prefer to increase the amount of time waited
>>>> in the clock driver, or adding a fixed delay _before_ the clk_enable()
>>>> so that the 200 us that the clock driver gives it would be enough.
>>>>
>>>> I'm just not a fan of ignoring status bits if it can be helped.
>>> I too would want to do that but it is not just about the delay.
>>> As per QMP PHY hardware designers, pipe_clk should be enabled in GCC
>>> as first thing in the PHY initialization sequence. Same sequence also has
>>> been used in downstream phy driver always.
>>> Changing the sequence might work but I would like to stick to the HPG
>>> recommendation and avoid any deviation as PHY issues are very hard to
>>> debug.
>> So hardware guys tell you that you're _supposed to_ ignore the clock
>> ready bit for that clock and just hope it turns on and settles in time
>> once power comes on for the clock?  That doesn't seem ideal.  My guess
>> is that it's a bug in the specification that the QMP PHY hardware
>> designers gave you.
It could be a bug in specification. But same sequence has been well tested on 
both
msm8996 and sdm845, so I would for now like to stick with that for now.
>> Stephen can feel free to override me if he disagrees since he's in
>> charge of the clock part of this, but IMHO we should get the
>> specification fixed and turn things on in the order that lets us check
>> the status bits.
>>
> Presumably there's a PLL "enable" bit in the QMP phy init sequence that
> we can use to enable the PLL output at a bypass rate and then enable the
> clk in GCC and then resume the PLL enable sequence. That would allow us
> to make sure the clk is working.
>
> Are the branches in GCC ever turned on or off at runtime though? Or do
> we just turn them on because they're defaulted off out of reset and then
> leave them on?
It can be left on always.
>
> I ask because it may be easier to never expose these clks in Linux, hit
> the enable bits in the branches during clk driver probe, and then act
> like they never exist because we don't really use them.
This sounds better idea. Let me check if I can get a patch for same in msm8996
and sdm845 clock drivers.


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 2/3] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-04-13 Thread Manu Gautam
Hi Jack,


On 4/13/2018 11:03 PM, Jack Pham wrote:
> Hi Manu,
>
> On Fri, Apr 13, 2018 at 10:21:23PM +0530, Manu Gautam wrote:
>> DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
>> Some of its uses are described below resulting in need to
>> have a separate glue driver instead of using dwc3-of-simple:
>>  - It exposes register interface to override vbus-override
>>and lane0-pwr-present signals going to hardware. These
>>must be updated in peripheral mode for DWC3 if vbus lines
>>are not connected to hardware block. Otherwise RX termination
>>in SS mode or DP pull-up is not applied by device controller.
>>  - pwr_events_irq_stat support to check if USB2 PHY is in L2 state
>>before glue driver proceeds with suspend.
>>  - Support for wakeup interrupts lines that are asserted whenever
>>there is any wakeup event on USB3 or USB2 bus.
>>  - Support to replace pip3 clock going to DWC3 with utmi clock
>>for hardware configuration where SSPHY is not used with DWC3.
>>
>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
> 
>
>> +static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom)
>> +{
>> +struct device   *dev = qcom->dev;
>> +struct extcon_dev   *host_edev;
>> +int ret;
>> +
>> +if (!of_property_read_bool(dev->of_node, "extcon"))
>> +return 0;
>> +
>> +qcom->edev = extcon_get_edev_by_phandle(dev, 0);
> Are the extcon phandles bound to the glue node? I don't see the
> description in the bindings doc in PATCH 1/3. And if so, would it be
> a duplicate of the child node's extcon binding? Then again, the
> alternative would be to grab it directly from the child (i.e.
> qcom->dwc3->dev.of_node) which I'm not sure is ok to do or not.
>

Yes these are bound to glue node. I missed to add it to documentation, will do
so.
I kept it separate for couple of reasons - one is to not peek too-much into 
child
node. Another reason is that doing so allows to have extcon in "peripheral"
only mode as well (not just drd mode which is the case with dwc3 core).
It allows to notify h/w when vbus is not there in device mode which IMO is
right thing to do.



-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 0/3] usb: dwc3: support for Qualcomm DWC3 glue

2018-04-13 Thread Manu Gautam
Add separate dwc3-qcom glue driver for Qualcomm SOCs having dwc3 core.
It is needed to support peripheral mode.
Patches also add support to invoke PHY runtime PM functions on host
mode bus-suspend.

Changes since v1:
 - Move dwc3 core register accesses from glue driver to dwc3 core as
   per review comment from Felipe.
 - Addressed other review comments from Felipe and Rob.
 - Some other minor code changes related to redability.
 - Add reset_control assert in driver probe to ensure core registers
   are reset to POR value in case of any initalization by boot code. 

Manu Gautam (3):
  dt-bindings: usb: Update documentation for Qualcomm DWC3 driver
  usb: dwc3: Add Qualcomm DWC3 glue driver
  usb: dwc3: core: Suspend PHYs on runtime suspend in host mode

 .../devicetree/bindings/usb/qcom,dwc3.txt  |  78 ++-
 drivers/usb/dwc3/Kconfig   |  12 +
 drivers/usb/dwc3/Makefile  |   1 +
 drivers/usb/dwc3/core.c|  36 +-
 drivers/usb/dwc3/dwc3-of-simple.c  |   1 -
 drivers/usb/dwc3/dwc3-qcom.c   | 618 +
 6 files changed, 721 insertions(+), 25 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3-qcom.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 3/3] usb: dwc3: core: Suspend PHYs on runtime suspend in host mode

2018-04-13 Thread Manu Gautam
Some PHY drivers (e.g. for Qualcomm QUSB2 and QMP PHYs) support
runtime PM to reduce PHY power consumption during bus_suspend.
Add changes to let core auto-suspend PHYs on host bus-suspend
using GUSB2PHYCFG register if needed for a platform. Also perform
PHYs runtime suspend/resume and let platform glue drivers e.g.
dwc3-qcom handle remote wakeup during bus suspend by waking up
devices on receiving wakeup event from PHY.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/usb/dwc3/core.c | 36 +---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a15648d..449a098 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1394,6 +1394,7 @@ static int dwc3_remove(struct platform_device *pdev)
 static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
 {
unsigned long   flags;
+   u32 reg;
 
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -1403,9 +1404,25 @@ static int dwc3_suspend_common(struct dwc3 *dwc, 
pm_message_t msg)
dwc3_core_exit(dwc);
break;
case DWC3_GCTL_PRTCAP_HOST:
-   /* do nothing during host runtime_suspend */
-   if (!PMSG_IS_AUTO(msg))
+   if (!PMSG_IS_AUTO(msg)) {
dwc3_core_exit(dwc);
+   break;
+   }
+
+   /* Let controller to suspend HSPHY before PHY driver suspends */
+   if (dwc->dis_u2_susphy_quirk ||
+   dwc->dis_enblslpm_quirk) {
+   reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+   reg |=  DWC3_GUSB2PHYCFG_ENBLSLPM |
+   DWC3_GUSB2PHYCFG_SUSPHY;
+   dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+   /* Give some time for USB2 PHY to suspend */
+   usleep_range(5000, 6000);
+   }
+
+   phy_pm_runtime_put_sync(dwc->usb2_generic_phy);
+   phy_pm_runtime_put_sync(dwc->usb3_generic_phy);
break;
case DWC3_GCTL_PRTCAP_OTG:
/* do nothing during runtime_suspend */
@@ -1433,6 +1450,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
 {
unsigned long   flags;
int ret;
+   u32 reg;
 
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -1446,13 +1464,25 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
spin_unlock_irqrestore(>lock, flags);
break;
case DWC3_GCTL_PRTCAP_HOST:
-   /* nothing to do on host runtime_resume */
if (!PMSG_IS_AUTO(msg)) {
ret = dwc3_core_init(dwc);
if (ret)
return ret;
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
+   break;
}
+   /* Restore GUSB2PHYCFG bits that were modified in suspend */
+   reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+   if (dwc->dis_u2_susphy_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+
+   if (dwc->dis_enblslpm_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+
+   dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+   phy_pm_runtime_get_sync(dwc->usb2_generic_phy);
+   phy_pm_runtime_get_sync(dwc->usb3_generic_phy);
break;
case DWC3_GCTL_PRTCAP_OTG:
/* nothing to do on runtime_resume */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 2/3] usb: dwc3: Add Qualcomm DWC3 glue driver

2018-04-13 Thread Manu Gautam
DWC3 controller on Qualcomm SOCs has a Qscratch wrapper.
Some of its uses are described below resulting in need to
have a separate glue driver instead of using dwc3-of-simple:
 - It exposes register interface to override vbus-override
   and lane0-pwr-present signals going to hardware. These
   must be updated in peripheral mode for DWC3 if vbus lines
   are not connected to hardware block. Otherwise RX termination
   in SS mode or DP pull-up is not applied by device controller.
 - pwr_events_irq_stat support to check if USB2 PHY is in L2 state
   before glue driver proceeds with suspend.
 - Support for wakeup interrupts lines that are asserted whenever
   there is any wakeup event on USB3 or USB2 bus.
 - Support to replace pip3 clock going to DWC3 with utmi clock
   for hardware configuration where SSPHY is not used with DWC3.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/usb/dwc3/Kconfig  |  12 +
 drivers/usb/dwc3/Makefile |   1 +
 drivers/usb/dwc3/dwc3-of-simple.c |   1 -
 drivers/usb/dwc3/dwc3-qcom.c  | 618 ++
 4 files changed, 631 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/dwc3/dwc3-qcom.c

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index ab8c0e0..451012e 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -106,4 +106,16 @@ config USB_DWC3_ST
  inside (i.e. STiH407).
  Say 'Y' or 'M' if you have one such device.
 
+config USB_DWC3_QCOM
+   tristate "Qualcomm Platform"
+   depends on ARCH_QCOM || COMPILE_TEST
+   depends on OF
+   default USB_DWC3
+   help
+ Some Qualcomm SoCs use DesignWare Core IP for USB2/3
+ functionality.
+ This driver also handles Qscratch wrapper which is needed
+ for peripheral mode support.
+ Say 'Y' or 'M' if you have one such device.
+
 endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 025bc68..5c07d8f 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -48,3 +48,4 @@ obj-$(CONFIG_USB_DWC3_PCI)+= dwc3-pci.o
 obj-$(CONFIG_USB_DWC3_KEYSTONE)+= dwc3-keystone.o
 obj-$(CONFIG_USB_DWC3_OF_SIMPLE)   += dwc3-of-simple.o
 obj-$(CONFIG_USB_DWC3_ST)  += dwc3-st.o
+obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index cb2ee96..0fd0e8e 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -208,7 +208,6 @@ static int dwc3_of_simple_runtime_resume(struct device *dev)
 };
 
 static const struct of_device_id of_dwc3_simple_match[] = {
-   { .compatible = "qcom,dwc3" },
{ .compatible = "rockchip,rk3399-dwc3" },
{ .compatible = "xlnx,zynqmp-dwc3" },
{ .compatible = "cavium,octeon-7130-usb-uctl" },
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
new file mode 100644
index 000..ecb2218
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -0,0 +1,618 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Inspired by dwc3-of-simple.c
+ */
+#define DEBUG
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "core.h"
+
+/* USB QSCRATCH Hardware registers */
+#define QSCRATCH_HS_PHY_CTRL   0x10
+#define UTMI_OTG_VBUS_VALIDBIT(20)
+#define SW_SESSVLD_SEL BIT(28)
+
+#define QSCRATCH_SS_PHY_CTRL   0x30
+#define LANE0_PWR_PRESENT  BIT(24)
+
+#define QSCRATCH_GENERAL_CFG   0x08
+#define PIPE_UTMI_CLK_SEL  BIT(0)
+#define PIPE3_PHYSTATUS_SW BIT(3)
+#define PIPE_UTMI_CLK_DIS  BIT(8)
+
+#define PWR_EVNT_IRQ_STAT_REG  0x58
+#define PWR_EVNT_LPM_IN_L2_MASKBIT(4)
+#define PWR_EVNT_LPM_OUT_L2_MASK   BIT(5)
+
+struct dwc3_qcom {
+   struct device   *dev;
+   void __iomem*qscratch_base;
+   struct platform_device  *dwc3;
+   struct clk  **clks;
+   int num_clocks;
+   struct reset_control*resets;
+
+   int hs_phy_irq;
+   int dp_hs_phy_irq;
+   int dm_hs_phy_irq;
+   int ss_phy_irq;
+
+   struct extcon_dev   *edev;
+   struct extcon_dev   *host_edev;
+   struct notifier_block   vbus_nb;
+   struct notifier_block   host_nb;
+
+   enum usb_dr_modemode;
+   boolis_suspended;
+   boolpm_suspended;
+};
+
+static inl

[PATCH v2 1/3] dt-bindings: usb: Update documentation for Qualcomm DWC3 driver

2018-04-13 Thread Manu Gautam
Existing documentation has lot of incorrect information as it
was originally added for a driver that no longer exists.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 .../devicetree/bindings/usb/qcom,dwc3.txt  | 78 --
 1 file changed, 57 insertions(+), 21 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt 
b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
index bc8a2fa..fdc574a 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
@@ -1,54 +1,90 @@
 Qualcomm SuperSpeed DWC3 USB SoC controller
 
 Required properties:
-- compatible:  should contain "qcom,dwc3"
+- compatible:  should contain "qcom,dwc3"
+- reg: offset and length of register set for QSCRATCH wrapper
+- power-domains:   specifies a phandle to PM domain provider node
 - clocks:  A list of phandle + clock-specifier pairs for the
clocks listed in clock-names
-- clock-names: Should contain the following:
+- clock-names: Should contain the following:
   "core"   Master/Core clock, have to be >= 125 MHz for SS
operation and >= 60MHz for HS operation
+  "mock_utmi"  Mock utmi clock needed for ITP/SOF generation in
+   host mode. Its frequency should be 19.2MHz.
+  "sleep"  Sleep clock, used for wakeup when USB3 core goes
+   into low power mode (U3).
 
 Optional clocks:
   "iface"  System bus AXI clock.  Not present on all platforms
-  "sleep"  Sleep clock, used when USB3 core goes into low
-   power mode (U3).
+  "cfg_noc"System Config NOC clock. Not present on all platforms
+- assigned-clocks: should be:
+   MOCK_UTMI_CLK
+   MASTER_CLK
+- assigned-clock-rates: should be:
+19.2Mhz (19200) for MOCK_UTMI_CLK
+>=125Mhz (12500) for MASTER_CLK in SS mode
+>=60Mhz (6000) for MASTER_CLK in HS mode
+
+Optional properties:
+- resets:  list of phandle and reset specifier pairs
+- interrupts:  specifies interrupts from controller wrapper used
+   to wakeup from low power/susepnd state. Must contain
+   one or more entry for interrupt-names property
+- interrupt-names: Must include the following entries:
+   - "hs_phy_irq": The interrupt that is asserted when a
+  wakeup event is received on USB2 bus
+   - "ss_phy_irq": The interrupt that is asserted when a
+  wakeup event is received on USB3 bus
+   - "dm_hs_phy_irq" and "dp_hs_phy_irq": Separate
+  interrupts for any wakeup event on DM and DP lines
+- qcom,select-utmi-as-pipe-clk: if present, disable USB3 pipe_clk requirement.
+   Used when dwc3 operates without SSPHY and only
+   HS/FS/LS modes are supported.
 
 Required child node:
 A child node must exist to represent the core DWC3 IP block. The name of
 the node is not important. The content of the node is defined in dwc3.txt.
 
 Phy documentation is provided in the following places:
-Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt
+Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt   - USB3 QMP PHY
+Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt - USB2 QUSB2 PHY
 
 Example device nodes:
 
hs_phy: phy@100f8800 {
-   compatible = "qcom,dwc3-hs-usb-phy";
-   reg = <0x100f8800 0x30>;
-   clocks = < USB30_0_UTMI_CLK>;
-   clock-names = "ref";
-   #phy-cells = <0>;
-
+   compatible = "qcom,qusb2-v2-phy";
+   ...
};
 
ss_phy: phy@100f8830 {
-   compatible = "qcom,dwc3-ss-usb-phy";
-   reg = <0x100f8830 0x30>;
-   clocks = < USB30_0_MASTER_CLK>;
-   clock-names = "ref";
-   #phy-cells = <0>;
-
+   compatible = "qcom,qmp-v3-usb3-phy";
+   ...
};
 
-   usb3_0: usb30@0 {
+   usb3_0: usb30@a6f8800 {
compatible = "qcom,dwc3";
+   reg = <0xa6f8800 0x400>;
#ad

Re: [PATCH v4 6/7] dt-bindings: phy-qcom-usb2: Add support to override tuning values

2018-04-10 Thread Manu Gautam


On 4/10/2018 1:48 AM, Rob Herring wrote:
> On Thu, Mar 29, 2018 at 01:38:23PM -0700, Doug Anderson wrote:
>> Hi,
>>
>> On Thu, Mar 29, 2018 at 4:04 AM, Manu Gautam <mgau...@codeaurora.org> wrote:
>>> To improve eye diagram for PHYs on different boards of same SOC,
>>> some parameters may need to be changed. Provide device tree
>>> properties to override these from board specific device tree
>>> files. While at it, replace "qcom,qusb2-v2-phy" with compatible
>>> string for USB2 PHY on sdm845 which was earlier added for
>>> sdm845 only.
>>>
>>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>>> ---
>>>  .../devicetree/bindings/phy/qcom-qusb2-phy.txt| 19 
>>> ++-
>>>  1 file changed, 18 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
>>> b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>>> index 42c9742..0ed140a 100644
>>> --- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>>> +++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>>> @@ -6,7 +6,7 @@ QUSB2 controller supports LS/FS/HS usb connectivity on 
>>> Qualcomm chipsets.
>>>  Required properties:
>>>   - compatible: compatible list, contains
>>>"qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
>>> -  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
>>> +  "qcom,sdm845-qusb2-phy" for 10nm PHY on sdm845.
>>>
>>>   - reg: offset and length of the PHY register set.
>>>   - #phy-cells: must be 0.
>>> @@ -27,6 +27,23 @@ Optional properties:
>>> tuning parameter value for qusb2 phy.
>>>
>>>   - qcom,tcsr-syscon: Phandle to TCSR syscon register region.
>> Just to confirm: the new properties below work just fine on the old
>> msm8996 PHY too, right?
No it won't as register layouts and bit fields are different. Also IMP_CTRL
register doesnt exist for msm8996. I will mention that explicitly here.

>>
>>
>>> + - qcom,imp-res-offset-value: It is a 6 bit value that specifies offset to 
>>> be
>>> +   added to PHY refgen RESCODE via IMP_CTRL1 register. It is a 
>>> PHY
>>> +   tuning paramter that may vary for different boards of same 
>>> SOC.
>>> + - qcom,hstx-trim-value: It is a 4 bit value that specifies tuning for HSTX
>>> +   output current. 0x0 value corresponding to 24mA which is 
>>> maximum
>>> +   current and 0xf corresponds to lowest current which is 15mA.
>>> + - qcom,preemphasis-level: It is a 2 bit value that specifies pre-emphasis 
>>> level.
>>> +   Possible values are:
>>> +   00: NONE
>>> +   01: +5%
>>> +   10: +10%
>>> +   11: +15%
>> The user of the device tree will expect to specify this in decimal,
>> right?  So list the above as 0, 1, 2, 3.  ...not 00, 01, 10, 11.
Fine.
>> (though below I suggest that specifying 0, 1, 2, 3 is probably not
>> quite the right way to describe this property).
>>
>>
>>> +- qcom,preemphasis-width: It is a 1 bit value that specifies how long the 
>>> HSTX
>>> +   pre-emphasis (specified using qcom,preemphasis-level) must 
>>> be in
>>> +   effect. Possible values are:
>>> +   0: Full-bit width
>>> +   1: Half-bit width
>> Perhaps just make this a boolean property.  If it exists then you get
>> the non-default case.  AKA: if the default is full bit width, then
>> you'd allow a boolean property "qcom,preemphasis-half-width" to
>> override.  If the default is half bit width then you'd allow
>> "qcom,preemphasis-full-width" to override.

Default property value for an SOC is specified in driver and could vary from
soc to soc. Hence, from board devicetree for different SOCs we might need
to select separate widths overriding default driver values.
Alternative is to have two bool properties each for half and full-width. Did
you actually mean that?

>>
>>
>> For all the above optional bits, please indicate what the default is
>> if they aren't specified.  If you have to specify a different default
>> for sdm845 vs. msm8996 then so be it (though it would be nice to avoid
>> it by changing the default for sdm845 unless that's totally crazy).
Sure.
>>
>>
>> Overall this looks pr

Re: [PATCH v4 2/7] phy: qcom-qmp: Enable pipe_clk before PHY initialization

2018-04-10 Thread Manu Gautam
Hi,


On 3/30/2018 2:24 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Mar 29, 2018 at 11:44 AM, Doug Anderson <diand...@chromium.org> wrote:
>> Hi,
>>
>> On Thu, Mar 29, 2018 at 4:04 AM, Manu Gautam <mgau...@codeaurora.org> wrote:
>>> QMP PHY for USB/PCIE requires pipe_clk for locking of
>>> retime buffers at the pipe interface. Driver checks for
>>> PHY_STATUS without enabling pipe_clk due to which
>>> phy_init() fails with initialization timeout.
>>> Though pipe_clk is output from PHY (after PLL is programmed
>>> during initialization sequence) to GCC clock_ctl and then fed
>>> back to PHY but for PHY_STATUS register to reflect successful
>>> initialization pipe_clk from GCC must be present.
>>> Since, clock driver now ignores status_check for pipe_clk on
>>> clk_enable/disable, driver can safely enable/disable pipe_clk
>>> from phy_init/exit.
>>>
>>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>>> ---
>>>  drivers/phy/qualcomm/phy-qcom-qmp.c | 22 --
>>>  1 file changed, 8 insertions(+), 14 deletions(-)
>> Overall this looks much better than the previous version.  Thanks!  :)
>>
>> I wonder one thing though.  You describe the original problem as this:
>>
>> 1. If you don't turn the clock on in qcom_qmp_phy_init() then the PHY
>> never sets the "ready" status.
>>
>> 2. If you don't have the PHY powered on / out of reset (which happens
>> in qcom_qmp_phy_init()) then when you enable/disable the clock it
>> doesn't properly update the status.  That's why you needed patch #1 in
>> this series.
>>
>>
>> I wonder: could you solve the above _without_ needing to use
>> BRANCH_HALT_DELAY in the clock driver?  Specifically, can you tell me
>> what happens if you put the clk_prepare_enable() after you've powered
>> on the PHY and taken it out of reset but before you check the status?
>> Said another way, put the "clk_prepare_enable(qphy->pipe_clk)" call
>> right before the "readl_poll_timeout" of the ready status?
>>
>>
>> If you do that, you'll turn everything on.  Then you'll check that the
>> clock's status is OK and then that the PHY's status is OK.
> Oh!  This is what you did in the previous version of the patch, then you said:
>
> "That is still needed as PHY might take some time to generate pipe_clk
> after its PLL is locked".
>
> It's really going to take more than the 200 us that the clock driver
> is giving it?  If so, I'd prefer to increase the amount of time waited
> in the clock driver, or adding a fixed delay _before_ the clk_enable()
> so that the 200 us that the clock driver gives it would be enough.
>
> I'm just not a fan of ignoring status bits if it can be helped.

I too would want to do that but it is not just about the delay.
As per QMP PHY hardware designers, pipe_clk should be enabled in GCC
as first thing in the PHY initialization sequence. Same sequence also has
been used in downstream phy driver always.
Changing the sequence might work but I would like to stick to the HPG
recommendation and avoid any deviation as PHY issues are very hard to
debug.


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v4 1/7] clk: msm8996-gcc: change halt check for USB/PCIE pipe_clk

2018-04-10 Thread Manu Gautam
Hi,


On 4/6/2018 1:37 AM, Stephen Boyd wrote:
> Quoting Doug Anderson (2018-03-29 13:55:55)
>> Hi,
>>
>> On Thu, Mar 29, 2018 at 4:04 AM, Manu Gautam <mgau...@codeaurora.org> wrote:
>>> The USB and PCIE pipe clocks are sourced from external clocks
>>> inside the QMP USB/PCIE PHYs. Enabling or disabling of PIPE RCG
>>> clocks is dependent on PHY initialization sequence hence
>>> update halt_check to BRANCH_HALT_DELAY for these clocks so
>>> that clock status bit is not polled when enabling or disabling
>>> the clocks. It allows to simplify PHY client driver code which
>>> is both user and source of the pipe_clk and avoid error logging
>>> related status check on clk_disable/enable.
>>>
>>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>>> ---
>>>  drivers/clk/qcom/gcc-msm8996.c | 4 
>>>  1 file changed, 4 insertions(+)
>> As per my feedback on <https://patchwork.kernel.org/patch/10314937/>,
>> I'm not a fan of this.  Hopefully we can adjust the PHY driver so it's
>> not needed.
>>
> Agreed. We should be able to enable the clks at the right time and halt
> bits should work. From what I can recall we had that working before on
> db820c, so has something changed?

As replied in other patch IMO it is better to stick to the recommended
sequence and have this change as it would allow to cleanup PHY driver
and align with HPG. One reason I can think of why it works
on db820c is that there is some code in bootloader that enables
all USB clocks (including pipe_clk). Same is the case with SDM845.
And I start seeing errors if bootloader is changed or skip pipe_clk enable.



-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v4 7/7] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-04-10 Thread Manu Gautam
Hi,


On 3/30/2018 2:08 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Mar 29, 2018 at 4:04 AM, Manu Gautam <mgau...@codeaurora.org> wrote:
>> @@ -241,6 +252,18 @@ struct qusb2_phy_cfg {
>>   * @tcsr: TCSR syscon register map
>>   * @cell: nvmem cell containing phy tuning value
>>   *
>> + * @override_imp_res_offset: PHY should use different rescode offset
>> + * @imp_res_offset_value: rescode offset to be updated in IMP_CTRL1 register
>> + *
>> + * @override_hstx_trim: PHY should use different HSTX o/p current value
>> + * @hstx_trim_value: HSTX_TRIM value to be updated in TUNE1 register
>> + *
>> + * @override_preemphasis: PHY should use different pre-amphasis amplitude
>> + * @preemphasis_level: Amplitude Pre-Emphasis to be updated in TUNE1 
>> register
>> + *
>> + * @override_preemphasis_width: PHY should use different pre-emphasis 
>> duration
>> + * @preemphasis_width: half/full-width Pre-Emphasis updated via TUNE1
>> + *
> nit: spacing here doesn't match spacing in the structure.  AKA: you've
> smashed together all 8 properties in the structure but not in the
> description.
Will fix it.
>
>
>>   * @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
>> @@ -259,12 +282,35 @@ struct qusb2_phy {
>> struct regmap *tcsr;
>> struct nvmem_cell *cell;
>>
>> +   bool override_imp_res_offset;
>> +   u8 imp_res_offset_value;
>> +   bool override_hstx_trim;
>> +   u8 hstx_trim_value;
>> +   bool override_preemphasis;
>> +   u8 preemphasis_level;
>> +   bool override_preemphasis_width;
>> +   u8 preemphasis_width;
>> +
>> const struct qusb2_phy_cfg *cfg;
>> bool has_se_clk_scheme;
>> bool phy_initialized;
>> enum phy_mode mode;
>>  };
>>
>> +static inline void qusb2_write_mask(void __iomem *base, u32 offset,
>> +   u32 val, u32 mask)
>> +{
>> +   u32 reg;
>> +
>> +   reg = readl(base + offset);
>> +   reg &= ~mask;
>> +   reg |= val;
> "reg |= (val & mask)" instead of just "reg |= val"
>
> You don't do any bounds checking of the device tree entries and this
> will at least make sure that a bad value for a field won't screw up
> other fields (and so, presumably, it will be easier to find the bug).
>
It makes sense. Will change accordingly.

>
>> +   writel(reg, base + offset);
>> +
>> +   /* Ensure above write is completed */
>> +   readl(base + offset);
> You're using readl() and writel() which have barriers.  Why do you
> need this extra readl()?

This requirement comes from AHB2PHY wrapper designers and HPG.
Also existing qusb2_setbits/clrbits() wrapper already have similar handling.

>
>
>> +}
>> +
>>  static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
>>  {
>> u32 reg;
>> @@ -305,6 +351,42 @@ void qcom_qusb2_phy_configure(void __iomem *base,
>>  }
>>
>>  /*
>> + * Update board specific PHY tuning override values if specified from
>> + * device tree.
>> + *
> nit: remove extra comment line with just a "*" on it.
Sure.
>
>
>> + */
>> +static void qusb2_phy_override_phy_params(struct qusb2_phy *qphy)
>> +{
>> +   const struct qusb2_phy_cfg *cfg = qphy->cfg;
>> +
>> +   if (qphy->override_imp_res_offset)
>> +   qusb2_write_mask(qphy->base, QUSB2PHY_IMP_CTRL1,
>> +qphy->imp_res_offset_value << 
>> IMP_RES_OFFSET_SHIFT,
>> +IMP_RES_OFFSET_MASK);
>> +
>> +   if (qphy->override_hstx_trim)
>> +   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
>> +qphy->hstx_trim_value << HSTX_TRIM_SHIFT,
>> +HSTX_TRIM_MASK);
>> +
>> +   if (qphy->override_preemphasis)
>> +   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
>> +   qphy->preemphasis_level << 
>> PREEMPHASIS_EN_SHIFT,
>> +   PREEMPHASIS_EN_MASK);
>> +
>> +   if (qphy->override_preemphasis_width) {
>> +   if (qphy->preemphasis_width)
>> +   qusb2_setbits(qphy->base,
>> + cfg-&

Re: [PATCH v4 2/7] phy: qcom-qmp: Enable pipe_clk before PHY initialization

2018-04-13 Thread Manu Gautam
Hi,


On 4/13/2018 2:08 AM, Stephen Boyd wrote:
> Quoting Manu Gautam (2018-04-11 08:37:38)
>>> I ask because it may be easier to never expose these clks in Linux, hit
>>> the enable bits in the branches during clk driver probe, and then act
>>> like they never exist because we don't really use them.
>> This sounds better idea. Let me check if I can get a patch for same in 
>> msm8996
>> and sdm845 clock drivers.
>>
> Ok! Presumably the PHY has a way to tell if it failed to turn on right?
> Put another way, I'm hoping these branch bits aren't there to help us
> debug and figure out when the PHY PLL fails to lock.

Yes, PHY has a PCS_STATUS3 register that indicates whether pipe_clk got enabled 
or
not.


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845

2018-04-18 Thread Manu Gautam
Hi Amit,


On 4/18/2018 6:33 PM, Amit Nischal wrote:
>>> +   /* Disable the GPLL0 active input to MMSS and GPU via MISC 
>>> registers */
>>> +   regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3);
>>> +   regmap_update_bits(regmap, 0x71028, 0x3, 0x3);
>>
>> I think we'll have to throw in the pipe clk branch stuff in here too?
>> And then drop the pipe clks from the driver?
>
> All the USB pipe clocks would be taken care. The PCIE pipe branch
> clocks would have to be explicitly disabled so as to retain the
> memory logic. Otherwise, it would lead to memory corruption in case
> the external source is directly disabled without disabling the branch clock. 

PHY driver is same for both USB and PCIE and both PHYs use pipe_clk.
If there is indeed some limitation and pipe_clk cant be left enabled
always then I will suggest to not change pipe_clk handling for USB as well.

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2] phy: core: Allow phy_pm_runtime_xxx API calls with NULL phy

2018-04-15 Thread Manu Gautam
Hi Kishon,


On 3/20/2018 11:31 AM, Manu Gautam wrote:
> phy_init() and phy_exit() calls, and phy_power_on() and
> phy_power_off() already accept NULL as valid PHY reference
> and act as NOP. Extend same concept to phy runtime_pm APIs
> to keep drivers (e.g. dwc3) code simple while dealing with
> optional PHYs.

Wondering if you had a chance to review this.

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v4 6/7] dt-bindings: phy-qcom-usb2: Add support to override tuning values

2018-04-15 Thread Manu Gautam
Hi,


On 4/13/2018 2:17 AM, Doug Anderson wrote:
>> Thanks for review Rob. I too agree with both the viewpoints.
>> Doug, if it is not of much concern then can I stick with current approach?
> I certainly would appreciate the #defines and believe they add to the
> readability, but if you're dead set against it and Rob says it's OK, I
> won't yell too loudly.
>
Agree to the readability part. Will add #defines as you suggested.
-thanks

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 0/2] usb: dwc3: support clocks and resets for DWC3 core

2018-04-23 Thread Manu Gautam
HI,


On 4/19/2018 4:03 AM, Masahiro Yamada wrote:
> In the current design of DWC3 driver,
> the DT typically becomes a nested structure like follows:
>
>   dwc3-glue {
>   compatible = "foo,dwc3";
>   ...
>
>   dwc3 {
>   compatible = "snps,dwc3";
>   ...
>   };
>   }
>
> The current DWC3 core (drivers/usb/dwc3/core.c) can not handle
> clocks / resets at all.
>
> The only solution we have now, is to put DWC3 core node under
> the glue layer node, then add clocks and resets there.
> Actually, dwc3-of-simple.c exists to handle clocks and resets.
>
> As always for digital circuits, DWC3 core IP itself needs clock input.
> This is specific to this IP.  So, supporting clocks and resets in
> dwc3/core.c makes sense.

Why can't dwc3-of-simple be used with this IP?
Adding core/reset handling in both core and glue drivers might
only add to confusion and I cant think of a reason why having a parent
node representing dwc3-of-simple glue would be any concern.
Or are you planning to remove dwc3-of-simple.c driver?

>
> In this version, the number of clocks (and names) is specific
> to this IP, with clock names taken from Synopsys datasheet.

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 1/3] dt-bindings: usb: Update documentation for Qualcomm DWC3 driver

2018-04-16 Thread Manu Gautam
Hi Rob,


On 4/17/2018 2:08 AM, Rob Herring wrote:
> On Fri, Apr 13, 2018 at 10:21:22PM +0530, Manu Gautam wrote:
>> Existing documentation has lot of incorrect information as it
>> was originally added for a driver that no longer exists.
>>
>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>> ---
>>  .../devicetree/bindings/usb/qcom,dwc3.txt  | 78 
>> --
>>  1 file changed, 57 insertions(+), 21 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt 
>> b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> index bc8a2fa..fdc574a 100644
>> --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> @@ -1,54 +1,90 @@
>>  Qualcomm SuperSpeed DWC3 USB SoC controller
>>  
>>  Required properties:
>> -- compatible:   should contain "qcom,dwc3"
>> +- compatible:   should contain "qcom,dwc3"
> Needs an SoC specific compatible string.

Thanks for review.
Sure. Will add that.

>
>> +- reg:  offset and length of register set for QSCRATCH 
>> wrapper
>> +- power-domains:specifies a phandle to PM domain provider node
>>  - clocks:   A list of phandle + clock-specifier pairs for the
>>  clocks listed in clock-names
>> -- clock-names:  Should contain the following:
>> +- clock-names:  Should contain the following:
>>"core"Master/Core clock, have to be >= 125 MHz for SS
>>  operation and >= 60MHz for HS operation
>> +  "mock_utmi"   Mock utmi clock needed for ITP/SOF generation in
>> +host mode. Its frequency should be 19.2MHz.
>> +  "sleep"   Sleep clock, used for wakeup when USB3 core goes
>> +into low power mode (U3).
>>  
>>  Optional clocks:
>>"iface"   System bus AXI clock.  Not present on all platforms
>> -  "sleep"   Sleep clock, used when USB3 core goes into low
>> -power mode (U3).
>> +  "cfg_noc" System Config NOC clock. Not present on all platforms
> These need to be specific as to which compatible properties have or 
> don't have these clocks.
ok

>
>> +- assigned-clocks:  should be:
>> +MOCK_UTMI_CLK
>> +MASTER_CLK
>> +- assigned-clock-rates: should be:
>> +19.2Mhz (19200) for MOCK_UTMI_CLK
>> +>=125Mhz (12500) for MASTER_CLK in SS 
>> mode
>> +>=60Mhz (6000) for MASTER_CLK in HS mode
>> +
>> +Optional properties:
>> +- resets:   list of phandle and reset specifier pairs
> How many?
I will provide exact detail for each compatible property.
>
>> +- interrupts:   specifies interrupts from controller wrapper 
>> used
>> +to wakeup from low power/susepnd state. Must contain
>> +one or more entry for interrupt-names property
>> +- interrupt-names:  Must include the following entries:
>> +- "hs_phy_irq": The interrupt that is asserted when a
>> +   wakeup event is received on USB2 bus
>> +- "ss_phy_irq": The interrupt that is asserted when a
>> +   wakeup event is received on USB3 bus
>> +- "dm_hs_phy_irq" and "dp_hs_phy_irq": Separate
>> +   interrupts for any wakeup event on DM and DP lines
> Sounds like the irqs are actually part of the PHYs? If so, then that's 
> where they should be in the DT.
No. These are actually part of controller wrapper called - qscratch which
has connectivity to phy outputs signals. Also, these are abstracted from PHY
and are present irrespective of type of phy present. I will add soc specific
info also in comments specifying which interrupts are not present on particular
soc/compatible.

>
>> +- qcom,select-utmi-as-pipe-clk: if present, disable USB3 pipe_clk 
>> requirement.
>> +Used when dwc3 operates without SSPHY and only
>> +HS/FS/LS modes are supported.
>>  
>>  Required child node:
>>  A child node must exist to represent the core DWC3 IP block. The name of
>>  the node is not important. The content of the node is

Re: [PATCH v3 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-27 Thread Manu Gautam
Hi,


On 3/27/2018 12:26 PM, Vivek Gautam wrote:
>
>
> On 3/27/2018 10:37 AM, Manu Gautam wrote:
>> Hi Doug,
>>
>>
>> On 3/27/2018 9:56 AM, Doug Anderson wrote:
>>> Manu
>>>
>>> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam <mgau...@codeaurora.org> 
>>> wrote:
>>>> QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
>>>> to take place. This clock is output from PHY to GCC clock_ctl and then
>>>> fed back to QMP PHY and is available from PHY only after PHY is reset
>>>> and initialized, hence it can't be enabled too early in initialization
>>>> sequence.
>>>>
>>>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>>>> ---
>>>>   drivers/phy/qualcomm/phy-qcom-qmp.c | 33 
>>>> -
>>>>   1 file changed, 32 insertions(+), 1 deletion(-)
>>> So it's now new with this patch, but it's more obvious with this
>>> patch.  It seems like "UFS/PCIE" is kinda broken w/ respect to how it
>>> controls its clock.  Specifically:
>>>
>>> * If you init the PHY but don't power it on, then you "exit" the PHY:
>>> you'll disable/unprepare "pipe_clk" even though you never
>>> prepare/enabled it.
>>>
>>> * If you init the PHY, power it on, power it off, power it on, and
>>> exit the PHY: you'll leave the clock prepared one extra time.
>>>
>>> Specifically I'd expect: for UFS/PCIE the disable/unprepare should be
>>> symmetric with the enable/prepare and should be in "power off", not in
>>> exit.
>>>
>>> ...or did I miss something?
>>>
>>>
>>> Interestingly, your patch fixes this problem for USB3 (where init/exit
>>> are now symmetric), but leaves the problem there for UFS/PCIE.
>>>
>> Thanks for review.
>> One of the reason why pipe_clk is disabled as part of phy_exit is that
>> halt_check from clk_disable reports error if called after PHY has been
>> powered down or phy_exit.
>> I believe that warning should be ignored in qcom gcc-clock driver
>> (for applicable platforms) by using BRANCH_HALT_DELAY as halt_check
>> for pipe_clk and performing clk_disable from power_off for UFS/PCIE.
> UFS doesn't use PIPE clock.

Yes, UFS PHY doesn't use one. But similar to pipe_clk there are rx/tx symbol_clk
output from PHY that is used by UFS controller. I will update code comments
to not refer UFS for pipe_clk.

> But considering for PCIe, if we disable pipe clock when phy is still running, 
> then
> it shouldn't be a problem. We should also not see the halt warning as the gcc
> driver should be able to just turn the gate off.
> The reason why it will throw that error is when the parent clock to that gate
> is gated, i.e. the pipe clock is not flowing on that branch.

I got the confirmation that pipe_clk is needed for PCIE as well for its
initialization to happen successfully. So we do need clock driver change
to fix this in PHY driver.

>
> Best regards
> Vivek
>
>>
>> I can implement that as separate patch once dependent gcc driver
>> patch(es) gets in. Would that be ok?
>>
>> -Manu
>>
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-27 Thread Manu Gautam
Hi Vivek,


On 3/27/2018 12:21 PM, Vivek Gautam wrote:
> Hi Manu,
>
>
> On 3/23/2018 11:41 AM, Manu Gautam wrote:
>> QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
>> to take place.
>
> AFAIK, that's not true. The pipe clock is the *output* of the PLL, and it's 
> should not
> be needed for PLL calibration and locking. The PLL locking happens when the 
> phy is
> configured and powered on.
> Atleast that's what the PIPE spec also says.
>
>    CLK
>  |
>  |
>  Y
>    
>   |  PLL    |> PCLK (this is pipe clock 125/250/... MHz 
> corresponding to the data width)
>    
>
> That's the reason we were enabling it after the PLL was locked.

I got this clarified by QMP PHY hardware designer that pipe_clk is indeed
needed for PHY to complete init sequence and reflect in PHY_STATUS (mainly
for calibration and I should remove PLL lock from commit subject).
It might work on some platforms without this change if boot code
leaves pipe clock enabled during bootup.


>
>> This clock is output from PHY to GCC clock_ctl and then
>> fed back to QMP PHY and is available from PHY only after PHY is reset
>> and initialized, hence it can't be enabled too early in initialization
>> sequence.
>>
>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-qmp.c | 33 -
>>   1 file changed, 32 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
>> b/drivers/phy/qualcomm/phy-qcom-qmp.c
>> index 6470c5d..5d8df6a 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
>> @@ -1008,6 +1008,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
>>   status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
>>   mask = cfg->mask_pcs_ready;
>>   +    /*
>> + * USB3 PHY requires pipe_clk for PLL lock and calibration.
>> + * Enable it from here for USB. For UFS/PCIE, it gets enabled
>> + * from poweron.
>> + */
>> +    if (cfg->type == PHY_TYPE_USB3) {
>> +    ret = clk_prepare_enable(qphy->pipe_clk);
>
> As mentioned before AFAIU, pipe clock is just an output coming out of the 
> PHY's PLL
> and we shouldn't try to enable pipe clock before PHY even gets initialized.
> We should may just try to first fix the unbalanced pipe clock enable/disable 
> problem.
>
> Moreover, lets take care of all USB, PCIe and DP phys when we want to 
> enable/disbale
> pipe clock as all of them use this clock.

I will get the pipe_clk requirement for PCIE as well and do it for both
(depending on gcc change).

>
> Best regards
> Vivek
>
>> +    if (ret) {
>> +    dev_err(qmp->dev, "pipe_clk enable err=%d\n", ret);
>> +    goto err_clk_enable;
>> +    }
>> +    }
>> +
>>   ret = readl_poll_timeout(status, val, !(val & mask), 1,
>>    PHY_INIT_COMPLETE_TIMEOUT);
>>   if (ret) {
>> @@ -1019,6 +1032,9 @@ static int qcom_qmp_phy_init(struct phy *phy)
>>   return ret;
>>     err_pcs_ready:
>> +    if (cfg->type == PHY_TYPE_USB3)
>> +    clk_disable_unprepare(qphy->pipe_clk);
>> +err_clk_enable:
>>   if (cfg->has_lane_rst)
>>   reset_control_assert(qphy->lane_rst);
>>   err_lane_rst:
>> @@ -1288,10 +1304,19 @@ static int phy_pipe_clk_register(struct qcom_qmp 
>> *qmp, struct device_node *np)
>>   .owner    = THIS_MODULE,
>>   };
>>   +/* USB PHY doesn't require power_on op */
>> +static const struct phy_ops qcom_qmp_usb_phy_gen_ops = {
>> +    .init    = qcom_qmp_phy_init,
>> +    .exit    = qcom_qmp_phy_exit,
>> +    .set_mode    = qcom_qmp_phy_set_mode,
>> +    .owner    = THIS_MODULE,
>> +};
>> +
>>   static
>>   int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
>>   {
>>   struct qcom_qmp *qmp = dev_get_drvdata(dev);
>> +    const struct phy_ops *ops;
>>   struct phy *generic_phy;
>>   struct qmp_phy *qphy;
>>   char prop_name[MAX_PROP_NAME];
>> @@ -1354,7 +1379,13 @@ int qcom_qmp_phy_create(struct device *dev, struct 
>> device_node *np, int id)
>>   }
>>   }
>>   -    generic_phy = devm_phy_create(dev, np, _qmp_phy_gen_ops);
>> +    /* USB PHY doesn't use power_on op */
>> +    if (qmp->cfg->type == PHY_TYPE_USB3)
>> +    ops = _qmp_usb_phy_gen_ops;
>> +    else
>> +    ops = _qmp_phy_gen_ops;
>> +
>> +    generic_phy = devm_phy_create(dev, np, ops);
>>   if (IS_ERR(generic_phy)) {
>>   ret = PTR_ERR(generic_phy);
>>   dev_err(dev, "failed to create qphy %d\n", ret);
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-26 Thread Manu Gautam
Hi Doug,


On 3/27/2018 9:56 AM, Doug Anderson wrote:
> Manu
>
> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam <mgau...@codeaurora.org> wrote:
>> QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
>> to take place. This clock is output from PHY to GCC clock_ctl and then
>> fed back to QMP PHY and is available from PHY only after PHY is reset
>> and initialized, hence it can't be enabled too early in initialization
>> sequence.
>>
>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp.c | 33 -
>>  1 file changed, 32 insertions(+), 1 deletion(-)
> So it's now new with this patch, but it's more obvious with this
> patch.  It seems like "UFS/PCIE" is kinda broken w/ respect to how it
> controls its clock.  Specifically:
>
> * If you init the PHY but don't power it on, then you "exit" the PHY:
> you'll disable/unprepare "pipe_clk" even though you never
> prepare/enabled it.
>
> * If you init the PHY, power it on, power it off, power it on, and
> exit the PHY: you'll leave the clock prepared one extra time.
>
> Specifically I'd expect: for UFS/PCIE the disable/unprepare should be
> symmetric with the enable/prepare and should be in "power off", not in
> exit.
>
> ...or did I miss something?
>
>
> Interestingly, your patch fixes this problem for USB3 (where init/exit
> are now symmetric), but leaves the problem there for UFS/PCIE.
>

Thanks for review.
One of the reason why pipe_clk is disabled as part of phy_exit is that
halt_check from clk_disable reports error if called after PHY has been
powered down or phy_exit.
I believe that warning should be ignored in qcom gcc-clock driver
(for applicable platforms) by using BRANCH_HALT_DELAY as halt_check
for pipe_clk and performing clk_disable from power_off for UFS/PCIE.

I can implement that as separate patch once dependent gcc driver
patch(es) gets in. Would that be ok?

-Manu

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-28 Thread Manu Gautam
Hi,


On 3/28/2018 3:27 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam <mgau...@codeaurora.org> wrote:
>> Update compatible strings for USB2 PHYs on sdm845.
>> There are two QUSB2 PHYs present on sdm845. Few PHY registers
>> programming is different for these PHYs related to electrical
>> parameters, otherwise both are same.
>>
>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>> ---
>>  Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
>> b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> index 42c9742..b99a57f 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> +++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> @@ -6,7 +6,9 @@ QUSB2 controller supports LS/FS/HS usb connectivity on 
>> Qualcomm chipsets.
>>  Required properties:
>>   - compatible: compatible list, contains
>>"qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
>> -  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
>> +  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY,
>> +  "qcom,sdm845-qusb2-phy-1" for primary PHY on sdm845,
>> +  "qcom,sdm845-qusb2-phy-2" for secondary PHY on sdm845.
> Similar question to the one I posed on
> <https://patchwork.kernel.org/patch/10302761/> for the QMP PHY.  What
> is "qcom,qusb2-v2-phy"?  Is it some ideal abstract version of the PHY?
>  Do we expect that anyone would actually use that compatible string?
>
> In this case in <https://patchwork.kernel.org/patch/10302755/> it
> looks as if you're using the same settings as
> "qcom,sdm845-qusb2-phy-2", so presumably "qcom,qusb2-v2-phy" should
> just be deleted.
>

I will remove "qcom,qusb2-v2-phy".


> -Doug

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 3/6] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-03-28 Thread Manu Gautam
Hi,


On 3/28/2018 3:07 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam <mgau...@codeaurora.org> wrote:
>> Update compatible strings for USB3 PHYs on SDM845.
>> One is QMPv3 DisplayPort-USB combo PHY and other one
>> is USB UNI PHY which is single lane USB3 PHY without
>> DP capability.
>>
>> Reviewed-by: Rob Herring <r...@kernel.org>
>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>> ---
>>  Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
>> b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
>> index dcf1b8f..cef8765 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
>> +++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
>> @@ -9,7 +9,9 @@ Required properties:
>>"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,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
>> +  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy,
>> +  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
>> +  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on 
>> sdm845.
> I'm confused.  What value does "qcom,qmp-v3-usb3-phy" have as a
> separate entry from "qcom,sdm845-qmp-usb3-phy"?  Is
> "qcom,qmp-v3-usb3-phy" expected to work on some non-SDM845 based
> device?
>
> Personally I think you should remove "qcom,qmp-v3-usb3-phy" from the
> bindings as part of this patch (replacing it with the new string
> qcom,sdm845-qmp-usb3-phy)".  Yeah, yeah bindings are forever.  ...but
> that particular string was added about a month ago and (I believe) it
> was intended for SDM845 anyway.  As per
> <https://patchwork.kernel.org/patch/10302759/> match to the exact same
> PHY data which leads extra credence to my belief.
>
> If later on you find that some future chip can use the exact same
> driver / settings as the SDM845 you can always list the
> "qcom,sdm845-qmp-usb3-phy" string as a secondary compatible anyway.
>

I agree. Will just remove "qcom,sdm845-qmp-usb3-phy"

> -Doug

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 6/6] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-03-28 Thread Manu Gautam
Hi,


On 3/28/2018 4:22 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam <mgau...@codeaurora.org> wrote:
>> There are two QUSB2 PHYs present on sdm845. Update PHY
>> registers programming for both the PHYs related to
>> electrical parameters to improve eye diagram.
> This tuning difference is truly associated with the SoC itself?  Are
> you sure?  Are the two different PHYs in the SoC somehow using
> different silicon processes?  ...or is one close to another IP block
> that is noisy?  ...or something else to account for this difference?
>
> It seems more likely that this tuning difference is associated with
> the board.  If you're _certain_ this is really due to internal SoC
> differences you'll have to come up with some darn good evidence to
> convince me...

This difference must be due to board only.

>
> If the tuning is truly associated with the board then:
>
> 1. You should have a single device tree compatible string.  IMHO it
> should contain the name of the SoC in it, so "qcom,sdm845-qusb2-phy".
> It's generally OK to name something in Linux using the name of the
> first thing that happened to support it in Linux (even if later
> processors use the exact same component).  Leaving it as just
> "qcom,qusb2-v2-phy" is OK with me too if that's what everyone wants.
I will remove "qcom,qusb2-v2-phy" as I don't expect any users of that.
>
>
> 2. You should figure out how to describe the needed board-to-board
> tuning in device tree.
>
> The only two differences you have right now are:
>
> QUSB2PHY_IMP_CTRL1: 0 => 0x8
> QUSB2PHY_PORT_TUNE1: 0x30 => 0x48
>
> I'm not sure I found all the correct documentation for the PHY (the
> docs I have say that "TUNE1" bit 3 is "reserved") so I can't come up
> with all of these for you.  But I think I found the difference
> accounting for the upper nybble of TUNE1 changing from 0x3 to 0x4.
> For this, I think you'd want a device tree property like:
>
> qcom,hstx_trim_mv
>
> ...and the values of that property would be the values from 800 to 950
> in 8 steps, or [800, 821, 842, 864, 885, 907, 928, 950].
>
> You'd want to do similar things for the other differences.
>
> You don't need to encode every possible difference right now.  When
> you come up with something that needs to be different you add a new
> optional device tree property (defaulting to whatever the driver used
> to do) to describe your new property.

Sure. I will come up with separate device tree properties to specify
board-to-board differences in PHY tuning.


>
> -Doug

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-28 Thread Manu Gautam
Hi,


On 3/28/2018 1:44 AM, Doug Anderson wrote:
> Hi,
>
> On Tue, Mar 27, 2018 at 12:50 AM, Manu Gautam <mgau...@codeaurora.org> wrote:
>> Hi,
>>
>>
>> On 3/27/2018 12:26 PM, Vivek Gautam wrote:
>>>
>>> On 3/27/2018 10:37 AM, Manu Gautam wrote:
>>>> Hi Doug,
>>>>
>>>>
>>>> On 3/27/2018 9:56 AM, Doug Anderson wrote:
>>>>> Manu
>>>>>
>>>>> On Thu, Mar 22, 2018 at 11:11 PM, Manu Gautam <mgau...@codeaurora.org> 
>>>>> wrote:
>>>>>> QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
>>>>>> to take place. This clock is output from PHY to GCC clock_ctl and then
>>>>>> fed back to QMP PHY and is available from PHY only after PHY is reset
>>>>>> and initialized, hence it can't be enabled too early in initialization
>>>>>> sequence.
>>>>>>
>>>>>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>>>>>> ---
>>>>>>   drivers/phy/qualcomm/phy-qcom-qmp.c | 33 
>>>>>> -
>>>>>>   1 file changed, 32 insertions(+), 1 deletion(-)
>>>>> So it's now new with this patch, but it's more obvious with this
>>>>> patch.  It seems like "UFS/PCIE" is kinda broken w/ respect to how it
>>>>> controls its clock.  Specifically:
>>>>>
>>>>> * If you init the PHY but don't power it on, then you "exit" the PHY:
>>>>> you'll disable/unprepare "pipe_clk" even though you never
>>>>> prepare/enabled it.
>>>>>
>>>>> * If you init the PHY, power it on, power it off, power it on, and
>>>>> exit the PHY: you'll leave the clock prepared one extra time.
>>>>>
>>>>> Specifically I'd expect: for UFS/PCIE the disable/unprepare should be
>>>>> symmetric with the enable/prepare and should be in "power off", not in
>>>>> exit.
>>>>>
>>>>> ...or did I miss something?
>>>>>
>>>>>
>>>>> Interestingly, your patch fixes this problem for USB3 (where init/exit
>>>>> are now symmetric), but leaves the problem there for UFS/PCIE.
>>>>>
>>>> Thanks for review.
>>>> One of the reason why pipe_clk is disabled as part of phy_exit is that
>>>> halt_check from clk_disable reports error if called after PHY has been
>>>> powered down or phy_exit.
>>>> I believe that warning should be ignored in qcom gcc-clock driver
>>>> (for applicable platforms) by using BRANCH_HALT_DELAY as halt_check
>>>> for pipe_clk and performing clk_disable from power_off for UFS/PCIE.
>>> UFS doesn't use PIPE clock.
> Just to confirm: we no longer need to do this "BRANCH_HALT_DELAY" now
> that we've figured everything out, right?

That is still needed as PHY might take some time to generate pipe_clk
after its PLL is locked (or while initialization sequence is carried out).
Performing clk_enable will throw a warning. Hence, it is better to
have halt_check that will allow to club pipe_clk with other clocks and
enable it at the beginning of phy_init.

>
>
>> Yes, UFS PHY doesn't use one. But similar to pipe_clk there are rx/tx 
>> symbol_clk
>> output from PHY that is used by UFS controller. I will update code comments
>> to not refer UFS for pipe_clk.
>>
>>> But considering for PCIe, if we disable pipe clock when phy is still 
>>> running, then
>>> it shouldn't be a problem. We should also not see the halt warning as the 
>>> gcc
>>> driver should be able to just turn the gate off.
>>> The reason why it will throw that error is when the parent clock to that 
>>> gate
>>> is gated, i.e. the pipe clock is not flowing on that branch.
>> I got the confirmation that pipe_clk is needed for PCIE as well for its
>> initialization to happen successfully. So we do need clock driver change
>> to fix this in PHY driver.
> So basically if I'm understanding this correctly:
>
> * Both USB and PCIE need the clk_enable() in qcom_qmp_phy_init()
>
> * UFS doesn't even use a pipe clock (pipe_clk is NULL and thus these
> calls are no-ops).
>
> So that means the next version of this code will simply get rid of
> qcom_qmp_phy_poweron() and we can now use the same phy_ops for both
> everything again?  That also makes everything symmetric and gets rid
> of the possible imbalance of clock 

[PATCH v4 0/7] phy: qcom: Updates for USB PHYs on SDM845

2018-03-29 Thread Manu Gautam
SDM845 has two USB instances each with QUSB2 and QMP PHYs.
One of the QMP PHY is USB-DP (DisplayPort) combo PHY where
as other one is single lane UNI-PHY (without DP support).
Changes are related to PHY configuration for electrical
parameters tuning to improve eye-diagram and some fixes.

Changes since v3:
 - As per Doug's review comments added device tree parameters
   to handle board level differences in PHY tuning values instead
   of adding separate device tree bindings.
 - Replace PHY version specific bindings names with SOC name as
   no one is going to use generic binding names.
 - Update halt_check to not check for pipe clock status that
   allows to simplify pipe_clk handling in QMP driver.

Changes since v2:
 - Use separate phy_ops for USB to not register power_on op.
 - And other minor changes as per review comments from Stephen.

Changes since v1:
 - Updated qusb2 compatibility name as per comment from Vivek.

Manu Gautam (7):
  clk: msm8996-gcc: change halt check for USB/PCIE pipe_clk
  phy: qcom-qmp: Enable pipe_clk before PHY initialization
  phy: qcom-qusb2: Fix crash if nvmem cell not specified
  dt-bindings: phy-qcom-qmp: Update bindings for sdm845
  phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845
  dt-bindings: phy-qcom-usb2: Add support to override tuning values
  phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

 .../devicetree/bindings/phy/qcom-qmp-phy.txt   |   3 +-
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt |  19 ++-
 drivers/clk/qcom/gcc-msm8996.c |   4 +
 drivers/phy/qualcomm/phy-qcom-qmp.c| 169 +++--
 drivers/phy/qualcomm/phy-qcom-qmp.h|   5 +
 drivers/phy/qualcomm/phy-qcom-qusb2.c  | 116 +-
 6 files changed, 298 insertions(+), 18 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 2/7] phy: qcom-qmp: Enable pipe_clk before PHY initialization

2018-03-29 Thread Manu Gautam
QMP PHY for USB/PCIE requires pipe_clk for locking of
retime buffers at the pipe interface. Driver checks for
PHY_STATUS without enabling pipe_clk due to which
phy_init() fails with initialization timeout.
Though pipe_clk is output from PHY (after PLL is programmed
during initialization sequence) to GCC clock_ctl and then fed
back to PHY but for PHY_STATUS register to reflect successful
initialization pipe_clk from GCC must be present.
Since, clock driver now ignores status_check for pipe_clk on
clk_enable/disable, driver can safely enable/disable pipe_clk
from phy_init/exit.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 22 --
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 6470c5d..fddb1c9 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -793,19 +793,6 @@ static void qcom_qmp_phy_configure(void __iomem *base,
}
 }
 
-static int qcom_qmp_phy_poweron(struct phy *phy)
-{
-   struct qmp_phy *qphy = phy_get_drvdata(phy);
-   struct qcom_qmp *qmp = qphy->qmp;
-   int ret;
-
-   ret = clk_prepare_enable(qphy->pipe_clk);
-   if (ret)
-   dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
-
-   return ret;
-}
-
 static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 {
const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -974,6 +961,12 @@ static int qcom_qmp_phy_init(struct phy *phy)
}
}
 
+   ret = clk_prepare_enable(qphy->pipe_clk);
+   if (ret) {
+   dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
+   goto err_clk_enable;
+   }
+
/* 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 */
@@ -1019,6 +1012,8 @@ static int qcom_qmp_phy_init(struct phy *phy)
return ret;
 
 err_pcs_ready:
+   clk_disable_unprepare(qphy->pipe_clk);
+err_clk_enable:
if (cfg->has_lane_rst)
reset_control_assert(qphy->lane_rst);
 err_lane_rst:
@@ -1283,7 +1278,6 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, 
struct device_node *np)
 static const struct phy_ops qcom_qmp_phy_gen_ops = {
.init   = qcom_qmp_phy_init,
.exit   = qcom_qmp_phy_exit,
-   .power_on   = qcom_qmp_phy_poweron,
.set_mode   = qcom_qmp_phy_set_mode,
.owner  = THIS_MODULE,
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 5/7] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-03-29 Thread Manu Gautam
QMP V3 UNI PHY is a single lane USB3 PHY without support
for DisplayPort (DP).
Main difference from DP combo QMPv3 PHY is that UNI PHY
doesn't have dual RX/TX lanes and no separate DP_COM
block for configuration related to type-c or DP.
Also remove "qcom,qmp-v3-usb3-phy" compatible string which
was earlier added for sdm845 only as there wouldn't be
any user of same.
While at it, fix has_pwrdn_delay attribute for USB-DP
PHY configuration and.

Reviewed-by: Evan Green <evgr...@chromium.org>
Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 147 +++-
 drivers/phy/qualcomm/phy-qcom-qmp.h |   5 ++
 2 files changed, 151 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index fddb1c9..4c47010 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -490,6 +490,118 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
 };
 
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+   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, 0x06),
+   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_uniphy_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, 0xc6),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+   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, 0x1c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_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),
+ 

[PATCH v4 1/7] clk: msm8996-gcc: change halt check for USB/PCIE pipe_clk

2018-03-29 Thread Manu Gautam
The USB and PCIE pipe clocks are sourced from external clocks
inside the QMP USB/PCIE PHYs. Enabling or disabling of PIPE RCG
clocks is dependent on PHY initialization sequence hence
update halt_check to BRANCH_HALT_DELAY for these clocks so
that clock status bit is not polled when enabling or disabling
the clocks. It allows to simplify PHY client driver code which
is both user and source of the pipe_clk and avoid error logging
related status check on clk_disable/enable.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/clk/qcom/gcc-msm8996.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index 5d74512..336d12d 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -1418,6 +1418,7 @@ enum {
 
 static struct clk_branch gcc_usb3_phy_pipe_clk = {
.halt_reg = 0x50004,
+   .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x50004,
.enable_mask = BIT(0),
@@ -2472,6 +2473,7 @@ enum {
 
 static struct clk_branch gcc_pcie_0_pipe_clk = {
.halt_reg = 0x6b018,
+   .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x6b018,
.enable_mask = BIT(0),
@@ -2547,6 +2549,7 @@ enum {
 
 static struct clk_branch gcc_pcie_1_pipe_clk = {
.halt_reg = 0x6d018,
+   .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x6d018,
.enable_mask = BIT(0),
@@ -2622,6 +2625,7 @@ enum {
 
 static struct clk_branch gcc_pcie_2_pipe_clk = {
.halt_reg = 0x6e018,
+   .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x6e018,
.enable_mask = BIT(0),
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 7/7] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-03-29 Thread Manu Gautam
There are two QUSB2 PHYs present on sdm845. In order
to improve eye diagram for both the PHYs some parameters
need to be changed. Provide device tree properties to
override these from board specific device tree files.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 112 +-
 1 file changed, 111 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 40fdef8..adcc3f8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -60,6 +60,17 @@
 #define CORE_RESET BIT(5)
 #define CORE_RESET_MUX BIT(6)
 
+/* QUSB2PHY_IMP_CTRL1 register bits */
+#define IMP_RES_OFFSET_MASKGENMASK(5, 0)
+#define IMP_RES_OFFSET_SHIFT   0x0
+
+/* QUSB2PHY_PORT_TUNE1 register bits */
+#define HSTX_TRIM_MASK GENMASK(7, 4)
+#define HSTX_TRIM_SHIFT0x4
+#define PREEMPH_HALF_WIDTH BIT(2)
+#define PREEMPHASIS_EN_MASKGENMASK(1, 0)
+#define PREEMPHASIS_EN_SHIFT   0x0
+
 #define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO   0x04
 #define QUSB2PHY_PLL_CLOCK_INVERTERS   0x18c
 #define QUSB2PHY_PLL_CMODE 0x2c
@@ -241,6 +252,18 @@ struct qusb2_phy_cfg {
  * @tcsr: TCSR syscon register map
  * @cell: nvmem cell containing phy tuning value
  *
+ * @override_imp_res_offset: PHY should use different rescode offset
+ * @imp_res_offset_value: rescode offset to be updated in IMP_CTRL1 register
+ *
+ * @override_hstx_trim: PHY should use different HSTX o/p current value
+ * @hstx_trim_value: HSTX_TRIM value to be updated in TUNE1 register
+ *
+ * @override_preemphasis: PHY should use different pre-amphasis amplitude
+ * @preemphasis_level: Amplitude Pre-Emphasis to be updated in TUNE1 register
+ *
+ * @override_preemphasis_width: PHY should use different pre-emphasis duration
+ * @preemphasis_width: half/full-width Pre-Emphasis updated via TUNE1
+ *
  * @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
@@ -259,12 +282,35 @@ struct qusb2_phy {
struct regmap *tcsr;
struct nvmem_cell *cell;
 
+   bool override_imp_res_offset;
+   u8 imp_res_offset_value;
+   bool override_hstx_trim;
+   u8 hstx_trim_value;
+   bool override_preemphasis;
+   u8 preemphasis_level;
+   bool override_preemphasis_width;
+   u8 preemphasis_width;
+
const struct qusb2_phy_cfg *cfg;
bool has_se_clk_scheme;
bool phy_initialized;
enum phy_mode mode;
 };
 
+static inline void qusb2_write_mask(void __iomem *base, u32 offset,
+   u32 val, u32 mask)
+{
+   u32 reg;
+
+   reg = readl(base + offset);
+   reg &= ~mask;
+   reg |= val;
+   writel(reg, base + offset);
+
+   /* Ensure above write is completed */
+   readl(base + offset);
+}
+
 static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
 {
u32 reg;
@@ -305,6 +351,42 @@ void qcom_qusb2_phy_configure(void __iomem *base,
 }
 
 /*
+ * Update board specific PHY tuning override values if specified from
+ * device tree.
+ *
+ */
+static void qusb2_phy_override_phy_params(struct qusb2_phy *qphy)
+{
+   const struct qusb2_phy_cfg *cfg = qphy->cfg;
+
+   if (qphy->override_imp_res_offset)
+   qusb2_write_mask(qphy->base, QUSB2PHY_IMP_CTRL1,
+qphy->imp_res_offset_value << IMP_RES_OFFSET_SHIFT,
+IMP_RES_OFFSET_MASK);
+
+   if (qphy->override_hstx_trim)
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
+qphy->hstx_trim_value << HSTX_TRIM_SHIFT,
+HSTX_TRIM_MASK);
+
+   if (qphy->override_preemphasis)
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
+   qphy->preemphasis_level << PREEMPHASIS_EN_SHIFT,
+   PREEMPHASIS_EN_MASK);
+
+   if (qphy->override_preemphasis_width) {
+   if (qphy->preemphasis_width)
+   qusb2_setbits(qphy->base,
+ cfg->regs[QUSB2PHY_PORT_TUNE1],
+ PREEMPH_HALF_WIDTH);
+   else
+   qusb2_clrbits(qphy->base,
+ cfg->regs[QUSB2PHY_PORT_TUNE1],
+ PREEMPH_HALF_WIDTH);
+   }
+}
+
+/*
  * Fetches HS Tx tuning value from nvmem and sets the
  * QUSB2PHY_PORT_TUNE1/2 register.
  * For error case, skip setting the val

[PATCH v4 3/7] phy: qcom-qusb2: Fix crash if nvmem cell not specified

2018-03-29 Thread Manu Gautam
Driver currently crashes due to NULL pointer deference
while updating PHY tune register if nvmem cell is NULL.
Since, fused value for Tune1/2 register is optional,
we'd rather bail out.

Fixes: ca04d9d3e1b1 ("phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips")
Reviewed-by: Vivek Gautam <vivek.gau...@codeaurora.org>
Reviewed-by: Evan Green <evgr...@chromium.org>
Cc: stable <sta...@vger.kernel.org> # 4.14+
Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 94afeac..40fdef8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -315,6 +315,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
const struct qusb2_phy_cfg *cfg = qphy->cfg;
u8 *val;
 
+   /* efuse register is optional */
+   if (!qphy->cell)
+   return;
+
/*
 * Read efuse register having TUNE2/1 parameter's high nibble.
 * If efuse register shows value as 0x0, or if we fail to find
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 4/7] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-03-29 Thread Manu Gautam
Update compatible strings for USB3 PHYs on SDM845.
One is QMPv3 DisplayPort-USB combo PHY and other one
is USB UNI PHY which is single lane USB3 PHY without
DP capability. While at it also remove "qcom,qmp-v3-usb3-phy"
compatible string which was earlier added for sdm845
only as there wouldn't be any user of same.

Reviewed-by: Rob Herring <r...@kernel.org>
Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index dcf1b8f..266a1bb 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -9,7 +9,8 @@ Required properties:
   "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,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
+  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
+  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845.
 
  - reg: offset and length of register set for PHY's common serdes block.
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 6/7] dt-bindings: phy-qcom-usb2: Add support to override tuning values

2018-03-29 Thread Manu Gautam
To improve eye diagram for PHYs on different boards of same SOC,
some parameters may need to be changed. Provide device tree
properties to override these from board specific device tree
files. While at it, replace "qcom,qusb2-v2-phy" with compatible
string for USB2 PHY on sdm845 which was earlier added for
sdm845 only.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt| 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index 42c9742..0ed140a 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -6,7 +6,7 @@ QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm 
chipsets.
 Required properties:
  - compatible: compatible list, contains
   "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
-  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+  "qcom,sdm845-qusb2-phy" for 10nm PHY on sdm845.
 
  - reg: offset and length of the PHY register set.
  - #phy-cells: must be 0.
@@ -27,6 +27,23 @@ Optional properties:
tuning parameter value for qusb2 phy.
 
  - qcom,tcsr-syscon: Phandle to TCSR syscon register region.
+ - qcom,imp-res-offset-value: It is a 6 bit value that specifies offset to be
+   added to PHY refgen RESCODE via IMP_CTRL1 register. It is a PHY
+   tuning paramter that may vary for different boards of same SOC.
+ - qcom,hstx-trim-value: It is a 4 bit value that specifies tuning for HSTX
+   output current. 0x0 value corresponding to 24mA which is maximum
+   current and 0xf corresponds to lowest current which is 15mA.
+ - qcom,preemphasis-level: It is a 2 bit value that specifies pre-emphasis 
level.
+   Possible values are:
+   00: NONE
+   01: +5%
+   10: +10%
+   11: +15%
+- qcom,preemphasis-width: It is a 1 bit value that specifies how long the HSTX
+   pre-emphasis (specified using qcom,preemphasis-level) must be in
+   effect. Possible values are:
+   0: Full-bit width
+   1: Half-bit width
 
 Example:
hsusb_phy: phy@7411000 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH 4/6] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-03-20 Thread Manu Gautam
Hi,


On 3/19/2018 11:21 PM, Evan Green wrote:
> Hi Manu,
>
> On Fri, Mar 16, 2018 at 2:46 AM Manu Gautam <mgau...@codeaurora.org> wrote:
[snip]
>> index d1c6905..5d78d43 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp.h
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
>> @@ -214,6 +214,8 @@
>>   #define QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN0x030
>>   #define QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE0x034
>>   #define QSERDES_V3_RX_RX_TERM_BW   0x07c
>> +#define QSERDES_V3_RX_VGA_CAL_CNTRL1   0x0bc
> I noticed you add this definition, but never use it. Are you missing a
> QMP_PHY_INIT_CFG line for this register in qmp_v3_usb3_uniphy_rx_tbl[], or
> is that register "don't care"? It looks important, and while its default
> value out of reset might be valid, you never know what nutty value boot
> firmware might set it to.
>

Yes POR value of this register is valid for this soc.
QMP driver resets (asserts and de-asserts reset_control) in probe. So, that 
should
ensure that PHY registers are indeed set to POR value. Left the definition there
if different setting needed to be done for a different variant of h/w in future.

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-20 Thread Manu Gautam
Hi,


On 3/20/2018 3:53 PM, Vivek Gautam wrote:
> Hi Manu,
>
>
> On 3/16/2018 3:14 PM, Manu Gautam wrote:
>> Update compatible strings for USB2 PHYs on sdm845.
>> There are two QUSB2 PHYs present on sdm845. Few PHY registers
>> programming is different for these PHYs related to electrical
>> parameters, otherwise both are same.
>>
>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>> ---
>>   Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 4 +++-
>>   1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
>> b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> index 42c9742..20deaeb 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> +++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
>> @@ -6,7 +6,9 @@ QUSB2 controller supports LS/FS/HS usb connectivity on 
>> Qualcomm chipsets.
>>   Required properties:
>>    - compatible: compatible list, contains
>>  "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
>> -   "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
>> +   "qcom,qusb2-v2-phy" for QUSB2 V2 PHY,
>> +   "qcom,sdm845-1-qusb2-phy" for primary PHY on sdm845,
>> +   "qcom,sdm845-2-qusb2-phy" for secondary PHY on sdm845.
>
> Thanks for the patch.
>
> "qcom,sdm845-1/2-qusb2-phy" gives an impression that it is different versions 
> of SoC,
> and not like two numbers of phy.
> May be - "qcom,sdm845-qusb2-phy-1/2"

I agree with that. Will update.

>
> Regards
> Vivek
>  
>
>>      - 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



[PATCH v2 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-22 Thread Manu Gautam
QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
to take place. This lock is output from PHY to GCC clock_ctl and then
fed back to QMP PHY and is output from PHY only after PHY is reset
and initialized, hence it can't be enabled too early in initialization
sequence.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 6470c5d..73aa282 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -797,8 +797,13 @@ static int qcom_qmp_phy_poweron(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 ret;
 
+   /* Not needed for USB3 PHY as pipe_clk is enabled from phy_init */
+   if (cfg->type == PHY_TYPE_USB3)
+   return 0;
+
ret = clk_prepare_enable(qphy->pipe_clk);
if (ret)
dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
@@ -1008,6 +1013,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
mask = cfg->mask_pcs_ready;
 
+   /* USB3 PHY requires pipe_clk for PLL lock and calibration */
+   if (cfg->type == PHY_TYPE_USB3) {
+   ret = clk_prepare_enable(qphy->pipe_clk);
+   if (ret)
+   dev_err(qmp->dev, "pipe_clk enable err=%d\n", ret);
+   /*
+* Ignore this error as pipe_clk might take some time to get
+* enabled. In any case following check for PHY PLL lock would
+* timeout below if there is a fatal error and clock is not fed
+* to PHY
+*/
+   }
+
ret = readl_poll_timeout(status, val, !(val & mask), 1,
 PHY_INIT_COMPLETE_TIMEOUT);
if (ret) {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 2/6] phy: qcom-qusb2: Fix crash if nvmem cell not specified

2018-03-22 Thread Manu Gautam
Driver currently crashes due to NULL pointer deference
while updating PHY tune register if nvmem cell is NULL.
Since, fused value for Tune1/2 register is optional,
we'd rather bail out.

Fixes: ca04d9d3e1b1 ("phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips")
Reviewed-by: Vivek Gautam <vivek.gau...@codeaurora.org>
Cc: stable <sta...@vger.kernel.org> # 4.14+
Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 94afeac..40fdef8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -315,6 +315,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
const struct qusb2_phy_cfg *cfg = qphy->cfg;
u8 *val;
 
+   /* efuse register is optional */
+   if (!qphy->cell)
+   return;
+
/*
 * Read efuse register having TUNE2/1 parameter's high nibble.
 * If efuse register shows value as 0x0, or if we fail to find
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 6/6] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-03-22 Thread Manu Gautam
There are two QUSB2 PHYs present on sdm845. Update PHY
registers programming for both the PHYs related to
electrical parameters to improve eye diagram.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 40fdef8..020cbb2 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -174,6 +174,27 @@ enum qusb2phy_reg_layout {
QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
 };
 
+static const struct qusb2_phy_init_tbl sdm845_init_tbl_1[] = {
+   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, 0x8),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
+
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x45),
+   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 */
@@ -220,6 +241,18 @@ struct qusb2_phy_cfg {
.autoresume_en= BIT(0),
 };
 
+static const struct qusb2_phy_cfg sdm845_phy_cfg_1 = {
+   .tbl= sdm845_init_tbl_1,
+   .tbl_num= ARRAY_SIZE(sdm845_init_tbl_1),
+   .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,
+   .has_pll_override = true,
+   .autoresume_en= BIT(0),
+};
+
 static const char * const qusb2_phy_vreg_names[] = {
"vdda-pll", "vdda-phy-dpdm",
 };
@@ -649,6 +682,12 @@ static int qusb2_phy_exit(struct phy *phy)
}, {
.compatible = "qcom,qusb2-v2-phy",
.data   = _v2_phy_cfg,
+   }, {
+   .compatible = "qcom,sdm845-qusb2-phy-1",
+   .data   = _phy_cfg_1,
+   }, {
+   .compatible = "qcom,sdm845-qusb2-phy-2",
+   .data   = _v2_phy_cfg,
},
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 0/6] phy: qcom: Updates for USB PHYs on SDM845

2018-03-22 Thread Manu Gautam
SDM845 has two USB instances each with QUSB2 and QMP PHYs.
One of the QMP PHY is USB-DP (DisplayPort) combo PHY where
as other one is single lane UNI-PHY (without DP support).
Changes are related to PHY configuration for electrical
parameters tuning to improve eye-diagram and some fixes.

Changes since v1:
 - Updated qusb2 compatibility name as per comment from Vivek.

Manu Gautam (6):
  phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS
  phy: qcom-qusb2: Fix crash if nvmem cell not specified
  dt-bindings: phy-qcom-qmp: Update bindings for sdm845
  phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845
  dt-bindings: phy-qcom-usb2: Update bindings for sdm845
  phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

 .../devicetree/bindings/phy/qcom-qmp-phy.txt   |   4 +-
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt |   4 +-
 drivers/phy/qualcomm/phy-qcom-qmp.c| 166 +
 drivers/phy/qualcomm/phy-qcom-qmp.h|   5 +
 drivers/phy/qualcomm/phy-qcom-qusb2.c  |  43 ++
 5 files changed, 220 insertions(+), 2 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 3/6] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-03-22 Thread Manu Gautam
Update compatible strings for USB3 PHYs on SDM845.
One is QMPv3 DisplayPort-USB combo PHY and other one
is USB UNI PHY which is single lane USB3 PHY without
DP capability.

Reviewed-by: Rob Herring <r...@kernel.org>
Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index dcf1b8f..cef8765 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -9,7 +9,9 @@ Required properties:
   "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,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
+  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy,
+  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
+  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845.
 
  - reg: offset and length of register set for PHY's common serdes block.
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 4/6] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-03-22 Thread Manu Gautam
QMP V3 UNI PHY is a single lane USB3 PHY without support
for DisplayPort (DP).
Main difference from DP combo QMPv3 PHY is that UNI PHY
doesn't have dual RX/TX lanes and no separate DP_COM
block for configuration related to type-c or DP.
While at it, fix has_pwrdn_delay attribute for USB-DP
PHY configuration.

Reviewed-by: Evan Green <evgr...@chromium.org>
Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 148 
 drivers/phy/qualcomm/phy-qcom-qmp.h |   5 ++
 2 files changed, 153 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 73aa282..689951d 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -490,6 +490,118 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
 };
 
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+   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, 0x06),
+   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_uniphy_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, 0xc6),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+   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, 0x1c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_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_

[PATCH v2 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-22 Thread Manu Gautam
Update compatible strings for USB2 PHYs on sdm845.
There are two QUSB2 PHYs present on sdm845. Few PHY registers
programming is different for these PHYs related to electrical
parameters, otherwise both are same.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index 42c9742..b99a57f 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -6,7 +6,9 @@ QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm 
chipsets.
 Required properties:
  - compatible: compatible list, contains
   "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
-  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY,
+  "qcom,sdm845-qusb2-phy-1" for primary PHY on sdm845,
+  "qcom,sdm845-qusb2-phy-2" for secondary PHY on sdm845.
 
  - 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



Re: [PATCH v1 1/2] phy: Add QMP phy based UFS phy support for sdm845

2018-03-20 Thread Manu Gautam
Hi Can,


On 3/21/2018 8:12 AM, c...@codeaurora.org wrote:
> On 2018-03-20 19:30, Can Guo wrote:
>> Add UFS PHY support to make SDM845 UFS work with common PHY framework.
>>
>> Signed-off-by: Can Guo 
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp.c | 120 
>> +++-
>>  drivers/phy/qualcomm/phy-qcom-qmp.h |   8 +++
>>  2 files changed, 126 insertions(+), 2 deletions(-)
>>
[snip]
>> +    /* true, if PCS block has a separate SW_RESET register */
>> +    bool has_sw_rst;
>>  };
>>

You should set this for qmp_v3_usb3_uniphy_cfg as well.
Please also mention dependency on my patches [1] and [2] in your cover letter

[1] 
http://lists-archives.com/linux-kernel/29071659-dt-bindings-phy-qcom-qmp-update-bindings-for-sdm845.html
[2] 
lists-archives.com/linux-kernel/29071660-phy-qcom-qmp-add-qmp-v3-usb3-uni-phy-support-for-sdm845.html


>>  /**
>> @@ -636,6 +712,10 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  "aux", "cfg_ahb", "ref", "com_aux",
>>  };
>>
>> +static const char * const sdm845_ufs_phy_clk_l[] = {
>> +    "ref_clk", "ref_aux_clk",
>> +};
>> +
>>  /* list of resets */
>>  static const char * const msm8996_pciephy_reset_l[] = {
>>  "phy", "common", "cfg",
>> @@ -650,6 +730,10 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  "vdda-phy", "vdda-pll",
>>  };
>>
>> +static const char * const sdm845_phy_vreg_l[] = {
>> +    "vdda-phy", "vdda-pll",
>> +};
>> +
>>  static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
>>  .type    = PHY_TYPE_PCIE,
>>  .nlanes    = 3,
>> @@ -679,6 +763,7 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  .has_pwrdn_delay    = true,
>>  .pwrdn_delay_min    = POWER_DOWN_DELAY_US_MIN,
>>  .pwrdn_delay_max    = POWER_DOWN_DELAY_US_MAX,
>> +    .has_sw_rst    = true,
>>  };
>>
>>  static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
>> @@ -704,6 +789,7 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  .start_ctrl    = SERDES_START | PCS_START,
>>  .pwrdn_ctrl    = SW_PWRDN,
>>  .mask_pcs_ready    = PHYSTATUS,
>> +    .has_sw_rst    = true,
>>  };
>>
>>  /* list of resets */
>> @@ -740,6 +826,7 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  .has_pwrdn_delay    = true,
>>  .pwrdn_delay_min    = 995,    /* us */
>>  .pwrdn_delay_max    = 1005,    /* us */
>> +    .has_sw_rst    = true,
>>  };
>>
>>  static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
>> @@ -772,6 +859,30 @@ static inline void qphy_clrbits(void __iomem
>> *base, u32 offset, u32 val)
>>  .has_phy_dp_com_ctrl    = true,
>>  .tx_b_lane_offset    = 0x400,
>>  .rx_b_lane_offset    = 0x400,
>> +    .has_sw_rst    = true,
>> +};
>> +
>> +static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
>> +    .type    = PHY_TYPE_UFS,
>> +    .nlanes    = 2,
>> +
>> +    .serdes_tbl    = sdm845_ufsphy_serdes_tbl,
>> +    .serdes_tbl_num    = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
>> +    .tx_tbl    = sdm845_ufsphy_tx_tbl,
>> +    .tx_tbl_num    = ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
>> +    .rx_tbl    = sdm845_ufsphy_rx_tbl,
>> +    .rx_tbl_num    = ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
>> +    .pcs_tbl    = sdm845_ufsphy_pcs_tbl,
>> +    .pcs_tbl_num    = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
>> +    .clk_list    = sdm845_ufs_phy_clk_l,
>> +    .num_clks    = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
>> +    .vreg_list    = sdm845_phy_vreg_l,
>> +    .num_vregs    = ARRAY_SIZE(sdm845_phy_vreg_l),
>> +    .regs    = sdm845_ufsphy_regs_layout,
>> +
>> +    .start_ctrl    = SERDES_START,
>> +    .pwrdn_ctrl    = SW_PWRDN,
>> +    .mask_pcs_ready    = PCS_READY,
>>  };
>>
>>  static void qcom_qmp_phy_configure(void __iomem *base,
>> @@ -998,7 +1109,8 @@ static int qcom_qmp_phy_init(struct phy *phy)
>>  usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
>>
>>  /* Pull PHY out of reset state */
>> -    qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
>> +    if (cfg->has_sw_rst)
>> +    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);
>>
>> @@ -1036,7 +1148,8 @@ static int qcom_qmp_phy_exit(struct phy *phy)
>>  clk_disable_unprepare(qphy->pipe_clk);
>>
>>  /* PHY reset */
>> -    qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
>> +    if (cfg->has_sw_rst)
>> +    qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
>>
>>  /* stop SerDes and Phy-Coding-Sublayer */
>>  qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
>> @@ -1383,6 +1496,9 @@ int qcom_qmp_phy_create(struct device *dev,
>> struct device_node *np, int id)
>>  }, {

[PATCH v3 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-23 Thread Manu Gautam
Update compatible strings for USB2 PHYs on sdm845.
There are two QUSB2 PHYs present on sdm845. Few PHY registers
programming is different for these PHYs related to electrical
parameters, otherwise both are same.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index 42c9742..b99a57f 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -6,7 +6,9 @@ QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm 
chipsets.
 Required properties:
  - compatible: compatible list, contains
   "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
-  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY,
+  "qcom,sdm845-qusb2-phy-1" for primary PHY on sdm845,
+  "qcom,sdm845-qusb2-phy-2" for secondary PHY on sdm845.
 
  - 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



[PATCH v3 0/6] phy: qcom: Updates for USB PHYs on SDM845

2018-03-23 Thread Manu Gautam
SDM845 has two USB instances each with QUSB2 and QMP PHYs.
One of the QMP PHY is USB-DP (DisplayPort) combo PHY where
as other one is single lane UNI-PHY (without DP support).
Changes are related to PHY configuration for electrical
parameters tuning to improve eye-diagram and some fixes.

Changes since v2:
 - Use separate phy_ops for USB to not register power_on op.
 - And other minor changes as per review comments from Stephen.

Changes since v1:
 - Updated qusb2 compatibility name as per comment from Vivek.

Manu Gautam (6):
  phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS
  phy: qcom-qusb2: Fix crash if nvmem cell not specified
  dt-bindings: phy-qcom-qmp: Update bindings for sdm845
  phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845
  dt-bindings: phy-qcom-usb2: Update bindings for sdm845
  phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

 .../devicetree/bindings/phy/qcom-qmp-phy.txt   |   4 +-
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt |   4 +-
 drivers/phy/qualcomm/phy-qcom-qmp.c| 181 -
 drivers/phy/qualcomm/phy-qcom-qmp.h|   5 +
 drivers/phy/qualcomm/phy-qcom-qusb2.c  |  43 +
 5 files changed, 234 insertions(+), 3 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 4/6] phy: qcom-qmp: Add QMP V3 USB3 UNI PHY support for sdm845

2018-03-23 Thread Manu Gautam
QMP V3 UNI PHY is a single lane USB3 PHY without support
for DisplayPort (DP).
Main difference from DP combo QMPv3 PHY is that UNI PHY
doesn't have dual RX/TX lanes and no separate DP_COM
block for configuration related to type-c or DP.
While at it, fix has_pwrdn_delay attribute for USB-DP
PHY configuration.

Reviewed-by: Evan Green <evgr...@chromium.org>
Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 148 
 drivers/phy/qualcomm/phy-qcom-qmp.h |   5 ++
 2 files changed, 153 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 5d8df6a..d88331b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -490,6 +490,118 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
 };
 
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+   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, 0x06),
+   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_uniphy_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, 0xc6),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x50),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
+   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, 0x1c),
+   QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_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_

[PATCH v3 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-23 Thread Manu Gautam
QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
to take place. This clock is output from PHY to GCC clock_ctl and then
fed back to QMP PHY and is available from PHY only after PHY is reset
and initialized, hence it can't be enabled too early in initialization
sequence.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 33 -
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 6470c5d..5d8df6a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -1008,6 +1008,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
mask = cfg->mask_pcs_ready;
 
+   /*
+* USB3 PHY requires pipe_clk for PLL lock and calibration.
+* Enable it from here for USB. For UFS/PCIE, it gets enabled
+* from poweron.
+*/
+   if (cfg->type == PHY_TYPE_USB3) {
+   ret = clk_prepare_enable(qphy->pipe_clk);
+   if (ret) {
+   dev_err(qmp->dev, "pipe_clk enable err=%d\n", ret);
+   goto err_clk_enable;
+   }
+   }
+
ret = readl_poll_timeout(status, val, !(val & mask), 1,
 PHY_INIT_COMPLETE_TIMEOUT);
if (ret) {
@@ -1019,6 +1032,9 @@ static int qcom_qmp_phy_init(struct phy *phy)
return ret;
 
 err_pcs_ready:
+   if (cfg->type == PHY_TYPE_USB3)
+   clk_disable_unprepare(qphy->pipe_clk);
+err_clk_enable:
if (cfg->has_lane_rst)
reset_control_assert(qphy->lane_rst);
 err_lane_rst:
@@ -1288,10 +1304,19 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, 
struct device_node *np)
.owner  = THIS_MODULE,
 };
 
+/* USB PHY doesn't require power_on op */
+static const struct phy_ops qcom_qmp_usb_phy_gen_ops = {
+   .init   = qcom_qmp_phy_init,
+   .exit   = qcom_qmp_phy_exit,
+   .set_mode   = qcom_qmp_phy_set_mode,
+   .owner  = THIS_MODULE,
+};
+
 static
 int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
 {
struct qcom_qmp *qmp = dev_get_drvdata(dev);
+   const struct phy_ops *ops;
struct phy *generic_phy;
struct qmp_phy *qphy;
char prop_name[MAX_PROP_NAME];
@@ -1354,7 +1379,13 @@ int qcom_qmp_phy_create(struct device *dev, struct 
device_node *np, int id)
}
}
 
-   generic_phy = devm_phy_create(dev, np, _qmp_phy_gen_ops);
+   /* USB PHY doesn't use power_on op */
+   if (qmp->cfg->type == PHY_TYPE_USB3)
+   ops = _qmp_usb_phy_gen_ops;
+   else
+   ops = _qmp_phy_gen_ops;
+
+   generic_phy = devm_phy_create(dev, np, ops);
if (IS_ERR(generic_phy)) {
ret = PTR_ERR(generic_phy);
dev_err(dev, "failed to create qphy %d\n", ret);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 2/6] phy: qcom-qusb2: Fix crash if nvmem cell not specified

2018-03-23 Thread Manu Gautam
Driver currently crashes due to NULL pointer deference
while updating PHY tune register if nvmem cell is NULL.
Since, fused value for Tune1/2 register is optional,
we'd rather bail out.

Fixes: ca04d9d3e1b1 ("phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips")
Reviewed-by: Vivek Gautam <vivek.gau...@codeaurora.org>
Cc: stable <sta...@vger.kernel.org> # 4.14+
Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 94afeac..40fdef8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -315,6 +315,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
const struct qusb2_phy_cfg *cfg = qphy->cfg;
u8 *val;
 
+   /* efuse register is optional */
+   if (!qphy->cell)
+   return;
+
/*
 * Read efuse register having TUNE2/1 parameter's high nibble.
 * If efuse register shows value as 0x0, or if we fail to find
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 3/6] dt-bindings: phy-qcom-qmp: Update bindings for sdm845

2018-03-23 Thread Manu Gautam
Update compatible strings for USB3 PHYs on SDM845.
One is QMPv3 DisplayPort-USB combo PHY and other one
is USB UNI PHY which is single lane USB3 PHY without
DP capability.

Reviewed-by: Rob Herring <r...@kernel.org>
Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index dcf1b8f..cef8765 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -9,7 +9,9 @@ Required properties:
   "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,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
+  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy,
+  "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845,
+  "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845.
 
  - reg: offset and length of register set for PHY's common serdes block.
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3 6/6] phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845

2018-03-23 Thread Manu Gautam
There are two QUSB2 PHYs present on sdm845. Update PHY
registers programming for both the PHYs related to
electrical parameters to improve eye diagram.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 40fdef8..020cbb2 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -174,6 +174,27 @@ enum qusb2phy_reg_layout {
QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
 };
 
+static const struct qusb2_phy_init_tbl sdm845_init_tbl_1[] = {
+   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, 0x8),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
+
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x45),
+   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 */
@@ -220,6 +241,18 @@ struct qusb2_phy_cfg {
.autoresume_en= BIT(0),
 };
 
+static const struct qusb2_phy_cfg sdm845_phy_cfg_1 = {
+   .tbl= sdm845_init_tbl_1,
+   .tbl_num= ARRAY_SIZE(sdm845_init_tbl_1),
+   .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,
+   .has_pll_override = true,
+   .autoresume_en= BIT(0),
+};
+
 static const char * const qusb2_phy_vreg_names[] = {
"vdda-pll", "vdda-phy-dpdm",
 };
@@ -649,6 +682,12 @@ static int qusb2_phy_exit(struct phy *phy)
}, {
.compatible = "qcom,qusb2-v2-phy",
.data   = _v2_phy_cfg,
+   }, {
+   .compatible = "qcom,sdm845-qusb2-phy-1",
+   .data   = _phy_cfg_1,
+   }, {
+   .compatible = "qcom,sdm845-qusb2-phy-2",
+   .data   = _v2_phy_cfg,
},
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 1/6] phy: qcom-qmp: Enable pipe_clk before checking USB3 PHY_STATUS

2018-03-22 Thread Manu Gautam
Hi Stephen,


On 3/23/2018 12:13 AM, Stephen Boyd wrote:
> Quoting Manu Gautam (2018-03-22 01:50:41)
>> QMP PHY for USB mode requires pipe_clk for calibration and PLL lock
>> to take place. This lock is output from PHY to GCC clock_ctl and then
> s/lock/clock/
Yes, will fix typo.
>> fed back to QMP PHY and is output from PHY only after PHY is reset
>> and initialized, hence it can't be enabled too early in initialization
>> sequence.
>>
>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp.c | 18 ++
>>  1 file changed, 18 insertions(+)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
>> b/drivers/phy/qualcomm/phy-qcom-qmp.c
>> index 6470c5d..73aa282 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
>> @@ -797,8 +797,13 @@ static int qcom_qmp_phy_poweron(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 ret;
>>  
>> +   /* Not needed for USB3 PHY as pipe_clk is enabled from phy_init */
>> +   if (cfg->type == PHY_TYPE_USB3)
>> +   return 0;
> Would be nice to not even assign phy_poweron when the PHY is USB3 type.
Yes, that should be better.

>
>> +
>> ret = clk_prepare_enable(qphy->pipe_clk);
>> if (ret)
>> dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
>> @@ -1008,6 +1013,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
>> status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
>> mask = cfg->mask_pcs_ready;
>>  
>> +   /* USB3 PHY requires pipe_clk for PLL lock and calibration */
>> +   if (cfg->type == PHY_TYPE_USB3) {
>> +   ret = clk_prepare_enable(qphy->pipe_clk);
>> +   if (ret)
>> +   dev_err(qmp->dev, "pipe_clk enable err=%d\n", ret);
>> +   /*
>> +* Ignore this error as pipe_clk might take some time to get
>> +* enabled. In any case following check for PHY PLL lock 
>> would
>> +* timeout below if there is a fatal error and clock is not 
>> fed
>> +* to PHY
>> +*/
>> +
> This is odd. If clk_enable() fails then we don't keep parent clks (or
> the clk that's being operated on) up refcounted and enabled. How is that
> going to work?

I agree. My intent was to ignore only halt_check errors from clock driver.
In any case this condition (to ignore clk_enable error) should probably
be handled in clock driver. And I see that clock driver is already using
halt_check as BRANCH_HALT_DELAY, so I don't need to worry about that
in phy driver.



-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2] phy: core: Allow phy_pm_runtime_xxx API calls with NULL phy

2018-03-20 Thread Manu Gautam
phy_init() and phy_exit() calls, and phy_power_on() and
phy_power_off() already accept NULL as valid PHY reference
and act as NOP. Extend same concept to phy runtime_pm APIs
to keep drivers (e.g. dwc3) code simple while dealing with
optional PHYs.

Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
---
Changes for v2:
 - Fixed compilation warning

 drivers/phy/phy-core.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 3c31ce5..1fda576 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -153,6 +153,9 @@ int phy_pm_runtime_get(struct phy *phy)
 {
int ret;
 
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(>dev))
return -ENOTSUPP;
 
@@ -168,6 +171,9 @@ int phy_pm_runtime_get_sync(struct phy *phy)
 {
int ret;
 
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(>dev))
return -ENOTSUPP;
 
@@ -181,6 +187,9 @@ int phy_pm_runtime_get_sync(struct phy *phy)
 
 int phy_pm_runtime_put(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(>dev))
return -ENOTSUPP;
 
@@ -190,6 +199,9 @@ int phy_pm_runtime_put(struct phy *phy)
 
 int phy_pm_runtime_put_sync(struct phy *phy)
 {
+   if (!phy)
+   return 0;
+
if (!pm_runtime_enabled(>dev))
return -ENOTSUPP;
 
@@ -199,6 +211,9 @@ int phy_pm_runtime_put_sync(struct phy *phy)
 
 void phy_pm_runtime_allow(struct phy *phy)
 {
+   if (!phy)
+   return;
+
if (!pm_runtime_enabled(>dev))
return;
 
@@ -208,6 +223,9 @@ void phy_pm_runtime_allow(struct phy *phy)
 
 void phy_pm_runtime_forbid(struct phy *phy)
 {
+   if (!phy)
+   return;
+
if (!pm_runtime_enabled(>dev))
return;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH 5/6] dt-bindings: phy-qcom-usb2: Update bindings for sdm845

2018-03-18 Thread Manu Gautam
Hi,


On 3/18/2018 6:22 PM, Rob Herring wrote:
> On Fri, Mar 16, 2018 at 03:14:58PM +0530, Manu Gautam wrote:
>> Update compatible strings for USB2 PHYs on sdm845.
>> There are two QUSB2 PHYs present on sdm845. Few PHY registers
>> programming is different for these PHYs related to electrical
>> parameters, otherwise both are same.
> Register locations are different or tuning values are different? For the 
> latter, is that something that could be DT properties?

There are only register values changes. Corresponding driver change:
https://patchwork.kernel.org/patch/10286803/


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 1/2] dt-bindings: usb: Update documentation for Qualcomm DWC3 driver

2018-03-18 Thread Manu Gautam
Hi,


On 3/18/2018 6:19 PM, Rob Herring wrote:
> On Tue, Mar 13, 2018 at 04:06:00PM +0530, Manu Gautam wrote:
>> Existing documentation has lot of incorrect information as it
>> was originally added for a driver that no longer exists.
>>
>> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>
>> ---
>>  .../devicetree/bindings/usb/qcom,dwc3.txt  | 87 
>> +++---
>>  1 file changed, 59 insertions(+), 28 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt 
>> b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> index bc8a2fa..df312f7 100644
>> --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
>> @@ -1,54 +1,85 @@
>>  Qualcomm SuperSpeed DWC3 USB SoC controller
>>  
>>  Required properties:
>> -- compatible:   should contain "qcom,dwc3"
>> -- clocks:   A list of phandle + clock-specifier pairs for the
>> -clocks listed in clock-names
>> -- clock-names:  Should contain the following:
>> -  "core"Master/Core clock, have to be >= 125 MHz for SS
>> -operation and >= 60MHz for HS operation
>> -
>> -Optional clocks:
>> -  "iface"   System bus AXI clock.  Not present on all platforms
>> -  "sleep"   Sleep clock, used when USB3 core goes into low
>> -power mode (U3).
>> +- compatible:   should contain "qcom,dwc3"
>> +- reg:  offset and length of register set for QSCRATCH 
>> wrapper
>> +- reg-names:should be "qscratch"
> reg-names is pointless for a single range.
Ok. Will change this.

>
>> +- power-domains:specifies a phandle to PM domain provider node
>> +- clocks:   list of phandle + clock-specifier pairs
> How many clocks and what are they?
I will add description of the clocks in next version of patchset.


>
>> +- assigned-clocks:  should be:
>> +MOCK_UTMI_CLK
>> +MASTER_CLK
>> +- assigned-clock-rates: should be:
>> +19.2Mhz (19200) for MOCK_UTMI_CLK
>> +>=125Mhz (12500) for MASTER_CLK in SS 
>> mode
>> +>=60Mhz (6000) for MASTER_CLK in HS mode
>> +
>> +Optional properties:
>> +- resets:   list of phandle and reset specifier pairs
>> +- interrupts:   specifies interrupts from controller wrapper 
>> used
>> +to wakeup from low power/susepnd state. Must contain
>> +one or more entry for interrupt-names property
>> +- interrupt-names:  Must include the following entries:
>> +- "hs_phy_irq": The interrupt that is asserted when a
>> +   wakeup event is received on USB2 bus
>> +- "ss_phy_irq": The interrupt that is asserted when a
>> +   wakeup event is received on USB3 bus
>> +- "dm_hs_phy_irq" and "dp_hs_phy_irq": Separate
>> +   interrupts for any wakeup event on DM and DP lines
>> +- qcom,select-utmi-as-pipe-clk: if present, disable USB3 pipe_clk 
>> requirement.
>> +Used when dwc3 operates without SSPHY and only
>> +HS/FS/LS modes are supported.
>>  
>>  Required child node:
>>  A child node must exist to represent the core DWC3 IP block. The name of
>>  the node is not important. The content of the node is defined in dwc3.txt.
>>  
>>  Phy documentation is provided in the following places:
>> -Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt
>> +Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt   - USB3 QMP PHY
>> +Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt - USB2 QUSB2 PHY

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v7 3/4] phy: Add QMP phy based UFS phy support for sdm845

2018-06-27 Thread Manu Gautam
Hi,

On 6/19/2018 2:06 PM, Can Guo wrote:
> +static int qcom_qmp_phy_poweron(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;
> + void __iomem *pcs = qphy->pcs;
> + void __iomem *status;
> + unsigned int mask, val;
> + int ret = 0;
> +
> + if (cfg->type != PHY_TYPE_UFS)
> + return 0;
> +
> + /*
> +  * For UFS PHY that has not software reset control, serdes start
> +  * should only happen when UFS driver explicitly calls phy_power_on
> +  * after it deasserts software reset.
> +  */

Instead of relying on UFS glue driver to assert/de-assert PHY
which requires UFS PHY initialization to be split in init() and
poweron(), we can rather register reset_controller from ufs-qcom
driver.
PHY driver can then assert/de-assert as per UFS PHY requirement
in init() function itself and there won't be any need to have
poweron() routine for UFS as init can perform complete PHY
initialization without any dependency on ufs-qcom glue driver.

-Manu

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


Re: [PATCH v7 1/4] phy: Update PHY power control sequence

2018-06-27 Thread Manu Gautam



On 6/19/2018 2:06 PM, Can Guo wrote:
> All PHYs should be powered on before register configuration starts. And
> only PCIe PHYs need an extra power control before deasserts reset state.
> 
> Signed-off-by: Can Guo 
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp.c | 19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)

Reviewed-by: Manu Gautam 

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


Re: [PATCH v7 2/4] phy: General struct and field cleanup

2018-06-27 Thread Manu Gautam



On 6/19/2018 2:06 PM, Can Guo wrote:
> Move MSM8996 specific PHY vreg list struct name to a genernal one as it is
> used by all PHYs. Add a specific field to handle dual lane situation.
> 
> Signed-off-by: Can Guo 
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp.c | 25 ++---
>  1 file changed, 14 insertions(+), 11 deletions(-)

Reviewed-by: Manu Gautam 

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


[PATCH v2 2/2] phy: qcom-qusb2: Fix HSTX_TRIM tuning with fused value for SDM845

2018-10-16 Thread Manu Gautam
Tune1 register on sdm845 is used to update HSTX_TRIM with fused
setting. Enable same by specifying update_tune1_with_efuse flag
for sdm845, otherwise driver ends up programming tune2 register.

Fixes: ef17f6e212ca ("phy: qcom-qusb2: Add QUSB2 PHYs support for sdm845")
Signed-off-by: Manu Gautam 
Reviewed-by: Douglas Anderson 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 9d6c88064158..69c92843eb3b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -231,6 +231,7 @@ static const struct qusb2_phy_cfg sdm845_phy_cfg = {
.mask_core_ready = CORE_READY_STATUS,
.has_pll_override = true,
.autoresume_en= BIT(0),
+   .update_tune1_with_efuse = true,
 };
 
 static const char * const qusb2_phy_vreg_names[] = {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 1/2] phy: qcom-qusb2: Use HSTX_TRIM fused value as is

2018-10-16 Thread Manu Gautam
Fix HSTX_TRIM tuning logic which instead of using fused value
as HSTX_TRIM, incorrectly performs bitwise OR operation with
existing default value.

Fixes: ca04d9d3e1b1 ("phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips")
Signed-off-by: Manu Gautam 
Reviewed-by: Douglas Anderson 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index e70e425f26f5..9d6c88064158 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -402,10 +402,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
 
/*
 * 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
-* configuring phy.
+* If efuse register shows value as 0x0 (indicating value is not
+* fused), or if we fail to find a valid efuse register setting,
+* then use default value for high nibble that we have already
+* set while configuring the phy.
 */
val = nvmem_cell_read(qphy->cell, NULL);
if (IS_ERR(val) || !val[0]) {
@@ -415,12 +415,13 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
 
/* 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);
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
+val[0] << HSTX_TRIM_SHIFT,
+HSTX_TRIM_MASK);
else
-   qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
- val[0] << 0x4);
-
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
+val[0] << HSTX_TRIM_SHIFT,
+HSTX_TRIM_MASK);
 }
 
 static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v1] arm64: dts: qcom: sdm845: Fix pcs_misc region address for UNI PHY

2018-10-25 Thread Manu Gautam
Correct address for pcs_misc register region of USB3 QMP UNI PHY.
These registers are used during runtime-suspend/resume routines
of phy.

Fixes: ca4db2b538a1 ("arm64: dts: qcom: sdm845: Add USB-related nodes")
Signed-off-by: Manu Gautam 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index b72bdb0a31a5..84bee81562a5 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -1156,7 +1156,7 @@
reg = <0x88eb200 0x128>,
  <0x88eb400 0x1fc>,
  <0x88eb800 0x218>,
- <0x88e9600 0x70>;
+ <0x88eb600 0x70>;
#phy-cells = <0>;
clocks = < GCC_USB3_SEC_PHY_PIPE_CLK>;
clock-names = "pipe0";
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v1] phy: qcom-qusb2: Fix HSTX_TRIM tuning with fused value for SDM845

2018-10-05 Thread Manu Gautam
Tune1 register on sdm845 is used to update HSTX_TRIM with fused
setting. Enable same by specifying update_tune1_with_efuse flag
for sdm845, otherwise driver ends up programming tune2 register.
While at it, also fix HSTX_TRIM tuning logic which instead of
using fused value as HSTX_TRIM, incorrectly performs bitwise OR
operation with existing default value.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index e70e425f26f5..defeb0b7cfa0 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -231,6 +231,7 @@ static const struct qusb2_phy_cfg sdm845_phy_cfg = {
.mask_core_ready = CORE_READY_STATUS,
.has_pll_override = true,
.autoresume_en= BIT(0),
+   .update_tune1_with_efuse = true,
 };
 
 static const char * const qusb2_phy_vreg_names[] = {
@@ -415,12 +416,13 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
 
/* 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);
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
+val[0] << HSTX_TRIM_SHIFT,
+HSTX_TRIM_MASK);
else
-   qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
- val[0] << 0x4);
-
+   qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
+val[0] << HSTX_TRIM_SHIFT,
+HSTX_TRIM_MASK);
 }
 
 static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



<    1   2   3   4   5   >