From: Dmitry Osipenko <digetx@gmail.com>
To: Jon Hunter <jonathanh@nvidia.com>,
Thierry Reding <thierry.reding@gmail.com>
Cc: linux-arm-kernel@lists.infradead.org,
linux-tegra@vger.kernel.org, stable@vger.kernel.org,
Peter De Schrijver <pdeschrijver@nvidia.com>
Subject: Re: [PATCH] ARM: tegra: Fix restoration of PLLM when exiting suspend
Date: Tue, 17 Dec 2019 17:28:08 +0300 [thread overview]
Message-ID: <57264acd-2623-9e9f-53c6-3b4cd3991315@gmail.com> (raw)
In-Reply-To: <6ee48145-7315-4283-ae56-fbf00b00f16b@nvidia.com>
17.12.2019 17:19, Jon Hunter пишет:
>
> On 10/12/2019 20:29, Dmitry Osipenko wrote:
>> 10.12.2019 22:28, Dmitry Osipenko пишет:
>>> Hello Jon,
>>>
>>> 10.12.2019 13:37, Jon Hunter пишет:
>>>> The suspend entry and exit code for 32-bit Tegra devices assumes that
>>>> the PLLM (which is used to provide the clock for external memory)
>>>> is always enabled on entry to suspend. Hence, the current code always
>>>> disables the PLLM on entry to suspend and re-enables the PLLM on exit
>>>> from suspend.
>>>>
>>>> Since the introduction of the Tegra124 EMC driver by commit 73a7f0a90641
>>>> ("memory: tegra: Add EMC (external memory controller) driver"), which is
>>>> used to scale the EMC frequency, PLLM may not be the current clock
>>>> source for the EMC on entry to suspend and hence may not be enabled.
>>>> Always enabling the PLLM on exit from suspend can cause the actual
>>>> status on the PLL to be different from that reported by the common clock
>>>> framework.
>>>>
>>>> On kernels prior to v4.5, the code to set the rate of the PLLM had a
>>>> test to verify if the PLL was enabled and if the PLL was enabled,
>>>> setting the rate would fail. Since commit 267b62a96951
>>>> ("clk: tegra: pll: Update PLLM handling") the test to see if PLLM is
>>>> enabled was removed.
>>>>
>>>> With these earlier kernels, if the PLLM is disabled on entering suspend
>>>> and the EMC driver attempts to set the parent of the EMC clock to the
>>>> PLLM on exiting suspend, then the set rate for the PLLM will fail and in
>>>> turn cause the resume to fail.
>>>>
>>>> We should not be re-enabling the PLLM on resume from suspend unless it
>>>> was enabled on entry to suspend. Therefore, fix this by saving the state
>>>> of PLLM on entry to suspend and only re-enable it, if it was already
>>>> enabled.
>>>>
>>>> Fixes: 73a7f0a90641 ("memory: tegra: Add EMC (external memory controller) driver")
>>>> Cc: stable@vger.kernel.org
>>>>
>>>> Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
>>>> ---
>>>> arch/arm/mach-tegra/sleep-tegra30.S | 33 +++++++++++++++++++++++------
>>>> 1 file changed, 27 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
>>>> index 3341a12bbb9c..c2f0793a424f 100644
>>>> --- a/arch/arm/mach-tegra/sleep-tegra30.S
>>>> +++ b/arch/arm/mach-tegra/sleep-tegra30.S
>>>> @@ -337,26 +337,42 @@ ENTRY(tegra30_lp1_reset)
>>>> add r1, r1, #2
>>>> wait_until r1, r7, r3
>>>>
>>>> - /* enable PLLM via PMC */
>>>> + /* restore PLLM state */
>>>> mov32 r2, TEGRA_PMC_BASE
>>>> + adr r7, tegra_pllm_status
>>>> + ldr r1, [r7]
>>>> + cmp r2, #(1 << 12)
>>>> + bne _skip_pllm
>>>> +
>>>> ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
>>>> orr r1, r1, #(1 << 12)
>>>> str r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
>>>>
>>>> pll_enable r1, r0, CLK_RESET_PLLM_BASE, 0
>>>> + pll_locked r1, r0, CLK_RESET_PLLM_BASE
>>>> +
>>>> +_skip_pllm:
>>>> pll_enable r1, r0, CLK_RESET_PLLC_BASE, 0
>>>> pll_enable r1, r0, CLK_RESET_PLLX_BASE, 0
>>>>
>>>> b _pll_m_c_x_done
>>>>
>>>> _no_pll_iddq_exit:
>>>> - /* enable PLLM via PMC */
>>>> + /* restore PLLM state */
>>>> mov32 r2, TEGRA_PMC_BASE
>>>> + adr r7, tegra_pllm_status
>>>> + ldr r1, [r7]
>>>> + cmp r2, #(1 << 12)
>>>> + bne _skip_pllm_no_iddq
>>>> +
>>>> ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
>>>> orr r1, r1, #(1 << 12)
>>>> str r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
>>>>
>>>> pll_enable r1, r0, CLK_RESET_PLLM_BASE, CLK_RESET_PLLM_MISC
>>>> + pll_locked r1, r0, CLK_RESET_PLLM_BASE
>>>> +
>>>> +_skip_pllm_no_iddq:
>>>> pll_enable r1, r0, CLK_RESET_PLLC_BASE, CLK_RESET_PLLC_MISC
>>>> pll_enable r1, r0, CLK_RESET_PLLX_BASE, CLK_RESET_PLLX_MISC
>>>>
>>>> @@ -364,7 +380,6 @@ _pll_m_c_x_done:
>>>> pll_enable r1, r0, CLK_RESET_PLLP_BASE, CLK_RESET_PLLP_MISC
>>>> pll_enable r1, r0, CLK_RESET_PLLA_BASE, CLK_RESET_PLLA_MISC
>>>>
>>>> - pll_locked r1, r0, CLK_RESET_PLLM_BASE
>>>> pll_locked r1, r0, CLK_RESET_PLLP_BASE
>>>> pll_locked r1, r0, CLK_RESET_PLLA_BASE
>>>> pll_locked r1, r0, CLK_RESET_PLLC_BASE
>>>> @@ -526,6 +541,8 @@ __no_dual_emc_chanl:
>>>> ENDPROC(tegra30_lp1_reset)
>>>>
>>>> .align L1_CACHE_SHIFT
>>>> +tegra_pllm_status:
>>>> + .word 0
>>>> tegra30_sdram_pad_address:
>>>> .word TEGRA_EMC_BASE + EMC_CFG @0x0
>>>> .word TEGRA_EMC_BASE + EMC_ZCAL_INTERVAL @0x4
>>>> @@ -624,10 +641,14 @@ tegra30_switch_cpu_to_clk32k:
>>>> add r1, r1, #2
>>>> wait_until r1, r7, r9
>>>
>>>
>>>> - /* disable PLLM via PMC in LP1 */
>>>> + /* disable PLLM, if enabled, via PMC in LP1 */
>>>> + adr r1, tegra_pllm_status
>>>> ldr r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
>>>> - bic r0, r0, #(1 << 12)
>>>> - str r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
>>>> + and r2, r0, #(1 << 12)
>>>> + str r2, [r1]
>>>> + cmp r2, #(1 << 12)
>>>> + biceq r0, r0, #(1 << 12)
>>>> + streq r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
>>>>
>>>> /* disable PLLP, PLLA, PLLC and PLLX */
>>>> ldr r0, [r5, #CLK_RESET_PLLP_BASE]
>>>
>>> PLLM's enable-status could be defined either by PMC or CaR. Thus at
>>> first you need to check whether PMC overrides CaR's enable and then
>>> judge the enable state based on PMC or CaR state respectively.
>>>
>>
>> Actually, now I think that it doesn't make sense to check PMC WB0 state
>> at all. IIUC, PLLM's state of the WB0 register defines whether Boot ROM
>> should enable PLLM on resume from suspend. Thus it will be correct to
>> check only the CaR's enable-state of PLLM.
>
> Thanks for pointing this out and sorry for the delay. However, I am not
> sure I agree that we should not check this at all. If the override bit
> is set, then we do want to check the state from the PMC register and if
> it is not then we should just use the PLLM register itself.
Sorry if I wasn't clear.. my point is that the PMC's override register
bit doesn't reflect the PLLM's enable-state. The PLLM could be disabled
while PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE bit is set.
The CaR's PLLM enable-state reflects the actual hardware state. At least
that's what I see on T30.
>> Looks like it is a bit of nonsense that clk_pll_is_enabled() checks
>> PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE for judging of the enable-state. This
>> is not the first time I'm getting confused by it, perhaps will be
>> worthwhile to clean up that part of the clk driver's code (if I'm not
>> missing something).
>
> That code looks fine to me. I just think this code entering and exiting
> suspend needs to be fixed. I will re-work this fix.
>
> Jon
>
next prev parent reply other threads:[~2019-12-17 14:28 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-10 10:37 [PATCH] ARM: tegra: Fix restoration of PLLM when exiting suspend Jon Hunter
2019-12-10 12:09 ` Thierry Reding
2019-12-10 14:29 ` Jon Hunter
2019-12-10 14:32 ` Jon Hunter
2019-12-10 19:28 ` Dmitry Osipenko
2019-12-10 20:29 ` Dmitry Osipenko
2019-12-11 8:50 ` Peter De Schrijver
2019-12-12 22:18 ` Dmitry Osipenko
2019-12-17 14:19 ` Jon Hunter
2019-12-17 14:28 ` Dmitry Osipenko [this message]
[not found] ` <57264acd-2623-9e9f-53c6-3b4cd3991315-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2020-06-12 15:20 ` Dmitry Osipenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=57264acd-2623-9e9f-53c6-3b4cd3991315@gmail.com \
--to=digetx@gmail.com \
--cc=jonathanh@nvidia.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-tegra@vger.kernel.org \
--cc=pdeschrijver@nvidia.com \
--cc=stable@vger.kernel.org \
--cc=thierry.reding@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox