Revert "gpu: host1x: Add IOMMU support"
authorBen Hutchings <ben@decadent.org.uk>
Sat, 22 Jul 2017 00:14:38 +0000 (01:14 +0100)
committerBastian Blank <waldi@debian.org>
Fri, 22 Jun 2018 09:50:22 +0000 (10:50 +0100)
This reverts commit 404bfb78daf3bedafb0bfab24947059575cbea3d, which
resulted in a build failure:

drivers/gpu/host1x/cdma.c: In function 'host1x_pushbuffer_init':
drivers/gpu/host1x/cdma.c:94:48: error: passing argument 3 of 'dma_alloc_wc' from incompatible pointer type [-Werror=incompatible-pointer-types]
   pb->mapped = dma_alloc_wc(host1x->dev, size, &pb->phys,
                                                ^
In file included from drivers/gpu/host1x/cdma.c:22:0:
include/linux/dma-mapping.h:773:21: note: expected 'dma_addr_t * {aka long long unsigned int *}' but argument is of type 'phys_addr_t * {aka unsigned int *}'
 static inline void *dma_alloc_wc(struct device *dev, size_t size,
                     ^~~~~~~~~~~~

This code is mixing up dma_addr_t and phys_addr_t, and this looks had
to avoid when combining the two address mapping APIs.  But with XEN
enabled and ARM_LPAE not enabled, as in the armmp config, dma_addr_t
is 64-bit while phys_addr_t is 32-bit.

It also reverts commits fea20995976f "gpu: host1x: Free the IOMMU
domain when there is no device to attach", 8b3f5ac6b55f "gpu: host1x:
Don't fail on NULL bo physical address", 1f876c3fcead "gpu: host1x:
Rewrite conditional for better readability" and 41c3068cc2fd "gpu:
host1x: Use IOMMU groups" which depend on it.

Gbp-Pq: Topic debian
Gbp-Pq: Name revert-gpu-host1x-add-iommu-support.patch

drivers/gpu/host1x/cdma.c
drivers/gpu/host1x/cdma.h
drivers/gpu/host1x/dev.c
drivers/gpu/host1x/dev.h
drivers/gpu/host1x/hw/cdma_hw.c
drivers/gpu/host1x/job.c
drivers/gpu/host1x/job.h

index 28541b28073907434e1f929b9adf0cdc5c9cf01b..c5d82a8a2ec9c2498bf9e7ed96823cb14db8afae 100644 (file)
@@ -51,15 +51,9 @@ static void host1x_pushbuffer_destroy(struct push_buffer *pb)
        struct host1x_cdma *cdma = pb_to_cdma(pb);
        struct host1x *host1x = cdma_to_host1x(cdma);
 
-       if (!pb->phys)
-               return;
-
-       if (host1x->domain) {
-               iommu_unmap(host1x->domain, pb->dma, pb->alloc_size);
-               free_iova(&host1x->iova, iova_pfn(&host1x->iova, pb->dma));
-       }
-
-       dma_free_wc(host1x->dev, pb->alloc_size, pb->mapped, pb->phys);
+       if (pb->phys != 0)
+               dma_free_wc(host1x->dev, pb->size_bytes + 4, pb->mapped,
+                           pb->phys);
 
        pb->mapped = NULL;
        pb->phys = 0;
@@ -72,64 +66,28 @@ static int host1x_pushbuffer_init(struct push_buffer *pb)
 {
        struct host1x_cdma *cdma = pb_to_cdma(pb);
        struct host1x *host1x = cdma_to_host1x(cdma);
-       struct iova *alloc;
-       u32 size;
-       int err;
 
        pb->mapped = NULL;
        pb->phys = 0;
-       pb->size = HOST1X_PUSHBUFFER_SLOTS * 8;
-
-       size = pb->size + 4;
+       pb->size_bytes = HOST1X_PUSHBUFFER_SLOTS * 8;
 
        /* initialize buffer pointers */
-       pb->fence = pb->size - 8;
+       pb->fence = pb->size_bytes - 8;
        pb->pos = 0;
 
-       if (host1x->domain) {
-               unsigned long shift;
-
-               size = iova_align(&host1x->iova, size);
-
-               pb->mapped = dma_alloc_wc(host1x->dev, size, &pb->phys,
-                                         GFP_KERNEL);
-               if (!pb->mapped)
-                       return -ENOMEM;
-
-               shift = iova_shift(&host1x->iova);
-               alloc = alloc_iova(&host1x->iova, size >> shift,
-                                  host1x->iova_end >> shift, true);
-               if (!alloc) {
-                       err = -ENOMEM;
-                       goto iommu_free_mem;
-               }
-
-               pb->dma = iova_dma_addr(&host1x->iova, alloc);
-               err = iommu_map(host1x->domain, pb->dma, pb->phys, size,
-                               IOMMU_READ);
-               if (err)
-                       goto iommu_free_iova;
-       } else {
-               pb->mapped = dma_alloc_wc(host1x->dev, size, &pb->phys,
-                                         GFP_KERNEL);
-               if (!pb->mapped)
-                       return -ENOMEM;
-
-               pb->dma = pb->phys;
-       }
-
-       pb->alloc_size = size;
+       /* allocate and map pushbuffer memory */
+       pb->mapped = dma_alloc_wc(host1x->dev, pb->size_bytes + 4, &pb->phys,
+                                 GFP_KERNEL);
+       if (!pb->mapped)
+               goto fail;
 
        host1x_hw_pushbuffer_init(host1x, pb);
 
        return 0;
 
-iommu_free_iova:
-       __free_iova(&host1x->iova, alloc);
-iommu_free_mem:
-       dma_free_wc(host1x->dev, pb->alloc_size, pb->mapped, pb->phys);
-
-       return err;
+fail:
+       host1x_pushbuffer_destroy(pb);
+       return -ENOMEM;
 }
 
 /*
@@ -143,7 +101,7 @@ static void host1x_pushbuffer_push(struct push_buffer *pb, u32 op1, u32 op2)
        WARN_ON(pb->pos == pb->fence);
        *(p++) = op1;
        *(p++) = op2;
-       pb->pos = (pb->pos + 8) & (pb->size - 1);
+       pb->pos = (pb->pos + 8) & (pb->size_bytes - 1);
 }
 
 /*
@@ -153,7 +111,7 @@ static void host1x_pushbuffer_push(struct push_buffer *pb, u32 op1, u32 op2)
 static void host1x_pushbuffer_pop(struct push_buffer *pb, unsigned int slots)
 {
        /* Advance the next write position */
-       pb->fence = (pb->fence + slots * 8) & (pb->size - 1);
+       pb->fence = (pb->fence + slots * 8) & (pb->size_bytes - 1);
 }
 
 /*
@@ -161,7 +119,7 @@ static void host1x_pushbuffer_pop(struct push_buffer *pb, unsigned int slots)
  */
 static u32 host1x_pushbuffer_space(struct push_buffer *pb)
 {
-       return ((pb->fence - pb->pos) & (pb->size - 1)) / 8;
+       return ((pb->fence - pb->pos) & (pb->size_bytes - 1)) / 8;
 }
 
 /*
index 286d49386be965f195ecf0b264badf002e9186ac..fd41cdb1eb5ab3de72bf15db2ce7335c5035709b 100644 (file)
@@ -43,12 +43,10 @@ struct host1x_job;
 
 struct push_buffer {
        void *mapped;                   /* mapped pushbuffer memory */
-       dma_addr_t dma;                 /* device address of pushbuffer */
-       phys_addr_t phys;               /* physical address of pushbuffer */
+       dma_addr_t phys;                /* physical address of pushbuffer */
        u32 fence;                      /* index we've written */
        u32 pos;                        /* index to write to */
-       u32 size;
-       u32 alloc_size;
+       u32 size_bytes;
 };
 
 struct buffer_timeout {
index 03db71173f5ded9cd0448bd441cf8c0378b18b16..f089f0d4c262111a52c62e7240929ecf9e06a2a8 100644 (file)
@@ -27,7 +27,6 @@
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/host1x.h>
-#undef CREATE_TRACE_POINTS
 
 #include "bus.h"
 #include "channel.h"
@@ -218,44 +217,11 @@ static int host1x_probe(struct platform_device *pdev)
                return err;
        }
 
-       host->group = iommu_group_get(&pdev->dev);
-       if (host->group) {
-               struct iommu_domain_geometry *geometry;
-               unsigned long order;
-
-               host->domain = iommu_domain_alloc(&platform_bus_type);
-               if (!host->domain) {
-                       err = -ENOMEM;
-                       goto put_group;
-               }
-
-               err = iommu_attach_group(host->domain, host->group);
-               if (err) {
-                       if (err == -ENODEV) {
-                               iommu_domain_free(host->domain);
-                               host->domain = NULL;
-                               iommu_group_put(host->group);
-                               host->group = NULL;
-                               goto skip_iommu;
-                       }
-
-                       goto fail_free_domain;
-               }
-
-               geometry = &host->domain->geometry;
-
-               order = __ffs(host->domain->pgsize_bitmap);
-               init_iova_domain(&host->iova, 1UL << order,
-                                geometry->aperture_start >> order);
-               host->iova_end = geometry->aperture_end;
-       }
-
-skip_iommu:
        err = host1x_channel_list_init(&host->channel_list,
                                       host->info->nb_channels);
        if (err) {
                dev_err(&pdev->dev, "failed to initialize channel list\n");
-               goto fail_detach_device;
+               return err;
        }
 
        err = clk_prepare_enable(host->clk);
@@ -300,17 +266,6 @@ fail_unprepare_disable:
        clk_disable_unprepare(host->clk);
 fail_free_channels:
        host1x_channel_list_free(&host->channel_list);
-fail_detach_device:
-       if (host->group && host->domain) {
-               put_iova_domain(&host->iova);
-               iommu_detach_group(host->domain, host->group);
-       }
-fail_free_domain:
-       if (host->domain)
-               iommu_domain_free(host->domain);
-put_group:
-       iommu_group_put(host->group);
-
        return err;
 }
 
@@ -324,13 +279,6 @@ static int host1x_remove(struct platform_device *pdev)
        reset_control_assert(host->rst);
        clk_disable_unprepare(host->clk);
 
-       if (host->domain) {
-               put_iova_domain(&host->iova);
-               iommu_detach_group(host->domain, host->group);
-               iommu_domain_free(host->domain);
-               iommu_group_put(host->group);
-       }
-
        return 0;
 }
 
index 43e9fabb43a1f5bdf2f3e7e5ca37451934aba70d..4217b022ef837027b5eee28266306b78dece30a9 100644 (file)
@@ -18,8 +18,6 @@
 #define HOST1X_DEV_H
 
 #include <linux/device.h>
-#include <linux/iommu.h>
-#include <linux/iova.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 
@@ -117,11 +115,6 @@ struct host1x {
        struct clk *clk;
        struct reset_control *rst;
 
-       struct iommu_group *group;
-       struct iommu_domain *domain;
-       struct iova_domain iova;
-       dma_addr_t iova_end;
-
        struct mutex intr_mutex;
        int intr_syncpt_irq;
 
index ce320534cbed39aa3fc06aa1473a9187ed671e62..9544efe6582df72d6ba15960f12b8c9b4d47e8b6 100644 (file)
@@ -30,7 +30,7 @@
  */
 static void push_buffer_init(struct push_buffer *pb)
 {
-       *(u32 *)(pb->mapped + pb->size) = host1x_opcode_restart(0);
+       *(u32 *)(pb->mapped + pb->size_bytes) = host1x_opcode_restart(0);
 }
 
 /*
@@ -55,8 +55,8 @@ static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr,
                *(p++) = HOST1X_OPCODE_NOP;
                *(p++) = HOST1X_OPCODE_NOP;
                dev_dbg(host1x->dev, "%s: NOP at %pad+%#x\n", __func__,
-                       &pb->dma, getptr);
-               getptr = (getptr + 8) & (pb->size - 1);
+                       &pb->phys, getptr);
+               getptr = (getptr + 8) & (pb->size_bytes - 1);
        }
 
        wmb();
@@ -78,9 +78,10 @@ static void cdma_start(struct host1x_cdma *cdma)
                         HOST1X_CHANNEL_DMACTRL);
 
        /* set base, put and end pointer */
-       host1x_ch_writel(ch, cdma->push_buffer.dma, HOST1X_CHANNEL_DMASTART);
+       host1x_ch_writel(ch, cdma->push_buffer.phys, HOST1X_CHANNEL_DMASTART);
        host1x_ch_writel(ch, cdma->push_buffer.pos, HOST1X_CHANNEL_DMAPUT);
-       host1x_ch_writel(ch, cdma->push_buffer.dma + cdma->push_buffer.size + 4,
+       host1x_ch_writel(ch, cdma->push_buffer.phys +
+                        cdma->push_buffer.size_bytes + 4,
                         HOST1X_CHANNEL_DMAEND);
 
        /* reset GET */
@@ -114,8 +115,9 @@ static void cdma_timeout_restart(struct host1x_cdma *cdma, u32 getptr)
                         HOST1X_CHANNEL_DMACTRL);
 
        /* set base, end pointer (all of memory) */
-       host1x_ch_writel(ch, cdma->push_buffer.dma, HOST1X_CHANNEL_DMASTART);
-       host1x_ch_writel(ch, cdma->push_buffer.dma + cdma->push_buffer.size,
+       host1x_ch_writel(ch, cdma->push_buffer.phys, HOST1X_CHANNEL_DMASTART);
+       host1x_ch_writel(ch, cdma->push_buffer.phys +
+                        cdma->push_buffer.size_bytes,
                         HOST1X_CHANNEL_DMAEND);
 
        /* set GET, by loading the value in PUT (then reset GET) */
index db509ab8874e58fd1f798da270fa8035ed4563d3..534ec5545ebcee8e638f47f294747cd4d415bd72 100644 (file)
@@ -178,10 +178,9 @@ static int do_waitchks(struct host1x_job *job, struct host1x *host,
        return 0;
 }
 
-static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
+static unsigned int pin_job(struct host1x_job *job)
 {
        unsigned int i;
-       int err;
 
        job->num_unpins = 0;
 
@@ -191,12 +190,12 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
                dma_addr_t phys_addr;
 
                reloc->target.bo = host1x_bo_get(reloc->target.bo);
-               if (!reloc->target.bo) {
-                       err = -EINVAL;
+               if (!reloc->target.bo)
                        goto unpin;
-               }
 
                phys_addr = host1x_bo_pin(reloc->target.bo, &sgt);
+               if (!phys_addr)
+                       goto unpin;
 
                job->addr_phys[job->num_unpins] = phys_addr;
                job->unpins[job->num_unpins].bo = reloc->target.bo;
@@ -206,63 +205,28 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 
        for (i = 0; i < job->num_gathers; i++) {
                struct host1x_job_gather *g = &job->gathers[i];
-               size_t gather_size = 0;
-               struct scatterlist *sg;
                struct sg_table *sgt;
                dma_addr_t phys_addr;
-               unsigned long shift;
-               struct iova *alloc;
-               unsigned int j;
 
                g->bo = host1x_bo_get(g->bo);
-               if (!g->bo) {
-                       err = -EINVAL;
+               if (!g->bo)
                        goto unpin;
-               }
 
                phys_addr = host1x_bo_pin(g->bo, &sgt);
+               if (!phys_addr)
+                       goto unpin;
 
-               if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
-                       for_each_sg(sgt->sgl, sg, sgt->nents, j)
-                               gather_size += sg->length;
-                       gather_size = iova_align(&host->iova, gather_size);
-
-                       shift = iova_shift(&host->iova);
-                       alloc = alloc_iova(&host->iova, gather_size >> shift,
-                                          host->iova_end >> shift, true);
-                       if (!alloc) {
-                               err = -ENOMEM;
-                               goto unpin;
-                       }
-
-                       err = iommu_map_sg(host->domain,
-                                       iova_dma_addr(&host->iova, alloc),
-                                       sgt->sgl, sgt->nents, IOMMU_READ);
-                       if (err == 0) {
-                               __free_iova(&host->iova, alloc);
-                               err = -EINVAL;
-                               goto unpin;
-                       }
-
-                       job->addr_phys[job->num_unpins] =
-                               iova_dma_addr(&host->iova, alloc);
-                       job->unpins[job->num_unpins].size = gather_size;
-               } else {
-                       job->addr_phys[job->num_unpins] = phys_addr;
-               }
-
-               job->gather_addr_phys[i] = job->addr_phys[job->num_unpins];
-
+               job->addr_phys[job->num_unpins] = phys_addr;
                job->unpins[job->num_unpins].bo = g->bo;
                job->unpins[job->num_unpins].sgt = sgt;
                job->num_unpins++;
        }
 
-       return 0;
+       return job->num_unpins;
 
 unpin:
        host1x_job_unpin(job);
-       return err;
+       return 0;
 }
 
 static int do_relocs(struct host1x_job *job, struct host1x_job_gather *g)
@@ -631,8 +595,8 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev)
                host1x_syncpt_load(host->syncpt + i);
 
        /* pin memory */
