video: tegra: host: Remove version from dev name
[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/slab.h>
22 #include <linux/nvhost_ioctl.h>
23 #include <mach/powergate.h>
24 #include <mach/iomap.h>
25 #include "t20.h"
26 #include "host1x/host1x_syncpt.h"
27 #include "host1x/host1x_hardware.h"
28 #include "gr3d/gr3d.h"
29 #include "gr3d/gr3d_t20.h"
30 #include "mpe/mpe.h"
31 #include "host1x/host1x.h"
32 #include "nvhost_hwctx.h"
33 #include "nvhost_channel.h"
34 #include "host1x/host1x_channel.h"
35 #include "host1x/host1x_cdma.h"
36 #include "chip_support.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 t20_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_gr3d01_device = {
121         .name           = "gr3d",
122         .version        = 1,
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}, {"emc", UINT_MAX}, {} },
130         .powergate_ids  = {TEGRA_POWERGATE_3D, -1},
131         NVHOST_DEFAULT_CLOCKGATE_DELAY,
132         .moduleid       = NVHOST_MODULE_NONE,
133 };
134
135 static struct nvhost_device tegra_gr2d01_device = {
136         .name           = "gr2d",
137         .id             = -1,
138         .index          = 2,
139         .syncpts        = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1),
140         .waitbases      = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
141         .modulemutexes  = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
142                           BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
143         .clocks         = { {"gr2d", UINT_MAX},
144                             {"epp", UINT_MAX},
145                             {"emc", UINT_MAX} },
146         NVHOST_MODULE_NO_POWERGATE_IDS,
147         .clockgate_delay = 0,
148         .moduleid       = NVHOST_MODULE_NONE,
149 };
150
151 static struct resource isp_resources_t20[] = {
152         {
153                 .name = "regs",
154                 .start = TEGRA_ISP_BASE,
155                 .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1,
156                 .flags = IORESOURCE_MEM,
157         }
158 };
159
160 static struct nvhost_device tegra_isp01_device = {
161         .name           = "isp",
162         .id             = -1,
163         .resource = isp_resources_t20,
164         .num_resources = ARRAY_SIZE(isp_resources_t20),
165         .index          = 3,
166         .syncpts        = 0,
167         NVHOST_MODULE_NO_POWERGATE_IDS,
168         NVHOST_DEFAULT_CLOCKGATE_DELAY,
169         .moduleid       = NVHOST_MODULE_ISP,
170 };
171
172 static struct resource vi_resources[] = {
173         {
174                 .name = "regs",
175                 .start = TEGRA_VI_BASE,
176                 .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1,
177                 .flags = IORESOURCE_MEM,
178         },
179 };
180
181 static struct nvhost_device tegra_vi01_device = {
182         .name           = "vi",
183         .resource = vi_resources,
184         .num_resources = ARRAY_SIZE(vi_resources),
185         .id             = -1,
186         .index          = 4,
187         .syncpts        = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) |
188                           BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) |
189                           BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
190                           BIT(NVSYNCPT_VI_ISP_4),
191         .modulemutexes  = BIT(NVMODMUTEX_VI),
192         .exclusive      = true,
193         NVHOST_MODULE_NO_POWERGATE_IDS,
194         NVHOST_DEFAULT_CLOCKGATE_DELAY,
195         .moduleid       = NVHOST_MODULE_VI,
196 };
197
198 static struct resource tegra_mpe01_resources[] = {
199         {
200                 .name = "regs",
201                 .start = TEGRA_MPE_BASE,
202                 .end = TEGRA_MPE_BASE + TEGRA_MPE_SIZE - 1,
203                 .flags = IORESOURCE_MEM,
204         },
205 };
206
207 static struct nvhost_device tegra_mpe01_device = {
208         .name           = "mpe",
209         .version        = 1,
210         .id             = -1,
211         .resource       = tegra_mpe01_resources,
212         .num_resources  = ARRAY_SIZE(tegra_mpe01_resources),
213         .index          = 5,
214         .syncpts        = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) |
215                           BIT(NVSYNCPT_MPE_WR_SAFE),
216         .waitbases      = BIT(NVWAITBASE_MPE),
217         .class          = NV_VIDEO_ENCODE_MPEG_CLASS_ID,
218         .waitbasesync   = true,
219         .keepalive      = true,
220         .clocks         = { {"mpe", UINT_MAX},
221                             {"emc", UINT_MAX} },
222         .powergate_ids  = {TEGRA_POWERGATE_MPE, -1},
223         NVHOST_DEFAULT_CLOCKGATE_DELAY,
224         .moduleid       = NVHOST_MODULE_MPE,
225 };
226
227 static struct nvhost_device tegra_dsi01_device = {
228         .name           = "dsi",
229         .id             = -1,
230         .index          = 6,
231         .syncpts        = BIT(NVSYNCPT_DSI),
232         .modulemutexes  = BIT(NVMODMUTEX_DSI),
233         NVHOST_MODULE_NO_POWERGATE_IDS,
234         NVHOST_DEFAULT_CLOCKGATE_DELAY,
235         .moduleid       = NVHOST_MODULE_NONE,
236 };
237
238 static struct nvhost_device *t20_devices[] = {
239         &tegra_host1x01_device,
240         &tegra_display01_device,
241         &tegra_gr3d01_device,
242         &tegra_gr2d01_device,
243         &tegra_isp01_device,
244         &tegra_vi01_device,
245         &tegra_mpe01_device,
246         &tegra_dsi01_device,
247 };
248
249 int tegra2_register_host1x_devices(void)
250 {
251         return nvhost_add_devices(t20_devices, ARRAY_SIZE(t20_devices));
252 }
253
254 static inline void __iomem *t20_channel_aperture(void __iomem *p, int ndx)
255 {
256         p += ndx * NV_HOST1X_CHANNEL_MAP_SIZE_BYTES;
257         return p;
258 }
259
260 static inline int t20_nvhost_hwctx_handler_init(struct nvhost_channel *ch)
261 {
262         int err = 0;
263         unsigned long syncpts = ch->dev->syncpts;
264         unsigned long waitbases = ch->dev->waitbases;
265         u32 syncpt = find_first_bit(&syncpts, BITS_PER_LONG);
266         u32 waitbase = find_first_bit(&waitbases, BITS_PER_LONG);
267         struct nvhost_driver *drv = to_nvhost_driver(ch->dev->dev.driver);
268
269         if (drv->alloc_hwctx_handler) {
270                 ch->ctxhandler = drv->alloc_hwctx_handler(syncpt,
271                                 waitbase, ch);
272                 if (!ch->ctxhandler)
273                         err = -ENOMEM;
274         }
275
276         return err;
277 }
278
279 static int t20_channel_init(struct nvhost_channel *ch,
280         struct nvhost_master *dev, int index)
281 {
282         ch->chid = index;
283         mutex_init(&ch->reflock);
284         mutex_init(&ch->submitlock);
285
286         ch->aperture = t20_channel_aperture(dev->aperture, index);
287
288         return t20_nvhost_hwctx_handler_init(ch);
289 }
290
291 int nvhost_init_t20_channel_support(struct nvhost_master *host,
292         struct nvhost_chip_support *op)
293 {
294         op->channel.init = t20_channel_init;
295         op->channel.submit = host1x_channel_submit;
296         op->channel.read3dreg = host1x_channel_read_3d_reg;
297
298         return 0;
299 }
300
301 static void t20_free_nvhost_channel(struct nvhost_channel *ch)
302 {
303         nvhost_free_channel_internal(ch, &t20_num_alloc_channels);
304 }
305
306 static struct nvhost_channel *t20_alloc_nvhost_channel(
307                 struct nvhost_device *dev)
308 {
309         return nvhost_alloc_channel_internal(dev->index,
310                 nvhost_get_host(dev)->info.nb_channels,
311                 &t20_num_alloc_channels);
312 }
313
314 int nvhost_init_t20_support(struct nvhost_master *host,
315         struct nvhost_chip_support *op)
316 {
317         int err;
318
319         /* don't worry about cleaning up on failure... "remove" does it. */
320         err = nvhost_init_t20_channel_support(host, op);
321         if (err)
322                 return err;
323         err = host1x_init_cdma_support(op);
324         if (err)
325                 return err;
326         err = nvhost_init_t20_debug_support(op);
327         if (err)
328                 return err;
329         err = host1x_init_syncpt_support(host, op);
330         if (err)
331                 return err;
332         err = nvhost_init_t20_intr_support(op);
333         if (err)
334                 return err;
335         err = nvhost_memmgr_init(op);
336
337         op->nvhost_dev.alloc_nvhost_channel = t20_alloc_nvhost_channel;
338         op->nvhost_dev.free_nvhost_channel = t20_free_nvhost_channel;
339
340         return 0;
341 }