Re: [PATCH v2 1/6] gpu: host1x: Enable Tegra186 syncpoint protection
From: Dmitry Osipenko
Date: Fri Sep 22 2017 - 19:18:08 EST
On 22.09.2017 17:02, Mikko Perttunen wrote:
> On 09/05/2017 04:33 PM, Dmitry Osipenko wrote:
>> On 05.09.2017 11:10, Mikko Perttunen wrote:
>>> ... >> diff --git a/drivers/gpu/host1x/hw/channel_hw.c
> b/drivers/gpu/host1x/hw/channel_hw.c
>>> index 8447a56c41ca..0161da331702 100644
>>> --- a/drivers/gpu/host1x/hw/channel_hw.c
>>> +++ b/drivers/gpu/host1x/hw/channel_hw.c
>>> @@ -147,6 +147,9 @@ static int channel_submit(struct host1x_job *job)
>>> Â ÂÂÂÂÂ syncval = host1x_syncpt_incr_max(sp, user_syncpt_incrs);
>>> Â +ÂÂÂ /* assign syncpoint to channel */
>>> +ÂÂÂ host1x_hw_syncpt_assign_channel(host, sp, ch);
>>
>> This function could be renamed to host1x_hw_assign_syncpt_to_channel() and then
>> comment to it won't be needed.
>
> Maybe host1x_hw_syncpt_assign_to_channel? I'd like to keep the current noun_verb
> format. Though IMHO even the current name is pretty descriptive in itself.
>
That variant sounds good to me as well.
>>
>> It is not very nice that channel would be re-assigned on each submit. Maybe that
>> assignment should be done by host1x_syncpt_request() ?
>
> host1x_syncpt_request doesn't know about the channel so we'd have to thread this
> information there and through each client driver in drm/tegra/, so I decided not
> to do this at this time. I'm planning a new channel allocation model which will
> change that side of the code anyway, so I'd like to revisit this at that point.
> For our current channel model, the current implementation doesn't have any
> functional downsides anyway.
>
Another very minor downside is that it causes an extra dummy invocation on
pre-Tegra186. Of course that could be changed later in a follow-up patch, not a
big deal :)
>>
>>> +
>>> ÂÂÂÂÂ job->syncpt_end = syncval;
>>> Â ÂÂÂÂÂ /* add a setclass for modules that require it */
>>> diff --git a/drivers/gpu/host1x/hw/syncpt_hw.c
>>> b/drivers/gpu/host1x/hw/syncpt_hw.c
>>> index 7b0270d60742..dc7a44614fef 100644
>>> --- a/drivers/gpu/host1x/hw/syncpt_hw.c
>>> +++ b/drivers/gpu/host1x/hw/syncpt_hw.c
>>> @@ -106,6 +106,50 @@ static int syncpt_patch_wait(struct host1x_syncpt *sp,
>>> void *patch_addr)
>>> ÂÂÂÂÂ return 0;
>>> Â }
>>> Â +/**
>>> + * syncpt_assign_channel() - Assign syncpoint to channel
>>> + * @sp: syncpoint
>>> + * @ch: channel
>>> + *
>>> + * On chips with the syncpoint protection feature (Tegra186+), assign @sp to
>>> + * @ch, preventing other channels from incrementing the syncpoints. If @ch is
>>> + * NULL, unassigns the syncpoint.
>>> + *
>>> + * On older chips, do nothing.
>>> + */
>>> +static void syncpt_assign_channel(struct host1x_syncpt *sp,
>>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ struct host1x_channel *ch)
>>> +{
>>> +#if HOST1X_HW >= 6
>>> +ÂÂÂ struct host1x *host = sp->host;
>>> +
>>> +ÂÂÂ if (!host->hv_regs)
>>> +ÂÂÂÂÂÂÂ return;
>>> +
>>> +ÂÂÂ host1x_sync_writel(host,
>>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ HOST1X_SYNC_SYNCPT_CH_APP_CH(ch ? ch->id : 0xff),
>>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ HOST1X_SYNC_SYNCPT_CH_APP(sp->id));
>>> +#endif
>>> +}
>>> +
>>> +/**
>>> + * syncpt_enable_protection() - Enable syncpoint protection
>>> + * @host: host1x instance
>>> + *
>>> + * On chips with the syncpoint protection feature (Tegra186+), enable this
>>> + * feature. On older chips, do nothing.
>>> + */
>>> +static void syncpt_enable_protection(struct host1x *host)
>>> +{
>>> +#if HOST1X_HW >= 6
>>> +ÂÂÂ if (!host->hv_regs)
>>> +ÂÂÂÂÂÂÂ return;
>>> +
>>> +ÂÂÂ host1x_hypervisor_writel(host, HOST1X_HV_SYNCPT_PROT_EN_CH_EN,
>>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ HOST1X_HV_SYNCPT_PROT_EN);
>>> +#endif
>>> +}
>>> +
>>> Â static const struct host1x_syncpt_ops host1x_syncpt_ops = {
>>> ÂÂÂÂÂ .restore = syncpt_restore,
>>> ÂÂÂÂÂ .restore_wait_base = syncpt_restore_wait_base,
>>> @@ -113,4 +157,6 @@ static const struct host1x_syncpt_ops host1x_syncpt_ops = {
>>> ÂÂÂÂÂ .load = syncpt_load,
>>> ÂÂÂÂÂ .cpu_incr = syncpt_cpu_incr,
>>> ÂÂÂÂÂ .patch_wait = syncpt_patch_wait,
>>> +ÂÂÂ .assign_channel = syncpt_assign_channel,
>>> +ÂÂÂ .enable_protection = syncpt_enable_protection,
>>> Â };
>>> diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
>>> index 048ac9e344ce..4c7a4c8b2ad2 100644
>>> --- a/drivers/gpu/host1x/syncpt.c
>>> +++ b/drivers/gpu/host1x/syncpt.c
>>> @@ -398,6 +398,13 @@ 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_channel(host, &syncpt[i], NULL);
>>> ÂÂÂÂÂ }
>>> Â ÂÂÂÂÂ for (i = 0; i < host->info->nb_bases; i++)
>>> @@ -408,6 +415,7 @@ int host1x_syncpt_init(struct host1x *host)
>>> ÂÂÂÂÂ host->bases = bases;
>>> Â ÂÂÂÂÂ host1x_syncpt_restore(host);
>>> +ÂÂÂ host1x_hw_syncpt_enable_protection(host);
>>> Â ÂÂÂÂÂ /* Allocate sync point to use for clearing waits for expired fences */
>>> ÂÂÂÂÂ host->nop_sp = host1x_syncpt_alloc(host, NULL, 0);
>>>
>>
>>
--
Dmitry