1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * drivers/video/rockchip/video/vehicle_flinger.c
4 *
5 * Copyright (C) 2022 Rockchip Electronics Co., Ltd.
6 * Authors:
7 * Jianwei Fan <jianwei.fan@rock-chips.com>
8 *
9 */
10
11 #include <linux/atomic.h>
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/errno.h>
15 #include <linux/string.h>
16 #include <linux/mm.h>
17 #include <linux/slab.h>
18 #include <linux/delay.h>
19 #include <linux/device.h>
20 #include <linux/kthread.h>
21 #include <linux/fb.h>
22 #include <linux/init.h>
23 #include <linux/vmalloc.h>
24 #include <asm/div64.h>
25 #include <linux/uaccess.h>
26 #include <linux/linux_logo.h>
27 #include <linux/dma-mapping.h>
28 #include <linux/regulator/consumer.h>
29 #include <linux/of_address.h>
30 #include <linux/memblock.h>
31 #include <linux/kthread.h>
32 #include <linux/fdtable.h>
33 #include <linux/miscdevice.h>
34 #ifdef CONFIG_OF
35 #include <linux/of.h>
36 #include <linux/of_platform.h>
37 #include <linux/of_gpio.h>
38 #include <video/of_display_timing.h>
39 #include <video/display_timing.h>
40 #endif
41
42 #include "vehicle_flinger.h"
43 #include "../../../gpu/drm/rockchip/rockchip_drm_direct_show.h"
44 #include "../drivers/video/rockchip/rga3/include/rga_drv.h"
45
46 static int vehicle_dump_cif;
47 static int vehicle_dump_rga;
48 static int vehicle_dump_vop;
49
50 enum force_value {
51 FORCE_WIDTH = 1920,
52 FORCE_HEIGHT = 1080,
53 FORCE_STRIDE = 1920,
54 FORCE_XOFFSET = 0,
55 FORCE_YOFFSET = 0,
56 FORCE_FORMAT = HAL_PIXEL_FORMAT_YCrCb_NV12,
57 FORCE_ROTATION = RGA_TRANSFORM_ROT_0,
58 };
59
60 enum {
61 NUM_SOURCE_BUFFERS = 5, /*5 src buffer for cif*/
62 NUM_TARGET_BUFFERS = 3, /*3 dst buffer rga*/
63 };
64
65 enum buffer_state {
66 UNKNOWN = 0,
67 FREE,
68 DEQUEUE,
69 QUEUE,
70 ACQUIRE,
71 DISPLAY,
72 };
73
74 struct rect {
75 size_t x;
76 size_t y;
77 size_t w;
78 size_t h;
79 size_t s;
80 size_t f;
81 };
82
83 struct graphic_buffer {
84 struct list_head list;
85 uint32_t handle;
86 struct rockchip_drm_direct_show_buffer *drm_buffer;
87 int fd;
88 struct sync_fence *rel_fence;
89 struct rect src;
90 struct rect dst;
91 enum buffer_state state;
92 unsigned long phy_addr;
93 void *vir_addr;
94 int rotation;
95 int offset;
96 int len;
97 int width;
98 int height;
99 int stride;
100 int format;
101 struct work_struct render_work;
102 ktime_t timestamp;
103 };
104
105 struct queue_buffer {
106 struct list_head list;
107 struct graphic_buffer *buffer;
108 };
109
110 struct flinger {
111 struct device *dev;
112 struct ion_client *ion_client;
113 struct work_struct init_work;
114 struct work_struct render_work;
115 struct workqueue_struct *render_workqueue;
116 struct mutex source_buffer_lock;/*src buffer lock*/
117 struct mutex target_buffer_lock;/*dst buffer lock*/
118 struct graphic_buffer source_buffer[NUM_SOURCE_BUFFERS];
119 struct graphic_buffer target_buffer[NUM_TARGET_BUFFERS];
120 struct mutex queue_buffer_lock;
121 struct list_head queue_buffer_list;
122 wait_queue_head_t worker_wait;
123 atomic_t worker_cond_atomic;
124 atomic_t worker_running_atomic;
125 int source_index;
126 int target_index;
127 struct vehicle_cfg v_cfg;
128 int cvbs_field_count;
129 struct graphic_buffer *last_src_buffer;
130 /*debug*/
131 int debug_cif_count;
132 int debug_vop_count;
133 bool running;
134 struct drm_device *drm_dev;
135 struct drm_crtc *crtc;
136 struct drm_plane *plane;
137 const char *crtc_name;
138 const char *plane_name;
139 };
140
141 static struct flinger *flinger;
142
143 static int rk_flinger_queue_work(struct flinger *flinger,
144 struct graphic_buffer *src_buffer);
145
rk_flinger_alloc_bpp(int format)146 static int rk_flinger_alloc_bpp(int format)
147 {
148 int width = 4;
149
150 switch (format) {
151 case HAL_PIXEL_FORMAT_RGB_565:
152 width = 2;
153 break;
154 case HAL_PIXEL_FORMAT_RGB_888:
155 width = 3;
156 break;
157 case HAL_PIXEL_FORMAT_RGBA_8888:
158 width = 4;
159 break;
160 case HAL_PIXEL_FORMAT_RGBX_8888:
161 width = 4;
162 break;
163 case HAL_PIXEL_FORMAT_BGRA_8888:
164 width = 4;
165 break;
166 case HAL_PIXEL_FORMAT_YCrCb_NV12:
167 width = 2;
168 break;
169 default:
170 VEHICLE_INFO("%s: unsupported format: 0x%x\n", __func__, format);
171 break;
172 }
173
174 return width;
175 }
176
rk_flinger_HAL_format_to_DRM(int format)177 static int rk_flinger_HAL_format_to_DRM(int format)
178 {
179 int drm_format = 0;
180
181 switch (format) {
182 case HAL_PIXEL_FORMAT_RGBX_8888:
183 drm_format = DRM_FORMAT_XRGB8888;
184 break;
185 case HAL_PIXEL_FORMAT_YCrCb_NV12:
186 drm_format = DRM_FORMAT_NV12;
187 break;
188 case HAL_PIXEL_FORMAT_RGB_888:
189 drm_format = DRM_FORMAT_RGB888;
190 break;
191 case HAL_PIXEL_FORMAT_RGB_565:
192 drm_format = DRM_FORMAT_RGB565;
193 break;
194 default:
195 VEHICLE_INFO("%s: unsupported format: 0x%x\n", __func__, format);
196 break;
197 }
198
199 return drm_format;
200 }
201
rk_flinger_alloc_buffer(struct flinger * flg,struct graphic_buffer * buffer,int w,int h,int s,int f)202 static int rk_flinger_alloc_buffer(struct flinger *flg,
203 struct graphic_buffer *buffer,
204 int w, int h,
205 int s, int f)
206 {
207 unsigned long phy_addr;
208 size_t len;
209 int bpp;
210 int ret = 0;
211 struct rockchip_drm_direct_show_buffer *create_buffer;
212
213 VEHICLE_DG("------------alloc buffer start---------\n");
214 if (!flg)
215 return -ENODEV;
216
217 if (!buffer)
218 return -EINVAL;
219
220 bpp = rk_flinger_alloc_bpp(f);
221 len = s * h * bpp;
222
223 create_buffer = kmalloc(sizeof(struct rockchip_drm_direct_show_buffer), GFP_KERNEL);
224 if (!create_buffer)
225 return -ENOMEM;
226 create_buffer->width = w;
227 create_buffer->height = h;
228 create_buffer->pixel_format = rk_flinger_HAL_format_to_DRM(f);
229 create_buffer->flag = ROCKCHIP_BO_CONTIG;
230
231 ret = rockchip_drm_direct_show_alloc_buffer(flg->drm_dev, create_buffer);
232 if (ret)
233 VEHICLE_DGERR("error: failed to alloc drm buffer\n");
234
235 VEHICLE_DG("-----creat buffer over-----\n");
236 buffer->vir_addr = create_buffer->vir_addr[0];
237 buffer->handle = create_buffer->dmabuf_fd;
238 phy_addr = create_buffer->phy_addr[0];
239 buffer->fd = create_buffer->dmabuf_fd;
240 buffer->drm_buffer = create_buffer;
241
242 buffer->rel_fence = NULL;
243 buffer->phy_addr = phy_addr;
244 buffer->rotation = 0;
245 buffer->width = w;
246 buffer->height = h;
247 buffer->stride = s;
248 buffer->format = f;
249 buffer->len = len;
250
251 return ret;
252 }
253
rk_flinger_free_buffer(struct flinger * flinger,struct graphic_buffer * buffer)254 static int rk_flinger_free_buffer(struct flinger *flinger,
255 struct graphic_buffer *buffer)
256 {
257 if (!flinger)
258 return -ENODEV;
259
260 if (!buffer)
261 return -EINVAL;
262
263 if (buffer->drm_buffer)
264 rockchip_drm_direct_show_free_buffer(flinger->drm_dev,
265 buffer->drm_buffer);
266
267 return 0;
268 }
269
rk_flinger_create_worker(struct flinger * flinger)270 static int rk_flinger_create_worker(struct flinger *flinger)
271 {
272 struct workqueue_struct *wq = NULL;
273
274 wq = create_singlethread_workqueue("flinger-render");
275 if (!wq) {
276 VEHICLE_DGERR("wzqtest Failed to create flinger workqueue\n");
277 return -ENODEV;
278 }
279 flinger->render_workqueue = wq;
280
281 return 0;
282 }
283
rk_flinger_destroy_worker(struct flinger * flinger)284 static int rk_flinger_destroy_worker(struct flinger *flinger)
285 {
286 if (!flinger)
287 return -ENODEV;
288
289 if (flinger->render_workqueue)
290 destroy_workqueue(flinger->render_workqueue);
291
292 return 0;
293 }
294
vehicle_flinger_parse_dt(struct flinger * flinger)295 static int vehicle_flinger_parse_dt(struct flinger *flinger)
296 {
297 struct device *dev = flinger->dev;
298
299 if (of_property_read_string(dev->of_node, "vehicle,crtc_name", &flinger->crtc_name)) {
300 dev_info(dev, "%s: get crtc_name failed, use default!\n", __func__);
301 flinger->crtc_name = "video_port3";
302 } else {
303 dev_info(dev, "%s: get crtc name from dts, crtc-name = %s\n",
304 __func__, flinger->crtc_name);
305 }
306
307 if (of_property_read_string(dev->of_node, "vehicle,plane_name", &flinger->plane_name)) {
308 dev_info(dev, "%s: get crtc_name failed, use default!\n", __func__);
309 flinger->plane_name = "Esmart3-win0";
310 } else {
311 dev_info(dev, "%s: get crtc name from dts, crtc-name = %s\n",
312 __func__, flinger->plane_name);
313 }
314
315 return 0;
316 }
317
vehicle_flinger_init(struct device * dev,struct vehicle_cfg * v_cfg)318 int vehicle_flinger_init(struct device *dev, struct vehicle_cfg *v_cfg)
319 {
320 struct graphic_buffer *buffer;
321 struct flinger *flg = NULL;
322 int i, ret, w, h, s, f;
323 static bool inited;
324
325 if (inited)
326 return 0;
327
328 VEHICLE_INFO("%s: v_cfg->rotate_mirror(0x%x)\n", __func__, v_cfg->rotate_mirror);
329
330 // if (FORCE_ROTATION == RGA_TRANSFORM_ROT_270 || FORCE_ROTATION == RGA_TRANSFORM_ROT_90) {
331 if ((v_cfg->rotate_mirror & RGA_TRANSFORM_ROT_MASK) == 0x01 ||
332 (v_cfg->rotate_mirror & RGA_TRANSFORM_ROT_MASK) == 0x04) {
333 w = FORCE_WIDTH;
334 h = ALIGN(FORCE_HEIGHT, 64);
335 s = ALIGN(FORCE_HEIGHT, 64);
336 f = FORCE_FORMAT;
337 } else {
338 w = ALIGN(FORCE_WIDTH, 64);
339 h = FORCE_HEIGHT;
340 s = ALIGN(FORCE_STRIDE, 64);
341 f = FORCE_FORMAT;
342 }
343
344 flg = kzalloc(sizeof(*flg), GFP_KERNEL);
345 if (!flg) {
346 VEHICLE_DGERR("flinger is NULL\n");
347 return -ENOMEM;
348 }
349
350 if (!flg->drm_dev)
351 flg->drm_dev = rockchip_drm_get_dev();
352 if (!flg->drm_dev) {
353 VEHICLE_DGERR("------drm device is not ready!!!-----\n");
354 kfree(flg);
355 return -ENODEV;
356 }
357
358 mutex_init(&flg->queue_buffer_lock);
359 mutex_init(&flg->source_buffer_lock);
360 mutex_init(&flg->target_buffer_lock);
361 INIT_LIST_HEAD(&flg->queue_buffer_list);
362 init_waitqueue_head(&flg->worker_wait);
363 atomic_set(&flg->worker_cond_atomic, 0);
364 atomic_set(&flg->worker_running_atomic, 1);
365
366 for (i = 0; i < NUM_SOURCE_BUFFERS; i++) {
367 flg->source_buffer[i].handle = 0;
368 flg->source_buffer[i].phy_addr = 0;
369 flg->source_buffer[i].fd = -1;
370 }
371 for (i = 0; i < NUM_TARGET_BUFFERS; i++) {
372 flg->target_buffer[i].phy_addr = 0;
373 flg->target_buffer[i].handle = 0;
374 flg->target_buffer[i].fd = -1;
375 }
376
377 for (i = 0; i < NUM_SOURCE_BUFFERS; i++) {
378 buffer = &(flg->source_buffer[i]);
379 ret = rk_flinger_alloc_buffer(flg, buffer, w, h, s, f);
380 if (ret) {
381 VEHICLE_DGERR("rk_flinger alloc src buffer failed(%d)\n",
382 ret);
383 goto free_dst_alloc;
384 }
385 buffer->state = FREE;
386 }
387 for (i = 0; i < NUM_TARGET_BUFFERS; i++) {
388 buffer = &(flg->target_buffer[i]);
389 // f = HAL_PIXEL_FORMAT_RGBX_8888;
390 // if (FORCE_ROTATION == RGA_TRANSFORM_ROT_270 ||
391 // FORCE_ROTATION == RGA_TRANSFORM_ROT_90)
392 if ((v_cfg->rotate_mirror & RGA_TRANSFORM_ROT_MASK) == 0x01 ||
393 (v_cfg->rotate_mirror & RGA_TRANSFORM_ROT_MASK) == 0x04)
394 ret = rk_flinger_alloc_buffer(flg, buffer, h, w, s, f);
395 else
396 ret = rk_flinger_alloc_buffer(flg, buffer, w, h, s, f);
397 // ret = rk_flinger_alloc_buffer(flg, buffer, w, h, s, f);
398 if (ret) {
399 VEHICLE_DGERR("rk_flinger alloc dst buffer failed\n");
400 goto free_src_alloc;
401 }
402 buffer->state = FREE;
403 }
404
405 ret = rk_flinger_create_worker(flg);
406 if (ret) {
407 VEHICLE_DGERR("rk_flinger create worker failed\n");
408 goto free_dst_alloc;
409 }
410 flinger = flg;
411
412 memcpy(&flg->v_cfg, v_cfg, sizeof(struct vehicle_cfg));
413 rk_flinger_queue_work(flg, NULL);
414 flg->dev = dev;
415
416 ret = vehicle_flinger_parse_dt(flg);
417 if (ret) {
418 VEHICLE_DGERR("vehicle flinger parse dts failed\n");
419 goto free_dst_alloc;
420 }
421
422 VEHICLE_INFO("vehicle flinger init ok\n");
423 inited = true;
424
425 return 0;
426 free_dst_alloc:
427 for (i = 0; i < NUM_TARGET_BUFFERS; i++)
428 rk_flinger_free_buffer(flg, &(flg->target_buffer[i]));
429
430 free_src_alloc:
431 for (i = 0; i < NUM_SOURCE_BUFFERS; i++)
432 rk_flinger_free_buffer(flg, &(flg->source_buffer[i]));
433
434 return -EINVAL;
435 }
vehicle_flinger_deinit(void)436 __maybe_unused int vehicle_flinger_deinit(void)
437 {
438 struct flinger *flg = flinger;
439 int i;
440
441 if (!flg)
442 return -ENODEV;
443
444 atomic_set(&flg->worker_running_atomic, 0);
445 atomic_inc(&flg->worker_cond_atomic);
446 wake_up(&flg->worker_wait);
447 flush_work(&flg->render_work);
448 flush_workqueue(flg->render_workqueue);
449 rk_flinger_destroy_worker(flg);
450
451 flinger = NULL;
452 for (i = 0; i < NUM_SOURCE_BUFFERS; i++)
453 rk_flinger_free_buffer(flg, &flg->source_buffer[i]);
454
455 for (i = 0; i < NUM_TARGET_BUFFERS; i++)
456 rk_flinger_free_buffer(flg, &flg->target_buffer[i]);
457
458 kfree(flg);
459
460 return 0;
461 }
462
rk_flinger_format_hal_to_rga(int format)463 static int rk_flinger_format_hal_to_rga(int format)
464 {
465 int rga_format = -1;
466
467 switch (format) {
468 case HAL_PIXEL_FORMAT_RGB_565:
469 rga_format = RGA_FORMAT_RGB_565;
470 break;
471 case HAL_PIXEL_FORMAT_RGB_888:
472 rga_format = RGA_FORMAT_RGB_888;
473 break;
474 case HAL_PIXEL_FORMAT_RGBA_8888:
475 rga_format = RGA_FORMAT_RGBA_8888;
476 break;
477 case HAL_PIXEL_FORMAT_RGBX_8888:
478 rga_format = RGA_FORMAT_RGBX_8888;
479 break;
480 case HAL_PIXEL_FORMAT_BGRA_8888:
481 rga_format = RGA_FORMAT_BGRA_8888;
482 break;
483 case HAL_PIXEL_FORMAT_YCrCb_NV12:
484 rga_format = RGA_FORMAT_YCrCb_420_SP;
485 break;
486 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
487 rga_format = RGA_FORMAT_YCbCr_422_SP;
488 break;
489 default:
490 break;
491 }
492
493 return rga_format;
494 }
495
rk_flinger_set_rect(struct rect * rect,int x,size_t y,int w,int h,int s,int f)496 static int rk_flinger_set_rect(struct rect *rect, int x, size_t y,
497 int w, int h, int s, int f)
498 {
499 if (!rect)
500 return -EINVAL;
501
502 rect->x = x;
503 rect->y = y;
504 rect->w = w;
505 rect->h = h;
506 rect->s = s;
507 rect->f = f;
508
509 return 0;
510 }
511
512 static int
rk_flinger_set_buffer_rotation(struct graphic_buffer * buffer,int r)513 rk_flinger_set_buffer_rotation(struct graphic_buffer *buffer, int r)
514 {
515 if (!buffer)
516 return -EINVAL;
517
518 buffer->rotation = r;
519
520 return buffer->rotation;
521 }
522
523 static int
rk_flinger_cacultae_dst_rect_by_rotation(struct graphic_buffer * buffer)524 rk_flinger_cacultae_dst_rect_by_rotation(struct graphic_buffer *buffer)
525 {
526 struct rect *src_rect, *dst_rect;
527
528 if (!buffer)
529 return -EINVAL;
530
531 src_rect = &buffer->src;
532 dst_rect = &buffer->dst;
533
534 switch (buffer->rotation & RGA_TRANSFORM_ROT_MASK) {
535 case RGA_TRANSFORM_ROT_90:
536 case RGA_TRANSFORM_ROT_270:
537 dst_rect->x = src_rect->x;
538 dst_rect->y = src_rect->y;
539 dst_rect->h = src_rect->w;
540 dst_rect->w = src_rect->h;
541 dst_rect->s = src_rect->h;
542 break;
543 case RGA_TRANSFORM_ROT_0:
544 case RGA_TRANSFORM_ROT_180:
545 case RGA_TRANSFORM_FLIP_H:
546 case RGA_TRANSFORM_FLIP_V:
547 default:
548 dst_rect->x = src_rect->x;
549 dst_rect->y = src_rect->y;
550 dst_rect->w = src_rect->w;
551 dst_rect->h = src_rect->h;
552 dst_rect->s = src_rect->s;
553 break;
554 }
555
556 return 0;
557 }
558
rk_flinger_fill_buffer_rects(struct graphic_buffer * buffer,struct rect * src_rect,struct rect * dst_rect)559 static int rk_flinger_fill_buffer_rects(struct graphic_buffer *buffer,
560 struct rect *src_rect,
561 struct rect *dst_rect)
562 {
563 if (!buffer)
564 return -EINVAL;
565
566 if (src_rect)
567 memcpy(&buffer->src, src_rect, sizeof(struct rect));
568 if (dst_rect)
569 memcpy(&buffer->dst, dst_rect, sizeof(struct rect));
570
571 return 0;
572 }
573
rk_flinger_iep_deinterlace(struct flinger * flinger,struct graphic_buffer * src_buffer,struct graphic_buffer * dst_buffer)574 static int rk_flinger_iep_deinterlace(struct flinger *flinger,
575 struct graphic_buffer *src_buffer,
576 struct graphic_buffer *dst_buffer)
577 {
578 struct rga_req rga_request;
579 int ret;
580
581 memset(&rga_request, 0, sizeof(rga_request));
582
583 if (!src_buffer || !dst_buffer)
584 return -EINVAL;
585
586 rga_request.rotate_mode = 0;
587 rga_request.sina = 0;
588 rga_request.cosa = 0;
589
590 rga_request.src.act_w = src_buffer->src.w;
591 rga_request.src.act_h = src_buffer->src.h;
592 rga_request.src.x_offset = 0;
593 rga_request.src.y_offset = 0;
594 rga_request.src.vir_w = src_buffer->src.w;
595 rga_request.src.vir_h = src_buffer->src.h;
596 rga_request.src.yrgb_addr = src_buffer->fd;
597 rga_request.src.uv_addr = 0;
598 rga_request.src.v_addr = 0;
599 rga_request.src.format = RGA_FORMAT_YCrCb_420_SP;
600 if (src_buffer->rotation == RGA_TRANSFORM_ROT_0 ||
601 src_buffer->rotation == RGA_TRANSFORM_ROT_180) {
602 rga_request.dst.act_w = src_buffer->src.w;
603 rga_request.dst.act_h = src_buffer->src.h / 2;
604 rga_request.dst.vir_w = src_buffer->src.w;
605 rga_request.dst.vir_h = src_buffer->src.h / 2;
606 } else {
607 rga_request.dst.act_w = src_buffer->src.w / 2;
608 rga_request.dst.act_h = src_buffer->src.h;
609 rga_request.dst.vir_w = src_buffer->src.w / 2;
610 rga_request.dst.vir_h = src_buffer->src.h;
611 }
612 rga_request.dst.x_offset = 0;
613 rga_request.dst.y_offset = 0;
614
615 rga_request.dst.yrgb_addr = dst_buffer->fd;
616 rga_request.dst.uv_addr = 0;
617 rga_request.dst.v_addr = 0;
618 rga_request.dst.format = RGA_FORMAT_YCrCb_420_SP;
619
620 rga_request.scale_mode = 1;
621
622 rga_request.mmu_info.mmu_en = 1;
623 rga_request.mmu_info.mmu_flag = ((2 & 0x3) << 4) |
624 1 | (1 << 31 | 1 << 8 | 1 << 10);
625
626 rga_request.src.rd_mode = RGA_RASTER_MODE;
627 rga_request.dst.rd_mode = RGA_RASTER_MODE;
628
629 ret = rga_kernel_commit(&rga_request);
630 if (ret)
631 VEHICLE_DGERR("RGA_BLIT_SYNC failed(%d)\n", ret);
632
633 dst_buffer->width = src_buffer->width;
634 dst_buffer->height = src_buffer->height;
635 dst_buffer->src.f = src_buffer->src.f;
636
637 if (src_buffer->rotation == RGA_TRANSFORM_ROT_0 ||
638 src_buffer->rotation == RGA_TRANSFORM_ROT_180) {
639 dst_buffer->src.w = src_buffer->src.w;
640 dst_buffer->src.h = src_buffer->src.h / 2;
641 } else {
642 dst_buffer->src.w = src_buffer->src.w / 2;
643 dst_buffer->src.h = src_buffer->src.h;
644 }
645 dst_buffer->src.x = 0;
646 dst_buffer->src.y = 0;
647
648 src_buffer->state = FREE;
649
650 return 0;
651 }
652
rk_flinger_rga_scaler(struct flinger * flinger,struct graphic_buffer * src_buffer,struct graphic_buffer * dst_buffer)653 static int rk_flinger_rga_scaler(struct flinger *flinger,
654 struct graphic_buffer *src_buffer,
655 struct graphic_buffer *dst_buffer)
656 {
657 struct rga_req rga_request;
658 int ret;
659
660 memset(&rga_request, 0, sizeof(rga_request));
661
662 if (!src_buffer || !dst_buffer)
663 return -EINVAL;
664
665 rga_request.rotate_mode = 0;
666 rga_request.sina = 0;
667 rga_request.cosa = 0;
668
669 rga_request.yuv2rgb_mode = 0x0 << 0; // yuvtoyuv config 0
670 /* yuv to rgb color space transform if need */
671 //rga_request.yuv2rgb_mode = 0x1 << 0; // limit range
672 //rga_request.yuv2rgb_mode = 0x2 << 0; // full range
673
674 rga_request.src.act_w = src_buffer->src.w;
675 rga_request.src.act_h = src_buffer->src.h;
676 rga_request.src.x_offset = 0;
677 rga_request.src.y_offset = 0;
678 rga_request.src.vir_w = src_buffer->src.w;
679 rga_request.src.vir_h = src_buffer->src.h;
680 rga_request.src.yrgb_addr = src_buffer->fd;
681 rga_request.src.uv_addr = 0;
682 rga_request.src.v_addr = 0;
683 rga_request.src.format = RGA_FORMAT_YCrCb_420_SP;
684
685 rga_request.dst.act_w = dst_buffer->width;
686 rga_request.dst.act_h = dst_buffer->height;
687 rga_request.dst.x_offset = 0;
688 rga_request.dst.y_offset = 0;
689 rga_request.dst.vir_w = dst_buffer->width;
690 rga_request.dst.vir_h = dst_buffer->height;
691 rga_request.dst.yrgb_addr = dst_buffer->fd;
692 rga_request.dst.uv_addr = 0;
693 rga_request.dst.v_addr = 0;
694 rga_request.dst.format = RGA_FORMAT_YCrCb_420_SP;
695
696 rga_request.scale_mode = 1;
697
698 rga_request.mmu_info.mmu_en = 1;
699 rga_request.mmu_info.mmu_flag = ((2 & 0x3) << 4) |
700 1 | (1 << 31 | 1 << 8 | 1 << 10);
701
702 rga_request.src.rd_mode = RGA_RASTER_MODE;
703 rga_request.dst.rd_mode = RGA_RASTER_MODE;
704
705 ret = rga_kernel_commit(&rga_request);
706 if (ret)
707 VEHICLE_DGERR("RGA_BLIT_SYNC failed(%d)\n", ret);
708
709 dst_buffer->src.f = dst_buffer->format;
710 dst_buffer->src.w = dst_buffer->width;
711 dst_buffer->src.h = dst_buffer->height;
712 dst_buffer->src.x = 0;
713 dst_buffer->src.y = 0;
714 /* save rga in buffer */
715 if (vehicle_dump_rga) {
716 struct file *filep = NULL;
717 loff_t pos = 0;
718 static bool file_ready;
719 static int frame_count;
720
721 VEHICLE_DG("@%s src->vir_addr[0](%d) addr[100](%d)\n",
722 __func__, ((char *)(src_buffer->vir_addr))[0],
723 ((char *)(src_buffer->vir_addr))[100]);
724 if (!file_ready) {
725 int frame_len = src_buffer->src.w * src_buffer->src.h * 3 / 2;
726 char path[128] = {0};
727 mm_segment_t fs;
728
729 VEHICLE_DG("save vop frame(%d) frame_len(%d)\n",
730 frame_count++, frame_len);
731 sprintf(path, "/data/rga_scaler_in_%zu_%zu.yuv",
732 src_buffer->src.w, src_buffer->src.h);
733 filep = filp_open(path, O_CREAT | O_RDWR, 0666);
734 if (IS_ERR(filep)) {
735 VEHICLE_DGERR(" %s filp_open failed!\n", path);
736 file_ready = false;
737 } else {
738 fs = get_fs();
739 set_fs(KERNEL_DS);
740 vfs_write(filep,
741 (unsigned char __user *)(src_buffer->vir_addr),
742 frame_len, &pos);
743 filp_close(filep, NULL);
744 set_fs(fs);
745 VEHICLE_INFO(" %s file saved ok!\n", path);
746 file_ready = true;
747 }
748 }
749 }
750 /* save rga out buffer */
751 if (vehicle_dump_rga) {
752 struct file *filep = NULL;
753 loff_t pos = 0;
754 static bool file_ready;
755 static int frame_count;
756
757 VEHICLE_DG("@%s dst->vir_addr[0](%d) addr[100](%d)\n",
758 __func__, ((char *)(dst_buffer->vir_addr))[0],
759 ((char *)(dst_buffer->vir_addr))[100]);
760 if (!file_ready) {
761 /* NV12 */
762 int frame_len = dst_buffer->src.w * dst_buffer->src.h * 3 / 2;
763 char path[128] = {0};
764 mm_segment_t fs;
765
766 VEHICLE_DG("save vop frame(%d) frame_len(%d)\n",
767 frame_count++, frame_len);
768 sprintf(path, "/data/rga_scaler_out_%zu_%zu.yuv",
769 dst_buffer->src.w, dst_buffer->src.h);
770 filep = filp_open(path, O_CREAT | O_RDWR, 0666);
771 if (IS_ERR(filep)) {
772 VEHICLE_DGERR(" %s filp_open failed!\n", path);
773 file_ready = false;
774 } else {
775 fs = get_fs();
776 set_fs(KERNEL_DS);
777 vfs_write(filep,
778 (unsigned char __user *)(dst_buffer->vir_addr),
779 frame_len, &pos);
780 filp_close(filep, NULL);
781 set_fs(fs);
782 VEHICLE_INFO(" %s file saved ok!\n", path);
783 file_ready = true;
784 }
785 }
786 }
787
788 src_buffer->state = FREE;
789
790 return 0;
791 }
792
rk_flinger_rga_blit(struct flinger * flinger,struct graphic_buffer * src_buffer,struct graphic_buffer * dst_buffer)793 static int rk_flinger_rga_blit(struct flinger *flinger,
794 struct graphic_buffer *src_buffer,
795 struct graphic_buffer *dst_buffer)
796 {
797 struct rga_req rga_request;
798 int sx, sy, sw, sh, ss, sf;
799 int dx, dy, dw, dh, ds, df;
800 int orientation;
801 int ret;
802 int src_fd, dst_fd;
803
804 if (!src_buffer || !dst_buffer)
805 return -EINVAL;
806
807 src_fd = src_buffer->fd;
808 dst_fd = dst_buffer->fd;
809
810 memset(&rga_request, 0, sizeof(rga_request));
811
812 orientation = src_buffer->rotation;
813 dst_buffer->rotation = src_buffer->rotation;
814
815 sx = src_buffer->src.x;
816 sy = src_buffer->src.y;
817 sw = src_buffer->src.w;
818 ss = src_buffer->src.s;
819 sh = src_buffer->src.h;
820 sf = rk_flinger_format_hal_to_rga(src_buffer->src.f);
821 VEHICLE_DG("%s src: sx:%d, sy:%d, sw:%d, ss:%d, sh:%d\n",
822 __func__, sx, sy, sw, ss, sh);
823 dx = src_buffer->dst.x;
824 dy = src_buffer->dst.y;
825 dw = src_buffer->dst.w;
826 ds = src_buffer->dst.s;
827 dh = src_buffer->dst.h;
828 df = rk_flinger_format_hal_to_rga(src_buffer->dst.f);
829 VEHICLE_DG("%s dst: dx:%d, dy:%d, dw:%d, ds:%d, dh:%d\n",
830 __func__, dx, dy, dw, ds, dh);
831 if (src_buffer->offset) {
832 sh += src_buffer->offset / src_buffer->len * sh;
833 sx = src_buffer->offset / src_buffer->len * sh;
834 src_fd = 0;
835 }
836 VEHICLE_DG("%s src: sx:%d, sy:%d, sw:%d, ss:%d, sh:%d\n",
837 __func__, sx, sy, sw, ss, sh);
838 switch (orientation) {
839 case RGA_TRANSFORM_ROT_0:
840 rga_request.rotate_mode = 0;
841 rga_request.sina = 0;
842 rga_request.cosa = 0;
843 rga_request.dst.vir_w = ds;
844 rga_request.dst.vir_h = dh;
845 rga_request.dst.act_w = dw;
846 rga_request.dst.act_h = dh;
847 rga_request.dst.x_offset = 0;
848 rga_request.dst.y_offset = 0;
849 break;
850 case RGA_TRANSFORM_FLIP_H:/*x mirror*/
851 rga_request.rotate_mode = 2;
852 rga_request.dst.vir_w = ds;
853 rga_request.dst.vir_h = dh;
854 rga_request.dst.act_w = dw;
855 rga_request.dst.act_h = dh;
856 rga_request.dst.x_offset = 0;
857 rga_request.dst.y_offset = 0;
858 break;
859 case RGA_TRANSFORM_FLIP_V:/*y mirror*/
860 rga_request.rotate_mode = 3;
861 rga_request.dst.vir_w = ds;
862 rga_request.dst.vir_h = dh;
863 rga_request.dst.act_w = dw;
864 rga_request.dst.act_h = dh;
865 rga_request.dst.x_offset = 0;
866 rga_request.dst.y_offset = 0;
867 break;
868 case RGA_TRANSFORM_ROT_90:
869 rga_request.rotate_mode = 1;
870 rga_request.sina = 65536;
871 rga_request.cosa = 0;
872 rga_request.dst.vir_w = ds;
873 rga_request.dst.vir_h = dh;
874 rga_request.dst.act_w = dh;
875 rga_request.dst.act_h = dw;
876 rga_request.dst.x_offset = 0;
877 rga_request.dst.y_offset = 0;
878 break;
879 case RGA_TRANSFORM_ROT_180:
880 rga_request.rotate_mode = 1;
881 rga_request.sina = 0;
882 rga_request.cosa = -65536;
883 rga_request.dst.vir_w = ds;
884 rga_request.dst.vir_h = dh;
885 rga_request.dst.act_w = dw;
886 rga_request.dst.act_h = dh;
887 rga_request.dst.x_offset = 0;
888 rga_request.dst.y_offset = 0;
889 break;
890 case RGA_TRANSFORM_ROT_270:
891 rga_request.rotate_mode = 1;
892 rga_request.sina = -65536;
893 rga_request.cosa = 0;
894 rga_request.dst.vir_w = ds;
895 rga_request.dst.vir_h = dh;
896 rga_request.dst.act_w = dh;
897 rga_request.dst.act_h = dw;
898 rga_request.dst.x_offset = 0;
899 rga_request.dst.y_offset = 0;
900 break;
901 default:
902 rga_request.rotate_mode = 0;
903 rga_request.sina = 0;
904 rga_request.cosa = 0;
905 rga_request.dst.vir_w = ds;
906 rga_request.dst.vir_h = dh;
907 rga_request.dst.act_w = dw;
908 rga_request.dst.act_h = dh;
909 rga_request.dst.x_offset = 0;
910 rga_request.dst.y_offset = 0;
911 break;
912 }
913
914 rga_request.src.yrgb_addr = src_fd;
915 rga_request.src.uv_addr = 0;
916 rga_request.src.v_addr = 0;
917
918 rga_request.dst.yrgb_addr = dst_fd;
919 rga_request.dst.uv_addr = 0;
920 rga_request.dst.v_addr = 0;
921
922 rga_request.src.vir_w = ss;
923 rga_request.src.vir_h = sh;
924 rga_request.src.format = sf;
925 rga_request.src.act_w = sw;
926 rga_request.src.act_h = sh;
927 rga_request.src.x_offset = 0;
928 rga_request.src.y_offset = 0;
929
930 rga_request.dst.format = df;
931
932 rga_request.clip.xmin = 0;
933 rga_request.clip.xmax = dw - 1;
934 rga_request.clip.ymin = 0;
935 rga_request.clip.ymax = dh - 1;
936 rga_request.scale_mode = 0;
937
938 rga_request.yuv2rgb_mode = 0x0 << 0; // yuvtoyuv config 0
939 /* yuv to rgb color space transform if need */
940 //rga_request.yuv2rgb_mode = 0x1 << 0; // limit range
941 //rga_request.yuv2rgb_mode = 0x2 << 0; // full range
942
943 rga_request.mmu_info.mmu_en = 1;
944 rga_request.mmu_info.mmu_flag = ((2 & 0x3) << 4) |
945 1 | (1 << 31 | 1 << 8 | 1 << 10);
946
947 rga_request.src.rd_mode = RGA_RASTER_MODE;
948 rga_request.dst.rd_mode = RGA_RASTER_MODE;
949
950 VEHICLE_DG("%s src_buffer->src.f(%zu) src_buffer->dst.f(%zu)",
951 __func__, src_buffer->src.f, src_buffer->dst.f);
952 ret = rga_kernel_commit(&rga_request);
953 if (ret)
954 VEHICLE_DGERR("RGA_BLIT_SYNC failed(%d)\n", ret);
955
956 return 0;
957 }
958
rk_flinger_rga_render(struct flinger * flinger,struct graphic_buffer * src_buffer,struct graphic_buffer * dst_buffer,struct graphic_buffer * tmp_buffer)959 static int rk_flinger_rga_render(struct flinger *flinger,
960 struct graphic_buffer *src_buffer,
961 struct graphic_buffer *dst_buffer,
962 struct graphic_buffer *tmp_buffer)
963 {
964 int rotation;
965
966 if (!flinger || !src_buffer || !dst_buffer)
967 return -EINVAL;
968
969 if (dst_buffer && dst_buffer->rel_fence)
970 dst_buffer->rel_fence = NULL;
971
972 if ((src_buffer->rotation & RGA_TRANSFORM_ROT_MASK) &&
973 (src_buffer->rotation & RGA_TRANSFORM_FLIP_MASK)) {
974
975 rotation = flinger->v_cfg.rotate_mirror;
976 /* 1. rotate */
977 src_buffer->rotation = rotation & RGA_TRANSFORM_ROT_MASK;
978 rk_flinger_rga_blit(flinger, src_buffer, tmp_buffer);
979 rk_flinger_fill_buffer_rects(tmp_buffer, &src_buffer->dst,
980 &src_buffer->dst);
981 tmp_buffer->src.f = src_buffer->dst.f;
982 tmp_buffer->rotation = rotation & RGA_TRANSFORM_FLIP_MASK;
983 /* 2. mirror */
984 rk_flinger_rga_blit(flinger, tmp_buffer, dst_buffer);
985 rk_flinger_fill_buffer_rects(dst_buffer, &tmp_buffer->dst,
986 &tmp_buffer->dst);
987 dst_buffer->src.f = src_buffer->dst.f;
988
989 src_buffer->rotation = rotation;
990 } else {
991 rk_flinger_rga_blit(flinger, src_buffer, dst_buffer);
992 rk_flinger_fill_buffer_rects(dst_buffer, &src_buffer->dst,
993 &src_buffer->dst);
994 dst_buffer->src.f = src_buffer->dst.f;
995 }
996 /* save rga out buffer */
997 if (vehicle_dump_rga) {
998 struct file *filep = NULL;
999 loff_t pos = 0;
1000 static bool file_ready;
1001 static int frame_count;
1002
1003 VEHICLE_DG("@%s dst->vir_addr[0](%d) addr[100](%d)\n",
1004 __func__, ((char *)(dst_buffer->vir_addr))[0],
1005 ((char *)(dst_buffer->vir_addr))[100]);
1006 if (!file_ready) {
1007 int frame_len = dst_buffer->src.w * dst_buffer->src.h * 3 / 2;//NV12
1008 char path[128] = {0};
1009 mm_segment_t fs;
1010
1011 VEHICLE_DG("save vop frame(%d) frame_len(%d)\n",
1012 frame_count++, frame_len);
1013 sprintf(path, "/data/rga_render_%zu_%zu.yuv",
1014 dst_buffer->src.w, dst_buffer->src.h);
1015 filep = filp_open(path, O_CREAT | O_RDWR, 0666);
1016 if (IS_ERR(filep)) {
1017 VEHICLE_DGERR(" %s filp_open failed!\n", path);
1018 file_ready = false;
1019 } else {
1020 fs = get_fs();
1021 set_fs(KERNEL_DS);
1022 vfs_write(filep,
1023 (unsigned char __user *)(dst_buffer->vir_addr),
1024 frame_len, &pos);
1025 filp_close(filep, NULL);
1026 set_fs(fs);
1027 VEHICLE_INFO(" %s file saved ok!\n", path);
1028 file_ready = true;
1029 }
1030 }
1031 }
1032
1033 return 0;
1034 }
1035
rk_drm_vehicle_commit(struct flinger * flinger,struct graphic_buffer * buffer)1036 static void rk_drm_vehicle_commit(struct flinger *flinger, struct graphic_buffer *buffer)
1037 {
1038 struct rockchip_drm_direct_show_commit_info commit_info;
1039 int hdisplay = flinger->crtc->state->adjusted_mode.hdisplay;
1040 int vdisplay = flinger->crtc->state->adjusted_mode.vdisplay;
1041
1042 commit_info.crtc = flinger->crtc;
1043 commit_info.plane = flinger->plane;
1044
1045 commit_info.src_x = 0;
1046 commit_info.src_y = 0;
1047 commit_info.src_w = buffer->src.w;
1048 commit_info.src_h = buffer->src.h;
1049 // commit_info.src_w = buffer->drm_buffer->width;
1050 // commit_info.src_h = buffer->drm_buffer->height;
1051
1052 /*center display*/
1053 // commit_info.dst_x = (hdisplay - BUFFER_WIDTH) / 2;
1054 // commit_info.dst_y = (vdisplay - BUFFER_HEIGHT) / 2;
1055 // commit_info.dst_w = commit_info.src_w;
1056 // commit_info.dst_h = commit_info.src_h;
1057
1058 /*full screen display */
1059 commit_info.dst_x = 0;
1060 commit_info.dst_y = 0;
1061 commit_info.dst_w = hdisplay;
1062 commit_info.dst_h = vdisplay;
1063
1064 commit_info.top_zpos = true;
1065
1066 commit_info.buffer = buffer->drm_buffer;
1067
1068 if (vehicle_dump_vop) {
1069 struct file *filep = NULL;
1070 loff_t pos = 0;
1071 static bool file_ready;
1072 static int frame_count;
1073
1074 if (!file_ready) {
1075 int frame_len = buffer->drm_buffer->width *
1076 buffer->drm_buffer->height * 3 / 2;//NV12
1077 char path[128] = {0};
1078 mm_segment_t fs;
1079
1080 VEHICLE_DG("save vop frame(%d) frame_len(%d)\n",
1081 frame_count++, frame_len);
1082 sprintf(path, "/data/vop_commit_%d_%d.yuv",
1083 buffer->drm_buffer->width,
1084 buffer->drm_buffer->height);
1085 filep = filp_open(path, O_CREAT | O_RDWR, 0666);
1086 if (IS_ERR(filep)) {
1087 VEHICLE_DGERR(" %s filp_open failed!\n", path);
1088 file_ready = false;
1089 } else {
1090 fs = get_fs();
1091 set_fs(KERNEL_DS);
1092 vfs_write(filep,
1093 (unsigned char __user *)(buffer->drm_buffer->vir_addr[0]),
1094 frame_len, &pos);
1095 filp_close(filep, NULL);
1096 set_fs(fs);
1097 VEHICLE_INFO(" %s file saved ok!\n", path);
1098 file_ready = true;
1099 }
1100 }
1101 }
1102 rockchip_drm_direct_show_commit(flinger->drm_dev, &commit_info);
1103 }
1104
1105 static int drop_frames_number;
rk_flinger_vop_show(struct flinger * flinger,struct graphic_buffer * buffer)1106 static int rk_flinger_vop_show(struct flinger *flinger,
1107 struct graphic_buffer *buffer)
1108 {
1109 if (!flinger || !buffer)
1110 return -EINVAL;
1111
1112 VEHICLE_DG("flinger vop show buffer wxh(%zux%zu)\n",
1113 buffer->src.w, buffer->src.h);
1114 if (drop_frames_number > 0) {
1115 VEHICLE_INFO("%s discard the frame num(%d)!\n", __func__, drop_frames_number);
1116 drop_frames_number--;
1117 return 0;
1118 }
1119
1120 if (!flinger->running)
1121 return 0;
1122
1123 /* get crtc and plane */
1124 flinger->crtc = rockchip_drm_direct_show_get_crtc(flinger->drm_dev, flinger->crtc_name);
1125 if (flinger->crtc == NULL) {
1126 VEHICLE_DGERR("error: failed to get crtc\n");
1127 return -EINVAL;
1128 }
1129
1130 flinger->plane = rockchip_drm_direct_show_get_plane(flinger->drm_dev, flinger->plane_name);
1131 if (flinger->plane == NULL) {
1132 VEHICLE_DGERR("error: failed to get plane\n");
1133 return -EINVAL;
1134 }
1135
1136 rk_drm_vehicle_commit(flinger, buffer);
1137
1138 flinger->debug_vop_count++;
1139 /* save vop show buffer */
1140 if (vehicle_dump_vop) {
1141 struct file *filep = NULL;
1142 loff_t pos = 0;
1143 static bool file_ready;
1144 static int frame_count;
1145
1146 VEHICLE_DG("@%s buffer->vir_addr[0](%d) addr[100](%d)\n",
1147 __func__, ((char *)(buffer->vir_addr))[0],
1148 ((char *)(buffer->vir_addr))[100]);
1149 if (!file_ready) {
1150 int frame_len = buffer->src.w * buffer->src.h * 3 / 2;//NV12
1151 char path[128] = {0};
1152 mm_segment_t fs;
1153
1154 VEHICLE_DG("save vop frame(%d) frame_len(%d)\n",
1155 frame_count++, frame_len);
1156 sprintf(path, "/data/vop_show_%zu_%zu.yuv",
1157 buffer->src.w, buffer->src.h);
1158 filep = filp_open(path, O_CREAT | O_RDWR, 0666);
1159 if (IS_ERR(filep)) {
1160 VEHICLE_DGERR(" %s filp_open failed!\n", path);
1161 file_ready = false;
1162 } else {
1163 fs = get_fs();
1164 set_fs(KERNEL_DS);
1165 vfs_write(filep,
1166 (unsigned char __user *)(buffer->vir_addr),
1167 frame_len, &pos);
1168 filp_close(filep, NULL);
1169 set_fs(fs);
1170 VEHICLE_INFO(" %s file saved ok!\n", path);
1171 file_ready = true;
1172 }
1173 }
1174 }
1175
1176 return 0;
1177 }
1178
rk_flinger_first_done(struct work_struct * work)1179 static void rk_flinger_first_done(struct work_struct *work)
1180 {
1181 struct graphic_buffer *buffer;
1182 struct flinger *flg = flinger;
1183 int i;
1184 struct flinger *flg_test =
1185 container_of(work, struct flinger, init_work);
1186 struct vehicle_cfg *v_cfg = &flg_test->v_cfg;
1187
1188 if (!flg)
1189 return;
1190
1191 for (i = 0; i < NUM_SOURCE_BUFFERS; i++) {
1192 if (flg->source_buffer[i].state == FREE) {
1193 buffer = &(flg->source_buffer[i]);
1194 rk_flinger_set_rect(&buffer->src,
1195 FORCE_XOFFSET, FORCE_YOFFSET,
1196 v_cfg->width, v_cfg->height,
1197 v_cfg->width, FORCE_FORMAT);
1198 rk_flinger_set_buffer_rotation(buffer, v_cfg->rotate_mirror);
1199 rk_flinger_cacultae_dst_rect_by_rotation(buffer);
1200 buffer->dst.f = buffer->src.f;
1201 VEHICLE_INFO("buffer[%d]->rotation(%d).\n",
1202 i, buffer->rotation);
1203 }
1204 }
1205 }
1206
rk_flinger_render_show(struct work_struct * work)1207 static void rk_flinger_render_show(struct work_struct *work)
1208 {
1209 struct graphic_buffer *src_buffer, *dst_buffer, *iep_buffer, *buffer;
1210 /* struct queue_buffer *cur = NULL, *next = NULL; */
1211 struct flinger *flg = flinger;
1212 int i, found = 0;
1213 static int count = -1;
1214 static int last_src_index = -1;
1215 bool cvbs_flag = true;
1216 struct flinger *flg_test =
1217 container_of(work, struct flinger, render_work);
1218 struct vehicle_cfg *v_cfg = &flg_test->v_cfg;
1219
1220 src_buffer = NULL;
1221 dst_buffer = NULL;
1222 flg->source_index = 0;
1223
1224 do {
1225 try_again:
1226 wait_event_interruptible_timeout(flg->worker_wait,
1227 atomic_read(&flg->worker_cond_atomic),
1228 msecs_to_jiffies(1000000));
1229 VEHICLE_DG("wake up enter, v_cfg.w*h(%dx%d)\n",
1230 v_cfg->width, v_cfg->height);
1231
1232 if (atomic_read(&flg->worker_running_atomic) == 0) {
1233 VEHICLE_INFO("%s loop exit\n", __func__);
1234 break;
1235 }
1236 if (atomic_read(&flg->worker_cond_atomic) <= 0) {
1237 /*printk("waiting 'worker_cond_atomic' timed out.");*/
1238 goto try_again;
1239 }
1240 atomic_dec(&flg->worker_cond_atomic);
1241
1242 /* 1. find src buffer */
1243 src_buffer = NULL;
1244 found = last_src_index + 1;
1245 for (i = 1; i < NUM_SOURCE_BUFFERS; i++, found++) {
1246 found = found % NUM_SOURCE_BUFFERS;
1247 if (flg->source_buffer[found].state == QUEUE) {
1248 src_buffer = &flg->source_buffer[found];
1249 last_src_index = found;
1250 break;
1251 }
1252 }
1253
1254 if (!src_buffer || !src_buffer->fd) {
1255 usleep_range(3000, 3100);
1256 VEHICLE_DGERR("[%s:%d] error, no buffer\n", __func__, __LINE__);
1257 goto try_again;
1258 }
1259
1260 count++;
1261 src_buffer->state = ACQUIRE;
1262 /* save rkcif buffer */
1263 if (vehicle_dump_cif) {
1264 // struct file *filep = NULL;
1265 struct file *filep;
1266 loff_t pos = 0;
1267 static bool file_ready;
1268 static int frame_count;
1269
1270 VEHICLE_DG("src_buffer->vir_addr[0](%d) addr[100](%d)\n",
1271 ((char *)(src_buffer->vir_addr))[0],
1272 ((char *)(src_buffer->vir_addr))[100]);
1273
1274 if (!file_ready) {
1275 //nv12 frame_len=w*h*3/2
1276 int frame_len = src_buffer->src.w * src_buffer->src.h * 3 / 2;
1277 char path[128] = {0};
1278 mm_segment_t fs;
1279
1280 VEHICLE_DG("save vop frame(%d) frame_len(%d)\n",
1281 frame_count++, frame_len);
1282 sprintf(path, "/data/cif_out_%zu_%zu.yuv",
1283 src_buffer->src.w, src_buffer->src.h);
1284 filep = filp_open(path, O_RDWR | O_CREAT, 0666);
1285 if (IS_ERR(filep)) {
1286 VEHICLE_DGERR(" %s filp_open failed!\n", path);
1287 file_ready = false;
1288 } else {
1289 fs = get_fs();
1290 set_fs(KERNEL_DS);
1291 vfs_write(filep, src_buffer->vir_addr, frame_len, &pos);
1292 filp_close(filep, NULL);
1293 set_fs(fs);
1294 VEHICLE_INFO(" %s file saved ok!\n", path);
1295 file_ready = true;
1296 }
1297 }
1298 }
1299
1300 /* 2. find dst buffer */
1301 dst_buffer = NULL;
1302 iep_buffer = NULL;
1303 /*get iep, rga, vop buffer*/
1304 if (1) { //rotation by rga
1305 if (flg->v_cfg.input_format == CIF_INPUT_FORMAT_PAL ||
1306 flg->v_cfg.input_format == CIF_INPUT_FORMAT_NTSC) {
1307 iep_buffer = &(flg->target_buffer
1308 [NUM_TARGET_BUFFERS - 1]);
1309 iep_buffer->state = ACQUIRE;
1310 cvbs_flag = true;
1311 } else {
1312 cvbs_flag = false;
1313 }
1314 dst_buffer = &(flg->target_buffer
1315 [count % (NUM_TARGET_BUFFERS - 1)]);
1316 dst_buffer->state = ACQUIRE;
1317 } else if (flg->v_cfg.input_format == CIF_INPUT_FORMAT_PAL ||
1318 flg->v_cfg.input_format == CIF_INPUT_FORMAT_NTSC) {
1319 iep_buffer = &(flg->target_buffer
1320 [count % NUM_TARGET_BUFFERS]);
1321 iep_buffer->state = ACQUIRE;
1322 }
1323 if (!iep_buffer || !iep_buffer->fd) {
1324 if (iep_buffer)
1325 iep_buffer->state = FREE;
1326 }
1327
1328 /* 3 do deinterlace & rotation & display*/
1329 if (!cvbs_flag) {
1330 // YPbPr
1331 VEHICLE_DG("it is ypbpr signal\n");
1332 iep_buffer = &(flg->target_buffer[NUM_TARGET_BUFFERS - 1]);
1333 iep_buffer->state = ACQUIRE;
1334 //scaler by rga to force widthxheight display
1335 rk_flinger_rga_render(flg, src_buffer, iep_buffer, dst_buffer);
1336 src_buffer->state = FREE;
1337 rk_flinger_rga_scaler(flg, iep_buffer, dst_buffer);
1338 iep_buffer->state = FREE;
1339 rk_flinger_vop_show(flg, dst_buffer);
1340 for (i = 0; i < NUM_TARGET_BUFFERS; i++) {
1341 buffer = &(flinger->target_buffer[i]);
1342 if (buffer->state == DISPLAY)
1343 buffer->state = FREE;
1344 }
1345
1346 dst_buffer->state = DISPLAY;
1347 } else {
1348 // cvbs
1349 VEHICLE_DG("it is a cvbs signal\n");
1350 rk_flinger_rga_render(flg, src_buffer, dst_buffer, iep_buffer);
1351 src_buffer->state = FREE;
1352 rk_flinger_iep_deinterlace(flg, dst_buffer, iep_buffer);
1353 dst_buffer->state = FREE;
1354 rk_flinger_rga_scaler(flg, iep_buffer, dst_buffer);
1355 rk_flinger_vop_show(flg, dst_buffer);
1356 iep_buffer->state = FREE;
1357
1358 for (i = 0; i < NUM_TARGET_BUFFERS; i++) {
1359 buffer = &(flinger->target_buffer[i]);
1360 if (buffer->state == DISPLAY)
1361 buffer->state = FREE;
1362 }
1363 dst_buffer->state = DISPLAY;
1364 }
1365 } while (1);
1366 }
1367
rk_flinger_queue_work(struct flinger * flinger,struct graphic_buffer * src_buffer)1368 static int rk_flinger_queue_work(struct flinger *flinger,
1369 struct graphic_buffer *src_buffer)
1370 {
1371 if (!flinger)
1372 return -ENODEV;
1373
1374 if (!src_buffer) {
1375 if (flinger->render_workqueue) {
1376 INIT_WORK(&flinger->init_work, rk_flinger_first_done);
1377 queue_work(flinger->render_workqueue,
1378 &flinger->init_work);
1379 }
1380 }
1381
1382 if (flinger->render_workqueue) {
1383 INIT_WORK(&flinger->render_work, rk_flinger_render_show);
1384 queue_work(flinger->render_workqueue, &flinger->render_work);
1385 }
1386
1387 return 0;
1388 }
1389
1390 static struct graphic_buffer *
rk_flinger_lookup_buffer_by_phy_addr(unsigned long phy_addr)1391 rk_flinger_lookup_buffer_by_phy_addr(unsigned long phy_addr)
1392 {
1393 struct graphic_buffer *buffer = NULL;
1394 struct flinger *flg = flinger;
1395 int i;
1396
1397 VEHICLE_DG("%s:phy_addr=%lx\n", __func__, phy_addr);
1398 for (i = 1; i < NUM_SOURCE_BUFFERS; i++) {
1399 if (flg->source_buffer[i].state == DEQUEUE) {
1400 buffer = &(flg->source_buffer[i]);
1401 if (buffer && (buffer->offset +
1402 buffer->phy_addr == phy_addr)) {
1403 buffer->state = QUEUE;
1404 break;
1405 }
1406 }
1407 }
1408 if (i < NUM_SOURCE_BUFFERS)
1409 return buffer;
1410 else
1411 return NULL;
1412 }
1413
vehicle_rotation_param_check(struct vehicle_cfg * v_cfg)1414 static bool vehicle_rotation_param_check(struct vehicle_cfg *v_cfg)
1415 {
1416 switch (v_cfg->rotate_mirror & RGA_TRANSFORM_ROT_MASK) {
1417 case RGA_TRANSFORM_ROT_90:
1418 case RGA_TRANSFORM_ROT_270:
1419 case RGA_TRANSFORM_ROT_0:
1420 case RGA_TRANSFORM_ROT_180:
1421 return true;
1422 default:
1423 VEHICLE_INFO("invalid rotate-mirror param %d\n",
1424 v_cfg->rotate_mirror);
1425 v_cfg->rotate_mirror = v_cfg->rotate_mirror & RGA_TRANSFORM_FLIP_MASK;
1426 return false;
1427 }
1428
1429 switch (v_cfg->rotate_mirror & RGA_TRANSFORM_FLIP_MASK) {
1430 case RGA_TRANSFORM_FLIP_H:
1431 case RGA_TRANSFORM_FLIP_V:
1432 return true;
1433 default:
1434 VEHICLE_INFO("invalid rotate-mirror param %d\n",
1435 v_cfg->rotate_mirror);
1436 v_cfg->rotate_mirror = v_cfg->rotate_mirror & RGA_TRANSFORM_ROT_MASK;
1437 return false;
1438 }
1439 }
vehicle_flinger_reverse_open(struct vehicle_cfg * v_cfg,bool android_is_ready)1440 int vehicle_flinger_reverse_open(struct vehicle_cfg *v_cfg,
1441 bool android_is_ready)
1442 {
1443 int i;
1444 int width;
1445 int height;
1446 struct flinger *flg = flinger;
1447 struct graphic_buffer *buffer;
1448 int hal_format;
1449
1450 width = v_cfg->width;
1451 height = v_cfg->height;
1452
1453 if (!flinger)
1454 return -ENODEV;
1455
1456 vehicle_rotation_param_check(v_cfg);
1457
1458 if (v_cfg->output_format == CIF_OUTPUT_FORMAT_422)
1459 hal_format = HAL_PIXEL_FORMAT_YCbCr_422_SP;
1460 else
1461 hal_format = HAL_PIXEL_FORMAT_YCrCb_NV12;
1462
1463 /* 1. reinit buffer format */
1464 for (i = 0; i < NUM_SOURCE_BUFFERS; i++) {
1465 buffer = &(flg->source_buffer[i]);
1466 rk_flinger_set_rect(&buffer->src,
1467 0, 0, width,
1468 height, width, hal_format);
1469 rk_flinger_set_buffer_rotation(buffer, v_cfg->rotate_mirror);
1470 rk_flinger_cacultae_dst_rect_by_rotation(buffer);
1471 buffer->dst.f = buffer->src.f;
1472 buffer->state = FREE;
1473 }
1474
1475 for (i = 0; i < NUM_TARGET_BUFFERS; i++) {
1476 buffer = &(flg->target_buffer[i]);
1477 buffer->state = FREE;
1478 }
1479
1480 /*2. fill buffer info*/
1481 for (i = 0; i < NUM_SOURCE_BUFFERS && i < MAX_BUF_NUM; i++) {
1482 v_cfg->buf_phy_addr[i] = flinger->source_buffer[i].phy_addr;
1483 VEHICLE_DG("buf_phy_addr=%x, i=%d", v_cfg->buf_phy_addr[i], i);
1484 }
1485
1486 v_cfg->buf_num = NUM_SOURCE_BUFFERS;
1487
1488 flg->cvbs_field_count = 0;
1489 memcpy(&flg->v_cfg, v_cfg, sizeof(struct vehicle_cfg));
1490 flg->running = true;
1491 drop_frames_number = v_cfg->drop_frames;
1492
1493 return 0;
1494 }
1495
vehicle_flinger_reverse_close(bool android_is_ready)1496 int vehicle_flinger_reverse_close(bool android_is_ready)
1497 {
1498 struct flinger *flg = flinger;
1499
1500 flg->running = false;
1501 if (flg->drm_dev && flg->plane)
1502 rockchip_drm_direct_show_disable_plane(flg->drm_dev, flg->plane);
1503 VEHICLE_DG("%s(%d) done\n", __func__, __LINE__);
1504
1505 return 0;
1506 }
1507
vehicle_flinger_request_cif_buffer(void)1508 unsigned long vehicle_flinger_request_cif_buffer(void)
1509 {
1510 struct graphic_buffer *src_buffer = NULL;
1511 struct flinger *flg = flinger;
1512 static int last_src_index = -1;
1513 int found;
1514 int i;
1515
1516 src_buffer = NULL;
1517 for (i = 1; i < NUM_SOURCE_BUFFERS; i++) {
1518 found = (last_src_index + i) % NUM_SOURCE_BUFFERS;
1519 VEHICLE_DG("%s,flg->source_buffer[%d].state(%d)",
1520 __func__, found, flg->source_buffer[found].state);
1521 if (flg->source_buffer[found].state == FREE) {
1522 src_buffer = &flg->source_buffer[found];
1523 last_src_index = found;
1524 src_buffer->state = DEQUEUE;
1525 break;
1526 }
1527 }
1528
1529 if (i < NUM_SOURCE_BUFFERS)
1530 return src_buffer->phy_addr;
1531 else
1532 return 0;
1533 }
1534
vehicle_flinger_commit_cif_buffer(u32 buf_phy_addr)1535 void vehicle_flinger_commit_cif_buffer(u32 buf_phy_addr)
1536 {
1537 struct graphic_buffer *buffer = NULL;
1538 struct flinger *flg = flinger;
1539
1540 if (!flg)
1541 return;
1542
1543 buffer = rk_flinger_lookup_buffer_by_phy_addr(buf_phy_addr);
1544 if (buffer) {
1545 buffer->timestamp = ktime_get();
1546 atomic_inc(&flg->worker_cond_atomic);
1547 flg->debug_cif_count++;
1548 wake_up(&flg->worker_wait);
1549 } else {
1550 VEHICLE_DGERR("%x, no free buffer\n", buf_phy_addr);
1551 }
1552 }
1553