temp revert rk change
[firefly-linux-kernel-4.4.55.git] / drivers / video / tegra / host / nvhost_cpuaccess.c
1 /*
2  * drivers/video/tegra/host/nvhost_cpuaccess.c
3  *
4  * Tegra Graphics Host Cpu Register Access
5  *
6  * Copyright (c) 2010, NVIDIA Corporation.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23 #include "nvhost_cpuaccess.h"
24 #include "dev.h"
25 #include <linux/string.h>
26
27 #define cpuaccess_to_dev(ctx) container_of(ctx, struct nvhost_master, cpuaccess)
28
29 int nvhost_cpuaccess_init(struct nvhost_cpuaccess *ctx,
30                         struct platform_device *pdev)
31 {
32         int i;
33         for (i = 0; i < NVHOST_MODULE_NUM; i++) {
34                 struct resource *mem;
35                 mem = platform_get_resource(pdev, IORESOURCE_MEM, i+1);
36                 if (!mem) {
37                         dev_err(&pdev->dev, "missing module memory resource\n");
38                         return -ENXIO;
39                 }
40
41                 ctx->regs[i] = ioremap(mem->start, resource_size(mem));
42                 if (!ctx->regs[i]) {
43                         dev_err(&pdev->dev, "failed to map module registers\n");
44                         return -ENXIO;
45                 }
46         }
47
48         return 0;
49 }
50
51 void nvhost_cpuaccess_deinit(struct nvhost_cpuaccess *ctx)
52 {
53         int i;
54         for (i = 0; i < NVHOST_MODULE_NUM; i++) {
55                 iounmap(ctx->regs[i]);
56                 release_resource(ctx->reg_mem[i]);
57         }
58 }
59
60 int nvhost_mutex_try_lock(struct nvhost_cpuaccess *ctx, unsigned int idx)
61 {
62         struct nvhost_master *dev = cpuaccess_to_dev(ctx);
63         void __iomem *sync_regs = dev->sync_aperture;
64         u32 reg;
65
66         /* mlock registers returns 0 when the lock is aquired.
67          * writing 0 clears the lock. */
68         nvhost_module_busy(&dev->mod);
69         reg = readl(sync_regs + (HOST1X_SYNC_MLOCK_0 + idx * 4));
70         if (reg) {
71                 nvhost_module_idle(&dev->mod);
72                 return -ERESTARTSYS;
73         }
74         return 0;
75 }
76
77 void nvhost_mutex_unlock(struct nvhost_cpuaccess *ctx, unsigned int idx)
78 {
79         struct nvhost_master *dev = cpuaccess_to_dev(ctx);
80         void __iomem *sync_regs = dev->sync_aperture;
81         writel(0, sync_regs + (HOST1X_SYNC_MLOCK_0 + idx * 4));
82         nvhost_module_idle(&dev->mod);
83 }
84
85 void nvhost_read_module_regs(struct nvhost_cpuaccess *ctx, u32 module,
86                         u32 offset, size_t size, void *values)
87 {
88         struct nvhost_master *dev = cpuaccess_to_dev(ctx);
89         void __iomem *p = ctx->regs[module] + offset;
90         u32* out = (u32*)values;
91         BUG_ON(size & 3);
92         size >>= 2;
93         nvhost_module_busy(&dev->mod);
94         while (size--) {
95                 *(out++) = readl(p);
96                 p += 4;
97         }
98         rmb();
99         nvhost_module_idle(&dev->mod);
100 }
101
102 void nvhost_write_module_regs(struct nvhost_cpuaccess *ctx, u32 module,
103                         u32 offset, size_t size, const void *values)
104 {
105         struct nvhost_master *dev = cpuaccess_to_dev(ctx);
106         void __iomem *p = ctx->regs[module] + offset;
107         const u32* in = (const u32*)values;
108         BUG_ON(size & 3);
109         size >>= 2;
110         nvhost_module_busy(&dev->mod);
111         while (size--) {
112                 writel(*(in++), p);
113                 p += 4;
114         }
115         wmb();
116         nvhost_module_idle(&dev->mod);
117 }