• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * vendor/amlogic/media/common/ge2d/ge2d_wq.c
3  *
4  * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  */
17 
18 #include <linux/interrupt.h>
19 #include <linux/list.h>
20 #include <linux/spinlock.h>
21 #include <linux/kthread.h>
22 #include <linux/device.h>
23 #include <linux/slab.h>
24 #include <linux/interrupt.h>
25 #include <linux/of.h>
26 #include <linux/of_fdt.h>
27 #include <linux/reset.h>
28 #include <linux/clk.h>
29 #include <linux/delay.h>
30 
31 /* Amlogic Headers */
32 #include <linux/amlogic/cpu_version.h>
33 #include <linux/amlogic/media/canvas/canvas.h>
34 #include <linux/amlogic/media/canvas/canvas_mgr.h>
35 #include <linux/amlogic/media/ge2d/ge2d.h>
36 #include <linux/platform_device.h>
37 #ifdef CONFIG_AMLOGIC_ION
38 #include <meson_ion.h>
39 #endif
40 
41 /* Local Headers */
42 #include "ge2dgen.h"
43 #include "ge2d_log.h"
44 #include "ge2d_io.h"
45 #include "ge2d_reg.h"
46 #include "ge2d_dmabuf.h"
47 #include "ge2d_wq.h"
48 
49 #ifdef CONFIG_AMLOGIC_MEDIA_FB
50 #include "osd_io.h"
51 #include "osd_hw.h"
52 #endif
53 
54 #define CANVAS_ADDR_NOWRAP 0x00
55 #define CANVAS_ADDR_WRAPX 0x01
56 #define CANVAS_ADDR_WRAPY 0x02
57 #define CANVAS_BLKMODE_MASK 3
58 #define CANVAS_BLKMODE_BIT 24
59 #define CANVAS_BLKMODE_LINEAR 0x00
60 #define CANVAS_BLKMODE_32X32 0x01
61 #define CANVAS_BLKMODE_64X32 0x02s
62 
63 #define OSD1_CANVAS_INDEX 0x40
64 #define OSD2_CANVAS_INDEX 0x43
65 #define OSD3_CANVAS_INDEX 0x41
66 #define OSD4_CANVAS_INDEX 0x42
67 #define ALLOC_CANVAS_INDEX 0x44
68 
69 static struct ge2d_manager_s ge2d_manager;
70 static int ge2d_irq = -ENXIO;
71 static struct clk *ge2d_clk;
72 
73 static const int bpp_type_lut[] = {
74 #ifdef CONFIG_AMLOGIC_MEDIA_FB
75     /* 16bit */
76     COLOR_INDEX_16_655,    /* 0 */
77     COLOR_INDEX_16_844,    /* 1 */
78     COLOR_INDEX_16_6442,   /* 2 */
79     COLOR_INDEX_16_4444_R, /* 3 */
80     COLOR_INDEX_16_565,    /* 4 */
81     COLOR_INDEX_16_4444_A, /* 5 */
82     COLOR_INDEX_16_1555_A, /* 6 */
83     COLOR_INDEX_16_4642_R, /* 7 */
84     /* 24bit */
85     COLOR_INDEX_24_RGB,    /* 0 */
86     COLOR_INDEX_24_5658,   /* 1 */
87     COLOR_INDEX_24_8565,   /* 2 */
88     COLOR_INDEX_24_6666_R, /* 3 */
89     COLOR_INDEX_24_6666_A, /* 4 */
90     COLOR_INDEX_24_888_B,  /* 5 */
91     0, 0,
92     /* 32bit */
93     COLOR_INDEX_32_RGBA, /* 0 */
94     COLOR_INDEX_32_ARGB, /* 1 */
95     COLOR_INDEX_32_ABGR, /* 2 */
96     COLOR_INDEX_32_BGRA, /* 3 */
97     0, 0, 0, 0
98 #endif
99 };
100 
101 static const int default_ge2d_color_lut[] = {
102     0,
103     0,
104     0, /* BPP_TYPE_02_PAL4    = 2, */
105     0,
106     0, /* BPP_TYPE_04_PAL16   = 4, */
107     0,
108     0,
109     0,
110     0,                         /* BPP_TYPE_08_PAL256=8, */
111     GE2D_FORMAT_S16_RGB_655,   /* BPP_TYPE_16_655 =9, */
112     GE2D_FORMAT_S16_RGB_844,   /* BPP_TYPE_16_844 =10, */
113     GE2D_FORMAT_S16_RGBA_6442, /* BPP_TYPE_16_6442 =11 , */
114     GE2D_FORMAT_S16_RGBA_4444, /* BPP_TYPE_16_4444_R = 12, */
115     GE2D_FORMAT_S16_RGBA_4642, /* BPP_TYPE_16_4642_R = 13, */
116     GE2D_FORMAT_S16_ARGB_1555, /* BPP_TYPE_16_1555_A=14, */
117     GE2D_FORMAT_S16_ARGB_4444, /* BPP_TYPE_16_4444_A = 15, */
118     GE2D_FORMAT_S16_RGB_565,   /* BPP_TYPE_16_565 =16, */
119     0,
120     0,
121     GE2D_FORMAT_S24_ARGB_6666, /* BPP_TYPE_24_6666_A=19, */
122     GE2D_FORMAT_S24_RGBA_6666, /* BPP_TYPE_24_6666_R=20, */
123     GE2D_FORMAT_S24_ARGB_8565, /* BPP_TYPE_24_8565 =21, */
124     GE2D_FORMAT_S24_RGBA_5658, /* BPP_TYPE_24_5658 = 22, */
125     GE2D_FORMAT_S24_BGR,       /* BPP_TYPE_24_888_B = 23, */
126     GE2D_FORMAT_S24_RGB,       /* BPP_TYPE_24_RGB = 24, */
127     0,
128     0,
129     0,
130     0,
131     GE2D_FORMAT_S32_BGRA, /* BPP_TYPE_32_BGRA=29, */
132     GE2D_FORMAT_S32_ABGR, /* BPP_TYPE_32_ABGR = 30, */
133     GE2D_FORMAT_S32_RGBA, /* BPP_TYPE_32_RGBA=31, */
134     GE2D_FORMAT_S32_ARGB, /* BPP_TYPE_32_ARGB=32, */
135 };
136 
137 static int ge2d_buffer_get_phys(struct aml_dma_cfg *cfg, unsigned long *addr);
138 static int ge2d_buffer_unmap(struct aml_dma_cfg *cfg);
139 
ge2d_pre_init(void)140 static void ge2d_pre_init(void)
141 {
142     struct ge2d_gen_s ge2d_gen_cfg;
143 
144     ge2d_gen_cfg.interrupt_ctrl = 0x02;
145     ge2d_gen_cfg.dp_on_cnt = 0;
146     ge2d_gen_cfg.dp_off_cnt = 0;
147     ge2d_gen_cfg.dp_onoff_mode = 0;
148     ge2d_gen_cfg.vfmt_onoff_en = 0;
149     /*  fifo size control, 00: 512, 01: 256, 10: 128 11: 96 */
150     ge2d_gen_cfg.fifo_size = 0;
151     /* fifo burst control, 00: 24x64, 01: 32x64
152      * 10: 48x64, 11:64x64
153      */
154     ge2d_gen_cfg.burst_ctrl = 0;
155     ge2d_set_gen(&ge2d_gen_cfg);
156 }
157 
ge2d_clk_config(bool enable)158 static int ge2d_clk_config(bool enable)
159 {
160     if (ge2d_clk == NULL)
161         return -1;
162     if (enable) {
163         clk_prepare_enable(ge2d_clk);
164     } else {
165         clk_disable_unprepare(ge2d_clk);
166     }
167 
168     return 0;
169 }
170 
ge2d_pwr_config(bool enable)171 void ge2d_pwr_config(bool enable)
172 {
173     int i, table_size;
174     struct ge2d_ctrl_s tmp;
175     struct ge2d_ctrl_s *power_table;
176 
177     if (ge2d_meson_dev.has_self_pwr) {
178         if (enable) {
179             power_table = ge2d_meson_dev.poweron_table->power_table;
180             table_size = ge2d_meson_dev.poweron_table->table_size;
181         } else {
182             power_table = ge2d_meson_dev.poweroff_table->power_table;
183             table_size = ge2d_meson_dev.poweroff_table->table_size;
184         }
185 
186         for (i = 0; i < table_size; i++) {
187             tmp = power_table[i];
188             ge2d_set_pwr_tbl_bits(tmp.table_type, tmp.reg, tmp.val, tmp.start, tmp.len);
189             if (tmp.udelay > 0) {
190                 udelay(tmp.udelay);
191             }
192         }
193     }
194 
195     ge2d_clk_config(enable);
196 
197     if (enable) {
198         ge2d_soft_rst();
199         ge2d_pre_init();
200     }
201 }
202 
get_queue_member_count(struct list_head * head)203 static int get_queue_member_count(struct list_head *head)
204 {
205     int member_count = 0;
206 
207     struct ge2d_queue_item_s *pitem;
208 
209     list_for_each_entry(pitem, head, list)
210     {
211         member_count++;
212         if (member_count > MAX_GE2D_CMD) { /* error has occurred */
213             break;
214         }
215     }
216 
217     return member_count;
218 }
219 
work_queue_status_show(struct class * cla,struct class_attribute * attr,char * buf)220 ssize_t work_queue_status_show(struct class *cla, struct class_attribute *attr, char *buf)
221 {
222     struct ge2d_context_s *wq = ge2d_manager.current_wq;
223 
224     if (wq == 0) {
225         return 0;
226     }
227     return snprintf(buf, 40L, "cmd count in queue:%d\n", get_queue_member_count(&wq->work_queue));
228 }
229 
free_queue_status_show(struct class * cla,struct class_attribute * attr,char * buf)230 ssize_t free_queue_status_show(struct class *cla, struct class_attribute *attr, char *buf)
231 {
232     struct ge2d_context_s *wq = ge2d_manager.current_wq;
233 
234     if (wq == 0) {
235         return 0;
236     }
237     return snprintf(buf, 40L, "free space :%d\n", get_queue_member_count(&wq->free_queue));
238 }
239 
work_queue_no_space(struct ge2d_context_s * queue)240 static inline int work_queue_no_space(struct ge2d_context_s *queue)
241 {
242     return list_empty(&queue->free_queue);
243 }
244 
ge2d_dump_cmd(struct ge2d_cmd_s * cfg)245 static void ge2d_dump_cmd(struct ge2d_cmd_s *cfg)
246 {
247     ge2d_log_dbg("src1_x_start=%d,src1_y_start=%d\n", cfg->src1_x_start, cfg->src1_y_start);
248     ge2d_log_dbg("src1_x_end=%d,src1_y_end=%d\n", cfg->src1_x_end, cfg->src1_y_end);
249     ge2d_log_dbg("src1_x_rev=%d,src1_y_rev=%d\n", cfg->src1_x_rev, cfg->src1_y_rev);
250     ge2d_log_dbg("src1_fill_color_en=%d\n", cfg->src1_fill_color_en);
251 
252     ge2d_log_dbg("src2_x_start=%d,src2_y_start=%d\n", cfg->src2_x_start, cfg->src2_y_start);
253     ge2d_log_dbg("src2_x_end=%d,src2_y_end=%d\n", cfg->src2_x_end, cfg->src2_y_end);
254     ge2d_log_dbg("src2_x_rev=%d,src2_y_rev=%d\n", cfg->src2_x_rev, cfg->src2_y_rev);
255     ge2d_log_dbg("src2_fill_color_en=%d\n", cfg->src2_fill_color_en);
256 
257     ge2d_log_dbg("dst_x_start=%d,dst_y_start=%d\n", cfg->dst_x_start, cfg->dst_y_start);
258     ge2d_log_dbg("dst_x_end=%d,dst_y_end=%d\n", cfg->dst_x_end, cfg->dst_y_end);
259     ge2d_log_dbg("dst_x_rev=%d,dst_y_rev=%d\n", cfg->dst_x_rev, cfg->dst_y_rev);
260     ge2d_log_dbg("dst_xy_swap=%d\n", cfg->dst_xy_swap);
261 
262     ge2d_log_dbg("color_blend_mode=0x%x\n", cfg->color_blend_mode);
263     ge2d_log_dbg("color_src_blend_factor=0x%x\n", cfg->color_src_blend_factor);
264     ge2d_log_dbg("color_dst_blend_factor=0x%x\n", cfg->color_dst_blend_factor);
265     ge2d_log_dbg("color_logic_op=0x%x\n", cfg->color_logic_op);
266     ge2d_log_dbg("alpha_blend_mode=0x%x\n", cfg->alpha_blend_mode);
267     ge2d_log_dbg("alpha_src_blend_factor=0x%x\n", cfg->alpha_src_blend_factor);
268     ge2d_log_dbg("alpha_src_blend_factor=0x%x\n", cfg->alpha_dst_blend_factor);
269     ge2d_log_dbg("alpha_logic_op=0x%x\n", cfg->alpha_logic_op);
270 
271     ge2d_log_dbg("sc_prehsc_en=%d\n", cfg->sc_prehsc_en);
272     ge2d_log_dbg("sc_prevsc_en=%d\n", cfg->sc_prevsc_en);
273     ge2d_log_dbg("sc_hsc_en=%d\n", cfg->sc_hsc_en);
274     ge2d_log_dbg("sc_vsc_en=%d\n", cfg->sc_vsc_en);
275     ge2d_log_dbg("vsc_phase_step=%d\n", cfg->vsc_phase_step);
276     ge2d_log_dbg("vsc_phase_slope=%d\n", cfg->vsc_phase_slope);
277     ge2d_log_dbg("vsc_rpt_l0_num=%d\n", cfg->vsc_rpt_l0_num);
278     ge2d_log_dbg("vsc_ini_phase=%d\n", cfg->vsc_ini_phase);
279     ge2d_log_dbg("hsc_phase_step=%d\n", cfg->hsc_phase_step);
280     ge2d_log_dbg("hsc_phase_slope=%d\n", cfg->hsc_phase_slope);
281     ge2d_log_dbg("hsc_rpt_p0_num=%d\n", cfg->hsc_rpt_p0_num);
282     ge2d_log_dbg("hsc_ini_phase=%d\n", cfg->hsc_ini_phase);
283     ge2d_log_dbg("hsc_div_en=%d\n", cfg->hsc_div_en);
284     ge2d_log_dbg("hsc_div_length=%d\n", cfg->hsc_div_length);
285     ge2d_log_dbg("hsc_adv_num=%d\n", cfg->hsc_adv_num);
286     ge2d_log_dbg("hsc_adv_phase=%d\n", cfg->hsc_adv_phase);
287     ge2d_log_dbg("src1_cmult_asel=%d\n", cfg->src1_cmult_asel);
288     ge2d_log_dbg("src2_cmult_asel=%d\n", cfg->src2_cmult_asel);
289 
290     ge2d_log_dbg("GE2D_STATUS0=0x%x\n", ge2d_reg_read(GE2D_STATUS0));
291     ge2d_log_dbg("GE2D_STATUS1=0x%x\n", ge2d_reg_read(GE2D_STATUS1));
292 }
293 
ge2d_set_canvas(struct ge2d_config_s * cfg)294 static void ge2d_set_canvas(struct ge2d_config_s *cfg)
295 {
296 	int i, index;
297 	int index_src = 0, index_src2 = 0, index_dst = 0;
298 	int canvas_set = 0;
299 
300 	index = ALLOC_CANVAS_INDEX;
301 	for (i = 0; i < MAX_PLANE; i++) {
302 		if (cfg->src_canvas_cfg[i].canvas_used) {
303 			index_src |= index << (8 * i);
304 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
305 			canvas_config(index++,
306 				cfg->src_canvas_cfg[i].phys_addr,
307 				cfg->src_canvas_cfg[i].stride,
308 				cfg->src_canvas_cfg[i].height,
309 				CANVAS_ADDR_NOWRAP,
310 				CANVAS_BLKMODE_LINEAR);
311 #endif
312 			cfg->src_canvas_cfg[i].canvas_used = 0;
313 			ge2d_log_dbg("src canvas: addr(%lx),stride(%d),height(%d)",
314 				cfg->src_canvas_cfg[i].phys_addr,
315 				cfg->src_canvas_cfg[i].stride,
316 				cfg->src_canvas_cfg[i].height);
317 			canvas_set = 1;
318 		}
319 	}
320 	if (canvas_set) {
321 		cfg->src1_data.canaddr = index_src;
322 		ge2d_log_dbg("src canvas_index:%x\n", index_src);
323 		canvas_set = 0;
324 	}
325 	for (i = 0; i < MAX_PLANE; i++) {
326 		if (cfg->src2_canvas_cfg[i].canvas_used) {
327 			index_src2 |= index << (8 * i);
328 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
329 			canvas_config(index++,
330 				cfg->src2_canvas_cfg[i].phys_addr,
331 				cfg->src2_canvas_cfg[i].stride,
332 				cfg->src2_canvas_cfg[i].height,
333 				CANVAS_ADDR_NOWRAP,
334 				CANVAS_BLKMODE_LINEAR);
335 #endif
336 			cfg->src2_canvas_cfg[i].canvas_used = 0;
337 			ge2d_log_dbg("src2 canvas: addr(%lx),stride(%d),height(%d)",
338 				cfg->src2_canvas_cfg[i].phys_addr,
339 				cfg->src2_canvas_cfg[i].stride,
340 				cfg->src2_canvas_cfg[i].height);
341 			canvas_set = 1;
342 		}
343 	}
344 	if (canvas_set) {
345 		cfg->src2_dst_data.src2_canaddr = index_src2;
346 		ge2d_log_dbg("src2 canvas_index:%x\n", index_src2);
347 		canvas_set = 0;
348 	}
349 
350 	for (i = 0; i < MAX_PLANE; i++) {
351 		if (cfg->dst_canvas_cfg[i].canvas_used) {
352 			index_dst |= index << (8 * i);
353 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
354 			canvas_config(index++,
355 				cfg->dst_canvas_cfg[i].phys_addr,
356 				cfg->dst_canvas_cfg[i].stride,
357 				cfg->dst_canvas_cfg[i].height,
358 				CANVAS_ADDR_NOWRAP,
359 				CANVAS_BLKMODE_LINEAR);
360 #endif
361 			cfg->dst_canvas_cfg[i].canvas_used = 0;
362 			ge2d_log_dbg("dst canvas: addr(%lx),stride(%d),height(%d)",
363 				cfg->dst_canvas_cfg[i].phys_addr,
364 				cfg->dst_canvas_cfg[i].stride,
365 				cfg->dst_canvas_cfg[i].height);
366 			canvas_set = 1;
367 		}
368 	}
369 	if (canvas_set) {
370 		cfg->src2_dst_data.dst_canaddr = index_dst;
371 		ge2d_log_dbg("dst canvas_index:%x\n", index_dst);
372 	}
373 }
374 
ge2d_process_work_queue(struct ge2d_context_s * wq)375 static int ge2d_process_work_queue(struct ge2d_context_s *wq)
376 {
377     struct ge2d_config_s *cfg;
378     struct ge2d_queue_item_s *pitem;
379     unsigned int mask = 0x1;
380     struct list_head *head = &wq->work_queue, *pos;
381     int ret = 0, i = 0;
382     unsigned int block_mode;
383     int timeout = 0;
384     if (wq->ge2d_request_exit) {
385         goto exit;
386     }
387     ge2d_manager.ge2d_state = GE2D_STATE_RUNNING;
388     pos = head->next;
389     if (pos != head) {                    /* current work queue not empty. */
390         if (wq != ge2d_manager.last_wq) { /* maybe */
391             /* modify the first item . */
392             pitem = (struct ge2d_queue_item_s *)pos;
393             if (pitem) {
394                 pitem->config.update_flag = UPDATE_ALL;
395             } else {
396                 ge2d_log_err("can't get pitem\n");
397                 ret = -1;
398                 goto exit;
399             }
400         } else {
401             /* modify the first item . */
402             pitem = (struct ge2d_queue_item_s *)pos;
403         }
404     } else {
405         ret = -1;
406         goto exit;
407     }
408 
409     do {
410         cfg = &pitem->config;
411         ge2d_set_canvas(cfg);
412         mask = 0x1;
413         while (cfg->update_flag && mask <= UPDATE_SCALE_COEF) {
414             /* we do not change */
415             switch (cfg->update_flag & mask) {
416                 case UPDATE_SRC_DATA:
417                     ge2d_set_src1_data(&cfg->src1_data);
418                     break;
419                 case UPDATE_SRC_GEN:
420                     ge2d_set_src1_gen(&cfg->src1_gen);
421                     break;
422                 case UPDATE_DST_DATA:
423                     ge2d_set_src2_dst_data(&cfg->src2_dst_data);
424                     break;
425                 case UPDATE_DST_GEN:
426                     ge2d_set_src2_dst_gen(&cfg->src2_dst_gen);
427                     break;
428                 case UPDATE_DP_GEN:
429                     ge2d_set_dp_gen(cfg);
430                     break;
431                 case UPDATE_SCALE_COEF:
432                     ge2d_set_src1_scale_coef(cfg->v_scale_coef_type, cfg->h_scale_coef_type);
433                     break;
434             }
435 
436             cfg->update_flag &= ~mask;
437             mask = mask << 1;
438         }
439         pitem->cmd.hang_flag = 1;
440         ge2d_set_cmd(&pitem->cmd); /* set START_FLAG in this func. */
441         /* remove item */
442         block_mode = pitem->cmd.wait_done_flag;
443 
444         while (ge2d_is_busy()) {
445             timeout = wait_event_interruptible_timeout(ge2d_manager.event.cmd_complete, !ge2d_is_busy(),
446                                                        msecs_to_jiffies(1000L));
447             if (timeout == 0) {
448                 ge2d_log_err("ge2d timeout!!!\n");
449                 ge2d_dump_cmd(&pitem->cmd);
450                 ge2d_soft_rst();
451                 break;
452             }
453         }
454         /* if block mode (cmd) */
455         if (block_mode) {
456             pitem->cmd.wait_done_flag = 0;
457             wake_up_interruptible(&wq->cmd_complete);
458         }
459         spin_lock(&wq->lock);
460         pos = pos->next;
461         list_move_tail(&pitem->list, &wq->free_queue);
462         spin_unlock(&wq->lock);
463         /* if dma buf detach it */
464         for (i = 0; i < MAX_PLANE; i++) {
465             if (pitem->config.src_dma_cfg[i].dma_used) {
466                 ge2d_buffer_unmap((struct aml_dma_cfg *)pitem->config.src_dma_cfg[i].dma_cfg);
467                 pitem->config.src_dma_cfg[i].dma_used = 0;
468                 kfree(pitem->config.src_dma_cfg[i].dma_cfg);
469             }
470             if (pitem->config.src2_dma_cfg[i].dma_used) {
471                 ge2d_buffer_unmap((struct aml_dma_cfg *)pitem->config.src2_dma_cfg[i].dma_cfg);
472                 pitem->config.src2_dma_cfg[i].dma_used = 0;
473                 kfree(pitem->config.src2_dma_cfg[i].dma_cfg);
474             }
475             if (pitem->config.dst_dma_cfg[i].dma_used) {
476                 ge2d_buffer_unmap((struct aml_dma_cfg *)pitem->config.dst_dma_cfg[i].dma_cfg);
477                 pitem->config.dst_dma_cfg[i].dma_used = 0;
478                 kfree(pitem->config.dst_dma_cfg[i].dma_cfg);
479             }
480         }
481         pitem = (struct ge2d_queue_item_s *)pos;
482     } while (pos != head);
483     ge2d_manager.last_wq = wq;
484 exit:
485     if (wq->ge2d_request_exit) {
486         complete(&ge2d_manager.event.process_complete);
487     }
488     ge2d_manager.ge2d_state = GE2D_STATE_IDLE;
489     return ret;
490 }
491 
ge2d_wq_handle(int irq_number,void * para)492 static irqreturn_t ge2d_wq_handle(int irq_number, void *para)
493 {
494     wake_up(&ge2d_manager.event.cmd_complete);
495     return IRQ_HANDLED;
496 }
497 
update_canvas_cfg(struct ge2d_canvas_cfg_s * canvas_cfg,unsigned long phys_addr,unsigned int stride,unsigned int height)498 static void update_canvas_cfg(struct ge2d_canvas_cfg_s *canvas_cfg, unsigned long phys_addr, unsigned int stride,
499                               unsigned int height)
500 {
501     canvas_cfg->canvas_used = 1;
502     canvas_cfg->phys_addr = phys_addr;
503     canvas_cfg->stride = stride;
504     canvas_cfg->height = height;
505 }
506 
ge2d_wq_get_canvas_cfg(struct ge2d_context_s * wq,unsigned int data_type,unsigned int plane_id)507 struct ge2d_canvas_cfg_s *ge2d_wq_get_canvas_cfg(struct ge2d_context_s *wq, unsigned int data_type,
508                                                  unsigned int plane_id)
509 {
510     struct ge2d_canvas_cfg_s *canvas_cfg = NULL;
511 
512     switch (data_type) {
513         case AML_GE2D_SRC:
514             canvas_cfg = &wq->config.src_canvas_cfg[plane_id];
515             break;
516         case AML_GE2D_SRC2:
517             canvas_cfg = &wq->config.src2_canvas_cfg[plane_id];
518             break;
519         case AML_GE2D_DST:
520             canvas_cfg = &wq->config.dst_canvas_cfg[plane_id];
521             break;
522         default:
523             ge2d_log_err("wrong data_type\n");
524             break;
525     }
526     return canvas_cfg;
527 }
528 
ge2d_wq_get_dma_cfg(struct ge2d_context_s * wq,unsigned int data_type,unsigned int plane_id)529 struct ge2d_dma_cfg_s *ge2d_wq_get_dma_cfg(struct ge2d_context_s *wq, unsigned int data_type, unsigned int plane_id)
530 {
531     struct ge2d_dma_cfg_s *dma_cfg = NULL;
532 
533     switch (data_type) {
534         case AML_GE2D_SRC:
535             dma_cfg = &wq->config.src_dma_cfg[plane_id];
536             break;
537         case AML_GE2D_SRC2:
538             dma_cfg = &wq->config.src2_dma_cfg[plane_id];
539             break;
540         case AML_GE2D_DST:
541             dma_cfg = &wq->config.dst_dma_cfg[plane_id];
542             break;
543         default:
544             ge2d_log_err("wrong data_type\n");
545             break;
546     }
547 
548     return dma_cfg;
549 }
550 
ge2d_wq_get_src_data(struct ge2d_context_s * wq)551 struct ge2d_src1_data_s *ge2d_wq_get_src_data(struct ge2d_context_s *wq)
552 {
553     return &wq->config.src1_data;
554 }
555 
ge2d_wq_get_src_gen(struct ge2d_context_s * wq)556 struct ge2d_src1_gen_s *ge2d_wq_get_src_gen(struct ge2d_context_s *wq)
557 {
558     return &wq->config.src1_gen;
559 }
560 
ge2d_wq_get_dst_data(struct ge2d_context_s * wq)561 struct ge2d_src2_dst_data_s *ge2d_wq_get_dst_data(struct ge2d_context_s *wq)
562 {
563     return &wq->config.src2_dst_data;
564 }
565 
ge2d_wq_get_dst_gen(struct ge2d_context_s * wq)566 struct ge2d_src2_dst_gen_s *ge2d_wq_get_dst_gen(struct ge2d_context_s *wq)
567 {
568     return &wq->config.src2_dst_gen;
569 }
570 
ge2d_wq_get_dp_gen(struct ge2d_context_s * wq)571 struct ge2d_dp_gen_s *ge2d_wq_get_dp_gen(struct ge2d_context_s *wq)
572 {
573     return &wq->config.dp_gen;
574 }
575 
ge2d_wq_get_cmd(struct ge2d_context_s * wq)576 struct ge2d_cmd_s *ge2d_wq_get_cmd(struct ge2d_context_s *wq)
577 {
578     return &wq->cmd;
579 }
580 
ge2d_wq_set_scale_coef(struct ge2d_context_s * wq,unsigned int v_scale_coef_type,unsigned int h_scale_coef_type)581 void ge2d_wq_set_scale_coef(struct ge2d_context_s *wq, unsigned int v_scale_coef_type, unsigned int h_scale_coef_type)
582 {
583     if (wq) {
584         wq->config.v_scale_coef_type = v_scale_coef_type;
585         wq->config.h_scale_coef_type = h_scale_coef_type;
586         wq->config.update_flag |= UPDATE_SCALE_COEF;
587     }
588 }
589 
ge2d_wq_add_work(struct ge2d_context_s * wq)590 int ge2d_wq_add_work(struct ge2d_context_s *wq)
591 {
592     struct ge2d_queue_item_s *pitem;
593 
594     ge2d_log_dbg("add new work @@%s:%d\n", __func__, __LINE__);
595     if (work_queue_no_space(wq)) {
596         ge2d_log_dbg("work queue no space\n");
597         /* we should wait for queue empty at this point. */
598         return -1;
599     }
600 
601     pitem = list_entry(wq->free_queue.next, struct ge2d_queue_item_s, list);
602     if (IS_ERR(pitem)) {
603         goto error;
604     }
605     memcpy(&pitem->cmd, &wq->cmd, sizeof(struct ge2d_cmd_s));
606     memset(&wq->cmd, 0, sizeof(struct ge2d_cmd_s));
607     memcpy(&pitem->config, &wq->config, sizeof(struct ge2d_config_s));
608     wq->config.update_flag = 0; /* reset config set flag */
609     spin_lock(&wq->lock);
610     list_move_tail(&pitem->list, &wq->work_queue);
611     spin_unlock(&wq->lock);
612     ge2d_log_dbg("add new work ok\n");
613     /* only read not need lock */
614     if (ge2d_manager.event.cmd_in_sem.count == 0) {
615         up(&ge2d_manager.event.cmd_in_sem); /* new cmd come in */
616     }
617     /* add block mode   if() */
618     if (pitem->cmd.wait_done_flag) {
619         wait_event_interruptible(wq->cmd_complete, pitem->cmd.wait_done_flag == 0);
620     }
621     return 0;
622 error:
623     return -1;
624 }
625 
get_next_work_queue(struct ge2d_manager_s * manager)626 static inline struct ge2d_context_s *get_next_work_queue(struct ge2d_manager_s *manager)
627 {
628     struct ge2d_context_s *pcontext;
629 
630     spin_lock(&ge2d_manager.event.sem_lock);
631     list_for_each_entry(pcontext, &manager->process_queue, list)
632     {
633         /* not lock maybe delay to next time. */
634         if (!list_empty(&pcontext->work_queue)) {
635             /* move head . */
636             list_move(&manager->process_queue, &pcontext->list);
637             spin_unlock(&ge2d_manager.event.sem_lock);
638             return pcontext;
639         }
640     }
641     spin_unlock(&ge2d_manager.event.sem_lock);
642     return NULL;
643 }
644 
ge2d_monitor_thread(void * data)645 static int ge2d_monitor_thread(void *data)
646 {
647     int ret;
648     struct ge2d_manager_s *manager = (struct ge2d_manager_s *)data;
649 
650     ge2d_log_info("ge2d workqueue monitor start\n");
651     /* setup current_wq here. */
652     while (ge2d_manager.process_queue_state != GE2D_PROCESS_QUEUE_STOP) {
653         ret = down_interruptible(&manager->event.cmd_in_sem);
654         ge2d_pwr_config(true);
655         while ((manager->current_wq = get_next_work_queue(manager)) != NULL) {
656             ge2d_process_work_queue(manager->current_wq);
657         }
658         if (!ge2d_dump_reg_enable) {
659             ge2d_pwr_config(false);
660         }
661     }
662     ge2d_log_info("exit ge2d_monitor_thread\n");
663     return 0;
664 }
665 
ge2d_start_monitor(void)666 static int ge2d_start_monitor(void)
667 {
668     int ret = 0;
669 
670     ge2d_log_info("ge2d start monitor\n");
671     ge2d_manager.process_queue_state = GE2D_PROCESS_QUEUE_START;
672     ge2d_manager.ge2d_thread = kthread_run(ge2d_monitor_thread, &ge2d_manager, "ge2d_monitor");
673     if (IS_ERR(ge2d_manager.ge2d_thread)) {
674         ret = PTR_ERR(ge2d_manager.ge2d_thread);
675         ge2d_log_err("ge2d failed to start kthread (%d)\n", ret);
676     }
677     return ret;
678 }
679 
ge2d_stop_monitor(void)680 static int ge2d_stop_monitor(void)
681 {
682     ge2d_log_info("stop ge2d monitor thread\n");
683     if (ge2d_manager.ge2d_thread) {
684         ge2d_manager.process_queue_state = GE2D_PROCESS_QUEUE_STOP;
685         up(&ge2d_manager.event.cmd_in_sem);
686         kthread_stop(ge2d_manager.ge2d_thread);
687         ge2d_manager.ge2d_thread = NULL;
688     }
689     return 0;
690 }
691 
bpp(unsigned int format)692 static inline int bpp(unsigned int format)
693 {
694     switch (format & GE2D_BPP_MASK) {
695         case GE2D_BPP_8BIT:
696             return 8L;
697         case GE2D_BPP_16BIT:
698             return 16L;
699         case GE2D_BPP_24BIT:
700             if ((GE2D_COLOR_MAP_NV21 == (format & GE2D_COLOR_MAP_NV21)) ||
701                 (GE2D_COLOR_MAP_NV12 == (format & GE2D_COLOR_MAP_NV12))) {
702                 return 8L;
703             }
704             return 24L;
705         case GE2D_BPP_32BIT:
706         default:
707             return 32L;
708     }
709 }
710 
build_ge2d_config(struct ge2d_context_s * context,struct config_para_s * cfg,struct src_dst_para_s * src,struct src_dst_para_s * dst)711 static int build_ge2d_config(struct ge2d_context_s *context, struct config_para_s *cfg, struct src_dst_para_s *src,
712                              struct src_dst_para_s *dst)
713 {
714     struct ge2d_canvas_cfg_s *canvas_cfg = NULL;
715     int i;
716 
717     if (src) {
718         src->xres = cfg->src_planes[0].w;
719         src->yres = cfg->src_planes[0].h;
720         src->ge2d_color_index = cfg->src_format;
721         src->bpp = bpp(cfg->src_format);
722         for (i = 0; i < MAX_PLANE; i++) {
723             if (cfg->src_planes[0].addr) {
724                 if (ge2d_meson_dev.canvas_status == 1) {
725                     if (i == 0) {
726                         src->canvas_index = 0;
727                         src->phy_addr = cfg->src_planes[0].addr;
728                         src->stride = cfg->src_planes[0].w * src->bpp / 8L;
729                     } else {
730                         ge2d_log_info("not support src_planes>1\n");
731                     }
732                 } else {
733                     src->canvas_index = 0;
734                     canvas_cfg = ge2d_wq_get_canvas_cfg(context, AML_GE2D_SRC, i);
735                     if (!canvas_cfg) {
736                         return -1;
737                     }
738                     update_canvas_cfg(canvas_cfg, cfg->src_planes[i].addr, cfg->src_planes[i].w * src->bpp / 8L,
739                                       cfg->src_planes[i].h);
740                 }
741             }
742         }
743     }
744     if (dst) {
745         dst->xres = cfg->dst_planes[0].w;
746         dst->yres = cfg->dst_planes[0].h;
747         dst->ge2d_color_index = cfg->dst_format;
748         dst->bpp = bpp(cfg->dst_format);
749         for (i = 0; i < MAX_PLANE; i++) {
750             if (cfg->dst_planes[i].addr) {
751                 if (ge2d_meson_dev.canvas_status == 1) {
752                     if (i == 0) {
753                         dst->canvas_index = 0;
754                         dst->phy_addr = cfg->dst_planes[0].addr;
755                         dst->stride = cfg->dst_planes[0].w * dst->bpp / 8L;
756                     } else {
757                         ge2d_log_info("not support dst_planes>1\n");
758                     }
759                 } else {
760                     dst->canvas_index = 0;
761                     canvas_cfg = ge2d_wq_get_canvas_cfg(context, AML_GE2D_DST, i);
762                     if (!canvas_cfg) {
763                         return -1;
764                     }
765                     update_canvas_cfg(canvas_cfg, cfg->dst_planes[i].addr, cfg->dst_planes[i].w * dst->bpp / 8L,
766                                       cfg->dst_planes[i].h);
767                 }
768             }
769         }
770     }
771     return 0;
772 }
773 
setup_display_property(struct src_dst_para_s * src_dst,int index)774 static int setup_display_property(struct src_dst_para_s *src_dst, int index)
775 {
776     return 0;
777 }
778 
ge2d_antiflicker_enable(struct ge2d_context_s * context,unsigned long enable)779 int ge2d_antiflicker_enable(struct ge2d_context_s *context, unsigned long enable)
780 {
781     /*
782      * antiflicker used in cvbs mode, if antiflicker is enabled,
783      * it represent that we want this feature be enabled for all ge2d work
784      */
785     struct ge2d_context_s *pcontext;
786 
787     spin_lock(&ge2d_manager.event.sem_lock);
788     list_for_each_entry(pcontext, &ge2d_manager.process_queue, list)
789     {
790         ge2dgen_antiflicker(pcontext, enable);
791     }
792     spin_unlock(&ge2d_manager.event.sem_lock);
793 
794     return 0;
795 }
796 
ge2d_context_config(struct ge2d_context_s * context,struct config_para_s * ge2d_config)797 int ge2d_context_config(struct ge2d_context_s *context, struct config_para_s *ge2d_config)
798 {
799     struct src_dst_para_s src, dst, tmp;
800     int type = ge2d_config->src_dst_type;
801 
802     ge2d_log_dbg(" ge2d init\n");
803     memset(&src, 0, sizeof(struct src_dst_para_s));
804     memset(&dst, 0, sizeof(struct src_dst_para_s));
805     /* setup src and dst */
806     switch (type) {
807         case OSD0_OSD0:
808         case OSD0_OSD1:
809         case OSD1_OSD0:
810         case ALLOC_OSD0:
811             if (setup_display_property(&src, OSD1_CANVAS_INDEX) < 0) {
812                 return -1;
813             }
814             break;
815         default:
816             break;
817     }
818     switch (type) {
819         case OSD0_OSD1:
820         case OSD1_OSD1:
821         case OSD1_OSD0:
822         case ALLOC_OSD1:
823             if (setup_display_property(&dst, OSD2_CANVAS_INDEX) < 0) {
824                 return -1;
825             }
826             break;
827         case ALLOC_ALLOC:
828         default:
829             break;
830     }
831     ge2d_log_dbg("OSD ge2d type %d\n", type);
832     switch (type) {
833         case OSD0_OSD0:
834             dst = src;
835             break;
836         case OSD0_OSD1:
837             break;
838         case OSD1_OSD1:
839             src = dst;
840             break;
841         case OSD1_OSD0:
842             tmp = src;
843             src = dst;
844             dst = tmp;
845             break;
846         case ALLOC_OSD0:
847             dst = src;
848             build_ge2d_config(context, ge2d_config, &src, NULL);
849             break;
850         case ALLOC_OSD1:
851             build_ge2d_config(context, ge2d_config, &src, NULL);
852             break;
853         case ALLOC_ALLOC:
854             build_ge2d_config(context, ge2d_config, &src, &dst);
855             break;
856         default:
857             break;
858     }
859     if (src.bpp < 16L || dst.bpp < 16L) {
860         ge2d_log_dbg("src dst bpp type, src=%d,dst=%d\n", src.bpp, dst.bpp);
861     }
862 
863     /* next will config regs */
864     ge2d_log_dbg("ge2d src.xres %d src.yres %d, dst.xres %d dst.yres %d\n", src.xres, src.yres, dst.xres, dst.yres);
865     ge2d_log_dbg("src_format: 0x%x, dst_format: 0x%x\n", src.ge2d_color_index, dst.ge2d_color_index);
866 
867     ge2dgen_src(context, src.canvas_index, src.ge2d_color_index, src.phy_addr, src.stride);
868     ge2dgen_src_clip(context, 0, 0, src.xres, src.yres);
869     ge2dgen_src2(context, dst.canvas_index, dst.ge2d_color_index, dst.phy_addr, dst.stride);
870     ge2dgen_src2_clip(context, 0, 0, dst.xres, dst.yres);
871     ge2dgen_const_color(context, ge2d_config->alu_const_color);
872     ge2dgen_dst(context, dst.canvas_index, dst.ge2d_color_index, dst.phy_addr, dst.stride);
873     ge2dgen_dst_clip(context, 0, 0, dst.xres, dst.yres, DST_CLIP_MODE_INSIDE);
874     return 0;
875 }
876 
build_ge2d_addr_config(struct config_planes_s * plane,unsigned int format,unsigned int * addr,unsigned int * stride)877 static int build_ge2d_addr_config(struct config_planes_s *plane, unsigned int format, unsigned int *addr,
878                                   unsigned int *stride)
879 {
880     int ret = -1;
881     int bpp_value = bpp(format);
882 
883     bpp_value /= 8L;
884     ge2d_log_dbg("build_ge2d_addr_config bpp_value=%d\n", bpp_value);
885     if (plane) {
886         if (plane[0].addr) {
887             *addr = plane[0].addr;
888             *stride = plane[0].w * bpp_value;
889             ret = 0;
890         }
891         /* not support multi-src_planes */
892         if ((plane[1].addr) || (plane[2L].addr) || (plane[3L].addr)) {
893             ge2d_log_info("ge2d not support NV21 mode\n");
894             ret = -1;
895         }
896     }
897     return ret;
898 }
899 
build_ge2d_addr_config_ion(struct config_planes_ion_s * plane,unsigned int format,unsigned int * addr,unsigned int * stride)900 static int build_ge2d_addr_config_ion(struct config_planes_ion_s *plane, unsigned int format, unsigned int *addr,
901                                       unsigned int *stride)
902 {
903     int ret = -1;
904     int bpp_value = bpp(format);
905     unsigned long addr_temp = 0;
906 
907     bpp_value /= 8L;
908     ge2d_log_dbg("build_ge2d_addr_config_ion bpp_value=%d\n", bpp_value);
909     if (plane) {
910         if (plane[0].shared_fd) {
911 #ifdef CONFIG_AMLOGIC_ION
912             size_t len = 0;
913 
914             ret = meson_ion_share_fd_to_phys(ge2d_ion_client, plane[0].shared_fd, &addr_temp, &len);
915             if (ret != 0) {
916                 return ret;
917             }
918 #else
919             return ret;
920 #endif
921         }
922         plane[0].addr += addr_temp;
923         if (plane[0].addr) {
924             *addr = plane[0].addr;
925             *stride = plane[0].w * bpp_value;
926             ret = 0;
927         }
928         /* not support multi-src_planes */
929         if ((plane[1].addr) || (plane[2L].addr) || (plane[3L].addr)) {
930             ge2d_log_info("ge2d not support NV21 mode\n");
931             ret = -1;
932         }
933     }
934     return ret;
935 }
936 
build_ge2d_addr_config_dma(struct ge2d_context_s * context,struct config_planes_ion_s * plane,unsigned int format,unsigned int * addr,unsigned int * stride,unsigned int dir,unsigned int data_type)937 static int build_ge2d_addr_config_dma(struct ge2d_context_s *context, struct config_planes_ion_s *plane,
938                                       unsigned int format, unsigned int *addr, unsigned int *stride, unsigned int dir,
939                                       unsigned int data_type)
940 {
941     int ret = -1;
942     int bpp_value = bpp(format);
943     unsigned long addr_temp = 0;
944 
945     bpp_value /= 8L;
946     ge2d_log_dbg("build_ge2d_addr_config_ion bpp_value=%d\n", bpp_value);
947     if (plane) {
948         if (plane[0].shared_fd) {
949             struct ge2d_dma_cfg_s *cfg = NULL;
950             struct aml_dma_cfg *dma_cfg = NULL;
951 
952             cfg = ge2d_wq_get_dma_cfg(context, data_type, 0);
953             if (!cfg) {
954                 return -1;
955             }
956             cfg->dma_used = 1;
957             dma_cfg = kzalloc(sizeof(*dma_cfg), GFP_KERNEL);
958             dma_cfg->fd = plane[0].shared_fd;
959             dma_cfg->dev = &(ge2d_manager.pdev->dev);
960             dma_cfg->dir = dir;
961             cfg->dma_cfg = dma_cfg;
962             ret = ge2d_buffer_get_phys(dma_cfg, &addr_temp);
963             if (ret != 0) {
964                 return ret;
965             }
966         }
967         plane[0].addr += addr_temp;
968         if (plane[0].addr) {
969             *addr = plane[0].addr;
970             *stride = plane[0].w * bpp_value;
971             ret = 0;
972         }
973         /* not support multi-src_planes */
974         if ((plane[1].addr) || (plane[2L].addr) || (plane[3L].addr)) {
975             ge2d_log_info("ge2d not support NV21 mode\n");
976             ret = -1;
977         }
978     }
979     return ret;
980 }
981 
build_ge2d_config_ex(struct ge2d_context_s * context,struct config_planes_s * plane,unsigned int format,unsigned int data_type)982 static int build_ge2d_config_ex(struct ge2d_context_s *context, struct config_planes_s *plane, unsigned int format,
983                                 unsigned int data_type)
984 {
985     struct ge2d_canvas_cfg_s *canvas_cfg = NULL;
986     int bpp_value = bpp(format);
987     int ret = -1, i = 0;
988 
989     bpp_value /= 8L;
990     if (plane) {
991         for (i = 0; i < MAX_PLANE; i++) {
992             if (plane[i].addr) {
993                 canvas_cfg = ge2d_wq_get_canvas_cfg(context, data_type, i);
994                 if (!canvas_cfg) {
995                     return -1;
996                 }
997                 update_canvas_cfg(canvas_cfg, plane[i].addr, plane[i].w * bpp_value, plane[i].h);
998                 ret = 0;
999             }
1000         }
1001     }
1002     return ret;
1003 }
1004 
build_ge2d_config_ex_ion(struct ge2d_context_s * context,struct config_planes_ion_s * plane,unsigned int format,unsigned int data_type)1005 static int build_ge2d_config_ex_ion(struct ge2d_context_s *context, struct config_planes_ion_s *plane,
1006                                     unsigned int format, unsigned int data_type)
1007 {
1008     struct ge2d_canvas_cfg_s *canvas_cfg = NULL;
1009     int bpp_value = bpp(format);
1010     int ret = -1, i;
1011     int canvas_set = 0;
1012     unsigned long addr;
1013     size_t len;
1014 
1015     bpp_value /= 8L;
1016     if (plane) {
1017         for (i = 0; i < MAX_PLANE; i++) {
1018             /* multi-src_planes */
1019             canvas_set = 0;
1020             if (plane[i].shared_fd) {
1021 #ifdef CONFIG_AMLOGIC_ION
1022                 ret = meson_ion_share_fd_to_phys(ge2d_ion_client, plane[i].shared_fd, &addr, &len);
1023                 if (ret != 0) {
1024                     return ret;
1025                 }
1026 #else
1027                 return ret;
1028 #endif
1029                 plane[i].addr = addr;
1030                 canvas_set = 1;
1031             } else if (plane[i].addr) {
1032                 plane[i].addr += plane[0].addr;
1033                 canvas_set = 1;
1034             }
1035             if (canvas_set) {
1036                 canvas_cfg = ge2d_wq_get_canvas_cfg(context, data_type, i);
1037                 if (!canvas_cfg) {
1038                     return -1;
1039                 }
1040                 update_canvas_cfg(canvas_cfg, plane[i].addr, plane[i].w * bpp_value, plane[i].h);
1041                 canvas_set = 0;
1042                 ret = 0;
1043             }
1044         }
1045     }
1046     return ret;
1047 }
1048 
build_ge2d_config_ex_dma(struct ge2d_context_s * context,struct config_planes_ion_s * plane,unsigned int format,unsigned int dir,unsigned int data_type)1049 static int build_ge2d_config_ex_dma(struct ge2d_context_s *context, struct config_planes_ion_s *plane,
1050                                     unsigned int format, unsigned int dir, unsigned int data_type)
1051 {
1052     struct ge2d_canvas_cfg_s *canvas_cfg = NULL;
1053     int bpp_value = bpp(format);
1054     int ret = -1, i;
1055     int canvas_set = 0;
1056     unsigned long addr;
1057 
1058     bpp_value /= 8L;
1059     if (plane) {
1060         for (i = 0; i < MAX_PLANE; i++) {
1061             /* multi-src_planes */
1062             canvas_set = 0;
1063             if (plane[i].shared_fd) {
1064                 struct ge2d_dma_cfg_s *cfg = NULL;
1065                 struct aml_dma_cfg *dma_cfg = NULL;
1066 
1067                 cfg = ge2d_wq_get_dma_cfg(context, data_type, i);
1068                 if (!cfg) {
1069                     return -1;
1070                 }
1071                 cfg->dma_used = 1;
1072                 dma_cfg = kzalloc(sizeof(*dma_cfg), GFP_KERNEL);
1073                 if (!dma_cfg) {
1074                     return ret;
1075                 }
1076                 dma_cfg->fd = plane[i].shared_fd;
1077                 dma_cfg->dev = &(ge2d_manager.pdev->dev);
1078                 dma_cfg->dir = dir;
1079                 cfg->dma_cfg = dma_cfg;
1080                 ret = ge2d_buffer_get_phys(dma_cfg, &addr);
1081                 if (ret != 0) {
1082                     return ret;
1083                 }
1084                 plane[i].addr = addr;
1085                 canvas_set = 1;
1086             } else if (plane[i].addr) {
1087                 plane[i].addr += plane[0].addr;
1088                 canvas_set = 1;
1089             }
1090             if (canvas_set) {
1091                 canvas_cfg = ge2d_wq_get_canvas_cfg(context, data_type, i);
1092                 if (!canvas_cfg) {
1093                     return -1;
1094                 }
1095                 update_canvas_cfg(canvas_cfg, plane[i].addr, plane[i].w * bpp_value, plane[i].h);
1096                 canvas_set = 0;
1097             }
1098         }
1099     }
1100     return ret;
1101 }
1102 
ge2d_context_config_ex(struct ge2d_context_s * context,struct config_para_ex_s * ge2d_config)1103 int ge2d_context_config_ex(struct ge2d_context_s *context, struct config_para_ex_s *ge2d_config)
1104 {
1105     struct src_dst_para_s tmp;
1106     struct ge2d_src1_gen_s *src1_gen_cfg;
1107     struct ge2d_src2_dst_data_s *src2_dst_data_cfg;
1108     struct ge2d_src2_dst_gen_s *src2_dst_gen_cfg;
1109     struct ge2d_dp_gen_s *dp_gen_cfg;
1110     struct ge2d_cmd_s *ge2d_cmd_cfg;
1111     int top, left, width, height;
1112     unsigned int src_addr = 0, src2_addr = 0, dst_addr = 0;
1113     unsigned int src_stride = 0, src2_stride = 0, dst_stride = 0;
1114 
1115     /* setup src and dst */
1116     switch (ge2d_config->src_para.mem_type) {
1117         case CANVAS_OSD0:
1118         case CANVAS_OSD1:
1119             if (setup_display_property(&tmp, (ge2d_config->src_para.mem_type == CANVAS_OSD0) ? OSD1_CANVAS_INDEX
1120                                                                                              : OSD2_CANVAS_INDEX) < 0) {
1121                 return -1;
1122             }
1123             ge2d_config->src_para.canvas_index = tmp.canvas_index;
1124             ge2d_config->src_para.format = tmp.ge2d_color_index;
1125             src_addr = tmp.phy_addr;
1126             src_stride = tmp.stride;
1127             ge2d_log_dbg("ge2d: src1-->type: osd%d, format: 0x%x !!\n", ge2d_config->src_para.mem_type - CANVAS_OSD0,
1128                          ge2d_config->src_para.format);
1129 
1130             top = ge2d_config->src_para.top;
1131             left = ge2d_config->src_para.left;
1132             width = ge2d_config->src_para.width;
1133             height = ge2d_config->src_para.height;
1134             if ((left + width > tmp.xres) || (top + height > tmp.yres)) {
1135                 ge2d_log_dbg("ge2d src error: out of range\n");
1136                 return -1;
1137             }
1138             ge2d_config->src_para.width = tmp.xres;
1139             ge2d_config->src_para.height = tmp.yres;
1140             ge2d_log_dbg("ge2d osd phy_addr:0x%x,stride=0x%x,format:0x%x\n", src_addr, src_stride,
1141                          ge2d_config->src_para.format);
1142             break;
1143         case CANVAS_ALLOC:
1144             top = ge2d_config->src_para.top;
1145             left = ge2d_config->src_para.left;
1146             width = ge2d_config->src_para.width;
1147             height = ge2d_config->src_para.height;
1148             if ((left + width > ge2d_config->src_planes[0].w) || (top + height > ge2d_config->src_planes[0].h)) {
1149                 ge2d_log_dbg("ge2d error: src alloc, out of range\n");
1150                 return -1;
1151             }
1152             if (ge2d_meson_dev.canvas_status == 1) {
1153                 if (build_ge2d_addr_config(&ge2d_config->src_planes[0], ge2d_config->src_para.format, &src_addr,
1154                                            &src_stride) < 0) {
1155                     return -1;
1156                 }
1157                 ge2d_log_dbg("ge2d alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", src_addr, src_stride,
1158                              ge2d_config->src_para.format);
1159             } else {
1160                 if (build_ge2d_config_ex(context, &ge2d_config->src_planes[0], ge2d_config->src_para.format,
1161                                          AML_GE2D_SRC) < 0) {
1162                     return -1;
1163                 }
1164                 ge2d_config->src_para.canvas_index = 0;
1165                 ge2d_log_dbg("ge2d src alloc,format:0x%x\n", ge2d_config->src_para.format);
1166             }
1167             break;
1168         default:
1169             break;
1170     }
1171 
1172     switch (ge2d_config->src2_para.mem_type) {
1173         case CANVAS_OSD0:
1174         case CANVAS_OSD1:
1175             if (setup_display_property(&tmp, (ge2d_config->src2_para.mem_type == CANVAS_OSD0)
1176                                                  ? OSD1_CANVAS_INDEX
1177                                                  : OSD2_CANVAS_INDEX) < 0) {
1178                 return -1;
1179             }
1180             ge2d_config->src2_para.canvas_index = tmp.canvas_index;
1181             ge2d_config->src2_para.format = tmp.ge2d_color_index;
1182             src2_addr = tmp.phy_addr;
1183             src2_stride = tmp.stride;
1184             ge2d_log_dbg("ge2d: src2-->type: osd%d, format: 0x%x !!\n", ge2d_config->src2_para.mem_type - CANVAS_OSD0,
1185                          ge2d_config->src2_para.format);
1186 
1187             top = ge2d_config->src2_para.top;
1188             left = ge2d_config->src2_para.left;
1189             width = ge2d_config->src2_para.width;
1190             height = ge2d_config->src2_para.height;
1191             if ((left + width > tmp.xres) || (top + height > tmp.yres)) {
1192                 ge2d_log_dbg("ge2d error: src2: osd%d, out of range\n", ge2d_config->src2_para.mem_type - CANVAS_OSD0);
1193                 return -1;
1194             }
1195             ge2d_config->src2_para.width = tmp.xres;
1196             ge2d_config->src2_para.height = tmp.yres;
1197             ge2d_log_dbg("ge2d osd phy_addr:0x%x,stride=0x%x,format:0x%x\n", src2_addr, src_stride,
1198                          ge2d_config->src2_para.format);
1199             break;
1200         case CANVAS_ALLOC:
1201             top = ge2d_config->src2_para.top;
1202             left = ge2d_config->src2_para.left;
1203             width = ge2d_config->src2_para.width;
1204             height = ge2d_config->src2_para.height;
1205             if ((left + width > ge2d_config->src2_planes[0].w) || (top + height > ge2d_config->src2_planes[0].h)) {
1206                 ge2d_log_dbg("ge2d error: src2: alloc, out of range\n");
1207                 return -1;
1208             }
1209             if (ge2d_config->src2_planes[0].addr == ge2d_config->src_planes[0].addr) {
1210                 ge2d_config->src2_para.canvas_index = ge2d_config->src_para.canvas_index;
1211                 src2_addr = src_addr;
1212                 src2_stride = src_stride;
1213             } else {
1214                 if (ge2d_meson_dev.canvas_status == 1) {
1215                     if (build_ge2d_addr_config(&ge2d_config->src2_planes[0], ge2d_config->src2_para.format, &src2_addr,
1216                                                &src2_stride) < 0) {
1217                         return -1;
1218                     }
1219                     ge2d_log_dbg("ge2d alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", src2_addr, src2_stride,
1220                                  ge2d_config->src2_para.format);
1221                 } else {
1222                     if (build_ge2d_config_ex(context, &ge2d_config->src2_planes[0], ge2d_config->src2_para.format,
1223                                              AML_GE2D_SRC2) < 0) {
1224                         return -1;
1225                     }
1226                     ge2d_config->src2_para.canvas_index = 0;
1227                     ge2d_log_dbg("ge2d src2 alloc,format:0x%x\n", ge2d_config->src2_para.format);
1228                 }
1229             }
1230             break;
1231         default:
1232             break;
1233     }
1234 
1235     switch (ge2d_config->dst_para.mem_type) {
1236         case CANVAS_OSD0:
1237         case CANVAS_OSD1:
1238             if (setup_display_property(&tmp, (ge2d_config->dst_para.mem_type == CANVAS_OSD0) ? OSD1_CANVAS_INDEX
1239                                                                                              : OSD2_CANVAS_INDEX) < 0) {
1240                 return -1;
1241             }
1242             ge2d_config->dst_para.canvas_index = tmp.canvas_index;
1243             ge2d_config->dst_para.format = tmp.ge2d_color_index;
1244             dst_addr = tmp.phy_addr;
1245             dst_stride = tmp.stride;
1246 
1247             ge2d_log_dbg("ge2d: dst-->type: osd%d, format: 0x%x !!\n", ge2d_config->dst_para.mem_type - CANVAS_OSD0,
1248                          ge2d_config->dst_para.format);
1249 
1250             top = ge2d_config->dst_para.top;
1251             left = ge2d_config->dst_para.left;
1252             width = ge2d_config->dst_para.width;
1253             height = ge2d_config->dst_para.height;
1254             if ((left + width > tmp.xres) || (top + height > tmp.yres)) {
1255                 ge2d_log_dbg("ge2d error: dst: osd%d, out of range\n", ge2d_config->dst_para.mem_type - CANVAS_OSD0);
1256                 return -1;
1257             }
1258             ge2d_config->dst_para.width = tmp.xres;
1259             ge2d_config->dst_para.height = tmp.yres;
1260             ge2d_log_dbg("ge2d osd phy_addr:0x%x,stride=0x%x,format:0x%x\n", dst_addr, dst_stride,
1261                          ge2d_config->dst_para.format);
1262             break;
1263         case CANVAS_ALLOC:
1264             top = ge2d_config->dst_para.top;
1265             left = ge2d_config->dst_para.left;
1266             width = ge2d_config->dst_para.width;
1267             height = ge2d_config->dst_para.height;
1268             if ((left + width > ge2d_config->dst_planes[0].w) || (top + height > ge2d_config->dst_planes[0].h)) {
1269                 ge2d_log_dbg("ge2d error: dst: alloc, out of range\n");
1270                 return -1;
1271             }
1272             if (ge2d_config->dst_planes[0].addr == ge2d_config->src_planes[0].addr) {
1273                 ge2d_config->dst_para.canvas_index = ge2d_config->src_para.canvas_index;
1274                 dst_addr = src_addr;
1275                 dst_stride = src_stride;
1276             } else if (ge2d_config->dst_planes[0].addr == ge2d_config->src2_planes[0].addr) {
1277                 ge2d_config->dst_para.canvas_index = ge2d_config->src2_para.canvas_index;
1278                 dst_addr = src2_addr;
1279                 dst_stride = src2_stride;
1280             } else {
1281                 if (ge2d_meson_dev.canvas_status == 1) {
1282                     if (build_ge2d_addr_config(&ge2d_config->dst_planes[0], ge2d_config->dst_para.format, &dst_addr,
1283                                                &dst_stride) < 0) {
1284                         return -1;
1285                     }
1286                     ge2d_log_dbg("ge2d alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", dst_addr, dst_stride,
1287                                  ge2d_config->dst_para.format);
1288                 } else {
1289                     if (build_ge2d_config_ex(context, &ge2d_config->dst_planes[0], ge2d_config->dst_para.format,
1290                                              AML_GE2D_DST) < 0) {
1291                         return -1;
1292                     }
1293                     ge2d_config->dst_para.canvas_index = 0;
1294                     ge2d_log_dbg("ge2d: dst alloc,format:0x%x\n", ge2d_config->dst_para.format);
1295                 }
1296             }
1297             break;
1298         default:
1299             break;
1300     }
1301 
1302     ge2dgen_rendering_dir(context, ge2d_config->src_para.x_rev, ge2d_config->src_para.y_rev,
1303                           ge2d_config->dst_para.x_rev, ge2d_config->dst_para.y_rev, ge2d_config->dst_xy_swap);
1304     ge2dgen_const_color(context, ge2d_config->alu_const_color);
1305 
1306     ge2dgen_src(context, ge2d_config->src_para.canvas_index, ge2d_config->src_para.format, src_addr, src_stride);
1307     ge2dgen_src_clip(context, ge2d_config->src_para.left, ge2d_config->src_para.top, ge2d_config->src_para.width,
1308                      ge2d_config->src_para.height);
1309     ge2dgen_src_key(context, ge2d_config->src_key.key_enable, ge2d_config->src_key.key_color,
1310                     ge2d_config->src_key.key_mask, ge2d_config->src_key.key_mode);
1311 #ifdef CONFIG_GE2D_SRC2
1312     ge2dgent_src_gbalpha(context, ge2d_config->src1_gb_alpha, ge2d_config->src2_gb_alpha);
1313 #else
1314     ge2dgent_src_gbalpha(context, ge2d_config->src1_gb_alpha, 0);
1315 #endif
1316     ge2dgen_src_color(context, ge2d_config->src_para.color);
1317 
1318     ge2dgen_src2(context, ge2d_config->src2_para.canvas_index, ge2d_config->src2_para.format, src2_addr, src2_stride);
1319     ge2dgen_src2_clip(context, ge2d_config->src2_para.left, ge2d_config->src2_para.top, ge2d_config->src2_para.width,
1320                       ge2d_config->src2_para.height);
1321 
1322     ge2dgen_dst(context, ge2d_config->dst_para.canvas_index, ge2d_config->dst_para.format, dst_addr, dst_stride);
1323     ge2dgen_dst_clip(context, ge2d_config->dst_para.left, ge2d_config->dst_para.top, ge2d_config->dst_para.width,
1324                      ge2d_config->dst_para.height, DST_CLIP_MODE_INSIDE);
1325 
1326     src1_gen_cfg = ge2d_wq_get_src_gen(context);
1327     src1_gen_cfg->fill_mode = ge2d_config->src_para.fill_mode;
1328     src1_gen_cfg->chfmt_rpt_pix = 0;
1329     src1_gen_cfg->cvfmt_rpt_pix = 0;
1330 
1331     src2_dst_data_cfg = ge2d_wq_get_dst_data(context);
1332     src2_dst_data_cfg->src2_def_color = ge2d_config->src2_para.color;
1333 
1334     src2_dst_gen_cfg = ge2d_wq_get_dst_gen(context);
1335     src2_dst_gen_cfg->src2_fill_mode = ge2d_config->src2_para.fill_mode;
1336 
1337     dp_gen_cfg = ge2d_wq_get_dp_gen(context);
1338 
1339     dp_gen_cfg->src1_vsc_phase0_always_en = ge2d_config->src1_hsc_phase0_always_en;
1340     dp_gen_cfg->src1_hsc_phase0_always_en = ge2d_config->src1_vsc_phase0_always_en;
1341     if ((context->config.v_scale_coef_type == FILTER_TYPE_GAU0) ||
1342         (context->config.v_scale_coef_type == FILTER_TYPE_GAU0_BOT) ||
1343         (context->config.v_scale_coef_type == FILTER_TYPE_GAU1) ||
1344         (context->config.h_scale_coef_type == FILTER_TYPE_GAU0) ||
1345         (context->config.h_scale_coef_type == FILTER_TYPE_GAU0_BOT) ||
1346         (context->config.h_scale_coef_type == FILTER_TYPE_GAU1)) {
1347         /* 1bit, 0: using minus, 1: using repeat data */
1348         dp_gen_cfg->src1_hsc_rpt_ctrl = ge2d_config->src1_hsc_rpt_ctrl;
1349         /* 1bit, 0: using minus  1: using repeat data */
1350         dp_gen_cfg->src1_vsc_rpt_ctrl = ge2d_config->src1_vsc_rpt_ctrl;
1351     } else {
1352         /* 1bit, 0: using minus, 1: using repeat data */
1353         dp_gen_cfg->src1_hsc_rpt_ctrl = 1;
1354         /* 1bit, 0: using minus  1: using repeat data */
1355         dp_gen_cfg->src1_vsc_rpt_ctrl = 1;
1356     }
1357     dp_gen_cfg->src1_gb_alpha = 0xff;
1358     dp_gen_cfg->src1_gb_alpha_en = 0;
1359 #ifdef CONFIG_GE2D_SRC2
1360     dp_gen_cfg->src2_gb_alpha = 0xff;
1361     dp_gen_cfg->src2_gb_alpha_en = 0;
1362 #endif
1363     dp_gen_cfg->src2_key_en = ge2d_config->src2_key.key_enable;
1364     dp_gen_cfg->src2_key_mode = ge2d_config->src2_key.key_mode;
1365     dp_gen_cfg->src2_key = ge2d_config->src2_key.key_color;
1366     dp_gen_cfg->src2_key_mask = ge2d_config->src2_key.key_mask;
1367 
1368     dp_gen_cfg->bitmask_en = ge2d_config->bitmask_en;
1369     dp_gen_cfg->bitmask = ge2d_config->bitmask;
1370     dp_gen_cfg->bytemask_only = ge2d_config->bytemask_only;
1371 
1372     ge2d_cmd_cfg = ge2d_wq_get_cmd(context);
1373 
1374     ge2d_cmd_cfg->src1_fill_color_en = ge2d_config->src_para.fill_color_en;
1375 
1376     ge2d_cmd_cfg->src2_x_rev = ge2d_config->src2_para.x_rev;
1377     ge2d_cmd_cfg->src2_y_rev = ge2d_config->src2_para.y_rev;
1378     ge2d_cmd_cfg->src2_fill_color_en = ge2d_config->src2_para.fill_color_en;
1379 
1380     ge2d_cmd_cfg->vsc_phase_slope = ge2d_config->vsc_phase_slope;
1381     ge2d_cmd_cfg->vsc_ini_phase = ge2d_config->vf_init_phase;
1382     ge2d_cmd_cfg->vsc_phase_step = ge2d_config->vsc_start_phase_step;
1383     ge2d_cmd_cfg->vsc_rpt_l0_num = ge2d_config->vf_rpt_num;
1384 
1385     /* let internal decide */
1386     ge2d_cmd_cfg->hsc_phase_slope = ge2d_config->hsc_phase_slope;
1387     ge2d_cmd_cfg->hsc_ini_phase = ge2d_config->hf_init_phase;
1388     ge2d_cmd_cfg->hsc_phase_step = ge2d_config->hsc_start_phase_step;
1389     ge2d_cmd_cfg->hsc_rpt_p0_num = ge2d_config->hf_rpt_num;
1390 
1391     ge2d_cmd_cfg->src1_cmult_asel = 0;
1392     ge2d_cmd_cfg->src2_cmult_asel = 0;
1393     context->config.update_flag = UPDATE_ALL;
1394 
1395     return 0;
1396 }
1397 EXPORT_SYMBOL(ge2d_context_config_ex);
1398 
ge2d_context_config_ex_ion(struct ge2d_context_s * context,struct config_para_ex_ion_s * ge2d_config)1399 int ge2d_context_config_ex_ion(struct ge2d_context_s *context, struct config_para_ex_ion_s *ge2d_config)
1400 {
1401     struct src_dst_para_s tmp;
1402     struct ge2d_src1_gen_s *src1_gen_cfg;
1403     struct ge2d_src2_dst_data_s *src2_dst_data_cfg;
1404     struct ge2d_src2_dst_gen_s *src2_dst_gen_cfg;
1405     struct ge2d_dp_gen_s *dp_gen_cfg;
1406     struct ge2d_cmd_s *ge2d_cmd_cfg;
1407     int top, left, width, height;
1408     unsigned int src_addr = 0, src2_addr = 0, dst_addr = 0;
1409     unsigned int src_stride = 0, src2_stride = 0, dst_stride = 0;
1410 
1411     /* setup src and dst */
1412     switch (ge2d_config->src_para.mem_type) {
1413         case CANVAS_OSD0:
1414         case CANVAS_OSD1:
1415             if (setup_display_property(&tmp, (ge2d_config->src_para.mem_type == CANVAS_OSD0) ? OSD1_CANVAS_INDEX
1416                                                                                              : OSD2_CANVAS_INDEX) < 0) {
1417                 return -1;
1418             }
1419             ge2d_config->src_para.canvas_index = tmp.canvas_index;
1420             ge2d_config->src_para.format = tmp.ge2d_color_index;
1421             src_addr = tmp.phy_addr;
1422             src_stride = tmp.stride;
1423 
1424             ge2d_log_dbg("ge2d: src1-->type: osd%d, format: 0x%x !!\n", ge2d_config->src_para.mem_type - CANVAS_OSD0,
1425                          ge2d_config->src_para.format);
1426 
1427             top = ge2d_config->src_para.top;
1428             left = ge2d_config->src_para.left;
1429             width = ge2d_config->src_para.width;
1430             height = ge2d_config->src_para.height;
1431             if ((left + width > tmp.xres) || (top + height > tmp.yres)) {
1432                 ge2d_log_dbg("ge2d src error: out of range\n");
1433                 return -1;
1434             }
1435             ge2d_config->src_para.width = tmp.xres;
1436             ge2d_config->src_para.height = tmp.yres;
1437             ge2d_log_dbg("ge2d osd phy_addr:0x%x,stride=0x%x,format:0x%x\n", src_addr, src_stride,
1438                          ge2d_config->src_para.format);
1439             break;
1440         case CANVAS_ALLOC:
1441             top = ge2d_config->src_para.top;
1442             left = ge2d_config->src_para.left;
1443             width = ge2d_config->src_para.width;
1444             height = ge2d_config->src_para.height;
1445             if ((left + width > ge2d_config->src_planes[0].w) || (top + height > ge2d_config->src_planes[0].h)) {
1446                 ge2d_log_dbg("ge2d error: src alloc, out of range\n");
1447                 return -1;
1448             }
1449             if (ge2d_meson_dev.canvas_status == 1) {
1450                 if (build_ge2d_addr_config_ion(&ge2d_config->src_planes[0], ge2d_config->src_para.format, &src_addr,
1451                                                &src_stride) < 0) {
1452                     return -1;
1453                 }
1454                 ge2d_log_dbg("ge2d alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", src_addr, src_stride,
1455                              ge2d_config->src_para.format);
1456             } else {
1457                 if (build_ge2d_config_ex_ion(context, &ge2d_config->src_planes[0], ge2d_config->src_para.format,
1458                                              AML_GE2D_SRC) < 0) {
1459                     return -1;
1460                 }
1461                 ge2d_config->src_para.canvas_index = 0;
1462                 ge2d_log_dbg("ge2d src alloc,format:0x%x\n", ge2d_config->src_para.format);
1463             }
1464             break;
1465         default:
1466             break;
1467     }
1468 
1469     switch (ge2d_config->src2_para.mem_type) {
1470         case CANVAS_OSD0:
1471         case CANVAS_OSD1:
1472             if (setup_display_property(&tmp, (ge2d_config->src2_para.mem_type == CANVAS_OSD0)
1473                                                  ? OSD1_CANVAS_INDEX
1474                                                  : OSD2_CANVAS_INDEX) < 0) {
1475                 return -1;
1476             }
1477             ge2d_config->src2_para.canvas_index = tmp.canvas_index;
1478             ge2d_config->src2_para.format = tmp.ge2d_color_index;
1479             src2_addr = tmp.phy_addr;
1480             src2_stride = tmp.stride;
1481 
1482             ge2d_log_dbg("ge2d: src2-->type: osd%d, format: 0x%x !!\n", ge2d_config->src2_para.mem_type - CANVAS_OSD0,
1483                          ge2d_config->src2_para.format);
1484 
1485             top = ge2d_config->src2_para.top;
1486             left = ge2d_config->src2_para.left;
1487             width = ge2d_config->src2_para.width;
1488             height = ge2d_config->src2_para.height;
1489             if ((left + width > tmp.xres) || (top + height > tmp.yres)) {
1490                 ge2d_log_dbg("ge2d error: src2: osd%d, out of range\n", ge2d_config->src2_para.mem_type - CANVAS_OSD0);
1491                 return -1;
1492             }
1493             ge2d_config->src2_para.width = tmp.xres;
1494             ge2d_config->src2_para.height = tmp.yres;
1495             ge2d_log_dbg("ge2d osd phy_addr:0x%x,stride=0x%x,format:0x%x\n", src2_addr, src2_stride,
1496                          ge2d_config->src2_para.format);
1497             break;
1498         case CANVAS_ALLOC:
1499             top = ge2d_config->src2_para.top;
1500             left = ge2d_config->src2_para.left;
1501             width = ge2d_config->src2_para.width;
1502             height = ge2d_config->src2_para.height;
1503             if ((left + width > ge2d_config->src2_planes[0].w) || (top + height > ge2d_config->src2_planes[0].h)) {
1504                 ge2d_log_dbg("ge2d error: src2: alloc, out of range\n");
1505                 return -1;
1506             }
1507 
1508             if (ge2d_meson_dev.canvas_status == 1) {
1509                 if (build_ge2d_addr_config_ion(&ge2d_config->src2_planes[0], ge2d_config->src2_para.format, &src2_addr,
1510                                                &src2_stride) < 0) {
1511                     return -1;
1512                 }
1513                 ge2d_log_dbg("ge2d alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", src2_addr, src2_stride,
1514                              ge2d_config->src2_para.format);
1515             } else {
1516                 if (build_ge2d_config_ex_ion(context, &ge2d_config->src2_planes[0], ge2d_config->src2_para.format,
1517                                              AML_GE2D_SRC2) < 0) {
1518                     return -1;
1519                 }
1520                 ge2d_config->src2_para.canvas_index = 0;
1521                 ge2d_log_dbg("ge2d src2 alloc,format:0x%x\n", ge2d_config->src2_para.format);
1522             }
1523             break;
1524         default:
1525             break;
1526     }
1527 
1528     switch (ge2d_config->dst_para.mem_type) {
1529         case CANVAS_OSD0:
1530         case CANVAS_OSD1:
1531             if (setup_display_property(&tmp, (ge2d_config->dst_para.mem_type == CANVAS_OSD0) ? OSD1_CANVAS_INDEX
1532                                                                                              : OSD2_CANVAS_INDEX) < 0) {
1533                 return -1;
1534             }
1535             ge2d_config->dst_para.canvas_index = tmp.canvas_index;
1536             ge2d_config->dst_para.format = tmp.ge2d_color_index;
1537             dst_addr = tmp.phy_addr;
1538             dst_stride = tmp.stride;
1539 
1540             ge2d_log_dbg("ge2d: dst-->type: osd%d, format: 0x%x !!\n", ge2d_config->dst_para.mem_type - CANVAS_OSD0,
1541                          ge2d_config->dst_para.format);
1542 
1543             top = ge2d_config->dst_para.top;
1544             left = ge2d_config->dst_para.left;
1545             width = ge2d_config->dst_para.width;
1546             height = ge2d_config->dst_para.height;
1547             if ((left + width > tmp.xres) || (top + height > tmp.yres)) {
1548                 ge2d_log_dbg("ge2d error: dst: osd%d, out of range\n", ge2d_config->dst_para.mem_type - CANVAS_OSD0);
1549                 return -1;
1550             }
1551             ge2d_config->dst_para.width = tmp.xres;
1552             ge2d_config->dst_para.height = tmp.yres;
1553             ge2d_log_dbg("ge2d osd phy_addr:0x%x,stride=0x%x,format:0x%x\n", dst_addr, dst_stride,
1554                          ge2d_config->dst_para.format);
1555             break;
1556         case CANVAS_ALLOC:
1557             top = ge2d_config->dst_para.top;
1558             left = ge2d_config->dst_para.left;
1559             width = ge2d_config->dst_para.width;
1560             height = ge2d_config->dst_para.height;
1561             if ((left + width > ge2d_config->dst_planes[0].w) || (top + height > ge2d_config->dst_planes[0].h)) {
1562                 ge2d_log_dbg("ge2d error: dst: alloc, out of range\n");
1563                 return -1;
1564             }
1565 
1566             if (ge2d_meson_dev.canvas_status == 1) {
1567                 if (build_ge2d_addr_config_ion(&ge2d_config->dst_planes[0], ge2d_config->dst_para.format, &dst_addr,
1568                                                &dst_stride) < 0) {
1569                     return -1;
1570                 }
1571                 ge2d_log_dbg("ge2d alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", dst_addr, dst_stride,
1572                              ge2d_config->dst_para.format);
1573             } else {
1574                 if (build_ge2d_config_ex_ion(context, &ge2d_config->dst_planes[0], ge2d_config->dst_para.format,
1575                                              AML_GE2D_DST) < 0) {
1576                     return -1;
1577                 }
1578                 ge2d_config->dst_para.canvas_index = 0;
1579                 ge2d_log_dbg("ge2d: dst alloc,format:0x%x\n", ge2d_config->dst_para.format);
1580             }
1581             break;
1582         default:
1583             break;
1584     }
1585 
1586     ge2dgen_rendering_dir(context, ge2d_config->src_para.x_rev, ge2d_config->src_para.y_rev,
1587                           ge2d_config->dst_para.x_rev, ge2d_config->dst_para.y_rev, ge2d_config->dst_xy_swap);
1588     ge2dgen_const_color(context, ge2d_config->alu_const_color);
1589 
1590     ge2dgen_src(context, ge2d_config->src_para.canvas_index, ge2d_config->src_para.format, src_addr, src_stride);
1591     ge2dgen_src_clip(context, ge2d_config->src_para.left, ge2d_config->src_para.top, ge2d_config->src_para.width,
1592                      ge2d_config->src_para.height);
1593     ge2dgen_src_key(context, ge2d_config->src_key.key_enable, ge2d_config->src_key.key_color,
1594                     ge2d_config->src_key.key_mask, ge2d_config->src_key.key_mode);
1595 #ifdef CONFIG_GE2D_SRC2
1596     ge2dgent_src_gbalpha(context, ge2d_config->src1_gb_alpha, ge2d_config->src2_gb_alpha);
1597 #else
1598     ge2dgent_src_gbalpha(context, ge2d_config->src1_gb_alpha, 0);
1599 #endif
1600     ge2dgen_src_color(context, ge2d_config->src_para.color);
1601 
1602     ge2dgen_src2(context, ge2d_config->src2_para.canvas_index, ge2d_config->src2_para.format, src2_addr, src2_stride);
1603     ge2dgen_src2_clip(context, ge2d_config->src2_para.left, ge2d_config->src2_para.top, ge2d_config->src2_para.width,
1604                       ge2d_config->src2_para.height);
1605 
1606     ge2dgen_dst(context, ge2d_config->dst_para.canvas_index, ge2d_config->dst_para.format, dst_addr, dst_stride);
1607     ge2dgen_dst_clip(context, ge2d_config->dst_para.left, ge2d_config->dst_para.top, ge2d_config->dst_para.width,
1608                      ge2d_config->dst_para.height, DST_CLIP_MODE_INSIDE);
1609 
1610     src1_gen_cfg = ge2d_wq_get_src_gen(context);
1611     src1_gen_cfg->fill_mode = ge2d_config->src_para.fill_mode;
1612     src1_gen_cfg->chfmt_rpt_pix = 0;
1613     src1_gen_cfg->cvfmt_rpt_pix = 0;
1614 
1615     src2_dst_data_cfg = ge2d_wq_get_dst_data(context);
1616     src2_dst_data_cfg->src2_def_color = ge2d_config->src2_para.color;
1617 
1618     src2_dst_gen_cfg = ge2d_wq_get_dst_gen(context);
1619     src2_dst_gen_cfg->src2_fill_mode = ge2d_config->src2_para.fill_mode;
1620 
1621     dp_gen_cfg = ge2d_wq_get_dp_gen(context);
1622 
1623     dp_gen_cfg->src1_vsc_phase0_always_en = ge2d_config->src1_hsc_phase0_always_en;
1624     dp_gen_cfg->src1_hsc_phase0_always_en = ge2d_config->src1_vsc_phase0_always_en;
1625     if ((context->config.v_scale_coef_type == FILTER_TYPE_GAU0) ||
1626         (context->config.v_scale_coef_type == FILTER_TYPE_GAU0_BOT) ||
1627         (context->config.v_scale_coef_type == FILTER_TYPE_GAU1) ||
1628         (context->config.h_scale_coef_type == FILTER_TYPE_GAU0) ||
1629         (context->config.h_scale_coef_type == FILTER_TYPE_GAU0_BOT) ||
1630         (context->config.h_scale_coef_type == FILTER_TYPE_GAU1)) {
1631         /* 1bit, 0: using minus, 1: using repeat data */
1632         dp_gen_cfg->src1_hsc_rpt_ctrl = ge2d_config->src1_hsc_rpt_ctrl;
1633         /* 1bit, 0: using minus  1: using repeat data */
1634         dp_gen_cfg->src1_vsc_rpt_ctrl = ge2d_config->src1_vsc_rpt_ctrl;
1635     } else {
1636         /* 1bit, 0: using minus, 1: using repeat data */
1637         dp_gen_cfg->src1_hsc_rpt_ctrl = 1;
1638         /* 1bit, 0: using minus  1: using repeat data */
1639         dp_gen_cfg->src1_vsc_rpt_ctrl = 1;
1640     }
1641     dp_gen_cfg->src1_gb_alpha = ge2d_config->src1_gb_alpha & 0xff;
1642     dp_gen_cfg->src1_gb_alpha_en = ge2d_config->src1_gb_alpha_en & 1;
1643 #ifdef CONFIG_GE2D_SRC2
1644     dp_gen_cfg->src2_gb_alpha = ge2d_config->src2_gb_alpha & 0xff;
1645     dp_gen_cfg->src2_gb_alpha_en = ge2d_config->src2_gb_alpha_en & 1;
1646 #endif
1647     dp_gen_cfg->src2_key_en = ge2d_config->src2_key.key_enable;
1648     dp_gen_cfg->src2_key_mode = ge2d_config->src2_key.key_mode;
1649     dp_gen_cfg->src2_key = ge2d_config->src2_key.key_color;
1650     dp_gen_cfg->src2_key_mask = ge2d_config->src2_key.key_mask;
1651 
1652     dp_gen_cfg->bitmask_en = ge2d_config->bitmask_en;
1653     dp_gen_cfg->bitmask = ge2d_config->bitmask;
1654     dp_gen_cfg->bytemask_only = ge2d_config->bytemask_only;
1655 
1656     ge2d_cmd_cfg = ge2d_wq_get_cmd(context);
1657 
1658     ge2d_cmd_cfg->src1_fill_color_en = ge2d_config->src_para.fill_color_en;
1659 
1660     ge2d_cmd_cfg->src2_x_rev = ge2d_config->src2_para.x_rev;
1661     ge2d_cmd_cfg->src2_y_rev = ge2d_config->src2_para.y_rev;
1662     ge2d_cmd_cfg->src2_fill_color_en = ge2d_config->src2_para.fill_color_en;
1663 #ifdef CONFIG_GE2D_SRC2
1664     ge2d_cmd_cfg->src2_cmult_ad = ge2d_config->src2_cmult_ad;
1665 #endif
1666 
1667     ge2d_cmd_cfg->vsc_phase_slope = ge2d_config->vsc_phase_slope;
1668     ge2d_cmd_cfg->vsc_ini_phase = ge2d_config->vf_init_phase;
1669     ge2d_cmd_cfg->vsc_phase_step = ge2d_config->vsc_start_phase_step;
1670     ge2d_cmd_cfg->vsc_rpt_l0_num = ge2d_config->vf_rpt_num;
1671 
1672     /* let internal decide */
1673     ge2d_cmd_cfg->hsc_phase_slope = ge2d_config->hsc_phase_slope;
1674     ge2d_cmd_cfg->hsc_ini_phase = ge2d_config->hf_init_phase;
1675     ge2d_cmd_cfg->hsc_phase_step = ge2d_config->hsc_start_phase_step;
1676     ge2d_cmd_cfg->hsc_rpt_p0_num = ge2d_config->hf_rpt_num;
1677     ge2d_cmd_cfg->src1_cmult_asel = ge2d_config->src1_cmult_asel;
1678     ge2d_cmd_cfg->src2_cmult_asel = ge2d_config->src2_cmult_asel;
1679 
1680     ge2d_cmd_cfg->src1_fmt = ge2d_config->src_para.format;
1681     ge2d_cmd_cfg->src2_fmt = ge2d_config->src2_para.format;
1682     ge2d_cmd_cfg->dst_fmt = ge2d_config->dst_para.format;
1683 
1684     context->config.update_flag = UPDATE_ALL;
1685 
1686     return 0;
1687 }
ge2d_context_config_ex_mem(struct ge2d_context_s * context,struct config_para_ex_memtype_s * ge2d_config_mem)1688 int ge2d_context_config_ex_mem(struct ge2d_context_s *context, struct config_para_ex_memtype_s *ge2d_config_mem)
1689 {
1690     struct src_dst_para_s tmp;
1691     struct ge2d_src1_gen_s *src1_gen_cfg;
1692     struct ge2d_src2_dst_data_s *src2_dst_data_cfg;
1693     struct ge2d_src2_dst_gen_s *src2_dst_gen_cfg;
1694     struct ge2d_dp_gen_s *dp_gen_cfg;
1695     struct ge2d_cmd_s *ge2d_cmd_cfg;
1696     int top, left, width, height;
1697     unsigned int src_addr = 0, src2_addr = 0, dst_addr = 0;
1698     unsigned int src_stride = 0, src2_stride = 0, dst_stride = 0;
1699     struct config_para_ex_ion_s *ge2d_config;
1700     int i;
1701 
1702     ge2d_config = &(ge2d_config_mem->_ge2d_config_ex);
1703     /* reset dms_used flag */
1704     for (i = 0; i < MAX_PLANE; i++) {
1705         context->config.src_dma_cfg[i].dma_used = 0;
1706         context->config.src2_dma_cfg[i].dma_used = 0;
1707         context->config.dst_dma_cfg[i].dma_used = 0;
1708     }
1709     /* setup src and dst */
1710     switch (ge2d_config->src_para.mem_type) {
1711         case CANVAS_OSD0:
1712         case CANVAS_OSD1:
1713             if (setup_display_property(&tmp, (ge2d_config->src_para.mem_type == CANVAS_OSD0) ? OSD1_CANVAS_INDEX
1714                                                                                              : OSD2_CANVAS_INDEX) < 0) {
1715                 return -1;
1716             }
1717             ge2d_config->src_para.canvas_index = tmp.canvas_index;
1718             ge2d_config->src_para.format = tmp.ge2d_color_index;
1719             src_addr = tmp.phy_addr;
1720             src_stride = tmp.stride;
1721 
1722             ge2d_log_dbg("ge2d: src1-->type: osd%d, format: 0x%x !!\n", ge2d_config->src_para.mem_type - CANVAS_OSD0,
1723                          ge2d_config->src_para.format);
1724 
1725             top = ge2d_config->src_para.top;
1726             left = ge2d_config->src_para.left;
1727             width = ge2d_config->src_para.width;
1728             height = ge2d_config->src_para.height;
1729             if ((left + width > tmp.xres) || (top + height > tmp.yres)) {
1730                 ge2d_log_dbg("ge2d src error: out of range\n");
1731                 return -1;
1732             }
1733             ge2d_config->src_para.width = tmp.xres;
1734             ge2d_config->src_para.height = tmp.yres;
1735             ge2d_log_dbg("ge2d osd phy_addr:0x%x,stride=0x%x,format:0x%x\n", src_addr, src_stride,
1736                          ge2d_config->src_para.format);
1737             break;
1738         case CANVAS_ALLOC:
1739             top = ge2d_config->src_para.top;
1740             left = ge2d_config->src_para.left;
1741             width = ge2d_config->src_para.width;
1742             height = ge2d_config->src_para.height;
1743             if ((left + width > ge2d_config->src_planes[0].w) || (top + height > ge2d_config->src_planes[0].h)) {
1744                 ge2d_log_dbg("ge2d error: src alloc, out of range\n");
1745                 return -1;
1746             }
1747             if (ge2d_meson_dev.canvas_status == 1) {
1748                 if (ge2d_config_mem->src1_mem_alloc_type == AML_GE2D_MEM_ION) {
1749                     if (build_ge2d_addr_config_ion(&ge2d_config->src_planes[0], ge2d_config->src_para.format, &src_addr,
1750                                                    &src_stride) < 0) {
1751                         return -1;
1752                     }
1753                     ge2d_log_dbg("ge2d ion alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", src_addr, src_stride,
1754                                  ge2d_config->src_para.format);
1755                 } else if (ge2d_config_mem->src1_mem_alloc_type == AML_GE2D_MEM_DMABUF) {
1756                     if (build_ge2d_addr_config_dma(context, &ge2d_config->src_planes[0], ge2d_config->src_para.format,
1757                                                    &src_addr, &src_stride, DMA_TO_DEVICE, AML_GE2D_SRC) < 0) {
1758                         return -1;
1759                     }
1760                     ge2d_log_dbg("ge2d dma alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", src_addr, src_stride,
1761                                  ge2d_config->src_para.format);
1762                 }
1763             } else {
1764                 if (ge2d_config_mem->src1_mem_alloc_type == AML_GE2D_MEM_ION) {
1765                     if (build_ge2d_config_ex_ion(context, &ge2d_config->src_planes[0], ge2d_config->src_para.format,
1766                                                  AML_GE2D_SRC) < 0) {
1767                         return -1;
1768                     }
1769                     ge2d_config->src_para.canvas_index = 0;
1770                     ge2d_log_dbg("ge2d ion alloc,format:0x%x\n", ge2d_config->src_para.format);
1771                 } else if (ge2d_config_mem->src1_mem_alloc_type == AML_GE2D_MEM_DMABUF) {
1772                     if (build_ge2d_config_ex_dma(context, &ge2d_config->src_planes[0], ge2d_config->src_para.format,
1773                                                  DMA_TO_DEVICE, AML_GE2D_SRC) < 0) {
1774                         return -1;
1775                     }
1776                     ge2d_config->src_para.canvas_index = 0;
1777                     ge2d_log_dbg("ge2d dma alloc,format:0x%x\n", ge2d_config->src_para.format);
1778                 }
1779             }
1780             break;
1781         default:
1782             break;
1783     }
1784 
1785     switch (ge2d_config->src2_para.mem_type) {
1786         case CANVAS_OSD0:
1787         case CANVAS_OSD1:
1788             if (setup_display_property(&tmp, (ge2d_config->src2_para.mem_type == CANVAS_OSD0)
1789                                                  ? OSD1_CANVAS_INDEX
1790                                                  : OSD2_CANVAS_INDEX) < 0) {
1791                 return -1;
1792             }
1793             ge2d_config->src2_para.canvas_index = tmp.canvas_index;
1794             ge2d_config->src2_para.format = tmp.ge2d_color_index;
1795             src2_addr = tmp.phy_addr;
1796             src2_stride = tmp.stride;
1797 
1798             ge2d_log_dbg("ge2d: src2-->type: osd%d, format: 0x%x !!\n", ge2d_config->src2_para.mem_type - CANVAS_OSD0,
1799                          ge2d_config->src2_para.format);
1800 
1801             top = ge2d_config->src2_para.top;
1802             left = ge2d_config->src2_para.left;
1803             width = ge2d_config->src2_para.width;
1804             height = ge2d_config->src2_para.height;
1805             if ((left + width > tmp.xres) || (top + height > tmp.yres)) {
1806                 ge2d_log_dbg("ge2d error: src2: osd%d, out of range\n", ge2d_config->src2_para.mem_type - CANVAS_OSD0);
1807                 return -1;
1808             }
1809             ge2d_config->src2_para.width = tmp.xres;
1810             ge2d_config->src2_para.height = tmp.yres;
1811             ge2d_log_dbg("ge2d osd phy_addr:0x%x,stride=0x%x,format:0x%x\n", src2_addr, src2_stride,
1812                          ge2d_config->src2_para.format);
1813             break;
1814         case CANVAS_ALLOC:
1815             top = ge2d_config->src2_para.top;
1816             left = ge2d_config->src2_para.left;
1817             width = ge2d_config->src2_para.width;
1818             height = ge2d_config->src2_para.height;
1819             if ((left + width > ge2d_config->src2_planes[0].w) || (top + height > ge2d_config->src2_planes[0].h)) {
1820                 ge2d_log_dbg("ge2d error: src2: alloc, out of range\n");
1821                 return -1;
1822             }
1823 
1824             if (ge2d_meson_dev.canvas_status == 1) {
1825                 if (ge2d_config_mem->src2_mem_alloc_type == AML_GE2D_MEM_ION) {
1826                     if (build_ge2d_addr_config_ion(&ge2d_config->src2_planes[0], ge2d_config->src2_para.format,
1827                                                    &src2_addr, &src2_stride) < 0) {
1828                         return -1;
1829                     }
1830                     ge2d_log_dbg("ge2d ion alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", src2_addr, src2_stride,
1831                                  ge2d_config->src2_para.format);
1832                 } else if (ge2d_config_mem->src2_mem_alloc_type == AML_GE2D_MEM_DMABUF) {
1833                     if (build_ge2d_addr_config_dma(context, &ge2d_config->src2_planes[0], ge2d_config->src2_para.format,
1834                                                    &src2_addr, &src2_stride, DMA_TO_DEVICE, AML_GE2D_SRC2) < 0)
1835                         return -1;
1836                     ge2d_log_dbg("ge2d dma alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", src2_addr, src2_stride,
1837                                  ge2d_config->src2_para.format);
1838                 }
1839             } else {
1840                 if (ge2d_config_mem->src2_mem_alloc_type == AML_GE2D_MEM_ION) {
1841                     if (build_ge2d_config_ex_ion(context, &ge2d_config->src2_planes[0], ge2d_config->src2_para.format,
1842                                                  AML_GE2D_SRC2) < 0) {
1843                         return -1;
1844                     }
1845                     ge2d_config->src2_para.canvas_index = 0;
1846                     ge2d_log_dbg("ge2d src2 ion alloc,format:0x%x\n", ge2d_config->src2_para.format);
1847                 } else if (ge2d_config_mem->src2_mem_alloc_type == AML_GE2D_MEM_DMABUF) {
1848                     if (build_ge2d_config_ex_dma(context, &ge2d_config->src2_planes[0], ge2d_config->src2_para.format,
1849                                                  DMA_TO_DEVICE, AML_GE2D_SRC2) < 0) {
1850                         return -1;
1851                     }
1852                     ge2d_config->src2_para.canvas_index = 0;
1853                     ge2d_log_dbg("ge2d src2 dma alloc,format:0x%x\n", ge2d_config->src2_para.format);
1854                 }
1855             }
1856             break;
1857         default:
1858             break;
1859     }
1860 
1861     switch (ge2d_config->dst_para.mem_type) {
1862         case CANVAS_OSD0:
1863         case CANVAS_OSD1:
1864             if (setup_display_property(&tmp, (ge2d_config->dst_para.mem_type == CANVAS_OSD0) ? OSD1_CANVAS_INDEX
1865                                                                                              : OSD2_CANVAS_INDEX) < 0) {
1866                 return -1;
1867             }
1868             ge2d_config->dst_para.canvas_index = tmp.canvas_index;
1869             ge2d_config->dst_para.format = tmp.ge2d_color_index;
1870             dst_addr = tmp.phy_addr;
1871             dst_stride = tmp.stride;
1872 
1873             ge2d_log_dbg("ge2d: dst-->type: osd%d, format: 0x%x !!\n", ge2d_config->dst_para.mem_type - CANVAS_OSD0,
1874                          ge2d_config->dst_para.format);
1875 
1876             top = ge2d_config->dst_para.top;
1877             left = ge2d_config->dst_para.left;
1878             width = ge2d_config->dst_para.width;
1879             height = ge2d_config->dst_para.height;
1880             if ((left + width > tmp.xres) || (top + height > tmp.yres)) {
1881                 ge2d_log_dbg("ge2d error: dst: osd%d, out of range\n", ge2d_config->dst_para.mem_type - CANVAS_OSD0);
1882                 return -1;
1883             }
1884             ge2d_config->dst_para.width = tmp.xres;
1885             ge2d_config->dst_para.height = tmp.yres;
1886             ge2d_log_dbg("ge2d osd phy_addr:0x%x,stride=0x%x,format:0x%x\n", dst_addr, dst_stride,
1887                          ge2d_config->dst_para.format);
1888             break;
1889         case CANVAS_ALLOC:
1890             top = ge2d_config->dst_para.top;
1891             left = ge2d_config->dst_para.left;
1892             width = ge2d_config->dst_para.width;
1893             height = ge2d_config->dst_para.height;
1894             if ((left + width > ge2d_config->dst_planes[0].w) || (top + height > ge2d_config->dst_planes[0].h)) {
1895                 ge2d_log_dbg("ge2d error: dst: alloc, out of range\n");
1896                 return -1;
1897             }
1898 
1899             if (ge2d_meson_dev.canvas_status == 1) {
1900                 if (ge2d_config_mem->dst_mem_alloc_type == AML_GE2D_MEM_ION) {
1901                     if (build_ge2d_addr_config_ion(&ge2d_config->dst_planes[0], ge2d_config->dst_para.format, &dst_addr,
1902                                                    &dst_stride) < 0) {
1903                         return -1;
1904                     }
1905                     ge2d_log_dbg("ge2d ion alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", dst_addr, dst_stride,
1906                                  ge2d_config->dst_para.format);
1907                 } else if (ge2d_config_mem->dst_mem_alloc_type == AML_GE2D_MEM_DMABUF) {
1908                     if (build_ge2d_addr_config_dma(context, &ge2d_config->dst_planes[0], ge2d_config->dst_para.format,
1909                                                    &dst_addr, &dst_stride, DMA_FROM_DEVICE, AML_GE2D_DST) < 0) {
1910                         return -1;
1911                     }
1912                     ge2d_log_dbg("ge2d dma alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", dst_addr, dst_stride,
1913                                  ge2d_config->dst_para.format);
1914                 }
1915             } else {
1916                 if (ge2d_config_mem->dst_mem_alloc_type == AML_GE2D_MEM_ION) {
1917                     if (build_ge2d_config_ex_ion(context, &ge2d_config->dst_planes[0], ge2d_config->dst_para.format,
1918                                                  AML_GE2D_DST) < 0) {
1919                         return -1;
1920                     }
1921                     ge2d_config->dst_para.canvas_index = 0;
1922                     ge2d_log_dbg("ge2d: dst ion alloc,format:0x%x\n", ge2d_config->dst_para.format);
1923                 } else if (ge2d_config_mem->dst_mem_alloc_type == AML_GE2D_MEM_DMABUF) {
1924                     if (build_ge2d_config_ex_dma(context, &ge2d_config->dst_planes[0], ge2d_config->dst_para.format,
1925                                                  DMA_FROM_DEVICE, AML_GE2D_DST) < 0) {
1926                         return -1;
1927                     }
1928                     ge2d_config->dst_para.canvas_index = 0;
1929                     ge2d_log_dbg("ge2d: dst dma alloc,format:0x%x\n", ge2d_config->dst_para.format);
1930                 }
1931             }
1932             break;
1933         default:
1934             break;
1935     }
1936 
1937     ge2dgen_rendering_dir(context, ge2d_config->src_para.x_rev, ge2d_config->src_para.y_rev,
1938                           ge2d_config->dst_para.x_rev, ge2d_config->dst_para.y_rev, ge2d_config->dst_xy_swap);
1939     ge2dgen_const_color(context, ge2d_config->alu_const_color);
1940 
1941     ge2dgen_src(context, ge2d_config->src_para.canvas_index, ge2d_config->src_para.format, src_addr, src_stride);
1942     ge2dgen_src_clip(context, ge2d_config->src_para.left, ge2d_config->src_para.top, ge2d_config->src_para.width,
1943                      ge2d_config->src_para.height);
1944     ge2dgen_src_key(context, ge2d_config->src_key.key_enable, ge2d_config->src_key.key_color,
1945                     ge2d_config->src_key.key_mask, ge2d_config->src_key.key_mode);
1946 #ifdef CONFIG_GE2D_SRC2
1947     ge2dgent_src_gbalpha(context, ge2d_config->src1_gb_alpha, ge2d_config->src2_gb_alpha);
1948 #else
1949     ge2dgent_src_gbalpha(context, ge2d_config->src1_gb_alpha, 0);
1950 #endif
1951     ge2dgen_src_color(context, ge2d_config->src_para.color);
1952 
1953     ge2dgen_src2(context, ge2d_config->src2_para.canvas_index, ge2d_config->src2_para.format, src2_addr, src2_stride);
1954     ge2dgen_src2_clip(context, ge2d_config->src2_para.left, ge2d_config->src2_para.top, ge2d_config->src2_para.width,
1955                       ge2d_config->src2_para.height);
1956 
1957     ge2dgen_dst(context, ge2d_config->dst_para.canvas_index, ge2d_config->dst_para.format, dst_addr, dst_stride);
1958     ge2dgen_dst_clip(context, ge2d_config->dst_para.left, ge2d_config->dst_para.top, ge2d_config->dst_para.width,
1959                      ge2d_config->dst_para.height, DST_CLIP_MODE_INSIDE);
1960 
1961     src1_gen_cfg = ge2d_wq_get_src_gen(context);
1962     src1_gen_cfg->fill_mode = ge2d_config->src_para.fill_mode;
1963     src1_gen_cfg->chfmt_rpt_pix = 0;
1964     src1_gen_cfg->cvfmt_rpt_pix = 0;
1965 
1966     src2_dst_data_cfg = ge2d_wq_get_dst_data(context);
1967     src2_dst_data_cfg->src2_def_color = ge2d_config->src2_para.color;
1968 
1969     src2_dst_gen_cfg = ge2d_wq_get_dst_gen(context);
1970     src2_dst_gen_cfg->src2_fill_mode = ge2d_config->src2_para.fill_mode;
1971 
1972     dp_gen_cfg = ge2d_wq_get_dp_gen(context);
1973 
1974     dp_gen_cfg->src1_vsc_phase0_always_en = ge2d_config->src1_hsc_phase0_always_en;
1975     dp_gen_cfg->src1_hsc_phase0_always_en = ge2d_config->src1_vsc_phase0_always_en;
1976     if ((context->config.v_scale_coef_type == FILTER_TYPE_GAU0) ||
1977         (context->config.v_scale_coef_type == FILTER_TYPE_GAU0_BOT) ||
1978         (context->config.v_scale_coef_type == FILTER_TYPE_GAU1) ||
1979         (context->config.h_scale_coef_type == FILTER_TYPE_GAU0) ||
1980         (context->config.h_scale_coef_type == FILTER_TYPE_GAU0_BOT) ||
1981         (context->config.h_scale_coef_type == FILTER_TYPE_GAU1)) {
1982         /* 1bit, 0: using minus, 1: using repeat data */
1983         dp_gen_cfg->src1_hsc_rpt_ctrl = ge2d_config->src1_hsc_rpt_ctrl;
1984         /* 1bit, 0: using minus  1: using repeat data */
1985         dp_gen_cfg->src1_vsc_rpt_ctrl = ge2d_config->src1_vsc_rpt_ctrl;
1986     } else {
1987         /* 1bit, 0: using minus, 1: using repeat data */
1988         dp_gen_cfg->src1_hsc_rpt_ctrl = 1;
1989         /* 1bit, 0: using minus  1: using repeat data */
1990         dp_gen_cfg->src1_vsc_rpt_ctrl = 1;
1991     }
1992     dp_gen_cfg->src1_gb_alpha = ge2d_config->src1_gb_alpha & 0xff;
1993     dp_gen_cfg->src1_gb_alpha_en = ge2d_config->src1_gb_alpha_en & 1;
1994 #ifdef CONFIG_GE2D_SRC2
1995     dp_gen_cfg->src2_gb_alpha = ge2d_config->src2_gb_alpha & 0xff;
1996     dp_gen_cfg->src2_gb_alpha_en = ge2d_config->src2_gb_alpha_en & 1;
1997 #endif
1998     dp_gen_cfg->src2_key_en = ge2d_config->src2_key.key_enable;
1999     dp_gen_cfg->src2_key_mode = ge2d_config->src2_key.key_mode;
2000     dp_gen_cfg->src2_key = ge2d_config->src2_key.key_color;
2001     dp_gen_cfg->src2_key_mask = ge2d_config->src2_key.key_mask;
2002 
2003     dp_gen_cfg->bitmask_en = ge2d_config->bitmask_en;
2004     dp_gen_cfg->bitmask = ge2d_config->bitmask;
2005     dp_gen_cfg->bytemask_only = ge2d_config->bytemask_only;
2006 
2007     ge2d_cmd_cfg = ge2d_wq_get_cmd(context);
2008 
2009     ge2d_cmd_cfg->src1_fill_color_en = ge2d_config->src_para.fill_color_en;
2010 
2011     ge2d_cmd_cfg->src2_x_rev = ge2d_config->src2_para.x_rev;
2012     ge2d_cmd_cfg->src2_y_rev = ge2d_config->src2_para.y_rev;
2013     ge2d_cmd_cfg->src2_fill_color_en = ge2d_config->src2_para.fill_color_en;
2014 #ifdef CONFIG_GE2D_SRC2
2015     ge2d_cmd_cfg->src2_cmult_ad = ge2d_config->src2_cmult_ad;
2016 #endif
2017 
2018     ge2d_cmd_cfg->vsc_phase_slope = ge2d_config->vsc_phase_slope;
2019     ge2d_cmd_cfg->vsc_ini_phase = ge2d_config->vf_init_phase;
2020     ge2d_cmd_cfg->vsc_phase_step = ge2d_config->vsc_start_phase_step;
2021     ge2d_cmd_cfg->vsc_rpt_l0_num = ge2d_config->vf_rpt_num;
2022 
2023     /* let internal decide */
2024     ge2d_cmd_cfg->hsc_phase_slope = ge2d_config->hsc_phase_slope;
2025     ge2d_cmd_cfg->hsc_ini_phase = ge2d_config->hf_init_phase;
2026     ge2d_cmd_cfg->hsc_phase_step = ge2d_config->hsc_start_phase_step;
2027     ge2d_cmd_cfg->hsc_rpt_p0_num = ge2d_config->hf_rpt_num;
2028     ge2d_cmd_cfg->src1_cmult_asel = ge2d_config->src1_cmult_asel;
2029     ge2d_cmd_cfg->src2_cmult_asel = ge2d_config->src2_cmult_asel;
2030     context->config.update_flag = UPDATE_ALL;
2031 
2032     memcpy(&context->config.matrix_custom, &ge2d_config_mem->matrix_custom, sizeof(struct ge2d_matrix_s));
2033 
2034     return 0;
2035 }
2036 
ge2d_buffer_alloc(struct ge2d_dmabuf_req_s * ge2d_req_buf)2037 int ge2d_buffer_alloc(struct ge2d_dmabuf_req_s *ge2d_req_buf)
2038 {
2039     struct device *dev;
2040 
2041     dev = &(ge2d_manager.pdev->dev);
2042     return ge2d_dma_buffer_alloc(ge2d_manager.buffer, dev, ge2d_req_buf);
2043 }
2044 
ge2d_buffer_export(struct ge2d_dmabuf_exp_s * ge2d_exp_buf)2045 int ge2d_buffer_export(struct ge2d_dmabuf_exp_s *ge2d_exp_buf)
2046 {
2047     return ge2d_dma_buffer_export(ge2d_manager.buffer, ge2d_exp_buf);
2048 }
2049 
ge2d_buffer_free(int index)2050 int ge2d_buffer_free(int index)
2051 {
2052     return ge2d_dma_buffer_free(ge2d_manager.buffer, index);
2053 }
2054 
ge2d_buffer_dma_flush(int dma_fd)2055 void ge2d_buffer_dma_flush(int dma_fd)
2056 {
2057     struct device *dev;
2058 
2059     dev = &(ge2d_manager.pdev->dev);
2060     ge2d_dma_buffer_dma_flush(dev, dma_fd);
2061 }
2062 
ge2d_buffer_cache_flush(int dma_fd)2063 void ge2d_buffer_cache_flush(int dma_fd)
2064 {
2065     struct device *dev;
2066 
2067     dev = &(ge2d_manager.pdev->dev);
2068     ge2d_dma_buffer_cache_flush(dev, dma_fd);
2069 }
2070 
ge2d_buffer_get_phys(struct aml_dma_cfg * cfg,unsigned long * addr)2071 static int ge2d_buffer_get_phys(struct aml_dma_cfg *cfg, unsigned long *addr)
2072 {
2073     return ge2d_dma_buffer_get_phys(ge2d_manager.buffer, cfg, addr);
2074 }
2075 
ge2d_buffer_unmap(struct aml_dma_cfg * cfg)2076 static int ge2d_buffer_unmap(struct aml_dma_cfg *cfg)
2077 {
2078     return ge2d_dma_buffer_unmap_info(ge2d_manager.buffer, cfg);
2079 }
2080 
create_ge2d_work_queue(void)2081 struct ge2d_context_s *create_ge2d_work_queue(void)
2082 {
2083     int i;
2084     struct ge2d_queue_item_s *p_item;
2085     struct ge2d_context_s *ge2d_work_queue;
2086     int empty;
2087 
2088     if (!ge2d_manager.probe) {
2089         return NULL;
2090     }
2091     ge2d_work_queue = kzalloc(sizeof(struct ge2d_context_s), GFP_KERNEL);
2092     ge2d_work_queue->config.h_scale_coef_type = FILTER_TYPE_BILINEAR;
2093     ge2d_work_queue->config.v_scale_coef_type = FILTER_TYPE_BILINEAR;
2094     ge2d_work_queue->ge2d_request_exit = 0;
2095     if (IS_ERR(ge2d_work_queue)) {
2096         ge2d_log_err("can't create work queue\n");
2097         return NULL;
2098     }
2099     INIT_LIST_HEAD(&ge2d_work_queue->work_queue);
2100     INIT_LIST_HEAD(&ge2d_work_queue->free_queue);
2101     init_waitqueue_head(&ge2d_work_queue->cmd_complete);
2102     spin_lock_init(&ge2d_work_queue->lock); /* for process lock. */
2103     for (i = 0; i < MAX_GE2D_CMD; i++) {
2104         p_item = kcalloc(1, sizeof(struct ge2d_queue_item_s), GFP_KERNEL);
2105         if (IS_ERR(p_item)) {
2106             ge2d_log_err("can't request queue item memory\n");
2107             return NULL;
2108         }
2109         list_add_tail(&p_item->list, &ge2d_work_queue->free_queue);
2110     }
2111 
2112     /* put this process queue  into manager queue list. */
2113     /* maybe process queue is changing . */
2114     spin_lock(&ge2d_manager.event.sem_lock);
2115     empty = list_empty(&ge2d_manager.process_queue);
2116     list_add_tail(&ge2d_work_queue->list, &ge2d_manager.process_queue);
2117     spin_unlock(&ge2d_manager.event.sem_lock);
2118     return ge2d_work_queue; /* find it */
2119 }
2120 EXPORT_SYMBOL(create_ge2d_work_queue);
2121 
destroy_ge2d_work_queue(struct ge2d_context_s * ge2d_work_queue)2122 int destroy_ge2d_work_queue(struct ge2d_context_s *ge2d_work_queue)
2123 {
2124     struct ge2d_queue_item_s *pitem, *tmp;
2125     struct list_head *head;
2126     int empty, timeout = 0;
2127 
2128     if (ge2d_work_queue) {
2129         /* first detatch it from the process queue,then delete it . */
2130         /* maybe process queue is changing .so we lock it. */
2131         spin_lock(&ge2d_manager.event.sem_lock);
2132         list_del(&ge2d_work_queue->list);
2133         empty = list_empty(&ge2d_manager.process_queue);
2134         spin_unlock(&ge2d_manager.event.sem_lock);
2135         if ((ge2d_manager.current_wq == ge2d_work_queue) && (ge2d_manager.ge2d_state == GE2D_STATE_RUNNING)) {
2136             ge2d_work_queue->ge2d_request_exit = 1;
2137             timeout = wait_for_completion_timeout(&ge2d_manager.event.process_complete, msecs_to_jiffies(500L));
2138             if (!timeout) {
2139                 ge2d_log_err("wait timeout\n");
2140             }
2141             /* condition so complex ,simplify it . */
2142             ge2d_manager.last_wq = NULL;
2143         } /* else we can delete it safely. */
2144 
2145         head = &ge2d_work_queue->work_queue;
2146         list_for_each_entry_safe(pitem, tmp, head, list)
2147         {
2148             if (pitem) {
2149                 list_del(&pitem->list);
2150                 kfree(pitem);
2151             }
2152         }
2153         head = &ge2d_work_queue->free_queue;
2154         list_for_each_entry_safe(pitem, tmp, head, list)
2155         {
2156             if (pitem) {
2157                 list_del(&pitem->list);
2158                 kfree(pitem);
2159             }
2160         }
2161 
2162         kfree(ge2d_work_queue);
2163         ge2d_work_queue = NULL;
2164         return 0;
2165     }
2166 
2167     return -1;
2168 }
2169 EXPORT_SYMBOL(destroy_ge2d_work_queue);
2170 
ge2d_wq_init(struct platform_device * pdev,int irq,struct clk * clk)2171 int ge2d_wq_init(struct platform_device *pdev, int irq, struct clk *clk)
2172 {
2173     ge2d_manager.pdev = pdev;
2174     ge2d_irq = irq;
2175     ge2d_clk = clk;
2176 
2177     ge2d_log_info("ge2d: pdev=%px, irq=%d, clk=%px\n", pdev, irq, clk);
2178 
2179     ge2d_manager.irq_num = request_irq(ge2d_irq, ge2d_wq_handle, IRQF_SHARED, "ge2d", (void *)&ge2d_manager);
2180     if (ge2d_manager.irq_num < 0) {
2181         ge2d_log_err("ge2d request irq error\n");
2182         return -1;
2183     }
2184 
2185     /* prepare bottom half */
2186     spin_lock_init(&ge2d_manager.event.sem_lock);
2187     sema_init(&ge2d_manager.event.cmd_in_sem, 1);
2188     init_waitqueue_head(&ge2d_manager.event.cmd_complete);
2189     init_completion(&ge2d_manager.event.process_complete);
2190     INIT_LIST_HEAD(&ge2d_manager.process_queue);
2191     ge2d_manager.last_wq = NULL;
2192     ge2d_manager.ge2d_thread = NULL;
2193     ge2d_manager.buffer = ge2d_dma_buffer_create();
2194     if (!ge2d_manager.buffer) {
2195         return -1;
2196     }
2197 
2198     if (ge2d_start_monitor()) {
2199         ge2d_log_err("ge2d create thread error\n");
2200         return -1;
2201     }
2202     ge2d_manager.probe = 1;
2203     return 0;
2204 }
2205 
ge2d_wq_deinit(void)2206 int ge2d_wq_deinit(void)
2207 {
2208     ge2d_stop_monitor();
2209     ge2d_log_info("deinit ge2d device\n");
2210     if (ge2d_manager.irq_num >= 0) {
2211         free_irq(ge2d_manager.irq_num, &ge2d_manager);
2212         ge2d_manager.irq_num = -1;
2213     }
2214     ge2d_irq = -1;
2215     clk_disable_unprepare(ge2d_clk);
2216     ge2d_dma_buffer_destroy(ge2d_manager.buffer);
2217     ge2d_manager.buffer = NULL;
2218     ge2d_manager.pdev = NULL;
2219 
2220     return 0;
2221 }
2222