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