1 /*
2 * g2d_ovl_u.c
3 *
4 * Copyright (c) 2007-2019 Allwinnertech Co., Ltd.
5 * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
6 *
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18 #include <stdlib.h>
19
20 #include "g2d_ovl_u.h"
21
g2d_ovl_u_fc_set(struct ovl_u_submodule * p_ovl_u,__u32 sel,__u32 color_value)22 __s32 g2d_ovl_u_fc_set(struct ovl_u_submodule *p_ovl_u, __u32 sel,
23 __u32 color_value)
24 {
25 __s32 ret = -1;
26 struct g2d_mixer_ovl_u_reg *p_reg = p_ovl_u->get_reg(p_ovl_u, sel);
27
28 if (!p_reg)
29 goto OUT;
30
31 p_reg->ovl_attr.bits.lay_fillcolor_en = 1;
32 p_reg->ovl_fill_color = color_value;
33
34 p_ovl_u->set_block_dirty(p_ovl_u, sel, 1);
35
36 ret = 0;
37 OUT:
38 return ret;
39 }
40
g2d_uilayer_set(struct ovl_u_submodule * p_ovl_u,__u32 sel,g2d_image_enh * p_img)41 __s32 g2d_uilayer_set(struct ovl_u_submodule *p_ovl_u, __u32 sel,
42 g2d_image_enh *p_img)
43 {
44 __u64 addr0;
45 __u32 ycnt, ucnt, vcnt;
46 __u32 pitch0;
47 __s32 ret = -1;
48 struct g2d_mixer_ovl_u_reg *p_reg = p_ovl_u->get_reg(p_ovl_u, sel);
49
50 if (!p_reg)
51 goto OUT;
52
53 p_reg->ovl_attr.bits.lay_glbalpha = p_img->alpha & 0xff;
54 if (p_img->bpremul)
55 p_reg->ovl_attr.bits.lay_premul_ctl = 1;
56 p_reg->ovl_attr.bits.lay_fbfmt = p_img->format;
57 p_reg->ovl_attr.bits.alpha_mode = p_img->mode;
58 p_reg->ovl_attr.bits.lay_en = 1;
59
60 p_reg->ovl_mem.bits.lay_width =
61 (p_img->clip_rect.w == 0 ? 0 : p_img->clip_rect.w - 1) & 0x1fff;
62 p_reg->ovl_mem.bits.lay_height =
63 (p_img->clip_rect.h == 0 ? 0 : p_img->clip_rect.h - 1) & 0x1fff;
64 p_reg->ovl_winsize.bits.width =
65 (p_img->clip_rect.w == 0 ? 0 : p_img->clip_rect.w - 1) & 0x1fff;
66 p_reg->ovl_winsize.bits.height =
67 (p_img->clip_rect.h == 0 ? 0 : p_img->clip_rect.h - 1) & 0x1fff;
68
69 p_reg->ovl_mem_coor.dwval = 0;
70 g2d_byte_cal(p_img->format, &ycnt, &ucnt, &vcnt);
71 pitch0 = cal_align(ycnt * p_img->width, p_img->align[0]);
72 p_reg->ovl_mem_pitch0 = pitch0;
73
74 addr0 =
75 p_img->laddr[0] + ((__u64) p_img->haddr[0] << 32) +
76 pitch0 * p_img->clip_rect.y + ycnt * p_img->clip_rect.x;
77 p_reg->ovl_mem_low_addr0 = addr0 & 0xffffffff;
78 p_reg->ovl_mem_high_addr = (addr0 >> 32) & 0xff;
79
80 if (p_img->bbuff == 0)
81 g2d_ovl_u_fc_set(p_ovl_u, sel, p_img->color);
82
83 p_ovl_u->set_block_dirty(p_ovl_u, sel, 1);
84 ret = 0;
85 OUT:
86 return ret;
87 }
88
g2d_uilayer_overlay_set(struct ovl_u_submodule * p_ovl_u,__u32 sel,g2d_coor * coor,__u32 w,__u32 h)89 __s32 g2d_uilayer_overlay_set(struct ovl_u_submodule *p_ovl_u, __u32 sel,
90 g2d_coor *coor, __u32 w, __u32 h)
91 {
92 __s32 ret = -1;
93 struct g2d_mixer_ovl_u_reg *p_reg = p_ovl_u->get_reg(p_ovl_u, sel);
94
95 if (!p_reg)
96 goto OUT;
97
98 p_reg->ovl_winsize.bits.width = (w - 1) & 0x1fff;
99 p_reg->ovl_winsize.bits.height = (h - 1) & 0x1fff;
100
101 p_reg->ovl_mem_coor.bits.lay_xcoor = coor->x;
102 p_reg->ovl_mem_coor.bits.lay_ycoor = coor->y;
103 ret = 0;
104 OUT:
105 return ret;
106 }
107
ovl_u_rcq_setup(struct ovl_u_submodule * p_ovl_u,u8 * base,struct g2d_rcq_mem_info * p_rcq_info)108 static int ovl_u_rcq_setup(struct ovl_u_submodule *p_ovl_u, u8 *base,
109 struct g2d_rcq_mem_info *p_rcq_info)
110 {
111 u8 *reg_base = base + G2D_UI0;
112 __s32 ret = -1;
113
114 if (!p_ovl_u) {
115 G2D_ERR_MSG("Null pointer!\n");
116 goto OUT;
117 }
118
119 p_ovl_u->reg_info->size = sizeof(struct g2d_mixer_ovl_v_reg);
120 p_ovl_u->reg_info->vir_addr = (u8 *)g2d_top_reg_memory_alloc(
121 p_ovl_u->reg_info->size,
122 (void *)&(p_ovl_u->reg_info->phy_addr), p_rcq_info);
123
124 if (!p_ovl_u->reg_info->vir_addr) {
125 G2D_ERR_MSG("Malloc writeback reg rcq memory fail!\n");
126 goto OUT;
127 }
128 p_ovl_u->reg_blks[0].vir_addr = p_ovl_u->reg_info->vir_addr;
129 p_ovl_u->reg_blks[0].phy_addr = p_ovl_u->reg_info->phy_addr;
130 p_ovl_u->reg_blks[0].size = p_ovl_u->reg_info->size;
131 p_ovl_u->reg_blks[0].reg_addr = reg_base;
132
133 p_ovl_u->reg_info->size = sizeof(struct g2d_mixer_ovl_v_reg);
134 p_ovl_u->reg_info->vir_addr = (u8 *)g2d_top_reg_memory_alloc(
135 p_ovl_u->reg_info->size,
136 (void *)&(p_ovl_u->reg_info->phy_addr), p_rcq_info);
137
138 if (!p_ovl_u->reg_info->vir_addr) {
139 G2D_ERR_MSG("Malloc writeback reg rcq memory fail!\n");
140 goto OUT;
141 }
142 p_ovl_u->reg_blks[1].vir_addr = p_ovl_u->reg_info->vir_addr;
143 p_ovl_u->reg_blks[1].phy_addr = p_ovl_u->reg_info->phy_addr;
144 p_ovl_u->reg_blks[1].size = p_ovl_u->reg_info->size;
145 p_ovl_u->reg_blks[1].reg_addr = base + G2D_UI1;
146
147 p_ovl_u->reg_info->size = sizeof(struct g2d_mixer_ovl_v_reg);
148 p_ovl_u->reg_info->vir_addr = (u8 *)g2d_top_reg_memory_alloc(
149 p_ovl_u->reg_info->size,
150 (void *)&(p_ovl_u->reg_info->phy_addr), p_rcq_info);
151
152 if (!p_ovl_u->reg_info->vir_addr) {
153 G2D_ERR_MSG("Malloc writeback reg rcq memory fail!\n");
154 goto OUT;
155 }
156 p_ovl_u->reg_blks[2].vir_addr = p_ovl_u->reg_info->vir_addr;
157 p_ovl_u->reg_blks[2].phy_addr = p_ovl_u->reg_info->phy_addr;
158 p_ovl_u->reg_blks[2].size = p_ovl_u->reg_info->size;
159 p_ovl_u->reg_blks[2].reg_addr = base + G2D_UI2;
160 ret = 0;
161
162 OUT:
163 return ret;
164 }
165
ovl_v_get_reg_block_num(struct ovl_u_submodule * p_ovl_u)166 static __u32 ovl_v_get_reg_block_num(struct ovl_u_submodule *p_ovl_u)
167 {
168 if (p_ovl_u)
169 return p_ovl_u->reg_blk_num;
170 return 0;
171 }
172
ovl_v_get_reg_block(struct ovl_u_submodule * p_ovl_u,struct g2d_reg_block ** blks)173 static __s32 ovl_v_get_reg_block(struct ovl_u_submodule *p_ovl_u,
174 struct g2d_reg_block **blks)
175 {
176 __s32 i = 0, ret = -1;
177
178 if (p_ovl_u) {
179 for (i = 0; i < p_ovl_u->reg_blk_num; ++i)
180 blks[i] = p_ovl_u->reg_blks + i;
181 ret = 0;
182 }
183
184 return ret;
185 }
186
ovl_v_get_reg(struct ovl_u_submodule * p_ovl_u,__u32 sel)187 static struct g2d_mixer_ovl_u_reg *ovl_v_get_reg(struct ovl_u_submodule *p_ovl_u, __u32 sel)
188 {
189 if (sel > p_ovl_u->reg_blk_num - 1)
190 goto OUT;
191
192 #if G2D_MIXER_RCQ_USED == 1
193 return (struct g2d_mixer_ovl_u_reg *)(p_ovl_u->reg_blks[sel]
194 .vir_addr);
195 #else
196 return (struct g2d_mixer_ovl_u_reg *)(p_ovl_u->reg_blks[sel]
197 .reg_addr);
198 #endif
199 OUT:
200 return NULL;
201 }
202
203
ovl_v_set_block_dirty(struct ovl_u_submodule * p_ovl_u,__u32 blk_id,__u32 dirty)204 static void ovl_v_set_block_dirty(struct ovl_u_submodule *p_ovl_u, __u32 blk_id, __u32 dirty)
205 {
206
207 if (blk_id > p_ovl_u->reg_blk_num - 1)
208 return;
209
210 #if G2D_MIXER_RCQ_USED == 1
211 if (p_ovl_u && p_ovl_u->reg_blks->rcq_hd)
212 p_ovl_u->reg_blks[blk_id].rcq_hd->dirty.bits.dirty = dirty;
213 else
214 G2D_ERR_MSG("Null pointer!\n");
215 #else
216
217 if (p_ovl_u)
218 p_ovl_u->reg_blks[blk_id].dirty = dirty;
219 else
220 G2D_ERR_MSG("Null pointer!\n");
221 #endif
222 }
223
ovl_v_get_rcq_mem_size(struct ovl_u_submodule * p_ovl_u)224 static __u32 ovl_v_get_rcq_mem_size(struct ovl_u_submodule *p_ovl_u)
225 {
226 return G2D_RCQ_BYTE_ALIGN(sizeof(struct g2d_mixer_ovl_v_reg)) *
227 p_ovl_u->reg_blk_num;
228 }
229
ovl_u_destory(struct ovl_u_submodule * p_ovl_u)230 static __s32 ovl_u_destory(struct ovl_u_submodule *p_ovl_u)
231 {
232 __s32 ret = -1;
233
234 if (p_ovl_u) {
235 free(p_ovl_u->reg_blks);
236 p_ovl_u->reg_blks = NULL;
237
238 free(p_ovl_u->reg_info);
239 p_ovl_u->reg_info = NULL;
240 ret = 0;
241 free(p_ovl_u);
242 }
243
244 return ret;
245 }
246
247 struct ovl_u_submodule *
g2d_ovl_u_submodule_setup(struct g2d_mixer_frame * p_frame)248 g2d_ovl_u_submodule_setup(struct g2d_mixer_frame *p_frame)
249 {
250 struct ovl_u_submodule *p_ovl_u = NULL;
251
252 p_ovl_u = hal_malloc(sizeof(struct ovl_u_submodule));
253
254 if (!p_ovl_u) {
255 G2D_ERR_MSG("malloc wb submodule fail!\n");
256 return NULL;
257 }
258 memset(p_ovl_u, 0, sizeof(struct ovl_u_submodule));
259 p_ovl_u->rcq_setup = ovl_u_rcq_setup;
260 p_ovl_u->reg_blk_num = UI_LAYER_NUMBER;
261 p_ovl_u->get_reg_block_num = ovl_v_get_reg_block_num;
262 p_ovl_u->get_reg_block = ovl_v_get_reg_block;
263 p_ovl_u->get_reg = ovl_v_get_reg;
264 p_ovl_u->set_block_dirty = ovl_v_set_block_dirty;
265 p_ovl_u->get_rcq_mem_size = ovl_v_get_rcq_mem_size;
266 p_ovl_u->destory = ovl_u_destory;
267
268 p_ovl_u->reg_blks =
269 hal_malloc(sizeof(struct g2d_reg_block) * p_ovl_u->reg_blk_num);
270 p_ovl_u->reg_info =
271 hal_malloc(sizeof(struct g2d_reg_mem_info));
272
273 if (!p_ovl_u->reg_blks || !p_ovl_u->reg_info) {
274 G2D_ERR_MSG("malloc wb reg info fail!\n");
275 goto FREE_WB;
276 }
277 memset(p_ovl_u->reg_blks, 0, sizeof(struct g2d_reg_block) * p_ovl_u->reg_blk_num);
278 memset(p_ovl_u->reg_info, 0, sizeof(struct g2d_reg_mem_info));
279
280 return p_ovl_u;
281 FREE_WB:
282 free(p_ovl_u->reg_blks);
283 free(p_ovl_u->reg_info);
284 free(p_ovl_u);
285
286 return NULL;
287 }
288