video: tegra: host: Remove version from Tegra11 gr3d
[linux-2.6.git] / drivers / video / tegra / host / t114 / t114.c
1 /*
2  * drivers/video/tegra/host/t114/t114.c
3  *
4  * Tegra Graphics Init for T114 Architecture Chips
5  *
6  * Copyright (c) 2010-2012, 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 <linux/init.h>
24 #include <linux/mutex.h>
25 #include <mach/powergate.h>
26 #include <mach/iomap.h>
27 #include "dev.h"
28 #include "host1x/host1x_cdma.h"
29 #include "t20/t20.h"
30 #include "t30/t30.h"
31 #include "t114.h"
32 #include "host1x/host1x_hardware.h"
33 #include "host1x/host1x_syncpt.h"
34 #include "host1x/host1x_actmon.h"
35 #include "gr3d/gr3d.h"
36 #include "gr3d/gr3d_t114.h"
37 #include "gr3d/scale3d.h"
38 #include "msenc/msenc.h"
39 #include "tsec/tsec.h"
40 #include <linux/nvhost_ioctl.h>
41 #include "nvhost_channel.h"
42 #include "nvhost_memmgr.h"
43 #include "chip_support.h"
44
45 #define NVMODMUTEX_2D_FULL   (1)
46 #define NVMODMUTEX_2D_SIMPLE (2)
47 #define NVMODMUTEX_2D_SB_A   (3)
48 #define NVMODMUTEX_2D_SB_B   (4)
49 #define NVMODMUTEX_3D        (5)
50 #define NVMODMUTEX_DISPLAYA  (6)
51 #define NVMODMUTEX_DISPLAYB  (7)
52 #define NVMODMUTEX_VI        (8)
53 #define NVMODMUTEX_DSI       (9)
54
55 #define HOST_EMC_FLOOR 300000000
56
57 static int t114_num_alloc_channels = 0;
58
59 static struct resource tegra_host1x02_resources[] = {
60         {
61                 .start = TEGRA_HOST1X_BASE,
62                 .end = TEGRA_HOST1X_BASE + TEGRA_HOST1X_SIZE - 1,
63                 .flags = IORESOURCE_MEM,
64         },
65         {
66                 .start = INT_SYNCPT_THRESH_BASE,
67                 .end = INT_SYNCPT_THRESH_BASE + INT_SYNCPT_THRESH_NR - 1,
68                 .flags = IORESOURCE_IRQ,
69         },
70         {
71                 .start = INT_HOST1X_MPCORE_GENERAL,
72                 .end = INT_HOST1X_MPCORE_GENERAL,
73                 .flags = IORESOURCE_IRQ,
74         },
75 };
76
77 static const char *s_syncpt_names[32] = {
78         "gfx_host",
79         "", "", "", "", "", "", "",
80         "disp0_a", "disp1_a", "avp_0",
81         "csi_vi_0", "csi_vi_1",
82         "vi_isp_0", "vi_isp_1", "vi_isp_2", "vi_isp_3", "vi_isp_4",
83         "2d_0", "2d_1",
84         "disp0_b", "disp1_b",
85         "3d",
86         "mpe",
87         "disp0_c", "disp1_c",
88         "vblank0", "vblank1",
89         "mpe_ebm_eof", "mpe_wr_safe",
90         "2d_tinyblt",
91         "dsi"
92 };
93
94 static struct host1x_device_info host1x02_info = {
95         .nb_channels    = 9,
96         .nb_pts         = 32,
97         .nb_mlocks      = 16,
98         .nb_bases       = 8,
99         .syncpt_names   = s_syncpt_names,
100         .client_managed = NVSYNCPTS_CLIENT_MANAGED,
101 };
102
103 static struct nvhost_device tegra_host1x02_device = {
104         .dev            = {.platform_data = &host1x02_info},
105         .name           = "host1x",
106         .id             = -1,
107         .resource       = tegra_host1x02_resources,
108         .num_resources  = ARRAY_SIZE(tegra_host1x02_resources),
109         .clocks         = {{"host1x", UINT_MAX}, {} },
110         NVHOST_MODULE_NO_POWERGATE_IDS,
111 };
112
113 static struct nvhost_device tegra_display01_device = {
114         .name          = "display",
115         .id            = -1,
116         .index         = 0,
117         .syncpts       = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) |
118                          BIT(NVSYNCPT_DISP0_B) | BIT(NVSYNCPT_DISP1_B) |
119                          BIT(NVSYNCPT_DISP0_C) | BIT(NVSYNCPT_DISP1_C) |
120                          BIT(NVSYNCPT_VBLANK0) | BIT(NVSYNCPT_VBLANK1),
121         .modulemutexes = BIT(NVMODMUTEX_DISPLAYA) | BIT(NVMODMUTEX_DISPLAYB),
122         NVHOST_MODULE_NO_POWERGATE_IDS,
123         NVHOST_DEFAULT_CLOCKGATE_DELAY,
124         .moduleid      = NVHOST_MODULE_NONE,
125 };
126
127 static struct nvhost_device tegra_gr3d03_device = {
128         .name          = "gr3d",
129         .version       = 3,
130         .id            = -1,
131         .index         = 1,
132         .syncpts       = BIT(NVSYNCPT_3D),
133         .waitbases     = BIT(NVWAITBASE_3D),
134         .modulemutexes = BIT(NVMODMUTEX_3D),
135         .class         = NV_GRAPHICS_3D_CLASS_ID,
136         .clocks = {{"gr3d", UINT_MAX},
137                         {"emc", HOST_EMC_FLOOR} },
138         NVHOST_MODULE_NO_POWERGATE_IDS,
139         NVHOST_DEFAULT_CLOCKGATE_DELAY,
140         .moduleid      = NVHOST_MODULE_NONE,
141 };
142
143 static struct nvhost_device tegra_gr2d03_device = {
144         .name          = "gr2d",
145         .id            = -1,
146         .index         = 2,
147         .syncpts       = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1),
148         .waitbases     = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
149         .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
150                          BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
151         .clocks = {{"gr2d", 0},
152                         {"epp", UINT_MAX},
153                         {"emc", HOST_EMC_FLOOR} },
154         NVHOST_MODULE_NO_POWERGATE_IDS,
155         NVHOST_DEFAULT_CLOCKGATE_DELAY,
156         .moduleid      = NVHOST_MODULE_NONE,
157 };
158
159 static struct resource isp_resources[] = {
160         {
161                 .name = "regs",
162                 .start = TEGRA_ISP_BASE,
163                 .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1,
164                 .flags = IORESOURCE_MEM,
165         }
166 };
167
168 static struct nvhost_device tegra_isp01_device = {
169         .name    = "isp",
170         .id      = -1,
171         .resource = isp_resources,
172         .num_resources = ARRAY_SIZE(isp_resources),
173         .index   = 3,
174         .syncpts = 0,
175         NVHOST_MODULE_NO_POWERGATE_IDS,
176         NVHOST_DEFAULT_CLOCKGATE_DELAY,
177         .moduleid      = NVHOST_MODULE_ISP,
178 };
179
180 static struct resource vi_resources[] = {
181         {
182                 .name = "regs",
183                 .start = TEGRA_VI_BASE,
184                 .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1,
185                 .flags = IORESOURCE_MEM,
186         },
187 };
188
189 static struct nvhost_device tegra_vi01_device = {
190         .name          = "vi",
191         .id            = -1,
192         .resource      = vi_resources,
193         .num_resources = ARRAY_SIZE(vi_resources),
194         .index         = 4,
195         .syncpts       = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) |
196                          BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) |
197                          BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
198                          BIT(NVSYNCPT_VI_ISP_4),
199         .modulemutexes = BIT(NVMODMUTEX_VI),
200         .exclusive     = true,
201         NVHOST_MODULE_NO_POWERGATE_IDS,
202         NVHOST_DEFAULT_CLOCKGATE_DELAY,
203         .moduleid      = NVHOST_MODULE_VI,
204 };
205
206 static struct resource msenc_resources[] = {
207         {
208                 .name = "regs",
209                 .start = TEGRA_MSENC_BASE,
210                 .end = TEGRA_MSENC_BASE + TEGRA_MSENC_SIZE - 1,
211                 .flags = IORESOURCE_MEM,
212         },
213 };
214
215 static struct nvhost_device tegra_msenc02_device = {
216         .name          = "msenc",
217         .id            = -1,
218         .resource      = msenc_resources,
219         .num_resources = ARRAY_SIZE(msenc_resources),
220         .index         = 5,
221         .syncpts       = BIT(NVSYNCPT_MSENC),
222         .waitbases     = BIT(NVWAITBASE_MSENC),
223         .class         = NV_VIDEO_ENCODE_MSENC_CLASS_ID,
224         .exclusive     = false,
225         .keepalive     = true,
226         .clocks = {{"msenc", UINT_MAX}, {"emc", HOST_EMC_FLOOR} },
227         NVHOST_MODULE_NO_POWERGATE_IDS,
228         NVHOST_DEFAULT_CLOCKGATE_DELAY,
229         .moduleid      = NVHOST_MODULE_MSENC,
230 };
231
232 static struct nvhost_device tegra_dsi01_device = {
233         .name          = "dsi",
234         .id            = -1,
235         .index         = 6,
236         .syncpts       = BIT(NVSYNCPT_DSI),
237         .modulemutexes = BIT(NVMODMUTEX_DSI),
238         NVHOST_MODULE_NO_POWERGATE_IDS,
239         NVHOST_DEFAULT_CLOCKGATE_DELAY,
240         .moduleid      = NVHOST_MODULE_NONE,
241 };
242
243 static struct resource tsec_resources[] = {
244         {
245                 .name = "regs",
246                 .start = TEGRA_TSEC_BASE,
247                 .end = TEGRA_TSEC_BASE + TEGRA_TSEC_SIZE - 1,
248                 .flags = IORESOURCE_MEM,
249         },
250 };
251
252 static struct nvhost_device tegra_tsec01_device = {
253         /* channel 7 */
254         .name          = "tsec",
255         .id            = -1,
256         .resource      = tsec_resources,
257         .num_resources = ARRAY_SIZE(tsec_resources),
258         .index         = 7,
259         .syncpts       = BIT(NVSYNCPT_TSEC),
260         .waitbases     = BIT(NVWAITBASE_TSEC),
261         .class         = NV_TSEC_CLASS_ID,
262         .exclusive     = false,
263         .clocks = {{"tsec", UINT_MAX}, {"emc", HOST_EMC_FLOOR} },
264         NVHOST_MODULE_NO_POWERGATE_IDS,
265         NVHOST_DEFAULT_CLOCKGATE_DELAY,
266         .moduleid      = NVHOST_MODULE_TSEC,
267 };
268
269 static struct nvhost_device *t11_devices[] = {
270         &tegra_host1x02_device,
271         &tegra_display01_device,
272         &tegra_gr3d03_device,
273         &tegra_gr2d03_device,
274         &tegra_isp01_device,
275         &tegra_vi01_device,
276         &tegra_msenc02_device,
277         &tegra_dsi01_device,
278         &tegra_tsec01_device,
279 };
280
281 int tegra11_register_host1x_devices(void)
282 {
283         return nvhost_add_devices(t11_devices, ARRAY_SIZE(t11_devices));
284 }
285
286 static inline int t114_nvhost_hwctx_handler_init(struct nvhost_channel *ch)
287 {
288         int err = 0;
289         unsigned long syncpts = ch->dev->syncpts;
290         unsigned long waitbases = ch->dev->waitbases;
291         u32 syncpt = find_first_bit(&syncpts, BITS_PER_LONG);
292         u32 waitbase = find_first_bit(&waitbases, BITS_PER_LONG);
293         struct nvhost_driver *drv = to_nvhost_driver(ch->dev->dev.driver);
294
295         if (drv->alloc_hwctx_handler) {
296                 ch->ctxhandler = drv->alloc_hwctx_handler(syncpt,
297                                 waitbase, ch);
298                 if (!ch->ctxhandler)
299                         err = -ENOMEM;
300         }
301
302         return err;
303 }
304
305 static inline void __iomem *t114_channel_aperture(void __iomem *p, int ndx)
306 {
307         p += ndx * NV_HOST1X_CHANNEL_MAP_SIZE_BYTES;
308         return p;
309 }
310
311 static int t114_channel_init(struct nvhost_channel *ch,
312                             struct nvhost_master *dev, int index)
313 {
314         ch->chid = index;
315         mutex_init(&ch->reflock);
316         mutex_init(&ch->submitlock);
317
318         ch->aperture = t114_channel_aperture(dev->aperture, index);
319
320         return t114_nvhost_hwctx_handler_init(ch);
321 }
322
323 int nvhost_init_t114_channel_support(struct nvhost_master *host,
324         struct nvhost_chip_support *op)
325 {
326         int result = nvhost_init_t20_channel_support(host, op);
327         /* We're using 8 out of 9 channels supported by hw */
328         op->channel.init = t114_channel_init;
329
330         return result;
331 }
332
333 static void t114_free_nvhost_channel(struct nvhost_channel *ch)
334 {
335         nvhost_free_channel_internal(ch, &t114_num_alloc_channels);
336 }
337
338 static struct nvhost_channel *t114_alloc_nvhost_channel(
339                 struct nvhost_device *dev)
340 {
341         return nvhost_alloc_channel_internal(dev->index,
342                 nvhost_get_host(dev)->info.nb_channels,
343                 &t114_num_alloc_channels);
344 }
345
346 int nvhost_init_t114_support(struct nvhost_master *host,
347         struct nvhost_chip_support *op)
348 {
349         int err;
350
351         /* don't worry about cleaning up on failure... "remove" does it. */
352         err = nvhost_init_t114_channel_support(host, op);
353         if (err)
354                 return err;
355         err = host1x_init_cdma_support(op);
356         if (err)
357                 return err;
358         err = nvhost_init_t20_debug_support(op);
359         if (err)
360                 return err;
361         err = host1x_init_syncpt_support(host, op);
362         if (err)
363                 return err;
364         err = nvhost_init_t20_intr_support(op);
365         if (err)
366                 return err;
367         err = nvhost_memmgr_init(op);
368         if (err)
369                 return err;
370         op->nvhost_dev.alloc_nvhost_channel = t114_alloc_nvhost_channel;
371         op->nvhost_dev.free_nvhost_channel = t114_free_nvhost_channel;
372
373         /* Initialize T114 3D actmon */
374         err = host1x_actmon_init(host);
375
376         return 0;
377 }