10b3474f93a42585fd1c24ce249b4411fad97453
[sfrench/cifs-2.6.git] / drivers / media / platform / rcar-isp.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2021 Renesas Electronics Corp.
4  *
5  * Driver for Renesas R-Car ISP Channel Selector
6  *
7  * The ISP hardware is capable of more than just channel selection, features
8  * such as demosaicing, white balance control and color space conversion are
9  * also possible. These more advanced features are not supported by the driver
10  * due to lack of documentation.
11  */
12
13 #include <linux/module.h>
14 #include <linux/mutex.h>
15 #include <linux/of_device.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/reset.h>
19
20 #include <media/mipi-csi2.h>
21 #include <media/v4l2-subdev.h>
22
23 #define ISPINPUTSEL0_REG                                0x0008
24 #define ISPINPUTSEL0_SEL_CSI0                           BIT(31)
25
26 #define ISPSTART_REG                                    0x0014
27 #define ISPSTART_START                                  0xffff
28 #define ISPSTART_STOP                                   0x0000
29
30 #define ISPPROCMODE_DT_REG(n)                           (0x1100 + (0x4 * (n)))
31 #define ISPPROCMODE_DT_PROC_MODE_VC3(pm)                (((pm) & 0x3f) << 24)
32 #define ISPPROCMODE_DT_PROC_MODE_VC2(pm)                (((pm) & 0x3f) << 16)
33 #define ISPPROCMODE_DT_PROC_MODE_VC1(pm)                (((pm) & 0x3f) << 8)
34 #define ISPPROCMODE_DT_PROC_MODE_VC0(pm)                ((pm) & 0x3f)
35
36 #define ISPCS_FILTER_ID_CH_REG(n)                       (0x3000 + (0x0100 * (n)))
37
38 #define ISPCS_DT_CODE03_CH_REG(n)                       (0x3008 + (0x100 * (n)))
39 #define ISPCS_DT_CODE03_EN3                             BIT(31)
40 #define ISPCS_DT_CODE03_DT3(dt)                         (((dt) & 0x3f) << 24)
41 #define ISPCS_DT_CODE03_EN2                             BIT(23)
42 #define ISPCS_DT_CODE03_DT2(dt)                         (((dt) & 0x3f) << 16)
43 #define ISPCS_DT_CODE03_EN1                             BIT(15)
44 #define ISPCS_DT_CODE03_DT1(dt)                         (((dt) & 0x3f) << 8)
45 #define ISPCS_DT_CODE03_EN0                             BIT(7)
46 #define ISPCS_DT_CODE03_DT0(dt)                         ((dt) & 0x3f)
47
48 struct rcar_isp_format {
49         u32 code;
50         unsigned int datatype;
51         unsigned int procmode;
52 };
53
54 static const struct rcar_isp_format rcar_isp_formats[] = {
55         {
56                 .code = MEDIA_BUS_FMT_RGB888_1X24,
57                 .datatype = MIPI_CSI2_DT_RGB888,
58                 .procmode = 0x15
59         }, {
60                 .code = MEDIA_BUS_FMT_Y10_1X10,
61                 .datatype = MIPI_CSI2_DT_RAW10,
62                 .procmode = 0x10,
63         }, {
64                 .code = MEDIA_BUS_FMT_UYVY8_1X16,
65                 .datatype = MIPI_CSI2_DT_YUV422_8B,
66                 .procmode = 0x0c,
67         }, {
68                 .code = MEDIA_BUS_FMT_YUYV8_1X16,
69                 .datatype = MIPI_CSI2_DT_YUV422_8B,
70                 .procmode = 0x0c,
71         }, {
72                 .code = MEDIA_BUS_FMT_UYVY8_2X8,
73                 .datatype = MIPI_CSI2_DT_YUV422_8B,
74                 .procmode = 0x0c,
75         }, {
76                 .code = MEDIA_BUS_FMT_YUYV10_2X10,
77                 .datatype = MIPI_CSI2_DT_YUV422_8B,
78                 .procmode = 0x0c,
79         },
80 };
81
82 static const struct rcar_isp_format *risp_code_to_fmt(unsigned int code)
83 {
84         unsigned int i;
85
86         for (i = 0; i < ARRAY_SIZE(rcar_isp_formats); i++) {
87                 if (rcar_isp_formats[i].code == code)
88                         return &rcar_isp_formats[i];
89         }
90
91         return NULL;
92 }
93
94 enum rcar_isp_input {
95         RISP_CSI_INPUT0,
96         RISP_CSI_INPUT1,
97 };
98
99 enum rcar_isp_pads {
100         RCAR_ISP_SINK,
101         RCAR_ISP_PORT0,
102         RCAR_ISP_PORT1,
103         RCAR_ISP_PORT2,
104         RCAR_ISP_PORT3,
105         RCAR_ISP_PORT4,
106         RCAR_ISP_PORT5,
107         RCAR_ISP_PORT6,
108         RCAR_ISP_PORT7,
109         RCAR_ISP_NUM_PADS,
110 };
111
112 struct rcar_isp {
113         struct device *dev;
114         void __iomem *base;
115         struct reset_control *rstc;
116
117         enum rcar_isp_input csi_input;
118
119         struct v4l2_subdev subdev;
120         struct media_pad pads[RCAR_ISP_NUM_PADS];
121
122         struct v4l2_async_notifier notifier;
123         struct v4l2_subdev *remote;
124
125         struct mutex lock; /* Protects mf and stream_count. */
126         struct v4l2_mbus_framefmt mf;
127         int stream_count;
128 };
129
130 static inline struct rcar_isp *sd_to_isp(struct v4l2_subdev *sd)
131 {
132         return container_of(sd, struct rcar_isp, subdev);
133 }
134
135 static inline struct rcar_isp *notifier_to_isp(struct v4l2_async_notifier *n)
136 {
137         return container_of(n, struct rcar_isp, notifier);
138 }
139
140 static void risp_write(struct rcar_isp *isp, u32 offset, u32 value)
141 {
142         iowrite32(value, isp->base + offset);
143 }
144
145 static u32 risp_read(struct rcar_isp *isp, u32 offset)
146 {
147         return ioread32(isp->base + offset);
148 }
149
150 static int risp_power_on(struct rcar_isp *isp)
151 {
152         int ret;
153
154         ret = pm_runtime_resume_and_get(isp->dev);
155         if (ret < 0)
156                 return ret;
157
158         ret = reset_control_deassert(isp->rstc);
159         if (ret < 0) {
160                 pm_runtime_put(isp->dev);
161                 return ret;
162         }
163
164         return 0;
165 }
166
167 static void risp_power_off(struct rcar_isp *isp)
168 {
169         reset_control_assert(isp->rstc);
170         pm_runtime_put(isp->dev);
171 }
172
173 static int risp_start(struct rcar_isp *isp)
174 {
175         const struct rcar_isp_format *format;
176         unsigned int vc;
177         u32 sel_csi = 0;
178         int ret;
179
180         format = risp_code_to_fmt(isp->mf.code);
181         if (!format) {
182                 dev_err(isp->dev, "Unsupported bus format\n");
183                 return -EINVAL;
184         }
185
186         ret = risp_power_on(isp);
187         if (ret) {
188                 dev_err(isp->dev, "Failed to power on ISP\n");
189                 return ret;
190         }
191
192         /* Select CSI-2 input source. */
193         if (isp->csi_input == RISP_CSI_INPUT1)
194                 sel_csi = ISPINPUTSEL0_SEL_CSI0;
195
196         risp_write(isp, ISPINPUTSEL0_REG,
197                    risp_read(isp, ISPINPUTSEL0_REG) | sel_csi);
198
199         /* Configure Channel Selector. */
200         for (vc = 0; vc < 4; vc++) {
201                 u8 ch = vc + 4;
202                 u8 dt = format->datatype;
203
204                 risp_write(isp, ISPCS_FILTER_ID_CH_REG(ch), BIT(vc));
205                 risp_write(isp, ISPCS_DT_CODE03_CH_REG(ch),
206                            ISPCS_DT_CODE03_EN3 | ISPCS_DT_CODE03_DT3(dt) |
207                            ISPCS_DT_CODE03_EN2 | ISPCS_DT_CODE03_DT2(dt) |
208                            ISPCS_DT_CODE03_EN1 | ISPCS_DT_CODE03_DT1(dt) |
209                            ISPCS_DT_CODE03_EN0 | ISPCS_DT_CODE03_DT0(dt));
210         }
211
212         /* Setup processing method. */
213         risp_write(isp, ISPPROCMODE_DT_REG(format->datatype),
214                    ISPPROCMODE_DT_PROC_MODE_VC3(format->procmode) |
215                    ISPPROCMODE_DT_PROC_MODE_VC2(format->procmode) |
216                    ISPPROCMODE_DT_PROC_MODE_VC1(format->procmode) |
217                    ISPPROCMODE_DT_PROC_MODE_VC0(format->procmode));
218
219         /* Start ISP. */
220         risp_write(isp, ISPSTART_REG, ISPSTART_START);
221
222         ret = v4l2_subdev_call(isp->remote, video, s_stream, 1);
223         if (ret)
224                 risp_power_off(isp);
225
226         return ret;
227 }
228
229 static void risp_stop(struct rcar_isp *isp)
230 {
231         v4l2_subdev_call(isp->remote, video, s_stream, 0);
232
233         /* Stop ISP. */
234         risp_write(isp, ISPSTART_REG, ISPSTART_STOP);
235
236         risp_power_off(isp);
237 }
238
239 static int risp_s_stream(struct v4l2_subdev *sd, int enable)
240 {
241         struct rcar_isp *isp = sd_to_isp(sd);
242         int ret = 0;
243
244         mutex_lock(&isp->lock);
245
246         if (!isp->remote) {
247                 ret = -ENODEV;
248                 goto out;
249         }
250
251         if (enable && isp->stream_count == 0) {
252                 ret = risp_start(isp);
253                 if (ret)
254                         goto out;
255         } else if (!enable && isp->stream_count == 1) {
256                 risp_stop(isp);
257         }
258
259         isp->stream_count += enable ? 1 : -1;
260 out:
261         mutex_unlock(&isp->lock);
262
263         return ret;
264 }
265
266 static const struct v4l2_subdev_video_ops risp_video_ops = {
267         .s_stream = risp_s_stream,
268 };
269
270 static int risp_set_pad_format(struct v4l2_subdev *sd,
271                                struct v4l2_subdev_state *sd_state,
272                                struct v4l2_subdev_format *format)
273 {
274         struct rcar_isp *isp = sd_to_isp(sd);
275         struct v4l2_mbus_framefmt *framefmt;
276
277         mutex_lock(&isp->lock);
278
279         if (!risp_code_to_fmt(format->format.code))
280                 format->format.code = rcar_isp_formats[0].code;
281
282         if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
283                 isp->mf = format->format;
284         } else {
285                 framefmt = v4l2_subdev_get_try_format(sd, sd_state, 0);
286                 *framefmt = format->format;
287         }
288
289         mutex_unlock(&isp->lock);
290
291         return 0;
292 }
293
294 static int risp_get_pad_format(struct v4l2_subdev *sd,
295                                struct v4l2_subdev_state *sd_state,
296                                struct v4l2_subdev_format *format)
297 {
298         struct rcar_isp *isp = sd_to_isp(sd);
299
300         mutex_lock(&isp->lock);
301
302         if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
303                 format->format = isp->mf;
304         else
305                 format->format = *v4l2_subdev_get_try_format(sd, sd_state, 0);
306
307         mutex_unlock(&isp->lock);
308
309         return 0;
310 }
311
312 static const struct v4l2_subdev_pad_ops risp_pad_ops = {
313         .set_fmt = risp_set_pad_format,
314         .get_fmt = risp_get_pad_format,
315         .link_validate = v4l2_subdev_link_validate_default,
316 };
317
318 static const struct v4l2_subdev_ops rcar_isp_subdev_ops = {
319         .video  = &risp_video_ops,
320         .pad    = &risp_pad_ops,
321 };
322
323 /* -----------------------------------------------------------------------------
324  * Async handling and registration of subdevices and links
325  */
326
327 static int risp_notify_bound(struct v4l2_async_notifier *notifier,
328                              struct v4l2_subdev *subdev,
329                              struct v4l2_async_subdev *asd)
330 {
331         struct rcar_isp *isp = notifier_to_isp(notifier);
332         int pad;
333
334         pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode,
335                                           MEDIA_PAD_FL_SOURCE);
336         if (pad < 0) {
337                 dev_err(isp->dev, "Failed to find pad for %s\n", subdev->name);
338                 return pad;
339         }
340
341         isp->remote = subdev;
342
343         dev_dbg(isp->dev, "Bound %s pad: %d\n", subdev->name, pad);
344
345         return media_create_pad_link(&subdev->entity, pad,
346                                      &isp->subdev.entity, 0,
347                                      MEDIA_LNK_FL_ENABLED |
348                                      MEDIA_LNK_FL_IMMUTABLE);
349 }
350
351 static void risp_notify_unbind(struct v4l2_async_notifier *notifier,
352                                struct v4l2_subdev *subdev,
353                                struct v4l2_async_subdev *asd)
354 {
355         struct rcar_isp *isp = notifier_to_isp(notifier);
356
357         isp->remote = NULL;
358
359         dev_dbg(isp->dev, "Unbind %s\n", subdev->name);
360 }
361
362 static const struct v4l2_async_notifier_operations risp_notify_ops = {
363         .bound = risp_notify_bound,
364         .unbind = risp_notify_unbind,
365 };
366
367 static int risp_parse_dt(struct rcar_isp *isp)
368 {
369         struct v4l2_async_subdev *asd;
370         struct fwnode_handle *fwnode;
371         struct fwnode_handle *ep;
372         unsigned int id;
373         int ret;
374
375         for (id = 0; id < 2; id++) {
376                 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(isp->dev),
377                                                      0, id, 0);
378                 if (ep)
379                         break;
380         }
381
382         if (!ep) {
383                 dev_err(isp->dev, "Not connected to subdevice\n");
384                 return -EINVAL;
385         }
386
387         if (id == 1)
388                 isp->csi_input = RISP_CSI_INPUT1;
389
390         fwnode = fwnode_graph_get_remote_endpoint(ep);
391         fwnode_handle_put(ep);
392
393         dev_dbg(isp->dev, "Found '%pOF'\n", to_of_node(fwnode));
394
395         v4l2_async_nf_init(&isp->notifier);
396         isp->notifier.ops = &risp_notify_ops;
397
398         asd = v4l2_async_nf_add_fwnode(&isp->notifier, fwnode,
399                                        struct v4l2_async_subdev);
400         fwnode_handle_put(fwnode);
401         if (IS_ERR(asd))
402                 return PTR_ERR(asd);
403
404         ret = v4l2_async_subdev_nf_register(&isp->subdev, &isp->notifier);
405         if (ret)
406                 v4l2_async_nf_cleanup(&isp->notifier);
407
408         return ret;
409 }
410
411 /* -----------------------------------------------------------------------------
412  * Platform Device Driver
413  */
414
415 static const struct media_entity_operations risp_entity_ops = {
416         .link_validate = v4l2_subdev_link_validate,
417 };
418
419 static int risp_probe_resources(struct rcar_isp *isp,
420                                 struct platform_device *pdev)
421 {
422         struct resource *res;
423
424         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
425         isp->base = devm_ioremap_resource(&pdev->dev, res);
426         if (IS_ERR(isp->base))
427                 return PTR_ERR(isp->base);
428
429         isp->rstc = devm_reset_control_get(&pdev->dev, NULL);
430
431         return PTR_ERR_OR_ZERO(isp->rstc);
432 }
433
434 static const struct of_device_id risp_of_id_table[] = {
435         { .compatible = "renesas,r8a779a0-isp" },
436         { /* sentinel */ },
437 };
438 MODULE_DEVICE_TABLE(of, risp_of_id_table);
439
440 static int risp_probe(struct platform_device *pdev)
441 {
442         struct rcar_isp *isp;
443         unsigned int i;
444         int ret;
445
446         isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL);
447         if (!isp)
448                 return -ENOMEM;
449
450         isp->dev = &pdev->dev;
451
452         mutex_init(&isp->lock);
453
454         ret = risp_probe_resources(isp, pdev);
455         if (ret) {
456                 dev_err(isp->dev, "Failed to get resources\n");
457                 goto error_mutex;
458         }
459
460         platform_set_drvdata(pdev, isp);
461
462         pm_runtime_enable(&pdev->dev);
463
464         ret = risp_parse_dt(isp);
465         if (ret)
466                 goto error_pm;
467
468         isp->subdev.owner = THIS_MODULE;
469         isp->subdev.dev = &pdev->dev;
470         v4l2_subdev_init(&isp->subdev, &rcar_isp_subdev_ops);
471         v4l2_set_subdevdata(&isp->subdev, &pdev->dev);
472         snprintf(isp->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s %s",
473                  KBUILD_MODNAME, dev_name(&pdev->dev));
474         isp->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
475
476         isp->subdev.entity.function = MEDIA_ENT_F_VID_MUX;
477         isp->subdev.entity.ops = &risp_entity_ops;
478
479         isp->pads[RCAR_ISP_SINK].flags = MEDIA_PAD_FL_SINK;
480         for (i = RCAR_ISP_PORT0; i < RCAR_ISP_NUM_PADS; i++)
481                 isp->pads[i].flags = MEDIA_PAD_FL_SOURCE;
482
483         ret = media_entity_pads_init(&isp->subdev.entity, RCAR_ISP_NUM_PADS,
484                                      isp->pads);
485         if (ret)
486                 goto error_notifier;
487
488         ret = v4l2_async_register_subdev(&isp->subdev);
489         if (ret < 0)
490                 goto error_notifier;
491
492         dev_info(isp->dev, "Using CSI-2 input: %u\n", isp->csi_input);
493
494         return 0;
495 error_notifier:
496         v4l2_async_nf_unregister(&isp->notifier);
497         v4l2_async_nf_cleanup(&isp->notifier);
498 error_pm:
499         pm_runtime_disable(&pdev->dev);
500 error_mutex:
501         mutex_destroy(&isp->lock);
502
503         return ret;
504 }
505
506 static int risp_remove(struct platform_device *pdev)
507 {
508         struct rcar_isp *isp = platform_get_drvdata(pdev);
509
510         v4l2_async_nf_unregister(&isp->notifier);
511         v4l2_async_nf_cleanup(&isp->notifier);
512
513         v4l2_async_unregister_subdev(&isp->subdev);
514
515         pm_runtime_disable(&pdev->dev);
516
517         mutex_destroy(&isp->lock);
518
519         return 0;
520 }
521
522 static struct platform_driver rcar_isp_driver = {
523         .driver = {
524                 .name = "rcar-isp",
525                 .of_match_table = risp_of_id_table,
526         },
527         .probe = risp_probe,
528         .remove = risp_remove,
529 };
530
531 module_platform_driver(rcar_isp_driver);
532
533 MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
534 MODULE_DESCRIPTION("Renesas R-Car ISP Channel Selector driver");
535 MODULE_LICENSE("GPL");