video: tegra: host: Serialize 2D jobs
[linux-2.6.git] / drivers / video / tegra / host / t20 / t20.c
1 /*
2  * drivers/video/tegra/host/t20/t20.c
3  *
4  * Tegra Graphics Init for T20 Architecture Chips
5  *
6  * Copyright (c) 2011-2012, NVIDIA Corporation.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU General Public License,
10  * version 2, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <linux/nvhost_ioctl.h>
22 #include <mach/powergate.h>
23 #include <mach/iomap.h>
24 #include "t20.h"
25 #include "gr3d/gr3d_t20.h"
26 #include "mpe/mpe.h"
27 #include "host1x/host1x.h"
28 #include "nvhost_channel.h"
29 #include "nvhost_memmgr.h"
30 #include "host1x/host1x01_hardware.h"
31 #include "host1x/host1x_syncpt.h"
32 #include "chip_support.h"
33
34 #define NVMODMUTEX_2D_FULL      (1)
35 #define NVMODMUTEX_2D_SIMPLE    (2)
36 #define NVMODMUTEX_2D_SB_A      (3)
37 #define NVMODMUTEX_2D_SB_B      (4)
38 #define NVMODMUTEX_3D           (5)
39 #define NVMODMUTEX_DISPLAYA     (6)
40 #define NVMODMUTEX_DISPLAYB     (7)
41 #define NVMODMUTEX_VI           (8)
42 #define NVMODMUTEX_DSI          (9)
43
44 static int t20_num_alloc_channels = 0;
45
46 static struct resource tegra_host1x01_resources[] = {
47         {
48                 .start = TEGRA_HOST1X_BASE,
49                 .end = TEGRA_HOST1X_BASE + TEGRA_HOST1X_SIZE - 1,
50                 .flags = IORESOURCE_MEM,
51         },
52         {
53                 .start = INT_SYNCPT_THRESH_BASE,
54                 .end = INT_SYNCPT_THRESH_BASE + INT_SYNCPT_THRESH_NR - 1,
55                 .flags = IORESOURCE_IRQ,
56         },
57         {
58                 .start = INT_HOST1X_MPCORE_GENERAL,
59                 .end = INT_HOST1X_MPCORE_GENERAL,
60                 .flags = IORESOURCE_IRQ,
61         },
62 };
63
64 static const char *s_syncpt_names[32] = {
65         "gfx_host",
66         "", "", "", "", "", "", "",
67         "disp0_a", "disp1_a", "avp_0",
68         "csi_vi_0", "csi_vi_1",
69         "vi_isp_0", "vi_isp_1", "vi_isp_2", "vi_isp_3", "vi_isp_4",
70         "2d_0", "2d_1",
71         "disp0_b", "disp1_b",
72         "3d",
73         "mpe",
74         "disp0_c", "disp1_c",
75         "vblank0", "vblank1",
76         "mpe_ebm_eof", "mpe_wr_safe",
77         "2d_tinyblt",
78         "dsi"
79 };
80
81 static struct host1x_device_info host1x01_info = {
82         .nb_channels    = 8,
83         .nb_pts         = 32,
84         .nb_mlocks      = 16,
85         .nb_bases       = 8,
86         .syncpt_names   = s_syncpt_names,
87         .client_managed = NVSYNCPTS_CLIENT_MANAGED,
88 };
89
90 static struct nvhost_device tegra_host1x01_device = {
91         .dev            = {.platform_data = &host1x01_info},
92         .name           = "host1x",
93         .id             = -1,
94         .resource       = tegra_host1x01_resources,
95         .num_resources  = ARRAY_SIZE(tegra_host1x01_resources),
96         .clocks         = {{"host1x", UINT_MAX}, {} },
97         NVHOST_MODULE_NO_POWERGATE_IDS,
98 };
99
100 static struct nvhost_device tegra_display01_device = {
101         .name           = "display",
102         .id             = -1,
103         .index          = 0,
104         .syncpts        = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) |
105                           BIT(NVSYNCPT_DISP0_B) | BIT(NVSYNCPT_DISP1_B) |
106                           BIT(NVSYNCPT_DISP0_C) | BIT(NVSYNCPT_DISP1_C) |
107                           BIT(NVSYNCPT_VBLANK0) | BIT(NVSYNCPT_VBLANK1),
108         .modulemutexes  = BIT(NVMODMUTEX_DISPLAYA) | BIT(NVMODMUTEX_DISPLAYB),
109         NVHOST_MODULE_NO_POWERGATE_IDS,
110         NVHOST_DEFAULT_CLOCKGATE_DELAY,
111         .moduleid       = NVHOST_MODULE_NONE,
112 };
113
114 static struct nvhost_device tegra_gr3d01_device = {
115         .name           = "gr3d",
116         .version        = 1,
117         .id             = -1,
118         .index          = 1,
119         .syncpts        = BIT(NVSYNCPT_3D),
120         .waitbases      = BIT(NVWAITBASE_3D),
121         .modulemutexes  = BIT(NVMODMUTEX_3D),
122         .class          = NV_GRAPHICS_3D_CLASS_ID,
123         .clocks         = {{"gr3d", UINT_MAX}, {"emc", UINT_MAX}, {} },
124         .powergate_ids  = {TEGRA_POWERGATE_3D, -1},
125         NVHOST_DEFAULT_CLOCKGATE_DELAY,
126         .moduleid       = NVHOST_MODULE_NONE,
127 };
128
129 static struct nvhost_device tegra_gr2d01_device = {
130         .name           = "gr2d",
131         .id             = -1,
132         .index          = 2,
133         .syncpts        = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1),
134         .waitbases      = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
135         .modulemutexes  = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
136                           BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
137         .clocks         = { {"gr2d", UINT_MAX},
138                             {"epp", UINT_MAX},
139                             {"emc", UINT_MAX} },
140         NVHOST_MODULE_NO_POWERGATE_IDS,
141         .clockgate_delay = 0,
142         .moduleid       = NVHOST_MODULE_NONE,
143         .serialize      = true,
144 };
145
146 static struct resource isp_resources_t20[] = {
147         {
148                 .name = "regs",
149                 .start = TEGRA_ISP_BASE,
150                 .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1,
151                 .flags = IORESOURCE_MEM,
152         }
153 };
154
155 static struct nvhost_device tegra_isp01_device = {
156         .name           = "isp",
157         .id             = -1,
158         .resource = isp_resources_t20,
159         .num_resources = ARRAY_SIZE(isp_resources_t20),
160         .index          = 3,
161         .syncpts        = 0,
162         NVHOST_MODULE_NO_POWERGATE_IDS,
163         NVHOST_DEFAULT_CLOCKGATE_DELAY,
164         .moduleid       = NVHOST_MODULE_ISP,
165 };
166
167 static struct resource vi_resources[] = {
168         {
169                 .name = "regs",
170                 .start = TEGRA_VI_BASE,
171                 .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1,
172                 .flags = IORESOURCE_MEM,
173         },
174 };
175
176 static struct nvhost_device tegra_vi01_device = {
177         .name           = "vi",
178         .resource = vi_resources,
179         .num_resources = ARRAY_SIZE(vi_resources),
180         .id             = -1,
181         .index          = 4,
182         .syncpts        = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) |
183                           BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) |
184                           BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
185                           BIT(NVSYNCPT_VI_ISP_4),
186         .modulemutexes  = BIT(NVMODMUTEX_VI),
187         .exclusive      = true,
188         NVHOST_MODULE_NO_POWERGATE_IDS,
189         NVHOST_DEFAULT_CLOCKGATE_DELAY,
190         .moduleid       = NVHOST_MODULE_VI,
191 };
192
193 static struct resource tegra_mpe01_resources[] = {
194         {
195                 .name = "regs",
196                 .start = TEGRA_MPE_BASE,
197                 .end = TEGRA_MPE_BASE + TEGRA_MPE_SIZE - 1,
198                 .flags = IORESOURCE_MEM,
199         },
200 };
201
202 static struct nvhost_device tegra_mpe01_device = {
203         .name           = "mpe",
204         .version        = 1,
205         .id             = -1,
206         .resource       = tegra_mpe01_resources,
207         .num_resources  = ARRAY_SIZE(tegra_mpe01_resources),
208         .index          = 5,
209         .syncpts        = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) |
210                           BIT(NVSYNCPT_MPE_WR_SAFE),
211         .waitbases      = BIT(NVWAITBASE_MPE),
212         .class          = NV_VIDEO_ENCODE_MPEG_CLASS_ID,
213         .waitbasesync   = true,
214         .keepalive      = true,
215         .clocks         = { {"mpe", UINT_MAX},
216                             {"emc", UINT_MAX} },
217         .powergate_ids  = {TEGRA_POWERGATE_MPE, -1},
218         NVHOST_DEFAULT_CLOCKGATE_DELAY,
219         .moduleid       = NVHOST_MODULE_MPE,
220 };
221
222 static struct nvhost_device tegra_dsi01_device = {
223         .name           = "dsi",
224         .id             = -1,
225         .index          = 6,
226         .syncpts        = BIT(NVSYNCPT_DSI),
227         .modulemutexes  = BIT(NVMODMUTEX_DSI),
228         NVHOST_MODULE_NO_POWERGATE_IDS,
229         NVHOST_DEFAULT_CLOCKGATE_DELAY,
230         .moduleid       = NVHOST_MODULE_NONE,
231 };
232
233 static struct nvhost_device *t20_devices[] = {
234         &tegra_host1x01_device,
235         &tegra_display01_device,
236         &tegra_gr3d01_device,
237         &tegra_gr2d01_device,
238         &tegra_isp01_device,
239         &tegra_vi01_device,
240         &tegra_mpe01_device,
241         &tegra_dsi01_device,
242 };
243
244 int tegra2_register_host1x_devices(void)
245 {
246         return nvhost_add_devices(t20_devices, ARRAY_SIZE(t20_devices));
247 }
248
249 static void t20_free_nvhost_channel(struct nvhost_channel *ch)
250 {
251         nvhost_free_channel_internal(ch, &t20_num_alloc_channels);
252 }
253
254 static struct nvhost_channel *t20_alloc_nvhost_channel(
255                 struct nvhost_device *dev)
256 {
257         return nvhost_alloc_channel_internal(dev->index,
258                 nvhost_get_host(dev)->info.nb_channels,
259                 &t20_num_alloc_channels);
260 }
261
262 #include "host1x/host1x_channel.c"
263 #include "host1x/host1x_cdma.c"
264 #include "host1x/host1x_debug.c"
265 #include "host1x/host1x_syncpt.c"
266 #include "host1x/host1x_intr.c"
267
268 int nvhost_init_t20_support(struct nvhost_master *host,
269         struct nvhost_chip_support *op)
270 {
271         int err;
272
273         op->channel = host1x_channel_ops;
274         op->cdma = host1x_cdma_ops;
275         op->push_buffer = host1x_pushbuffer_ops;
276         op->debug = host1x_debug_ops;
277         host->sync_aperture = host->aperture + HOST1X_CHANNEL_SYNC_REG_BASE;
278         op->syncpt = host1x_syncpt_ops;
279         op->intr = host1x_intr_ops;
280         err = nvhost_memmgr_init(op);
281         if (err)
282                 return err;
283
284         op->nvhost_dev.alloc_nvhost_channel = t20_alloc_nvhost_channel;
285         op->nvhost_dev.free_nvhost_channel = t20_free_nvhost_channel;
286
287         return 0;
288 }