From 8ed3b80af8ccf3fc043d95f86ed88f60856a8809 Mon Sep 17 00:00:00 2001 From: Prashanth K Date: Thu, 7 Jul 2022 10:55:00 +0530 Subject: [PATCH] usb: phy: Add driver support for overriding qmp phy sequence Added driver support to override SS phy init sequence from device tree. Phy override sequence can be added using "qcom,qmp-phy-override-seq" property on DT file. And this property takes array of Reg-Value pairs. Override seq is appended to init seq, and the resultant merged seq is used to initialize the QMP phy. Change-Id: If6898ef0d25f433bed36ecd9cfb5bb74e14ac63d Signed-off-by: Prashanth K --- drivers/usb/phy/phy-msm-ssusb-qmp.c | 39 +++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/usb/phy/phy-msm-ssusb-qmp.c b/drivers/usb/phy/phy-msm-ssusb-qmp.c index eba24f2bb181..e32d8952fe53 100644 --- a/drivers/usb/phy/phy-msm-ssusb-qmp.c +++ b/drivers/usb/phy/phy-msm-ssusb-qmp.c @@ -139,7 +139,7 @@ struct msm_ssphy_qmp { bool in_suspend; u32 *phy_reg; /* revision based offset */ int reg_offset_cnt; - u32 *qmp_phy_init_seq; + struct qmp_reg_val *qmp_phy_init_seq; int init_seq_len; bool invert_ps_polarity; enum qmp_phy_type phy_type; @@ -359,19 +359,17 @@ put_gdsc: return rc < 0 ? rc : 0; } -static int configure_phy_regs(struct usb_phy *uphy, - const struct qmp_reg_val *reg) +static int configure_phy_regs(struct msm_ssphy_qmp *phy) { - struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp, - phy); + struct qmp_reg_val *reg = phy->qmp_phy_init_seq; int i; if (!reg) { - dev_err(uphy->dev, "NULL PHY configuration\n"); + dev_err(phy->phy.dev, "NULL PHY configuration\n"); return -EINVAL; } - for (i = 0; i < phy->init_seq_len/2; i++) { + for (i = 0; i < phy->init_seq_len; i++) { writel_relaxed(reg->val, phy->base + reg->offset); reg++; } @@ -507,7 +505,6 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy) phy); int ret; unsigned int init_timeout_usec = INIT_MAX_TIME_USEC; - const struct qmp_reg_val *reg = NULL; dev_dbg(uphy->dev, "Initializing QMP phy\n"); @@ -537,10 +534,8 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy) /* power up PHY */ usb_qmp_powerup_phy(phy); - reg = (struct qmp_reg_val *)phy->qmp_phy_init_seq; - /* Main configuration */ - ret = configure_phy_regs(uphy, reg); + ret = configure_phy_regs(phy); if (ret) { dev_err(uphy->dev, "Failed the main PHY configuration\n"); goto fail; @@ -937,7 +932,7 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev) struct msm_ssphy_qmp *phy; struct device *dev = &pdev->dev; struct resource *res; - int ret = 0, size = 0, len; + int ret = 0, size = 0, size1 = 0, len; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) @@ -1057,15 +1052,27 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev) return -EINVAL; } - phy->qmp_phy_init_seq = devm_kzalloc(dev, size, GFP_KERNEL); + of_get_property(dev->of_node, "qcom,qmp-phy-override-seq", &size1); + if (size1 % sizeof(*phy->qmp_phy_init_seq)) { + dev_err(dev, "invalid override seq len\n"); + return -EINVAL; + } + + len = size + size1; + phy->qmp_phy_init_seq = devm_kzalloc(dev, len, GFP_KERNEL); if (!phy->qmp_phy_init_seq) return -ENOMEM; - phy->init_seq_len = (size / sizeof(*phy->qmp_phy_init_seq)); + phy->init_seq_len = (len / sizeof(*phy->qmp_phy_init_seq)); of_property_read_u32_array(dev->of_node, "qcom,qmp-phy-init-seq", - phy->qmp_phy_init_seq, - phy->init_seq_len); + (u32 *)phy->qmp_phy_init_seq, + size / sizeof(u32)); + + of_property_read_u32_array(dev->of_node, + "qcom,qmp-phy-override-seq", + (u32 *)((char *)phy->qmp_phy_init_seq + size), + size1 / sizeof(u32)); } else { dev_err(dev, "error need qmp-phy-init-seq\n"); return -EINVAL;