arm: tegra: Modify MC domain APIs
[linux-3.10.git] / drivers / video / tegra / host / vi / vi.c
1 /*
2  * drivers/video/tegra/host/vi/vi.c
3  *
4  * Tegra Graphics Host VI
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/export.h>
22 #include <linux/resource.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/of.h>
25 #include <linux/of_device.h>
26 #include <linux/of_platform.h>
27
28 #include <mach/pm_domains.h>
29
30 #include "dev.h"
31 #include "bus_client.h"
32 #include "nvhost_acm.h"
33 #include "t20/t20.h"
34 #include "t30/t30.h"
35 #include "t114/t114.h"
36 #include "t148/t148.h"
37 #include "vi.h"
38
39 static struct of_device_id tegra_vi_of_match[] = {
40         { .compatible = "nvidia,tegra20-vi",
41                 .data = (struct nvhost_device_data *)&t20_vi_info },
42         { .compatible = "nvidia,tegra30-vi",
43                 .data = (struct nvhost_device_data *)&t30_vi_info },
44         { .compatible = "nvidia,tegra114-vi",
45                 .data = (struct nvhost_device_data *)&t11_vi_info },
46         { .compatible = "nvidia,tegra148-vi",
47                 .data = (struct nvhost_device_data *)&t14_vi_info },
48         { },
49 };
50
51 static int vi_probe(struct platform_device *dev)
52 {
53         int err = 0;
54         struct vi *tegra_vi;
55         struct nvhost_device_data *pdata = NULL;
56
57         if (dev->dev.of_node) {
58                 const struct of_device_id *match;
59
60                 match = of_match_device(tegra_vi_of_match, &dev->dev);
61                 if (match)
62                         pdata = (struct nvhost_device_data *)match->data;
63         } else
64                 pdata = (struct nvhost_device_data *)dev->dev.platform_data;
65
66         WARN_ON(!pdata);
67         if (!pdata) {
68                 dev_info(&dev->dev, "no platform data\n");
69                 return -ENODATA;
70         }
71
72         dev_info(&dev->dev, "%s: ++\n", __func__);
73         tegra_vi = kzalloc(sizeof(struct vi), GFP_KERNEL);
74         if (!tegra_vi) {
75                 dev_err(&dev->dev, "can't allocate memory for vi\n");
76                 return -ENOMEM;
77         }
78
79         tegra_vi->ndev = dev;
80         pdata->private_data = tegra_vi;
81
82 #ifdef CONFIG_TEGRA_CAMERA
83         tegra_vi->camera = tegra_camera_register(dev);
84         if (!tegra_vi->camera) {
85                 dev_err(&dev->dev, "%s: can't register tegra_camera\n",
86                                 __func__);
87                 goto camera_register_fail;
88         }
89 #endif
90         pdata->pdev = dev;
91         mutex_init(&pdata->lock);
92         platform_set_drvdata(dev, pdata);
93         nvhost_module_init(dev);
94         err = nvhost_client_device_get_resources(dev);
95         if (err)
96                 goto camera_register_fail;
97
98         err = nvhost_client_device_init(dev);
99         if (err)
100                 goto camera_register_fail;
101
102         tegra_pd_add_device(&dev->dev);
103         pm_runtime_use_autosuspend(&dev->dev);
104         pm_runtime_set_autosuspend_delay(&dev->dev, pdata->clockgate_delay);
105         pm_runtime_enable(&dev->dev);
106
107         return 0;
108
109 camera_register_fail:
110         kfree(tegra_vi);
111         return err;
112
113 }
114
115 static int __exit vi_remove(struct platform_device *dev)
116 {
117 #ifdef CONFIG_TEGRA_CAMERA
118         int err = 0;
119         struct nvhost_device_data *pdata =
120                 (struct nvhost_device_data *)platform_get_drvdata(dev);
121         struct vi *tegra_vi = (struct vi *)pdata->private_data;
122 #endif
123
124         dev_info(&dev->dev, "%s: ++\n", __func__);
125
126 #ifdef CONFIG_TEGRA_CAMERA
127         err = tegra_camera_unregister(tegra_vi->camera);
128         if (err)
129                 return err;
130 #endif
131
132         return 0;
133 }
134
135 #ifdef CONFIG_PM
136 static int vi_suspend(struct device *dev)
137 {
138 #ifdef CONFIG_TEGRA_CAMERA
139         struct platform_device *pdev = to_platform_device(dev);
140         struct nvhost_device_data *pdata =
141                 (struct nvhost_device_data *)platform_get_drvdata(pdev);
142         struct vi *tegra_vi = (struct vi *)pdata->private_data;
143 #endif
144
145         dev_info(dev, "%s: ++\n", __func__);
146
147 #ifdef CONFIG_TEGRA_CAMERA
148         tegra_camera_suspend(tegra_vi->camera);
149 #endif
150
151         return nvhost_client_device_suspend(to_platform_device(dev));
152 }
153
154 static int vi_resume(struct device *dev)
155 {
156 #ifdef CONFIG_TEGRA_CAMERA
157         struct platform_device *pdev = to_platform_device(dev);
158         struct nvhost_device_data *pdata =
159                 (struct nvhost_device_data *)platform_get_drvdata(pdev);
160         struct vi *tegra_vi = (struct vi *)pdata->private_data;
161 #endif
162
163         dev_info(dev, "%s: ++\n", __func__);
164
165 #ifdef CONFIG_TEGRA_CAMERA
166         tegra_camera_resume(tegra_vi->camera);
167 #endif
168
169         return 0;
170 }
171
172 #ifdef CONFIG_PM_RUNTIME
173 static int vi_runtime_suspend(struct device *dev)
174 {
175         return nvhost_module_disable_clk(to_platform_device(dev));
176 }
177
178 static int vi_runtime_resume(struct device *dev)
179 {
180         return nvhost_module_enable_clk(to_platform_device(dev));
181 }
182 #endif /* CONFIG_PM_RUNTIME */
183
184 static const struct dev_pm_ops vi_pm_ops = {
185         .suspend = vi_suspend,
186         .resume = vi_resume,
187 #ifdef CONFIG_PM_RUNTIME
188         .runtime_suspend = vi_runtime_suspend,
189         .runtime_resume = vi_runtime_resume,
190 #endif /* CONFIG_PM_RUNTIME */
191 };
192
193 #define VI_PM_OPS       (&vi_pm_ops)
194
195 #else
196
197 #define VI_PM_OPS       NULL
198
199 #endif
200
201 static struct platform_driver vi_driver = {
202         .probe = vi_probe,
203         .remove = __exit_p(vi_remove),
204         .driver = {
205                 .owner = THIS_MODULE,
206                 .name = "vi",
207                 .pm = VI_PM_OPS,
208 #ifdef CONFIG_OF
209                 .of_match_table = tegra_vi_of_match,
210 #endif
211         }
212 };
213
214 static int __init vi_init(void)
215 {
216         return platform_driver_register(&vi_driver);
217 }
218
219 static void __exit vi_exit(void)
220 {
221         platform_driver_unregister(&vi_driver);
222 }
223
224 late_initcall(vi_init);
225 module_exit(vi_exit);