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