xref: /OK3568_Linux_fs/kernel/drivers/video/rockchip/vehicle/vehicle_flinger.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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