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