Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: qcom-qmp-usb: add support for updated sc8280xp binding

Add support for the new SC8280XP binding.

Note that the binding does not try to describe every register subregion
and instead the driver holds the corresponding offsets. This includes
the PCS_USB region which was initially overlooked.

Note that the driver will no longer accept the old binding due to the
fixed "phy_phy" reset name.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20221028160435.26948-14-johan+linaro@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Johan Hovold and committed by
Vinod Koul
c0a6c252 183462e8

+67 -15
+67 -15
drivers/phy/qualcomm/phy-qcom-qmp-usb.c
··· 1414 1414 QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x21), 1415 1415 }; 1416 1416 1417 + struct qmp_usb_offsets { 1418 + u16 serdes; 1419 + u16 pcs; 1420 + u16 pcs_usb; 1421 + u16 tx; 1422 + u16 rx; 1423 + }; 1424 + 1417 1425 /* struct qmp_phy_cfg - per-PHY initialization config */ 1418 1426 struct qmp_phy_cfg { 1419 1427 int lanes; 1428 + 1429 + const struct qmp_usb_offsets *offsets; 1420 1430 1421 1431 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */ 1422 1432 const struct qmp_phy_init_tbl *serdes_tbl; ··· 1558 1548 "vdda-phy", "vdda-pll", 1559 1549 }; 1560 1550 1551 + static const struct qmp_usb_offsets qmp_usb_offsets_v5 = { 1552 + .serdes = 0, 1553 + .pcs = 0x0200, 1554 + .pcs_usb = 0x1200, 1555 + .tx = 0x0e00, 1556 + .rx = 0x1000, 1557 + }; 1558 + 1561 1559 static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = { 1562 1560 .lanes = 1, 1563 1561 ··· 1655 1637 static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = { 1656 1638 .lanes = 1, 1657 1639 1640 + .offsets = &qmp_usb_offsets_v5, 1641 + 1658 1642 .serdes_tbl = sc8280xp_usb3_uniphy_serdes_tbl, 1659 1643 .serdes_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_serdes_tbl), 1660 1644 .tx_tbl = sc8280xp_usb3_uniphy_tx_tbl, ··· 1667 1647 .pcs_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_pcs_tbl), 1668 1648 .clk_list = qmp_v4_phy_clk_l, 1669 1649 .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l), 1670 - .reset_list = msm8996_usb3phy_reset_l, 1671 - .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), 1650 + .reset_list = qcm2290_usb3phy_reset_l, 1651 + .num_resets = ARRAY_SIZE(qcm2290_usb3phy_reset_l), 1672 1652 .vreg_list = qmp_phy_vreg_l, 1673 1653 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1674 1654 .regs = qmp_v4_usb3phy_regs_layout, 1675 - .pcs_usb_offset = 0x1000, 1676 1655 }; 1677 1656 1678 1657 static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = { ··· 2480 2461 return 0; 2481 2462 } 2482 2463 2464 + static int qmp_usb_parse_dt(struct qmp_usb *qmp) 2465 + { 2466 + struct platform_device *pdev = to_platform_device(qmp->dev); 2467 + const struct qmp_phy_cfg *cfg = qmp->cfg; 2468 + const struct qmp_usb_offsets *offs = cfg->offsets; 2469 + struct device *dev = qmp->dev; 2470 + void __iomem *base; 2471 + 2472 + if (!offs) 2473 + return -EINVAL; 2474 + 2475 + base = devm_platform_ioremap_resource(pdev, 0); 2476 + if (IS_ERR(base)) 2477 + return PTR_ERR(base); 2478 + 2479 + qmp->serdes = base + offs->serdes; 2480 + qmp->pcs = base + offs->pcs; 2481 + qmp->pcs_usb = base + offs->pcs_usb; 2482 + qmp->tx = base + offs->tx; 2483 + qmp->rx = base + offs->rx; 2484 + 2485 + qmp->pipe_clk = devm_clk_get(dev, "pipe"); 2486 + if (IS_ERR(qmp->pipe_clk)) { 2487 + return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), 2488 + "failed to get pipe clock\n"); 2489 + } 2490 + 2491 + return 0; 2492 + } 2493 + 2483 2494 static int qmp_usb_probe(struct platform_device *pdev) 2484 2495 { 2485 2496 struct device *dev = &pdev->dev; 2486 - struct device_node *child; 2487 2497 struct phy_provider *phy_provider; 2498 + struct device_node *np; 2488 2499 struct qmp_usb *qmp; 2489 2500 int ret; 2490 2501 ··· 2540 2491 if (ret) 2541 2492 return ret; 2542 2493 2543 - child = of_get_next_available_child(dev->of_node, NULL); 2544 - if (!child) 2545 - return -EINVAL; 2494 + /* Check for legacy binding with child node. */ 2495 + np = of_get_next_available_child(dev->of_node, NULL); 2496 + if (np) { 2497 + ret = qmp_usb_parse_dt_legacy(qmp, np); 2498 + } else { 2499 + np = of_node_get(dev->of_node); 2500 + ret = qmp_usb_parse_dt(qmp); 2501 + } 2502 + if (ret) 2503 + goto err_node_put; 2546 2504 2547 2505 pm_runtime_set_active(dev); 2548 2506 ret = devm_pm_runtime_enable(dev); ··· 2561 2505 */ 2562 2506 pm_runtime_forbid(dev); 2563 2507 2564 - ret = qmp_usb_parse_dt_legacy(qmp, child); 2508 + ret = phy_pipe_clk_register(qmp, np); 2565 2509 if (ret) 2566 2510 goto err_node_put; 2567 2511 2568 - ret = phy_pipe_clk_register(qmp, child); 2569 - if (ret) 2570 - goto err_node_put; 2571 - 2572 - qmp->phy = devm_phy_create(dev, child, &qmp_usb_phy_ops); 2512 + qmp->phy = devm_phy_create(dev, np, &qmp_usb_phy_ops); 2573 2513 if (IS_ERR(qmp->phy)) { 2574 2514 ret = PTR_ERR(qmp->phy); 2575 2515 dev_err(dev, "failed to create PHY: %d\n", ret); ··· 2574 2522 2575 2523 phy_set_drvdata(qmp->phy, qmp); 2576 2524 2577 - of_node_put(child); 2525 + of_node_put(np); 2578 2526 2579 2527 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 2580 2528 2581 2529 return PTR_ERR_OR_ZERO(phy_provider); 2582 2530 2583 2531 err_node_put: 2584 - of_node_put(child); 2532 + of_node_put(np); 2585 2533 return ret; 2586 2534 } 2587 2535