-       err = pin_job(host, job);
-       if (err)
+       err = pin_job(job);
+       if (!err)
                goto out;
 
        if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) {
@@ -680,19 +644,11 @@ EXPORT_SYMBOL(host1x_job_pin);
 
 void host1x_job_unpin(struct host1x_job *job)
 {
-       struct host1x *host = dev_get_drvdata(job->channel->dev->parent);
        unsigned int i;
 
        for (i = 0; i < job->num_unpins; i++) {
                struct host1x_job_unpin_data *unpin = &job->unpins[i];
 
-               if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
-                       iommu_unmap(host->domain, job->addr_phys[i],
-                                   unpin->size);
-                       free_iova(&host->iova,
-                               iova_pfn(&host->iova, job->addr_phys[i]));
-               }
-
                host1x_bo_unpin(unpin->bo, unpin->sgt);
                host1x_bo_put(unpin->bo);
        }
index 4bda51d503ec0a2a1fa0a3f52ae61494bc1b4229..7a780ec9c101070f789cebef51d934c2e8cbbac1 100644 (file)
@@ -30,7 +30,6 @@ struct host1x_job_gather {
 struct host1x_job_unpin_data {
        struct host1x_bo *bo;
        struct sg_table *sgt;
-       size_t size;
 };
 
 /*