video: tegra: host: Make rate requests per clock
[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_t30.h"
29 #include "gr3d/scale3d.h"
30 #include "mpe/mpe.h"
31 #include "host1x/host1x.h"
32 #include "host1x/host1x01_hardware.h"
33 #include "chip_support.h"
34 #include "nvhost_channel.h"
35 #include "nvhost_memmgr.h"
36 #include "host1x/host1x_syncpt.h"
37 #include "gr3d/pod_scaling.h"
38
39 #define NVMODMUTEX_2D_FULL      (1)
40 #define NVMODMUTEX_2D_SIMPLE    (2)
41 #define NVMODMUTEX_2D_SB_A      (3)
42 #define NVMODMUTEX_2D_SB_B      (4)
43 #define NVMODMUTEX_3D           (5)
44 #define NVMODMUTEX_DISPLAYA     (6)
45 #define NVMODMUTEX_DISPLAYB     (7)
46 #define NVMODMUTEX_VI           (8)
47 #define NVMODMUTEX_DSI          (9)
48
49 static int t30_num_alloc_channels = 0;
50
51 static struct resource tegra_host1x01_resources[] = {
52         {
53                 .start = TEGRA_HOST1X_BASE,
54                 .end = TEGRA_HOST1X_BASE + TEGRA_HOST1X_SIZE - 1,
55                 .flags = IORESOURCE_MEM,
56         },
57         {
58                 .start = INT_SYNCPT_THRESH_BASE,
59                 .end = INT_SYNCPT_THRESH_BASE + INT_SYNCPT_THRESH_NR - 1,
60                 .flags = IORESOURCE_IRQ,
61         },
62         {
63                 .start = INT_HOST1X_MPCORE_GENERAL,
64                 .end = INT_HOST1X_MPCORE_GENERAL,
65                 .flags = IORESOURCE_IRQ,
66         },
67 };
68
69 static const char *s_syncpt_names[32] = {
70         "gfx_host",
71         "", "", "", "", "", "", "",
72         "disp0_a", "disp1_a", "avp_0",
73         "csi_vi_0", "csi_vi_1",
74         "vi_isp_0", "vi_isp_1", "vi_isp_2", "vi_isp_3", "vi_isp_4",
75         "2d_0", "2d_1",
76         "disp0_b", "disp1_b",
77         "3d",
78         "mpe",
79         "disp0_c", "disp1_c",
80         "vblank0", "vblank1",
81         "mpe_ebm_eof", "mpe_wr_safe",
82         "2d_tinyblt",
83         "dsi"
84 };
85
86 static struct host1x_device_info host1x01_info = {
87         .nb_channels    = 8,
88         .nb_pts         = 32,
89         .nb_mlocks      = 16,
90         .nb_bases       = 8,
91         .syncpt_names   = s_syncpt_names,
92         .client_managed = NVSYNCPTS_CLIENT_MANAGED,
93 };
94
95 static struct nvhost_device tegra_host1x01_device = {
96         .dev            = {.platform_data = &host1x01_info},
97         .name           = "host1x",
98         .id             = -1,
99         .resource       = tegra_host1x01_resources,
100         .num_resources  = ARRAY_SIZE(tegra_host1x01_resources),
101         .clocks         = {{"host1x", UINT_MAX}, {} },
102         NVHOST_MODULE_NO_POWERGATE_IDS,
103 };
104
105 static struct nvhost_device tegra_display01_device = {
106         .name           = "display",
107         .id             = -1,
108         .index          = 0,
109         .syncpts        = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) |
110                           BIT(NVSYNCPT_DISP0_B) | BIT(NVSYNCPT_DISP1_B) |
111                           BIT(NVSYNCPT_DISP0_C) | BIT(NVSYNCPT_DISP1_C) |
112                           BIT(NVSYNCPT_VBLANK0) | BIT(NVSYNCPT_VBLANK1),
113         .modulemutexes  = BIT(NVMODMUTEX_DISPLAYA) | BIT(NVMODMUTEX_DISPLAYB),
114         NVHOST_MODULE_NO_POWERGATE_IDS,
115         NVHOST_DEFAULT_CLOCKGATE_DELAY,
116         .moduleid       = NVHOST_MODULE_NONE,
117 };
118
119 static struct nvhost_device tegra_gr3d02_device = {
120         .name           = "gr3d",
121         .version        = 2,
122         .id             = -1,
123         .index          = 1,
124         .syncpts        = BIT(NVSYNCPT_3D),
125         .waitbases      = BIT(NVWAITBASE_3D),
126         .modulemutexes  = BIT(NVMODMUTEX_3D),
127         .class          = NV_GRAPHICS_3D_CLASS_ID,
128         .clocks         = { {"gr3d", UINT_MAX, 8},
129                             {"gr3d2", UINT_MAX},
130                             {"emc", UINT_MAX, 75} },
131         .powergate_ids = { TEGRA_POWERGATE_3D,
132                            TEGRA_POWERGATE_3D1 },
133         NVHOST_DEFAULT_CLOCKGATE_DELAY,
134         .can_powergate = true,
135         .powerup_reset = true,
136         .powergate_delay = 250,
137         .moduleid       = NVHOST_MODULE_NONE,
138 };
139
140 static struct nvhost_device tegra_gr2d02_device = {
141         .name           = "gr2d",
142         .id             = -1,
143         .index          = 2,
144         .syncpts        = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1),
145         .waitbases      = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1),
146         .modulemutexes  = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) |
147                           BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B),
148         .clocks         = { {"gr2d", 0, 7},
149                           {"epp", 0, 10},
150                           {"emc", 300000000, 75} },
151         NVHOST_MODULE_NO_POWERGATE_IDS,
152         .clockgate_delay = 0,
153         .moduleid       = NVHOST_MODULE_NONE,
154         .serialize      = true,
155 };
156
157 static struct resource isp_resources_t20[] = {
158         {
159                 .name = "regs",
160                 .start = TEGRA_ISP_BASE,
161                 .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1,
162                 .flags = IORESOURCE_MEM,
163         }
164 };
165
166 static struct nvhost_device tegra_isp01_device = {
167         .name           = "isp",
168         .id             = -1,
169         .resource = isp_resources_t20,
170         .num_resources = ARRAY_SIZE(isp_resources_t20),
171         .index          = 3,
172         .syncpts        = BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
173                           BIT(NVSYNCPT_VI_ISP_4),
174         .clocks         = { {"epp", 0, 10}
175                           },
176         .keepalive      = true,
177         NVHOST_MODULE_NO_POWERGATE_IDS,
178         NVHOST_DEFAULT_CLOCKGATE_DELAY,
179         .moduleid       = NVHOST_MODULE_ISP,
180 };
181
182 static struct resource vi_resources[] = {
183         {
184                 .name = "regs",
185                 .start = TEGRA_VI_BASE,
186                 .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1,
187                 .flags = IORESOURCE_MEM,
188         },
189 };
190
191 static struct nvhost_device tegra_vi01_device = {
192         .name           = "vi",
193         .resource = vi_resources,
194         .num_resources = ARRAY_SIZE(vi_resources),
195         .id             = -1,
196         .index          = 4,
197         .syncpts        = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) |
198                           BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) |
199                           BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) |
200                           BIT(NVSYNCPT_VI_ISP_4),
201         .modulemutexes  = BIT(NVMODMUTEX_VI),
202         .exclusive      = true,
203         NVHOST_MODULE_NO_POWERGATE_IDS,
204         NVHOST_DEFAULT_CLOCKGATE_DELAY,
205         .moduleid       = NVHOST_MODULE_VI,
206 };
207
208 static struct resource tegra_mpe01_resources[] = {
209         {
210                 .name = "regs",
211                 .start = TEGRA_MPE_BASE,
212                 .end = TEGRA_MPE_BASE + TEGRA_MPE_SIZE - 1,
213                 .flags = IORESOURCE_MEM,
214         },
215 };
216
217 static struct nvhost_device tegra_mpe02_device = {
218         .name           = "mpe",
219         .version        = 2,
220         .id             = -1,
221         .resource       = tegra_mpe01_resources,
222         .num_resources  = ARRAY_SIZE(tegra_mpe01_resources),
223         .index          = 5,
224         .syncpts        = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) |
225                           BIT(NVSYNCPT_MPE_WR_SAFE),
226         .waitbases      = BIT(NVWAITBASE_MPE),
227         .class          = NV_VIDEO_ENCODE_MPEG_CLASS_ID,
228         .waitbasesync   = true,
229         .keepalive      = true,
230         .clocks         = { {"mpe", UINT_MAX, 29},
231                             {"emc", 400000000, 75} },
232         .powergate_ids  = {TEGRA_POWERGATE_MPE, -1},
233         NVHOST_DEFAULT_CLOCKGATE_DELAY,
234         .can_powergate  = true,
235         .powergate_delay = 100,
236         .moduleid       = NVHOST_MODULE_MPE,
237 };
238
239 static struct nvhost_device tegra_dsi01_device = {
240         .name           = "dsi",
241         .id             = -1,
242         .index          = 6,
243         .syncpts        = BIT(NVSYNCPT_DSI),
244         .modulemutexes  = BIT(NVMODMUTEX_DSI),
245         NVHOST_MODULE_NO_POWERGATE_IDS,
246         NVHOST_DEFAULT_CLOCKGATE_DELAY,
247         .moduleid       = NVHOST_MODULE_NONE,
248 };
249
250 static struct nvhost_device *t30_devices[] = {
251         &tegra_host1x01_device,
252         &tegra_display01_device,
253         &tegra_gr3d02_device,
254         &tegra_gr2d02_device,
255         &tegra_isp01_device,
256         &tegra_vi01_device,
257         &tegra_mpe02_device,
258         &tegra_dsi01_device,
259 };
260
261 int tegra3_register_host1x_devices(void)
262 {
263         return nvhost_add_devices(t30_devices, ARRAY_SIZE(t30_devices));
264 }
265
266 static void t30_free_nvhost_channel(struct nvhost_channel *ch)
267 {
268         nvhost_free_channel_internal(ch, &t30_num_alloc_channels);
269 }
270
271 static struct nvhost_channel *t30_alloc_nvhost_channel(
272                 struct nvhost_device *dev)
273 {
274         return nvhost_alloc_channel_internal(dev->index,
275                 nvhost_get_host(dev)->info.nb_channels,
276                 &t30_num_alloc_channels);
277 }
278
279 #include "host1x/host1x_channel.c"
280 #include "host1x/host1x_cdma.c"
281 #include "host1x/host1x_debug.c"
282 #include "host1x/host1x_syncpt.c"
283 #include "host1x/host1x_intr.c"
284
285 int nvhost_init_t30_support(struct nvhost_master *host,
286         struct nvhost_chip_support *op)
287 {
288         int err;
289
290         op->channel = host1x_channel_ops;
291         op->cdma = host1x_cdma_ops;
292         op->push_buffer = host1x_pushbuffer_ops;
293         op->debug = host1x_debug_ops;
294         host->sync_aperture = host->aperture + HOST1X_CHANNEL_SYNC_REG_BASE;
295         op->syncpt = host1x_syncpt_ops;
296         op->intr = host1x_intr_ops;
297         err = nvhost_memmgr_init(op);
298         if (err)
299                 return err;
300
301         op->nvhost_dev.alloc_nvhost_channel = t30_alloc_nvhost_channel;
302         op->nvhost_dev.free_nvhost_channel = t30_free_nvhost_channel;
303
304         return 0;
305 }