[PATCH v3 00/16] Support for Qualcomm QUSBv2 and QMPv3 USB PHYs
QUSB-v2 and QMP-v3 USB PHYs are present on Qualcomm's 14nm and 10nm SOCs. This patch series adds support for runtime PM for these USB PHYs and adds fixes in drivers to follow PHY reset and initialization sequence as per hardware programming manual. Changes since v2: - Drop sw-vbus override related patches as dwc3 glue driver to take care of same. - Don't read current linestate but rather rely on current speed which will be notified by core driver. This is required to have correct polarity of wakeup events detection in PHY. Changes since v1: - Incorporated review comments. - Fixes to align with hardware programming manual. - Added support for QUSBv2 and QMPv3 PHYs. - Enable DP/DM asynchronous interrupts from QUSB2 USB2 PHY for remote-wakeup. - Enable LFPS and RX-TERM detection for attach and detach events from QMP USB3 PHY for remotewakeup. - Update sw-vbus override in PHY wrapper for device mode. - Dropped one dwc3 patch from this series which I will submit with other dwc3 patches. ("usb: dwc3: core: Notify USB3 PHY as well for DRD modes") Manu Gautam (14): phy: qcom-qmp: Power-on PHY before initialization phy: qcom-qusb2: Power-on PHY before initialization phy: qcom-qmp: Fix PHY block reset sequence phy: qcom-qmp: Move SERDES/PCS START after PHY reset phy: qcom-qusb2: Add support for different register layouts dt-bindings: phy-qcom-qusb2: Update binding for QUSB2 V2 version phy: qcom-qusb2: Add support for QUSB2 V2 version phy: qcom-qmp: Move register offsets to header file phy: qcom-qmp: Add register offsets for QMP V3 PHY dt-bindings: phy-qcom-qmp: Update bindings for QMP V3 USB PHY phy: qcom-qmp: Add support for QMP V3 USB3 PHY phy: Add notify_speed callback phy: qcom-qusb2: Add support for runtime PM phy: qcom-qmp: Add support for runtime PM Vivek Gautam (2): phy: qcom-qmp: Fix phy pipe clock gating phy: qcom-qmp: Adapt to clk_bulk_* APIs .../devicetree/bindings/phy/qcom-qmp-phy.txt | 6 +- .../devicetree/bindings/phy/qcom-qusb2-phy.txt | 5 +- drivers/phy/phy-core.c | 30 + drivers/phy/qualcomm/phy-qcom-qmp.c| 662 ++--- drivers/phy/qualcomm/phy-qcom-qmp.h| 289 + drivers/phy/qualcomm/phy-qcom-qusb2.c | 395 ++-- include/linux/phy/phy.h| 26 + 7 files changed, 1153 insertions(+), 260 deletions(-) create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp.h -- 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-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 09/16] phy: qcom-qusb2: Add support for QUSB2 V2 version
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 --- 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 c0c5358..bda1f4c 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 */ @@ -139,6 +190,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", }; @@ -419,6 +480,9 @@ static int qusb2_phy_exit(struct phy *phy) { .compatible = "qcom,msm8996-qusb2-phy", .data = &msm8996_phy_cfg, + }, { + .compatible = "qcom,qusb2-v2-phy", + .data = &qusb2_v2_phy_cfg, }, { }, }; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 16/16] phy: qcom-qmp: Add support for runtime PM
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 --- drivers/phy/qualcomm/phy-qcom-qmp.c | 185 +++- drivers/phy/qualcomm/phy-qcom-qmp.h | 3 + 2 files changed, 187 insertions(+), 1 deletion(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index efd187b..9553741 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 + * @speed: current PHY speed */ 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_speed speed; }; static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) @@ -988,6 +1016,7 @@ static int qcom_qmp_phy_init(struct phy *phy) dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret); goto err_pcs_ready; } + qmp->phy_initialized = true; return 0; @@ -1022,6 +1051,135 @@ 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_notify_speed(struct phy *phy, enum phy_speed speed) +{ + struct qmp_phy *qphy = phy_get_drvdata(phy); + struct qcom_qmp *qmp = qphy->qmp; + + qmp->speed = speed; + + return 0; +} + +static enum phy_speed qcom_qmp_phy_get_speed(struct phy *phy) +{ + struct qmp_phy *qphy = phy_get_drvdata(phy); + struct qcom_qmp *qmp = qphy->qmp; + + return qmp->speed; +} + +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->speed == PHY_SPEED_USB_SS) + intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN; + else + intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL; + + /*
[PATCH v3 15/16] phy: qcom-qusb2: Add support for runtime PM
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 --- drivers/phy/qualcomm/phy-qcom-qusb2.c | 181 ++ 1 file changed, 181 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index bda1f4c..84cce0e 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,9 +193,13 @@ 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 PHY has PLL_CORE_INPUT_OVERRIDE register to reset PLL */ + bool has_pll_override; }; static const struct qusb2_phy_cfg msm8996_phy_cfg = { @@ -188,6 +210,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 = { @@ -198,6 +221,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[] = { @@ -223,6 +248,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 + * @speed: current PHY speed */ struct qusb2_phy { struct phy *phy; @@ -239,6 +266,8 @@ struct qusb2_phy { const struct qusb2_phy_cfg *cfg; bool has_se_clk_scheme; + bool phy_initialized; + enum phy_speed speed; }; static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val) @@ -307,6 +336,137 @@ 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_notify_speed(struct phy *phy, enum phy_speed speed) +{ + struct qusb2_phy *qphy = phy_get_drvdata(phy); + + qphy->speed = speed; + + return 0; +} + +static enum phy_speed qusb2_phy_get_speed(struct phy *phy) +{ + struct qusb2_phy *qphy = phy_get_drvdata(phy); + + return qphy->speed; +} + +static int __maybe_unused qusb2_phy_runtime_suspend(struct device *dev) +{ + struct qusb2_phy *qp
[PATCH v3 13/16] phy: qcom-qmp: Add support for QMP V3 USB3 PHY
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 --- 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 15a734f..efd187b 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_init_tbl qmp_v3_usb3_rx_tbl[] = {
[PATCH v3 14/16] phy: Add notify_speed callback
QCOM USB PHYs can monitor resume/remote-wakeup event in suspended state. However PHY driver must know current operational speed of PHY in order to set correct polarity of wakeup events for detection. E.g. QUSB2 PHY monitors DP/DM signals depending on 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 --- drivers/phy/phy-core.c | 30 ++ include/linux/phy/phy.h | 26 ++ 2 files changed, 56 insertions(+) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index b4964b0..03df2be 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -387,6 +387,36 @@ int phy_calibrate(struct phy *phy) } EXPORT_SYMBOL_GPL(phy_calibrate); +int phy_notify_speed(struct phy *phy, enum phy_speed speed) +{ + int ret; + + if (!phy || !phy->ops->notify_speed) + return 0; + + mutex_lock(&phy->mutex); + ret = phy->ops->notify_speed(phy, speed); + mutex_unlock(&phy->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(phy_notify_speed); + +enum phy_speed phy_get_speed(struct phy *phy) +{ + enum phy_speed ret; + + if (!phy || !phy->ops->get_speed) + return PHY_SPEED_UNKNOWN; + + mutex_lock(&phy->mutex); + ret = phy->ops->get_speed(phy); + mutex_unlock(&phy->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(phy_get_speed); + /** * _of_phy_get() - lookup and obtain a reference to a phy by phandle * @np: device_node for which to get the phy diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 4f8423a..9efd3cd 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -33,6 +33,14 @@ enum phy_mode { PHY_MODE_UFS_HS_B, }; +enum phy_speed { + PHY_SPEED_UNKNOWN, + PHY_SPEED_USB_LS, + PHY_SPEED_USB_FS, + PHY_SPEED_USB_HS, + PHY_SPEED_USB_SS, +}; + /** * struct phy_ops - set of function pointers for performing phy operations * @init: operation to be performed for initializing phy @@ -42,6 +50,8 @@ enum phy_mode { * @set_mode: set the mode of the phy * @reset: resetting the phy * @calibrate: calibrate the phy + * @notify_speed: notify phy driver of current speed of PHY + * @get_speed: get current operational speed of PHY * @owner: the module owner containing the ops */ struct phy_ops { @@ -52,6 +62,8 @@ struct phy_ops { int (*set_mode)(struct phy *phy, enum phy_mode mode); int (*reset)(struct phy *phy); int (*calibrate)(struct phy *phy); + int (*notify_speed)(struct phy *phy, enum phy_speed speed); + enum phy_speed (*get_speed)(struct phy *phy); struct module *owner; }; @@ -146,6 +158,8 @@ static inline void *phy_get_drvdata(struct phy *phy) int phy_set_mode(struct phy *phy, enum phy_mode mode); int phy_reset(struct phy *phy); int phy_calibrate(struct phy *phy); +int phy_notify_speed(struct phy *phy, enum phy_speed speed); +enum phy_speed phy_get_speed(struct phy *phy); static inline int phy_get_bus_width(struct phy *phy) { return phy->attrs.bus_width; @@ -274,6 +288,18 @@ static inline int phy_calibrate(struct phy *phy) return -ENOSYS; } +static inline int phy_notify_speed(struct phy *phy, enum phy_speed speed) +{ + if (!phy) + return 0; + return -EINVAL; +} + +static inline enum phy_speed phy_get_speed(struct phy *phy) +{ + return PHY_SPEED_UNKNOWN; +} + static inline int phy_get_bus_width(struct phy *phy) { return -ENOSYS; -- 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-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 12/16] dt-bindings: phy-qcom-qmp: Update bindings for QMP V3 USB PHY
Update compatible string and clock names for QMP version V3 USB PHY. Acked-by: Rob Herring Signed-off-by: Manu Gautam --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 11/16] phy: qcom-qmp: Add register offsets for QMP V3 PHY
Registers offsets for QMP V3 PHY are changed from previous versions (1/2), update same in header file. Signed-off-by: Manu Gautam --- 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 0x16c +#define QSERDES_V3_COM_D
[PATCH v3 10/16] phy: qcom-qmp: Move register offsets to header file
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 --- 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 263cf50..15a734f 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 -#define QSERDES_COM_CORECLK_DIV_MODE1
[PATCH v3 08/16] dt-bindings: phy-qcom-qusb2: Update binding for QUSB2 V2 version
Update generic compatible string for QUSB2 V2 PHY. This will allow all targets using QUSB2 V2 use same string. Acked-by: Rob Herring Signed-off-by: Manu Gautam --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 06/16] phy: qcom-qmp: Move SERDES/PCS START after PHY reset
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 --- 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 aa27757..263cf50 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -882,12 +882,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 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 07/16] phy: qcom-qusb2: Add support for different register layouts
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 --- drivers/phy/qualcomm/phy-qcom-qusb2.c | 131 -- 1 file changed, 95 insertions(+), 36 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index 4a5b2a1..c0c5358 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,24 @@ 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; }; 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,12 +206,17 @@ static inline void qusb2_clrbits(void __iomem *base, u32 offset, u32 val) static inline void qcom_qusb2_phy_configure(void __iomem *base, + const unsigned int *regs, const struct qusb2_phy_init_tbl tbl[], int num) { int i; - for (i = 0; i < num; i++) - writel(tbl[i].val, base + tbl[i].offset); + for (i = 0; i < num; i++) { + if (tbl[i].in
[PATCH v3 04/16] phy: qcom-qusb2: Power-on PHY before initialization
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 --- drivers/phy/qualcomm/phy-qcom-qusb2.c | 47 +++ 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index 6c57524..4a5b2a1 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -195,54 +195,31 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy) qusb2_setbits(qphy->base, QUSB2PHY_PORT_TUNE2, val[0] << 0x4); } -static int qusb2_phy_poweron(struct phy *phy) +static int qusb2_phy_init(struct phy *phy) { struct qusb2_phy *qphy = phy_get_drvdata(phy); - int num = ARRAY_SIZE(qphy->vregs); + unsigned int val; + unsigned int clk_scheme; int ret; - dev_vdbg(&phy->dev, "%s(): Powering-on QUSB2 phy\n", __func__); + dev_vdbg(&phy->dev, "%s(): Initializing QUSB2 phy\n", __func__); /* turn on regulator supplies */ - ret = regulator_bulk_enable(num, qphy->vregs); + ret = regulator_bulk_enable(ARRAY_SIZE(qphy->vregs), qphy->vregs); if (ret) return ret; ret = clk_prepare_enable(qphy->iface_clk); if (ret) { dev_err(&phy->dev, "failed to enable iface_clk, %d\n", ret); - regulator_bulk_disable(num, qphy->vregs); - return ret; + goto poweroff_phy; } - return 0; -} - -static int qusb2_phy_poweroff(struct phy *phy) -{ - struct qusb2_phy *qphy = phy_get_drvdata(phy); - - clk_disable_unprepare(qphy->iface_clk); - - regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs); - - return 0; -} - -static int qusb2_phy_init(struct phy *phy) -{ - struct qusb2_phy *qphy = phy_get_drvdata(phy); - unsigned int val; - unsigned int clk_scheme; - int ret; - - dev_vdbg(&phy->dev, "%s(): Initializing QUSB2 phy\n", __func__); - /* enable ahb interface clock to program phy */ ret = clk_prepare_enable(qphy->cfg_ahb_clk); if (ret) { dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret); - return ret; + goto disable_iface_clk; } /* Perform phy reset */ @@ -344,6 +321,11 @@ static int qusb2_phy_init(struct phy *phy) reset_control_assert(qphy->phy_reset); disable_ahb_clk: clk_disable_unprepare(qphy->cfg_ahb_clk); +disable_iface_clk: + clk_disable_unprepare(qphy->iface_clk); +poweroff_phy: + regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs); + return ret; } @@ -361,6 +343,9 @@ static int qusb2_phy_exit(struct phy *phy) reset_control_assert(qphy->phy_reset); clk_disable_unprepare(qphy->cfg_ahb_clk); + clk_disable_unprepare(qphy->iface_clk); + + regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs); return 0; } @@ -368,8 +353,6 @@ static int qusb2_phy_exit(struct phy *phy) static const struct phy_ops qusb2_phy_gen_ops = { .init = qusb2_phy_init, .exit = qusb2_phy_exit, - .power_on = qusb2_phy_poweron, - .power_off = qusb2_phy_poweroff, .owner = THIS_MODULE, }; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 03/16] phy: qcom-qmp: Power-on PHY before initialization
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 QMP PHY need to be executed together always, hence remove poweron callback from phy_ops and explicitly perform this from com_init, similar changes needed for poweroff. On similar lines move clk_enable from init to com_init which can be called once for multi lane PHYs. Signed-off-by: Manu Gautam --- drivers/phy/qualcomm/phy-qcom-qmp.c | 61 + 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index 90794dd..2f427e3 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -720,33 +720,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 num = qmp->cfg->num_vregs; - int ret; - - dev_vdbg(&phy->dev, "Powering on QMP phy\n"); - - /* turn on regulator supplies */ - ret = regulator_bulk_enable(num, qmp->vregs); - if (ret) - dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret); - - return ret; -} - -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; -} - static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -759,6 +732,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) { + mutex_unlock(&qmp->phy_mutex); + return ret; + } + + 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) { @@ -803,6 +789,9 @@ 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); mutex_unlock(&qmp->phy_mutex); return ret; @@ -832,6 +821,10 @@ static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp) while (--i >= 0) reset_control_assert(qmp->resets[i]); + clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks); + + regulator_bulk_disable(cfg->num_vregs, qmp->vregs); + mutex_unlock(&qmp->phy_mutex); return 0; @@ -852,15 +845,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); @@ -915,8 +902,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; } @@ -943,8 +928,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; } @@ -1057,8 +1040,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, - .power_off = qcom_qmp_phy_poweroff, .owner = THIS_MODULE, }; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 05/16] phy: qcom-qmp: Fix PHY block reset sequence
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 --- 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 2f427e3..aa27757 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -739,13 +739,16 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp) return ret; } - 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", @@ -754,6 +757,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); @@ -778,7 +787,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; } } @@ -786,11 +795,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); mutex_unlock(&qmp->phy_mutex); -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 02/16] phy: qcom-qmp: Adapt to clk_bulk_* APIs
From: Vivek Gautam Move from using array of clocks to clk_bulk_* APIs that are available now. Signed-off-by: Vivek Gautam Signed-off-by: Manu Gautam --- 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 76acaec..90794dd 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; @@ -848,22 +848,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); @@ -918,9 +915,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; } @@ -930,7 +926,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); @@ -948,8 +943,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; } @@ -998,29 +992,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->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 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 01/16] phy: qcom-qmp: Fix phy pipe clock gating
From: Vivek Gautam 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 enabling pipe clock at the end of phy_init(), and 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 Signed-off-by: Manu Gautam --- drivers/phy/qualcomm/phy-qcom-qmp.c | 26 -- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index e17f035..76acaec 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -731,19 +731,10 @@ static int qcom_qmp_phy_poweron(struct phy *phy) /* turn on regulator supplies */ ret = regulator_bulk_enable(num, qmp->vregs); - if (ret) { + 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) { - dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret); - regulator_bulk_disable(num, qmp->vregs); - return ret; - } - return 0; + return ret; } static int qcom_qmp_phy_poweroff(struct phy *phy) @@ -751,8 +742,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; @@ -915,7 +904,14 @@ static int qcom_qmp_phy_init(struct phy *phy) goto err_pcs_ready; } - return ret; + /* phy is initialized; we can turn on the pipe clock now */ + ret = clk_prepare_enable(qphy->pipe_clk); + if (ret) { + dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret); + goto err_pcs_ready; + } + + return 0; err_pcs_ready: if (cfg->has_lane_rst) @@ -936,6 +932,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 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH net,stable] net: qmi_wwan: add Quectel BG96 2c7c:0296
From: Sebastian Sjoholm Date: Mon, 20 Nov 2017 19:05:17 +0100 > Quectel BG96 is an Qualcomm MDM9206 based IoT modem, supporting both > CAT-M and NB-IoT. Tested hardware is BG96 mounted on Quectel development > board (EVB). The USB id is added to qmi_wwan.c to allow QMI > communication with the BG96. > > Signed-off-by: Sebastian Sjoholm Applied and queued up for -stable. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: usbip port number limits
> - Mensaje original - > De: "Yuyang Du" > Para: "Shuah Khan" > CC: "Juan Zea" , sh...@kernel.org, "Bjørn Mork" > , linux-usb@vger.kernel.org, "Valentina Manea" > > Enviados: Martes, 21 de Noviembre 2017 8:45:33 > Asunto: Re: usbip port number limits > > On Wed, Nov 15, 2017 at 07:58:24AM -0700, Shuah Khan wrote: > > Hi Juan, > > > > On 11/15/2017 07:43 AM, Juan Zea wrote: > > > > > >>> Also, will you be able to revert the usb3 commit > > >>> 1c9de5bf428612458427943b724bea51abde520a > > >>> > > >>> and see if any of the problems go away. > > >>> > > >>> thanks, > > >>> -- Shuah > > >>> > > > > > >> I'm on it and will send results later. > > > > > >> Thanks, > > >> Juan > > > > > > Ok, I'm back. The revert was quite complex, with several conflicts I was > > > not able to resolve. So I started testing full checkouts around that > > > series of changes by Yuyang. > > > > I was hoping it will be easier. I was apprehensive it could be a com[ex > > revert. :( > > > > > That led me to bisecting the problem with the fingerprint reader, and the > > > culprit is here: > > > > > > 03cd00d538a6feb0492cd153edf256ef7d7bd95e is the first bad commit > > > commit 03cd00d538a6feb0492cd153edf256ef7d7bd95e > > > Author: Yuyang Du > > > Date: Thu Jun 8 13:04:09 2017 +0800 > > > > > > usbip: vhci-hcd: Set the vhci structure up to work > > > > > > This patch enables the new vhci structure. Its lock protects > > > both the USB2 hub and the shared USB3 hub. > > > > > > Signed-off-by: Yuyang Du > > > Acked-by: Shuah Khan > > > Signed-off-by: Greg Kroah-Hartman > > > > > > :04 04 b7b5c6b16db801c74354bb0d0a247855f64b0829 > > > 72524e78d281ebc8d36fa32cb93ed0278e99f880 M drivers > > > > > > The commit before, fingerprint reader works. Also, multicontroller works > > > (no usb3 ports). > > > In this bad commit, I get the errors I sent in the previous message. > > > > > > > Thanks for reporting and debugging the problem to isolate the commit. I was > > suspecting one of these commit based on the messages you are seeing. > > > > I will see if I can fix this without doing a huge reverts. > > > Hi, > > Sorry for the latency. It seems now the bug is: > > Nov 14 14:35:29 kernel-tester kernel: [ 229.636543] kernel BUG at > drivers/usb/usbip/vhci_hcd.c:683! > > which is a hard one (you mentioned the lastest kernel is used). > > Since you didn't post patch, lets first make sure we are on the same > page. Could you please try the following patch and see whether the > bug still exists? > > Also, I'm assuming you are using a non-super-speed device. > > Thanks, > Yuyang > > - Hi, Please excuse me... I have reported two different problems in this post, and I think things are mixing up a bit. My bad. I've found two different problems: 1.- When compiling vhci driver with multiple hubs (in latest kernel), usbip tool doesn't seem able to "jump" to the second controller. As far as I understand, it seems to be a problem with high speed devices trying to get connected to super speed ports. I made a patch for avoiding this situation which is almost the same as the one you just sent. Both patches work. I can compile with several hubs of one port, and connect two devices via usbip and the second gets connected to the second controller (skipping the super speed port of first controller). 2.- The problem is some of these devices don't work, whatsoever controller or hub compiling configuration I do. A fingerprint reader and also recently discovered flash usb sticks don't work either. You can connect them with usbip tool, and they list with lsusb with no problem at all. But when you try to use them, you get this "kernel BUG at drivers/usb/usbip/vhci_hcd.c:669!" (by the way, the line number has changed in the latest pull from master I've just tested, but it's the same line of code). This second problem is the one I bisected in my last message. And I got to the commit 03cd00d538a6feb0492cd153edf256ef7d7bd95e, in which both devices stop working. The patch you sent fixes 1 but not 2. And yes, I'm using non-super-speed devices for testing. I hope this helped, and sorry for the mess, Juan Juan Antonio Zea Herranz Proyectos y consultoría | Qindel Group E: juan@qindel.com T: +34 91 766 24 21 M: +34 637 74 63 09 W: qindel.com -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ARM: dts: bcm283x: Fix fifo size for EP 6,7
On 11/20/2017 4:48 PM, Stefan Wahren wrote: > Hi Minas, > > Am 20.11.2017 um 12:59 schrieb Minas Harutyunyan: >> Hi Stefan, >> Looks like I know cause of issue... but I'm overloaded today and will able >> to check it tomorrow. Sorry for delay. > > thanks for your reply. There is no need to hurry, because the merge > window isn't open yet, but i like to get this fixed for the next kernel > release. > > I have the suspicion this is related to the fact that u-boot already > initialize the USB IP, before dwc2 driver is loaded. > > Regards > Stefan > >> >> Thanks, >> Minas >> > > Hi Stefan, We have prepared patch for this issue in July-August'17. Find attached 2 patch files. Please apply patches and test. If issue gone, we will send these patches to LKML by regular flow. Thanks, Minas From 8eff278552aaf248161df9af04f8b93f03526bcd Mon Sep 17 00:00:00 2001 From: Gevorg Sahakyan Date: Mon, 31 Jul 2017 17:19:51 +0400 Subject: [PATCH] usb: dwc2: Fix TxFIFO setup issue In host mode reading from DPTXSIZn returning invalid value(0) in dwc2_check_param_tx_fifo_sizes function. Added g_tx_fifo_size array in dwc2_hw_params structure in which stored power on reset valus of DPTXSIZn registers in device mode (forced to device). Updated dwc2_get_hwparams function to write DPTXFSIZn to array. Modyfied dwc2_check_param_tx_fifo_sizes function accordingly. Change-Id: I61d3db753b1bc06f0f2caf40df350a09655f18fd Signed-off-by: Gevorg Sahakyan --- diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 5029dde..3b71b49 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -533,6 +533,7 @@ unsigned utmi_phy_data_width:2; u32 snpsid; u32 dev_ep_dirs; + u32 g_tx_fifo_size[MAX_EPS_CHANNELS]; }; /* Size of control and EP0 buffers */ diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index 701516e..79080a9 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -452,7 +452,6 @@ int fifo; int min; u32 total = 0; - u32 dptxfszn; fifo_count = dwc2_hsotg_tx_fifo_count(hsotg); min = hsotg->hw_params.en_multiple_tx_fifo ? 16 : 4; @@ -467,15 +466,15 @@ } for (fifo = 1; fifo <= fifo_count; fifo++) { - dptxfszn = (dwc2_readl(hsotg, DPTXFSIZN(fifo)) & - FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT; if (hsotg->params.g_tx_fifo_size[fifo] < min || - hsotg->params.g_tx_fifo_size[fifo] > dptxfszn) { + hsotg->params.g_tx_fifo_size[fifo] > + hsotg->hw_params.g_tx_fifo_size[fifo]) { dev_warn(hsotg->dev, "%s: Invalid parameter g_tx_fifo_size[%d]=%d\n", __func__, fifo, hsotg->params.g_tx_fifo_size[fifo]); - hsotg->params.g_tx_fifo_size[fifo] = dptxfszn; + hsotg->params.g_tx_fifo_size[fifo] = + hsotg->hw_params.g_tx_fifo_size[fifo]; } } } @@ -607,6 +606,7 @@ { struct dwc2_hw_params *hw = &hsotg->hw_params; unsigned int width; + int fifo, fifo_count; u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4; u32 grxfsiz; @@ -675,6 +675,12 @@ hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >> GRXFSIZ_DEPTH_SHIFT; + fifo_count = dwc2_hsotg_tx_fifo_count(hsotg); + + for (fifo = 1; fifo <= fifo_count; fifo++) { + hw->g_tx_fifo_size[fifo] = (dwc2_readl(hsotg, DPTXFSIZN(fifo)) & + FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT; + } return 0; } From c6f7e1c790c4ef30ba818b119a177fdcd9ca7b34 Mon Sep 17 00:00:00 2001 From: Gevorg Sahakyan Date: Tue, 08 Aug 2017 15:45:32 +0400 Subject: [PATCH] usb: dwc2: Fix tx_fifo_total_depth calculation Removed ep_info subtraction during calculation tx_addr_max in dwc2_hsotg_tx_fifo_total_depth function, because its already done in hardware. Also removed dwc2_hsotg_ep_info_size function as no more need. Change-Id: If9a9f8ab115a6e998736ab991056f374eab9f747 Signed-off-by: Gevorg Sahakyan --- diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 98a4a79..3c52f46 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -206,47 +206,11 @@ } /** - * dwc2_hsotg_ep_info_size - return Endpoint Info Control block size in DWORDs - */ -static int dwc2_hsotg_ep_info_size(struct dwc2_hsotg *hsotg) -{ - int val = 0; - int i; - u32 ep_dirs; - - /* -* Don't need additional space for ep info control registers in -* slave mode. -*/ - if (!using_dma(hsotg)) { - dev_dbg(hsotg->dev, "Buffer DMA ep info size 0\n"); - return 0; - } - - /* -* Buffer DMA mode - 1 location per endpoit -* Descriptor DMA mode - 4 locations per e
Re: [RFC PATCH v2 0/7] typec: tcpm: Add sink side support for PPS
Hi Adam, On Tue, Nov 14, 2017 at 11:44:41AM +, Adam Thomson wrote: > This patch set adds sink side support for the PPS feature introduced in the > USB PD 3.0 specification. > > The source PPS supply is represented using the Power Supply framework to > provide > access and control APIs for dealing with it's operating voltage and current, > and switching between a standard PDO and PPS APDO operation. During standard > PDO > operation the voltage and current is read-only, but for APDO PPS these are > writable as well to allow for control. > > It should be noted that the keepalive for PPS is not handled within TCPM. The > expectation is that the external user will be required to ensure re-requests > occur regularly to ensure PPS remains and the source does not hard reset. > > Changes in v2: > - Use USB_PD and usb_pd prefixes for macros and inline functions in headers. > - Negotiate spec revision of PD headers during initial contract agreement. > - New headers now use SPDX tags for referencing correct license. > > NOTE: Code changes are based on linux-next tag 'next-20171114' to pick up > the move out of staging of TCPM related code. > > Adam Thomson (7): > typec: tcpm: Add PD Rev 3.0 definitions to PD header > typec: tcpm: Add ADO header for Alert message handling > typec: tcpm: Add SDB header for Status message handling > typec: tcpm: Add core support for sink side PPS > power: supply: Add type for USB PD PPS chargers > typec: tcpm: Represent source supply through power_supply class > typec: tcpm: Add support for sink PPS related messages > > drivers/power/supply/power_supply_sysfs.c | 2 +- > drivers/usb/typec/Kconfig | 1 + > drivers/usb/typec/fusb302/Kconfig | 2 +- > drivers/usb/typec/fusb302/fusb302.c | 63 +-- > drivers/usb/typec/tcpm.c | 851 > +- > include/linux/power_supply.h | 1 + > include/linux/usb/pd.h| 174 +- > include/linux/usb/pd_ado.h| 42 ++ > include/linux/usb/pd_ext_sdb.h| 31 ++ > include/linux/usb/tcpm.h | 2 +- > 10 files changed, 1071 insertions(+), 98 deletions(-) > create mode 100644 include/linux/usb/pd_ado.h > create mode 100644 include/linux/usb/pd_ext_sdb.h These don't apply on top of Badhri's series: http://www.spinics.net/lists/kernel/msg2649921.html Thanks, -- heikki -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [RFC PATCH v2 0/7] typec: tcpm: Add sink side support for PPS
On 21 November 2017 13:36, Heikki Krogerus write: > Hi Adam, > > On Tue, Nov 14, 2017 at 11:44:41AM +, Adam Thomson wrote: > > This patch set adds sink side support for the PPS feature introduced in the > > USB PD 3.0 specification. > > > > The source PPS supply is represented using the Power Supply framework to > > provide > > access and control APIs for dealing with it's operating voltage and current, > > and switching between a standard PDO and PPS APDO operation. During standard > PDO > > operation the voltage and current is read-only, but for APDO PPS these are > > writable as well to allow for control. > > > > It should be noted that the keepalive for PPS is not handled within TCPM. > > The > > expectation is that the external user will be required to ensure re-requests > > occur regularly to ensure PPS remains and the source does not hard reset. > > > > Changes in v2: > > - Use USB_PD and usb_pd prefixes for macros and inline functions in > > headers. > > - Negotiate spec revision of PD headers during initial contract agreement. > > - New headers now use SPDX tags for referencing correct license. > > > > NOTE: Code changes are based on linux-next tag 'next-20171114' to pick up > > the move out of staging of TCPM related code. > > > > Adam Thomson (7): > > typec: tcpm: Add PD Rev 3.0 definitions to PD header > > typec: tcpm: Add ADO header for Alert message handling > > typec: tcpm: Add SDB header for Status message handling > > typec: tcpm: Add core support for sink side PPS > > power: supply: Add type for USB PD PPS chargers > > typec: tcpm: Represent source supply through power_supply class > > typec: tcpm: Add support for sink PPS related messages > > > > drivers/power/supply/power_supply_sysfs.c | 2 +- > > drivers/usb/typec/Kconfig | 1 + > > drivers/usb/typec/fusb302/Kconfig | 2 +- > > drivers/usb/typec/fusb302/fusb302.c | 63 +-- > > drivers/usb/typec/tcpm.c | 851 > > +- > > include/linux/power_supply.h | 1 + > > include/linux/usb/pd.h| 174 +- > > include/linux/usb/pd_ado.h| 42 ++ > > include/linux/usb/pd_ext_sdb.h| 31 ++ > > include/linux/usb/tcpm.h | 2 +- > > 10 files changed, 1071 insertions(+), 98 deletions(-) > > create mode 100644 include/linux/usb/pd_ado.h > > create mode 100644 include/linux/usb/pd_ext_sdb.h > > These don't apply on top of Badhri's series: > http://www.spinics.net/lists/kernel/msg2649921.html Hi Heikki, When I submitted these I was aware of Badhri's patch set but at the time they hadn't been approved or pulled, at least not into the version of Linux next that I had based on. If these are now merged in to Linux Next then I'll re-spin based on those changes. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] typec: tcpm: fusb302: Resolve out of order messaging events
The expectation in the FUSB302 driver is that a TX_SUCCESS event should occur after a message has been sent, but before a GCRCSENT event is raised to indicate successful receipt of a message from the partner. However in some circumstances it is possible to see the hardware raise a GCRCSENT event before a TX_SUCCESS event is raised. The upshot of this is that the GCRCSENT handling portion of code ends up reporting the GoodCRC message to TCPM because the TX_SUCCESS event hasn't yet arrived to trigger a consumption of it. When TX_SUCCESS is then raised by the chip it ends up consuming the actual message that was meant for TCPM, and this incorrect sequence results in a hard reset from TCPM. To avoid this problem, this commit updates the message reading code to check whether a GoodCRC message was received or not. Based on this check it will either report that the previous transmission has completed or it will pass the msg data to TCPM for futher processing. This way the incorrect ordering of the events no longer matters. Signed-off-by: Adam Thomson --- Changes in v3: - Always read from FIFO on TX_SUCCES and GCRCSENT events, but decision on how to report to TCPM is no longer based on these event types but instead on type of message read in from FIFO. Changes in v2: - Remove erroneous extended header check Patch is based on Linux next-20171114 to include move out of staging. drivers/usb/typec/fusb302/fusb302.c | 21 + 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/fusb302/fusb302.c b/drivers/usb/typec/fusb302/fusb302.c index 72cb060..d200085 100644 --- a/drivers/usb/typec/fusb302/fusb302.c +++ b/drivers/usb/typec/fusb302/fusb302.c @@ -1543,6 +1543,21 @@ static int fusb302_pd_read_message(struct fusb302_chip *chip, fusb302_log(chip, "PD message header: %x", msg->header); fusb302_log(chip, "PD message len: %d", len); + /* +* Check if we've read off a GoodCRC message. If so then indicate to +* TCPM that the previous transmission has completed. Otherwise we pass +* the received message over to TCPM for processing. +* +* We make this check here instead of basing the reporting decision on +* the IRQ event type, as it's possible for the chip to report the +* TX_SUCCESS and GCRCSENT events out of order on occasion, so we need +* to check the message type to ensure correct reporting to TCPM. +*/ + if ((!len) && (pd_header_type_le(msg->header) == PD_CTRL_GOOD_CRC)) + tcpm_pd_transmit_complete(chip->tcpm_port, TCPC_TX_SUCCESS); + else + tcpm_pd_receive(chip->tcpm_port, msg); + return ret; } @@ -1650,13 +1665,12 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id) if (interrupta & FUSB_REG_INTERRUPTA_TX_SUCCESS) { fusb302_log(chip, "IRQ: PD tx success"); - /* read out the received good CRC */ ret = fusb302_pd_read_message(chip, &pd_msg); if (ret < 0) { - fusb302_log(chip, "cannot read in GCRC, ret=%d", ret); + fusb302_log(chip, + "cannot read in PD message, ret=%d", ret); goto done; } - tcpm_pd_transmit_complete(chip->tcpm_port, TCPC_TX_SUCCESS); } if (interrupta & FUSB_REG_INTERRUPTA_HARDRESET) { @@ -1677,7 +1691,6 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id) "cannot read in PD message, ret=%d", ret); goto done; } - tcpm_pd_receive(chip->tcpm_port, &pd_msg); } done: mutex_unlock(&chip->lock); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] typec: tcpm: fusb302: Resolve out of order messaging events
On 21 November 2017 14:08, Adam Thomson wrote: > Subject: [PATCH] typec: tcpm: fusb302: Resolve out of order messaging events Sorry. Finger trouble. Will resend with correct 'v3' title > The expectation in the FUSB302 driver is that a TX_SUCCESS event > should occur after a message has been sent, but before a GCRCSENT > event is raised to indicate successful receipt of a message from > the partner. However in some circumstances it is possible to see > the hardware raise a GCRCSENT event before a TX_SUCCESS event > is raised. The upshot of this is that the GCRCSENT handling portion > of code ends up reporting the GoodCRC message to TCPM because the > TX_SUCCESS event hasn't yet arrived to trigger a consumption of it. > When TX_SUCCESS is then raised by the chip it ends up consuming the > actual message that was meant for TCPM, and this incorrect sequence > results in a hard reset from TCPM. > > To avoid this problem, this commit updates the message reading > code to check whether a GoodCRC message was received or not. Based > on this check it will either report that the previous transmission > has completed or it will pass the msg data to TCPM for futher > processing. This way the incorrect ordering of the events no longer > matters. > > Signed-off-by: Adam Thomson > --- > > Changes in v3: > - Always read from FIFO on TX_SUCCES and GCRCSENT events, but decision on how >to report to TCPM is no longer based on these event types but instead on > type >of message read in from FIFO. > > Changes in v2: > - Remove erroneous extended header check > > Patch is based on Linux next-20171114 to include move out of staging. > > drivers/usb/typec/fusb302/fusb302.c | 21 + > 1 file changed, 17 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/typec/fusb302/fusb302.c > b/drivers/usb/typec/fusb302/fusb302.c > index 72cb060..d200085 100644 > --- a/drivers/usb/typec/fusb302/fusb302.c > +++ b/drivers/usb/typec/fusb302/fusb302.c > @@ -1543,6 +1543,21 @@ static int fusb302_pd_read_message(struct fusb302_chip > *chip, > fusb302_log(chip, "PD message header: %x", msg->header); > fusb302_log(chip, "PD message len: %d", len); > > + /* > + * Check if we've read off a GoodCRC message. If so then indicate to > + * TCPM that the previous transmission has completed. Otherwise we pass > + * the received message over to TCPM for processing. > + * > + * We make this check here instead of basing the reporting decision on > + * the IRQ event type, as it's possible for the chip to report the > + * TX_SUCCESS and GCRCSENT events out of order on occasion, so we need > + * to check the message type to ensure correct reporting to TCPM. > + */ > + if ((!len) && (pd_header_type_le(msg->header) == PD_CTRL_GOOD_CRC)) > + tcpm_pd_transmit_complete(chip->tcpm_port, TCPC_TX_SUCCESS); > + else > + tcpm_pd_receive(chip->tcpm_port, msg); > + > return ret; > } > > @@ -1650,13 +1665,12 @@ static irqreturn_t fusb302_irq_intn(int irq, void > *dev_id) > > if (interrupta & FUSB_REG_INTERRUPTA_TX_SUCCESS) { > fusb302_log(chip, "IRQ: PD tx success"); > - /* read out the received good CRC */ > ret = fusb302_pd_read_message(chip, &pd_msg); > if (ret < 0) { > - fusb302_log(chip, "cannot read in GCRC, ret=%d", ret); > + fusb302_log(chip, > + "cannot read in PD message, ret=%d", ret); > goto done; > } > - tcpm_pd_transmit_complete(chip->tcpm_port, TCPC_TX_SUCCESS); > } > > if (interrupta & FUSB_REG_INTERRUPTA_HARDRESET) { > @@ -1677,7 +1691,6 @@ static irqreturn_t fusb302_irq_intn(int irq, void > *dev_id) > "cannot read in PD message, ret=%d", ret); > goto done; > } > - tcpm_pd_receive(chip->tcpm_port, &pd_msg); > } > done: > mutex_unlock(&chip->lock); > -- > 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] typec: tcpm: fusb302: Resolve out of order messaging events
The expectation in the FUSB302 driver is that a TX_SUCCESS event should occur after a message has been sent, but before a GCRCSENT event is raised to indicate successful receipt of a message from the partner. However in some circumstances it is possible to see the hardware raise a GCRCSENT event before a TX_SUCCESS event is raised. The upshot of this is that the GCRCSENT handling portion of code ends up reporting the GoodCRC message to TCPM because the TX_SUCCESS event hasn't yet arrived to trigger a consumption of it. When TX_SUCCESS is then raised by the chip it ends up consuming the actual message that was meant for TCPM, and this incorrect sequence results in a hard reset from TCPM. To avoid this problem, this commit updates the message reading code to check whether a GoodCRC message was received or not. Based on this check it will either report that the previous transmission has completed or it will pass the msg data to TCPM for futher processing. This way the incorrect ordering of the events no longer matters. Signed-off-by: Adam Thomson --- Changes in v3: - Always read from FIFO on TX_SUCCES and GCRCSENT events, but decision on how to report to TCPM is no longer based on these event types but instead on type of message read in from FIFO. Changes in v2: - Remove erroneous extended header check Patch is based on Linux next-20171114 to include move out of staging. drivers/usb/typec/fusb302/fusb302.c | 21 + 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/fusb302/fusb302.c b/drivers/usb/typec/fusb302/fusb302.c index 72cb060..d200085 100644 --- a/drivers/usb/typec/fusb302/fusb302.c +++ b/drivers/usb/typec/fusb302/fusb302.c @@ -1543,6 +1543,21 @@ static int fusb302_pd_read_message(struct fusb302_chip *chip, fusb302_log(chip, "PD message header: %x", msg->header); fusb302_log(chip, "PD message len: %d", len); + /* +* Check if we've read off a GoodCRC message. If so then indicate to +* TCPM that the previous transmission has completed. Otherwise we pass +* the received message over to TCPM for processing. +* +* We make this check here instead of basing the reporting decision on +* the IRQ event type, as it's possible for the chip to report the +* TX_SUCCESS and GCRCSENT events out of order on occasion, so we need +* to check the message type to ensure correct reporting to TCPM. +*/ + if ((!len) && (pd_header_type_le(msg->header) == PD_CTRL_GOOD_CRC)) + tcpm_pd_transmit_complete(chip->tcpm_port, TCPC_TX_SUCCESS); + else + tcpm_pd_receive(chip->tcpm_port, msg); + return ret; } @@ -1650,13 +1665,12 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id) if (interrupta & FUSB_REG_INTERRUPTA_TX_SUCCESS) { fusb302_log(chip, "IRQ: PD tx success"); - /* read out the received good CRC */ ret = fusb302_pd_read_message(chip, &pd_msg); if (ret < 0) { - fusb302_log(chip, "cannot read in GCRC, ret=%d", ret); + fusb302_log(chip, + "cannot read in PD message, ret=%d", ret); goto done; } - tcpm_pd_transmit_complete(chip->tcpm_port, TCPC_TX_SUCCESS); } if (interrupta & FUSB_REG_INTERRUPTA_HARDRESET) { @@ -1677,7 +1691,6 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id) "cannot read in PD message, ret=%d", ret); goto done; } - tcpm_pd_receive(chip->tcpm_port, &pd_msg); } done: mutex_unlock(&chip->lock); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 0/7] typec: tcpm: Add sink side support for PPS
On Tue, Nov 21, 2017 at 01:51:41PM +, Adam Thomson wrote: > > These don't apply on top of Badhri's series: > > http://www.spinics.net/lists/kernel/msg2649921.html > > Hi Heikki, > > When I submitted these I was aware of Badhri's patch set but at the time they > hadn't been approved or pulled, at least not into the version of Linux next > that I had based on. If these are now merged in to Linux Next then I'll > re-spin > based on those changes. Sure, just wanted to give you heads up in case you had not noticed. Sorry for the noise. Cheers, -- heikki -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [RFC PATCH v2 0/7] typec: tcpm: Add sink side support for PPS
On 21 November 2017 14:18, Heikki Krogerus wrote: > On Tue, Nov 21, 2017 at 01:51:41PM +, Adam Thomson wrote: > > > These don't apply on top of Badhri's series: > > > http://www.spinics.net/lists/kernel/msg2649921.html > > > > Hi Heikki, > > > > When I submitted these I was aware of Badhri's patch set but at the time > > they > > hadn't been approved or pulled, at least not into the version of Linux next > > that I had based on. If these are now merged in to Linux Next then I'll > > re-spin > > based on those changes. > > Sure, just wanted to give you heads up in case you had not noticed. > > Sorry for the noise. No noise, and thanks for the heads up. I actually hadn't seen that go in :) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: usbip port number limits
On 11/21/2017 04:24 AM, Juan Zea wrote: >> - Mensaje original - >> De: "Yuyang Du" >> Para: "Shuah Khan" >> CC: "Juan Zea" , sh...@kernel.org, "Bjørn Mork" >> , linux-usb@vger.kernel.org, "Valentina Manea" >> >> Enviados: Martes, 21 de Noviembre 2017 8:45:33 >> Asunto: Re: usbip port number limits >> >> On Wed, Nov 15, 2017 at 07:58:24AM -0700, Shuah Khan wrote: >>> Hi Juan, >>> >>> On 11/15/2017 07:43 AM, Juan Zea wrote: >> Also, will you be able to revert the usb3 commit >> 1c9de5bf428612458427943b724bea51abde520a >> >> and see if any of the problems go away. >> >> thanks, >> -- Shuah >> > I'm on it and will send results later. > Thanks, > Juan Ok, I'm back. The revert was quite complex, with several conflicts I was not able to resolve. So I started testing full checkouts around that series of changes by Yuyang. >>> >>> I was hoping it will be easier. I was apprehensive it could be a com[ex >>> revert. :( >>> That led me to bisecting the problem with the fingerprint reader, and the culprit is here: 03cd00d538a6feb0492cd153edf256ef7d7bd95e is the first bad commit commit 03cd00d538a6feb0492cd153edf256ef7d7bd95e Author: Yuyang Du Date: Thu Jun 8 13:04:09 2017 +0800 usbip: vhci-hcd: Set the vhci structure up to work This patch enables the new vhci structure. Its lock protects both the USB2 hub and the shared USB3 hub. Signed-off-by: Yuyang Du Acked-by: Shuah Khan Signed-off-by: Greg Kroah-Hartman :04 04 b7b5c6b16db801c74354bb0d0a247855f64b0829 72524e78d281ebc8d36fa32cb93ed0278e99f880 M drivers The commit before, fingerprint reader works. Also, multicontroller works (no usb3 ports). In this bad commit, I get the errors I sent in the previous message. >>> >>> Thanks for reporting and debugging the problem to isolate the commit. I was >>> suspecting one of these commit based on the messages you are seeing. >>> >>> I will see if I can fix this without doing a huge reverts. >>> >> Hi, >> >> Sorry for the latency. It seems now the bug is: >> >> Nov 14 14:35:29 kernel-tester kernel: [ 229.636543] kernel BUG at >> drivers/usb/usbip/vhci_hcd.c:683! >> >> which is a hard one (you mentioned the lastest kernel is used). >> >> Since you didn't post patch, lets first make sure we are on the same >> page. Could you please try the following patch and see whether the >> bug still exists? >> >> Also, I'm assuming you are using a non-super-speed device. >> >> Thanks, >> Yuyang >> >> - > > > Hi, > > Please excuse me... I have reported two different problems in this post, > and I think things are mixing up a bit. My bad. I've found two different > problems: > > 1.- When compiling vhci driver with multiple hubs (in latest kernel), usbip > tool doesn't seem able to "jump" to the second controller. As far as I > understand, it seems to be a problem with high speed devices trying to get > connected to super speed ports. I made a patch for avoiding this situation > which is almost the same as the one you just sent. Both patches work. I can > compile with several hubs of one port, and connect two devices via usbip and > the second gets connected to the second controller (skipping the super speed > port of first controller). > > 2.- The problem is some of these devices don't work, whatsoever controller or > hub compiling configuration I do. A fingerprint reader and also recently > discovered flash usb sticks don't work either. You can connect them with > usbip tool, and they list with lsusb with no problem at all. But when you try > to use them, you get this "kernel BUG at drivers/usb/usbip/vhci_hcd.c:669!" > (by the way, the line number has changed in the latest pull from master I've > just tested, but it's the same line of code). This second problem is the one > I bisected in my last message. And I got to the commit > 03cd00d538a6feb0492cd153edf256ef7d7bd95e, in which both devices stop working. > > The patch you sent fixes 1 but not 2. And yes, I'm using non-super-speed > devices for testing. > > I hope this helped, and sorry for the mess, Thanks for finding the problem. usb2 devices don't work at all with the offending commit: 03cd00d538a6feb0492cd153edf256ef7d7bd95e I have been debugging on 4.12 and this bad commit. Low speed devices can be attached, but you see the following and then shutdown hangs. I don't believe this commit 03cd00d538a6feb0492cd153edf256ef7d7bd95e tested well on usb2 devices. and this commit is suspect. It is unfortunate that it wasn't caught during the patch testing, because it is so easy to run into this. I used one usb2 device and tried to attach over localhost and with this patch happens every single time. I am looking into reverting this commit as well as the rest of the usb3 work that is ba
RE: xhci_hcd HC died; cleaning up with TUSB7340 and µPD720201
> -Original Message- > From: Vignesh R [mailto:vigne...@ti.com] > Sent: Tuesday, November 21, 2017 12:48 AM > To: Roger Quadros > Cc: Chris Welch ; linux-usb@vger.kernel.org; > linux-...@vger.kernel.org; Joao Pinto ; KISHON VIJAY > ABRAHAM > Subject: Re: xhci_hcd HC died; cleaning up with TUSB7340 and µPD720201 > > > > On Monday 20 November 2017 07:01 PM, Roger Quadros wrote: > > On 20/11/17 15:19, Vignesh R wrote: > >> > >> > >> On Monday 20 November 2017 01:31 PM, Roger Quadros wrote: > >> [...] > > So, could you try reverting commit 8c934095fa2f3 and also apply > below patch and let me know if that fixes the issue? > > --- > > diff --git a/drivers/pci/dwc/pci-dra7xx.c > b/drivers/pci/dwc/pci-dra7xx.c index e77a4ceed74c..8280abc56f30 > 100644 > --- a/drivers/pci/dwc/pci-dra7xx.c > +++ b/drivers/pci/dwc/pci-dra7xx.c > @@ -259,10 +259,17 @@ static irqreturn_t > dra7xx_pcie_msi_irq_handler(int irq, void *arg) > u32 reg; > > reg = dra7xx_pcie_readl(dra7xx, > PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI); > + dra7xx_pcie_writel(dra7xx, > + PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, reg); > > switch (reg) { > case MSI: > - dw_handle_msi_irq(pp); > + /* > +* Need to make sure no MSI IRQs are pending before > +* exiting handler, else the wrapper will not catch new > +* IRQs. So loop around till dw_handle_msi_irq() returns > +* IRQ_NONE > +*/ > + while (dw_handle_msi_irq(pp) != IRQ_NONE); The patch looks good, I haven't had a failure in a few days of testing. You should also look at incorporating the following that I needed to change to get our product working. The first change fixes a miss by one error with the interrupt lines. The second change extends a patch you developed for errata i870 but we found is applicable to RC operation as well as EPs. Thanks very much for your help! diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c old mode 100644 new mode 100755 index defa272..6245d89 --- a/drivers/pci/dwc/pci-dra7xx.c +++ b/drivers/pci/dwc/pci-dra7xx.c @@ -238,8 +238,8 @@ static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp) dev_err(dev, "No PCIe Intc node found\n"); return -ENODEV; } - - dra7xx->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, +// PCI interrupt lines start at 1 not zero so need to add 1 + dra7xx->irq_domain = irq_domain_add_linear(pcie_intc_node, 4 + 1, &intx_domain_ops, pp); if (!dra7xx->irq_domain) { dev_err(dev, "Failed to get a INTx IRQ domain\n"); @@ -706,10 +706,16 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE, DEVICE_TYPE_RC); + // Errata i870 applies to RC as well as EP + ret = dra7xx_pcie_ep_legacy_mode(dev); + if (ret) + goto err_gpio; + ret = dra7xx_add_pcie_port(dra7xx, pdev); if (ret < 0) goto err_gpio; break; > >>> > >>> To avoid this kind of looping, shouldn't we be disabling all IRQ > >>> events while the interrupt handler is running and enable them just > >>> before we return from the hardirq handler? > >> > >> IIUC, you are saying to disable all MSIs at PCIe designware core > >> level, then call dw_handle_msi_irq() and then enable MSIs after > >> hardirq returns. But, the problem is if PCIe EP raises another MSI > >> after the call to EP's handler but before re-enabling MSIs, then it > >> will be ignored as IRQs are not yet enabled. > >> Ideally, EP's support Per Vector Masking(PVM) which allow RC to > >> prevent EP from sending MSI messages for sometime. But, > >> unfortunately, the cards mentioned here don't support this feature. > > > > I'm not aware of MSIs. > > > > But for any typical hardware, there should be an interrupt event > > enable register and an interrupt mask register. > > > > In the IRQ handler, we mask the interrupt but still keep the interrupt > > events enabled so that they can be latched during the time the interrupt was > masked. > > > > When the interrupt is unmasked at end of the IRQ handler, it should > > re-trigger the interrupt if any events were latched and pending. > > > > This way you don't need to keep checking for any pending events in the IRQ > handler. > > > > Thanks for the suggestion! I tried using interrupt masking at designware > level. > But, unfortunately that does not help and my test cases still fail. > Seems like designware MSI status register is a non-masked status and dra7xx > spec
[PATCH 1/2] usb: xhci: add relaxed timing quirk bit
Certain systems may run with CPUs at a very slow frequency. This patch adds a quirk bit that can be used to relax certain timings, etc. This quirk might be needed for other fields in the future, but initially, it will be used only on the IRQ control register to allow firmare to control the value of the register. This can prevent an "interrupt storm" effect on certain systems. Signed-off-by: Adam Wallis --- Documentation/devicetree/bindings/usb/usb-xhci.txt | 1 + drivers/usb/host/xhci.c| 25 +++--- drivers/usb/host/xhci.h| 1 + 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt index ae6e484..af2faa24 100644 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt @@ -29,6 +29,7 @@ Optional properties: - usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM - usb3-lpm-capable: determines if platform is USB3 LPM capable - quirk-broken-port-ped: set if the controller has broken port disable mechanism + - quirk-relaxed-timing: allows firmware to relax timing on certain registers Example: usb@f0931000 { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 327ba8b..e14a204 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -582,16 +582,25 @@ int xhci_run(struct usb_hcd *hcd) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "ERST deq = 64'h%0lx", (long unsigned int) temp_64); - xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "// Set the interrupt modulation register"); - temp = readl(&xhci->ir_set->irq_control); - temp &= ~ER_IRQ_INTERVAL_MASK; /* -* the increment interval is 8 times as much as that defined -* in xHCI spec on MTK's controller +* Systems with slow CPUs may not be able to tolerate +* agressive interrupt timing that silicon can tolerate. The +* XHCI_RELAXED_TIMING will allow firmware to set the IRQ +* Control field. */ - temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160); - writel(temp, &xhci->ir_set->irq_control); + if (!(xhci->quirks & XHCI_RELAXED_TIMING_QUIRK)) { + xhci_dbg_trace(xhci, trace_xhci_dbg_init, + "// Set the interrupt modulation register"); + temp = readl(&xhci->ir_set->irq_control); + temp &= ~ER_IRQ_INTERVAL_MASK; + + /* +* the increment interval is 8 times as much as that defined +* in xHCI spec on MTK's controller +*/ + temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160); + writel(temp, &xhci->ir_set->irq_control); + } /* Set the HCD state before we enable the irqs */ temp = readl(&xhci->op_regs->command); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 99a014a..6d451be 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1823,6 +1823,7 @@ struct xhci_hcd { /* Reserved. It was XHCI_U2_DISABLE_WAKE */ #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL(1 << 28) #define XHCI_HW_LPM_DISABLE(1 << 29) +#define XHCI_RELAXED_TIMING_QUIRK (1 << 30) unsigned intnum_active_eps; unsigned intlimit_active_eps; -- Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] usb: host: xhci-plat: check relaxed timing quirk bit
Check sysdev to see if the relaxed timing quirk ("quirk-relaxed-timing") is set. Signed-off-by: Adam Wallis --- drivers/usb/host/xhci-plat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 09f164f..ea221f3 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -266,6 +266,9 @@ static int xhci_plat_probe(struct platform_device *pdev) if (device_property_read_bool(sysdev, "usb3-lpm-capable")) xhci->quirks |= XHCI_LPM_SUPPORT; + if (device_property_read_bool(sysdev, "quirk-relaxed-timing")) + xhci->quirks |= XHCI_RELAXED_TIMING_QUIRK; + if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped")) xhci->quirks |= XHCI_BROKEN_PORT_PED; -- Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] usb: xhci: addition of timing quirk
On systems that allow CPUs to run at an extremely reduced frequency, it is possible to create an "interrupt" storm by USB settings that are not ideal at these speeds. This patch series introduces a quirk bit that currently only touches the Interrupt Control register but might be used in the future with other similar registers. This change allows for firmware (or scripts) to set these registers as required in place of using hard-coded values which might not be ideal for all platforms. Adam Wallis (2): usb: xhci: add relaxed timing quirk bit usb: host: xhci-plat: check relaxed timing quirk bit Documentation/devicetree/bindings/usb/usb-xhci.txt | 1 + drivers/usb/host/xhci-plat.c | 3 +++ drivers/usb/host/xhci.c| 25 +++--- drivers/usb/host/xhci.h| 1 + 4 files changed, 22 insertions(+), 8 deletions(-) -- Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] typec: tcpm: fusb302: Resolve out of order messaging events
On Tue, Nov 21, 2017 at 02:12:12PM +, Adam Thomson wrote: > The expectation in the FUSB302 driver is that a TX_SUCCESS event > should occur after a message has been sent, but before a GCRCSENT > event is raised to indicate successful receipt of a message from > the partner. However in some circumstances it is possible to see > the hardware raise a GCRCSENT event before a TX_SUCCESS event > is raised. The upshot of this is that the GCRCSENT handling portion > of code ends up reporting the GoodCRC message to TCPM because the > TX_SUCCESS event hasn't yet arrived to trigger a consumption of it. > When TX_SUCCESS is then raised by the chip it ends up consuming the > actual message that was meant for TCPM, and this incorrect sequence > results in a hard reset from TCPM. > > To avoid this problem, this commit updates the message reading > code to check whether a GoodCRC message was received or not. Based > on this check it will either report that the previous transmission > has completed or it will pass the msg data to TCPM for futher > processing. This way the incorrect ordering of the events no longer > matters. > > Signed-off-by: Adam Thomson I am not really happy about the code duplication (two calls to fusb302_pd_read_message() and identical error messages), but everything else I came up with was even more messy, so Reviewed-by: Guenter Roeck > --- > > Changes in v3: > - Always read from FIFO on TX_SUCCES and GCRCSENT events, but decision on how >to report to TCPM is no longer based on these event types but instead on > type >of message read in from FIFO. > > Changes in v2: > - Remove erroneous extended header check > > Patch is based on Linux next-20171114 to include move out of staging. > > drivers/usb/typec/fusb302/fusb302.c | 21 + > 1 file changed, 17 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/typec/fusb302/fusb302.c > b/drivers/usb/typec/fusb302/fusb302.c > index 72cb060..d200085 100644 > --- a/drivers/usb/typec/fusb302/fusb302.c > +++ b/drivers/usb/typec/fusb302/fusb302.c > @@ -1543,6 +1543,21 @@ static int fusb302_pd_read_message(struct fusb302_chip > *chip, > fusb302_log(chip, "PD message header: %x", msg->header); > fusb302_log(chip, "PD message len: %d", len); > > + /* > + * Check if we've read off a GoodCRC message. If so then indicate to > + * TCPM that the previous transmission has completed. Otherwise we pass > + * the received message over to TCPM for processing. > + * > + * We make this check here instead of basing the reporting decision on > + * the IRQ event type, as it's possible for the chip to report the > + * TX_SUCCESS and GCRCSENT events out of order on occasion, so we need > + * to check the message type to ensure correct reporting to TCPM. > + */ > + if ((!len) && (pd_header_type_le(msg->header) == PD_CTRL_GOOD_CRC)) > + tcpm_pd_transmit_complete(chip->tcpm_port, TCPC_TX_SUCCESS); > + else > + tcpm_pd_receive(chip->tcpm_port, msg); > + > return ret; > } > > @@ -1650,13 +1665,12 @@ static irqreturn_t fusb302_irq_intn(int irq, void > *dev_id) > > if (interrupta & FUSB_REG_INTERRUPTA_TX_SUCCESS) { > fusb302_log(chip, "IRQ: PD tx success"); > - /* read out the received good CRC */ > ret = fusb302_pd_read_message(chip, &pd_msg); > if (ret < 0) { > - fusb302_log(chip, "cannot read in GCRC, ret=%d", ret); > + fusb302_log(chip, > + "cannot read in PD message, ret=%d", ret); > goto done; > } > - tcpm_pd_transmit_complete(chip->tcpm_port, TCPC_TX_SUCCESS); > } > > if (interrupta & FUSB_REG_INTERRUPTA_HARDRESET) { > @@ -1677,7 +1691,6 @@ static irqreturn_t fusb302_irq_intn(int irq, void > *dev_id) > "cannot read in PD message, ret=%d", ret); > goto done; > } > - tcpm_pd_receive(chip->tcpm_port, &pd_msg); > } > done: > mutex_unlock(&chip->lock); > -- > 1.9.1 > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] usb: xhci: add relaxed timing quirk bit
On Tue, Nov 21, 2017 at 12:18:09PM -0500, Adam Wallis wrote: > Certain systems may run with CPUs at a very slow frequency. This > patch adds a quirk bit that can be used to relax certain timings, etc. > > This quirk might be needed for other fields in the future, but > initially, it will be used only on the IRQ control register to allow > firmare to control the value of the register. This can prevent an s/firmare/firmware/ By firmware control, you mean the register is initialized on boot and then not touched by the kernel? What if the XHCI block is reset? Not sure if that's possible. > "interrupt storm" effect on certain systems. So now we have 2 ways to deal with this? The existing MediaTek quirk and now this one. I think you should change the existing quirk to a value and set the value based on compatible strings. > Signed-off-by: Adam Wallis > --- > Documentation/devicetree/bindings/usb/usb-xhci.txt | 1 + > drivers/usb/host/xhci.c| 25 > +++--- > drivers/usb/host/xhci.h| 1 + > 3 files changed, 19 insertions(+), 8 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] usb: xhci: add relaxed timing quirk bit
On 11/21/2017 2:11 PM, Rob Herring wrote: > On Tue, Nov 21, 2017 at 12:18:09PM -0500, Adam Wallis wrote: >> Certain systems may run with CPUs at a very slow frequency. This >> patch adds a quirk bit that can be used to relax certain timings, etc. >> >> This quirk might be needed for other fields in the future, but >> initially, it will be used only on the IRQ control register to allow >> firmare to control the value of the register. This can prevent an > > s/firmare/firmware/ > Thanks, good catch. > By firmware control, you mean the register is initialized on boot and > then not touched by the kernel? What if the XHCI block is reset? Not > sure if that's possible. > >> "interrupt storm" effect on certain systems. > > So now we have 2 ways to deal with this? The existing MediaTek quirk and > now this one. I do agree that 2 different ways to deal with it is not ideal. I also think that having one hard-coded value (and one alternate for MTK) is also not ideal. > > I think you should change the existing quirk to a value and set the > value based on compatible strings. I like where you are going with this. Are you saying that I could read for a device property read from firmware (for DTB or ACPI) like DWC3 does for "snps,hird-threshold"? If you mean this, where do you recommend I store the desired IRQ_CONTROL value - in struct xhci_hcd ? Or by "compatible" strings, did you mean storing hard-coded values in the of_device_id usb_xhci_of_match[] array? This would still be hard-coding (which I would like to avoid) and also would not work for the ACPI case. > >> Signed-off-by: Adam Wallis >> --- >> Documentation/devicetree/bindings/usb/usb-xhci.txt | 1 + >> drivers/usb/host/xhci.c| 25 >> +++--- >> drivers/usb/host/xhci.h| 1 + >> 3 files changed, 19 insertions(+), 8 deletions(-) Thanks for the feedback Rob. Adam -- Adam Wallis Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] usb: xhci: add relaxed timing quirk bit
On Tue, Nov 21, 2017 at 1:49 PM, Adam Wallis wrote: > On 11/21/2017 2:11 PM, Rob Herring wrote: >> On Tue, Nov 21, 2017 at 12:18:09PM -0500, Adam Wallis wrote: >>> Certain systems may run with CPUs at a very slow frequency. This >>> patch adds a quirk bit that can be used to relax certain timings, etc. >>> >>> This quirk might be needed for other fields in the future, but >>> initially, it will be used only on the IRQ control register to allow >>> firmare to control the value of the register. This can prevent an >> >> s/firmare/firmware/ >> > > Thanks, good catch. > >> By firmware control, you mean the register is initialized on boot and >> then not touched by the kernel? What if the XHCI block is reset? Not >> sure if that's possible. >> >>> "interrupt storm" effect on certain systems. >> >> So now we have 2 ways to deal with this? The existing MediaTek quirk and >> now this one. > > I do agree that 2 different ways to deal with it is not ideal. I also think > that > having one hard-coded value (and one alternate for MTK) is also not ideal. Agreed. >> >> I think you should change the existing quirk to a value and set the >> value based on compatible strings. > > I like where you are going with this. Are you saying that I could read for a > device property read from firmware (for DTB or ACPI) like DWC3 does for > "snps,hird-threshold"? Is that for the same thing? If so, drop the vendor prefix and use that. Otherwise, a separate property should really be something that is per board rather than per SoC. > If you mean this, where do you recommend I store the > desired IRQ_CONTROL value - in struct xhci_hcd ? No idea. > Or by "compatible" strings, did you mean storing hard-coded values in the > of_device_id usb_xhci_of_match[] array? This would still be hard-coding > (which I > would like to avoid) and also would not work for the ACPI case. ACPI has match tables too? It would only be hardcoded per compatible which should be per SoC. Do you need per board/device tuning? If so, use a property. Rob -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] usb: xhci: add relaxed timing quirk bit
On 11/21/2017 3:06 PM, Rob Herring wrote: [..] >> I like where you are going with this. Are you saying that I could read for a >> device property read from firmware (for DTB or ACPI) like DWC3 does for >> "snps,hird-threshold"? > > Is that for the same thing? If so, drop the vendor prefix and use > that. Otherwise, a separate property should really be something that > is per board rather than per SoC. I don't think that's exactly the same property, but it's the same idea I would prefer to go with. That way, an integer can be passed in via the firmware tables. > >> If you mean this, where do you recommend I store the >> desired IRQ_CONTROL value - in struct xhci_hcd ? > > No idea. > >> Or by "compatible" strings, did you mean storing hard-coded values in the >> of_device_id usb_xhci_of_match[] array? This would still be hard-coding >> (which I >> would like to avoid) and also would not work for the ACPI case. > > ACPI has match tables too? > Yes, you can use DSD in a way that is similar to OF properties > It would only be hardcoded per compatible which should be per SoC. Do > you need per board/device tuning? If so, use a property. > The reason why I think it should dynamic via firmware tables is that * It's much less invasive for vendors to update their DT tables if they need to adjust on a per device/controller/family/etc basis then to adjust a properties table in xhci-plat * This would lead to less polluting in xhci-plat code > Rob > -- > To unsubscribe from this list: send the line "unsubscribe linux-usb" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > I will provide an updated proposed patch sometime this week. I also hope to get some feedback from Mathias to see what he prefers. Thanks again for the feedback Rob. -- Adam Wallis Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: usbip port number limits
Hi Shuah, On Tue, Nov 21, 2017 at 07:33:41AM -0700, Shuah Khan wrote: > > Thanks for finding the problem. usb2 devices don't work at all with the > offending commit: 03cd00d538a6feb0492cd153edf256ef7d7bd95e > > I have been debugging on 4.12 and this bad commit. Low speed devices can be > attached, but you see the following and then shutdown hangs. It sounds horrible. I am really trying to understand the situation. I tested and am testing mouses/keyboards, all of them work. Am I missing something? BTW, now I'm testing over localhost. > I don't believe this commit 03cd00d538a6feb0492cd153edf256ef7d7bd95e tested > well on usb2 devices. and this commit is suspect. It is unfortunate > that it wasn't caught during the patch testing, because it is so easy to > run into this. I used one usb2 device and tried to attach over localhost > and with this patch happens every single time. If it is this commit, chances are it should be not hard to fix, as the patches up to this point simply reorganize data structures. > I am looking into reverting this commit as well as the rest of the usb3 work > that is based on this bad commit as this commit introduced serious regression > for usb2 devices. > > I have reverted the patches on 4.15 base and testing it this week. I will have > to do the same for 4.13 as well. > > usb3 work and this rework patch can be tested well and I can take this > into 4.16 or so once it is is tested on all devices including the finger > print reader - I have a laptop to test this use-case. Sounds good. > My apologies for not catching this earlier. My apologies too. > The bug dmesg as follows: > > [ 2223.046019] kernel BUG at drivers/usb/usbip/vhci_hcd.c:704! Make sure we are on the same page. Is the BUG this one: 683 BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); Thanks, Yuyang -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: usbip port number limits
Hi Juan, On Tue, Nov 21, 2017 at 12:24:01PM +0100, Juan Zea wrote: > Please excuse me... I have reported two different problems in this post, > and I think things are mixing up a bit. My bad. I've found two different > problems: > > 1.- When compiling vhci driver with multiple hubs (in latest kernel), usbip > tool doesn't seem able to "jump" to the second controller. As far as I > understand, it seems to be a problem with high speed devices trying to get > connected to super speed ports. I made a patch for avoiding this situation > which is almost the same as the one you just sent. Both patches work. I can > compile with several hubs of one port, and connect two devices via usbip and > the second gets connected to the second controller (skipping the super speed > port of first controller). > > 2.- The problem is some of these devices don't work, whatsoever controller or > hub compiling configuration I do. A fingerprint reader and also recently > discovered flash usb sticks don't work either. You can connect them with > usbip tool, and they list with lsusb with no problem at all. But when you try > to use them, you get this "kernel BUG at drivers/usb/usbip/vhci_hcd.c:669!" > (by the way, the line number has changed in the latest pull from master I've > just tested, but it's the same line of code). This second problem is the one > I bisected in my last message. And I got to the commit > 03cd00d538a6feb0492cd153edf256ef7d7bd95e, in which both devices stop working. It'd be good if you can give greater detail of the exact (as much info as possible) setting of the fingerprint reader case. > The patch you sent fixes 1 but not 2. And yes, I'm using non-super-speed > devices for testing. This was what I understood. Just want to make sure we are on the same page. > I hope this helped, and sorry for the mess, Yes, it helped. My sincere apologies for the mess I created! Thanks, Yuyang -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html