1 /*
2 * vendor/amlogic/media/common/ge2d/ge2d_hw.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 /* Linux Headers */
19 #include <linux/types.h>
20
21 /* Amlogic Headers */
22 #include <linux/amlogic/cpu_version.h>
23 #include <linux/amlogic/media/ge2d/ge2d.h>
24
25 /* Local Headers */
26 #include "ge2d_log.h"
27 #include "ge2d_io.h"
28 #include "ge2d_reg.h"
29
30 #define GE2D_DST1_INDEX 0
31 #define GE2D_SRC1_INDEX 1
32 #define GE2D_SRC2_INDEX 2
33 static int gaul_filter_used;
34 static const unsigned int filt_coef_gau1[] = { /* gau1+phase */
35 0x20402000, 0x203f2001, 0x203e2002, 0x203d2003, 0x203c2004, 0x203b2005,
36 0x203a2006, 0x20392007, 0x20382008, 0x20372009, 0x2036200a, 0x2035200b,
37 0x2034200c, 0x2033200d, 0x2032200e, 0x2031200f, 0x20302010, 0x202f2011,
38 0x202e2012, 0x202d2013, 0x202c2014, 0x202b2015, 0x202a2016, 0x20292017,
39 0x20282018, 0x20272019, 0x2026201a, 0x2025201b, 0x2024201c, 0x2023201d,
40 0x2022201e, 0x2021201f, 0x20202020};
41
42 /* average, no phase, horizontal filter and vertical filter for top field */
43 static const unsigned int filt_coef_gau0[] = {
44 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
45 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
46 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
47 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020};
48
49 /* average, no phase, only for vertical filter of bot filed */
50 static const unsigned int filt_coef_gau0_bot[] = {
51 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00,
52 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00,
53 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00,
54 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00, 0x2a2b2a00};
55
56 static const unsigned int filt_coef0[] = { /* bicubic */
57 0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300, 0xfd7e0500, 0xfc7e0600,
58 0xfb7d0800, 0xfb7c0900, 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
59 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe, 0xf76f1dfd, 0xf76d1ffd,
60 0xf76b21fd, 0xf76824fd, 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
61 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa, 0xf8523cfa, 0xf8503ff9,
62 0xf84d42f9, 0xf84a45f9, 0xf84848f8};
63
64 static const unsigned int filt_coef1[] = { /* 2 point bilinear */
65 0x00800000, 0x007e0200, 0x007c0400, 0x007a0600, 0x00780800, 0x00760a00,
66 0x00740c00, 0x00720e00, 0x00701000, 0x006e1200, 0x006c1400, 0x006a1600,
67 0x00681800, 0x00661a00, 0x00641c00, 0x00621e00, 0x00602000, 0x005e2200,
68 0x005c2400, 0x005a2600, 0x00582800, 0x00562a00, 0x00542c00, 0x00522e00,
69 0x00503000, 0x004e3200, 0x004c3400, 0x004a3600, 0x00483800, 0x00463a00,
70 0x00443c00, 0x00423e00, 0x00404000};
71
72 static const unsigned int filt_coef2[] = { /* 3 point triangle */
73 0x40400000, 0x3f400100, 0x3d410200, 0x3c410300, 0x3a420400, 0x39420500,
74 0x37430600, 0x36430700, 0x35430800, 0x33450800, 0x32450900, 0x31450a00,
75 0x30450b00, 0x2e460c00, 0x2d460d00, 0x2c470d00, 0x2b470e00, 0x29480f00,
76 0x28481000, 0x27481100, 0x26491100, 0x25491200, 0x24491300, 0x234a1300,
77 0x224a1400, 0x214a1500, 0x204a1600, 0x1f4b1600, 0x1e4b1700, 0x1d4b1800,
78 0x1c4c1800, 0x1b4c1900, 0x1a4c1a00};
79 static const unsigned int filt_coef3[] = { /* 3 point triangle */
80 0x20402000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
83
ge2d_canv_config(u32 index,u32 addr,u32 stride)84 void ge2d_canv_config(u32 index, u32 addr, u32 stride)
85 {
86 ge2d_log_dbg("ge2d_canv_config:index=%d,addr=%x,stride=%d\n", index, addr, stride);
87 if (index <= 2L) {
88 ge2d_reg_write(GE2D_DST1_BADDR_CTRL + index * 2L, ((addr + 7L) >> 3L));
89 ge2d_reg_write(GE2D_DST1_STRIDE_CTRL + index * 2L, ((stride + 7L) >> 3L));
90 }
91 }
92
ge2d_set_src1_data(struct ge2d_src1_data_s * cfg)93 void ge2d_set_src1_data(struct ge2d_src1_data_s *cfg)
94 {
95 ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->urgent_en, 10L, 1);
96
97 ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->ddr_burst_size_y, 20L, 2L);
98 ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->ddr_burst_size_cb, 18L, 2L);
99 ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->ddr_burst_size_cr, 16L, 2L);
100
101 if (ge2d_meson_dev.canvas_status == 1) {
102 ge2d_canv_config(GE2D_SRC1_INDEX, cfg->phy_addr, cfg->stride);
103 } else {
104 ge2d_reg_write(GE2D_SRC1_CANVAS, ((cfg->canaddr & 0xff) << 24L) | (((cfg->canaddr >> 8L) & 0xff) << 16L) |
105 (((cfg->canaddr >> 16L) & 0xff) << 8L));
106 }
107
108 ge2d_reg_set_bits(GE2D_GEN_CTRL0, ((cfg->x_yc_ratio << 1) | cfg->y_yc_ratio), 10L, 2L);
109 ge2d_reg_set_bits(GE2D_GEN_CTRL0, cfg->sep_en, 0, 1);
110 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->endian, 7L, 1);
111 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->color_map, 3L, 4L);
112 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->format, 0, 2L);
113 if (ge2d_meson_dev.deep_color == 1) {
114 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->deep_color, 2L, 1);
115 }
116 if (ge2d_meson_dev.canvas_status == 1) {
117 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->mult_rounding, 18L, 1);
118 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->alpha_conv_mode0, 31L, 1);
119 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->alpha_conv_mode1, 10L, 1);
120 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->color_conv_mode0, 30L, 1);
121 ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->color_conv_mode1, 26L, 1);
122 }
123 ge2d_reg_set_bits(GE2D_GEN_CTRL0, cfg->mode_8b_sel, 5L, 2L);
124 ge2d_reg_set_bits(GE2D_GEN_CTRL0, cfg->lut_en, 3L, 1);
125
126 ge2d_reg_write(GE2D_SRC1_DEF_COLOR, cfg->def_color);
127 if (cfg->x_yc_ratio) {
128 /* horizontal formatter enable */
129 ge2d_reg_set_bits(GE2D_SRC1_FMT_CTRL, 1, 18L, 1);
130 } else {
131 /* horizontal formatter disable */
132 ge2d_reg_set_bits(GE2D_SRC1_FMT_CTRL, 0, 18L, 1);
133 }
134 if (cfg->y_yc_ratio) {
135 /* vertical formatter enable */
136 ge2d_reg_set_bits(GE2D_SRC1_FMT_CTRL, 1, 16L, 1);
137 } else {
138 /* vertical formatter disable */
139 ge2d_reg_set_bits(GE2D_SRC1_FMT_CTRL, 0, 16L, 1);
140 }
141 }
142
ge2d_set_src1_scale_coef(unsigned int v_filt_type,unsigned int h_filt_type)143 void ge2d_set_src1_scale_coef(unsigned int v_filt_type, unsigned int h_filt_type)
144 {
145 int i;
146
147 /* write vert filter coefs */
148 ge2d_reg_write(GE2D_SCALE_COEF_IDX, 0x0000);
149 if ((v_filt_type == FILTER_TYPE_GAU0) || (v_filt_type == FILTER_TYPE_GAU0_BOT) ||
150 (v_filt_type == FILTER_TYPE_GAU1) || (h_filt_type == FILTER_TYPE_GAU0) ||
151 (h_filt_type == FILTER_TYPE_GAU0_BOT) || (h_filt_type == FILTER_TYPE_GAU1)) {
152 gaul_filter_used = 1;
153 } else {
154 gaul_filter_used = 0;
155 }
156 for (i = 0; i < 33L; i++) {
157 if (v_filt_type == FILTER_TYPE_BICUBIC) {
158 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef0[i]);
159 } else if (v_filt_type == FILTER_TYPE_BILINEAR) {
160 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef1[i]);
161 } else if (v_filt_type == FILTER_TYPE_TRIANGLE) {
162 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef2[i]);
163 } else if (v_filt_type == FILTER_TYPE_GAU0) {
164 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef_gau0[i]);
165 } else if (v_filt_type == FILTER_TYPE_GAU0_BOT) {
166 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef_gau0_bot[i]);
167 } else if (v_filt_type == FILTER_TYPE_GAU1) {
168 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef_gau1[i]);
169 } else {
170 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef3[i]);
171 }
172 }
173
174 /* write horz filter coefs */
175 ge2d_reg_write(GE2D_SCALE_COEF_IDX, 0x0100);
176 for (i = 0; i < 33L; i++) {
177 if (h_filt_type == FILTER_TYPE_BICUBIC) {
178 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef0[i]);
179 } else if (h_filt_type == FILTER_TYPE_BILINEAR) {
180 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef1[i]);
181 } else if (h_filt_type == FILTER_TYPE_TRIANGLE) {
182 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef2[i]);
183 } else if (h_filt_type == FILTER_TYPE_GAU0) {
184 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef_gau0[i]);
185 } else if (h_filt_type == FILTER_TYPE_GAU0_BOT) {
186 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef_gau0_bot[i]);
187 } else if (h_filt_type == FILTER_TYPE_GAU1) {
188 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef_gau1[i]);
189 } else {
190 ge2d_reg_write(GE2D_SCALE_COEF, filt_coef3[i]);
191 }
192 }
193 }
194
ge2d_set_src1_gen(struct ge2d_src1_gen_s * cfg)195 void ge2d_set_src1_gen(struct ge2d_src1_gen_s *cfg)
196 {
197 ge2d_reg_write(GE2D_SRC1_CLIPX_START_END, (cfg->clipx_start_ex << 31L) | (cfg->clipx_start << 16L) |
198 (cfg->clipx_end_ex << 15L) | (cfg->clipx_end << 0));
199
200 ge2d_reg_write(GE2D_SRC1_CLIPY_START_END, (cfg->clipy_start_ex << 31L) | (cfg->clipy_start << 16L) |
201 (cfg->clipy_end_ex << 15L) | (cfg->clipy_end << 0));
202
203 ge2d_reg_set_bits(GE2D_GEN_CTRL0, cfg->pic_struct, 1, 2L);
204 ge2d_reg_set_bits(GE2D_GEN_CTRL0, (cfg->fill_mode & 0x1), 4L, 1);
205
206 ge2d_reg_set_bits(GE2D_SRC_OUTSIDE_ALPHA, ((cfg->fill_mode & 0x2) << 7L) | cfg->outside_alpha, 0, 9L);
207
208 ge2d_reg_set_bits(GE2D_SRC1_FMT_CTRL, cfg->chfmt_rpt_pix, 19L, 1);
209 ge2d_reg_set_bits(GE2D_SRC1_FMT_CTRL, cfg->cvfmt_rpt_pix, 17L, 1);
210 }
211
ge2d_set_src2_dst_data(struct ge2d_src2_dst_data_s * cfg)212 void ge2d_set_src2_dst_data(struct ge2d_src2_dst_data_s *cfg)
213 {
214 ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->urgent_en, 9L, 1);
215 ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->ddr_burst_size, 22L, 2L);
216
217 if (ge2d_meson_dev.canvas_status == 1) {
218 ge2d_canv_config(GE2D_SRC2_INDEX, cfg->src2_phyaddr, cfg->src2_stride);
219 ge2d_canv_config(GE2D_DST1_INDEX, cfg->dst_phyaddr, cfg->dst_stride);
220 } else {
221 /* only for m6 and later chips. */
222 ge2d_reg_write(GE2D_SRC2_DST_CANVAS, (cfg->src2_canaddr << 8L) | ((cfg->dst_canaddr & 0xff) << 0) |
223 ((cfg->dst_canaddr & 0xff00) << 8L));
224 }
225
226 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->src2_endian, 15L, 1);
227 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->src2_color_map, 11L, 4L);
228 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->src2_format, 8L, 2L);
229 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->dst_endian, 23L, 1);
230 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->dst_color_map, 19L, 4L);
231 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->dst_format, 16L, 2L);
232 ge2d_reg_set_bits(GE2D_GEN_CTRL0, cfg->src2_mode_8b_sel, 15L, 2L);
233 ge2d_reg_set_bits(GE2D_GEN_CTRL0, cfg->dst_mode_8b_sel, 24L, 2L);
234
235 ge2d_reg_set_bits(GE2D_GEN_CTRL3, cfg->dst2_pixel_byte_width, 16L, 2L);
236 ge2d_reg_set_bits(GE2D_GEN_CTRL3, cfg->dst2_color_map, 19L, 4L);
237 ge2d_reg_set_bits(GE2D_GEN_CTRL3, cfg->dst2_discard_mode, 10L, 4L);
238
239 ge2d_reg_set_bits(GE2D_GEN_CTRL3, cfg->dst2_enable, 8L, 1);
240 ge2d_reg_write(GE2D_SRC2_DEF_COLOR, cfg->src2_def_color);
241 }
242
ge2d_set_src2_dst_gen(struct ge2d_src2_dst_gen_s * cfg)243 void ge2d_set_src2_dst_gen(struct ge2d_src2_dst_gen_s *cfg)
244 {
245 ge2d_reg_write(GE2D_SRC2_CLIPX_START_END, (cfg->src2_clipx_start << 16L) | (cfg->src2_clipx_end << 0));
246
247 ge2d_reg_write(GE2D_SRC2_CLIPY_START_END, (cfg->src2_clipy_start << 16L) | (cfg->src2_clipy_end << 0));
248
249 ge2d_reg_set_bits(GE2D_GEN_CTRL0, cfg->src2_pic_struct, 12L, 2L);
250 ge2d_reg_set_bits(GE2D_GEN_CTRL0, (cfg->src2_fill_mode & 0x1), 14L, 1);
251
252 ge2d_reg_set_bits(GE2D_SRC_OUTSIDE_ALPHA, ((cfg->src2_fill_mode & 0x2) << 7L) | cfg->src2_outside_alpha, 16L, 9L);
253
254 ge2d_reg_write(GE2D_DST_CLIPX_START_END, (cfg->dst_clipx_start << 16L) | (cfg->dst_clipx_end << 0));
255
256 ge2d_reg_write(GE2D_DST_CLIPY_START_END, (cfg->dst_clipy_start << 16L) | (cfg->dst_clipy_end << 0));
257
258 ge2d_reg_set_bits(GE2D_GEN_CTRL0, cfg->dst_clip_mode, 23L, 1);
259 ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->dst_pic_struct, 14L, 2L);
260 }
261
ge2d_set_dp_gen(struct ge2d_config_s * config)262 void ge2d_set_dp_gen(struct ge2d_config_s *config)
263 {
264 struct ge2d_dp_gen_s *cfg = &config->dp_gen;
265
266 unsigned int antiflick_color_filter_n1[] = {0, 8, 16, 32};
267 unsigned int antiflick_color_filter_n2[] = {128, 112, 96, 64};
268 unsigned int antiflick_color_filter_n3[] = {0, 8, 16, 32};
269 unsigned int antiflick_color_filter_th[] = {8, 16, 64};
270 unsigned int antiflick_alpha_filter_n1[] = {0, 8, 16, 32};
271 unsigned int antiflick_alpha_filter_n2[] = {128, 112, 96, 64};
272 unsigned int antiflick_alpha_filter_n3[] = {0, 8, 16, 32};
273 unsigned int antiflick_alpha_filter_th[] = {8, 16, 64};
274
275 if (cfg->conv_matrix_en) {
276 cfg->antiflick_ycbcr_rgb_sel = 0; /* 0: yuv2rgb 1:rgb2rgb */
277 cfg->antiflick_cbcr_en = 1;
278 cfg->antiflick_r_coef = 0;
279 cfg->antiflick_g_coef = 0;
280 cfg->antiflick_b_coef = 0;
281 } else {
282 cfg->antiflick_ycbcr_rgb_sel = 1; /* 0: yuv2rgb 1:rgb2rgb */
283 cfg->antiflick_cbcr_en = 1;
284 cfg->antiflick_r_coef = 0x42; /* 0.257 */
285 cfg->antiflick_g_coef = 0x81; /* 0.504 */
286 cfg->antiflick_b_coef = 0x19; /* 0.098 */
287 }
288 memcpy(cfg->antiflick_color_filter_n1, antiflick_color_filter_n1, 4L * sizeof(unsigned int));
289 memcpy(cfg->antiflick_color_filter_n2, antiflick_color_filter_n2, 4L * sizeof(unsigned int));
290 memcpy(cfg->antiflick_color_filter_n3, antiflick_color_filter_n3, 4L * sizeof(unsigned int));
291 memcpy(cfg->antiflick_color_filter_th, antiflick_color_filter_th, 3L * sizeof(unsigned int));
292 memcpy(cfg->antiflick_alpha_filter_n1, antiflick_alpha_filter_n1, 4L * sizeof(unsigned int));
293 memcpy(cfg->antiflick_alpha_filter_n2, antiflick_alpha_filter_n2, 4L * sizeof(unsigned int));
294 memcpy(cfg->antiflick_alpha_filter_n3, antiflick_alpha_filter_n3, 4L * sizeof(unsigned int));
295 memcpy(cfg->antiflick_alpha_filter_th, antiflick_alpha_filter_th, 3L * sizeof(unsigned int));
296 cfg->src1_vsc_bank_length = 4L;
297 cfg->src1_hsc_bank_length = 4L;
298 ge2d_reg_set_bits(GE2D_SC_MISC_CTRL,
299 ((cfg->src1_hsc_rpt_ctrl << 9L) | (cfg->src1_vsc_rpt_ctrl << 8L) |
300 (cfg->src1_vsc_phase0_always_en << 7L) | (cfg->src1_vsc_bank_length << 4L) |
301 (cfg->src1_hsc_phase0_always_en << 3L) | (cfg->src1_hsc_bank_length << 0)),
302 0, 10L);
303
304 ge2d_reg_set_bits(GE2D_SC_MISC_CTRL, ((cfg->src1_vsc_nearest_en << 1) | (cfg->src1_hsc_nearest_en << 0)), 29L, 2L);
305 if (cfg->antiflick_en == 1) {
306 ge2d_reg_write(GE2D_ANTIFLICK_CTRL0, 0x80000000);
307 ge2d_reg_write(GE2D_ANTIFLICK_CTRL1, (cfg->antiflick_ycbcr_rgb_sel << 25L) | (cfg->antiflick_cbcr_en << 24L) |
308 ((cfg->antiflick_r_coef & 0xff) << 16L) |
309 ((cfg->antiflick_g_coef & 0xff) << 8L) |
310 ((cfg->antiflick_b_coef & 0xff) << 0));
311
312 ge2d_reg_write(GE2D_ANTIFLICK_COLOR_FILT0, ((cfg->antiflick_color_filter_th[0] & 0xff) << 24L) |
313 ((cfg->antiflick_color_filter_n3[0] & 0xff) << 16L) |
314 ((cfg->antiflick_color_filter_n2[0] & 0xff) << 8L) |
315 ((cfg->antiflick_color_filter_n1[0] & 0xff) << 0));
316
317 ge2d_reg_write(GE2D_ANTIFLICK_COLOR_FILT1, ((cfg->antiflick_color_filter_th[1] & 0xff) << 24L) |
318 ((cfg->antiflick_color_filter_n3[1] & 0xff) << 16L) |
319 ((cfg->antiflick_color_filter_n2[1] & 0xff) << 8L) |
320 ((cfg->antiflick_color_filter_n1[1] & 0xff) << 0));
321
322 ge2d_reg_write(GE2D_ANTIFLICK_COLOR_FILT2, ((cfg->antiflick_color_filter_th[2L] & 0xff) << 24L) |
323 ((cfg->antiflick_color_filter_n3[2L] & 0xff) << 16L) |
324 ((cfg->antiflick_color_filter_n2[2L] & 0xff) << 8L) |
325 ((cfg->antiflick_color_filter_n1[2L] & 0xff) << 0));
326
327 ge2d_reg_write(GE2D_ANTIFLICK_COLOR_FILT3, ((cfg->antiflick_color_filter_n3[3L] & 0xff) << 16L) |
328 ((cfg->antiflick_color_filter_n2[3L] & 0xff) << 8L) |
329 ((cfg->antiflick_color_filter_n1[3L] & 0xff) << 0));
330
331 ge2d_reg_write(GE2D_ANTIFLICK_ALPHA_FILT0, ((cfg->antiflick_alpha_filter_th[0] & 0xff) << 24L) |
332 ((cfg->antiflick_alpha_filter_n3[0] & 0xff) << 16L) |
333 ((cfg->antiflick_alpha_filter_n2[0] & 0xff) << 8L) |
334 ((cfg->antiflick_alpha_filter_n1[0] & 0xff) << 0));
335
336 ge2d_reg_write(GE2D_ANTIFLICK_ALPHA_FILT1, ((cfg->antiflick_alpha_filter_th[1] & 0xff) << 24L) |
337 ((cfg->antiflick_alpha_filter_n3[1] & 0xff) << 16L) |
338 ((cfg->antiflick_alpha_filter_n2[1] & 0xff) << 8L) |
339 ((cfg->antiflick_alpha_filter_n1[1] & 0xff) << 0));
340
341 ge2d_reg_write(GE2D_ANTIFLICK_ALPHA_FILT2, ((cfg->antiflick_alpha_filter_th[2L] & 0xff) << 24L) |
342 ((cfg->antiflick_alpha_filter_n3[2L] & 0xff) << 16L) |
343 ((cfg->antiflick_alpha_filter_n2[2L] & 0xff) << 8L) |
344 ((cfg->antiflick_alpha_filter_n1[2L] & 0xff) << 0));
345
346 ge2d_reg_write(GE2D_ANTIFLICK_ALPHA_FILT3, ((cfg->antiflick_alpha_filter_n3[3L] & 0xff) << 16L) |
347 ((cfg->antiflick_alpha_filter_n2[3L] & 0xff) << 8L) |
348 ((cfg->antiflick_alpha_filter_n1[3L] & 0xff) << 0));
349 } else {
350 ge2d_reg_set_bits(GE2D_ANTIFLICK_CTRL0, 0, 31L, 1);
351 }
352
353 if (cfg->use_matrix_default & MATRIX_CUSTOM) {
354 struct ge2d_matrix_s *matrix = &config->matrix_custom;
355
356 ge2d_log_dbg("using matrix_custom\n");
357 cfg->matrix_coef[0] = matrix->coef0;
358 cfg->matrix_coef[1] = matrix->coef1;
359 cfg->matrix_coef[2L] = matrix->coef2;
360 cfg->matrix_coef[3L] = matrix->coef3;
361 cfg->matrix_coef[4L] = matrix->coef4;
362 cfg->matrix_coef[5L] = matrix->coef5;
363 cfg->matrix_coef[6L] = matrix->coef6;
364 cfg->matrix_coef[7L] = matrix->coef7;
365 cfg->matrix_coef[8L] = matrix->coef8;
366 cfg->matrix_offset[0] = matrix->offset0;
367 cfg->matrix_offset[1] = matrix->offset1;
368 cfg->matrix_offset[2L] = matrix->offset2;
369 cfg->matrix_sat_in_en = matrix->sat_in_en;
370
371 ge2d_reg_write(GE2D_MATRIX_PRE_OFFSET,
372 (matrix->pre_offset0 << 20L) | (matrix->pre_offset1 << 10L) | matrix->pre_offset2);
373 } else {
374 if (cfg->use_matrix_default & MATRIX_YCC_TO_RGB) {
375 /* ycbcr(16-235) to rgb(0-255) */
376 cfg->matrix_coef[0] = 0x4a8;
377 cfg->matrix_coef[1] = 0;
378 cfg->matrix_coef[2L] = 0x662;
379 cfg->matrix_coef[3L] = 0x4a8;
380 cfg->matrix_coef[4L] = 0x1e6f;
381 cfg->matrix_coef[5L] = 0x1cbf;
382 cfg->matrix_coef[6L] = 0x4a8;
383 cfg->matrix_coef[7L] = 0x811;
384 cfg->matrix_coef[8L] = 0x0;
385 cfg->matrix_offset[0] = 0;
386 cfg->matrix_offset[1] = 0;
387 cfg->matrix_offset[2L] = 0;
388 cfg->matrix_sat_in_en = 1;
389 cfg->matrix_minus_16_ctrl = 0x4;
390 cfg->matrix_sign_ctrl = 0x3;
391 } else if (cfg->use_matrix_default & MATRIX_RGB_TO_YCC) {
392 if (cfg->use_matrix_default & MATRIX_BT_709) {
393 /* VDIN_MATRIX_RGB_YUV709 */
394 /* 0 0.183 0.614 0.062 16 */
395 /* 0 -0.101 -0.338 0.439 128 */
396 /* 0 0.439 -0.399 -0.04 128 */
397 cfg->matrix_coef[0] = 0xbb;
398 cfg->matrix_coef[1] = 0x275;
399 cfg->matrix_coef[2L] = 0x3f;
400 cfg->matrix_coef[3L] = 0x1f99;
401 cfg->matrix_coef[4L] = 0x1ea6;
402 cfg->matrix_coef[5L] = 0x1c2;
403 cfg->matrix_coef[6L] = 0x1c2;
404 cfg->matrix_coef[7L] = 0x1e67;
405 cfg->matrix_coef[8L] = 0x1fd7;
406 } else {
407 /* rgb(0-255) to ycbcr(16-235) */
408 /* 0.257 0.504 0.098 */
409 /* -0.148 -0.291 0.439 */
410 /* 0.439 -0.368 -0.071 */
411 cfg->matrix_coef[0] = 0x107;
412 cfg->matrix_coef[1] = 0x204;
413 cfg->matrix_coef[2L] = 0x64;
414 cfg->matrix_coef[3L] = 0x1f68;
415 cfg->matrix_coef[4L] = 0x1ed6;
416 cfg->matrix_coef[5L] = 0x1c2;
417 cfg->matrix_coef[6L] = 0x1c2;
418 cfg->matrix_coef[7L] = 0x1e87;
419 cfg->matrix_coef[8L] = 0x1fb7;
420 }
421 cfg->matrix_offset[0] = 16L;
422 cfg->matrix_offset[1] = 128L;
423 cfg->matrix_offset[2L] = 128L;
424 cfg->matrix_sat_in_en = 0;
425 cfg->matrix_minus_16_ctrl = 0;
426 cfg->matrix_sign_ctrl = 0;
427 } else if (cfg->use_matrix_default & MATRIX_FULL_RANGE_YCC_TO_RGB) {
428 /* ycbcr (0-255) to rgb(0-255) */
429 /* 1, 0, 1.402 */
430 /* 1, -0.34414, -0.71414 */
431 /* 1, 1.772 0 */
432 cfg->matrix_coef[0] = 0x400;
433 cfg->matrix_coef[1] = 0;
434 cfg->matrix_coef[2L] = 0x59c;
435 cfg->matrix_coef[3L] = 0x400;
436 cfg->matrix_coef[4L] = 0x1ea0;
437 cfg->matrix_coef[5L] = 0x1d25;
438 cfg->matrix_coef[6L] = 0x400;
439 cfg->matrix_coef[7L] = 0x717;
440 cfg->matrix_coef[8L] = 0;
441 cfg->matrix_offset[0] = 0;
442 cfg->matrix_offset[1] = 0;
443 cfg->matrix_offset[2L] = 0;
444 cfg->matrix_sat_in_en = 0;
445 cfg->matrix_minus_16_ctrl = 0;
446 cfg->matrix_sign_ctrl = 0x3;
447 } else if (cfg->use_matrix_default & MATRIX_RGB_TO_FULL_RANGE_YCC) {
448 cfg->matrix_coef[0] = 0x132;
449 cfg->matrix_coef[1] = 0x259;
450 cfg->matrix_coef[2L] = 0x75;
451 cfg->matrix_coef[3L] = 0x1f53;
452 cfg->matrix_coef[4L] = 0x1ead;
453 cfg->matrix_coef[5L] = 0x200;
454 cfg->matrix_coef[6L] = 0x200;
455 cfg->matrix_coef[7L] = 0x1e53;
456 cfg->matrix_coef[8L] = 0x1fad;
457 cfg->matrix_offset[0] = 0;
458 cfg->matrix_offset[1] = 128L;
459 cfg->matrix_offset[2L] = 128L;
460 cfg->matrix_sat_in_en = 0;
461 cfg->matrix_minus_16_ctrl = 0;
462 cfg->matrix_sign_ctrl = 0;
463 }
464
465 if (cfg->matrix_minus_16_ctrl) {
466 ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET, 0x1f0, 20L, 9L);
467 } else {
468 ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET, 0, 20L, 9L);
469 }
470
471 if (cfg->matrix_sign_ctrl & 3L) {
472 ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET, ((0x180 << 10L) | 0x180), 0, 20L);
473 } else {
474 ge2d_reg_set_bits(GE2D_MATRIX_PRE_OFFSET, 0, 0, 20L);
475 }
476 }
477
478 ge2d_reg_write(GE2D_MATRIX_COEF00_01, (cfg->matrix_coef[0] << 16L) | (cfg->matrix_coef[1] << 0));
479
480 ge2d_reg_write(GE2D_MATRIX_COEF02_10, (cfg->matrix_coef[2L] << 16L) | (cfg->matrix_coef[3L] << 0));
481
482 ge2d_reg_write(GE2D_MATRIX_COEF11_12, (cfg->matrix_coef[4L] << 16L) | (cfg->matrix_coef[5L] << 0));
483
484 ge2d_reg_write(GE2D_MATRIX_COEF20_21, (cfg->matrix_coef[6L] << 16L) | (cfg->matrix_coef[7L] << 0));
485
486 ge2d_reg_write(GE2D_MATRIX_COEF22_CTRL, (cfg->matrix_coef[8L] << 16L) | (cfg->matrix_sat_in_en << 7L) |
487
488 (cfg->conv_matrix_en << 0));
489
490 ge2d_reg_write(GE2D_MATRIX_OFFSET,
491 (cfg->matrix_offset[0] << 20L) | (cfg->matrix_offset[1] << 10L) | (cfg->matrix_offset[2L] << 0));
492
493 ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->src1_gb_alpha, 0, 8L);
494 ge2d_reg_set_bits(GE2D_GEN_CTRL2, cfg->src1_gb_alpha_en, 29L, 1);
495 #ifdef CONFIG_GE2D_SRC2
496 if (ge2d_meson_dev.src2_alp == 1) {
497 ge2d_reg_set_bits(GE2D_GEN_CTRL5, cfg->src2_gb_alpha, 0, 8L);
498 ge2d_reg_set_bits(GE2D_GEN_CTRL5, cfg->src2_gb_alpha_en, 8L, 1);
499 }
500 #endif
501 ge2d_reg_write(GE2D_ALU_CONST_COLOR, cfg->alu_const_color);
502 ge2d_reg_write(GE2D_SRC1_KEY, cfg->src1_key);
503 ge2d_reg_write(GE2D_SRC1_KEY_MASK, cfg->src1_key_mask);
504
505 ge2d_reg_write(GE2D_SRC2_KEY, cfg->src2_key);
506 ge2d_reg_write(GE2D_SRC2_KEY_MASK, cfg->src2_key_mask);
507
508 ge2d_reg_write(GE2D_DST_BITMASK, cfg->bitmask);
509
510 ge2d_reg_set_bits(GE2D_GEN_CTRL0,
511 ((cfg->bytemask_only << 5L) | (cfg->bitmask_en << 4L) | (cfg->src2_key_en << 3L) |
512 (cfg->src2_key_mode << 2L) | (cfg->src1_key_en << 1) | (cfg->src1_key_mode << 0)),
513 26L, 6L);
514 }
515
ge2d_cmd_fifo_full(void)516 int ge2d_cmd_fifo_full(void)
517 {
518 return ge2d_reg_read(GE2D_STATUS0) & (1 << 1);
519 }
520
ge2d_set_cmd(struct ge2d_cmd_s * cfg)521 void ge2d_set_cmd(struct ge2d_cmd_s *cfg)
522 {
523 unsigned int widthi, heighti, tmp_widthi, tmp_heighti, widtho, heighto;
524 unsigned int multo;
525 unsigned int x_extra_bit_start = 0, x_extra_bit_end = 0;
526 unsigned int y_extra_bit_start = 0, y_extra_bit_end = 0;
527 unsigned int x_chr_phase = 0, y_chr_phase = 0;
528 unsigned int x_yc_ratio, y_yc_ratio;
529 int sc_prehsc_en, sc_prevsc_en;
530 int rate_w = 10L, rate_h = 10L;
531 /* expand src region with one line. */
532 unsigned int src1_y_end = cfg->src1_y_end + 1;
533
534 while ((ge2d_reg_read(GE2D_STATUS0) & (1 << 1))) {
535 ;
536 }
537
538 x_yc_ratio = ge2d_reg_get_bits(GE2D_GEN_CTRL0, 11L, 1);
539 y_yc_ratio = ge2d_reg_get_bits(GE2D_GEN_CTRL0, 10L, 1);
540
541 /* src:yuv , dst: rgb */
542 if ((cfg->src1_fmt & GE2D_FORMAT_YUV) && ((cfg->dst_fmt & GE2D_FORMAT_YUV) == 0)) {
543 if (x_yc_ratio) {
544 if ((cfg->src1_x_rev + cfg->dst_x_rev) == 1) {
545 x_extra_bit_start = 3L;
546 x_extra_bit_end = 2L;
547 x_chr_phase = 0x4c;
548 } else {
549 x_extra_bit_start = 2L;
550 x_extra_bit_end = 3L;
551 x_chr_phase = 0xc4;
552 }
553 }
554 if (y_yc_ratio) {
555 if ((cfg->src1_y_rev + cfg->dst_y_rev) == 1) {
556 y_extra_bit_start = 3L;
557 y_extra_bit_end = 2L;
558 y_chr_phase = 0x4c;
559 } else {
560 y_extra_bit_start = 2L;
561 y_extra_bit_end = 3L;
562 y_chr_phase = 0xc4;
563 }
564 }
565 } else {
566 if (x_yc_ratio) {
567 if ((cfg->src1_x_rev + cfg->dst_x_rev) == 1) {
568 x_extra_bit_start = 3L;
569 x_extra_bit_end = 2L;
570 x_chr_phase = 0x08;
571 } else {
572 x_extra_bit_start = 2L;
573 x_extra_bit_end = 3L;
574 x_chr_phase = 0x08;
575 }
576 }
577
578 if (y_yc_ratio) {
579 if ((cfg->src1_y_rev + cfg->dst_y_rev) == 1) {
580 y_extra_bit_start = 3L;
581 y_extra_bit_end = 2L;
582 y_chr_phase = 0x4c;
583 } else {
584 y_extra_bit_start = 2L;
585 y_extra_bit_end = 3L;
586 y_chr_phase = 0x4c;
587 }
588 }
589 }
590 ge2d_reg_write(GE2D_SRC1_X_START_END, (x_extra_bit_start << 30L) | /* x start extra */
591 ((cfg->src1_x_start & 0x3fff) << 16L) |
592 (x_extra_bit_end << 14L) | /* x end extra */
593 ((cfg->src1_x_end & 0x3fff) << 0));
594
595 ge2d_reg_write(GE2D_SRC1_Y_START_END, (y_extra_bit_start << 30L) | /* y start extra */
596 ((cfg->src1_y_start & 0x3fff) << 16L) |
597 (y_extra_bit_end << 14L) | /* y end extra */
598 ((src1_y_end & 0x3fff) << 0));
599
600 ge2d_reg_set_bits(GE2D_SRC1_FMT_CTRL, x_chr_phase, 8L, 8L);
601 ge2d_reg_set_bits(GE2D_SRC1_FMT_CTRL, y_chr_phase, 0, 8L);
602
603 if (((cfg->src1_x_end - cfg->src1_x_start) == (cfg->dst_x_end - cfg->dst_x_start)) &&
604 ((cfg->src1_y_end - cfg->src1_y_start) == (cfg->dst_y_end - cfg->dst_y_start))) {
605 /* set chroma formatter repeat mode */
606 ge2d_reg_set_bits(GE2D_SRC1_FMT_CTRL, 1, 19L, 1);
607 ge2d_reg_set_bits(GE2D_SRC1_FMT_CTRL, 1, 17L, 1);
608 }
609
610 ge2d_reg_write(GE2D_SRC2_X_START_END, (cfg->src2_x_start << 16L) | (cfg->src2_x_end << 0));
611
612 ge2d_reg_write(GE2D_SRC2_Y_START_END, (cfg->src2_y_start << 16L) | (cfg->src2_y_end << 0));
613
614 ge2d_reg_write(GE2D_DST_X_START_END, (cfg->dst_x_start << 16L) | (cfg->dst_x_end << 0));
615
616 ge2d_reg_write(GE2D_DST_Y_START_END, (cfg->dst_y_start << 16L) | (cfg->dst_y_end << 0));
617
618 widthi = cfg->src1_x_end - cfg->src1_x_start + 1;
619 heighti = cfg->src1_y_end - cfg->src1_y_start + 1;
620
621 widtho = cfg->dst_xy_swap ? (cfg->dst_y_end - cfg->dst_y_start + 1) : (cfg->dst_x_end - cfg->dst_x_start + 1);
622 heighto = cfg->dst_xy_swap ? (cfg->dst_x_end - cfg->dst_x_start + 1) : (cfg->dst_y_end - cfg->dst_y_start + 1);
623
624 sc_prehsc_en = (widthi > widtho * 2L) ? 1 : 0;
625 sc_prevsc_en = (heighti > heighto * 2L) ? 1 : 0;
626
627 tmp_widthi = sc_prehsc_en ? ((widthi + 1) >> 1) : widthi;
628 tmp_heighti = sc_prevsc_en ? ((heighti + 1) >> 1) : heighti;
629
630 if (cfg->hsc_phase_step == 0) {
631 cfg->hsc_phase_step = ((tmp_widthi << 18L) / widtho) << 6L; /* width no more than 8192 */
632 }
633
634 if (cfg->vsc_phase_step == 0) {
635 cfg->vsc_phase_step = ((tmp_heighti << 18L) / heighto) << 6L; /* height no more than 8192 */
636 }
637
638 if ((cfg->sc_hsc_en) && (cfg->hsc_div_en)) {
639 cfg->hsc_div_length = (124L << 24L) / cfg->hsc_phase_step;
640
641 multo = cfg->hsc_phase_step * cfg->hsc_div_length;
642 cfg->hsc_adv_num = multo >> 24L;
643 cfg->hsc_adv_phase = multo & 0xffffff;
644 }
645
646 if (!gaul_filter_used) {
647 rate_w = (widtho * 10L) / widthi;
648 rate_h = (heighto * 10L) / heighti;
649 if (rate_h == 10L) {
650 /* not scaler case */
651 cfg->vsc_ini_phase = 0;
652 ge2d_reg_set_bits(GE2D_SC_MISC_CTRL, ((0 << 1) | (0 << 0)), 8L, 2L);
653 } else if (rate_h < 10L) {
654 /* scaler down case */
655 cfg->sc_vsc_en = 1;
656 cfg->vsc_rpt_l0_num = 1;
657 if (rate_h != 0) {
658 cfg->vsc_ini_phase = 0x5000000 / rate_h - 0x800000;
659 } else {
660 cfg->vsc_ini_phase = 0x5000000;
661 }
662 } else {
663 /* scaler up case */
664 cfg->sc_vsc_en = 1;
665 cfg->vsc_rpt_l0_num = 2L;
666 cfg->vsc_ini_phase = 0x800000 + 0x5000000 / rate_h;
667 }
668
669 if (rate_w == 10L) {
670 /* not scaler case */
671 cfg->hsc_ini_phase = 0;
672 ge2d_reg_set_bits(GE2D_SC_MISC_CTRL, ((0 << 1) | (0 << 0)), 8L, 2L);
673 } else if (rate_w < 10L) {
674 /* scaler down case */
675 cfg->sc_hsc_en = 1;
676 cfg->hsc_rpt_p0_num = 1;
677 if (rate_w != 0) {
678 cfg->hsc_ini_phase = 0x5000000 / rate_w - 0x800000;
679 } else {
680 cfg->hsc_ini_phase = 0x5000000;
681 }
682 } else {
683 /* scaler up case */
684 cfg->sc_hsc_en = 1;
685 cfg->hsc_rpt_p0_num = 2L;
686 cfg->hsc_ini_phase = 0x800000 + 0x5000000 / rate_w;
687 }
688 /* expand src1/src2 color with 1 */
689 ge2d_reg_set_bits(GE2D_GEN_CTRL2, 1, 27L, 1);
690 ge2d_reg_set_bits(GE2D_GEN_CTRL2, 1, 25L, 1);
691 }
692 ge2d_log_dbg("rate_w=%d,rate_h=%d\n", rate_w, rate_h);
693 ge2d_reg_set_bits(GE2D_SC_MISC_CTRL,
694 ((cfg->hsc_div_en << 17L) | (cfg->hsc_div_length << 4L) | (sc_prehsc_en << 3L) |
695 (sc_prevsc_en << 2L) | (cfg->sc_vsc_en << 1) | (cfg->sc_hsc_en << 0)),
696 11L, 18L);
697
698 ge2d_reg_write(GE2D_HSC_START_PHASE_STEP, cfg->hsc_phase_step);
699
700 ge2d_reg_write(GE2D_HSC_PHASE_SLOPE, cfg->hsc_phase_slope);
701
702 #ifdef CONFIG_GE2D_ADV_NUM
703 ge2d_reg_write(GE2D_HSC_ADV_CTRL, (cfg->hsc_adv_num << 24L) | (cfg->hsc_adv_phase << 0));
704 if (cfg->hsc_adv_num > 255L) {
705 cfg->hsc_adv_num = cfg->hsc_adv_num >> 8L;
706 } else {
707 cfg->hsc_adv_num = 0;
708 }
709 ge2d_reg_write(GE2D_HSC_INI_CTRL,
710 (cfg->hsc_rpt_p0_num << 29L) | (cfg->hsc_adv_num << 24L) | ((cfg->hsc_ini_phase & 0xffffff) << 0));
711 #else
712 ge2d_reg_write(GE2D_HSC_ADV_CTRL, (cfg->hsc_adv_num << 24L) | (cfg->hsc_adv_phase << 0));
713 ge2d_reg_write(GE2D_HSC_INI_CTRL, (cfg->hsc_rpt_p0_num << 29L) | ((cfg->hsc_ini_phase & 0xffffff) << 0));
714 #endif
715
716 ge2d_reg_write(GE2D_VSC_START_PHASE_STEP, cfg->vsc_phase_step);
717
718 ge2d_reg_write(GE2D_VSC_PHASE_SLOPE, cfg->vsc_phase_slope);
719
720 ge2d_reg_write(GE2D_VSC_INI_CTRL, (cfg->vsc_rpt_l0_num << 29L) | (cfg->vsc_ini_phase << 0));
721 #ifdef CONFIG_GE2D_SRC2
722 if (ge2d_meson_dev.src2_alp == 1) {
723 ge2d_reg_write(
724 GE2D_ALU_OP_CTRL,
725 (cfg->src2_cmult_ad << 27L) | (cfg->src1_cmult_asel << 25L) | (cfg->src2_cmult_asel << 23L) |
726 (cfg->color_blend_mode << 20L) | (cfg->color_src_blend_factor << 16L) |
727 (((cfg->color_blend_mode == 5L) ? cfg->color_logic_op : cfg->color_dst_blend_factor) << 12L) |
728 (cfg->alpha_blend_mode << 8L) | (cfg->alpha_src_blend_factor << 4L) |
729 (((cfg->alpha_blend_mode == 5L) ? cfg->alpha_logic_op : cfg->alpha_dst_blend_factor) << 0));
730 } else {
731 #endif
732 ge2d_reg_write(
733 GE2D_ALU_OP_CTRL,
734 (cfg->src1_cmult_asel << 25L) | (cfg->src2_cmult_asel << 24L) | (cfg->color_blend_mode << 20L) |
735 (cfg->color_src_blend_factor << 16L) |
736 (((cfg->color_blend_mode == 5L) ? cfg->color_logic_op : cfg->color_dst_blend_factor) << 12L) |
737 (cfg->alpha_blend_mode << 8L) | (cfg->alpha_src_blend_factor << 4L) |
738 (((cfg->alpha_blend_mode == 5L) ? cfg->alpha_logic_op : cfg->alpha_dst_blend_factor) << 0));
739 }
740
741 /* if true, disable bug fix about the dp_out_done/
742 * scale_out_done(test1823) hang issue when
743 * scaling down ratio is high.
744 */
745 if (ge2d_meson_dev.hang_flag == 1) {
746 ge2d_reg_set_bits(GE2D_GEN_CTRL4, cfg->hang_flag, 0, 1);
747 }
748 ge2d_reg_write(GE2D_CMD_CTRL, (cfg->src2_fill_color_en << 9L) | (cfg->src1_fill_color_en << 8L) |
749 (cfg->dst_xy_swap << 7L) | (cfg->dst_x_rev << 6L) | (cfg->dst_y_rev << 5L) |
750 (cfg->src2_x_rev << 4L) | (cfg->src2_y_rev << 3L) | (cfg->src1_x_rev << 2L) |
751 (cfg->src1_y_rev << 1) | 1 << 0 /* start cmd */
752 );
753 cfg->release_flag |= START_FLAG;
754 }
755
ge2d_wait_done(void)756 void ge2d_wait_done(void)
757 {
758 while (ge2d_reg_read(GE2D_STATUS0) & 1) {
759 ;
760 }
761 }
762
ge2d_is_busy(void)763 bool ge2d_is_busy(void)
764 {
765 if (ge2d_reg_read(GE2D_STATUS0) & 1) {
766 return true;
767 } else {
768 return false;
769 }
770 }
771
ge2d_soft_rst(void)772 void ge2d_soft_rst(void)
773 {
774 ge2d_reg_set_bits(GE2D_GEN_CTRL1, 1, 31L, 1);
775 ge2d_reg_set_bits(GE2D_GEN_CTRL1, 0, 31L, 1);
776 }
777
ge2d_set_gen(struct ge2d_gen_s * cfg)778 void ge2d_set_gen(struct ge2d_gen_s *cfg)
779 {
780 ge2d_reg_set_bits(GE2D_GEN_CTRL1, cfg->interrupt_ctrl, 24L, 2L);
781
782 ge2d_reg_write(GE2D_DP_ONOFF_CTRL, (cfg->dp_onoff_mode << 31L) | (cfg->dp_on_cnt << 16L) |
783 (cfg->vfmt_onoff_en << 15L) | (cfg->dp_off_cnt << 0));
784 if (ge2d_meson_dev.fifo == 1) {
785 ge2d_reg_set_bits(GE2D_GEN_CTRL4,
786 (cfg->fifo_size << 26L) | (cfg->fifo_size << 24L) | (cfg->fifo_size << 22L) |
787 (cfg->fifo_size << 20L) | (cfg->burst_ctrl << 18L) | (cfg->burst_ctrl << 16L),
788 16L, 12L);
789 }
790 }
791