video: tegra: host: Parameterize Tegra11 modules
[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          = "gr3d03",
129         .id            = -1,
130         .index         = 1,
131         .syncpts       = BIT(NVSYNCPT_3D),
132         .waitbases     = BIT(NVWAITBASE_3D),
133         .modulemutexes = BIT(NVMODMUTEX_3D),
134         .class         = NV_GRAPHICS_3D_CLASS_ID,
135         .clocks = {{"gr3d", UINT_MAX},
136                         {"emc", HOST_EMC_FLOOR} },
137         NVHOST_MODULE_NO_POWERGATE_IDS,
138         NVHOST_DEFAULT_CLOCKGATE_DELAY,
139         .moduleid      = NVHOST_MODULE_NONE,
140 };
141
142 static struct nvhost_device tegra_gr2d03_device = {
143         .name          = "gr2d",
144         .id            = -1,
145         .index         = 2,
146         .syncpts       = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1),
147         .waitbases     = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
148         .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
149                          BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
150         .clocks = {{"gr2d", 0},
151                         {"epp", UINT_MAX},
152                         {"emc", HOST_EMC_FLOOR} },
153         NVHOST_MODULE_NO_POWERGATE_IDS,
154         NVHOST_DEFAULT_CLOCKGATE_DELAY,
155         .moduleid      = NVHOST_MODULE_NONE,
156 };
157
158 static struct resource isp_resources[] = {
159         {
160                 .name = "regs",
161                 .start = TEGRA_ISP_BASE,
162                 .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1,
163                 .flags = IORESOURCE_MEM,
164         }
165 };
166
167 static struct nvhost_device tegra_isp01_device = {
168         .name    = "isp",
169         .id      = -1,
170         .resource = isp_resources,
171         .num_resources = ARRAY_SIZE(isp_resources),
172         .index   = 3,
173         .syncpts = 0,
174         NVHOST_MODULE_NO_POWERGATE_IDS,
175         NVHOST_DEFAULT_CLOCKGATE_DELAY,
176         .moduleid      = NVHOST_MODULE_ISP,
177 };
178
179 static struct resource vi_resources[] = {
180         {
181                 .name = "regs",
182                 .start = TEGRA_VI_BASE,
183                 .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1,
184                 .flags = IORESOURCE_MEM,
185         },
186 };
187
188 static struct nvhost_device tegra_vi01_device = {
189         .name          = "vi",
190         .id            = -1,
191         .resource      = vi_resources,
192         .num_resources = ARRAY_SIZE(vi_resources),
193         .index         = 4,
194         .syncpts       = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) |
195                          BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) |
196                          BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
197                          BIT(NVSYNCPT_VI_ISP_4),
198         .modulemutexes = BIT(NVMODMUTEX_VI),
199         .exclusive     = true,
200         NVHOST_MODULE_NO_POWERGATE_IDS,
201         NVHOST_DEFAULT_CLOCKGATE_DELAY,
202         .moduleid      = NVHOST_MODULE_VI,
203 };
204
205 static struct resource msenc_resources[] = {
206         {
207                 .name = "regs",
208                 .start = TEGRA_MSENC_BASE,
209                 .end = TEGRA_MSENC_BASE + TEGRA_MSENC_SIZE - 1,
210                 .flags = IORESOURCE_MEM,
211         },
212 };
213
214 static struct nvhost_device tegra_msenc02_device = {
215         .name          = "msenc",
216         .id            = -1,
217         .resource      = msenc_resources,
218         .num_resources = ARRAY_SIZE(msenc_resources),
219         .index         = 5,
220         .syncpts       = BIT(NVSYNCPT_MSENC),
221         .waitbases     = BIT(NVWAITBASE_MSENC),
222         .class         = NV_VIDEO_ENCODE_MSENC_CLASS_ID,
223         .exclusive     = false,
224         .keepalive     = true,
225         .clocks = {{"msenc", UINT_MAX}, {"emc", HOST_EMC_FLOOR} },
226         NVHOST_MODULE_NO_POWERGATE_IDS,
227         NVHOST_DEFAULT_CLOCKGATE_DELAY,
228         .moduleid      = NVHOST_MODULE_MSENC,
229 };
230
231 static struct nvhost_device tegra_dsi01_device = {
232         .name          = "dsi",
233         .id            = -1,
234         .index         = 6,
235         .syncpts       = BIT(NVSYNCPT_DSI),
236         .modulemutexes = BIT(NVMODMUTEX_DSI),
237         NVHOST_MODULE_NO_POWERGATE_IDS,
238         NVHOST_DEFAULT_CLOCKGATE_DELAY,
239         .moduleid      = NVHOST_MODULE_NONE,
240 };
241
242 static struct resource tsec_resources[] = {
243         {
244                 .name = "regs",
245                 .start = TEGRA_TSEC_BASE,
246                 .end = TEGRA_TSEC_BASE + TEGRA_TSEC_SIZE - 1,
247                 .flags = IORESOURCE_MEM,
248         },
249 };
250
251 static struct nvhost_device tegra_tsec01_device = {
252         /* channel 7 */
253         .name          = "tsec",
254         .id            = -1,
255         .resource      = tsec_resources,
256         .num_resources = ARRAY_SIZE(tsec_resources),
257         .index         = 7,
258         .syncpts       = BIT(NVSYNCPT_TSEC),
259         .waitbases     = BIT(NVWAITBASE_TSEC),
260         .class         = NV_TSEC_CLASS_ID,
261         .exclusive     = false,
262         .clocks = {{"tsec", UINT_MAX}, {"emc", HOST_EMC_FLOOR} },
263         NVHOST_MODULE_NO_POWERGATE_IDS,
264         NVHOST_DEFAULT_CLOCKGATE_DELAY,
265         .moduleid      = NVHOST_MODULE_TSEC,
266 };
267
268 static struct nvhost_device *t11_devices[] = {
269         &tegra_host1x02_device,
270         &tegra_display01_device,
271         &tegra_gr3d03_device,
272         &tegra_gr2d03_device,
273         &tegra_isp01_device,
274         &tegra_vi01_device,
275         &tegra_msenc02_device,
276         &tegra_dsi01_device,
277         &tegra_tsec01_device,
278 };
279
280 int tegra11_register_host1x_devices(void)
281 {
282         return nvhost_add_devices(t11_devices, ARRAY_SIZE(t11_devices));
283 }
284
285 static inline int t114_nvhost_hwctx_handler_init(struct nvhost_channel *ch)
286 {
287         int err = 0;
288         unsigned long syncpts = ch->dev->syncpts;
289         unsigned long waitbases = ch->dev->waitbases;
290         u32 syncpt = find_first_bit(&syncpts, BITS_PER_LONG);
291         u32 waitbase = find_first_bit(&waitbases, BITS_PER_LONG);
292         struct nvhost_driver *drv = to_nvhost_driver(ch->dev->dev.driver);
293
294         if (drv->alloc_hwctx_handler) {
295                 ch->ctxhandler = drv->alloc_hwctx_handler(syncpt,
296                                 waitbase, ch);
297                 if (!ch->ctxhandler)
298                         err = -ENOMEM;
299         }
300
301         return err;
302 }
303
304 static inline void __iomem *t114_channel_aperture(void __iomem *p, int ndx)
305 {
306         p += ndx * NV_HOST1X_CHANNEL_MAP_SIZE_BYTES;
307         return p;
308 }
309
310 static int t114_channel_init(struct nvhost_channel *ch,
311                             struct nvhost_master *dev, int index)
312 {
313         ch->chid = index;
314         mutex_init(&ch->reflock);
315         mutex_init(&ch->submitlock);
316
317         ch->aperture = t114_channel_aperture(dev->aperture, index);
318
319         return t114_nvhost_hwctx_handler_init(ch);
320 }
321
322 int nvhost_init_t114_channel_support(struct nvhost_master *host,
323         struct nvhost_chip_support *op)
324 {
325         int result = nvhost_init_t20_channel_support(host, op);
326         /* We're using 8 out of 9 channels supported by hw */
327         op->channel.init = t114_channel_init;
328
329         return result;
330 }
331
332 static void t114_free_nvhost_channel(struct nvhost_channel *ch)
333 {
334         nvhost_free_channel_internal(ch, &t114_num_alloc_channels);
335 }
336
337 static struct nvhost_channel *t114_alloc_nvhost_channel(
338                 struct nvhost_device *dev)
339 {
340         return nvhost_alloc_channel_internal(dev->index,
341                 nvhost_get_host(dev)->info.nb_channels,
342                 &t114_num_alloc_channels);
343 }
344
345 int nvhost_init_t114_support(struct nvhost_master *host,
346         struct nvhost_chip_support *op)
347 {
348         int err;
349
350         /* don't worry about cleaning up on failure... "remove" does it. */
351         err = nvhost_init_t114_channel_support(host, op);
352         if (err)
353                 return err;
354         err = host1x_init_cdma_support(op);
355         if (err)
356                 return err;
357         err = nvhost_init_t20_debug_support(op);
358         if (err)
359                 return err;
360         err = host1x_init_syncpt_support(host, op);
361         if (err)
362                 return err;
363         err = nvhost_init_t20_intr_support(op);
364         if (err)
365                 return err;
366         err = nvhost_memmgr_init(op);
367         if (err)
368                 return err;
369         op->nvhost_dev.alloc_nvhost_channel = t114_alloc_nvhost_channel;
370         op->nvhost_dev.free_nvhost_channel = t114_free_nvhost_channel;
371
372         /* Initialize T114 3D actmon */
373         err = host1x_actmon_init(host);
374
375         return 0;
376 }