Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / media / platform / s5p-tv / mixer_drv.c
1 /*
2  * Samsung TV Mixer driver
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5  *
6  * Tomasz Stanislawski, <t.stanislaws@samsung.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 as published
10  * by the Free Software Foundiation. either version 2 of the License,
11  * or (at your option) any later version
12  */
13
14 #include "mixer.h"
15
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 #include <linux/io.h>
19 #include <linux/interrupt.h>
20 #include <linux/irq.h>
21 #include <linux/fb.h>
22 #include <linux/delay.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/clk.h>
25
26 MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
27 MODULE_DESCRIPTION("Samsung MIXER");
28 MODULE_LICENSE("GPL");
29
30 /* --------- DRIVER PARAMETERS ---------- */
31
32 static struct mxr_output_conf mxr_output_conf[] = {
33         {
34                 .output_name = "S5P HDMI connector",
35                 .module_name = "s5p-hdmi",
36                 .cookie = 1,
37         },
38         {
39                 .output_name = "S5P SDO connector",
40                 .module_name = "s5p-sdo",
41                 .cookie = 0,
42         },
43 };
44
45 void mxr_get_mbus_fmt(struct mxr_device *mdev,
46         struct v4l2_mbus_framefmt *mbus_fmt)
47 {
48         struct v4l2_subdev *sd;
49         int ret;
50
51         mutex_lock(&mdev->mutex);
52         sd = to_outsd(mdev);
53         ret = v4l2_subdev_call(sd, video, g_mbus_fmt, mbus_fmt);
54         WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
55         mutex_unlock(&mdev->mutex);
56 }
57
58 void mxr_streamer_get(struct mxr_device *mdev)
59 {
60         mutex_lock(&mdev->mutex);
61         ++mdev->n_streamer;
62         mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
63         if (mdev->n_streamer == 1) {
64                 struct v4l2_subdev *sd = to_outsd(mdev);
65                 struct v4l2_mbus_framefmt mbus_fmt;
66                 struct mxr_resources *res = &mdev->res;
67                 int ret;
68
69                 if (to_output(mdev)->cookie == 0)
70                         clk_set_parent(res->sclk_mixer, res->sclk_dac);
71                 else
72                         clk_set_parent(res->sclk_mixer, res->sclk_hdmi);
73                 mxr_reg_s_output(mdev, to_output(mdev)->cookie);
74
75                 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mbus_fmt);
76                 WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
77                 ret = v4l2_subdev_call(sd, video, s_stream, 1);
78                 WARN(ret, "starting stream failed for output %s\n", sd->name);
79
80                 mxr_reg_set_mbus_fmt(mdev, &mbus_fmt);
81                 mxr_reg_streamon(mdev);
82                 ret = mxr_reg_wait4vsync(mdev);
83                 WARN(ret, "failed to get vsync (%d) from output\n", ret);
84         }
85         mutex_unlock(&mdev->mutex);
86         mxr_reg_dump(mdev);
87         /* FIXME: what to do when streaming fails? */
88 }
89
90 void mxr_streamer_put(struct mxr_device *mdev)
91 {
92         mutex_lock(&mdev->mutex);
93         --mdev->n_streamer;
94         mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
95         if (mdev->n_streamer == 0) {
96                 int ret;
97                 struct v4l2_subdev *sd = to_outsd(mdev);
98
99                 mxr_reg_streamoff(mdev);
100                 /* vsync applies Mixer setup */
101                 ret = mxr_reg_wait4vsync(mdev);
102                 WARN(ret, "failed to get vsync (%d) from output\n", ret);
103                 ret = v4l2_subdev_call(sd, video, s_stream, 0);
104                 WARN(ret, "stopping stream failed for output %s\n", sd->name);
105         }
106         WARN(mdev->n_streamer < 0, "negative number of streamers (%d)\n",
107                 mdev->n_streamer);
108         mutex_unlock(&mdev->mutex);
109         mxr_reg_dump(mdev);
110 }
111
112 void mxr_output_get(struct mxr_device *mdev)
113 {
114         mutex_lock(&mdev->mutex);
115         ++mdev->n_output;
116         mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
117         /* turn on auxiliary driver */
118         if (mdev->n_output == 1)
119                 v4l2_subdev_call(to_outsd(mdev), core, s_power, 1);
120         mutex_unlock(&mdev->mutex);
121 }
122
123 void mxr_output_put(struct mxr_device *mdev)
124 {
125         mutex_lock(&mdev->mutex);
126         --mdev->n_output;
127         mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
128         /* turn on auxiliary driver */
129         if (mdev->n_output == 0)
130                 v4l2_subdev_call(to_outsd(mdev), core, s_power, 0);
131         WARN(mdev->n_output < 0, "negative number of output users (%d)\n",
132                 mdev->n_output);
133         mutex_unlock(&mdev->mutex);
134 }
135
136 int mxr_power_get(struct mxr_device *mdev)
137 {
138         int ret = pm_runtime_get_sync(mdev->dev);
139
140         /* returning 1 means that power is already enabled,
141          * so zero success be returned */
142         if (IS_ERR_VALUE(ret))
143                 return ret;
144         return 0;
145 }
146
147 void mxr_power_put(struct mxr_device *mdev)
148 {
149         pm_runtime_put_sync(mdev->dev);
150 }
151
152 /* --------- RESOURCE MANAGEMENT -------------*/
153
154 static int mxr_acquire_plat_resources(struct mxr_device *mdev,
155                                       struct platform_device *pdev)
156 {
157         struct resource *res;
158         int ret;
159
160         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
161         if (res == NULL) {
162                 mxr_err(mdev, "get memory resource failed.\n");
163                 ret = -ENXIO;
164                 goto fail;
165         }
166
167         mdev->res.mxr_regs = ioremap(res->start, resource_size(res));
168         if (mdev->res.mxr_regs == NULL) {
169                 mxr_err(mdev, "register mapping failed.\n");
170                 ret = -ENXIO;
171                 goto fail;
172         }
173
174         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
175         if (res == NULL) {
176                 mxr_err(mdev, "get memory resource failed.\n");
177                 ret = -ENXIO;
178                 goto fail_mxr_regs;
179         }
180
181         mdev->res.vp_regs = ioremap(res->start, resource_size(res));
182         if (mdev->res.vp_regs == NULL) {
183                 mxr_err(mdev, "register mapping failed.\n");
184                 ret = -ENXIO;
185                 goto fail_mxr_regs;
186         }
187
188         res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
189         if (res == NULL) {
190                 mxr_err(mdev, "get interrupt resource failed.\n");
191                 ret = -ENXIO;
192                 goto fail_vp_regs;
193         }
194
195         ret = request_irq(res->start, mxr_irq_handler, 0, "s5p-mixer", mdev);
196         if (ret) {
197                 mxr_err(mdev, "request interrupt failed.\n");
198                 goto fail_vp_regs;
199         }
200         mdev->res.irq = res->start;
201
202         return 0;
203
204 fail_vp_regs:
205         iounmap(mdev->res.vp_regs);
206
207 fail_mxr_regs:
208         iounmap(mdev->res.mxr_regs);
209
210 fail:
211         return ret;
212 }
213
214 static void mxr_resource_clear_clocks(struct mxr_resources *res)
215 {
216         res->mixer      = ERR_PTR(-EINVAL);
217         res->vp         = ERR_PTR(-EINVAL);
218         res->sclk_mixer = ERR_PTR(-EINVAL);
219         res->sclk_hdmi  = ERR_PTR(-EINVAL);
220         res->sclk_dac   = ERR_PTR(-EINVAL);
221 }
222
223 static void mxr_release_plat_resources(struct mxr_device *mdev)
224 {
225         free_irq(mdev->res.irq, mdev);
226         iounmap(mdev->res.vp_regs);
227         iounmap(mdev->res.mxr_regs);
228 }
229
230 static void mxr_release_clocks(struct mxr_device *mdev)
231 {
232         struct mxr_resources *res = &mdev->res;
233
234         if (!IS_ERR(res->sclk_dac))
235                 clk_put(res->sclk_dac);
236         if (!IS_ERR(res->sclk_hdmi))
237                 clk_put(res->sclk_hdmi);
238         if (!IS_ERR(res->sclk_mixer))
239                 clk_put(res->sclk_mixer);
240         if (!IS_ERR(res->vp))
241                 clk_put(res->vp);
242         if (!IS_ERR(res->mixer))
243                 clk_put(res->mixer);
244 }
245
246 static int mxr_acquire_clocks(struct mxr_device *mdev)
247 {
248         struct mxr_resources *res = &mdev->res;
249         struct device *dev = mdev->dev;
250
251         mxr_resource_clear_clocks(res);
252
253         res->mixer = clk_get(dev, "mixer");
254         if (IS_ERR(res->mixer)) {
255                 mxr_err(mdev, "failed to get clock 'mixer'\n");
256                 goto fail;
257         }
258         res->vp = clk_get(dev, "vp");
259         if (IS_ERR(res->vp)) {
260                 mxr_err(mdev, "failed to get clock 'vp'\n");
261                 goto fail;
262         }
263         res->sclk_mixer = clk_get(dev, "sclk_mixer");
264         if (IS_ERR(res->sclk_mixer)) {
265                 mxr_err(mdev, "failed to get clock 'sclk_mixer'\n");
266                 goto fail;
267         }
268         res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
269         if (IS_ERR(res->sclk_hdmi)) {
270                 mxr_err(mdev, "failed to get clock 'sclk_hdmi'\n");
271                 goto fail;
272         }
273         res->sclk_dac = clk_get(dev, "sclk_dac");
274         if (IS_ERR(res->sclk_dac)) {
275                 mxr_err(mdev, "failed to get clock 'sclk_dac'\n");
276                 goto fail;
277         }
278
279         return 0;
280 fail:
281         mxr_release_clocks(mdev);
282         return -ENODEV;
283 }
284
285 static int mxr_acquire_resources(struct mxr_device *mdev,
286                                  struct platform_device *pdev)
287 {
288         int ret;
289         ret = mxr_acquire_plat_resources(mdev, pdev);
290
291         if (ret)
292                 goto fail;
293
294         ret = mxr_acquire_clocks(mdev);
295         if (ret)
296                 goto fail_plat;
297
298         mxr_info(mdev, "resources acquired\n");
299         return 0;
300
301 fail_plat:
302         mxr_release_plat_resources(mdev);
303 fail:
304         mxr_err(mdev, "resources acquire failed\n");
305         return ret;
306 }
307
308 static void mxr_release_resources(struct mxr_device *mdev)
309 {
310         mxr_release_clocks(mdev);
311         mxr_release_plat_resources(mdev);
312         memset(&mdev->res, 0, sizeof(mdev->res));
313         mxr_resource_clear_clocks(&mdev->res);
314 }
315
316 static void mxr_release_layers(struct mxr_device *mdev)
317 {
318         int i;
319
320         for (i = 0; i < ARRAY_SIZE(mdev->layer); ++i)
321                 if (mdev->layer[i])
322                         mxr_layer_release(mdev->layer[i]);
323 }
324
325 static int mxr_acquire_layers(struct mxr_device *mdev,
326                               struct mxr_platform_data *pdata)
327 {
328         mdev->layer[0] = mxr_graph_layer_create(mdev, 0);
329         mdev->layer[1] = mxr_graph_layer_create(mdev, 1);
330         mdev->layer[2] = mxr_vp_layer_create(mdev, 0);
331
332         if (!mdev->layer[0] || !mdev->layer[1] || !mdev->layer[2]) {
333                 mxr_err(mdev, "failed to acquire layers\n");
334                 goto fail;
335         }
336
337         return 0;
338
339 fail:
340         mxr_release_layers(mdev);
341         return -ENODEV;
342 }
343
344 /* ---------- POWER MANAGEMENT ----------- */
345
346 static int mxr_runtime_resume(struct device *dev)
347 {
348         struct mxr_device *mdev = to_mdev(dev);
349         struct mxr_resources *res = &mdev->res;
350         int ret;
351
352         mxr_dbg(mdev, "resume - start\n");
353         mutex_lock(&mdev->mutex);
354         /* turn clocks on */
355         ret = clk_prepare_enable(res->mixer);
356         if (ret < 0) {
357                 dev_err(mdev->dev, "clk_prepare_enable(mixer) failed\n");
358                 goto fail;
359         }
360         ret = clk_prepare_enable(res->vp);
361         if (ret < 0) {
362                 dev_err(mdev->dev, "clk_prepare_enable(vp) failed\n");
363                 goto fail_mixer;
364         }
365         ret = clk_prepare_enable(res->sclk_mixer);
366         if (ret < 0) {
367                 dev_err(mdev->dev, "clk_prepare_enable(sclk_mixer) failed\n");
368                 goto fail_vp;
369         }
370         /* apply default configuration */
371         mxr_reg_reset(mdev);
372         mxr_dbg(mdev, "resume - finished\n");
373
374         mutex_unlock(&mdev->mutex);
375         return 0;
376
377 fail_vp:
378         clk_disable_unprepare(res->vp);
379 fail_mixer:
380         clk_disable_unprepare(res->mixer);
381 fail:
382         mutex_unlock(&mdev->mutex);
383         dev_err(mdev->dev, "resume failed\n");
384         return ret;
385 }
386
387 static int mxr_runtime_suspend(struct device *dev)
388 {
389         struct mxr_device *mdev = to_mdev(dev);
390         struct mxr_resources *res = &mdev->res;
391         mxr_dbg(mdev, "suspend - start\n");
392         mutex_lock(&mdev->mutex);
393         /* turn clocks off */
394         clk_disable_unprepare(res->sclk_mixer);
395         clk_disable_unprepare(res->vp);
396         clk_disable_unprepare(res->mixer);
397         mutex_unlock(&mdev->mutex);
398         mxr_dbg(mdev, "suspend - finished\n");
399         return 0;
400 }
401
402 static const struct dev_pm_ops mxr_pm_ops = {
403         .runtime_suspend = mxr_runtime_suspend,
404         .runtime_resume  = mxr_runtime_resume,
405 };
406
407 /* --------- DRIVER INITIALIZATION ---------- */
408
409 static int mxr_probe(struct platform_device *pdev)
410 {
411         struct device *dev = &pdev->dev;
412         struct mxr_platform_data *pdata = dev->platform_data;
413         struct mxr_device *mdev;
414         int ret;
415
416         /* mdev does not exist yet so no mxr_dbg is used */
417         dev_info(dev, "probe start\n");
418
419         mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
420         if (!mdev) {
421                 dev_err(dev, "not enough memory.\n");
422                 ret = -ENOMEM;
423                 goto fail;
424         }
425
426         /* setup pointer to master device */
427         mdev->dev = dev;
428
429         mutex_init(&mdev->mutex);
430         spin_lock_init(&mdev->reg_slock);
431         init_waitqueue_head(&mdev->event_queue);
432
433         /* acquire resources: regs, irqs, clocks, regulators */
434         ret = mxr_acquire_resources(mdev, pdev);
435         if (ret)
436                 goto fail_mem;
437
438         /* configure resources for video output */
439         ret = mxr_acquire_video(mdev, mxr_output_conf,
440                 ARRAY_SIZE(mxr_output_conf));
441         if (ret)
442                 goto fail_resources;
443
444         /* configure layers */
445         ret = mxr_acquire_layers(mdev, pdata);
446         if (ret)
447                 goto fail_video;
448
449         pm_runtime_enable(dev);
450
451         mxr_info(mdev, "probe successful\n");
452         return 0;
453
454 fail_video:
455         mxr_release_video(mdev);
456
457 fail_resources:
458         mxr_release_resources(mdev);
459
460 fail_mem:
461         kfree(mdev);
462
463 fail:
464         dev_info(dev, "probe failed\n");
465         return ret;
466 }
467
468 static int mxr_remove(struct platform_device *pdev)
469 {
470         struct device *dev = &pdev->dev;
471         struct mxr_device *mdev = to_mdev(dev);
472
473         pm_runtime_disable(dev);
474
475         mxr_release_layers(mdev);
476         mxr_release_video(mdev);
477         mxr_release_resources(mdev);
478
479         kfree(mdev);
480
481         dev_info(dev, "remove successful\n");
482         return 0;
483 }
484
485 static struct platform_driver mxr_driver __refdata = {
486         .probe = mxr_probe,
487         .remove = mxr_remove,
488         .driver = {
489                 .name = MXR_DRIVER_NAME,
490                 .pm = &mxr_pm_ops,
491         }
492 };
493
494 static int __init mxr_init(void)
495 {
496         int i, ret;
497         static const char banner[] __initconst =
498                 "Samsung TV Mixer driver, "
499                 "(c) 2010-2011 Samsung Electronics Co., Ltd.\n";
500         pr_info("%s\n", banner);
501
502         /* Loading auxiliary modules */
503         for (i = 0; i < ARRAY_SIZE(mxr_output_conf); ++i)
504                 request_module(mxr_output_conf[i].module_name);
505
506         ret = platform_driver_register(&mxr_driver);
507         if (ret != 0) {
508                 pr_err("s5p-tv: registration of MIXER driver failed\n");
509                 return -ENXIO;
510         }
511
512         return 0;
513 }
514 module_init(mxr_init);
515
516 static void __exit mxr_exit(void)
517 {
518         platform_driver_unregister(&mxr_driver);
519 }
520 module_exit(mxr_exit);