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