1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * R-Car Gen3 Digital Radio Interface (DRIF) driver |
4 | * |
5 | * Copyright (C) 2017 Renesas Electronics Corporation |
6 | */ |
7 | |
8 | /* |
9 | * The R-Car DRIF is a receive only MSIOF like controller with an |
10 | * external master device driving the SCK. It receives data into a FIFO, |
11 | * then this driver uses the SYS-DMAC engine to move the data from |
12 | * the device to memory. |
13 | * |
14 | * Each DRIF channel DRIFx (as per datasheet) contains two internal |
15 | * channels DRIFx0 & DRIFx1 within itself with each having its own resources |
16 | * like module clk, register set, irq and dma. These internal channels share |
17 | * common CLK & SYNC from master. The two data pins D0 & D1 shall be |
18 | * considered to represent the two internal channels. This internal split |
19 | * is not visible to the master device. |
20 | * |
21 | * Depending on the master device, a DRIF channel can use |
22 | * (1) both internal channels (D0 & D1) to receive data in parallel (or) |
23 | * (2) one internal channel (D0 or D1) to receive data |
24 | * |
25 | * The primary design goal of this controller is to act as a Digital Radio |
26 | * Interface that receives digital samples from a tuner device. Hence the |
27 | * driver exposes the device as a V4L2 SDR device. In order to qualify as |
28 | * a V4L2 SDR device, it should possess a tuner interface as mandated by the |
29 | * framework. This driver expects a tuner driver (sub-device) to bind |
30 | * asynchronously with this device and the combined drivers shall expose |
31 | * a V4L2 compliant SDR device. The DRIF driver is independent of the |
32 | * tuner vendor. |
33 | * |
34 | * The DRIF h/w can support I2S mode and Frame start synchronization pulse mode. |
35 | * This driver is tested for I2S mode only because of the availability of |
36 | * suitable master devices. Hence, not all configurable options of DRIF h/w |
37 | * like lsb/msb first, syncdl, dtdl etc. are exposed via DT and I2S defaults |
38 | * are used. These can be exposed later if needed after testing. |
39 | */ |
40 | #include <linux/bitops.h> |
41 | #include <linux/clk.h> |
42 | #include <linux/dma-mapping.h> |
43 | #include <linux/dmaengine.h> |
44 | #include <linux/ioctl.h> |
45 | #include <linux/iopoll.h> |
46 | #include <linux/module.h> |
47 | #include <linux/of.h> |
48 | #include <linux/of_graph.h> |
49 | #include <linux/of_platform.h> |
50 | #include <linux/platform_device.h> |
51 | #include <linux/sched.h> |
52 | #include <media/v4l2-async.h> |
53 | #include <media/v4l2-ctrls.h> |
54 | #include <media/v4l2-device.h> |
55 | #include <media/v4l2-event.h> |
56 | #include <media/v4l2-fh.h> |
57 | #include <media/v4l2-ioctl.h> |
58 | #include <media/videobuf2-v4l2.h> |
59 | #include <media/videobuf2-vmalloc.h> |
60 | |
61 | /* DRIF register offsets */ |
62 | #define RCAR_DRIF_SITMDR1 0x00 |
63 | #define RCAR_DRIF_SITMDR2 0x04 |
64 | #define RCAR_DRIF_SITMDR3 0x08 |
65 | #define RCAR_DRIF_SIRMDR1 0x10 |
66 | #define RCAR_DRIF_SIRMDR2 0x14 |
67 | #define RCAR_DRIF_SIRMDR3 0x18 |
68 | #define RCAR_DRIF_SICTR 0x28 |
69 | #define RCAR_DRIF_SIFCTR 0x30 |
70 | #define RCAR_DRIF_SISTR 0x40 |
71 | #define RCAR_DRIF_SIIER 0x44 |
72 | #define RCAR_DRIF_SIRFDR 0x60 |
73 | |
74 | #define RCAR_DRIF_RFOVF BIT(3) /* Receive FIFO overflow */ |
75 | #define RCAR_DRIF_RFUDF BIT(4) /* Receive FIFO underflow */ |
76 | #define RCAR_DRIF_RFSERR BIT(5) /* Receive frame sync error */ |
77 | #define RCAR_DRIF_REOF BIT(7) /* Frame reception end */ |
78 | #define RCAR_DRIF_RDREQ BIT(12) /* Receive data xfer req */ |
79 | #define RCAR_DRIF_RFFUL BIT(13) /* Receive FIFO full */ |
80 | |
81 | /* SIRMDR1 */ |
82 | #define RCAR_DRIF_SIRMDR1_SYNCMD_FRAME (0 << 28) |
83 | #define RCAR_DRIF_SIRMDR1_SYNCMD_LR (3 << 28) |
84 | |
85 | #define RCAR_DRIF_SIRMDR1_SYNCAC_POL_HIGH (0 << 25) |
86 | #define RCAR_DRIF_SIRMDR1_SYNCAC_POL_LOW (1 << 25) |
87 | |
88 | #define RCAR_DRIF_SIRMDR1_MSB_FIRST (0 << 24) |
89 | #define RCAR_DRIF_SIRMDR1_LSB_FIRST (1 << 24) |
90 | |
91 | #define RCAR_DRIF_SIRMDR1_DTDL_0 (0 << 20) |
92 | #define RCAR_DRIF_SIRMDR1_DTDL_1 (1 << 20) |
93 | #define RCAR_DRIF_SIRMDR1_DTDL_2 (2 << 20) |
94 | #define RCAR_DRIF_SIRMDR1_DTDL_0PT5 (5 << 20) |
95 | #define RCAR_DRIF_SIRMDR1_DTDL_1PT5 (6 << 20) |
96 | |
97 | #define RCAR_DRIF_SIRMDR1_SYNCDL_0 (0 << 20) |
98 | #define RCAR_DRIF_SIRMDR1_SYNCDL_1 (1 << 20) |
99 | #define RCAR_DRIF_SIRMDR1_SYNCDL_2 (2 << 20) |
100 | #define RCAR_DRIF_SIRMDR1_SYNCDL_3 (3 << 20) |
101 | #define RCAR_DRIF_SIRMDR1_SYNCDL_0PT5 (5 << 20) |
102 | #define RCAR_DRIF_SIRMDR1_SYNCDL_1PT5 (6 << 20) |
103 | |
104 | #define RCAR_DRIF_MDR_GRPCNT(n) (((n) - 1) << 30) |
105 | #define RCAR_DRIF_MDR_BITLEN(n) (((n) - 1) << 24) |
106 | #define RCAR_DRIF_MDR_WDCNT(n) (((n) - 1) << 16) |
107 | |
108 | /* Hidden Transmit register that controls CLK & SYNC */ |
109 | #define RCAR_DRIF_SITMDR1_PCON BIT(30) |
110 | |
111 | #define RCAR_DRIF_SICTR_RX_RISING_EDGE BIT(26) |
112 | #define RCAR_DRIF_SICTR_RX_EN BIT(8) |
113 | #define RCAR_DRIF_SICTR_RESET BIT(0) |
114 | |
115 | /* Constants */ |
116 | #define RCAR_DRIF_NUM_HWBUFS 32 |
117 | #define RCAR_DRIF_MAX_DEVS 4 |
118 | #define RCAR_DRIF_DEFAULT_NUM_HWBUFS 16 |
119 | #define RCAR_DRIF_DEFAULT_HWBUF_SIZE (4 * PAGE_SIZE) |
120 | #define RCAR_DRIF_MAX_CHANNEL 2 |
121 | #define RCAR_SDR_BUFFER_SIZE SZ_64K |
122 | |
123 | /* Internal buffer status flags */ |
124 | #define RCAR_DRIF_BUF_DONE BIT(0) /* DMA completed */ |
125 | #define RCAR_DRIF_BUF_OVERFLOW BIT(1) /* Overflow detected */ |
126 | |
127 | #define to_rcar_drif_buf_pair(sdr, ch_num, idx) \ |
128 | (&((sdr)->ch[!(ch_num)]->buf[(idx)])) |
129 | |
130 | #define for_each_rcar_drif_channel(ch, ch_mask) \ |
131 | for_each_set_bit(ch, ch_mask, RCAR_DRIF_MAX_CHANNEL) |
132 | |
133 | /* Debug */ |
134 | #define rdrif_dbg(sdr, fmt, arg...) \ |
135 | dev_dbg(sdr->v4l2_dev.dev, fmt, ## arg) |
136 | |
137 | #define rdrif_err(sdr, fmt, arg...) \ |
138 | dev_err(sdr->v4l2_dev.dev, fmt, ## arg) |
139 | |
140 | /* Stream formats */ |
141 | struct rcar_drif_format { |
142 | u32 pixelformat; |
143 | u32 buffersize; |
144 | u32 bitlen; |
145 | u32 wdcnt; |
146 | u32 num_ch; |
147 | }; |
148 | |
149 | /* Format descriptions for capture */ |
150 | static const struct rcar_drif_format formats[] = { |
151 | { |
152 | .pixelformat = V4L2_SDR_FMT_PCU16BE, |
153 | .buffersize = RCAR_SDR_BUFFER_SIZE, |
154 | .bitlen = 16, |
155 | .wdcnt = 1, |
156 | .num_ch = 2, |
157 | }, |
158 | { |
159 | .pixelformat = V4L2_SDR_FMT_PCU18BE, |
160 | .buffersize = RCAR_SDR_BUFFER_SIZE, |
161 | .bitlen = 18, |
162 | .wdcnt = 1, |
163 | .num_ch = 2, |
164 | }, |
165 | { |
166 | .pixelformat = V4L2_SDR_FMT_PCU20BE, |
167 | .buffersize = RCAR_SDR_BUFFER_SIZE, |
168 | .bitlen = 20, |
169 | .wdcnt = 1, |
170 | .num_ch = 2, |
171 | }, |
172 | }; |
173 | |
174 | /* Buffer for a received frame from one or both internal channels */ |
175 | struct rcar_drif_frame_buf { |
176 | /* Common v4l buffer stuff -- must be first */ |
177 | struct vb2_v4l2_buffer vb; |
178 | struct list_head list; |
179 | }; |
180 | |
181 | /* OF graph endpoint's V4L2 async data */ |
182 | struct rcar_drif_graph_ep { |
183 | struct v4l2_subdev *subdev; /* Async matched subdev */ |
184 | }; |
185 | |
186 | /* DMA buffer */ |
187 | struct rcar_drif_hwbuf { |
188 | void *addr; /* CPU-side address */ |
189 | unsigned int status; /* Buffer status flags */ |
190 | }; |
191 | |
192 | /* Internal channel */ |
193 | struct rcar_drif { |
194 | struct rcar_drif_sdr *sdr; /* Group device */ |
195 | struct platform_device *pdev; /* Channel's pdev */ |
196 | void __iomem *base; /* Base register address */ |
197 | resource_size_t start; /* I/O resource offset */ |
198 | struct dma_chan *dmach; /* Reserved DMA channel */ |
199 | struct clk *clk; /* Module clock */ |
200 | struct rcar_drif_hwbuf buf[RCAR_DRIF_NUM_HWBUFS]; /* H/W bufs */ |
201 | dma_addr_t dma_handle; /* Handle for all bufs */ |
202 | unsigned int num; /* Channel number */ |
203 | bool acting_sdr; /* Channel acting as SDR device */ |
204 | }; |
205 | |
206 | /* DRIF V4L2 SDR */ |
207 | struct rcar_drif_sdr { |
208 | struct device *dev; /* Platform device */ |
209 | struct video_device *vdev; /* V4L2 SDR device */ |
210 | struct v4l2_device v4l2_dev; /* V4L2 device */ |
211 | |
212 | /* Videobuf2 queue and queued buffers list */ |
213 | struct vb2_queue vb_queue; |
214 | struct list_head queued_bufs; |
215 | spinlock_t queued_bufs_lock; /* Protects queued_bufs */ |
216 | spinlock_t dma_lock; /* To serialize DMA cb of channels */ |
217 | |
218 | struct mutex v4l2_mutex; /* To serialize ioctls */ |
219 | struct mutex vb_queue_mutex; /* To serialize streaming ioctls */ |
220 | struct v4l2_ctrl_handler ctrl_hdl; /* SDR control handler */ |
221 | struct v4l2_async_notifier notifier; /* For subdev (tuner) */ |
222 | struct rcar_drif_graph_ep ep; /* Endpoint V4L2 async data */ |
223 | |
224 | /* Current V4L2 SDR format ptr */ |
225 | const struct rcar_drif_format *fmt; |
226 | |
227 | /* Device tree SYNC properties */ |
228 | u32 mdr1; |
229 | |
230 | /* Internals */ |
231 | struct rcar_drif *ch[RCAR_DRIF_MAX_CHANNEL]; /* DRIFx0,1 */ |
232 | unsigned long hw_ch_mask; /* Enabled channels per DT */ |
233 | unsigned long cur_ch_mask; /* Used channels for an SDR FMT */ |
234 | u32 num_hw_ch; /* Num of DT enabled channels */ |
235 | u32 num_cur_ch; /* Num of used channels */ |
236 | u32 hwbuf_size; /* Each DMA buffer size */ |
237 | u32 produced; /* Buffers produced by sdr dev */ |
238 | }; |
239 | |
240 | /* Register access functions */ |
241 | static void rcar_drif_write(struct rcar_drif *ch, u32 offset, u32 data) |
242 | { |
243 | writel(val: data, addr: ch->base + offset); |
244 | } |
245 | |
246 | static u32 rcar_drif_read(struct rcar_drif *ch, u32 offset) |
247 | { |
248 | return readl(addr: ch->base + offset); |
249 | } |
250 | |
251 | /* Release DMA channels */ |
252 | static void rcar_drif_release_dmachannels(struct rcar_drif_sdr *sdr) |
253 | { |
254 | unsigned int i; |
255 | |
256 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) |
257 | if (sdr->ch[i]->dmach) { |
258 | dma_release_channel(chan: sdr->ch[i]->dmach); |
259 | sdr->ch[i]->dmach = NULL; |
260 | } |
261 | } |
262 | |
263 | /* Allocate DMA channels */ |
264 | static int rcar_drif_alloc_dmachannels(struct rcar_drif_sdr *sdr) |
265 | { |
266 | struct dma_slave_config dma_cfg; |
267 | unsigned int i; |
268 | int ret; |
269 | |
270 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
271 | struct rcar_drif *ch = sdr->ch[i]; |
272 | |
273 | ch->dmach = dma_request_chan(dev: &ch->pdev->dev, name: "rx" ); |
274 | if (IS_ERR(ptr: ch->dmach)) { |
275 | ret = PTR_ERR(ptr: ch->dmach); |
276 | if (ret != -EPROBE_DEFER) |
277 | rdrif_err(sdr, |
278 | "ch%u: dma channel req failed: %pe\n" , |
279 | i, ch->dmach); |
280 | ch->dmach = NULL; |
281 | goto dmach_error; |
282 | } |
283 | |
284 | /* Configure slave */ |
285 | memset(&dma_cfg, 0, sizeof(dma_cfg)); |
286 | dma_cfg.src_addr = (phys_addr_t)(ch->start + RCAR_DRIF_SIRFDR); |
287 | dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
288 | ret = dmaengine_slave_config(chan: ch->dmach, config: &dma_cfg); |
289 | if (ret) { |
290 | rdrif_err(sdr, "ch%u: dma slave config failed\n" , i); |
291 | goto dmach_error; |
292 | } |
293 | } |
294 | return 0; |
295 | |
296 | dmach_error: |
297 | rcar_drif_release_dmachannels(sdr); |
298 | return ret; |
299 | } |
300 | |
301 | /* Release queued vb2 buffers */ |
302 | static void rcar_drif_release_queued_bufs(struct rcar_drif_sdr *sdr, |
303 | enum vb2_buffer_state state) |
304 | { |
305 | struct rcar_drif_frame_buf *fbuf, *tmp; |
306 | unsigned long flags; |
307 | |
308 | spin_lock_irqsave(&sdr->queued_bufs_lock, flags); |
309 | list_for_each_entry_safe(fbuf, tmp, &sdr->queued_bufs, list) { |
310 | list_del(entry: &fbuf->list); |
311 | vb2_buffer_done(vb: &fbuf->vb.vb2_buf, state); |
312 | } |
313 | spin_unlock_irqrestore(lock: &sdr->queued_bufs_lock, flags); |
314 | } |
315 | |
316 | /* Set MDR defaults */ |
317 | static inline void rcar_drif_set_mdr1(struct rcar_drif_sdr *sdr) |
318 | { |
319 | unsigned int i; |
320 | |
321 | /* Set defaults for enabled internal channels */ |
322 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
323 | /* Refer MSIOF section in manual for this register setting */ |
324 | rcar_drif_write(ch: sdr->ch[i], RCAR_DRIF_SITMDR1, |
325 | RCAR_DRIF_SITMDR1_PCON); |
326 | |
327 | /* Setup MDR1 value */ |
328 | rcar_drif_write(ch: sdr->ch[i], RCAR_DRIF_SIRMDR1, data: sdr->mdr1); |
329 | |
330 | rdrif_dbg(sdr, "ch%u: mdr1 = 0x%08x" , |
331 | i, rcar_drif_read(sdr->ch[i], RCAR_DRIF_SIRMDR1)); |
332 | } |
333 | } |
334 | |
335 | /* Set DRIF receive format */ |
336 | static int rcar_drif_set_format(struct rcar_drif_sdr *sdr) |
337 | { |
338 | unsigned int i; |
339 | |
340 | rdrif_dbg(sdr, "setfmt: bitlen %u wdcnt %u num_ch %u\n" , |
341 | sdr->fmt->bitlen, sdr->fmt->wdcnt, sdr->fmt->num_ch); |
342 | |
343 | /* Sanity check */ |
344 | if (sdr->fmt->num_ch > sdr->num_cur_ch) { |
345 | rdrif_err(sdr, "fmt num_ch %u cur_ch %u mismatch\n" , |
346 | sdr->fmt->num_ch, sdr->num_cur_ch); |
347 | return -EINVAL; |
348 | } |
349 | |
350 | /* Setup group, bitlen & wdcnt */ |
351 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
352 | u32 mdr; |
353 | |
354 | /* Two groups */ |
355 | mdr = RCAR_DRIF_MDR_GRPCNT(2) | |
356 | RCAR_DRIF_MDR_BITLEN(sdr->fmt->bitlen) | |
357 | RCAR_DRIF_MDR_WDCNT(sdr->fmt->wdcnt); |
358 | rcar_drif_write(ch: sdr->ch[i], RCAR_DRIF_SIRMDR2, data: mdr); |
359 | |
360 | mdr = RCAR_DRIF_MDR_BITLEN(sdr->fmt->bitlen) | |
361 | RCAR_DRIF_MDR_WDCNT(sdr->fmt->wdcnt); |
362 | rcar_drif_write(ch: sdr->ch[i], RCAR_DRIF_SIRMDR3, data: mdr); |
363 | |
364 | rdrif_dbg(sdr, "ch%u: new mdr[2,3] = 0x%08x, 0x%08x\n" , |
365 | i, rcar_drif_read(sdr->ch[i], RCAR_DRIF_SIRMDR2), |
366 | rcar_drif_read(sdr->ch[i], RCAR_DRIF_SIRMDR3)); |
367 | } |
368 | return 0; |
369 | } |
370 | |
371 | /* Release DMA buffers */ |
372 | static void rcar_drif_release_buf(struct rcar_drif_sdr *sdr) |
373 | { |
374 | unsigned int i; |
375 | |
376 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
377 | struct rcar_drif *ch = sdr->ch[i]; |
378 | |
379 | /* First entry contains the dma buf ptr */ |
380 | if (ch->buf[0].addr) { |
381 | dma_free_coherent(dev: &ch->pdev->dev, |
382 | size: sdr->hwbuf_size * RCAR_DRIF_NUM_HWBUFS, |
383 | cpu_addr: ch->buf[0].addr, dma_handle: ch->dma_handle); |
384 | ch->buf[0].addr = NULL; |
385 | } |
386 | } |
387 | } |
388 | |
389 | /* Request DMA buffers */ |
390 | static int rcar_drif_request_buf(struct rcar_drif_sdr *sdr) |
391 | { |
392 | int ret = -ENOMEM; |
393 | unsigned int i, j; |
394 | void *addr; |
395 | |
396 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
397 | struct rcar_drif *ch = sdr->ch[i]; |
398 | |
399 | /* Allocate DMA buffers */ |
400 | addr = dma_alloc_coherent(dev: &ch->pdev->dev, |
401 | size: sdr->hwbuf_size * RCAR_DRIF_NUM_HWBUFS, |
402 | dma_handle: &ch->dma_handle, GFP_KERNEL); |
403 | if (!addr) { |
404 | rdrif_err(sdr, |
405 | "ch%u: dma alloc failed. num hwbufs %u size %u\n" , |
406 | i, RCAR_DRIF_NUM_HWBUFS, sdr->hwbuf_size); |
407 | goto error; |
408 | } |
409 | |
410 | /* Split the chunk and populate bufctxt */ |
411 | for (j = 0; j < RCAR_DRIF_NUM_HWBUFS; j++) { |
412 | ch->buf[j].addr = addr + (j * sdr->hwbuf_size); |
413 | ch->buf[j].status = 0; |
414 | } |
415 | } |
416 | return 0; |
417 | error: |
418 | return ret; |
419 | } |
420 | |
421 | /* Setup vb_queue minimum buffer requirements */ |
422 | static int rcar_drif_queue_setup(struct vb2_queue *vq, |
423 | unsigned int *num_buffers, unsigned int *num_planes, |
424 | unsigned int sizes[], struct device *alloc_devs[]) |
425 | { |
426 | struct rcar_drif_sdr *sdr = vb2_get_drv_priv(q: vq); |
427 | unsigned int q_num_bufs = vb2_get_num_buffers(q: vq); |
428 | |
429 | /* Need at least 16 buffers */ |
430 | if (q_num_bufs + *num_buffers < 16) |
431 | *num_buffers = 16 - q_num_bufs; |
432 | |
433 | *num_planes = 1; |
434 | sizes[0] = PAGE_ALIGN(sdr->fmt->buffersize); |
435 | rdrif_dbg(sdr, "num_bufs %d sizes[0] %d\n" , *num_buffers, sizes[0]); |
436 | |
437 | return 0; |
438 | } |
439 | |
440 | /* Enqueue buffer */ |
441 | static void rcar_drif_buf_queue(struct vb2_buffer *vb) |
442 | { |
443 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
444 | struct rcar_drif_sdr *sdr = vb2_get_drv_priv(q: vb->vb2_queue); |
445 | struct rcar_drif_frame_buf *fbuf = |
446 | container_of(vbuf, struct rcar_drif_frame_buf, vb); |
447 | unsigned long flags; |
448 | |
449 | rdrif_dbg(sdr, "buf_queue idx %u\n" , vb->index); |
450 | spin_lock_irqsave(&sdr->queued_bufs_lock, flags); |
451 | list_add_tail(new: &fbuf->list, head: &sdr->queued_bufs); |
452 | spin_unlock_irqrestore(lock: &sdr->queued_bufs_lock, flags); |
453 | } |
454 | |
455 | /* Get a frame buf from list */ |
456 | static struct rcar_drif_frame_buf * |
457 | rcar_drif_get_fbuf(struct rcar_drif_sdr *sdr) |
458 | { |
459 | struct rcar_drif_frame_buf *fbuf; |
460 | unsigned long flags; |
461 | |
462 | spin_lock_irqsave(&sdr->queued_bufs_lock, flags); |
463 | fbuf = list_first_entry_or_null(&sdr->queued_bufs, struct |
464 | rcar_drif_frame_buf, list); |
465 | if (!fbuf) { |
466 | /* |
467 | * App is late in enqueing buffers. Samples lost & there will |
468 | * be a gap in sequence number when app recovers |
469 | */ |
470 | rdrif_dbg(sdr, "\napp late: prod %u\n" , sdr->produced); |
471 | spin_unlock_irqrestore(lock: &sdr->queued_bufs_lock, flags); |
472 | return NULL; |
473 | } |
474 | list_del(entry: &fbuf->list); |
475 | spin_unlock_irqrestore(lock: &sdr->queued_bufs_lock, flags); |
476 | |
477 | return fbuf; |
478 | } |
479 | |
480 | /* Helpers to set/clear buf pair status */ |
481 | static inline bool rcar_drif_bufs_done(struct rcar_drif_hwbuf **buf) |
482 | { |
483 | return (buf[0]->status & buf[1]->status & RCAR_DRIF_BUF_DONE); |
484 | } |
485 | |
486 | static inline bool rcar_drif_bufs_overflow(struct rcar_drif_hwbuf **buf) |
487 | { |
488 | return ((buf[0]->status | buf[1]->status) & RCAR_DRIF_BUF_OVERFLOW); |
489 | } |
490 | |
491 | static inline void rcar_drif_bufs_clear(struct rcar_drif_hwbuf **buf, |
492 | unsigned int bit) |
493 | { |
494 | unsigned int i; |
495 | |
496 | for (i = 0; i < RCAR_DRIF_MAX_CHANNEL; i++) |
497 | buf[i]->status &= ~bit; |
498 | } |
499 | |
500 | /* Channel DMA complete */ |
501 | static void rcar_drif_channel_complete(struct rcar_drif *ch, u32 idx) |
502 | { |
503 | u32 str; |
504 | |
505 | ch->buf[idx].status |= RCAR_DRIF_BUF_DONE; |
506 | |
507 | /* Check for DRIF errors */ |
508 | str = rcar_drif_read(ch, RCAR_DRIF_SISTR); |
509 | if (unlikely(str & RCAR_DRIF_RFOVF)) { |
510 | /* Writing the same clears it */ |
511 | rcar_drif_write(ch, RCAR_DRIF_SISTR, data: str); |
512 | |
513 | /* Overflow: some samples are lost */ |
514 | ch->buf[idx].status |= RCAR_DRIF_BUF_OVERFLOW; |
515 | } |
516 | } |
517 | |
518 | /* DMA callback for each stage */ |
519 | static void rcar_drif_dma_complete(void *dma_async_param) |
520 | { |
521 | struct rcar_drif *ch = dma_async_param; |
522 | struct rcar_drif_sdr *sdr = ch->sdr; |
523 | struct rcar_drif_hwbuf *buf[RCAR_DRIF_MAX_CHANNEL]; |
524 | struct rcar_drif_frame_buf *fbuf; |
525 | bool overflow = false; |
526 | u32 idx, produced; |
527 | unsigned int i; |
528 | |
529 | spin_lock(lock: &sdr->dma_lock); |
530 | |
531 | /* DMA can be terminated while the callback was waiting on lock */ |
532 | if (!vb2_is_streaming(q: &sdr->vb_queue)) { |
533 | spin_unlock(lock: &sdr->dma_lock); |
534 | return; |
535 | } |
536 | |
537 | idx = sdr->produced % RCAR_DRIF_NUM_HWBUFS; |
538 | rcar_drif_channel_complete(ch, idx); |
539 | |
540 | if (sdr->num_cur_ch == RCAR_DRIF_MAX_CHANNEL) { |
541 | buf[0] = ch->num ? to_rcar_drif_buf_pair(sdr, ch->num, idx) : |
542 | &ch->buf[idx]; |
543 | buf[1] = ch->num ? &ch->buf[idx] : |
544 | to_rcar_drif_buf_pair(sdr, ch->num, idx); |
545 | |
546 | /* Check if both DMA buffers are done */ |
547 | if (!rcar_drif_bufs_done(buf)) { |
548 | spin_unlock(lock: &sdr->dma_lock); |
549 | return; |
550 | } |
551 | |
552 | /* Clear buf done status */ |
553 | rcar_drif_bufs_clear(buf, RCAR_DRIF_BUF_DONE); |
554 | |
555 | if (rcar_drif_bufs_overflow(buf)) { |
556 | overflow = true; |
557 | /* Clear the flag in status */ |
558 | rcar_drif_bufs_clear(buf, RCAR_DRIF_BUF_OVERFLOW); |
559 | } |
560 | } else { |
561 | buf[0] = &ch->buf[idx]; |
562 | if (buf[0]->status & RCAR_DRIF_BUF_OVERFLOW) { |
563 | overflow = true; |
564 | /* Clear the flag in status */ |
565 | buf[0]->status &= ~RCAR_DRIF_BUF_OVERFLOW; |
566 | } |
567 | } |
568 | |
569 | /* Buffer produced for consumption */ |
570 | produced = sdr->produced++; |
571 | spin_unlock(lock: &sdr->dma_lock); |
572 | |
573 | rdrif_dbg(sdr, "ch%u: prod %u\n" , ch->num, produced); |
574 | |
575 | /* Get fbuf */ |
576 | fbuf = rcar_drif_get_fbuf(sdr); |
577 | if (!fbuf) |
578 | return; |
579 | |
580 | for (i = 0; i < RCAR_DRIF_MAX_CHANNEL; i++) |
581 | memcpy(vb2_plane_vaddr(&fbuf->vb.vb2_buf, 0) + |
582 | i * sdr->hwbuf_size, buf[i]->addr, sdr->hwbuf_size); |
583 | |
584 | fbuf->vb.field = V4L2_FIELD_NONE; |
585 | fbuf->vb.sequence = produced; |
586 | fbuf->vb.vb2_buf.timestamp = ktime_get_ns(); |
587 | vb2_set_plane_payload(vb: &fbuf->vb.vb2_buf, plane_no: 0, size: sdr->fmt->buffersize); |
588 | |
589 | /* Set error state on overflow */ |
590 | vb2_buffer_done(vb: &fbuf->vb.vb2_buf, |
591 | state: overflow ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); |
592 | } |
593 | |
594 | static int rcar_drif_qbuf(struct rcar_drif *ch) |
595 | { |
596 | struct rcar_drif_sdr *sdr = ch->sdr; |
597 | dma_addr_t addr = ch->dma_handle; |
598 | struct dma_async_tx_descriptor *rxd; |
599 | dma_cookie_t cookie; |
600 | int ret = -EIO; |
601 | |
602 | /* Setup cyclic DMA with given buffers */ |
603 | rxd = dmaengine_prep_dma_cyclic(chan: ch->dmach, buf_addr: addr, |
604 | buf_len: sdr->hwbuf_size * RCAR_DRIF_NUM_HWBUFS, |
605 | period_len: sdr->hwbuf_size, dir: DMA_DEV_TO_MEM, |
606 | flags: DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
607 | if (!rxd) { |
608 | rdrif_err(sdr, "ch%u: prep dma cyclic failed\n" , ch->num); |
609 | return ret; |
610 | } |
611 | |
612 | /* Submit descriptor */ |
613 | rxd->callback = rcar_drif_dma_complete; |
614 | rxd->callback_param = ch; |
615 | cookie = dmaengine_submit(desc: rxd); |
616 | if (dma_submit_error(cookie)) { |
617 | rdrif_err(sdr, "ch%u: dma submit failed\n" , ch->num); |
618 | return ret; |
619 | } |
620 | |
621 | dma_async_issue_pending(chan: ch->dmach); |
622 | return 0; |
623 | } |
624 | |
625 | /* Enable reception */ |
626 | static int rcar_drif_enable_rx(struct rcar_drif_sdr *sdr) |
627 | { |
628 | unsigned int i; |
629 | u32 ctr; |
630 | int ret = -EINVAL; |
631 | |
632 | /* |
633 | * When both internal channels are enabled, they can be synchronized |
634 | * only by the master |
635 | */ |
636 | |
637 | /* Enable receive */ |
638 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
639 | ctr = rcar_drif_read(ch: sdr->ch[i], RCAR_DRIF_SICTR); |
640 | ctr |= (RCAR_DRIF_SICTR_RX_RISING_EDGE | |
641 | RCAR_DRIF_SICTR_RX_EN); |
642 | rcar_drif_write(ch: sdr->ch[i], RCAR_DRIF_SICTR, data: ctr); |
643 | } |
644 | |
645 | /* Check receive enabled */ |
646 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
647 | ret = readl_poll_timeout(sdr->ch[i]->base + RCAR_DRIF_SICTR, |
648 | ctr, ctr & RCAR_DRIF_SICTR_RX_EN, 7, 100000); |
649 | if (ret) { |
650 | rdrif_err(sdr, "ch%u: rx en failed. ctr 0x%08x\n" , i, |
651 | rcar_drif_read(sdr->ch[i], RCAR_DRIF_SICTR)); |
652 | break; |
653 | } |
654 | } |
655 | return ret; |
656 | } |
657 | |
658 | /* Disable reception */ |
659 | static void rcar_drif_disable_rx(struct rcar_drif_sdr *sdr) |
660 | { |
661 | unsigned int i; |
662 | u32 ctr; |
663 | int ret; |
664 | |
665 | /* Disable receive */ |
666 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
667 | ctr = rcar_drif_read(ch: sdr->ch[i], RCAR_DRIF_SICTR); |
668 | ctr &= ~RCAR_DRIF_SICTR_RX_EN; |
669 | rcar_drif_write(ch: sdr->ch[i], RCAR_DRIF_SICTR, data: ctr); |
670 | } |
671 | |
672 | /* Check receive disabled */ |
673 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
674 | ret = readl_poll_timeout(sdr->ch[i]->base + RCAR_DRIF_SICTR, |
675 | ctr, !(ctr & RCAR_DRIF_SICTR_RX_EN), 7, 100000); |
676 | if (ret) |
677 | dev_warn(&sdr->vdev->dev, |
678 | "ch%u: failed to disable rx. ctr 0x%08x\n" , |
679 | i, rcar_drif_read(sdr->ch[i], RCAR_DRIF_SICTR)); |
680 | } |
681 | } |
682 | |
683 | /* Stop channel */ |
684 | static void rcar_drif_stop_channel(struct rcar_drif *ch) |
685 | { |
686 | /* Disable DMA receive interrupt */ |
687 | rcar_drif_write(ch, RCAR_DRIF_SIIER, data: 0x00000000); |
688 | |
689 | /* Terminate all DMA transfers */ |
690 | dmaengine_terminate_sync(chan: ch->dmach); |
691 | } |
692 | |
693 | /* Stop receive operation */ |
694 | static void rcar_drif_stop(struct rcar_drif_sdr *sdr) |
695 | { |
696 | unsigned int i; |
697 | |
698 | /* Disable Rx */ |
699 | rcar_drif_disable_rx(sdr); |
700 | |
701 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) |
702 | rcar_drif_stop_channel(ch: sdr->ch[i]); |
703 | } |
704 | |
705 | /* Start channel */ |
706 | static int rcar_drif_start_channel(struct rcar_drif *ch) |
707 | { |
708 | struct rcar_drif_sdr *sdr = ch->sdr; |
709 | u32 ctr, str; |
710 | int ret; |
711 | |
712 | /* Reset receive */ |
713 | rcar_drif_write(ch, RCAR_DRIF_SICTR, RCAR_DRIF_SICTR_RESET); |
714 | ret = readl_poll_timeout(ch->base + RCAR_DRIF_SICTR, ctr, |
715 | !(ctr & RCAR_DRIF_SICTR_RESET), 7, 100000); |
716 | if (ret) { |
717 | rdrif_err(sdr, "ch%u: failed to reset rx. ctr 0x%08x\n" , |
718 | ch->num, rcar_drif_read(ch, RCAR_DRIF_SICTR)); |
719 | return ret; |
720 | } |
721 | |
722 | /* Queue buffers for DMA */ |
723 | ret = rcar_drif_qbuf(ch); |
724 | if (ret) |
725 | return ret; |
726 | |
727 | /* Clear status register flags */ |
728 | str = RCAR_DRIF_RFFUL | RCAR_DRIF_REOF | RCAR_DRIF_RFSERR | |
729 | RCAR_DRIF_RFUDF | RCAR_DRIF_RFOVF; |
730 | rcar_drif_write(ch, RCAR_DRIF_SISTR, data: str); |
731 | |
732 | /* Enable DMA receive interrupt */ |
733 | rcar_drif_write(ch, RCAR_DRIF_SIIER, data: 0x00009000); |
734 | |
735 | return ret; |
736 | } |
737 | |
738 | /* Start receive operation */ |
739 | static int rcar_drif_start(struct rcar_drif_sdr *sdr) |
740 | { |
741 | unsigned long enabled = 0; |
742 | unsigned int i; |
743 | int ret; |
744 | |
745 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
746 | ret = rcar_drif_start_channel(ch: sdr->ch[i]); |
747 | if (ret) |
748 | goto start_error; |
749 | enabled |= BIT(i); |
750 | } |
751 | |
752 | ret = rcar_drif_enable_rx(sdr); |
753 | if (ret) |
754 | goto enable_error; |
755 | |
756 | sdr->produced = 0; |
757 | return ret; |
758 | |
759 | enable_error: |
760 | rcar_drif_disable_rx(sdr); |
761 | start_error: |
762 | for_each_rcar_drif_channel(i, &enabled) |
763 | rcar_drif_stop_channel(ch: sdr->ch[i]); |
764 | |
765 | return ret; |
766 | } |
767 | |
768 | /* Start streaming */ |
769 | static int rcar_drif_start_streaming(struct vb2_queue *vq, unsigned int count) |
770 | { |
771 | struct rcar_drif_sdr *sdr = vb2_get_drv_priv(q: vq); |
772 | unsigned long enabled = 0; |
773 | unsigned int i; |
774 | int ret; |
775 | |
776 | mutex_lock(&sdr->v4l2_mutex); |
777 | |
778 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
779 | ret = clk_prepare_enable(clk: sdr->ch[i]->clk); |
780 | if (ret) |
781 | goto error; |
782 | enabled |= BIT(i); |
783 | } |
784 | |
785 | /* Set default MDRx settings */ |
786 | rcar_drif_set_mdr1(sdr); |
787 | |
788 | /* Set new format */ |
789 | ret = rcar_drif_set_format(sdr); |
790 | if (ret) |
791 | goto error; |
792 | |
793 | if (sdr->num_cur_ch == RCAR_DRIF_MAX_CHANNEL) |
794 | sdr->hwbuf_size = sdr->fmt->buffersize / RCAR_DRIF_MAX_CHANNEL; |
795 | else |
796 | sdr->hwbuf_size = sdr->fmt->buffersize; |
797 | |
798 | rdrif_dbg(sdr, "num hwbufs %u, hwbuf_size %u\n" , |
799 | RCAR_DRIF_NUM_HWBUFS, sdr->hwbuf_size); |
800 | |
801 | /* Alloc DMA channel */ |
802 | ret = rcar_drif_alloc_dmachannels(sdr); |
803 | if (ret) |
804 | goto error; |
805 | |
806 | /* Request buffers */ |
807 | ret = rcar_drif_request_buf(sdr); |
808 | if (ret) |
809 | goto error; |
810 | |
811 | /* Start Rx */ |
812 | ret = rcar_drif_start(sdr); |
813 | if (ret) |
814 | goto error; |
815 | |
816 | mutex_unlock(lock: &sdr->v4l2_mutex); |
817 | |
818 | return ret; |
819 | |
820 | error: |
821 | rcar_drif_release_queued_bufs(sdr, state: VB2_BUF_STATE_QUEUED); |
822 | rcar_drif_release_buf(sdr); |
823 | rcar_drif_release_dmachannels(sdr); |
824 | for_each_rcar_drif_channel(i, &enabled) |
825 | clk_disable_unprepare(clk: sdr->ch[i]->clk); |
826 | |
827 | mutex_unlock(lock: &sdr->v4l2_mutex); |
828 | |
829 | return ret; |
830 | } |
831 | |
832 | /* Stop streaming */ |
833 | static void rcar_drif_stop_streaming(struct vb2_queue *vq) |
834 | { |
835 | struct rcar_drif_sdr *sdr = vb2_get_drv_priv(q: vq); |
836 | unsigned int i; |
837 | |
838 | mutex_lock(&sdr->v4l2_mutex); |
839 | |
840 | /* Stop hardware streaming */ |
841 | rcar_drif_stop(sdr); |
842 | |
843 | /* Return all queued buffers to vb2 */ |
844 | rcar_drif_release_queued_bufs(sdr, state: VB2_BUF_STATE_ERROR); |
845 | |
846 | /* Release buf */ |
847 | rcar_drif_release_buf(sdr); |
848 | |
849 | /* Release DMA channel resources */ |
850 | rcar_drif_release_dmachannels(sdr); |
851 | |
852 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) |
853 | clk_disable_unprepare(clk: sdr->ch[i]->clk); |
854 | |
855 | mutex_unlock(lock: &sdr->v4l2_mutex); |
856 | } |
857 | |
858 | /* Vb2 ops */ |
859 | static const struct vb2_ops rcar_drif_vb2_ops = { |
860 | .queue_setup = rcar_drif_queue_setup, |
861 | .buf_queue = rcar_drif_buf_queue, |
862 | .start_streaming = rcar_drif_start_streaming, |
863 | .stop_streaming = rcar_drif_stop_streaming, |
864 | .wait_prepare = vb2_ops_wait_prepare, |
865 | .wait_finish = vb2_ops_wait_finish, |
866 | }; |
867 | |
868 | static int rcar_drif_querycap(struct file *file, void *fh, |
869 | struct v4l2_capability *cap) |
870 | { |
871 | struct rcar_drif_sdr *sdr = video_drvdata(file); |
872 | |
873 | strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); |
874 | strscpy(cap->card, sdr->vdev->name, sizeof(cap->card)); |
875 | strscpy(cap->bus_info, "platform:R-Car DRIF" , sizeof(cap->bus_info)); |
876 | |
877 | return 0; |
878 | } |
879 | |
880 | static int rcar_drif_set_default_format(struct rcar_drif_sdr *sdr) |
881 | { |
882 | unsigned int i; |
883 | |
884 | for (i = 0; i < ARRAY_SIZE(formats); i++) { |
885 | /* Matching fmt based on required channels is set as default */ |
886 | if (sdr->num_hw_ch == formats[i].num_ch) { |
887 | sdr->fmt = &formats[i]; |
888 | sdr->cur_ch_mask = sdr->hw_ch_mask; |
889 | sdr->num_cur_ch = sdr->num_hw_ch; |
890 | dev_dbg(sdr->dev, "default fmt[%u]: mask %lu num %u\n" , |
891 | i, sdr->cur_ch_mask, sdr->num_cur_ch); |
892 | return 0; |
893 | } |
894 | } |
895 | return -EINVAL; |
896 | } |
897 | |
898 | static int rcar_drif_enum_fmt_sdr_cap(struct file *file, void *priv, |
899 | struct v4l2_fmtdesc *f) |
900 | { |
901 | if (f->index >= ARRAY_SIZE(formats)) |
902 | return -EINVAL; |
903 | |
904 | f->pixelformat = formats[f->index].pixelformat; |
905 | |
906 | return 0; |
907 | } |
908 | |
909 | static int rcar_drif_g_fmt_sdr_cap(struct file *file, void *priv, |
910 | struct v4l2_format *f) |
911 | { |
912 | struct rcar_drif_sdr *sdr = video_drvdata(file); |
913 | |
914 | f->fmt.sdr.pixelformat = sdr->fmt->pixelformat; |
915 | f->fmt.sdr.buffersize = sdr->fmt->buffersize; |
916 | |
917 | return 0; |
918 | } |
919 | |
920 | static int rcar_drif_s_fmt_sdr_cap(struct file *file, void *priv, |
921 | struct v4l2_format *f) |
922 | { |
923 | struct rcar_drif_sdr *sdr = video_drvdata(file); |
924 | struct vb2_queue *q = &sdr->vb_queue; |
925 | unsigned int i; |
926 | |
927 | if (vb2_is_busy(q)) |
928 | return -EBUSY; |
929 | |
930 | for (i = 0; i < ARRAY_SIZE(formats); i++) { |
931 | if (formats[i].pixelformat == f->fmt.sdr.pixelformat) |
932 | break; |
933 | } |
934 | |
935 | if (i == ARRAY_SIZE(formats)) |
936 | i = 0; /* Set the 1st format as default on no match */ |
937 | |
938 | sdr->fmt = &formats[i]; |
939 | f->fmt.sdr.pixelformat = sdr->fmt->pixelformat; |
940 | f->fmt.sdr.buffersize = formats[i].buffersize; |
941 | memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); |
942 | |
943 | /* |
944 | * If a format demands one channel only out of two |
945 | * enabled channels, pick the 0th channel. |
946 | */ |
947 | if (formats[i].num_ch < sdr->num_hw_ch) { |
948 | sdr->cur_ch_mask = BIT(0); |
949 | sdr->num_cur_ch = formats[i].num_ch; |
950 | } else { |
951 | sdr->cur_ch_mask = sdr->hw_ch_mask; |
952 | sdr->num_cur_ch = sdr->num_hw_ch; |
953 | } |
954 | |
955 | rdrif_dbg(sdr, "cur: idx %u mask %lu num %u\n" , |
956 | i, sdr->cur_ch_mask, sdr->num_cur_ch); |
957 | |
958 | return 0; |
959 | } |
960 | |
961 | static int rcar_drif_try_fmt_sdr_cap(struct file *file, void *priv, |
962 | struct v4l2_format *f) |
963 | { |
964 | unsigned int i; |
965 | |
966 | for (i = 0; i < ARRAY_SIZE(formats); i++) { |
967 | if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { |
968 | f->fmt.sdr.buffersize = formats[i].buffersize; |
969 | return 0; |
970 | } |
971 | } |
972 | |
973 | f->fmt.sdr.pixelformat = formats[0].pixelformat; |
974 | f->fmt.sdr.buffersize = formats[0].buffersize; |
975 | memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); |
976 | |
977 | return 0; |
978 | } |
979 | |
980 | /* Tuner subdev ioctls */ |
981 | static int rcar_drif_enum_freq_bands(struct file *file, void *priv, |
982 | struct v4l2_frequency_band *band) |
983 | { |
984 | struct rcar_drif_sdr *sdr = video_drvdata(file); |
985 | |
986 | return v4l2_subdev_call(sdr->ep.subdev, tuner, enum_freq_bands, band); |
987 | } |
988 | |
989 | static int rcar_drif_g_frequency(struct file *file, void *priv, |
990 | struct v4l2_frequency *f) |
991 | { |
992 | struct rcar_drif_sdr *sdr = video_drvdata(file); |
993 | |
994 | return v4l2_subdev_call(sdr->ep.subdev, tuner, g_frequency, f); |
995 | } |
996 | |
997 | static int rcar_drif_s_frequency(struct file *file, void *priv, |
998 | const struct v4l2_frequency *f) |
999 | { |
1000 | struct rcar_drif_sdr *sdr = video_drvdata(file); |
1001 | |
1002 | return v4l2_subdev_call(sdr->ep.subdev, tuner, s_frequency, f); |
1003 | } |
1004 | |
1005 | static int rcar_drif_g_tuner(struct file *file, void *priv, |
1006 | struct v4l2_tuner *vt) |
1007 | { |
1008 | struct rcar_drif_sdr *sdr = video_drvdata(file); |
1009 | |
1010 | return v4l2_subdev_call(sdr->ep.subdev, tuner, g_tuner, vt); |
1011 | } |
1012 | |
1013 | static int rcar_drif_s_tuner(struct file *file, void *priv, |
1014 | const struct v4l2_tuner *vt) |
1015 | { |
1016 | struct rcar_drif_sdr *sdr = video_drvdata(file); |
1017 | |
1018 | return v4l2_subdev_call(sdr->ep.subdev, tuner, s_tuner, vt); |
1019 | } |
1020 | |
1021 | static const struct v4l2_ioctl_ops rcar_drif_ioctl_ops = { |
1022 | .vidioc_querycap = rcar_drif_querycap, |
1023 | |
1024 | .vidioc_enum_fmt_sdr_cap = rcar_drif_enum_fmt_sdr_cap, |
1025 | .vidioc_g_fmt_sdr_cap = rcar_drif_g_fmt_sdr_cap, |
1026 | .vidioc_s_fmt_sdr_cap = rcar_drif_s_fmt_sdr_cap, |
1027 | .vidioc_try_fmt_sdr_cap = rcar_drif_try_fmt_sdr_cap, |
1028 | |
1029 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
1030 | .vidioc_create_bufs = vb2_ioctl_create_bufs, |
1031 | .vidioc_prepare_buf = vb2_ioctl_prepare_buf, |
1032 | .vidioc_querybuf = vb2_ioctl_querybuf, |
1033 | .vidioc_qbuf = vb2_ioctl_qbuf, |
1034 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
1035 | |
1036 | .vidioc_streamon = vb2_ioctl_streamon, |
1037 | .vidioc_streamoff = vb2_ioctl_streamoff, |
1038 | |
1039 | .vidioc_s_frequency = rcar_drif_s_frequency, |
1040 | .vidioc_g_frequency = rcar_drif_g_frequency, |
1041 | .vidioc_s_tuner = rcar_drif_s_tuner, |
1042 | .vidioc_g_tuner = rcar_drif_g_tuner, |
1043 | .vidioc_enum_freq_bands = rcar_drif_enum_freq_bands, |
1044 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, |
1045 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, |
1046 | .vidioc_log_status = v4l2_ctrl_log_status, |
1047 | }; |
1048 | |
1049 | static const struct v4l2_file_operations rcar_drif_fops = { |
1050 | .owner = THIS_MODULE, |
1051 | .open = v4l2_fh_open, |
1052 | .release = vb2_fop_release, |
1053 | .read = vb2_fop_read, |
1054 | .poll = vb2_fop_poll, |
1055 | .mmap = vb2_fop_mmap, |
1056 | .unlocked_ioctl = video_ioctl2, |
1057 | }; |
1058 | |
1059 | static int rcar_drif_sdr_register(struct rcar_drif_sdr *sdr) |
1060 | { |
1061 | int ret; |
1062 | |
1063 | /* Init video_device structure */ |
1064 | sdr->vdev = video_device_alloc(); |
1065 | if (!sdr->vdev) |
1066 | return -ENOMEM; |
1067 | |
1068 | snprintf(buf: sdr->vdev->name, size: sizeof(sdr->vdev->name), fmt: "R-Car DRIF" ); |
1069 | sdr->vdev->fops = &rcar_drif_fops; |
1070 | sdr->vdev->ioctl_ops = &rcar_drif_ioctl_ops; |
1071 | sdr->vdev->release = video_device_release; |
1072 | sdr->vdev->lock = &sdr->v4l2_mutex; |
1073 | sdr->vdev->queue = &sdr->vb_queue; |
1074 | sdr->vdev->queue->lock = &sdr->vb_queue_mutex; |
1075 | sdr->vdev->ctrl_handler = &sdr->ctrl_hdl; |
1076 | sdr->vdev->v4l2_dev = &sdr->v4l2_dev; |
1077 | sdr->vdev->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_TUNER | |
1078 | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; |
1079 | video_set_drvdata(vdev: sdr->vdev, data: sdr); |
1080 | |
1081 | /* Register V4L2 SDR device */ |
1082 | ret = video_register_device(vdev: sdr->vdev, type: VFL_TYPE_SDR, nr: -1); |
1083 | if (ret) { |
1084 | video_device_release(vdev: sdr->vdev); |
1085 | sdr->vdev = NULL; |
1086 | dev_err(sdr->dev, "failed video_register_device (%d)\n" , ret); |
1087 | } |
1088 | |
1089 | return ret; |
1090 | } |
1091 | |
1092 | static void rcar_drif_sdr_unregister(struct rcar_drif_sdr *sdr) |
1093 | { |
1094 | video_unregister_device(vdev: sdr->vdev); |
1095 | sdr->vdev = NULL; |
1096 | } |
1097 | |
1098 | /* Sub-device bound callback */ |
1099 | static int rcar_drif_notify_bound(struct v4l2_async_notifier *notifier, |
1100 | struct v4l2_subdev *subdev, |
1101 | struct v4l2_async_connection *asd) |
1102 | { |
1103 | struct rcar_drif_sdr *sdr = |
1104 | container_of(notifier, struct rcar_drif_sdr, notifier); |
1105 | |
1106 | v4l2_set_subdev_hostdata(sd: subdev, p: sdr); |
1107 | sdr->ep.subdev = subdev; |
1108 | rdrif_dbg(sdr, "bound asd %s\n" , subdev->name); |
1109 | |
1110 | return 0; |
1111 | } |
1112 | |
1113 | /* Sub-device unbind callback */ |
1114 | static void rcar_drif_notify_unbind(struct v4l2_async_notifier *notifier, |
1115 | struct v4l2_subdev *subdev, |
1116 | struct v4l2_async_connection *asd) |
1117 | { |
1118 | struct rcar_drif_sdr *sdr = |
1119 | container_of(notifier, struct rcar_drif_sdr, notifier); |
1120 | |
1121 | if (sdr->ep.subdev != subdev) { |
1122 | rdrif_err(sdr, "subdev %s is not bound\n" , subdev->name); |
1123 | return; |
1124 | } |
1125 | |
1126 | /* Free ctrl handler if initialized */ |
1127 | v4l2_ctrl_handler_free(hdl: &sdr->ctrl_hdl); |
1128 | sdr->v4l2_dev.ctrl_handler = NULL; |
1129 | sdr->ep.subdev = NULL; |
1130 | |
1131 | rcar_drif_sdr_unregister(sdr); |
1132 | rdrif_dbg(sdr, "unbind asd %s\n" , subdev->name); |
1133 | } |
1134 | |
1135 | /* Sub-device registered notification callback */ |
1136 | static int rcar_drif_notify_complete(struct v4l2_async_notifier *notifier) |
1137 | { |
1138 | struct rcar_drif_sdr *sdr = |
1139 | container_of(notifier, struct rcar_drif_sdr, notifier); |
1140 | int ret; |
1141 | |
1142 | /* |
1143 | * The subdev tested at this point uses 4 controls. Using 10 as a worst |
1144 | * case scenario hint. When less controls are needed there will be some |
1145 | * unused memory and when more controls are needed the framework uses |
1146 | * hash to manage controls within this number. |
1147 | */ |
1148 | ret = v4l2_ctrl_handler_init(&sdr->ctrl_hdl, 10); |
1149 | if (ret) |
1150 | return -ENOMEM; |
1151 | |
1152 | sdr->v4l2_dev.ctrl_handler = &sdr->ctrl_hdl; |
1153 | ret = v4l2_device_register_subdev_nodes(v4l2_dev: &sdr->v4l2_dev); |
1154 | if (ret) { |
1155 | rdrif_err(sdr, "failed: register subdev nodes ret %d\n" , ret); |
1156 | goto error; |
1157 | } |
1158 | |
1159 | ret = v4l2_ctrl_add_handler(hdl: &sdr->ctrl_hdl, |
1160 | add: sdr->ep.subdev->ctrl_handler, NULL, from_other_dev: true); |
1161 | if (ret) { |
1162 | rdrif_err(sdr, "failed: ctrl add hdlr ret %d\n" , ret); |
1163 | goto error; |
1164 | } |
1165 | |
1166 | ret = rcar_drif_sdr_register(sdr); |
1167 | if (ret) |
1168 | goto error; |
1169 | |
1170 | return ret; |
1171 | |
1172 | error: |
1173 | v4l2_ctrl_handler_free(hdl: &sdr->ctrl_hdl); |
1174 | |
1175 | return ret; |
1176 | } |
1177 | |
1178 | static const struct v4l2_async_notifier_operations rcar_drif_notify_ops = { |
1179 | .bound = rcar_drif_notify_bound, |
1180 | .unbind = rcar_drif_notify_unbind, |
1181 | .complete = rcar_drif_notify_complete, |
1182 | }; |
1183 | |
1184 | /* Read endpoint properties */ |
1185 | static void rcar_drif_get_ep_properties(struct rcar_drif_sdr *sdr, |
1186 | struct fwnode_handle *fwnode) |
1187 | { |
1188 | u32 val; |
1189 | |
1190 | /* Set the I2S defaults for SIRMDR1*/ |
1191 | sdr->mdr1 = RCAR_DRIF_SIRMDR1_SYNCMD_LR | RCAR_DRIF_SIRMDR1_MSB_FIRST | |
1192 | RCAR_DRIF_SIRMDR1_DTDL_1 | RCAR_DRIF_SIRMDR1_SYNCDL_0; |
1193 | |
1194 | /* Parse sync polarity from endpoint */ |
1195 | if (!fwnode_property_read_u32(fwnode, propname: "sync-active" , val: &val)) |
1196 | sdr->mdr1 |= val ? RCAR_DRIF_SIRMDR1_SYNCAC_POL_HIGH : |
1197 | RCAR_DRIF_SIRMDR1_SYNCAC_POL_LOW; |
1198 | else |
1199 | sdr->mdr1 |= RCAR_DRIF_SIRMDR1_SYNCAC_POL_HIGH; /* default */ |
1200 | |
1201 | dev_dbg(sdr->dev, "mdr1 0x%08x\n" , sdr->mdr1); |
1202 | } |
1203 | |
1204 | /* Parse sub-devs (tuner) to find a matching device */ |
1205 | static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr) |
1206 | { |
1207 | struct v4l2_async_notifier *notifier = &sdr->notifier; |
1208 | struct fwnode_handle *fwnode, *ep; |
1209 | struct v4l2_async_connection *asd; |
1210 | |
1211 | v4l2_async_nf_init(notifier: &sdr->notifier, v4l2_dev: &sdr->v4l2_dev); |
1212 | |
1213 | ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(sdr->dev->of_node), |
1214 | NULL); |
1215 | if (!ep) |
1216 | return 0; |
1217 | |
1218 | /* Get the endpoint properties */ |
1219 | rcar_drif_get_ep_properties(sdr, fwnode: ep); |
1220 | |
1221 | fwnode = fwnode_graph_get_remote_port_parent(fwnode: ep); |
1222 | fwnode_handle_put(fwnode: ep); |
1223 | if (!fwnode) { |
1224 | dev_warn(sdr->dev, "bad remote port parent\n" ); |
1225 | return -EINVAL; |
1226 | } |
1227 | |
1228 | asd = v4l2_async_nf_add_fwnode(notifier, fwnode, |
1229 | struct v4l2_async_connection); |
1230 | fwnode_handle_put(fwnode); |
1231 | if (IS_ERR(ptr: asd)) |
1232 | return PTR_ERR(ptr: asd); |
1233 | |
1234 | return 0; |
1235 | } |
1236 | |
1237 | /* Check if the given device is the primary bond */ |
1238 | static bool rcar_drif_primary_bond(struct platform_device *pdev) |
1239 | { |
1240 | return of_property_read_bool(np: pdev->dev.of_node, propname: "renesas,primary-bond" ); |
1241 | } |
1242 | |
1243 | /* Check if both devices of the bond are enabled */ |
1244 | static struct device_node *rcar_drif_bond_enabled(struct platform_device *p) |
1245 | { |
1246 | struct device_node *np; |
1247 | |
1248 | np = of_parse_phandle(np: p->dev.of_node, phandle_name: "renesas,bonding" , index: 0); |
1249 | if (np && of_device_is_available(device: np)) |
1250 | return np; |
1251 | |
1252 | return NULL; |
1253 | } |
1254 | |
1255 | /* Check if the bonded device is probed */ |
1256 | static int rcar_drif_bond_available(struct rcar_drif_sdr *sdr, |
1257 | struct device_node *np) |
1258 | { |
1259 | struct platform_device *pdev; |
1260 | struct rcar_drif *ch; |
1261 | int ret = 0; |
1262 | |
1263 | pdev = of_find_device_by_node(np); |
1264 | if (!pdev) { |
1265 | dev_err(sdr->dev, "failed to get bonded device from node\n" ); |
1266 | return -ENODEV; |
1267 | } |
1268 | |
1269 | device_lock(dev: &pdev->dev); |
1270 | ch = platform_get_drvdata(pdev); |
1271 | if (ch) { |
1272 | /* Update sdr data in the bonded device */ |
1273 | ch->sdr = sdr; |
1274 | |
1275 | /* Update sdr with bonded device data */ |
1276 | sdr->ch[ch->num] = ch; |
1277 | sdr->hw_ch_mask |= BIT(ch->num); |
1278 | } else { |
1279 | /* Defer */ |
1280 | dev_info(sdr->dev, "defer probe\n" ); |
1281 | ret = -EPROBE_DEFER; |
1282 | } |
1283 | device_unlock(dev: &pdev->dev); |
1284 | |
1285 | put_device(dev: &pdev->dev); |
1286 | |
1287 | return ret; |
1288 | } |
1289 | |
1290 | /* V4L2 SDR device probe */ |
1291 | static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr) |
1292 | { |
1293 | int ret; |
1294 | |
1295 | /* Validate any supported format for enabled channels */ |
1296 | ret = rcar_drif_set_default_format(sdr); |
1297 | if (ret) { |
1298 | dev_err(sdr->dev, "failed to set default format\n" ); |
1299 | return ret; |
1300 | } |
1301 | |
1302 | /* Set defaults */ |
1303 | sdr->hwbuf_size = RCAR_DRIF_DEFAULT_HWBUF_SIZE; |
1304 | |
1305 | mutex_init(&sdr->v4l2_mutex); |
1306 | mutex_init(&sdr->vb_queue_mutex); |
1307 | spin_lock_init(&sdr->queued_bufs_lock); |
1308 | spin_lock_init(&sdr->dma_lock); |
1309 | INIT_LIST_HEAD(list: &sdr->queued_bufs); |
1310 | |
1311 | /* Init videobuf2 queue structure */ |
1312 | sdr->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE; |
1313 | sdr->vb_queue.io_modes = VB2_READ | VB2_MMAP | VB2_DMABUF; |
1314 | sdr->vb_queue.drv_priv = sdr; |
1315 | sdr->vb_queue.buf_struct_size = sizeof(struct rcar_drif_frame_buf); |
1316 | sdr->vb_queue.ops = &rcar_drif_vb2_ops; |
1317 | sdr->vb_queue.mem_ops = &vb2_vmalloc_memops; |
1318 | sdr->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
1319 | |
1320 | /* Init videobuf2 queue */ |
1321 | ret = vb2_queue_init(q: &sdr->vb_queue); |
1322 | if (ret) { |
1323 | dev_err(sdr->dev, "failed: vb2_queue_init ret %d\n" , ret); |
1324 | return ret; |
1325 | } |
1326 | |
1327 | /* Register the v4l2_device */ |
1328 | ret = v4l2_device_register(dev: sdr->dev, v4l2_dev: &sdr->v4l2_dev); |
1329 | if (ret) { |
1330 | dev_err(sdr->dev, "failed: v4l2_device_register ret %d\n" , ret); |
1331 | return ret; |
1332 | } |
1333 | |
1334 | /* |
1335 | * Parse subdevs after v4l2_device_register because if the subdev |
1336 | * is already probed, bound and complete will be called immediately |
1337 | */ |
1338 | ret = rcar_drif_parse_subdevs(sdr); |
1339 | if (ret) |
1340 | goto error; |
1341 | |
1342 | sdr->notifier.ops = &rcar_drif_notify_ops; |
1343 | |
1344 | /* Register notifier */ |
1345 | ret = v4l2_async_nf_register(notifier: &sdr->notifier); |
1346 | if (ret < 0) { |
1347 | dev_err(sdr->dev, "failed: notifier register ret %d\n" , ret); |
1348 | goto cleanup; |
1349 | } |
1350 | |
1351 | return ret; |
1352 | |
1353 | cleanup: |
1354 | v4l2_async_nf_cleanup(notifier: &sdr->notifier); |
1355 | error: |
1356 | v4l2_device_unregister(v4l2_dev: &sdr->v4l2_dev); |
1357 | |
1358 | return ret; |
1359 | } |
1360 | |
1361 | /* V4L2 SDR device remove */ |
1362 | static void rcar_drif_sdr_remove(struct rcar_drif_sdr *sdr) |
1363 | { |
1364 | v4l2_async_nf_unregister(notifier: &sdr->notifier); |
1365 | v4l2_async_nf_cleanup(notifier: &sdr->notifier); |
1366 | v4l2_device_unregister(v4l2_dev: &sdr->v4l2_dev); |
1367 | } |
1368 | |
1369 | /* DRIF channel probe */ |
1370 | static int rcar_drif_probe(struct platform_device *pdev) |
1371 | { |
1372 | struct rcar_drif_sdr *sdr; |
1373 | struct device_node *np; |
1374 | struct rcar_drif *ch; |
1375 | struct resource *res; |
1376 | int ret; |
1377 | |
1378 | /* Reserve memory for enabled channel */ |
1379 | ch = devm_kzalloc(dev: &pdev->dev, size: sizeof(*ch), GFP_KERNEL); |
1380 | if (!ch) |
1381 | return -ENOMEM; |
1382 | |
1383 | ch->pdev = pdev; |
1384 | |
1385 | /* Module clock */ |
1386 | ch->clk = devm_clk_get(dev: &pdev->dev, id: "fck" ); |
1387 | if (IS_ERR(ptr: ch->clk)) { |
1388 | ret = PTR_ERR(ptr: ch->clk); |
1389 | dev_err(&pdev->dev, "clk get failed (%d)\n" , ret); |
1390 | return ret; |
1391 | } |
1392 | |
1393 | /* Register map */ |
1394 | ch->base = devm_platform_get_and_ioremap_resource(pdev, index: 0, res: &res); |
1395 | if (IS_ERR(ptr: ch->base)) |
1396 | return PTR_ERR(ptr: ch->base); |
1397 | |
1398 | ch->start = res->start; |
1399 | platform_set_drvdata(pdev, data: ch); |
1400 | |
1401 | /* Check if both channels of the bond are enabled */ |
1402 | np = rcar_drif_bond_enabled(p: pdev); |
1403 | if (np) { |
1404 | /* Check if current channel acting as primary-bond */ |
1405 | if (!rcar_drif_primary_bond(pdev)) { |
1406 | ch->num = 1; /* Primary bond is channel 0 always */ |
1407 | of_node_put(node: np); |
1408 | return 0; |
1409 | } |
1410 | } |
1411 | |
1412 | /* Reserve memory for SDR structure */ |
1413 | sdr = devm_kzalloc(dev: &pdev->dev, size: sizeof(*sdr), GFP_KERNEL); |
1414 | if (!sdr) { |
1415 | of_node_put(node: np); |
1416 | return -ENOMEM; |
1417 | } |
1418 | ch->sdr = sdr; |
1419 | sdr->dev = &pdev->dev; |
1420 | |
1421 | /* Establish links between SDR and channel(s) */ |
1422 | sdr->ch[ch->num] = ch; |
1423 | sdr->hw_ch_mask = BIT(ch->num); |
1424 | if (np) { |
1425 | /* Check if bonded device is ready */ |
1426 | ret = rcar_drif_bond_available(sdr, np); |
1427 | of_node_put(node: np); |
1428 | if (ret) |
1429 | return ret; |
1430 | } |
1431 | sdr->num_hw_ch = hweight_long(w: sdr->hw_ch_mask); |
1432 | |
1433 | return rcar_drif_sdr_probe(sdr); |
1434 | } |
1435 | |
1436 | /* DRIF channel remove */ |
1437 | static void rcar_drif_remove(struct platform_device *pdev) |
1438 | { |
1439 | struct rcar_drif *ch = platform_get_drvdata(pdev); |
1440 | struct rcar_drif_sdr *sdr = ch->sdr; |
1441 | |
1442 | /* Channel 0 will be the SDR instance */ |
1443 | if (ch->num) |
1444 | return; |
1445 | |
1446 | /* SDR instance */ |
1447 | rcar_drif_sdr_remove(sdr); |
1448 | } |
1449 | |
1450 | /* FIXME: Implement suspend/resume support */ |
1451 | static int __maybe_unused rcar_drif_suspend(struct device *dev) |
1452 | { |
1453 | return 0; |
1454 | } |
1455 | |
1456 | static int __maybe_unused rcar_drif_resume(struct device *dev) |
1457 | { |
1458 | return 0; |
1459 | } |
1460 | |
1461 | static SIMPLE_DEV_PM_OPS(rcar_drif_pm_ops, rcar_drif_suspend, |
1462 | rcar_drif_resume); |
1463 | |
1464 | static const struct of_device_id rcar_drif_of_table[] = { |
1465 | { .compatible = "renesas,rcar-gen3-drif" }, |
1466 | { } |
1467 | }; |
1468 | MODULE_DEVICE_TABLE(of, rcar_drif_of_table); |
1469 | |
1470 | #define RCAR_DRIF_DRV_NAME "rcar_drif" |
1471 | static struct platform_driver rcar_drif_driver = { |
1472 | .driver = { |
1473 | .name = RCAR_DRIF_DRV_NAME, |
1474 | .of_match_table = rcar_drif_of_table, |
1475 | .pm = &rcar_drif_pm_ops, |
1476 | }, |
1477 | .probe = rcar_drif_probe, |
1478 | .remove_new = rcar_drif_remove, |
1479 | }; |
1480 | |
1481 | module_platform_driver(rcar_drif_driver); |
1482 | |
1483 | MODULE_DESCRIPTION("Renesas R-Car Gen3 DRIF driver" ); |
1484 | MODULE_ALIAS("platform:" RCAR_DRIF_DRV_NAME); |
1485 | MODULE_LICENSE("GPL" ); |
1486 | MODULE_AUTHOR("Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>" ); |
1487 | |