]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/media/platform/tegra/camera/mc_common.c
9a03cd396cc25868039d8494983a6807b819f949
[sojka/nv-tegra/linux-3.10.git] / drivers / media / platform / tegra / camera / mc_common.c
1 /*
2  * Tegra Video Input device common APIs
3  *
4  * Copyright (c) 2015-2016, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * Author: Bryan Wu <pengw@nvidia.com>
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 version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/init.h>
14 #include <linux/export.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/of_device.h>
18 #include <linux/of_platform.h>
19
20 #include <media/tegra_v4l2_camera.h>
21 #include <media/camera_common.h>
22 #include <media/v4l2-event.h>
23 #include <media/tegra_camera_platform.h>
24
25 #include "dev.h"
26 #include "camera/mc_common.h"
27 #include "vi/vi.h"
28 #include "camera/registers.h"
29
30 void vi_write(struct tegra_mc_vi *vi, unsigned int addr, u32 val)
31 {
32         writel(val, vi->iomem + addr);
33 }
34
35 /* In TPG mode, VI only support 2 formats */
36 static void vi_tpg_fmts_bitmap_init(struct tegra_mc_vi *vi)
37 {
38         int index;
39
40         bitmap_zero(vi->tpg_fmts_bitmap, MAX_FORMAT_NUM);
41
42         index = tegra_core_get_idx_by_code(MEDIA_BUS_FMT_SRGGB10_1X10);
43         bitmap_set(vi->tpg_fmts_bitmap, index, 1);
44
45         index = tegra_core_get_idx_by_code(MEDIA_BUS_FMT_RGB888_1X32_PADHI);
46         bitmap_set(vi->tpg_fmts_bitmap, index, 1);
47 }
48
49 int tegra_vi_power_on(struct tegra_mc_vi *vi)
50 {
51         int ret;
52
53         if (atomic_add_return(1, &vi->power_on_refcnt) > 1)
54                 return 0;
55
56         ret = nvhost_module_busy_ext(vi->ndev);
57         if (ret) {
58                 dev_err(vi->dev, "%s:nvhost module is busy\n", __func__);
59                 return ret;
60         }
61
62         if (vi->reg) {
63                 ret = regulator_enable(vi->reg);
64                 if (ret) {
65                         dev_err(vi->dev, "%s: enable csi regulator failed.\n",
66                                         __func__);
67                         goto error_regulator_fail;
68                 }
69         }
70
71         vi_write(vi, TEGRA_VI_CFG_CG_CTRL, 1);
72
73         /* unpowergate VE */
74         ret = tegra_unpowergate_partition(TEGRA_POWERGATE_VENC);
75         if (ret) {
76                 dev_err(vi->dev, "failed to unpower gate VI\n");
77                 goto error_unpowergate;
78         }
79
80         /* clock settings */
81         clk_prepare_enable(vi->clk);
82         ret = clk_set_rate(vi->clk, 0);
83         if (ret) {
84                 dev_err(vi->dev, "failed to set vi clock\n");
85                 goto error_clk_set_rate;
86         }
87
88         ret = tegra_camera_emc_clk_enable();
89         if (ret)
90                 goto err_emc_enable;
91
92         return 0;
93 err_emc_enable:
94         clk_disable_unprepare(vi->clk);
95 error_clk_set_rate:
96         tegra_powergate_partition(TEGRA_POWERGATE_VENC);
97 error_unpowergate:
98         regulator_disable(vi->reg);
99 error_regulator_fail:
100         nvhost_module_idle_ext(vi->ndev);
101
102         return ret;
103 }
104
105 void tegra_vi_power_off(struct tegra_mc_vi *vi)
106 {
107         if (!atomic_dec_and_test(&vi->power_on_refcnt))
108                 return;
109
110         tegra_channel_ec_close(vi);
111         tegra_camera_emc_clk_disable();
112         clk_disable_unprepare(vi->clk);
113         tegra_powergate_partition(TEGRA_POWERGATE_VENC);
114         regulator_disable(vi->reg);
115         nvhost_module_idle_ext(vi->ndev);
116 }
117
118 /* -----------------------------------------------------------------------------
119  * Media Controller and V4L2
120  */
121
122 static const char *const vi_pattern_strings[] = {
123         "Disabled",
124         "Black/White Direct Mode",
125         "Color Patch Mode",
126 };
127
128 static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
129 {
130         struct tegra_mc_vi *vi = container_of(ctrl->handler, struct tegra_mc_vi,
131                                            ctrl_handler);
132
133         switch (ctrl->id) {
134         case V4L2_CID_TEST_PATTERN:
135                 /*
136                  * TPG control is only avaiable to TPG driver,
137                  * it can't be changed to 0 to disable TPG mode.
138                  */
139                 if (!vi->pg_mode)
140                         break;
141
142                 if (ctrl->val) {
143                         dev_info(&vi->ndev->dev, "Set TPG mode to %d\n",
144                                  ctrl->val);
145                         vi->pg_mode = ctrl->val;
146                         vi->csi->pg_mode = vi->pg_mode;
147                 } else
148                         dev_warn(&vi->ndev->dev,
149                                  "TPG mode can't be disabled for TPG driver\n");
150                 break;
151         default:
152                 dev_err(vi->dev, "%s:Not valid ctrl\n", __func__);
153                 return -EINVAL;
154         }
155
156         return 0;
157 }
158
159 static const struct v4l2_ctrl_ops vi_ctrl_ops = {
160         .s_ctrl = vi_s_ctrl,
161 };
162
163 void tegra_vi_v4l2_cleanup(struct tegra_mc_vi *vi)
164 {
165         v4l2_ctrl_handler_free(&vi->ctrl_handler);
166         v4l2_device_unregister(&vi->v4l2_dev);
167         if (!vi->pg_mode)
168                 media_device_unregister(&vi->media_dev);
169 }
170 EXPORT_SYMBOL(tegra_vi_v4l2_cleanup);
171
172 static void tegra_vi_notify(struct v4l2_subdev *sd,
173                                           unsigned int notification, void *arg)
174 {
175         struct tegra_mc_vi *vi = container_of(sd->v4l2_dev,
176                         struct tegra_mc_vi, v4l2_dev);
177         unsigned ch, i;
178
179         if (notification != V4L2_DEVICE_NOTIFY_EVENT)
180                 return;
181
182         for (ch = 0; ch < vi->num_channels; ch++) {
183                 struct tegra_channel *chan = &vi->chans[ch];
184
185                 for (i = 0; i < chan->num_subdevs; i++)
186                         if (sd == chan->subdev[i])
187                                 v4l2_event_queue(&chan->video, arg);
188         }
189 }
190
191 int tegra_vi_v4l2_init(struct tegra_mc_vi *vi)
192 {
193         int ret;
194
195         vi_tpg_fmts_bitmap_init(vi);
196
197         /*
198          * TPG mode need to reuse the real media_device struct of tegra_vi,
199          * so bypass the media_device_register() here.
200          */
201         if (vi->pg_mode) {
202                 struct vi *tegra_vi = tegra_vi_get();
203                 if (tegra_vi)
204                         memcpy(&vi->media_dev, &tegra_vi->mc_vi.media_dev,
205                                         sizeof(struct media_device));
206         } else {
207                 vi->media_dev.dev = vi->dev;
208                 strlcpy(vi->media_dev.model, "NVIDIA Tegra Video Input Device",
209                                 sizeof(vi->media_dev.model));
210                 vi->media_dev.hw_revision = 3;
211
212                 ret = media_device_register(&vi->media_dev);
213                 if (ret < 0) {
214                         dev_err(vi->dev, "media device registration failed (%d)\n",
215                                         ret);
216                         return ret;
217                 }
218         }
219         mutex_init(&vi->bw_update_lock);
220         mutex_init(&vi->mipical_lock);
221         vi->v4l2_dev.mdev = &vi->media_dev;
222         vi->v4l2_dev.notify = tegra_vi_notify;
223         ret = v4l2_device_register(vi->dev, &vi->v4l2_dev);
224         if (ret < 0) {
225                 dev_err(vi->dev, "V4L2 device registration failed (%d)\n",
226                         ret);
227                 goto register_error;
228         }
229
230         v4l2_ctrl_handler_init(&vi->ctrl_handler, 1);
231         vi->pattern = v4l2_ctrl_new_std_menu_items(&vi->ctrl_handler,
232                                 &vi_ctrl_ops, V4L2_CID_TEST_PATTERN,
233                                 ARRAY_SIZE(vi_pattern_strings) - 1,
234                                 0, vi->pg_mode, vi_pattern_strings);
235
236         if (vi->ctrl_handler.error) {
237                 dev_err(vi->dev, "failed to add controls\n");
238                 ret = vi->ctrl_handler.error;
239                 goto ctrl_error;
240         }
241         vi->v4l2_dev.ctrl_handler = &vi->ctrl_handler;
242
243         ret = v4l2_ctrl_handler_setup(&vi->ctrl_handler);
244         if (ret < 0) {
245                 dev_err(vi->dev, "failed to set controls\n");
246                 goto ctrl_error;
247         }
248         return 0;
249
250
251 ctrl_error:
252         v4l2_ctrl_handler_free(&vi->ctrl_handler);
253         v4l2_device_unregister(&vi->v4l2_dev);
254 register_error:
255         if (!vi->pg_mode)
256                 media_device_unregister(&vi->media_dev);
257         return ret;
258 }
259
260 static int vi_get_clks(struct tegra_mc_vi *vi, struct platform_device *pdev)
261 {
262         int ret = 0;
263
264         vi->clk = devm_clk_get(&pdev->dev, "vi_v4l2");
265         if (IS_ERR(vi->clk)) {
266                 dev_err(&pdev->dev, "Failed to get vi clock\n");
267                 return PTR_ERR(vi->clk);
268         }
269
270         return ret;
271 }
272
273 static int vi_parse_dt(struct tegra_mc_vi *vi, struct platform_device *dev)
274 {
275         int err = 0;
276         int num_channels = 0;
277         struct device_node *node = dev->dev.of_node;
278
279         err = of_property_read_u32(node, "num-channels", &num_channels);
280         if (err) {
281                 dev_err(&dev->dev,
282                         "Failed to find num of channels, set TPG mode\n");
283                 vi->pg_mode = TEGRA_VI_PG_PATCH;
284         }
285
286         vi->num_channels = num_channels;
287         vi->chans = devm_kzalloc(&dev->dev,
288                         (sizeof(struct tegra_channel) * num_channels),
289                         GFP_KERNEL);
290         if (!vi->chans)
291                 return -ENOMEM;
292
293         return 0;
294 }
295
296 static void set_vi_register_base(struct tegra_mc_vi *mc_vi,
297                         void __iomem *regbase)
298 {
299         mc_vi->iomem = regbase;
300 }
301
302 int tegra_vi_media_controller_init(struct tegra_mc_vi *mc_vi,
303                                    struct platform_device *pdev)
304 {
305         int err = 0;
306         struct nvhost_device_data *pdata = pdev->dev.platform_data;
307
308         set_vi_register_base(mc_vi, pdata->aperture[0]);
309
310         err = vi_get_clks(mc_vi, pdev);
311         if (err)
312                 return err;
313
314         if (mc_vi->pg_mode) {
315                 mc_vi->chans = devm_kzalloc(&pdev->dev,
316                                             sizeof(struct tegra_channel) *
317                                             mc_vi->num_channels,
318                                             GFP_KERNEL);
319                 if (!mc_vi->chans)
320                         return -ENOMEM;
321         } else {
322                 err = vi_parse_dt(mc_vi, pdev);
323                 if (err)
324                         goto mc_init_fail;
325         }
326
327         mc_vi->ndev = pdev;
328         mc_vi->dev = &pdev->dev;
329         INIT_LIST_HEAD(&mc_vi->entities);
330
331         err = tegra_vi_v4l2_init(mc_vi);
332         if (err < 0)
333                 goto mc_init_fail;
334
335         /* Init Tegra VI channels */
336         err = tegra_vi_channels_init(mc_vi);
337         if (err < 0)
338                 goto channels_error;
339
340         /* Setup media links between VI and external sensor subdev. */
341         if (mc_vi->pg_mode)
342                 err = tegra_vi_tpg_graph_init(mc_vi);
343         else
344                 err = tegra_vi_graph_init(mc_vi);
345         if (err < 0)
346                 goto graph_error;
347
348         return 0;
349
350 graph_error:
351         tegra_vi_channels_cleanup(mc_vi);
352 channels_error:
353         tegra_vi_v4l2_cleanup(mc_vi);
354 mc_init_fail:
355         dev_err(&pdev->dev, "%s: failed\n", __func__);
356         return err;
357 }
358 EXPORT_SYMBOL(tegra_vi_media_controller_init);
359
360 void tegra_vi_media_controller_cleanup(struct tegra_mc_vi *mc_vi)
361 {
362         tegra_vi_graph_cleanup(mc_vi);
363         tegra_vi_channels_cleanup(mc_vi);
364         tegra_vi_v4l2_cleanup(mc_vi);
365 }
366 EXPORT_SYMBOL(tegra_vi_media_controller_cleanup);