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

usb: phy: msm: Vote for corner of VDD CX instead of voltage of VDD CX

New platform uses RBCPR hardware feature, with that voting for
absolute voltage of VDD CX is not required. Hence vote for corner of
VDD CX which uses nominal corner voltage on VDD CX.

Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
Cc: Mayank Rana <mrana@codeaurora.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>

authored by

Ivan T. Ivanov and committed by
Felipe Balbi
01799b62 349907c2

+33 -8
+5
Documentation/devicetree/bindings/usb/msm-hsusb.txt
··· 65 65 Some platforms may have configuration to allow USB 66 66 controller work with any of the two HSPHYs present. 67 67 68 + - qcom,vdd-levels: This property must be a list of three integer values 69 + (no, min, max) where each value represents either a voltage 70 + in microvolts or a value corresponding to voltage corner. 71 + 68 72 Example HSUSB OTG controller device node: 69 73 70 74 usb@f9a55000 { ··· 91 87 92 88 qcom,otg-control = <1>; 93 89 qcom,phy-init-sequence = < -1 0x63 >; 90 + qcom,vdd-levels = <1 5 7>; 94 91 };
+27 -8
drivers/usb/phy/phy-msm-usb.c
··· 62 62 63 63 #define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ 64 64 #define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ 65 + #define USB_PHY_SUSP_DIG_VOL 500000 /* uV */ 66 + 67 + enum vdd_levels { 68 + VDD_LEVEL_NONE = 0, 69 + VDD_LEVEL_MIN, 70 + VDD_LEVEL_MAX, 71 + }; 65 72 66 73 static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) 67 74 { ··· 76 69 77 70 if (init) { 78 71 ret = regulator_set_voltage(motg->vddcx, 79 - USB_PHY_VDD_DIG_VOL_MIN, 80 - USB_PHY_VDD_DIG_VOL_MAX); 72 + motg->vdd_levels[VDD_LEVEL_MIN], 73 + motg->vdd_levels[VDD_LEVEL_MAX]); 81 74 if (ret) { 82 75 dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); 83 76 return ret; ··· 88 81 dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); 89 82 } else { 90 83 ret = regulator_set_voltage(motg->vddcx, 0, 91 - USB_PHY_VDD_DIG_VOL_MAX); 84 + motg->vdd_levels[VDD_LEVEL_MAX]); 92 85 if (ret) 93 86 dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); 94 87 ret = regulator_disable(motg->vddcx); ··· 442 435 443 436 #ifdef CONFIG_PM 444 437 445 - #define USB_PHY_SUSP_DIG_VOL 500000 446 438 static int msm_hsusb_config_vddcx(struct msm_otg *motg, int high) 447 439 { 448 - int max_vol = USB_PHY_VDD_DIG_VOL_MAX; 440 + int max_vol = motg->vdd_levels[VDD_LEVEL_MAX]; 449 441 int min_vol; 450 442 int ret; 451 443 452 444 if (high) 453 - min_vol = USB_PHY_VDD_DIG_VOL_MIN; 445 + min_vol = motg->vdd_levels[VDD_LEVEL_MIN]; 454 446 else 455 - min_vol = USB_PHY_SUSP_DIG_VOL; 447 + min_vol = motg->vdd_levels[VDD_LEVEL_NONE]; 456 448 457 449 ret = regulator_set_voltage(motg->vddcx, min_vol, max_vol); 458 450 if (ret) { ··· 1447 1441 struct device_node *node = pdev->dev.of_node; 1448 1442 struct property *prop; 1449 1443 int len, ret, words; 1450 - u32 val; 1444 + u32 val, tmp[3]; 1451 1445 1452 1446 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 1453 1447 if (!pdata) ··· 1477 1471 1478 1472 if (!of_property_read_u32(node, "qcom,phy-num", &val) && val < 2) 1479 1473 motg->phy_number = val; 1474 + 1475 + motg->vdd_levels[VDD_LEVEL_NONE] = USB_PHY_SUSP_DIG_VOL; 1476 + motg->vdd_levels[VDD_LEVEL_MIN] = USB_PHY_VDD_DIG_VOL_MIN; 1477 + motg->vdd_levels[VDD_LEVEL_MAX] = USB_PHY_VDD_DIG_VOL_MAX; 1478 + 1479 + if (of_get_property(node, "qcom,vdd-levels", &len) && 1480 + len == sizeof(tmp)) { 1481 + of_property_read_u32_array(node, "qcom,vdd-levels", 1482 + tmp, len / sizeof(*tmp)); 1483 + motg->vdd_levels[VDD_LEVEL_NONE] = tmp[VDD_LEVEL_NONE]; 1484 + motg->vdd_levels[VDD_LEVEL_MIN] = tmp[VDD_LEVEL_MIN]; 1485 + motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX]; 1486 + } 1480 1487 1481 1488 prop = of_find_property(node, "qcom,phy-init-sequence", &len); 1482 1489 if (!prop || !len)
+1
include/linux/usb/msm_hsusb.h
··· 169 169 170 170 struct reset_control *phy_rst; 171 171 struct reset_control *link_rst; 172 + int vdd_levels[3]; 172 173 }; 173 174 174 175 #endif