425b352a66a8f3576482740764f9b50ba7492616
[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, 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/mutex.h>
24 #include <mach/powergate.h>
25 #include "dev.h"
26 #include "t30.h"
27 #include "gr3d/gr3d.h"
28 #include "mpe/mpe.h"
29 #include "gr3d/gr3d_t30.h"
30 #include "gr3d/scale3d.h"
31 #include "host1x/host1x_hardware.h"
32 #include "host1x/host1x_cdma.h"
33 #include "host1x/host1x_syncpt.h"
34 #include "gr3d/scale3d.h"
35 #include "../chip_support.h"
36
37 static struct nvhost_device devices[] = {
38         {.name   = "gr3d", .id = -1 },
39         {.name = "gr2d", .id = -1 },
40         {.name = "isp", .id = -1 },
41         {.name = "vi", .id = -1 },
42         {.name = "mpe", .id = -1 },
43         {.name = "dsi", .id = -1 },
44 };
45
46 #define NVMODMUTEX_2D_FULL   (1)
47 #define NVMODMUTEX_2D_SIMPLE (2)
48 #define NVMODMUTEX_2D_SB_A   (3)
49 #define NVMODMUTEX_2D_SB_B   (4)
50 #define NVMODMUTEX_3D        (5)
51 #define NVMODMUTEX_DISPLAYA  (6)
52 #define NVMODMUTEX_DISPLAYB  (7)
53 #define NVMODMUTEX_VI        (8)
54 #define NVMODMUTEX_DSI       (9)
55
56 #ifndef TEGRA_POWERGATE_3D1
57 #define TEGRA_POWERGATE_3D1 -1
58 #endif
59
60 const struct nvhost_channeldesc nvhost_t30_channelmap[] = {
61 {
62         /* channel 0 */
63         .name          = "display",
64         .syncpts       = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) |
65                          BIT(NVSYNCPT_DISP0_B) | BIT(NVSYNCPT_DISP1_B) |
66                          BIT(NVSYNCPT_DISP0_C) | BIT(NVSYNCPT_DISP1_C) |
67                          BIT(NVSYNCPT_VBLANK0) | BIT(NVSYNCPT_VBLANK1),
68         .modulemutexes = BIT(NVMODMUTEX_DISPLAYA) | BIT(NVMODMUTEX_DISPLAYB),
69         .module        = {
70                         NVHOST_MODULE_NO_POWERGATE_IDS,
71                         NVHOST_DEFAULT_CLOCKGATE_DELAY,
72                         },
73 },
74 {
75         /* channel 1 */
76         .name          = "gr3d",
77         .syncpts       = BIT(NVSYNCPT_3D),
78         .waitbases     = BIT(NVWAITBASE_3D),
79         .modulemutexes = BIT(NVMODMUTEX_3D),
80         .class         = NV_GRAPHICS_3D_CLASS_ID,
81         .module        = {
82                         .prepare_poweroff = nvhost_gr3d_prepare_power_off,
83                         .busy = nvhost_scale3d_notify_busy,
84                         .idle = nvhost_scale3d_notify_idle,
85                         .init = nvhost_scale3d_init,
86                         .deinit = nvhost_scale3d_deinit,
87                         .suspend = nvhost_scale3d_suspend,
88                         .clocks = {{"gr3d", UINT_MAX},
89                                         {"gr3d2", UINT_MAX},
90                                         {"emc", UINT_MAX} },
91                         .powergate_ids = {TEGRA_POWERGATE_3D,
92                                         TEGRA_POWERGATE_3D1},
93                         NVHOST_DEFAULT_CLOCKGATE_DELAY,
94                         .can_powergate = true,
95                         .powergate_delay = 100,
96         },
97 },
98 {
99         /* channel 2 */
100         .name          = "gr2d",
101         .syncpts       = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1),
102         .waitbases     = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
103         .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
104                          BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
105         .module        = {
106                         .clocks = {{"gr2d", 0},
107                                         {"epp", 0},
108                                         {"emc", 300000000} },
109                         NVHOST_MODULE_NO_POWERGATE_IDS,
110                         .clockgate_delay = 0,
111                         },
112 },
113 {
114         /* channel 3 */
115         .name    = "isp",
116         .syncpts = 0,
117         .module         = {
118                         NVHOST_MODULE_NO_POWERGATE_IDS,
119                         NVHOST_DEFAULT_CLOCKGATE_DELAY,
120                         },
121 },
122 {
123         /* channel 4 */
124         .name          = "vi",
125         .syncpts       = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) |
126                          BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) |
127                          BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
128                          BIT(NVSYNCPT_VI_ISP_4),
129         .modulemutexes = BIT(NVMODMUTEX_VI),
130         .exclusive     = true,
131         .module        = {
132                         NVHOST_MODULE_NO_POWERGATE_IDS,
133                         NVHOST_DEFAULT_CLOCKGATE_DELAY,
134                         },
135 },
136 {
137         /* channel 5 */
138         .name          = "mpe",
139         .syncpts       = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) |
140                          BIT(NVSYNCPT_MPE_WR_SAFE),
141         .waitbases     = BIT(NVWAITBASE_MPE),
142         .class         = NV_VIDEO_ENCODE_MPEG_CLASS_ID,
143         .waitbasesync  = true,
144         .keepalive     = true,
145         .module        = {
146                         .prepare_poweroff = nvhost_mpe_prepare_power_off,
147                         .clocks = {{"mpe", UINT_MAX}, {"emc", UINT_MAX}, {} },
148                         .powergate_ids  = {TEGRA_POWERGATE_MPE, -1},
149                         NVHOST_DEFAULT_CLOCKGATE_DELAY,
150                         .can_powergate  = true,
151                         .powergate_delay = 100,
152                         },
153 },
154 {
155         /* channel 6 */
156         .name          = "dsi",
157         .syncpts       = BIT(NVSYNCPT_DSI),
158         .modulemutexes = BIT(NVMODMUTEX_DSI),
159         .module        = {
160                         NVHOST_MODULE_NO_POWERGATE_IDS,
161                         NVHOST_DEFAULT_CLOCKGATE_DELAY,
162         },
163 } };
164
165 #define NVHOST_CHANNEL_BASE 0
166
167 static inline int t30_nvhost_hwctx_handler_init(
168         struct nvhost_hwctx_handler *h,
169         const char *module)
170 {
171         if (strcmp(module, "gr3d") == 0)
172                 return nvhost_gr3d_t30_ctxhandler_init(h);
173         else if (strcmp(module, "mpe") == 0)
174                 return nvhost_mpe_ctxhandler_init(h);
175
176         return 0;
177 }
178
179 static inline void __iomem *t30_channel_aperture(void __iomem *p, int ndx)
180 {
181         ndx += NVHOST_CHANNEL_BASE;
182         p += NV_HOST1X_CHANNEL0_BASE;
183         p += ndx * NV_HOST1X_CHANNEL_MAP_SIZE_BYTES;
184         return p;
185 }
186
187 static int t30_channel_init(struct nvhost_channel *ch,
188                             struct nvhost_master *dev, int index)
189 {
190         ch->dev = dev;
191         ch->chid = index;
192         ch->desc = nvhost_t30_channelmap + index;
193         mutex_init(&ch->reflock);
194         mutex_init(&ch->submitlock);
195
196         ch->aperture = t30_channel_aperture(dev->aperture, index);
197
198         return t30_nvhost_hwctx_handler_init(&ch->ctxhandler, ch->desc->name);
199 }
200
201 int nvhost_init_t30_channel_support(struct nvhost_master *host)
202 {
203         int result = nvhost_init_t20_channel_support(host);
204         host->op.channel.init = t30_channel_init;
205
206         return result;
207 }
208 int nvhost_init_t30_debug_support(struct nvhost_master *host)
209 {
210         nvhost_init_t20_debug_support(host);
211         host->op.debug.debug_init = nvhost_scale3d_debug_init;
212
213         return 0;
214 }
215
216 int nvhost_init_t30_support(struct nvhost_master *host)
217 {
218         int err;
219         int i;
220
221         for (i = 0; i < ARRAY_SIZE(devices); i++)
222                 nvhost_device_register(&devices[i]);
223
224         /* don't worry about cleaning up on failure... "remove" does it. */
225         err = nvhost_init_t30_channel_support(host);
226         if (err)
227                 return err;
228         err = host1x_init_cdma_support(host);
229         if (err)
230                 return err;
231         err = nvhost_init_t30_debug_support(host);
232         if (err)
233                 return err;
234         err = host1x_init_syncpt_support(host);
235         if (err)
236                 return err;
237         err = nvhost_init_t20_intr_support(host);
238         if (err)
239                 return err;
240         err = nvhost_init_t20_cpuaccess_support(host);
241         if (err)
242                 return err;
243         return 0;
244 }