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