ARM: IOMMU: Tegra20: Add iommu_ops for GART driver
[linux-2.6.git] / drivers / iommu / tegra-gart.c
1 /*
2  * IOMMU API for GART in Tegra20
3  *
4  * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19
20 #define pr_fmt(fmt)     "%s(): " fmt, __func__
21
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
24 #include <linux/spinlock.h>
25 #include <linux/slab.h>
26 #include <linux/vmalloc.h>
27 #include <linux/mm.h>
28 #include <linux/list.h>
29 #include <linux/device.h>
30 #include <linux/io.h>
31 #include <linux/iommu.h>
32
33 #include <asm/cacheflush.h>
34
35 /* bitmap of the page sizes currently supported */
36 #define GART_IOMMU_PGSIZES      (SZ_4K)
37
38 #define GART_CONFIG             0x24
39 #define GART_ENTRY_ADDR         0x28
40 #define GART_ENTRY_DATA         0x2c
41 #define GART_ENTRY_PHYS_ADDR_VALID      (1 << 31)
42
43 #define GART_PAGE_SHIFT         12
44 #define GART_PAGE_SIZE          (1 << GART_PAGE_SHIFT)
45 #define GART_PAGE_MASK                                          \
46         (~(GART_PAGE_SIZE - 1) & ~GART_ENTRY_PHYS_ADDR_VALID)
47
48 struct gart_client {
49         struct device           *dev;
50         struct list_head        list;
51 };
52
53 struct gart_device {
54         void __iomem            *regs;
55         u32                     *savedata;
56         u32                     page_count; /* total remappable size */
57         dma_addr_t              iovmm_base; /* offset to apply to vmm_area */
58         spinlock_t              pte_lock; /* for pagetable */
59         struct list_head        client;
60         spinlock_t              client_lock; /* for client list */
61         struct device           *dev;
62 };
63
64 #define GART_PTE(_pfn)                                          \
65         (GART_ENTRY_PHYS_ADDR_VALID | ((_pfn) << PAGE_SHIFT))
66
67 /*
68  * Any interaction between any block on PPSB and a block on APB or AHB
69  * must have these read-back to ensure the APB/AHB bus transaction is
70  * complete before initiating activity on the PPSB block.
71  */
72 #define FLUSH_GART_REGS(gart)   ((void)readl((gart)->regs + GART_CONFIG))
73
74 #define for_each_gart_pte(gart, iova)                                   \
75         for (iova = gart->iovmm_base;                                   \
76              iova < gart->iovmm_base + GART_PAGE_SIZE * gart->page_count; \
77              iova += GART_PAGE_SIZE)
78
79 static inline void gart_set_pte(struct gart_device *gart,
80                                 unsigned long offs, u32 pte)
81 {
82         writel(offs, gart->regs + GART_ENTRY_ADDR);
83         writel(pte, gart->regs + GART_ENTRY_DATA);
84
85         dev_dbg(gart->dev, "%s %08lx:%08x\n",
86                  pte ? "map" : "unmap", offs, pte & GART_PAGE_MASK);
87 }
88
89 static inline unsigned long gart_read_pte(struct gart_device *gart,
90                                           unsigned long offs)
91 {
92         unsigned long pte;
93
94         writel(offs, gart->regs + GART_ENTRY_ADDR);
95         pte = readl(gart->regs + GART_ENTRY_DATA);
96
97         return pte;
98 }
99
100 static void do_gart_setup(struct gart_device *gart, const u32 *data)
101 {
102         unsigned long iova;
103
104         for_each_gart_pte(gart, iova)
105                 gart_set_pte(gart, iova, data ? *(data++) : 0);
106
107         writel(1, gart->regs + GART_CONFIG);
108         FLUSH_GART_REGS(gart);
109 }
110
111 #ifdef DEBUG
112 static void gart_dump_table(struct gart_device *gart)
113 {
114         unsigned long iova;
115         unsigned long flags;
116
117         spin_lock_irqsave(&gart->pte_lock, flags);
118         for_each_gart_pte(gart, iova) {
119                 unsigned long pte;
120
121                 pte = gart_read_pte(gart, iova);
122
123                 dev_dbg(gart->dev, "%s %08lx:%08lx\n",
124                         (GART_ENTRY_PHYS_ADDR_VALID & pte) ? "v" : " ",
125                         iova, pte & GART_PAGE_MASK);
126         }
127         spin_unlock_irqrestore(&gart->pte_lock, flags);
128 }
129 #else
130 static inline void gart_dump_table(struct gart_device *gart)
131 {
132 }
133 #endif
134
135 static inline bool gart_iova_range_valid(struct gart_device *gart,
136                                          unsigned long iova, size_t bytes)
137 {
138         unsigned long iova_start, iova_end, gart_start, gart_end;
139
140         iova_start = iova;
141         iova_end = iova_start + bytes - 1;
142         gart_start = gart->iovmm_base;
143         gart_end = gart_start + gart->page_count * GART_PAGE_SIZE - 1;
144
145         if (iova_start < gart_start)
146                 return false;
147         if (iova_end > gart_end)
148                 return false;
149         return true;
150 }
151
152 static int gart_iommu_domain_init(struct iommu_domain *domain)
153 {
154         return 0;
155 }
156
157 static void gart_iommu_domain_destroy(struct iommu_domain *domain)
158 {
159         struct gart_device *gart = domain->priv;
160
161         spin_lock(&gart->client_lock);
162         if (!list_empty(&gart->client)) {
163                 struct gart_client *c;
164
165                 list_for_each_entry(c, &gart->client, list)
166                         dev_err(gart->dev,
167                                 "%s is still attached\n", dev_name(c->dev));
168         }
169         spin_unlock(&gart->client_lock);
170         domain->priv = NULL;
171 }
172
173 static int gart_iommu_attach_dev(struct iommu_domain *domain,
174                                  struct device *dev)
175 {
176         struct gart_device *gart;
177         struct gart_client *client, *c;
178         int err = 0;
179
180         gart = dev_get_drvdata(dev->parent);
181         if (!gart)
182                 return -EINVAL;
183         domain->priv = gart;
184         client = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
185         if (!client)
186                 return -ENOMEM;
187         client->dev = dev;
188
189         spin_lock(&gart->client_lock);
190         list_for_each_entry(c, &gart->client, list) {
191                 if (c->dev == dev) {
192                         dev_err(gart->dev,
193                                 "%s is already attached\n", dev_name(dev));
194                         err = -EINVAL;
195                         goto fail;
196                 }
197         }
198         list_add(&client->list, &gart->client);
199         spin_unlock(&gart->client_lock);
200         dev_dbg(gart->dev, "Attached %s\n", dev_name(dev));
201         return 0;
202
203 fail:
204         devm_kfree(dev, client);
205         spin_unlock(&gart->client_lock);
206         return err;
207 }
208
209 static void gart_iommu_detach_dev(struct iommu_domain *domain,
210                                   struct device *dev)
211 {
212         struct gart_device *gart = domain->priv;
213         struct gart_client *c;
214
215         spin_lock(&gart->client_lock);
216
217         list_for_each_entry(c, &gart->client, list) {
218                 if (c->dev == dev) {
219                         list_del(&c->list);
220                         devm_kfree(dev, c);
221                         dev_dbg(gart->dev, "Detached %s\n", dev_name(dev));
222                         goto out;
223                 }
224         }
225         dev_err(gart->dev, "Couldn't find\n");
226 out:
227         spin_unlock(&gart->client_lock);
228 }
229
230 static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,
231                           phys_addr_t pa, int gfp_order, int prot)
232 {
233         struct gart_device *gart = domain->priv;
234         unsigned long flags;
235         unsigned long count = (PAGE_SIZE << gfp_order) >> GART_PAGE_SHIFT;
236         int i;
237
238         if (!gart_iova_range_valid(gart, iova, count * GART_PAGE_SIZE))
239                 return -EINVAL;
240
241         spin_lock_irqsave(&gart->pte_lock, flags);
242
243         for (i = 0; i < count; i++) {
244                 unsigned long pfn;
245
246                 pfn = __phys_to_pfn(pa);
247                 if (!pfn_valid(pfn)) {
248                         dev_err(gart->dev, "Invalid page: %08x\n", pa);
249                         goto fail;
250                 }
251
252                 gart_set_pte(gart, iova, GART_PTE(pfn));
253                 iova += GART_PAGE_SIZE;
254         }
255         FLUSH_GART_REGS(gart);
256         spin_unlock_irqrestore(&gart->pte_lock, flags);
257         return 0;
258
259 fail:
260         while (--i >= 0) {
261                 iova -= GART_PAGE_SIZE;
262                 gart_set_pte(gart, iova, 0);
263         }
264         FLUSH_GART_REGS(gart);
265         spin_unlock_irqrestore(&gart->pte_lock, flags);
266         return -EINVAL;
267 }
268
269 static int gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
270                             int gfp_order)
271 {
272         int i;
273         struct gart_device *gart = domain->priv;
274         unsigned long flags;
275         unsigned long count = (PAGE_SIZE << gfp_order) >> GART_PAGE_SHIFT;
276
277         if (!gart_iova_range_valid(gart, iova, count * GART_PAGE_SIZE))
278                 return -EINVAL;
279
280         spin_lock_irqsave(&gart->pte_lock, flags);
281         for (i = 0; i < count; i++) {
282                 gart_set_pte(gart, iova, 0);
283                 iova += GART_PAGE_SIZE;
284         }
285         FLUSH_GART_REGS(gart);
286         spin_unlock_irqrestore(&gart->pte_lock, flags);
287         return 0;
288 }
289
290 static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain,
291                                            unsigned long iova)
292 {
293         struct gart_device *gart = domain->priv;
294         unsigned long pte;
295         phys_addr_t pa;
296         unsigned long flags;
297
298         if (!gart_iova_range_valid(gart, iova, 0))
299                 return -EINVAL;
300
301         spin_lock_irqsave(&gart->pte_lock, flags);
302         pte = gart_read_pte(gart, iova);
303         spin_unlock_irqrestore(&gart->pte_lock, flags);
304
305         pa = (pte & GART_PAGE_MASK);
306         if (!pfn_valid(__phys_to_pfn(pa))) {
307                 dev_err(gart->dev, "No entry for %08lx:%08x\n", iova, pa);
308                 gart_dump_table(gart);
309                 return -EINVAL;
310         }
311         return pa;
312 }
313
314 static int gart_iommu_domain_has_cap(struct iommu_domain *domain,
315                                      unsigned long cap)
316 {
317         return 0;
318 }
319
320 static struct iommu_ops gart_iommu_ops = {
321         .domain_init    = gart_iommu_domain_init,
322         .domain_destroy = gart_iommu_domain_destroy,
323         .attach_dev     = gart_iommu_attach_dev,
324         .detach_dev     = gart_iommu_detach_dev,
325         .map            = gart_iommu_map,
326         .unmap          = gart_iommu_unmap,
327         .iova_to_phys   = gart_iommu_iova_to_phys,
328         .domain_has_cap = gart_iommu_domain_has_cap,
329 };
330
331 static int tegra_gart_suspend(struct device *dev)
332 {
333         struct gart_device *gart = dev_get_drvdata(dev);
334         unsigned long iova;
335         u32 *data = gart->savedata;
336         unsigned long flags;
337
338         spin_lock_irqsave(&gart->pte_lock, flags);
339         for_each_gart_pte(gart, iova)
340                 *(data++) = gart_read_pte(gart, iova);
341         spin_unlock_irqrestore(&gart->pte_lock, flags);
342         return 0;
343 }
344
345 static int tegra_gart_resume(struct device *dev)
346 {
347         struct gart_device *gart = dev_get_drvdata(dev);
348         unsigned long flags;
349
350         spin_lock_irqsave(&gart->pte_lock, flags);
351         do_gart_setup(gart, gart->savedata);
352         spin_unlock_irqrestore(&gart->pte_lock, flags);
353         return 0;
354 }
355
356 static int tegra_gart_probe(struct platform_device *pdev)
357 {
358         struct gart_device *gart;
359         struct resource *res, *res_remap;
360         void __iomem *gart_regs;
361         int err;
362         struct device *dev = &pdev->dev;
363
364         BUILD_BUG_ON(PAGE_SHIFT != GART_PAGE_SHIFT);
365
366         /* the GART memory aperture is required */
367         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
368         res_remap = platform_get_resource(pdev, IORESOURCE_MEM, 1);
369         if (!res || !res_remap) {
370                 dev_err(dev, "GART memory aperture expected\n");
371                 return -ENXIO;
372         }
373
374         gart = devm_kzalloc(dev, sizeof(*gart), GFP_KERNEL);
375         if (!gart) {
376                 dev_err(dev, "failed to allocate gart_device\n");
377                 return -ENOMEM;
378         }
379
380         gart_regs = devm_ioremap(dev, res->start, resource_size(res));
381         if (!gart_regs) {
382                 dev_err(dev, "failed to remap GART registers\n");
383                 err = -ENXIO;
384                 goto fail;
385         }
386
387         gart->dev = &pdev->dev;
388         spin_lock_init(&gart->pte_lock);
389         spin_lock_init(&gart->client_lock);
390         INIT_LIST_HEAD(&gart->client);
391         gart->regs = gart_regs;
392         gart->iovmm_base = (dma_addr_t)res_remap->start;
393         gart->page_count = (resource_size(res_remap) >> GART_PAGE_SHIFT);
394
395         gart->savedata = vmalloc(sizeof(u32) * gart->page_count);
396         if (!gart->savedata) {
397                 dev_err(dev, "failed to allocate context save area\n");
398                 err = -ENOMEM;
399                 goto fail;
400         }
401
402         platform_set_drvdata(pdev, gart);
403         do_gart_setup(gart, NULL);
404         return 0;
405
406 fail:
407         if (gart_regs)
408                 devm_iounmap(dev, gart_regs);
409         if (gart && gart->savedata)
410                 vfree(gart->savedata);
411         devm_kfree(dev, gart);
412         return err;
413 }
414
415 static int tegra_gart_remove(struct platform_device *pdev)
416 {
417         struct gart_device *gart = platform_get_drvdata(pdev);
418         struct device *dev = gart->dev;
419
420         writel(0, gart->regs + GART_CONFIG);
421         if (gart->savedata)
422                 vfree(gart->savedata);
423         if (gart->regs)
424                 devm_iounmap(dev, gart->regs);
425         devm_kfree(dev, gart);
426         return 0;
427 }
428
429 const struct dev_pm_ops tegra_gart_pm_ops = {
430         .suspend        = tegra_gart_suspend,
431         .resume         = tegra_gart_resume,
432 };
433
434 static struct platform_driver tegra_gart_driver = {
435         .probe          = tegra_gart_probe,
436         .remove         = tegra_gart_remove,
437         .driver = {
438                 .owner  = THIS_MODULE,
439                 .name   = "tegra_gart",
440                 .pm     = &tegra_gart_pm_ops,
441         },
442 };
443
444 static int __devinit tegra_gart_init(void)
445 {
446         register_iommu(&gart_iommu_ops);
447         return platform_driver_register(&tegra_gart_driver);
448 }
449
450 static void __exit tegra_gart_exit(void)
451 {
452         platform_driver_unregister(&tegra_gart_driver);
453 }
454
455 subsys_initcall(tegra_gart_init);
456 module_exit(tegra_gart_exit);