video: tegra: host: Tegra12 updates to Tegra14 support
[linux-3.10.git] / drivers / video / tegra / host / t148 / t148.c
1 /*
2  * drivers/video/tegra/host/t148/t148.c
3  *
4  * Tegra Graphics Init for T148 Architecture Chips
5  *
6  * Copyright (c) 2012-2013, 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 <mach/powergate.h>
23 #include <linux/nvhost.h>
24
25 #include "dev.h"
26 #include "class_ids.h"
27 #include "host1x/host1x_cdma.h"
28 #include "t20/t20.h"
29 #include "t30/t30.h"
30 #include "t148/t148.h"
31 #include "t114/t114.h"
32 #include "host1x/host1x03_hardware.h"
33 #include "gr2d/gr2d_t114.h"
34 #include "gr3d/gr3d.h"
35 #include "gr3d/gr3d_t30.h"
36 #include "gr3d/gr3d_t114.h"
37 #include "gr3d/scale3d.h"
38 #include "nvhost_scale.h"
39 #include "gr3d/pod_scaling.h"
40 #include "msenc/msenc.h"
41 #include "tsec/tsec.h"
42 #include "linux/nvhost_ioctl.h"
43 #include "nvhost_channel.h"
44 #include "nvhost_memmgr.h"
45 #include "chip_support.h"
46 #include "class_ids.h"
47
48 /* HACK! This needs to come from DT */
49 #include "../../../../../arch/arm/mach-tegra/iomap.h"
50
51 static int t148_num_alloc_channels = 0;
52
53 static struct resource tegra_host1x03_resources[] = {
54         {
55                 .start = TEGRA_HOST1X_BASE,
56                 .end = TEGRA_HOST1X_BASE + TEGRA_HOST1X_SIZE - 1,
57                 .flags = IORESOURCE_MEM,
58         },
59         {
60                 .start = INT_HOST1X_MPCORE_SYNCPT,
61                 .end = INT_HOST1X_MPCORE_SYNCPT,
62                 .flags = IORESOURCE_IRQ,
63         },
64         {
65                 .start = INT_HOST1X_MPCORE_GENERAL,
66                 .end = INT_HOST1X_MPCORE_GENERAL,
67                 .flags = IORESOURCE_IRQ,
68         },
69 };
70
71 static const char *s_syncpt_names[48] = {
72         "gfx_host",
73         "", "", "", "", "", "", "",
74         "disp0_a", "disp1_a", "avp_0",
75         "csi_vi_0", "csi_vi_1",
76         "vi_isp_0", "vi_isp_1", "vi_isp_2", "vi_isp_3", "vi_isp_4",
77         "2d_0", "2d_1",
78         "disp0_b", "disp1_b",
79         "3d",
80         "msenc",
81         "disp0_c", "disp1_c",
82         "vblank0", "vblank1",
83         "tsec", "msenc_unused",
84         "2d_tinyblt",
85         "dsi"
86 };
87
88 static struct host1x_device_info host1x03_info = {
89         .nb_channels    = 12,
90         .nb_pts         = 48,
91         .nb_mlocks      = 16,
92         .nb_bases       = 12,
93         .syncpt_names   = s_syncpt_names,
94         .client_managed = NVSYNCPTS_CLIENT_MANAGED,
95 };
96
97 struct nvhost_device_data t14_host1x_info = {
98         .clocks         = { {"host1x", 81600000} },
99         NVHOST_MODULE_NO_POWERGATE_IDS,
100         .private_data   = &host1x03_info,
101 };
102
103 static struct platform_device tegra_host1x03_device = {
104         .name           = "host1x",
105         .id             = -1,
106         .resource       = tegra_host1x03_resources,
107         .num_resources  = ARRAY_SIZE(tegra_host1x03_resources),
108         .dev            = {
109                 .platform_data = &t14_host1x_info,
110         },
111 };
112
113 struct nvhost_device_data t14_gr3d_info = {
114         .version        = 3,
115         .index          = 1,
116         .syncpts        = {NVSYNCPT_3D},
117         .waitbases      = {NVWAITBASE_3D},
118         .modulemutexes  = {NVMODMUTEX_3D},
119         .class          = NV_GRAPHICS_3D_CLASS_ID,
120         .clocks         = { {"gr3d", UINT_MAX, 8, true},
121                             {"emc", UINT_MAX, 75} },
122         .powergate_ids  = { TEGRA_POWERGATE_3D, -1 },
123         NVHOST_DEFAULT_CLOCKGATE_DELAY,
124         .can_powergate  = true,
125         .powergate_delay = 250,
126         .powerup_reset  = true,
127         .moduleid       = NVHOST_MODULE_NONE,
128
129         .busy           = nvhost_scale_notify_busy,
130         .idle           = nvhost_scale_notify_idle,
131         .init           = nvhost_scale_hw_init,
132         .deinit         = nvhost_scale_hw_deinit,
133         .scaling_init   = nvhost_scale3d_init,
134         .scaling_deinit = nvhost_scale3d_deinit,
135         .scaling_post_cb = &nvhost_scale3d_callback,
136         .devfreq_governor = "nvhost_podgov",
137         .actmon_enabled = true,
138
139         .suspend_ndev   = nvhost_scale3d_suspend,
140         .prepare_poweroff = nvhost_gr3d_t114_prepare_power_off,
141         .finalize_poweron = nvhost_gr3d_t114_finalize_power_on,
142         .alloc_hwctx_handler = nvhost_gr3d_t114_ctxhandler_init,
143         .read_reg       = nvhost_gr3d_t30_read_reg,
144 };
145
146 static struct platform_device tegra_gr3d03_device = {
147         .name           = "gr3d",
148         .id             = -1,
149         .dev            = {
150                 .platform_data = &t14_gr3d_info,
151         },
152 };
153
154 struct nvhost_device_data t14_gr2d_info = {
155         .index          = 2,
156         .syncpts        = {NVSYNCPT_2D_0, NVSYNCPT_2D_1},
157         .waitbases      = {NVWAITBASE_2D_0, NVWAITBASE_2D_1},
158         .modulemutexes  = {NVMODMUTEX_2D_FULL, NVMODMUTEX_2D_SIMPLE,
159                           NVMODMUTEX_2D_SB_A, NVMODMUTEX_2D_SB_B},
160         .clocks         = { {"gr2d", 0, 7, true}, {"epp", 0, 10, true},
161                             {"emc", 300000000, 75 } },
162         .powergate_ids  = { TEGRA_POWERGATE_HEG, -1 },
163         .clockgate_delay = 0,
164         .can_powergate  = true,
165         .powergate_delay = 100,
166         .moduleid       = NVHOST_MODULE_NONE,
167         .serialize      = true,
168         .finalize_poweron = nvhost_gr2d_t114_finalize_poweron,
169 };
170
171 static struct platform_device tegra_gr2d03_device = {
172         .name           = "gr2d",
173         .id             = -1,
174         .dev            = {
175                 .platform_data = &t14_gr2d_info,
176         },
177 };
178
179 static struct resource isp_resources[] = {
180         {
181                 .name = "regs",
182                 .start = TEGRA_ISP_BASE,
183                 .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1,
184                 .flags = IORESOURCE_MEM,
185         }
186 };
187
188 struct nvhost_device_data t14_isp_info = {
189         .index          = 3,
190         .syncpts        = {NVSYNCPT_VI_ISP_2, NVSYNCPT_VI_ISP_3,
191                           NVSYNCPT_VI_ISP_4},
192         NVHOST_MODULE_NO_POWERGATE_IDS,
193         NVHOST_DEFAULT_CLOCKGATE_DELAY,
194         .moduleid       = NVHOST_MODULE_ISP,
195 };
196
197 static struct platform_device tegra_isp01_device = {
198         .name           = "isp",
199         .id             = -1,
200         .resource       = isp_resources,
201         .num_resources  = ARRAY_SIZE(isp_resources),
202         .dev            = {
203                 .platform_data = &t14_isp_info,
204         },
205 };
206
207 static struct resource vi_resources[] = {
208         {
209                 .name = "regs",
210                 .start = TEGRA_VI_BASE,
211                 .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1,
212                 .flags = IORESOURCE_MEM,
213         },
214         {
215                 .name = "irq",
216                 .start = INT_VI_GENERAL,
217                 .end = INT_VI_GENERAL,
218                 .flags = IORESOURCE_IRQ,
219         },
220 };
221
222 struct nvhost_device_data t14_vi_info = {
223         .index          = 4,
224         .syncpts        = {NVSYNCPT_CSI_VI_0, NVSYNCPT_CSI_VI_1,
225                           NVSYNCPT_VI_ISP_0, NVSYNCPT_VI_ISP_1,
226                           NVSYNCPT_VI_ISP_2, NVSYNCPT_VI_ISP_3,
227                           NVSYNCPT_VI_ISP_4},
228         .modulemutexes  = {NVMODMUTEX_VI_0},
229         .clocks         = { {"host1x", 136000000, 6} },
230         .exclusive      = true,
231         NVHOST_MODULE_NO_POWERGATE_IDS,
232         NVHOST_DEFAULT_CLOCKGATE_DELAY,
233         .moduleid       = NVHOST_MODULE_VI,
234         .update_clk     = nvhost_host1x_update_clk,
235 };
236
237 static struct platform_device tegra_vi01_device = {
238         .name           = "vi",
239         .id             = -1,
240         .resource       = vi_resources,
241         .num_resources  = ARRAY_SIZE(vi_resources),
242         .dev            = {
243                 .platform_data = &t14_vi_info,
244         },
245 };
246
247 static struct resource msenc_resources[] = {
248         {
249                 .name = "regs",
250                 .start = TEGRA_MSENC_BASE,
251                 .end = TEGRA_MSENC_BASE + TEGRA_MSENC_SIZE - 1,
252                 .flags = IORESOURCE_MEM,
253         },
254 };
255
256 struct nvhost_device_data t14_msenc_info = {
257         .version        = NVHOST_ENCODE_MSENC_VER(3, 0),
258         .index          = 5,
259         .syncpts        = {NVSYNCPT_MSENC},
260         .waitbases      = {NVWAITBASE_MSENC},
261         .class          = NV_VIDEO_ENCODE_MSENC_CLASS_ID,
262         .clocks         = { {"msenc", UINT_MAX, 107, true},
263                             {"emc", 300000000, 75} },
264         .powergate_ids = { TEGRA_POWERGATE_MPE, -1 },
265         NVHOST_DEFAULT_CLOCKGATE_DELAY,
266         .powergate_delay = 100,
267         .can_powergate = true,
268         .moduleid       = NVHOST_MODULE_MSENC,
269         .powerup_reset  = true,
270 };
271
272 static struct platform_device tegra_msenc03_device = {
273         .name           = "msenc",
274         .id             = -1,
275         .resource       = msenc_resources,
276         .num_resources  = ARRAY_SIZE(msenc_resources),
277         .dev            = {
278                 .platform_data = &t14_msenc_info,
279         },
280 };
281
282 static struct resource tsec_resources[] = {
283         {
284                 .name = "regs",
285                 .start = TEGRA_TSEC_BASE,
286                 .end = TEGRA_TSEC_BASE + TEGRA_TSEC_SIZE - 1,
287                 .flags = IORESOURCE_MEM,
288         },
289 };
290
291 struct nvhost_device_data t14_tsec_info = {
292         .version        = NVHOST_ENCODE_TSEC_VER(1,0),
293         .index          = 7,
294         .syncpts        = {NVSYNCPT_TSEC},
295         .waitbases      = {NVWAITBASE_TSEC},
296         .class          = NV_TSEC_CLASS_ID,
297         .exclusive      = false,
298         .clocks         = { {"tsec", UINT_MAX, 108, true},
299                             {"emc", 300000000, 75} },
300         NVHOST_MODULE_NO_POWERGATE_IDS,
301         NVHOST_DEFAULT_CLOCKGATE_DELAY,
302         .moduleid       = NVHOST_MODULE_TSEC,
303 };
304
305 static struct platform_device tegra_tsec01_device = {
306         .name           = "tsec",
307         .id             = -1,
308         .resource       = tsec_resources,
309         .num_resources  = ARRAY_SIZE(tsec_resources),
310         .dev            = {
311                 .platform_data = &t14_tsec_info,
312         },
313 };
314
315 static struct platform_device *t14_devices[] = {
316         &tegra_gr3d03_device,
317         &tegra_gr2d03_device,
318         &tegra_isp01_device,
319         &tegra_vi01_device,
320         &tegra_msenc03_device,
321         &tegra_tsec01_device,
322 };
323
324 struct platform_device *tegra14_register_host1x_devices(void)
325 {
326         int index = 0;
327         struct platform_device *pdev;
328
329         /* register host1x device first */
330         platform_device_register(&tegra_host1x03_device);
331         tegra_host1x03_device.dev.parent = NULL;
332
333         /* register clients with host1x device as parent */
334         for (index = 0; index < ARRAY_SIZE(t14_devices); index++) {
335                 pdev = t14_devices[index];
336                 pdev->dev.parent = &tegra_host1x03_device.dev;
337                 platform_device_register(pdev);
338         }
339
340         return &tegra_host1x03_device;
341 }
342
343 static void t148_free_nvhost_channel(struct nvhost_channel *ch)
344 {
345         nvhost_free_channel_internal(ch, &t148_num_alloc_channels);
346 }
347
348 static struct nvhost_channel *t148_alloc_nvhost_channel(
349                 struct platform_device *dev)
350 {
351         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
352         return nvhost_alloc_channel_internal(pdata->index,
353                 nvhost_get_host(dev)->info.nb_channels,
354                 &t148_num_alloc_channels);
355 }
356
357 #include "host1x/host1x_channel.c"
358 #include "host1x/host1x_cdma.c"
359 #include "host1x/host1x_debug.c"
360 #include "host1x/host1x_syncpt.c"
361 #include "host1x/host1x_intr.c"
362 #include "host1x/host1x_actmon_t114.c"
363 #include "host1x/host1x_tickctrl.c"
364
365 int nvhost_init_t148_support(struct nvhost_master *host,
366         struct nvhost_chip_support *op)
367 {
368         int err;
369
370         op->channel = host1x_channel_ops;
371         op->cdma = host1x_cdma_ops;
372         op->push_buffer = host1x_pushbuffer_ops;
373         op->debug = host1x_debug_ops;
374         host->sync_aperture = host->aperture + HOST1X_CHANNEL_SYNC_REG_BASE;
375         op->syncpt = host1x_syncpt_ops;
376         op->intr = host1x_intr_ops;
377         err = nvhost_memmgr_init(op);
378         if (err)
379                 return err;
380         op->nvhost_dev.alloc_nvhost_channel = t148_alloc_nvhost_channel;
381         op->nvhost_dev.free_nvhost_channel = t148_free_nvhost_channel;
382         op->actmon = host1x_actmon_ops;
383         op->tickctrl = host1x_tickctrl_ops;
384
385         return 0;
386 }