• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Beken Corporation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <common/bk_include.h>
17 #include <soc/soc.h>
18 #include <driver/hal/hal_dma2d_types.h>
19 #include "dma2d_ll.h"
20 #include "dma2d_hal.h"
21 
22 dma2d_hal_t s_dma2d_hal;
23 
dma2d_hal_init(DMA2D_HandleTypeDef * dma2d)24 bk_err_t dma2d_hal_init(DMA2D_HandleTypeDef *dma2d)
25 {
26 	s_dma2d_hal.hw = (dma2d_hw_t *)SOC_DMA2D_REG_BASE;
27 
28 	// 000:m2m; 001:m2m pixel convert with fg; 010:m2m blend; 011:r2m.only with output; 100: m2m blend fix fg; 101:m2m blend fix bg;
29 	dma2d_ll_set_dma2d_control_reg_mode(s_dma2d_hal.hw, dma2d->init.Mode);
30 	dma2d_ll_set_dma2d_control_reg_out_byte_revese(s_dma2d_hal.hw, dma2d->init.data_reverse);
31 	dma2d_ll_set_dma2d_control_reg_master_tran_length(s_dma2d_hal.hw, dma2d->init.trans_ability);
32 
33 	dma2d_ll_set_dma2d_control_reg_line_offset_mode(s_dma2d_hal.hw, dma2d->init.LineOffsetMode);
34 
35 	//0:argb888; 1:rgb888; 010:rgb565; 011:argb1555; 100:argb444
36 	dma2d_ll_set_out_pfc_contrl_out_color_mode(s_dma2d_hal.hw, dma2d->init.ColorMode);
37 
38 	dma2d_ll_set_out_pfc_contrl_out_alpha_invert(s_dma2d_hal.hw, dma2d->init.AlphaInverted);
39 	dma2d_ll_set_output_offset_out_line_offset(s_dma2d_hal.hw, dma2d->init.OutputOffset);
40 	dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_rb_swap(s_dma2d_hal.hw, dma2d->init.RedBlueSwap);
41 	return BK_OK;
42 }
43 
dma2d_hal_deinit(void)44 bk_err_t dma2d_hal_deinit(void)
45 {
46 	s_dma2d_hal.hw = (dma2d_hw_t *)SOC_DMA2D_REG_BASE;
47 
48 	// 000:m2m; 001:m2m pixel convert with fg; 010:m2m blend; 011:r2m.only with output; 100: m2m blend fix fg; 101:m2m blend fix bg;
49 	dma2d_ll_set_dma2d_control_reg_value(s_dma2d_hal.hw,0);
50 	dma2d_ll_set_dma2d_int_clear_value(s_dma2d_hal.hw, 0x3f);
51 	//0:argb888; 1:rgb888; 010:rgb565; 011:argb1555; 100:argb444
52 	dma2d_ll_set_out_pfc_contrl_value(s_dma2d_hal.hw, 0);
53 	dma2d_ll_set_output_offset_value(s_dma2d_hal.hw, 0);
54 	dma2d_ll_set_dma2d_fg_address_value(s_dma2d_hal.hw, 0);
55 	dma2d_ll_set_dma2d_bg_address_value(s_dma2d_hal.hw, 0);
56 	dma2d_ll_set_dma2d_fg_pfc_ctrl_value(s_dma2d_hal.hw, 0);
57 	dma2d_ll_set_dma2d_fg_pfc_ctrl_value(s_dma2d_hal.hw, 0);
58 
59 	return BK_OK;
60 }
61 
62 
63 /**
64   * @brief  Set the DMA2D transfer parameters.
65   * @param  dma2d     Pointer to a DMA2D_HandleTypeDef structure that contains
66   *                     the configuration information for the specified DMA2D.
67   * @param  src_addr      The source memory Buffer address
68   * @param  DstAddress The destination memory Buffer address
69   * @param  Width      The width of data to be transferred from source to destination.(number of pixel every line)
70   * @param  Height     The height of data to be transferred from source to destination.(number of line)
71   * @retval HAL status, uint32_t src_addr, uint32_t dst_addr, uint32_t width, uint32_t height
72   */
dma2d_hal_config(DMA2D_HandleTypeDef * dma2d,uint32_t src_addr,uint32_t dst_addr,uint32_t width,uint32_t height)73 bk_err_t dma2d_hal_config(DMA2D_HandleTypeDef *dma2d, uint32_t src_addr, uint32_t dst_addr, uint32_t width, uint32_t height)
74 {
75 	uint32_t tmp;
76 	uint32_t tmp1;
77 	uint32_t tmp2;
78 	uint32_t tmp3;
79 	uint32_t tmp4;
80 
81 	dma2d_ll_set_dma2d_number_of_line_pixel_line(s_dma2d_hal.hw, width);
82 	dma2d_ll_set_dma2d_number_of_line_number_line(s_dma2d_hal.hw, height);
83 	dma2d_ll_set_dma2d_out_mem_address_out_mem_address(s_dma2d_hal.hw, dst_addr);
84 
85 	if (dma2d->init.Mode == DMA2D_R2M) {
86 		tmp1 = src_addr & DMA2D_OCOLR_ALPHA_1;
87 		tmp2 = src_addr & DMA2D_OCOLR_RED_1;
88 		tmp3 = src_addr & DMA2D_OCOLR_GREEN_1;
89 		tmp4 = src_addr & DMA2D_OCOLR_BLUE_1;
90 		/* Prepare the value to be written to the OCOLR register according to the color mode */
91 		if (dma2d->init.ColorMode == DMA2D_OUTPUT_ARGB8888) {
92 			tmp = (tmp3 | tmp2 | tmp1| tmp4);
93 		}
94 		else if (dma2d->init.ColorMode == DMA2D_OUTPUT_RGB888) {
95 			tmp = (tmp3 | tmp2 | tmp4);
96 		}
97 		else if (dma2d->init.ColorMode == DMA2D_OUTPUT_RGB565) {
98 			tmp2 = (tmp2 >> 19U);
99 			tmp3 = (tmp3 >> 10U);
100 			tmp4 = (tmp4 >> 3U );
101 			tmp  = ((tmp3 << 5U) | (tmp2 << 11U) | tmp4);
102 		}
103 		else if (dma2d->init.ColorMode == DMA2D_OUTPUT_ARGB1555) {
104 			tmp1 = (tmp1 >> 31U);
105 			tmp2 = (tmp2 >> 19U);
106 			tmp3 = (tmp3 >> 11U);
107 			tmp4 = (tmp4 >> 3U );
108 			tmp  = ((tmp3 << 5U) | (tmp2 << 10U) | (tmp1 << 15U) | tmp4);
109 		}
110 		else /* Ddma2d->Init.ColorMode = DMA2D_OUTPUT_ARGB4444 */ {
111 			tmp1 = (tmp1 >> 28U);
112 			tmp2 = (tmp2 >> 20U);
113 			tmp3 = (tmp3 >> 12U);
114 			tmp4 = (tmp4 >> 4U );
115 			tmp  = ((tmp3 << 4U) | (tmp2 << 8U) | (tmp1 << 12U) | tmp4);
116 		}
117 		dma2d_ll_set_out_color_reg_output_clor_reg(s_dma2d_hal.hw, tmp);
118 	}
119 	else if (dma2d->init.Mode == DMA2D_M2M_BLEND_FG) /*M2M_blending with fixed color FG DMA2D Mode selected*/ {
120 		dma2d_ll_set_dma2d_bg_address_value(s_dma2d_hal.hw, src_addr);
121 	}
122 
123 	else /* M2M, M2M_PFC,M2M_Blending or M2M_blending with fixed color BG DMA2D Mode */ {
124 		/* Configure DMA2D source address */
125 		dma2d_ll_set_dma2d_fg_address_value(s_dma2d_hal.hw, src_addr);
126 	}
127 
128 	return BK_OK;
129 }
130 
131 
dma2d_hal_start_transfer(bool start_transfer)132 bk_err_t dma2d_hal_start_transfer(bool start_transfer)
133 {
134 	dma2d_ll_set_dma2d_control_reg_tran_start(s_dma2d_hal.hw, start_transfer);
135 	return BK_OK;
136 }
137 
dma2d_hal_is_transfer_done(void)138 bool dma2d_hal_is_transfer_done(void)
139 {
140 	return dma2d_ll_get_dma2d_control_reg_tran_start(s_dma2d_hal.hw);
141 }
142 
143 /**
144   * @brief  Start the multi-source DMA2D Transfer with interrupt enabled.
145   * @param  dma2d     Pointer to a DMA2D_HandleTypeDef structure that contains
146   *                     the configuration information for the DMA2D.
147   * @param  src_addr1 The source memory Buffer address for the foreground layer.
148   * @param  src_addr2 The source memory Buffer address for the background layer.
149   * @param  dst_addr  The destination memory Buffer address.
150   * @param  Width       The width of data to be transferred from source to destination (expressed in number of pixels per line).
151   * @param  Height      The height of data to be transferred from source to destination (expressed in number of lines).
152   * @retval HAL status
153   */
dma2d_hal_blending_start(DMA2D_HandleTypeDef * dma2d,uint32_t src_addr1,uint32_t src_addr2,uint32_t dst_addr,uint32_t Width,uint32_t Height)154 bk_err_t dma2d_hal_blending_start(DMA2D_HandleTypeDef *dma2d, uint32_t src_addr1, uint32_t src_addr2, uint32_t dst_addr, uint32_t Width,  uint32_t Height)
155 {
156 	if(dma2d->init.Mode == DMA2D_M2M_BLEND_FG)
157 	{
158 		/*blending & fixed FG*/
159 		dma2d_ll_set_dma2d_fg_color_reg_value(s_dma2d_hal.hw, src_addr1);
160 		/* Configure the source, destination address and the data size */
161 		dma2d_hal_config(dma2d, src_addr2, dst_addr, Width, Height);
162 	}
163 	else if (dma2d->init.Mode == DMA2D_M2M_BLEND_BG)
164 	{
165 		/*blending & fixed BG*/
166 		dma2d_ll_set_dma2d_bg_color_reg_value(s_dma2d_hal.hw, src_addr2);
167 		/* Configure the source, destination address and the data size */
168 		dma2d_hal_config(dma2d, src_addr1, dst_addr, Width, Height);
169 	}
170 	else
171 	{
172 		dma2d_ll_set_dma2d_bg_address_bg_address(s_dma2d_hal.hw, src_addr2);
173 		/* Configure the source, destination address and the data size */
174 		dma2d_hal_config(dma2d, src_addr1, dst_addr, Width, Height);
175 	}
176 	dma2d_ll_set_dma2d_control_reg_tran_start(s_dma2d_hal.hw, 1);
177 	return BK_OK;
178 }
179 
180 
dma2d_hal_suspend(bool suspend)181 bk_err_t dma2d_hal_suspend(bool suspend)
182 {
183 	dma2d_ll_set_dma2d_control_reg_tran_suspend(s_dma2d_hal.hw, suspend);
184 	return BK_OK;
185 }
186 
187 /**
188   * @brief  Configure the DMA2D CLUT Transfer.
189   * @param  dma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
190   *                   the configuration information for the DMA2D.
191   * @param  CLUTCfg  Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
192   *                   the configuration information for the color look up table.
193   * @param  LayerIdx DMA2D Layer index.
194   *                   This parameter can be one of the following values:
195   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
196   * @note API obsolete and maintained for compatibility with legacy. User is invited
197   *      to resort to HAL_DMA2D_CLUTStartLoad() instead to benefit from code compactness,
198   *      code size and improved heap usage.
199   * @retval HAL status
200   */
dma2d_hal_clut_config(DMA2D_CLUTCfgTypeDef CLUTCfg,uint32_t LayerIdx)201 bk_err_t dma2d_hal_clut_config(DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx)
202 {
203 	if(LayerIdx == DMA2D_BACKGROUND_LAYER)
204 	{
205 		/* Write background CLUT memory address */
206 		dma2d_ll_set_bg_clut_mem_address_value(s_dma2d_hal.hw, (uint32_t)CLUTCfg.pCLUT);
207 		/* Write background CLUT size and CLUT color mode */
208 		dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_clut_color_mode(s_dma2d_hal.hw, CLUTCfg.CLUTColorMode);
209 //		dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_start_clut();
210 		dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_clut_size(s_dma2d_hal.hw, CLUTCfg.Size);
211 	}
212 	/* Configure the CLUT of the foreground DMA2D layer */
213 	else
214 	{
215 		/* Write foreground CLUT memory address */
216 		dma2d_ll_set_fg_clut_mem_address_value(s_dma2d_hal.hw,  (uint32_t)CLUTCfg.pCLUT);
217 		/* Write foreground CLUT size and CLUT color mode */
218 		dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_color_mode(s_dma2d_hal.hw, CLUTCfg.CLUTColorMode);
219 		dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_clut_size(s_dma2d_hal.hw, CLUTCfg.Size);
220 	}
221 	return BK_OK;
222 }
223 
224 /**
225   * @brief  Configure the DMA2D Layer according to the specified
226   *         parameters in the DMA2D_HandleTypeDef.
227   * @param  dma2d Pointer to a DMA2D_HandleTypeDef structure that contains
228   *                 the configuration information for the DMA2D.
229   * @param  LayerIdx DMA2D Layer index.
230   *                   This parameter can be one of the following values:
231   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
232   * @retval HAL status
233   */
dma2d_hal_layer_config(DMA2D_HandleTypeDef * dma2d,uint32_t LayerIdx)234 bk_err_t dma2d_hal_layer_config(DMA2D_HandleTypeDef *dma2d, uint32_t LayerIdx)
235 {
236 	DMA2D_LAYER_CFG *pLayerCfg;
237 
238 	pLayerCfg = &dma2d->LayerCfg[LayerIdx];
239 
240 	/* Configure the background DMA2D layer */
241 	if (LayerIdx == DMA2D_BACKGROUND_LAYER) {
242 		 /* Write DMA2D BGPFCCR register */
243 		dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_color_mode(s_dma2d_hal.hw, pLayerCfg->InputColorMode);
244 		dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_alpha_mode(s_dma2d_hal.hw, pLayerCfg->AlphaMode);
245 		dma2d_ll_set_dma2d_bg_pfc_ctrl_alpha_invert(s_dma2d_hal.hw, pLayerCfg->AlphaInverted);
246 		dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_rb_swap(s_dma2d_hal.hw, pLayerCfg->RedBlueSwap);
247 
248 		if (pLayerCfg->AlphaMode == DMA2D_REPLACE_ALPHA) {
249 			dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_alpha(s_dma2d_hal.hw, pLayerCfg->InputAlpha);
250 		}
251 		if (pLayerCfg->AlphaMode == DMA2D_COMBINE_ALPHA) {
252 			dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_alpha(s_dma2d_hal.hw, (pLayerCfg->InputAlpha & dma2d_ll_get_dma2d_fg_pfc_ctrl_fg_alpha(s_dma2d_hal.hw)));
253 		}
254 
255 		/* DMA2D BGOR register configuration -------------------------------------*/
256 		dma2d_ll_set_dma2d_bg_offset_bg_line_offset(s_dma2d_hal.hw, pLayerCfg->InputOffset);
257 
258 		/* DMA2D BGCOLR register configuration -------------------------------------*/
259 		if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8))
260 		{
261 			dma2d_ll_set_dma2d_bg_color_reg_value(s_dma2d_hal.hw, pLayerCfg->Inputcolor);
262 		}
263 	}
264 	 /* Configure the foreground DMA2D layer */
265 	else {
266 		/* Write DMA2D FGPFCCR register */
267 		dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_color_mode(s_dma2d_hal.hw, pLayerCfg->InputColorMode);
268 		dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_alpha_mode(s_dma2d_hal.hw, pLayerCfg->AlphaMode);
269 		dma2d_ll_set_dma2d_fg_pfc_ctrl_alpha_invert(s_dma2d_hal.hw, pLayerCfg->AlphaInverted);
270 		dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_rb_swap(s_dma2d_hal.hw, pLayerCfg->RedBlueSwap);
271 
272 		if (pLayerCfg->AlphaMode == DMA2D_REPLACE_ALPHA) {
273 			dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_alpha(s_dma2d_hal.hw, pLayerCfg->InputAlpha);
274 		}
275 		if (pLayerCfg->AlphaMode == DMA2D_COMBINE_ALPHA) {
276 			dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_alpha(s_dma2d_hal.hw, (pLayerCfg->InputAlpha & dma2d_ll_get_dma2d_fg_pfc_ctrl_fg_alpha(s_dma2d_hal.hw)));
277 		}
278 
279 		/* DMA2D FGOR register configuration -------------------------------------*/
280 		dma2d_ll_set_dma2d_fg_offset_fg_line_offset(s_dma2d_hal.hw, pLayerCfg->InputOffset);
281 
282 		/* DMA2D FGCOLR register configuration -------------------------------------*/
283 		if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8)) {
284 			dma2d_ll_set_dma2d_bg_color_reg_value(s_dma2d_hal.hw, pLayerCfg->Inputcolor);
285 		}
286 	}
287 	return BK_OK;
288 }
289 
290 
dma2d_hal_abort(bool abort)291 bk_err_t dma2d_hal_abort(bool abort)
292 {
293 	dma2d_ll_set_dma2d_control_reg_tran_abort(s_dma2d_hal.hw, abort);
294 	return BK_OK;
295 }
296 
297 
dma2d_hal_int_config(DMA2D_INT_TYPE int_type,bool enable)298 bk_err_t dma2d_hal_int_config(DMA2D_INT_TYPE int_type, bool enable)
299 {
300 	uint32_t int_value;
301 
302 	int_value = dma2d_ll_get_dma2d_control_reg_value(s_dma2d_hal.hw);
303 
304 	if (1 == enable) {
305 		dma2d_ll_set_dma2d_control_reg_value(s_dma2d_hal.hw, int_value | int_type);
306 	}
307 	else {
308 		dma2d_ll_set_dma2d_control_reg_value(s_dma2d_hal.hw, int_value & ~(int_type));
309 	}
310 
311 	return BK_OK;
312 }
313 
dma2d_hal_int_status_get(void)314 bk_err_t dma2d_hal_int_status_get(void)
315 {
316 	return dma2d_ll_get_dma2d_int_status_value(s_dma2d_hal.hw);
317 }
318 
dma2d_hal_int_status_clear(DMA2D_INT_STATUS int_status)319 bk_err_t dma2d_hal_int_status_clear(DMA2D_INT_STATUS int_status)
320 {
321 	dma2d_ll_set_dma2d_int_clear_value(s_dma2d_hal.hw, int_status);
322 	return BK_OK;
323 }
324 
325 /**
326   * @brief  Configure the line watermark.
327   * @param  Line   Line Watermark configuration (maximum 16-bit long value expected).
328   * @note   dma2d_hal_line_Watermar_cfg() API used with the transfer watermark interrupt.
329   * @note   The transfer watermark interrupt is disabled once it has occurred.
330   * @retval HAL status
331   */
dma2d_hal_line_Watermar_cfg(uint32_t Line)332 bk_err_t dma2d_hal_line_Watermar_cfg(uint32_t Line)
333 {
334 	if (Line > 0xFFFF) {
335 		return BK_FAIL;
336 	}
337 	else {
338 		dma2d_ll_set_dma2d_line_watermark_line_watermark
339 (s_dma2d_hal.hw, Line);
340 	}
341 	return BK_OK;
342 }
343 
344 /**
345   * @brief  Start the multi-source DMA2D Transfer.
346   * @param  dma2d      Pointer to a DMA2D_HandleTypeDef structure that contains
347   *                      the configuration information for the DMA2D.
348   * @param  SrcAddress1 The source memory Buffer address for the foreground layer.
349   * @param  SrcAddress2 The source memory Buffer address for the background layer.
350   * @param  DstAddress  The destination memory Buffer address.
351   * @param  Width       The width of data to be transferred from source to destination (expressed in number of pixels per line).
352   * @param  Height      The height of data to be transferred from source to destination (expressed in number of lines).
353   * @retval HAL status
dma2d_hal_blending_config(uint32_t SrcAddress1,uint32_t SrcAddress2,uint32_t DstAddress,uint32_t Width,uint32_t Height)354   */
355 bk_err_t dma2d_hal_blending_config(uint32_t SrcAddress1, uint32_t SrcAddress2, uint32_t DstAddress, uint32_t Width, uint32_t Height)
356 {
357 	return dma2d_ll_get_dma2d_int_status_value(s_dma2d_hal.hw);
358 	return BK_OK;
359 }
360 
361 
362 /**
363   * @brief Configure dead time.
364   * @note The dead time value represents the guaranteed minimum number of cycles between
365   *       two consecutive transactions on the AHB bus.
366   * @param DeadTime dead time value.
367   * @param en.
368   * @retval HAL status
dma2d_hal_deadtime_config(uint8_t DeadTime,bool en)369   */
370 bk_err_t dma2d_hal_deadtime_config(uint8_t DeadTime, bool en)
371 {
372 	dma2d_ll_set_dma2d_master_time_config_master_time_ena(s_dma2d_hal.hw, en);
373 	dma2d_ll_set_dma2d_master_time_config_dead_time(s_dma2d_hal.hw, DeadTime);
374 
375 	return BK_OK;
376 }
377 
378 
379