GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / media / platform / renesas / vsp1 / vsp1_drv.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * vsp1_drv.c  --  R-Car VSP1 Driver
4  *
5  * Copyright (C) 2013-2015 Renesas Electronics Corporation
6  *
7  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
8  */
9
10 #include <linux/clk.h>
11 #include <linux/delay.h>
12 #include <linux/device.h>
13 #include <linux/interrupt.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/reset.h>
19 #include <linux/videodev2.h>
20
21 #include <media/rcar-fcp.h>
22 #include <media/v4l2-subdev.h>
23
24 #include "vsp1.h"
25 #include "vsp1_brx.h"
26 #include "vsp1_clu.h"
27 #include "vsp1_dl.h"
28 #include "vsp1_drm.h"
29 #include "vsp1_hgo.h"
30 #include "vsp1_hgt.h"
31 #include "vsp1_hsit.h"
32 #include "vsp1_lif.h"
33 #include "vsp1_lut.h"
34 #include "vsp1_pipe.h"
35 #include "vsp1_rwpf.h"
36 #include "vsp1_sru.h"
37 #include "vsp1_uds.h"
38 #include "vsp1_uif.h"
39 #include "vsp1_video.h"
40
41 /* -----------------------------------------------------------------------------
42  * Interrupt Handling
43  */
44
45 static irqreturn_t vsp1_irq_handler(int irq, void *data)
46 {
47         u32 mask = VI6_WPF_IRQ_STA_DFE | VI6_WPF_IRQ_STA_FRE |
48                    VI6_WPF_IRQ_STA_UND;
49         struct vsp1_device *vsp1 = data;
50         irqreturn_t ret = IRQ_NONE;
51         unsigned int i;
52         u32 status;
53
54         for (i = 0; i < vsp1->info->wpf_count; ++i) {
55                 struct vsp1_rwpf *wpf = vsp1->wpf[i];
56
57                 if (wpf == NULL)
58                         continue;
59
60                 status = vsp1_read(vsp1, VI6_WPF_IRQ_STA(i));
61                 vsp1_write(vsp1, VI6_WPF_IRQ_STA(i), ~status & mask);
62
63                 if ((status & VI6_WPF_IRQ_STA_UND) && wpf->entity.pipe) {
64                         wpf->entity.pipe->underrun_count++;
65
66                         dev_warn_ratelimited(vsp1->dev,
67                                 "Underrun occurred at WPF%u (total underruns %u)\n",
68                                 i, wpf->entity.pipe->underrun_count);
69                 }
70
71                 if (status & VI6_WPF_IRQ_STA_DFE) {
72                         vsp1_pipeline_frame_end(wpf->entity.pipe);
73                         ret = IRQ_HANDLED;
74                 }
75         }
76
77         return ret;
78 }
79
80 /* -----------------------------------------------------------------------------
81  * Entities
82  */
83
84 /*
85  * vsp1_create_sink_links - Create links from all sources to the given sink
86  *
87  * This function creates media links from all valid sources to the given sink
88  * pad. Links that would be invalid according to the VSP1 hardware capabilities
89  * are skipped. Those include all links
90  *
91  * - from a UDS to a UDS (UDS entities can't be chained)
92  * - from an entity to itself (no loops are allowed)
93  *
94  * Furthermore, the BRS can't be connected to histogram generators, but no
95  * special check is currently needed as all VSP instances that include a BRS
96  * have no histogram generator.
97  */
98 static int vsp1_create_sink_links(struct vsp1_device *vsp1,
99                                   struct vsp1_entity *sink)
100 {
101         struct media_entity *entity = &sink->subdev.entity;
102         struct vsp1_entity *source;
103         unsigned int pad;
104         int ret;
105
106         list_for_each_entry(source, &vsp1->entities, list_dev) {
107                 u32 flags;
108
109                 if (source->type == sink->type)
110                         continue;
111
112                 if (source->type == VSP1_ENTITY_HGO ||
113                     source->type == VSP1_ENTITY_HGT ||
114                     source->type == VSP1_ENTITY_LIF ||
115                     source->type == VSP1_ENTITY_WPF)
116                         continue;
117
118                 flags = source->type == VSP1_ENTITY_RPF &&
119                         sink->type == VSP1_ENTITY_WPF &&
120                         source->index == sink->index
121                       ? MEDIA_LNK_FL_ENABLED : 0;
122
123                 for (pad = 0; pad < entity->num_pads; ++pad) {
124                         if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK))
125                                 continue;
126
127                         ret = media_create_pad_link(&source->subdev.entity,
128                                                        source->source_pad,
129                                                        entity, pad, flags);
130                         if (ret < 0)
131                                 return ret;
132
133                         if (flags & MEDIA_LNK_FL_ENABLED)
134                                 source->sink = sink;
135                 }
136         }
137
138         return 0;
139 }
140
141 static int vsp1_uapi_create_links(struct vsp1_device *vsp1)
142 {
143         struct vsp1_entity *entity;
144         unsigned int i;
145         int ret;
146
147         list_for_each_entry(entity, &vsp1->entities, list_dev) {
148                 if (entity->type == VSP1_ENTITY_LIF ||
149                     entity->type == VSP1_ENTITY_RPF)
150                         continue;
151
152                 ret = vsp1_create_sink_links(vsp1, entity);
153                 if (ret < 0)
154                         return ret;
155         }
156
157         if (vsp1->hgo) {
158                 ret = media_create_pad_link(&vsp1->hgo->histo.entity.subdev.entity,
159                                             HISTO_PAD_SOURCE,
160                                             &vsp1->hgo->histo.video.entity, 0,
161                                             MEDIA_LNK_FL_ENABLED |
162                                             MEDIA_LNK_FL_IMMUTABLE);
163                 if (ret < 0)
164                         return ret;
165         }
166
167         if (vsp1->hgt) {
168                 ret = media_create_pad_link(&vsp1->hgt->histo.entity.subdev.entity,
169                                             HISTO_PAD_SOURCE,
170                                             &vsp1->hgt->histo.video.entity, 0,
171                                             MEDIA_LNK_FL_ENABLED |
172                                             MEDIA_LNK_FL_IMMUTABLE);
173                 if (ret < 0)
174                         return ret;
175         }
176
177         for (i = 0; i < vsp1->info->lif_count; ++i) {
178                 if (!vsp1->lif[i])
179                         continue;
180
181                 ret = media_create_pad_link(&vsp1->wpf[i]->entity.subdev.entity,
182                                             RWPF_PAD_SOURCE,
183                                             &vsp1->lif[i]->entity.subdev.entity,
184                                             LIF_PAD_SINK, 0);
185                 if (ret < 0)
186                         return ret;
187         }
188
189         for (i = 0; i < vsp1->info->rpf_count; ++i) {
190                 struct vsp1_rwpf *rpf = vsp1->rpf[i];
191
192                 ret = media_create_pad_link(&rpf->video->video.entity, 0,
193                                             &rpf->entity.subdev.entity,
194                                             RWPF_PAD_SINK,
195                                             MEDIA_LNK_FL_ENABLED |
196                                             MEDIA_LNK_FL_IMMUTABLE);
197                 if (ret < 0)
198                         return ret;
199         }
200
201         for (i = 0; i < vsp1->info->wpf_count; ++i) {
202                 /*
203                  * Connect the video device to the WPF. All connections are
204                  * immutable.
205                  */
206                 struct vsp1_rwpf *wpf = vsp1->wpf[i];
207
208                 ret = media_create_pad_link(&wpf->entity.subdev.entity,
209                                             RWPF_PAD_SOURCE,
210                                             &wpf->video->video.entity, 0,
211                                             MEDIA_LNK_FL_IMMUTABLE |
212                                             MEDIA_LNK_FL_ENABLED);
213                 if (ret < 0)
214                         return ret;
215         }
216
217         return 0;
218 }
219
220 static void vsp1_destroy_entities(struct vsp1_device *vsp1)
221 {
222         struct vsp1_entity *entity, *_entity;
223         struct vsp1_video *video, *_video;
224
225         list_for_each_entry_safe(entity, _entity, &vsp1->entities, list_dev) {
226                 list_del(&entity->list_dev);
227                 vsp1_entity_destroy(entity);
228         }
229
230         list_for_each_entry_safe(video, _video, &vsp1->videos, list) {
231                 list_del(&video->list);
232                 vsp1_video_cleanup(video);
233         }
234
235         v4l2_device_unregister(&vsp1->v4l2_dev);
236         if (vsp1->info->uapi)
237                 media_device_unregister(&vsp1->media_dev);
238         media_device_cleanup(&vsp1->media_dev);
239
240         if (!vsp1->info->uapi)
241                 vsp1_drm_cleanup(vsp1);
242 }
243
244 static int vsp1_create_entities(struct vsp1_device *vsp1)
245 {
246         struct media_device *mdev = &vsp1->media_dev;
247         struct v4l2_device *vdev = &vsp1->v4l2_dev;
248         struct vsp1_entity *entity;
249         unsigned int i;
250         int ret;
251
252         mdev->dev = vsp1->dev;
253         mdev->hw_revision = vsp1->version;
254         strscpy(mdev->model, vsp1->info->model, sizeof(mdev->model));
255         media_device_init(mdev);
256
257         vsp1->media_ops.link_setup = vsp1_entity_link_setup;
258         /*
259          * Don't perform link validation when the userspace API is disabled as
260          * the pipeline is configured internally by the driver in that case, and
261          * its configuration can thus be trusted.
262          */
263         if (vsp1->info->uapi)
264                 vsp1->media_ops.link_validate = v4l2_subdev_link_validate;
265
266         vdev->mdev = mdev;
267         ret = v4l2_device_register(vsp1->dev, vdev);
268         if (ret < 0) {
269                 dev_err(vsp1->dev, "V4L2 device registration failed (%d)\n",
270                         ret);
271                 goto done;
272         }
273
274         /* Instantiate all the entities. */
275         if (vsp1_feature(vsp1, VSP1_HAS_BRS)) {
276                 vsp1->brs = vsp1_brx_create(vsp1, VSP1_ENTITY_BRS);
277                 if (IS_ERR(vsp1->brs)) {
278                         ret = PTR_ERR(vsp1->brs);
279                         goto done;
280                 }
281
282                 list_add_tail(&vsp1->brs->entity.list_dev, &vsp1->entities);
283         }
284
285         if (vsp1_feature(vsp1, VSP1_HAS_BRU)) {
286                 vsp1->bru = vsp1_brx_create(vsp1, VSP1_ENTITY_BRU);
287                 if (IS_ERR(vsp1->bru)) {
288                         ret = PTR_ERR(vsp1->bru);
289                         goto done;
290                 }
291
292                 list_add_tail(&vsp1->bru->entity.list_dev, &vsp1->entities);
293         }
294
295         if (vsp1_feature(vsp1, VSP1_HAS_CLU)) {
296                 vsp1->clu = vsp1_clu_create(vsp1);
297                 if (IS_ERR(vsp1->clu)) {
298                         ret = PTR_ERR(vsp1->clu);
299                         goto done;
300                 }
301
302                 list_add_tail(&vsp1->clu->entity.list_dev, &vsp1->entities);
303         }
304
305         vsp1->hsi = vsp1_hsit_create(vsp1, true);
306         if (IS_ERR(vsp1->hsi)) {
307                 ret = PTR_ERR(vsp1->hsi);
308                 goto done;
309         }
310
311         list_add_tail(&vsp1->hsi->entity.list_dev, &vsp1->entities);
312
313         vsp1->hst = vsp1_hsit_create(vsp1, false);
314         if (IS_ERR(vsp1->hst)) {
315                 ret = PTR_ERR(vsp1->hst);
316                 goto done;
317         }
318
319         list_add_tail(&vsp1->hst->entity.list_dev, &vsp1->entities);
320
321         if (vsp1_feature(vsp1, VSP1_HAS_HGO) && vsp1->info->uapi) {
322                 vsp1->hgo = vsp1_hgo_create(vsp1);
323                 if (IS_ERR(vsp1->hgo)) {
324                         ret = PTR_ERR(vsp1->hgo);
325                         goto done;
326                 }
327
328                 list_add_tail(&vsp1->hgo->histo.entity.list_dev,
329                               &vsp1->entities);
330         }
331
332         if (vsp1_feature(vsp1, VSP1_HAS_HGT) && vsp1->info->uapi) {
333                 vsp1->hgt = vsp1_hgt_create(vsp1);
334                 if (IS_ERR(vsp1->hgt)) {
335                         ret = PTR_ERR(vsp1->hgt);
336                         goto done;
337                 }
338
339                 list_add_tail(&vsp1->hgt->histo.entity.list_dev,
340                               &vsp1->entities);
341         }
342
343         /*
344          * The LIFs are only supported when used in conjunction with the DU, in
345          * which case the userspace API is disabled. If the userspace API is
346          * enabled skip the LIFs, even when present.
347          */
348         if (!vsp1->info->uapi) {
349                 for (i = 0; i < vsp1->info->lif_count; ++i) {
350                         struct vsp1_lif *lif;
351
352                         lif = vsp1_lif_create(vsp1, i);
353                         if (IS_ERR(lif)) {
354                                 ret = PTR_ERR(lif);
355                                 goto done;
356                         }
357
358                         vsp1->lif[i] = lif;
359                         list_add_tail(&lif->entity.list_dev, &vsp1->entities);
360                 }
361         }
362
363         if (vsp1_feature(vsp1, VSP1_HAS_LUT)) {
364                 vsp1->lut = vsp1_lut_create(vsp1);
365                 if (IS_ERR(vsp1->lut)) {
366                         ret = PTR_ERR(vsp1->lut);
367                         goto done;
368                 }
369
370                 list_add_tail(&vsp1->lut->entity.list_dev, &vsp1->entities);
371         }
372
373         for (i = 0; i < vsp1->info->rpf_count; ++i) {
374                 struct vsp1_rwpf *rpf;
375
376                 rpf = vsp1_rpf_create(vsp1, i);
377                 if (IS_ERR(rpf)) {
378                         ret = PTR_ERR(rpf);
379                         goto done;
380                 }
381
382                 vsp1->rpf[i] = rpf;
383                 list_add_tail(&rpf->entity.list_dev, &vsp1->entities);
384
385                 if (vsp1->info->uapi) {
386                         struct vsp1_video *video = vsp1_video_create(vsp1, rpf);
387
388                         if (IS_ERR(video)) {
389                                 ret = PTR_ERR(video);
390                                 goto done;
391                         }
392
393                         list_add_tail(&video->list, &vsp1->videos);
394                 }
395         }
396
397         if (vsp1_feature(vsp1, VSP1_HAS_SRU)) {
398                 vsp1->sru = vsp1_sru_create(vsp1);
399                 if (IS_ERR(vsp1->sru)) {
400                         ret = PTR_ERR(vsp1->sru);
401                         goto done;
402                 }
403
404                 list_add_tail(&vsp1->sru->entity.list_dev, &vsp1->entities);
405         }
406
407         for (i = 0; i < vsp1->info->uds_count; ++i) {
408                 struct vsp1_uds *uds;
409
410                 uds = vsp1_uds_create(vsp1, i);
411                 if (IS_ERR(uds)) {
412                         ret = PTR_ERR(uds);
413                         goto done;
414                 }
415
416                 vsp1->uds[i] = uds;
417                 list_add_tail(&uds->entity.list_dev, &vsp1->entities);
418         }
419
420         for (i = 0; i < vsp1->info->uif_count; ++i) {
421                 struct vsp1_uif *uif;
422
423                 uif = vsp1_uif_create(vsp1, i);
424                 if (IS_ERR(uif)) {
425                         ret = PTR_ERR(uif);
426                         goto done;
427                 }
428
429                 vsp1->uif[i] = uif;
430                 list_add_tail(&uif->entity.list_dev, &vsp1->entities);
431         }
432
433         for (i = 0; i < vsp1->info->wpf_count; ++i) {
434                 struct vsp1_rwpf *wpf;
435
436                 wpf = vsp1_wpf_create(vsp1, i);
437                 if (IS_ERR(wpf)) {
438                         ret = PTR_ERR(wpf);
439                         goto done;
440                 }
441
442                 vsp1->wpf[i] = wpf;
443                 list_add_tail(&wpf->entity.list_dev, &vsp1->entities);
444
445                 if (vsp1->info->uapi) {
446                         struct vsp1_video *video = vsp1_video_create(vsp1, wpf);
447
448                         if (IS_ERR(video)) {
449                                 ret = PTR_ERR(video);
450                                 goto done;
451                         }
452
453                         list_add_tail(&video->list, &vsp1->videos);
454                 }
455         }
456
457         /* Register all subdevs. */
458         list_for_each_entry(entity, &vsp1->entities, list_dev) {
459                 ret = v4l2_device_register_subdev(&vsp1->v4l2_dev,
460                                                   &entity->subdev);
461                 if (ret < 0)
462                         goto done;
463         }
464
465         /*
466          * Create links and register subdev nodes if the userspace API is
467          * enabled or initialize the DRM pipeline otherwise.
468          */
469         if (vsp1->info->uapi) {
470                 ret = vsp1_uapi_create_links(vsp1);
471                 if (ret < 0)
472                         goto done;
473
474                 ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev);
475                 if (ret < 0)
476                         goto done;
477
478                 ret = media_device_register(mdev);
479         } else {
480                 ret = vsp1_drm_init(vsp1);
481         }
482
483 done:
484         if (ret < 0)
485                 vsp1_destroy_entities(vsp1);
486
487         return ret;
488 }
489
490 int vsp1_reset_wpf(struct vsp1_device *vsp1, unsigned int index)
491 {
492         unsigned int timeout;
493         u32 status;
494
495         status = vsp1_read(vsp1, VI6_STATUS);
496         if (!(status & VI6_STATUS_SYS_ACT(index)))
497                 return 0;
498
499         vsp1_write(vsp1, VI6_SRESET, VI6_SRESET_SRTS(index));
500         for (timeout = 10; timeout > 0; --timeout) {
501                 status = vsp1_read(vsp1, VI6_STATUS);
502                 if (!(status & VI6_STATUS_SYS_ACT(index)))
503                         break;
504
505                 usleep_range(1000, 2000);
506         }
507
508         if (!timeout) {
509                 dev_err(vsp1->dev, "failed to reset wpf.%u\n", index);
510                 return -ETIMEDOUT;
511         }
512
513         return 0;
514 }
515
516 static int vsp1_device_init(struct vsp1_device *vsp1)
517 {
518         unsigned int i;
519         int ret;
520
521         /* Reset any channel that might be running. */
522         for (i = 0; i < vsp1->info->wpf_count; ++i) {
523                 ret = vsp1_reset_wpf(vsp1, i);
524                 if (ret < 0)
525                         return ret;
526         }
527
528         vsp1_write(vsp1, VI6_CLK_DCSWT, (8 << VI6_CLK_DCSWT_CSTPW_SHIFT) |
529                    (8 << VI6_CLK_DCSWT_CSTRW_SHIFT));
530
531         for (i = 0; i < vsp1->info->rpf_count; ++i)
532                 vsp1_write(vsp1, VI6_DPR_RPF_ROUTE(i), VI6_DPR_NODE_UNUSED);
533
534         for (i = 0; i < vsp1->info->uds_count; ++i)
535                 vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED);
536
537         for (i = 0; i < vsp1->info->uif_count; ++i)
538                 vsp1_write(vsp1, VI6_DPR_UIF_ROUTE(i), VI6_DPR_NODE_UNUSED);
539
540         vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED);
541         vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, VI6_DPR_NODE_UNUSED);
542         vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, VI6_DPR_NODE_UNUSED);
543         vsp1_write(vsp1, VI6_DPR_HST_ROUTE, VI6_DPR_NODE_UNUSED);
544         vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, VI6_DPR_NODE_UNUSED);
545         vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, VI6_DPR_NODE_UNUSED);
546
547         if (vsp1_feature(vsp1, VSP1_HAS_BRS))
548                 vsp1_write(vsp1, VI6_DPR_ILV_BRS_ROUTE, VI6_DPR_NODE_UNUSED);
549
550         vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
551                    (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
552         vsp1_write(vsp1, VI6_DPR_HGT_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
553                    (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
554
555         vsp1_dlm_setup(vsp1);
556
557         return 0;
558 }
559
560 static void vsp1_mask_all_interrupts(struct vsp1_device *vsp1)
561 {
562         unsigned int i;
563
564         for (i = 0; i < vsp1->info->lif_count; ++i)
565                 vsp1_write(vsp1, VI6_DISP_IRQ_ENB(i), 0);
566         for (i = 0; i < vsp1->info->wpf_count; ++i)
567                 vsp1_write(vsp1, VI6_WPF_IRQ_ENB(i), 0);
568 }
569
570 /*
571  * vsp1_device_get - Acquire the VSP1 device
572  *
573  * Make sure the device is not suspended and initialize it if needed.
574  *
575  * Return 0 on success or a negative error code otherwise.
576  */
577 int vsp1_device_get(struct vsp1_device *vsp1)
578 {
579         return pm_runtime_resume_and_get(vsp1->dev);
580 }
581
582 /*
583  * vsp1_device_put - Release the VSP1 device
584  *
585  * Decrement the VSP1 reference count and cleanup the device if the last
586  * reference is released.
587  */
588 void vsp1_device_put(struct vsp1_device *vsp1)
589 {
590         pm_runtime_put_sync(vsp1->dev);
591 }
592
593 /* -----------------------------------------------------------------------------
594  * Power Management
595  */
596
597 static int __maybe_unused vsp1_pm_suspend(struct device *dev)
598 {
599         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
600
601         /*
602          * When used as part of a display pipeline, the VSP is stopped and
603          * restarted explicitly by the DU.
604          */
605         if (!vsp1->drm)
606                 vsp1_video_suspend(vsp1);
607
608         pm_runtime_force_suspend(vsp1->dev);
609
610         return 0;
611 }
612
613 static int __maybe_unused vsp1_pm_resume(struct device *dev)
614 {
615         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
616
617         pm_runtime_force_resume(vsp1->dev);
618
619         /*
620          * When used as part of a display pipeline, the VSP is stopped and
621          * restarted explicitly by the DU.
622          */
623         if (!vsp1->drm)
624                 vsp1_video_resume(vsp1);
625
626         return 0;
627 }
628
629 static int __maybe_unused vsp1_pm_runtime_suspend(struct device *dev)
630 {
631         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
632
633         rcar_fcp_disable(vsp1->fcp);
634         reset_control_assert(vsp1->rstc);
635
636         return 0;
637 }
638
639 static int __maybe_unused vsp1_pm_runtime_resume(struct device *dev)
640 {
641         struct vsp1_device *vsp1 = dev_get_drvdata(dev);
642         int ret;
643
644         ret = reset_control_deassert(vsp1->rstc);
645         if (ret < 0)
646                 return ret;
647
648         if (vsp1->info) {
649                 /*
650                  * On R-Car Gen2 and RZ/G1, vsp1 register access after deassert
651                  * can cause lock-up. It is a special case and needs some delay
652                  * to avoid this lock-up.
653                  */
654                 if (vsp1->info->gen == 2)
655                         udelay(1);
656
657                 ret = vsp1_device_init(vsp1);
658                 if (ret < 0)
659                         goto done;
660         }
661
662         ret = rcar_fcp_enable(vsp1->fcp);
663
664 done:
665         if (ret < 0)
666                 reset_control_assert(vsp1->rstc);
667
668         return ret;
669 }
670
671 static const struct dev_pm_ops vsp1_pm_ops = {
672         SET_SYSTEM_SLEEP_PM_OPS(vsp1_pm_suspend, vsp1_pm_resume)
673         SET_RUNTIME_PM_OPS(vsp1_pm_runtime_suspend, vsp1_pm_runtime_resume, NULL)
674 };
675
676 /* -----------------------------------------------------------------------------
677  * Platform Driver
678  */
679
680 static const struct vsp1_device_info vsp1_device_infos[] = {
681         {
682                 .version = VI6_IP_VERSION_MODEL_VSPS_H2,
683                 .model = "VSP1-S",
684                 .gen = 2,
685                 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HGO
686                           | VSP1_HAS_HGT | VSP1_HAS_LUT | VSP1_HAS_SRU
687                           | VSP1_HAS_WPF_VFLIP,
688                 .rpf_count = 5,
689                 .uds_count = 3,
690                 .wpf_count = 4,
691                 .num_bru_inputs = 4,
692                 .uapi = true,
693         }, {
694                 .version = VI6_IP_VERSION_MODEL_VSPR_H2,
695                 .model = "VSP1-R",
696                 .gen = 2,
697                 .features = VSP1_HAS_BRU | VSP1_HAS_SRU | VSP1_HAS_WPF_VFLIP,
698                 .rpf_count = 5,
699                 .uds_count = 3,
700                 .wpf_count = 4,
701                 .num_bru_inputs = 4,
702                 .uapi = true,
703         }, {
704                 .version = VI6_IP_VERSION_MODEL_VSPD_GEN2,
705                 .model = "VSP1-D",
706                 .gen = 2,
707                 .features = VSP1_HAS_BRU | VSP1_HAS_HGO | VSP1_HAS_LUT,
708                 .lif_count = 1,
709                 .rpf_count = 4,
710                 .uds_count = 1,
711                 .wpf_count = 1,
712                 .num_bru_inputs = 4,
713                 .uapi = true,
714         }, {
715                 .version = VI6_IP_VERSION_MODEL_VSPS_M2,
716                 .model = "VSP1-S",
717                 .gen = 2,
718                 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HGO
719                           | VSP1_HAS_HGT | VSP1_HAS_LUT | VSP1_HAS_SRU
720                           | VSP1_HAS_WPF_VFLIP,
721                 .rpf_count = 5,
722                 .uds_count = 1,
723                 .wpf_count = 4,
724                 .num_bru_inputs = 4,
725                 .uapi = true,
726         }, {
727                 .version = VI6_IP_VERSION_MODEL_VSPS_V2H,
728                 .model = "VSP1V-S",
729                 .gen = 2,
730                 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT
731                           | VSP1_HAS_SRU | VSP1_HAS_WPF_VFLIP,
732                 .rpf_count = 4,
733                 .uds_count = 1,
734                 .wpf_count = 4,
735                 .num_bru_inputs = 4,
736                 .uapi = true,
737         }, {
738                 .version = VI6_IP_VERSION_MODEL_VSPD_V2H,
739                 .model = "VSP1V-D",
740                 .gen = 2,
741                 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT,
742                 .lif_count = 1,
743                 .rpf_count = 4,
744                 .uds_count = 1,
745                 .wpf_count = 1,
746                 .num_bru_inputs = 4,
747                 .uapi = true,
748         }, {
749                 .version = VI6_IP_VERSION_MODEL_VSPI_GEN3,
750                 .model = "VSP2-I",
751                 .gen = 3,
752                 .features = VSP1_HAS_CLU | VSP1_HAS_HGO | VSP1_HAS_HGT
753                           | VSP1_HAS_LUT | VSP1_HAS_SRU | VSP1_HAS_WPF_HFLIP
754                           | VSP1_HAS_WPF_VFLIP,
755                 .rpf_count = 1,
756                 .uds_count = 1,
757                 .wpf_count = 1,
758                 .uapi = true,
759         }, {
760                 .version = VI6_IP_VERSION_MODEL_VSPBD_GEN3,
761                 .model = "VSP2-BD",
762                 .gen = 3,
763                 .features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
764                 .rpf_count = 5,
765                 .wpf_count = 1,
766                 .num_bru_inputs = 5,
767                 .uapi = true,
768         }, {
769                 .version = VI6_IP_VERSION_MODEL_VSPBC_GEN3,
770                 .model = "VSP2-BC",
771                 .gen = 3,
772                 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HGO
773                           | VSP1_HAS_LUT | VSP1_HAS_WPF_VFLIP,
774                 .rpf_count = 5,
775                 .wpf_count = 1,
776                 .num_bru_inputs = 5,
777                 .uapi = true,
778         }, {
779                 .version = VI6_IP_VERSION_MODEL_VSPBS_GEN3,
780                 .model = "VSP2-BS",
781                 .gen = 3,
782                 .features = VSP1_HAS_BRS | VSP1_HAS_WPF_VFLIP,
783                 .rpf_count = 2,
784                 .wpf_count = 1,
785                 .uapi = true,
786         }, {
787                 .version = VI6_IP_VERSION_MODEL_VSPD_GEN3,
788                 .model = "VSP2-D",
789                 .gen = 3,
790                 .features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP | VSP1_HAS_EXT_DL,
791                 .lif_count = 1,
792                 .rpf_count = 5,
793                 .uif_count = 1,
794                 .wpf_count = 2,
795                 .num_bru_inputs = 5,
796         }, {
797                 .version = VI6_IP_VERSION_MODEL_VSPD_V3,
798                 .model = "VSP2-D",
799                 .soc = VI6_IP_VERSION_SOC_V3H,
800                 .gen = 3,
801                 .features = VSP1_HAS_BRS | VSP1_HAS_BRU,
802                 .lif_count = 1,
803                 .rpf_count = 5,
804                 .uif_count = 1,
805                 .wpf_count = 1,
806                 .num_bru_inputs = 5,
807         }, {
808                 .version = VI6_IP_VERSION_MODEL_VSPD_V3,
809                 .model = "VSP2-D",
810                 .soc = VI6_IP_VERSION_SOC_V3M,
811                 .gen = 3,
812                 .features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_NON_ZERO_LBA,
813                 .lif_count = 1,
814                 .rpf_count = 5,
815                 .uif_count = 1,
816                 .wpf_count = 1,
817                 .num_bru_inputs = 5,
818         }, {
819                 .version = VI6_IP_VERSION_MODEL_VSPDL_GEN3,
820                 .model = "VSP2-DL",
821                 .gen = 3,
822                 .features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_EXT_DL,
823                 .lif_count = 2,
824                 .rpf_count = 5,
825                 .uif_count = 2,
826                 .wpf_count = 2,
827                 .num_bru_inputs = 5,
828         }, {
829                 .version = VI6_IP_VERSION_MODEL_VSPD_GEN4,
830                 .model = "VSP2-D",
831                 .gen = 4,
832                 .features = VSP1_HAS_BRU | VSP1_HAS_EXT_DL,
833                 .lif_count = 1,
834                 .rpf_count = 5,
835                 .uif_count = 2,
836                 .wpf_count = 1,
837                 .num_bru_inputs = 5,
838         },
839 };
840
841 static const struct vsp1_device_info rzg2l_vsp2_device_info = {
842         .version = VI6_IP_VERSION_MODEL_VSPD_RZG2L,
843         .model = "VSP2-D",
844         .soc = VI6_IP_VERSION_SOC_RZG2L,
845         .gen = 3,
846         .features = VSP1_HAS_BRS | VSP1_HAS_WPF_VFLIP | VSP1_HAS_EXT_DL
847                   | VSP1_HAS_NON_ZERO_LBA,
848         .lif_count = 1,
849         .rpf_count = 2,
850         .wpf_count = 1,
851 };
852
853 static const struct vsp1_device_info *vsp1_lookup_info(struct vsp1_device *vsp1)
854 {
855         const struct vsp1_device_info *info;
856         unsigned int i;
857         u32 model;
858         u32 soc;
859
860         /*
861          * Try the info stored in match data first for devices that don't have
862          * a version register.
863          */
864         info = of_device_get_match_data(vsp1->dev);
865         if (info) {
866                 vsp1->version = VI6_IP_VERSION_VSP_SW | info->version | info->soc;
867                 return info;
868         }
869
870         vsp1->version = vsp1_read(vsp1, VI6_IP_VERSION);
871         model = vsp1->version & VI6_IP_VERSION_MODEL_MASK;
872         soc = vsp1->version & VI6_IP_VERSION_SOC_MASK;
873
874         for (i = 0; i < ARRAY_SIZE(vsp1_device_infos); ++i) {
875                 info = &vsp1_device_infos[i];
876
877                 if (model == info->version && (!info->soc || soc == info->soc))
878                         return info;
879         }
880
881         dev_err(vsp1->dev, "unsupported IP version 0x%08x\n", vsp1->version);
882
883         return NULL;
884 }
885
886 static int vsp1_probe(struct platform_device *pdev)
887 {
888         struct vsp1_device *vsp1;
889         struct device_node *fcp_node;
890         int ret;
891         int irq;
892
893         vsp1 = devm_kzalloc(&pdev->dev, sizeof(*vsp1), GFP_KERNEL);
894         if (vsp1 == NULL)
895                 return -ENOMEM;
896
897         vsp1->dev = &pdev->dev;
898         INIT_LIST_HEAD(&vsp1->entities);
899         INIT_LIST_HEAD(&vsp1->videos);
900
901         platform_set_drvdata(pdev, vsp1);
902
903         /* I/O and IRQ resources (clock managed by the clock PM domain). */
904         vsp1->mmio = devm_platform_ioremap_resource(pdev, 0);
905         if (IS_ERR(vsp1->mmio))
906                 return PTR_ERR(vsp1->mmio);
907
908         irq = platform_get_irq(pdev, 0);
909         if (irq < 0)
910                 return irq;
911
912         vsp1->rstc = devm_reset_control_get_shared(&pdev->dev, NULL);
913         if (IS_ERR(vsp1->rstc))
914                 return dev_err_probe(&pdev->dev, PTR_ERR(vsp1->rstc),
915                                      "failed to get reset control\n");
916
917         /* FCP (optional). */
918         fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0);
919         if (fcp_node) {
920                 vsp1->fcp = rcar_fcp_get(fcp_node);
921                 of_node_put(fcp_node);
922                 if (IS_ERR(vsp1->fcp)) {
923                         dev_dbg(&pdev->dev, "FCP not found (%ld)\n",
924                                 PTR_ERR(vsp1->fcp));
925                         return PTR_ERR(vsp1->fcp);
926                 }
927
928                 /*
929                  * When the FCP is present, it handles all bus master accesses
930                  * for the VSP and must thus be used in place of the VSP device
931                  * to map DMA buffers.
932                  */
933                 vsp1->bus_master = rcar_fcp_get_device(vsp1->fcp);
934         } else {
935                 vsp1->bus_master = vsp1->dev;
936         }
937
938         /* Configure device parameters based on the version register. */
939         pm_runtime_enable(&pdev->dev);
940
941         ret = vsp1_device_get(vsp1);
942         if (ret < 0)
943                 goto done;
944
945         vsp1->info = vsp1_lookup_info(vsp1);
946         if (!vsp1->info) {
947                 vsp1_device_put(vsp1);
948                 ret = -ENXIO;
949                 goto done;
950         }
951
952         dev_dbg(&pdev->dev, "IP version 0x%08x\n", vsp1->version);
953
954         /*
955          * Previous use of the hardware (e.g. by the bootloader) could leave
956          * some interrupts enabled and pending.
957          *
958          * TODO: Investigate if this shouldn't be better handled by using the
959          * device reset provided by the CPG.
960          */
961         vsp1_mask_all_interrupts(vsp1);
962
963         vsp1_device_put(vsp1);
964
965         ret = devm_request_irq(&pdev->dev, irq, vsp1_irq_handler,
966                                IRQF_SHARED, dev_name(&pdev->dev), vsp1);
967         if (ret < 0) {
968                 dev_err(&pdev->dev, "failed to request IRQ\n");
969                 goto done;
970         }
971
972         /* Instantiate entities. */
973         ret = vsp1_create_entities(vsp1);
974         if (ret < 0) {
975                 dev_err(&pdev->dev, "failed to create entities\n");
976                 goto done;
977         }
978
979 done:
980         if (ret) {
981                 pm_runtime_disable(&pdev->dev);
982                 rcar_fcp_put(vsp1->fcp);
983         }
984
985         return ret;
986 }
987
988 static void vsp1_remove(struct platform_device *pdev)
989 {
990         struct vsp1_device *vsp1 = platform_get_drvdata(pdev);
991
992         vsp1_destroy_entities(vsp1);
993         rcar_fcp_put(vsp1->fcp);
994
995         pm_runtime_disable(&pdev->dev);
996 }
997
998 static const struct of_device_id vsp1_of_match[] = {
999         { .compatible = "renesas,vsp1" },
1000         { .compatible = "renesas,vsp2" },
1001         { .compatible = "renesas,r9a07g044-vsp2", .data = &rzg2l_vsp2_device_info },
1002         { },
1003 };
1004 MODULE_DEVICE_TABLE(of, vsp1_of_match);
1005
1006 static struct platform_driver vsp1_platform_driver = {
1007         .probe          = vsp1_probe,
1008         .remove_new     = vsp1_remove,
1009         .driver         = {
1010                 .name   = "vsp1",
1011                 .pm     = &vsp1_pm_ops,
1012                 .of_match_table = vsp1_of_match,
1013         },
1014 };
1015
1016 module_platform_driver(vsp1_platform_driver);
1017
1018 MODULE_ALIAS("vsp1");
1019 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
1020 MODULE_DESCRIPTION("Renesas VSP1 Driver");
1021 MODULE_LICENSE("GPL");