Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753200AbdHTQS2 (ORCPT ); Sun, 20 Aug 2017 12:18:28 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:33117 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753101AbdHTQS0 (ORCPT ); Sun, 20 Aug 2017 12:18:26 -0400 Subject: Re: [PATCH 1/4] gpu: host1x: Enable Tegra186 syncpoint protection To: Mikko Perttunen , thierry.reding@gmail.com, jonathanh@nvidia.com Cc: dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org References: <20170818161553.27597-1-mperttunen@nvidia.com> <20170818161553.27597-2-mperttunen@nvidia.com> From: Dmitry Osipenko Message-ID: <7db4c129-81aa-6f41-1b98-c301d057facf@gmail.com> Date: Sun, 20 Aug 2017 19:18:22 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.0 MIME-Version: 1.0 In-Reply-To: <20170818161553.27597-2-mperttunen@nvidia.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4886 Lines: 138 On 18.08.2017 19:15, Mikko Perttunen wrote: > Since Tegra186 the Host1x hardware allows syncpoints to be assigned to > specific channels, preventing any other channels from incrementing > them. > > Enable this feature where available and assign syncpoints to channels > when submitting a job. Syncpoints are currently never unassigned from > channels since that would require extra work and is unnecessary with > the current channel allocation model. > > Signed-off-by: Mikko Perttunen > --- > drivers/gpu/host1x/dev.h | 16 ++++++++++++++++ > drivers/gpu/host1x/hw/channel_hw.c | 3 +++ > drivers/gpu/host1x/hw/syncpt_hw.c | 26 ++++++++++++++++++++++++++ > drivers/gpu/host1x/syncpt.c | 3 +++ > 4 files changed, 48 insertions(+) > > diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h > index def802c0a6bf..2432a30ff6e2 100644 > --- a/drivers/gpu/host1x/dev.h > +++ b/drivers/gpu/host1x/dev.h > @@ -79,6 +79,9 @@ struct host1x_syncpt_ops { > u32 (*load)(struct host1x_syncpt *syncpt); > int (*cpu_incr)(struct host1x_syncpt *syncpt); > int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr); > + void (*assign_channel)(struct host1x_syncpt *syncpt, > + struct host1x_channel *channel); > + void (*set_protection)(struct host1x *host, bool enabled); > }; > > struct host1x_intr_ops { > @@ -186,6 +189,19 @@ static inline int host1x_hw_syncpt_patch_wait(struct host1x *host, > return host->syncpt_op->patch_wait(sp, patch_addr); > } > > +static inline void host1x_hw_syncpt_assign_channel(struct host1x *host, > + struct host1x_syncpt *sp, > + struct host1x_channel *ch) > +{ > + return host->syncpt_op->assign_channel(sp, ch); > +} > + > +static inline void host1x_hw_syncpt_set_protection(struct host1x *host, > + bool enabled) > +{ > + return host->syncpt_op->set_protection(host, enabled); > +} > + > static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm, > void (*syncpt_thresh_work)(struct work_struct *)) > { > 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); > + > 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..5d117ab1699e 100644 > --- a/drivers/gpu/host1x/hw/syncpt_hw.c > +++ b/drivers/gpu/host1x/hw/syncpt_hw.c > @@ -106,6 +106,30 @@ static int syncpt_patch_wait(struct host1x_syncpt *sp, void *patch_addr) > return 0; > } > > +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 > +} > + > +static void syncpt_set_protection(struct host1x *host, bool enabled) > +{ > +#if HOST1X_HW >= 6 > + host1x_hypervisor_writel(host, > + enabled ? HOST1X_HV_SYNCPT_PROT_EN_CH_EN : 0, > + 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 +137,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, > + .set_protection = syncpt_set_protection, > }; > diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c > index 048ac9e344ce..fe4d963b3e2a 100644 > --- a/drivers/gpu/host1x/syncpt.c > +++ b/drivers/gpu/host1x/syncpt.c > @@ -398,6 +398,8 @@ int host1x_syncpt_init(struct host1x *host) > for (i = 0; i < host->info->nb_pts; i++) { > syncpt[i].id = i; > syncpt[i].host = host; > + > + host1x_hw_syncpt_assign_channel(host, &syncpt[i], NULL); > } > > for (i = 0; i < host->info->nb_bases; i++) > @@ -408,6 +410,7 @@ int host1x_syncpt_init(struct host1x *host) > host->bases = bases; > > host1x_syncpt_restore(host); > + host1x_hw_syncpt_set_protection(host, true); Since protection is never disabled maybe something like host1x_hw_syncpt_enable_protection() would fit a bit better. > > /* Allocate sync point to use for clearing waits for expired fences */ > host->nop_sp = host1x_syncpt_alloc(host, NULL, 0); > -- Dmitry