forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/platform/vsp1/vsp1_wpf.c
....@@ -232,17 +232,41 @@
232232 vsp1_dlm_destroy(wpf->dlm);
233233 }
234234
235
+static int wpf_configure_writeback_chain(struct vsp1_rwpf *wpf,
236
+ struct vsp1_dl_list *dl)
237
+{
238
+ unsigned int index = wpf->entity.index;
239
+ struct vsp1_dl_list *dl_next;
240
+ struct vsp1_dl_body *dlb;
241
+
242
+ dl_next = vsp1_dl_list_get(wpf->dlm);
243
+ if (!dl_next) {
244
+ dev_err(wpf->entity.vsp1->dev,
245
+ "Failed to obtain a dl list, disabling writeback\n");
246
+ return -ENOMEM;
247
+ }
248
+
249
+ dlb = vsp1_dl_list_get_body0(dl_next);
250
+ vsp1_dl_body_write(dlb, VI6_WPF_WRBCK_CTRL(index), 0);
251
+ vsp1_dl_list_add_chain(dl, dl_next);
252
+
253
+ return 0;
254
+}
255
+
235256 static void wpf_configure_stream(struct vsp1_entity *entity,
236257 struct vsp1_pipeline *pipe,
258
+ struct vsp1_dl_list *dl,
237259 struct vsp1_dl_body *dlb)
238260 {
239261 struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev);
240262 struct vsp1_device *vsp1 = wpf->entity.vsp1;
241263 const struct v4l2_mbus_framefmt *source_format;
242264 const struct v4l2_mbus_framefmt *sink_format;
265
+ unsigned int index = wpf->entity.index;
243266 unsigned int i;
244267 u32 outfmt = 0;
245268 u32 srcrpf = 0;
269
+ int ret;
246270
247271 sink_format = vsp1_entity_get_pad_format(&wpf->entity,
248272 wpf->entity.config,
....@@ -250,8 +274,9 @@
250274 source_format = vsp1_entity_get_pad_format(&wpf->entity,
251275 wpf->entity.config,
252276 RWPF_PAD_SOURCE);
277
+
253278 /* Format */
254
- if (!pipe->lif) {
279
+ if (!pipe->lif || wpf->writeback) {
255280 const struct v4l2_pix_format_mplane *format = &wpf->format;
256281 const struct vsp1_format_info *fmtinfo = wpf->fmtinfo;
257282
....@@ -276,8 +301,7 @@
276301
277302 vsp1_wpf_write(wpf, dlb, VI6_WPF_DSWAP, fmtinfo->swap);
278303
279
- if (vsp1_feature(vsp1, VSP1_HAS_WPF_HFLIP) &&
280
- wpf->entity.index == 0)
304
+ if (vsp1_feature(vsp1, VSP1_HAS_WPF_HFLIP) && index == 0)
281305 vsp1_wpf_write(wpf, dlb, VI6_WPF_ROT_CTRL,
282306 VI6_WPF_ROT_CTRL_LN16 |
283307 (256 << VI6_WPF_ROT_CTRL_LMEM_WD_SHIFT));
....@@ -288,10 +312,8 @@
288312
289313 wpf->outfmt = outfmt;
290314
291
- vsp1_dl_body_write(dlb, VI6_DPR_WPF_FPORCH(wpf->entity.index),
315
+ vsp1_dl_body_write(dlb, VI6_DPR_WPF_FPORCH(index),
292316 VI6_DPR_WPF_FPORCH_FP_WPFN);
293
-
294
- vsp1_dl_body_write(dlb, VI6_WPF_WRBCK_CTRL, 0);
295317
296318 /*
297319 * Sources. If the pipeline has a single input and BRx is not used,
....@@ -317,10 +339,27 @@
317339
318340 vsp1_wpf_write(wpf, dlb, VI6_WPF_SRCRPF, srcrpf);
319341
320
- /* Enable interrupts */
321
- vsp1_dl_body_write(dlb, VI6_WPF_IRQ_STA(wpf->entity.index), 0);
322
- vsp1_dl_body_write(dlb, VI6_WPF_IRQ_ENB(wpf->entity.index),
342
+ /* Enable interrupts. */
343
+ vsp1_dl_body_write(dlb, VI6_WPF_IRQ_STA(index), 0);
344
+ vsp1_dl_body_write(dlb, VI6_WPF_IRQ_ENB(index),
323345 VI6_WFP_IRQ_ENB_DFEE);
346
+
347
+ /*
348
+ * Configure writeback for display pipelines (the wpf writeback flag is
349
+ * never set for memory-to-memory pipelines). Start by adding a chained
350
+ * display list to disable writeback after a single frame, and process
351
+ * to enable writeback. If the display list allocation fails don't
352
+ * enable writeback as we wouldn't be able to safely disable it,
353
+ * resulting in possible memory corruption.
354
+ */
355
+ if (wpf->writeback) {
356
+ ret = wpf_configure_writeback_chain(wpf, dl);
357
+ if (ret < 0)
358
+ wpf->writeback = false;
359
+ }
360
+
361
+ vsp1_dl_body_write(dlb, VI6_WPF_WRBCK_CTRL(index),
362
+ wpf->writeback ? VI6_WPF_WRBCK_CTRL_WBMD : 0);
324363 }
325364
326365 static void wpf_configure_frame(struct vsp1_entity *entity,
....@@ -362,6 +401,7 @@
362401 const struct vsp1_format_info *fmtinfo = wpf->fmtinfo;
363402 unsigned int width;
364403 unsigned int height;
404
+ unsigned int left;
365405 unsigned int offset;
366406 unsigned int flip;
367407 unsigned int i;
....@@ -371,13 +411,16 @@
371411 RWPF_PAD_SINK);
372412 width = sink_format->width;
373413 height = sink_format->height;
414
+ left = 0;
374415
375416 /*
376417 * Cropping. The partition algorithm can split the image into
377418 * multiple slices.
378419 */
379
- if (pipe->partitions > 1)
420
+ if (pipe->partitions > 1) {
380421 width = pipe->partition->wpf.width;
422
+ left = pipe->partition->wpf.left;
423
+ }
381424
382425 vsp1_wpf_write(wpf, dlb, VI6_WPF_HSZCLIP, VI6_WPF_SZCLIP_EN |
383426 (0 << VI6_WPF_SZCLIP_OFST_SHIFT) |
....@@ -386,7 +429,11 @@
386429 (0 << VI6_WPF_SZCLIP_OFST_SHIFT) |
387430 (height << VI6_WPF_SZCLIP_SIZE_SHIFT));
388431
389
- if (pipe->lif)
432
+ /*
433
+ * For display pipelines without writeback enabled there's no memory
434
+ * address to configure, return now.
435
+ */
436
+ if (pipe->lif && !wpf->writeback)
390437 return;
391438
392439 /*
....@@ -408,13 +455,11 @@
408455 flip = wpf->flip.active;
409456
410457 if (flip & BIT(WPF_CTRL_HFLIP) && !wpf->flip.rotate)
411
- offset = format->width - pipe->partition->wpf.left
412
- - pipe->partition->wpf.width;
458
+ offset = format->width - left - width;
413459 else if (flip & BIT(WPF_CTRL_VFLIP) && wpf->flip.rotate)
414
- offset = format->height - pipe->partition->wpf.left
415
- - pipe->partition->wpf.width;
460
+ offset = format->height - left - width;
416461 else
417
- offset = pipe->partition->wpf.left;
462
+ offset = left;
418463
419464 for (i = 0; i < format->num_planes; ++i) {
420465 unsigned int hsub = i > 0 ? fmtinfo->hsub : 1;
....@@ -436,7 +481,7 @@
436481 * image height.
437482 */
438483 if (wpf->flip.rotate)
439
- height = pipe->partition->wpf.width;
484
+ height = width;
440485 else
441486 height = format->height;
442487
....@@ -477,6 +522,12 @@
477522 vsp1_wpf_write(wpf, dlb, VI6_WPF_DSTM_ADDR_Y, mem.addr[0]);
478523 vsp1_wpf_write(wpf, dlb, VI6_WPF_DSTM_ADDR_C0, mem.addr[1]);
479524 vsp1_wpf_write(wpf, dlb, VI6_WPF_DSTM_ADDR_C1, mem.addr[2]);
525
+
526
+ /*
527
+ * Writeback operates in single-shot mode and lasts for a single frame,
528
+ * reset the writeback flag to false for the next frame.
529
+ */
530
+ wpf->writeback = false;
480531 }
481532
482533 static unsigned int wpf_max_width(struct vsp1_entity *entity,