2 * vsp1_wpf.c -- R-Car VSP1 Write Pixel Formatter
4 * Copyright (C) 2013-2014 Renesas Electronics Corporation
6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
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 by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
14 #include <linux/device.h>
16 #include <media/v4l2-subdev.h>
20 #include "vsp1_rwpf.h"
21 #include "vsp1_video.h"
23 #define WPF_MAX_WIDTH 2048
24 #define WPF_MAX_HEIGHT 2048
26 /* -----------------------------------------------------------------------------
30 static inline void vsp1_wpf_write(struct vsp1_rwpf
*wpf
,
31 struct vsp1_dl_list
*dl
, u32 reg
, u32 data
)
33 vsp1_dl_list_write(dl
, reg
+ wpf
->entity
.index
* VI6_WPF_OFFSET
, data
);
36 /* -----------------------------------------------------------------------------
37 * V4L2 Subdevice Core Operations
40 static int wpf_s_stream(struct v4l2_subdev
*subdev
, int enable
)
42 struct vsp1_rwpf
*wpf
= to_rwpf(subdev
);
43 struct vsp1_device
*vsp1
= wpf
->entity
.vsp1
;
48 /* Write to registers directly when stopping the stream as there will be
49 * no pipeline run to apply the display list.
51 vsp1_write(vsp1
, VI6_WPF_IRQ_ENB(wpf
->entity
.index
), 0);
52 vsp1_write(vsp1
, wpf
->entity
.index
* VI6_WPF_OFFSET
+
58 /* -----------------------------------------------------------------------------
59 * V4L2 Subdevice Operations
62 static struct v4l2_subdev_video_ops wpf_video_ops
= {
63 .s_stream
= wpf_s_stream
,
66 static struct v4l2_subdev_ops wpf_ops
= {
67 .video
= &wpf_video_ops
,
68 .pad
= &vsp1_rwpf_pad_ops
,
71 /* -----------------------------------------------------------------------------
72 * VSP1 Entity Operations
75 static void vsp1_wpf_destroy(struct vsp1_entity
*entity
)
77 struct vsp1_rwpf
*wpf
= entity_to_rwpf(entity
);
79 vsp1_dlm_destroy(wpf
->dlm
);
82 static void wpf_set_memory(struct vsp1_entity
*entity
, struct vsp1_dl_list
*dl
)
84 struct vsp1_rwpf
*wpf
= entity_to_rwpf(entity
);
86 vsp1_wpf_write(wpf
, dl
, VI6_WPF_DSTM_ADDR_Y
, wpf
->mem
.addr
[0]);
87 vsp1_wpf_write(wpf
, dl
, VI6_WPF_DSTM_ADDR_C0
, wpf
->mem
.addr
[1]);
88 vsp1_wpf_write(wpf
, dl
, VI6_WPF_DSTM_ADDR_C1
, wpf
->mem
.addr
[2]);
91 static void wpf_configure(struct vsp1_entity
*entity
, struct vsp1_dl_list
*dl
)
93 struct vsp1_pipeline
*pipe
= to_vsp1_pipeline(&entity
->subdev
.entity
);
94 struct vsp1_rwpf
*wpf
= to_rwpf(&entity
->subdev
);
95 struct vsp1_device
*vsp1
= wpf
->entity
.vsp1
;
96 const struct v4l2_mbus_framefmt
*source_format
;
97 const struct v4l2_mbus_framefmt
*sink_format
;
98 const struct v4l2_rect
*crop
;
104 crop
= vsp1_rwpf_get_crop(wpf
, wpf
->entity
.config
);
106 vsp1_wpf_write(wpf
, dl
, VI6_WPF_HSZCLIP
, VI6_WPF_SZCLIP_EN
|
107 (crop
->left
<< VI6_WPF_SZCLIP_OFST_SHIFT
) |
108 (crop
->width
<< VI6_WPF_SZCLIP_SIZE_SHIFT
));
109 vsp1_wpf_write(wpf
, dl
, VI6_WPF_VSZCLIP
, VI6_WPF_SZCLIP_EN
|
110 (crop
->top
<< VI6_WPF_SZCLIP_OFST_SHIFT
) |
111 (crop
->height
<< VI6_WPF_SZCLIP_SIZE_SHIFT
));
114 sink_format
= vsp1_entity_get_pad_format(&wpf
->entity
,
117 source_format
= vsp1_entity_get_pad_format(&wpf
->entity
,
122 const struct v4l2_pix_format_mplane
*format
= &wpf
->format
;
123 const struct vsp1_format_info
*fmtinfo
= wpf
->fmtinfo
;
125 outfmt
= fmtinfo
->hwfmt
<< VI6_WPF_OUTFMT_WRFMT_SHIFT
;
128 outfmt
|= VI6_WPF_OUTFMT_PXA
;
129 if (fmtinfo
->swap_yc
)
130 outfmt
|= VI6_WPF_OUTFMT_SPYCS
;
131 if (fmtinfo
->swap_uv
)
132 outfmt
|= VI6_WPF_OUTFMT_SPUVS
;
134 /* Destination stride and byte swapping. */
135 vsp1_wpf_write(wpf
, dl
, VI6_WPF_DSTM_STRIDE_Y
,
136 format
->plane_fmt
[0].bytesperline
);
137 if (format
->num_planes
> 1)
138 vsp1_wpf_write(wpf
, dl
, VI6_WPF_DSTM_STRIDE_C
,
139 format
->plane_fmt
[1].bytesperline
);
141 vsp1_wpf_write(wpf
, dl
, VI6_WPF_DSWAP
, fmtinfo
->swap
);
144 if (sink_format
->code
!= source_format
->code
)
145 outfmt
|= VI6_WPF_OUTFMT_CSC
;
147 outfmt
|= wpf
->alpha
<< VI6_WPF_OUTFMT_PDV_SHIFT
;
148 vsp1_wpf_write(wpf
, dl
, VI6_WPF_OUTFMT
, outfmt
);
150 vsp1_dl_list_write(dl
, VI6_DPR_WPF_FPORCH(wpf
->entity
.index
),
151 VI6_DPR_WPF_FPORCH_FP_WPFN
);
153 vsp1_dl_list_write(dl
, VI6_WPF_WRBCK_CTRL
, 0);
155 /* Sources. If the pipeline has a single input and BRU is not used,
156 * configure it as the master layer. Otherwise configure all
157 * inputs as sub-layers and select the virtual RPF as the master
160 for (i
= 0; i
< vsp1
->info
->rpf_count
; ++i
) {
161 struct vsp1_rwpf
*input
= pipe
->inputs
[i
];
166 srcrpf
|= (!pipe
->bru
&& pipe
->num_inputs
== 1)
167 ? VI6_WPF_SRCRPF_RPF_ACT_MST(input
->entity
.index
)
168 : VI6_WPF_SRCRPF_RPF_ACT_SUB(input
->entity
.index
);
171 if (pipe
->bru
|| pipe
->num_inputs
> 1)
172 srcrpf
|= VI6_WPF_SRCRPF_VIRACT_MST
;
174 vsp1_wpf_write(wpf
, dl
, VI6_WPF_SRCRPF
, srcrpf
);
176 /* Enable interrupts */
177 vsp1_dl_list_write(dl
, VI6_WPF_IRQ_STA(wpf
->entity
.index
), 0);
178 vsp1_dl_list_write(dl
, VI6_WPF_IRQ_ENB(wpf
->entity
.index
),
179 VI6_WFP_IRQ_ENB_FREE
);
182 static const struct vsp1_entity_operations wpf_entity_ops
= {
183 .destroy
= vsp1_wpf_destroy
,
184 .set_memory
= wpf_set_memory
,
185 .configure
= wpf_configure
,
188 /* -----------------------------------------------------------------------------
189 * Initialization and Cleanup
192 struct vsp1_rwpf
*vsp1_wpf_create(struct vsp1_device
*vsp1
, unsigned int index
)
194 struct vsp1_rwpf
*wpf
;
198 wpf
= devm_kzalloc(vsp1
->dev
, sizeof(*wpf
), GFP_KERNEL
);
200 return ERR_PTR(-ENOMEM
);
202 wpf
->max_width
= WPF_MAX_WIDTH
;
203 wpf
->max_height
= WPF_MAX_HEIGHT
;
205 wpf
->entity
.ops
= &wpf_entity_ops
;
206 wpf
->entity
.type
= VSP1_ENTITY_WPF
;
207 wpf
->entity
.index
= index
;
209 sprintf(name
, "wpf.%u", index
);
210 ret
= vsp1_entity_init(vsp1
, &wpf
->entity
, name
, 2, &wpf_ops
);
214 /* Initialize the display list manager. */
215 wpf
->dlm
= vsp1_dlm_create(vsp1
, index
, 4);
221 /* Initialize the control handler. */
222 ret
= vsp1_rwpf_init_ctrls(wpf
);
224 dev_err(vsp1
->dev
, "wpf%u: failed to initialize controls\n",
232 vsp1_entity_destroy(&wpf
->entity
);