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