Re: [PATCH v16 08/40] gpu: host1x: Add initial runtime PM and OPP support

Dmitry Osipenko
2021-12-22T19:01:08Z

22.12.2021 21:41, Jon Hunter пишет:
>
> On 22/12/2021 09:47, Jon Hunter wrote:
>>
>> On 21/12/2021 20:58, Dmitry Osipenko wrote:
>>> Hi,
>>>
>>> Thank you for testing it all.
>>>
>>> 21.12.2021 21:55, Jon Hunter пишет:
>>>> Hi Dmitry, Thierry,
>>>>
>>>> On 30/11/2021 23:23, Dmitry Osipenko wrote:
>>>>> Add runtime PM and OPP support to the Host1x driver. For the
>>>>> starter we
>>>>> will keep host1x always-on because dynamic power management require a
>>>>> major
>>>>> refactoring of the driver code since lot's of code paths are
>>>>> missing the
>>>>> RPM handling and we're going to remove some of these paths in the
>>>>> future.
>>>>
>>>>
>>>> Unfortunately, this change is breaking boot on Tegra186. Bisect points
>>>> to this and reverting on top of -next gets the board booting again.
>>>> Sadly, there is no panic or error reported, it is just a hard hang. I
>>>> will not have time to look at this this week and so we may need to
>>>> revert for the moment.
>>>
>>> Only T186 broken? What about T194?
>>
>> Yes interestingly only Tegra186 and no other board.
>>
>>> Which board model fails to boot? Is it running in hypervisor mode?
>>
>> This is Jetson TX2. No hypervisor.
>>
>>> Do you use any additional patches?
>>
>> No just plain -next. The tests run every day on top of tree.
>>
>>> Could you please test the below diff? I suspect that
>>> host1x_syncpt_save/restore may be entirely broken for T186 since we
>>> never used these funcs before.
>>>
>>> --- >8 ---
>>>
>>> diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
>>> index f5b4dcded088..fd5dfb875422 100644
>>> --- a/drivers/gpu/host1x/dev.c
>>> +++ b/drivers/gpu/host1x/dev.c
>>> @@ -580,7 +580,6 @@ static int __maybe_unused
>>> host1x_runtime_suspend(struct device *dev)
>>>       int err;
>>>
>>>       host1x_intr_stop(host);
>>> -    host1x_syncpt_save(host);
>>>
>>>       err = reset_control_bulk_assert(host->nresets, host->resets);
>>>       if (err) {
>>> @@ -596,9 +595,8 @@ static int __maybe_unused
>>> host1x_runtime_suspend(struct device *dev)
>>>       return 0;
>>>
>>>   resume_host1x:
>>> -    host1x_setup_sid_table(host);
>>> -    host1x_syncpt_restore(host);
>>>       host1x_intr_start(host);
>>> +    host1x_setup_sid_table(host);
>>>
>>>       return err;
>>>   }
>>> @@ -626,9 +624,8 @@ static int __maybe_unused
>>> host1x_runtime_resume(struct device *dev)
>>>           goto disable_clk;
>>>       }
>>>
>>> -    host1x_setup_sid_table(host);
>>> -    host1x_syncpt_restore(host);
>>>       host1x_intr_start(host);
>>> +    host1x_setup_sid_table(host);
>>
>>
>> Thanks! Will try this later, once the next bisect is finished :-)
>
> I tested the above, but this did not fix it. It still hangs on boot.

Thank you, now I see where the problem should be. Apparently host1x is
disabled at a boot time on T186 and we touch h/w before RPM is resumed.

Could you please revert the above change and try this instead:

diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
index e08e331e46ae..8194826c9ce3 100644
--- a/drivers/gpu/host1x/syncpt.c
+++ b/drivers/gpu/host1x/syncpt.c
@@ -137,6 +137,15 @@ void host1x_syncpt_restore(struct host1x *host)
struct host1x_syncpt *sp_base = host->syncpt;
unsigned int i;

+ for (i = 0; i < host->info->nb_pts; i++) {
+ /*
+ * Unassign syncpt from channels for purposes of Tegra186
+ * syncpoint protection. This prevents any channel from
+ * accessing it until it is reassigned.
+ */
+ host1x_hw_syncpt_assign_to_channel(host, sp_base + i, NULL);
+ }
+
for (i = 0; i < host1x_syncpt_nb_pts(host); i++)
host1x_hw_syncpt_restore(host, sp_base + i);

@@ -352,13 +361,6 @@ int host1x_syncpt_init(struct host1x *host)
for (i = 0; i < host->info->nb_pts; i++) {
syncpt[i].id = i;
syncpt[i].host = host;
-
- /*
- * Unassign syncpt from channels for purposes of Tegra186
- * syncpoint protection. This prevents any channel from
- * accessing it until it is reassigned.
- */
- host1x_hw_syncpt_assign_to_channel(host, &syncpt[i], NULL);
}

for (i = 0; i < host->info->nb_bases; i++)