Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 702027a1 authored by Hemant Kumar's avatar Hemant Kumar
Browse files

usb: xhci-msm-hsic: Handle periph_on signal for hsic system clk



Due to HW connectivity bug driver needs to force periph_on signal
on to prevent hsic core memory to go to retention mode when hsic
is active. Hence enable force-on mode for periph_on signal when
hsic is active and disable it upon entering low power mode.

Also, disable hsic system clk as the last clock upon hsic suspend
and enable hsic clocks in reverse order upon resume.

CRs-Fixed: 581297
Change-Id: I47c38c9e8654505ffebc8605b5198de6589da164
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent 8d806f01
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -230,6 +230,9 @@ static int mxhci_hsic_init_clocks(struct mxhci_hsic_hcd *mxhci, u32 init)
		goto out;
	}

	/* enable force-on mode for periph_on */
	clk_set_flags(mxhci->system_clk, CLKFLAG_RETAIN_PERIPH);

	ret = clk_prepare_enable(mxhci->core_clk);
	if (ret) {
		dev_err(mxhci->dev, "failed to enable core_clk\n");
@@ -588,11 +591,11 @@ static int mxhci_hsic_suspend(struct mxhci_hsic_hcd *mxhci)

	init_completion(&mxhci->phy_in_lpm);

	clk_disable_unprepare(mxhci->system_clk);
	clk_disable_unprepare(mxhci->core_clk);
	clk_disable_unprepare(mxhci->utmi_clk);
	clk_disable_unprepare(mxhci->hsic_clk);
	clk_disable_unprepare(mxhci->cal_clk);
	clk_disable_unprepare(mxhci->system_clk);

	ret = regulator_set_voltage(mxhci->hsic_vddcx, mxhci->vdd_no_vol_level,
			mxhci->vdd_high_vol_level);
@@ -614,6 +617,9 @@ static int mxhci_hsic_suspend(struct mxhci_hsic_hcd *mxhci)
		enable_irq(mxhci->wakeup_irq);
	}

	/* disable force-on mode for periph_on */
	clk_set_flags(mxhci->system_clk, CLKFLAG_NORETAIN_PERIPH);

	pm_relax(mxhci->dev);

	dev_dbg(mxhci->dev, "HSIC-USB in low power mode\n");
@@ -635,6 +641,9 @@ static int mxhci_hsic_resume(struct mxhci_hsic_hcd *mxhci)

	pm_stay_awake(mxhci->dev);

	/* enable force-on mode for periph_on */
	clk_set_flags(mxhci->system_clk, CLKFLAG_RETAIN_PERIPH);

	if (mxhci->bus_perf_client) {
		mxhci->bus_vote = true;
		queue_work(mxhci->wq, &mxhci->bus_vote_w);
@@ -660,11 +669,12 @@ static int mxhci_hsic_resume(struct mxhci_hsic_hcd *mxhci)
		dev_err(mxhci->dev,
			"unable to set nominal vddcx voltage (no VDD MIN)\n");


	clk_prepare_enable(mxhci->system_clk);
	clk_prepare_enable(mxhci->core_clk);
	clk_prepare_enable(mxhci->utmi_clk);
	clk_prepare_enable(mxhci->hsic_clk);
	clk_prepare_enable(mxhci->cal_clk);
	clk_prepare_enable(mxhci->hsic_clk);
	clk_prepare_enable(mxhci->utmi_clk);
	clk_prepare_enable(mxhci->core_clk);

	if (mxhci->wakeup_irq)
		usb_hcd_resume_root_hub(hcd);