]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: host: add h/w supported syncpoint range APIs
authorDeepak Nibade <dnibade@nvidia.com>
Mon, 16 Mar 2015 13:57:44 +0000 (19:27 +0530)
committerSachin Nikam <snikam@nvidia.com>
Mon, 30 Mar 2015 06:36:48 +0000 (23:36 -0700)
Add new field "nb_hw_pts" to struct host1x_device_info to store
the number of syncpoints supported in h/w
Already existing field "nb_pts" is used to store the number of
syncpoints supported in s/w
Hence, nb_pts <= nb_hw_pts

Add below API get "nb_hw_pts"
nvhost_syncpt_nb_hw_pts()

Add below API to check if syncpoint id is within h/w supported
syncpoint range
nvhost_syncpt_is_valid_hw_pt(id) which checks if
0 <= id < nb_hw_pts

Note that existing API nvhost_syncpt_is_valid_pt(id) checks if
pts_base <= id < pts_limit

Use nvhost_syncpt_nb_hw_pts() whereever we want to allocate
resources for syncpoints i.e. we allocate syncpoint resources
for all the syncpoints supported in h/w

Use nvhost_syncpt_is_valid_hw_pt() where it is fine to use
relaxed syncpt check (syncpt read/wait etc.)
Else use nvhost_syncpt_is_valid__pt() where we need to restrict
access to syncpoint supported in s/w only

Bug 1611482

Change-Id: I009028b81bcf1fa80b64f64a9372bec0e96d96f7
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/719039
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
13 files changed:
drivers/video/tegra/host/host1x/host1x.c
drivers/video/tegra/host/host1x/host1x.h
drivers/video/tegra/host/host1x/host1x_channel.c
drivers/video/tegra/host/host1x/host1x_intr.c
drivers/video/tegra/host/nvhost_cdma.c
drivers/video/tegra/host/nvhost_intr.c
drivers/video/tegra/host/nvhost_job.c
drivers/video/tegra/host/nvhost_sync.c
drivers/video/tegra/host/nvhost_syncpt.c
drivers/video/tegra/host/nvhost_syncpt.h
drivers/video/tegra/host/t124/t124.c
drivers/video/tegra/host/t210/t210.c
drivers/video/tegra/host/vhost/vhost_intr.c

