aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy/qualcomm/phy-qcom-qmp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-08 13:03:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-08 13:03:52 -0400
commit132d68d37d33f1d0b9c1f507c8b4d64c27ecec8a (patch)
treeb3c05972e5579e1574873fe745fb1358c62a269c /drivers/phy/qualcomm/phy-qcom-qmp.c
parent80f232121b69cc69a31ccb2b38c1665d770b0710 (diff)
parent3515468a87a47781f6af818773650513ff14656a (diff)
Merge tag 'usb-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY updates from Greg KH: "Here is the big set of USB and PHY driver patches for 5.2-rc1 There is the usual set of: - USB gadget updates - PHY driver updates and additions - USB serial driver updates and fixes - typec updates and new chips supported - mtu3 driver updates - xhci driver updates - other tiny driver updates Nothing really interesting, just constant forward progress. All of these have been in linux-next for a while with no reported issues. The usb-gadget and usb-serial trees were merged a bit "late", but both of them had been in linux-next before they got merged here last Friday" * tag 'usb-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (206 commits) USB: serial: f81232: implement break control USB: serial: f81232: add high baud rate support USB: serial: f81232: clear overrun flag USB: serial: f81232: fix interrupt worker not stop usb: dwc3: Rename DWC3_DCTL_LPM_ERRATA usb: dwc3: Fix default lpm_nyet_threshold value usb: dwc3: debug: Print GET_STATUS(device) tracepoint usb: dwc3: Do core validation early on probe usb: dwc3: gadget: Set lpm_capable usb: gadget: atmel: tie wake lock to running clock usb: gadget: atmel: support USB suspend usb: gadget: atmel_usba_udc: simplify setting of interrupt-enabled mask dwc2: gadget: Fix completed transfer size calculation in DDMA usb: dwc2: Set lpm mode parameters depend on HW configuration usb: dwc2: Fix channel disable flow usb: dwc2: Set actual frame number for completed ISOC transfer usb: gadget: do not use __constant_cpu_to_le16 usb: dwc2: gadget: Increase descriptors count for ISOC's usb: introduce usb_ep_type_string() function usb: dwc3: move synchronize_irq() out of the spinlock protected block ...
Diffstat (limited to 'drivers/phy/qualcomm/phy-qcom-qmp.c')
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp.c222
1 files changed, 165 insertions, 57 deletions
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 08d6f6f7f039..cd91b4179b10 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -242,6 +242,88 @@ static const struct qmp_phy_init_tbl msm8996_pcie_pcs_tbl[] = {
242 QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0x0e), 242 QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0x0e),
243}; 243};
244 244
245static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
246 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
247 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
248 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x0f),
249 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
250 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
251 QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
252 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
253 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
254 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
255 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER1, 0xff),
256 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_TIMER2, 0x3f),
257 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
258 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
259 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
260 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_EP_DIV, 0x19),
261 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x90),
262 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
263 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x03),
264 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x55),
265 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x55),
266 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
267 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0d),
268 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x04),
269 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
270 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x08),
271 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
272 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x34),
273 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
274 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x33),
275 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
276 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x07),
277 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x04),
278 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
279 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
280 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x09),
281 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
282 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x40),
283 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
284 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x02),
285 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
286 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x7e),
287 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x15),
288};
289
290static const struct qmp_phy_init_tbl msm8998_pcie_tx_tbl[] = {
291 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x02),
292 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
293 QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
294 QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
295};
296
297static const struct qmp_phy_init_tbl msm8998_pcie_rx_tbl[] = {
298 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
299 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x1c),
300 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
301 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0a),
302 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
303 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
304 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
305 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x04),
306 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN_HALF, 0x04),
307 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x00),
308 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
309 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
310 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x71),
311 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x40),
312};
313
314static const struct qmp_phy_init_tbl msm8998_pcie_pcs_tbl[] = {
315 QMP_PHY_INIT_CFG(QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE, 0x04),
316 QMP_PHY_INIT_CFG(QPHY_V3_PCS_OSC_DTCT_ACTIONS, 0x00),
317 QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x01),
318 QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
319 QMP_PHY_INIT_CFG(QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x20),
320 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00),
321 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
322 QMP_PHY_INIT_CFG(QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
323 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x99),
324 QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
325};
326
245static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl[] = { 327static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl[] = {
246 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14), 328 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
247 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), 329 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
@@ -897,6 +979,7 @@ struct qmp_phy {
897 * @init_count: phy common block initialization count 979 * @init_count: phy common block initialization count
898 * @phy_initialized: indicate if PHY has been initialized 980 * @phy_initialized: indicate if PHY has been initialized
899 * @mode: current PHY mode 981 * @mode: current PHY mode
982 * @ufs_reset: optional UFS PHY reset handle
900 */ 983 */
901struct qcom_qmp { 984struct qcom_qmp {
902 struct device *dev; 985 struct device *dev;
@@ -914,6 +997,8 @@ struct qcom_qmp {
914 int init_count; 997 int init_count;
915 bool phy_initialized; 998 bool phy_initialized;
916 enum phy_mode mode; 999 enum phy_mode mode;
1000
1001 struct reset_control *ufs_reset;
917}; 1002};
918 1003
919static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) 1004static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
@@ -1146,6 +1231,31 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
1146 .no_pcs_sw_reset = true, 1231 .no_pcs_sw_reset = true,
1147}; 1232};
1148 1233
1234static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
1235 .type = PHY_TYPE_PCIE,
1236 .nlanes = 1,
1237
1238 .serdes_tbl = msm8998_pcie_serdes_tbl,
1239 .serdes_tbl_num = ARRAY_SIZE(msm8998_pcie_serdes_tbl),
1240 .tx_tbl = msm8998_pcie_tx_tbl,
1241 .tx_tbl_num = ARRAY_SIZE(msm8998_pcie_tx_tbl),
1242 .rx_tbl = msm8998_pcie_rx_tbl,
1243 .rx_tbl_num = ARRAY_SIZE(msm8998_pcie_rx_tbl),
1244 .pcs_tbl = msm8998_pcie_pcs_tbl,
1245 .pcs_tbl_num = ARRAY_SIZE(msm8998_pcie_pcs_tbl),
1246 .clk_list = msm8996_phy_clk_l,
1247 .num_clks = ARRAY_SIZE(msm8996_phy_clk_l),
1248 .reset_list = ipq8074_pciephy_reset_l,
1249 .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
1250 .vreg_list = qmp_phy_vreg_l,
1251 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
1252 .regs = pciephy_regs_layout,
1253
1254 .start_ctrl = SERDES_START | PCS_START,
1255 .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
1256 .mask_com_pcs_ready = PCS_READY,
1257};
1258
1149static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { 1259static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
1150 .type = PHY_TYPE_USB3, 1260 .type = PHY_TYPE_USB3,
1151 .nlanes = 1, 1261 .nlanes = 1,
@@ -1314,6 +1424,7 @@ static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp)
1314 return 0; 1424 return 0;
1315 } 1425 }
1316 1426
1427 reset_control_assert(qmp->ufs_reset);
1317 if (cfg->has_phy_com_ctrl) { 1428 if (cfg->has_phy_com_ctrl) {
1318 qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL], 1429 qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
1319 SERDES_START | PCS_START); 1430 SERDES_START | PCS_START);
@@ -1335,8 +1446,7 @@ static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp)
1335 return 0; 1446 return 0;
1336} 1447}
1337 1448
1338/* PHY Initialization */ 1449static int qcom_qmp_phy_enable(struct phy *phy)
1339static int qcom_qmp_phy_init(struct phy *phy)
1340{ 1450{
1341 struct qmp_phy *qphy = phy_get_drvdata(phy); 1451 struct qmp_phy *qphy = phy_get_drvdata(phy);
1342 struct qcom_qmp *qmp = qphy->qmp; 1452 struct qcom_qmp *qmp = qphy->qmp;
@@ -1351,6 +1461,33 @@ static int qcom_qmp_phy_init(struct phy *phy)
1351 1461
1352 dev_vdbg(qmp->dev, "Initializing QMP phy\n"); 1462 dev_vdbg(qmp->dev, "Initializing QMP phy\n");
1353 1463
1464 if (cfg->no_pcs_sw_reset) {
1465 /*
1466 * Get UFS reset, which is delayed until now to avoid a
1467 * circular dependency where UFS needs its PHY, but the PHY
1468 * needs this UFS reset.
1469 */
1470 if (!qmp->ufs_reset) {
1471 qmp->ufs_reset =
1472 devm_reset_control_get_exclusive(qmp->dev,
1473 "ufsphy");
1474
1475 if (IS_ERR(qmp->ufs_reset)) {
1476 ret = PTR_ERR(qmp->ufs_reset);
1477 dev_err(qmp->dev,
1478 "failed to get UFS reset: %d\n",
1479 ret);
1480
1481 qmp->ufs_reset = NULL;
1482 return ret;
1483 }
1484 }
1485
1486 ret = reset_control_assert(qmp->ufs_reset);
1487 if (ret)
1488 goto err_lane_rst;
1489 }
1490
1354 ret = qcom_qmp_phy_com_init(qphy); 1491 ret = qcom_qmp_phy_com_init(qphy);
1355 if (ret) 1492 if (ret)
1356 return ret; 1493 return ret;
@@ -1383,14 +1520,9 @@ static int qcom_qmp_phy_init(struct phy *phy)
1383 cfg->rx_tbl, cfg->rx_tbl_num); 1520 cfg->rx_tbl, cfg->rx_tbl_num);
1384 1521
1385 qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num); 1522 qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
1386 1523 ret = reset_control_deassert(qmp->ufs_reset);
1387 /* 1524 if (ret)
1388 * UFS PHY requires the deassert of software reset before serdes start. 1525 goto err_lane_rst;
1389 * For UFS PHYs that do not have software reset control bits, defer
1390 * starting serdes until the power on callback.
1391 */
1392 if ((cfg->type == PHY_TYPE_UFS) && cfg->no_pcs_sw_reset)
1393 goto out;
1394 1526
1395 /* 1527 /*
1396 * Pull out PHY from POWER DOWN state. 1528 * Pull out PHY from POWER DOWN state.
@@ -1403,7 +1535,9 @@ static int qcom_qmp_phy_init(struct phy *phy)
1403 usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max); 1535 usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
1404 1536
1405 /* Pull PHY out of reset state */ 1537 /* Pull PHY out of reset state */
1406 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 1538 if (!cfg->no_pcs_sw_reset)
1539 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1540
1407 if (cfg->has_phy_dp_com_ctrl) 1541 if (cfg->has_phy_dp_com_ctrl)
1408 qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET); 1542 qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
1409 1543
@@ -1420,11 +1554,10 @@ static int qcom_qmp_phy_init(struct phy *phy)
1420 goto err_pcs_ready; 1554 goto err_pcs_ready;
1421 } 1555 }
1422 qmp->phy_initialized = true; 1556 qmp->phy_initialized = true;
1423 1557 return 0;
1424out:
1425 return ret;
1426 1558
1427err_pcs_ready: 1559err_pcs_ready:
1560 reset_control_assert(qmp->ufs_reset);
1428 clk_disable_unprepare(qphy->pipe_clk); 1561 clk_disable_unprepare(qphy->pipe_clk);
1429err_clk_enable: 1562err_clk_enable:
1430 if (cfg->has_lane_rst) 1563 if (cfg->has_lane_rst)
@@ -1435,7 +1568,7 @@ err_lane_rst:
1435 return ret; 1568 return ret;
1436} 1569}
1437 1570
1438static int qcom_qmp_phy_exit(struct phy *phy) 1571static int qcom_qmp_phy_disable(struct phy *phy)
1439{ 1572{
1440 struct qmp_phy *qphy = phy_get_drvdata(phy); 1573 struct qmp_phy *qphy = phy_get_drvdata(phy);
1441 struct qcom_qmp *qmp = qphy->qmp; 1574 struct qcom_qmp *qmp = qphy->qmp;
@@ -1463,44 +1596,6 @@ static int qcom_qmp_phy_exit(struct phy *phy)
1463 return 0; 1596 return 0;
1464} 1597}
1465 1598
1466static int qcom_qmp_phy_poweron(struct phy *phy)
1467{
1468 struct qmp_phy *qphy = phy_get_drvdata(phy);
1469 struct qcom_qmp *qmp = qphy->qmp;
1470 const struct qmp_phy_cfg *cfg = qmp->cfg;
1471 void __iomem *pcs = qphy->pcs;
1472 void __iomem *status;
1473 unsigned int mask, val;
1474 int ret = 0;
1475
1476 if (cfg->type != PHY_TYPE_UFS)
1477 return 0;
1478
1479 /*
1480 * For UFS PHY that has not software reset control, serdes start
1481 * should only happen when UFS driver explicitly calls phy_power_on
1482 * after it deasserts software reset.
1483 */
1484 if (cfg->no_pcs_sw_reset && !qmp->phy_initialized &&
1485 (qmp->init_count != 0)) {
1486 /* start SerDes and Phy-Coding-Sublayer */
1487 qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
1488
1489 status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
1490 mask = cfg->mask_pcs_ready;
1491
1492 ret = readl_poll_timeout(status, val, !(val & mask), 1,
1493 PHY_INIT_COMPLETE_TIMEOUT);
1494 if (ret) {
1495 dev_err(qmp->dev, "phy initialization timed-out\n");
1496 return ret;
1497 }
1498 qmp->phy_initialized = true;
1499 }
1500
1501 return ret;
1502}
1503
1504static int qcom_qmp_phy_set_mode(struct phy *phy, 1599static int qcom_qmp_phy_set_mode(struct phy *phy,
1505 enum phy_mode mode, int submode) 1600 enum phy_mode mode, int submode)
1506{ 1601{
@@ -1750,9 +1845,15 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
1750} 1845}
1751 1846
1752static const struct phy_ops qcom_qmp_phy_gen_ops = { 1847static const struct phy_ops qcom_qmp_phy_gen_ops = {
1753 .init = qcom_qmp_phy_init, 1848 .init = qcom_qmp_phy_enable,
1754 .exit = qcom_qmp_phy_exit, 1849 .exit = qcom_qmp_phy_disable,
1755 .power_on = qcom_qmp_phy_poweron, 1850 .set_mode = qcom_qmp_phy_set_mode,
1851 .owner = THIS_MODULE,
1852};
1853
1854static const struct phy_ops qcom_qmp_ufs_ops = {
1855 .power_on = qcom_qmp_phy_enable,
1856 .power_off = qcom_qmp_phy_disable,
1756 .set_mode = qcom_qmp_phy_set_mode, 1857 .set_mode = qcom_qmp_phy_set_mode,
1757 .owner = THIS_MODULE, 1858 .owner = THIS_MODULE,
1758}; 1859};
@@ -1763,6 +1864,7 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
1763 struct qcom_qmp *qmp = dev_get_drvdata(dev); 1864 struct qcom_qmp *qmp = dev_get_drvdata(dev);
1764 struct phy *generic_phy; 1865 struct phy *generic_phy;
1765 struct qmp_phy *qphy; 1866 struct qmp_phy *qphy;
1867 const struct phy_ops *ops = &qcom_qmp_phy_gen_ops;
1766 char prop_name[MAX_PROP_NAME]; 1868 char prop_name[MAX_PROP_NAME];
1767 int ret; 1869 int ret;
1768 1870
@@ -1849,7 +1951,10 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
1849 } 1951 }
1850 } 1952 }
1851 1953
1852 generic_phy = devm_phy_create(dev, np, &qcom_qmp_phy_gen_ops); 1954 if (qmp->cfg->type == PHY_TYPE_UFS)
1955 ops = &qcom_qmp_ufs_ops;
1956
1957 generic_phy = devm_phy_create(dev, np, ops);
1853 if (IS_ERR(generic_phy)) { 1958 if (IS_ERR(generic_phy)) {
1854 ret = PTR_ERR(generic_phy); 1959 ret = PTR_ERR(generic_phy);
1855 dev_err(dev, "failed to create qphy %d\n", ret); 1960 dev_err(dev, "failed to create qphy %d\n", ret);
@@ -1873,6 +1978,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
1873 .compatible = "qcom,msm8996-qmp-usb3-phy", 1978 .compatible = "qcom,msm8996-qmp-usb3-phy",
1874 .data = &msm8996_usb3phy_cfg, 1979 .data = &msm8996_usb3phy_cfg,
1875 }, { 1980 }, {
1981 .compatible = "qcom,msm8998-qmp-pcie-phy",
1982 .data = &msm8998_pciephy_cfg,
1983 }, {
1876 .compatible = "qcom,msm8998-qmp-ufs-phy", 1984 .compatible = "qcom,msm8998-qmp-ufs-phy",
1877 .data = &sdm845_ufsphy_cfg, 1985 .data = &sdm845_ufsphy_cfg,
1878 }, { 1986 }, {