index 36230b97daffd49a598988c2bade7c7ec64308d2..7d29909ed89f56293d9aa48a0bb35f051bebf7e9 100644 (file)
@@ -130,7 +130,7 @@ static int nvhost_ctrlopen(struct inode *inode, struct file *filp)
 static int nvhost_ioctl_ctrl_syncpt_read(struct nvhost_ctrl_userctx *ctx,
        struct nvhost_ctrl_syncpt_read_args *args)
 {
-       if (!nvhost_syncpt_is_valid_pt(&ctx->dev->syncpt, args->id))
+       if (!nvhost_syncpt_is_valid_hw_pt(&ctx->dev->syncpt, args->id))
                return -EINVAL;
        args->value = nvhost_syncpt_read(&ctx->dev->syncpt, args->id);
        trace_nvhost_ioctl_ctrl_syncpt_read(args->id, args->value);
@@ -152,7 +152,7 @@ static int nvhost_ioctl_ctrl_syncpt_waitex(struct nvhost_ctrl_userctx *ctx,
 {
        u32 timeout;
        int err;
-       if (!nvhost_syncpt_is_valid_pt(&ctx->dev->syncpt, args->id))
+       if (!nvhost_syncpt_is_valid_hw_pt(&ctx->dev->syncpt, args->id))
                return -EINVAL;
        if (args->timeout == NVHOST_NO_TIMEOUT)
                /* FIXME: MAX_SCHEDULE_TIMEOUT is ulong which can be bigger
@@ -177,7 +177,7 @@ static int nvhost_ioctl_ctrl_syncpt_waitmex(struct nvhost_ctrl_userctx *ctx,
        ulong timeout;
        int err;
        struct timespec ts;
-       if (!nvhost_syncpt_is_valid_pt(&ctx->dev->syncpt, args->id))
+       if (!nvhost_syncpt_is_valid_hw_pt(&ctx->dev->syncpt, args->id))
                return -EINVAL;
        if (args->timeout == NVHOST_NO_TIMEOUT)
                timeout = MAX_SCHEDULE_TIMEOUT;
@@ -227,7 +227,8 @@ static int nvhost_ioctl_ctrl_sync_fence_create(struct nvhost_ctrl_userctx *ctx,
        }
 
        for (i = 0; i < args->num_pts; i++) {
-               if (!nvhost_syncpt_is_valid_pt(&ctx->dev->syncpt, pts[i].id)) {
+               if (!nvhost_syncpt_is_valid_hw_pt(&ctx->dev->syncpt,
+                                       pts[i].id)) {
                        err = -EINVAL;
                        goto out;
                }
@@ -386,7 +387,7 @@ static int nvhost_ioctl_ctrl_get_version(struct nvhost_ctrl_userctx *ctx,
 static int nvhost_ioctl_ctrl_syncpt_read_max(struct nvhost_ctrl_userctx *ctx,
        struct nvhost_ctrl_syncpt_read_args *args)
 {
-       if (!nvhost_syncpt_is_valid_pt(&ctx->dev->syncpt, args->id))
+       if (!nvhost_syncpt_is_valid_hw_pt(&ctx->dev->syncpt, args->id))
                return -EINVAL;
        args->value = nvhost_syncpt_read_max(&ctx->dev->syncpt, args->id);
        return 0;
@@ -702,7 +703,7 @@ static int nvhost_alloc_resources(struct nvhost_master *host)
                return err;
 
        host->intr.syncpt = kzalloc(sizeof(struct nvhost_intr_syncpt) *
-                                   nvhost_syncpt_nb_pts(&host->syncpt),
+                                   nvhost_syncpt_nb_hw_pts(&host->syncpt),
                                    GFP_KERNEL);
 
        if (!host->intr.syncpt) {
index 8c9e527a3bbd7af2912e7ab0622ba8506556e67e..59a97edb83d4589984a2fe96da9a951de00f9fc9 100644 (file)
@@ -65,7 +65,10 @@ struct host1x_device_info {
        enum nvhost_channel_policy channel_policy; /* host1x: channel policy */
 
        /* Syncpoint info */
-       int             nb_pts;         /* host1x: num syncpoints supported */
+       int             nb_hw_pts;      /* host1x: num syncpoints supported
+                                          in h/w */
+       int             nb_pts;         /* host1x: num syncpoints supported
+                                          in s/w where nb_pts <= nb_hw_pts */
        int             pts_base;       /* host1x: syncpoint base */
        int             pts_limit;      /* host1x: syncpoint limit */
        enum nvhost_syncpt_policy syncpt_policy; /* host1x: syncpoint policy */
index 9d6268bb46a9947bf566311bbc2df2dd5dfa29ca..7d59b93114307521aa0feaea939a48b5772dd598 100644 (file)
@@ -130,7 +130,7 @@ static void add_sync_waits(struct nvhost_channel *ch, int fd)
                u32 id;
                pt = container_of(pos, struct sync_pt, pt_list);
                id = nvhost_sync_pt_id(pt);
-               if (!id || !nvhost_syncpt_is_valid_pt(sp, id)) {
+               if (!id || !nvhost_syncpt_is_valid_hw_pt(sp, id)) {
                        sync_fence_put(fence);
                        return;
                }
index 9763479fe2fa1c1d1a91a8b9b31ceaacc4f2d9cd..18406dd0519f7e8f2e9f0341be021ebf8967a651 100644 (file)
@@ -54,7 +54,8 @@ static irqreturn_t syncpt_thresh_cascade_isr(int irq, void *dev_id)
 
        ktime_get_ts(&isr_recv);
 
-       for (i = 0; i < DIV_ROUND_UP(dev->info.nb_pts, 32); i++) {
+       for (i = 0; i < DIV_ROUND_UP(nvhost_syncpt_nb_hw_pts(&dev->syncpt), 32);
+                       i++) {
                reg = readl(sync_regs +
                                host1x_sync_syncpt_thresh_cpu0_int_status_r() +
                                i * REGISTER_STRIDE);
@@ -65,9 +66,11 @@ static irqreturn_t syncpt_thresh_cascade_isr(int irq, void *dev_id)
                        int graphics_host_sp =
                                nvhost_syncpt_graphics_host_sp(&dev->syncpt);
 
-                       if (unlikely(sp_id >= dev->info.nb_pts)) {
+                       if (unlikely(!nvhost_syncpt_is_valid_hw_pt(&dev->syncpt,
+                                       sp_id))) {
                                dev_err(&dev->dev->dev, "%s(): syncpoint id %d is beyond the number of syncpoints (%d)\n",
-                                       __func__, sp_id, dev->info.nb_pts);
+                                       __func__, sp_id,
+                                       nvhost_syncpt_nb_hw_pts(&dev->syncpt));
                                goto out;
                        }
 
@@ -101,7 +104,7 @@ static void t20_intr_init_host_sync(struct nvhost_intr *intr)
 
        intr_op().disable_all_syncpt_intrs(intr);
 
-       for (i = 0; i < dev->info.nb_pts; i++)
+       for (i = 0; i < nvhost_syncpt_nb_hw_pts(&dev->syncpt); i++)
                INIT_WORK(&intr->syncpt[i].work, syncpt_thresh_cascade_fn);
 
        err = request_irq(intr->syncpt_irq,
@@ -176,8 +179,8 @@ static void t20_intr_disable_all_syncpt_intrs(struct nvhost_intr *intr)
        void __iomem *sync_regs = dev->sync_aperture;
        u32 reg;
 
-       for (reg = 0; reg < bit_word(dev->info.nb_pts) * REGISTER_STRIDE;
-                       reg += REGISTER_STRIDE) {
+       for (reg = 0; reg < bit_word(nvhost_syncpt_nb_hw_pts(&dev->syncpt))
+                       * REGISTER_STRIDE; reg += REGISTER_STRIDE) {
                /* disable interrupts for both cpu's */
                writel(0xffffffffu, sync_regs +
                                host1x_sync_syncpt_thresh_int_disable_r() +
@@ -331,21 +334,23 @@ static int intr_debug_dump(struct nvhost_intr *intr, struct output *o)
                readl(sync_regs + host1x_sync_intmask_r()));
 
        nvhost_debug_output(o, "\n---- host syncpt irq mask ----\n\n");
-       for (i = 0; i < DIV_ROUND_UP(dev->info.nb_pts, 16); i++)
+       for (i = 0; i < DIV_ROUND_UP(nvhost_syncpt_nb_hw_pts(&dev->syncpt), 16);
+                       i++)
                nvhost_debug_output(o, "syncpt_thresh_int_mask(%d) = 0x%08x\n",
                        i, readl(sync_regs +
                                host1x_sync_syncpt_thresh_int_mask_r() +
                                i * REGISTER_STRIDE));
 
        nvhost_debug_output(o, "\n---- host syncpt irq status ----\n\n");
-       for (i = 0; i < DIV_ROUND_UP(dev->info.nb_pts, 32); i++)
+       for (i = 0; i < DIV_ROUND_UP(nvhost_syncpt_nb_hw_pts(&dev->syncpt), 32);
+                       i++)
                nvhost_debug_output(o, "syncpt_thresh_cpu0_int_status(%d) = 0x%08x\n",
                        i, readl(sync_regs +
                                host1x_sync_syncpt_thresh_cpu0_int_status_r() +
                                i * REGISTER_STRIDE));
 
        nvhost_debug_output(o, "\n---- host syncpt thresh ----\n\n");
-       for (i = 0; i < dev->info.nb_pts; i++) {
+       for (i = 0; i < nvhost_syncpt_nb_hw_pts(&dev->syncpt); i++) {
                u32 reg = readl(sync_regs +
                                host1x_sync_syncpt_thresh_int_mask_r() +
                                bit_word(i * 2) * REGISTER_STRIDE);
index b28ada63cf3e29bd66583a16217b6d7e27d9056a..4cc878257b77b64293652f3259a5dd1783833439 100644 (file)
@@ -264,7 +264,7 @@ void nvhost_cdma_update_sync_queue(struct nvhost_cdma *cdma,
 {
        u32 get_restart;
        struct nvhost_job *job = NULL;
-       int nb_pts = nvhost_syncpt_nb_pts(syncpt);
+       int nb_pts = nvhost_syncpt_nb_hw_pts(syncpt);
        DECLARE_BITMAP(syncpt_used, nb_pts);
 
        bitmap_zero(syncpt_used, nb_pts);
index 6b78782c361926d5c5f26650a09fd4d1c34e8a7f..913f8fdd09c86e3955eb9e1401ee78fec9a9ce0f 100644 (file)
@@ -481,7 +481,7 @@ int nvhost_intr_init(struct nvhost_intr *intr, u32 irq_gen, u32 irq_sync)
        unsigned int id;
        struct nvhost_intr_syncpt *syncpt;
        struct nvhost_master *host = intr_to_dev(intr);
-       u32 nb_pts = nvhost_syncpt_nb_pts(&host->syncpt);
+       u32 nb_pts = nvhost_syncpt_nb_hw_pts(&host->syncpt);
 
        mutex_init(&intr->mutex);
        intr->syncpt_irq = irq_sync;
@@ -527,7 +527,7 @@ void nvhost_intr_stop(struct nvhost_intr *intr)
 {
        unsigned int id;
        struct nvhost_intr_syncpt *syncpt;
-       u32 nb_pts = nvhost_syncpt_nb_pts(&intr_to_dev(intr)->syncpt);
+       u32 nb_pts = nvhost_syncpt_nb_hw_pts(&intr_to_dev(intr)->syncpt);
 
        mutex_lock(&intr->mutex);
 
index c2f543ff382e97935115d930f9ff490450215627..a3e558b106b6d2568c073c6cf48a34b2b2257686 100644 (file)
@@ -220,7 +220,7 @@ static int do_waitchks(struct nvhost_job *job, struct nvhost_syncpt *sp,
                struct nvhost_waitchk *wait = &job->waitchk[i];
 
                /* validate syncpt id */
-               if (!nvhost_syncpt_is_valid_pt(sp, wait->syncpt_id))
+               if (!nvhost_syncpt_is_valid_hw_pt(sp, wait->syncpt_id))
                        continue;
 
                if (!wait->mem)
@@ -397,17 +397,18 @@ static int do_relocs(struct nvhost_job *job,
 int nvhost_job_pin(struct nvhost_job *job, struct nvhost_syncpt *sp)
 {
        int err = 0, i = 0, j = 0;
-       DECLARE_BITMAP(waitchk_mask, nvhost_syncpt_nb_pts(sp));
+       int nb_hw_pts = nvhost_syncpt_nb_hw_pts(sp);
+       DECLARE_BITMAP(waitchk_mask, nb_hw_pts);
 
-       bitmap_zero(waitchk_mask, nvhost_syncpt_nb_pts(sp));
+       bitmap_zero(waitchk_mask, nb_hw_pts);
        for (i = 0; i < job->num_waitchk; i++) {
                u32 syncpt_id = job->waitchk[i].syncpt_id;
-               if (nvhost_syncpt_is_valid_pt(sp, syncpt_id))
+               if (nvhost_syncpt_is_valid_hw_pt(sp, syncpt_id))
                        set_bit(syncpt_id, waitchk_mask);
        }
 
        /* get current syncpt values for waitchk */
-       for_each_set_bit(i, waitchk_mask, nvhost_syncpt_nb_pts(sp))
+       for_each_set_bit(i, waitchk_mask, nb_hw_pts)
                nvhost_syncpt_update_min(sp, i);
 
        /* pin memory */
index 66cda7bc5856766d2ddde36ac9fb10f995c218f0..eb452975e1c0391315fbcdf481a08cd7a7517eae 100644 (file)
@@ -422,7 +422,7 @@ struct sync_fence *nvhost_sync_create_fence(struct platform_device *pdev,
        struct sync_fence *fence = NULL;
 
        for (i = 0; i < num_pts; i++) {
-               if (!nvhost_syncpt_is_valid_pt(sp, pts[i].id)) {
+               if (!nvhost_syncpt_is_valid_hw_pt(sp, pts[i].id)) {
                        WARN_ON(1);
                        return ERR_PTR(-EINVAL);
                }
index b9381968a31900409743afda97824b9cc84f724d..3a9e0b6dcb336ddb0f4c08d1974d5e62a939775b 100644 (file)
@@ -207,7 +207,7 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id,
                        u32 id,
                        u32 thresh);
 
-       if (!id || !nvhost_syncpt_is_valid_pt(sp, id))
+       if (!id || !nvhost_syncpt_is_valid_hw_pt(sp, id))
                return -EINVAL;
 
        if (value)
@@ -963,7 +963,7 @@ int nvhost_syncpt_init(struct platform_device *dev,
 {
        int i;
        struct nvhost_master *host = syncpt_to_dev(sp);
-       int nb_pts = nvhost_syncpt_nb_pts(sp);
+       int nb_pts = nvhost_syncpt_nb_hw_pts(sp);
        int err = 0;
 
        /* Allocate structs for min, max and base values */
@@ -1026,8 +1026,7 @@ int nvhost_syncpt_init(struct platform_device *dev,
        }
 
        /* Fill in the attributes */
-       for (i = nvhost_syncpt_pts_base(sp);
-                       i < nvhost_syncpt_pts_limit(sp); i++) {
+       for (i = 0; i < nvhost_syncpt_nb_hw_pts(sp); i++) {
                struct nvhost_syncpt_attr *min =
                        &sp->syncpt_attrs[i*NUM_SYSFS_ENTRY];
                struct nvhost_syncpt_attr *max =
@@ -1094,8 +1093,7 @@ static void nvhost_syncpt_deinit_timeline(struct nvhost_syncpt *sp)
 {
 #ifdef CONFIG_TEGRA_GRHOST_SYNC
        int i;
-       for (i = nvhost_syncpt_pts_base(sp);
-                       i < nvhost_syncpt_pts_limit(sp); i++) {
+       for (i = 0; i < nvhost_syncpt_nb_hw_pts(sp); i++) {
                if (sp->timeline && sp->timeline[i]) {
                        sync_timeline_destroy(
                                (struct sync_timeline *)sp->timeline[i]);
@@ -1145,6 +1143,11 @@ int nvhost_syncpt_client_managed(struct nvhost_syncpt *sp, u32 id)
        return sp->client_managed[id];
 }
 
+int nvhost_syncpt_nb_hw_pts(struct nvhost_syncpt *sp)
+{
+       return syncpt_to_dev(sp)->info.nb_hw_pts;
+}
+
 int nvhost_syncpt_nb_pts(struct nvhost_syncpt *sp)
 {
        return syncpt_to_dev(sp)->info.nb_pts;
@@ -1165,6 +1168,12 @@ int nvhost_syncpt_pts_base(struct nvhost_syncpt *sp)
        return syncpt_to_dev(sp)->info.pts_base;
 }
 
+bool nvhost_syncpt_is_valid_hw_pt(struct nvhost_syncpt *sp, u32 id)
+{
+       return (id >= 0 && id < nvhost_syncpt_nb_hw_pts(sp) &&
+               id != NVSYNCPT_INVALID);
+}
+
 bool nvhost_syncpt_is_valid_pt(struct nvhost_syncpt *sp, u32 id)
 {
        return (id >= nvhost_syncpt_pts_base(sp) &&
@@ -1271,12 +1280,16 @@ void nvhost_syncpt_set_min_eq_max_ext(struct platform_device *dev, u32 id)
 }
 EXPORT_SYMBOL(nvhost_syncpt_set_min_eq_max_ext);
 
+/*
+ * For external clients, check the validity in full
+ * h/w supported syncpoint range
+ */
 bool nvhost_syncpt_is_valid_pt_ext(struct platform_device *dev, u32 id)
 {
        struct nvhost_master *master = nvhost_get_host(dev);
        struct nvhost_syncpt *sp = &master->syncpt;
 
-       return nvhost_syncpt_is_valid_pt(sp, id);
+       return nvhost_syncpt_is_valid_hw_pt(sp, id);
 }
 EXPORT_SYMBOL(nvhost_syncpt_is_valid_pt_ext);
 
index 8bc63a2e4d3b4e1d8f21245f1a49e7ec3febcbbf..e548837ad9a439f53331b5e11aa40141943073bf 100644 (file)
@@ -106,8 +106,10 @@ static inline u32 nvhost_syncpt_read_min(struct nvhost_syncpt *sp, u32 id)
 void nvhost_syncpt_patch_check(struct nvhost_syncpt *sp);
 void nvhost_syncpt_set_min_eq_max(struct nvhost_syncpt *sp, u32 id);
 int nvhost_syncpt_client_managed(struct nvhost_syncpt *sp, u32 id);
+int nvhost_syncpt_nb_hw_pts(struct nvhost_syncpt *sp);
 int nvhost_syncpt_nb_pts(struct nvhost_syncpt *sp);
 int nvhost_syncpt_pts_base(struct nvhost_syncpt *sp);
+bool nvhost_syncpt_is_valid_hw_pt(struct nvhost_syncpt *sp, u32 id);
 bool nvhost_syncpt_is_valid_pt(struct nvhost_syncpt *sp, u32 id);
 int nvhost_nb_syncpts_store(struct nvhost_syncpt *sp, const char *buf);
 int nvhost_syncpt_nb_mlocks(struct nvhost_syncpt *sp);
index 6d260618973b486a7053bd8d37bbe5c8167ab08f..d7e5839f859f63678d050bb2f28b6efe7783e83e 100644 (file)
@@ -79,6 +79,7 @@ static struct host1x_device_info host1x04_info = {
        .ch_limit       = T124_NVHOST_NUMCHANNELS,
        .nb_mlocks      = NV_HOST1X_NB_MLOCKS,
        .initialize_chip_support = nvhost_init_t124_support,
+       .nb_hw_pts      = NV_HOST1X_SYNCPT_NB_PTS,
        .nb_pts         = NV_HOST1X_SYNCPT_NB_PTS,
        .pts_base       = 0,
        .pts_limit      = NV_HOST1X_SYNCPT_NB_PTS,
index 509d1881f63364b49ac24f54b33532d1623cf786..72b1b6c47a4efc351c09344b71136adb73d48bff 100644 (file)
@@ -59,6 +59,7 @@ static struct host1x_device_info host1x04_info = {
        .ch_limit       = T124_NVHOST_NUMCHANNELS,
        .nb_mlocks      = NV_HOST1X_NB_MLOCKS,
        .initialize_chip_support = nvhost_init_t210_support,
+       .nb_hw_pts      = NV_HOST1X_SYNCPT_NB_PTS,
        .nb_pts         = NV_HOST1X_SYNCPT_NB_PTS,
        .pts_base       = 0,
        .pts_limit      = NV_HOST1X_SYNCPT_NB_PTS,
index 5c12839abfe5d841ede877a8c381256357d7379f..c7a462948693829457c4a4ab273ccf99755cc685 100644 (file)
@@ -62,10 +62,12 @@ static int syncpt_thresh_cascade_handler(void *dev_id)
                }
 
                sp_id = msg->id;
-               if (unlikely(sp_id >= dev->info.nb_pts)) {
+               if (unlikely(!nvhost_syncpt_is_valid_hw_pt(&dev->syncpt,
+                               sp_id))) {
                        dev_err(&dev->dev->dev,
                                "%s(): syncpoint id %d is beyond the number of syncpoints (%d)\n",
-                               __func__, sp_id, dev->info.nb_pts);
+                               __func__, sp_id,
+                               nvhost_syncpt_nb_hw_pts(&dev->syncpt));
                        tegra_gr_comm_release(handle);
                        continue;
                }
@@ -112,7 +114,7 @@ static void vhost_intr_init_host_sync(struct nvhost_intr *intr)
 
        intr_op().disable_all_syncpt_intrs(intr);
 
-       for (i = 0; i < dev->info.nb_pts; i++)
+       for (i = 0; i < nvhost_syncpt_nb_hw_pts(&dev->syncpt); i++)
                INIT_WORK(&intr->syncpt[i].work, syncpt_thresh_cascade_fn);
 
        ctx->syncpt_handler =