• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Beken Corporation
2 //
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 // Copyright 2020-2021 Beken
16 //
17 // Licensed under the Apache License, Version 2.0 (the "License");
18 // you may not use this file except in compliance with the License.
19 // You may obtain a copy of the License at
20 //
21 //     http://www.apache.org/licenses/LICENSE-2.0
22 //
23 // Unless required by applicable law or agreed to in writing, software
24 // distributed under the License is distributed on an "AS IS" BASIS,
25 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 // See the License for the specific language governing permissions and
27 // limitations under the License.
28 
29 
30 #include <stdlib.h>
31 #include <common/bk_include.h>
32 #include <os/mem.h>
33 #include "arch_interrupt.h"
34 #include "sys_driver.h"
35 #include "gpio_map.h"
36 #include "gpio_driver.h"
37 #include <driver/gpio.h>
38 #include <driver/int.h>
39 #include "dma2d_hal.h"
40 #include <driver/hal/hal_dma2d_types.h>
41 #include <driver/dma2d.h>
42 #include <modules/pm.h>
43 
44 #define DMA2D_TIMEOUT_ABORT           (1000U)  /**<  1s  */
45 #define DMA2D_TIMEOUT_SUSPEND         (1000U)  /**<  1s  */
46 
47 #if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
48 
49 static dma2d_isr_t s_dma2d_isr[DMA2D_ISR_NUM] = {NULL};
50 static void dma2d_isr(void);
51 static void dma2d_isr_common(void);
52 
53 #endif
54 
55 /**
56   * @brief  initializes the DMA2D peripheral registers
57   * @param  dma2d_init_t pointr structure that contains
58   *                 the configuration information for the DMA2D
59   *usage example:
60   *
61   * @retval None
62   */
bk_dma2d_driver_init(dma2d_config_t * dma2d)63 bk_err_t bk_dma2d_driver_init(dma2d_config_t *dma2d)
64 {
65 //if(sys_drv_dma2d_set(0, 0) != 0) {
66 //		os_printf("dma2d sys clk config error \r\n");
67 //		return BK_FAIL;
68 //	}
69 	bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_DMA2D, PM_POWER_MODULE_STATE_ON);
70 #if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
71 	os_memset(&s_dma2d_isr, 0, sizeof(s_dma2d_isr));
72 	bk_int_isr_register(INT_SRC_DMA2D, dma2d_isr, NULL);
73 #endif
74 
75 	dma2d_hal_init(dma2d);
76 	dma2d_hal_start_transfer(0);
77 
78 	return BK_OK;
79 }
80 
81 /**
82   * @brief  Deinitializes the DMA2D peripheral registers to their default reset values.
83   * @retval None
84   */
bk_dma2d_driver_deinit(void)85 bk_err_t bk_dma2d_driver_deinit(void)
86 {
87 	bk_int_isr_unregister(INT_SRC_DMA2D);
88 	dma2d_hal_deinit();
89 	bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_DMA2D, PM_POWER_MODULE_STATE_OFF);
90 	return BK_OK;
91 }
92 
93 /**
94   * @brief  Configure the DMA2D Layer according to the specified
95   * @param  dma2d Pointer to a dma2d_init_t structure that contains the configuration information for the DMA2D.
96   * @param  LayerIdx DMA2D Layer index.
97   *                   This parameter can be one of the following values:
98   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
99   * @retval HAL status
100   */
bk_dma2d_layer_config(dma2d_config_t * dma2d,uint32_t layer_idx)101 bk_err_t bk_dma2d_layer_config(dma2d_config_t *dma2d, uint32_t layer_idx)
102 {
103 	dma2d_hal_layer_config(dma2d, layer_idx);
104 	return BK_OK;
105 }
106 
107 
108 /**
109   * @brief  Start the DMA2D Transfer
110   * @param  dma2d     Pointer to a dma2d_init_t structure that contains  the configuration information for the DMA2D.
111   * @param  pdata      Configure the source memory Buffer address if
112   *                     the Memory-to-Memory or Memory-to-Memory with pixel format
113   *                     conversion mode is selected, or configure
114   *                     the color value if Register-to-Memory mode is selected.
115   * @param  dst_addr The destination memory Buffer address.
116   * @param  Width      The width of data to be transferred from source to destination (expressed in number of pixels per line).
117   * @param  Height     The height of data to be transferred from source to destination (expressed in number of lines).
118   * @retval bk_err_t status
119   */
bk_dma2d_start_transfer(dma2d_config_t * dma2d,uint32_t pdata,uint32_t dst_addr,uint32_t width,uint32_t height)120 bk_err_t bk_dma2d_start_transfer(dma2d_config_t *dma2d, uint32_t pdata, uint32_t dst_addr, uint32_t width, uint32_t height)
121 {
122 	dma2d_hal_config(dma2d, pdata, dst_addr, width, height);
123 	dma2d_hal_start_transfer(1);
124 	return BK_OK;
125 }
126 
127 
128 /**
129   * @brief  bk_dma2d_wait_transfer_done
130   * @retval return 0: transfer done, return others not transfer done
131   */
bk_dma2d_is_transfer_busy(void)132 bool bk_dma2d_is_transfer_busy(void)
133 {
134 	return dma2d_hal_is_transfer_done();
135 }
136 
137 /**
138   * @brief  Start the multi-source DMA2D Transfer.
139   * @param  dma2d      Pointer to a dma2d_init_t structure that contains  the configuration information for the DMA2D.
140   * @param  src_addr1 The source memory Buffer address for the foreground layer.
141   * @param  src_addr2 The source memory Buffer address for the background layer.
142   * @param  dst_addr  The destination memory Buffer address.
143   * @param  Width       The width of data to be transferred from source to destination (expressed in number of pixels per line).
144   * @param  Height      The height of data to be transferred from source to destination (expressed in number of lines).
145   * @retval bk_err_t status
146   */
bk_dma2d_start_blending(dma2d_config_t * dma2d,uint32_t fg_addr,uint32_t bg_addr,uint32_t dst_addr,uint32_t width,uint32_t height)147 bk_err_t bk_dma2d_start_blending(dma2d_config_t *dma2d, uint32_t fg_addr, uint32_t bg_addr, uint32_t dst_addr, uint32_t width,  uint32_t height)
148 {
149 	dma2d_hal_blending_start(dma2d, fg_addr, bg_addr, dst_addr, width, height);
150 	return BK_OK;
151 }
152 
153 /**
154   * @brief  bk_dma2d_int_config.
155   * @param  int_type  select from DMA2D_INT_TYPE, include int type:
156                      DMA2D_CFG_ERROR
157                      DMA2D_CLUT_TRANS_COMPLETE
158                      DMA2D_CLUT_TRANS_ERROR
159                      DMA2D_WARTERMARK_INT
160                      DMA2D_TRANS_COMPLETE
161                      DMA2D_TRANS_ERROR
162   * @param  enable int
163   * @retval bk_err_t status
164   */
bk_dma2d_int_enable(dma2d_int_type_t int_type,bool enable)165 bk_err_t bk_dma2d_int_enable(dma2d_int_type_t int_type, bool enable)
166 {
167 	dma2d_hal_int_config(int_type, enable);
168 	return BK_OK;
169 }
170 
171 /**
172   * @brief  bk_dma2d_int_status_get.
173   * @retval return <value> is all int status, can used by <value> & DMA2D_INT_STATUS check which int triggered
174                       typedef enum
175                       {
176                           DMA2D_TRANS_ERROR_STATUS = 0x1,
177                           DMA2D_TRANS_COMPLETE_STATUS,
178                           DMA2D_WARTERMARK_INT_STATUS,
179                           DMA2D_CLUT_TRANS_ERROR_STATUS,
180                           DMA2D_CLUT_TRANS_COMPLETE_STATUS,
181                           DMA2D_CFG_ERROR_STATUS
182                       }DMA2D_INT_STATUS;
183   */
bk_dma2d_int_status_get(void)184 uint32_t bk_dma2d_int_status_get(void)
185 {
186 	return dma2d_hal_int_status_get();
187 }
188 
189 /**
190   * @brief  clear int status
191   * @param  int_status select from DMA2D_INT_STATUS include:
192                           DMA2D_TRANS_ERROR_STATUS
193                           DMA2D_TRANS_COMPLETE_STATUS
194                           DMA2D_WARTERMARK_INT_STATUS
195                           DMA2D_CLUT_TRANS_ERROR_STATUS
196                           DMA2D_CLUT_TRANS_COMPLETE_STATUS
197                           DMA2D_CFG_ERROR_STATUS
198 
199   * @retval bk_err_t status
200   */
bk_dma2d_int_status_clear(dma2d_int_status_t int_status)201 bk_err_t bk_dma2d_int_status_clear(dma2d_int_status_t int_status)
202 {
203 	dma2d_hal_int_status_clear(int_status);
204 	return BK_OK;
205 }
206 
207 /**
208   * @brief bk_dma2d_suspend
209   * @param suspend
210   * @retval bk_err_t status
211   */
bk_driver_dma2d_suspend(bool suspend)212 bk_err_t bk_driver_dma2d_suspend(bool suspend)
213 {
214 	dma2d_hal_suspend(suspend);
215 	return BK_OK;
216 }
217 
218 
219 /**
220   * @brief  register dma2d cpu int isr
221   * @param  dma2d_isr the function you registr isr
222   * @retval bk_err_t status
223   */
bk_dma2d_isr_register(dma2d_isr_t dma2d_isr)224 bk_err_t bk_dma2d_isr_register(dma2d_isr_t dma2d_isr)
225 {
226 	bk_int_isr_register(INT_SRC_DMA2D, dma2d_isr, NULL);
227 	return BK_OK;
228 }
229 
HAL_GetTick()230 static uint32_t HAL_GetTick()
231 {
232 	return 0;
233 }
234 
235 /**
236   * @brief bk_dma2d_abort
237   * @param abort
238   * @retval bk_err_t status
239   */
240 
bk_driver_dma2d_abort(bool abort)241 bk_err_t bk_driver_dma2d_abort(bool abort)
242 {
243 	uint32_t tickstart;
244 
245 	/* Abort the DMA2D transfer */
246 	/* START bit is reset to make sure not to set it again, in the event the HW clears it
247 	   between the register read and the register write by the CPU (writing 0 has no
248 	   effect on START bitvalue) */
249 	dma2d_hal_abort(abort);
250 
251 	/* Get tick */
252 	tickstart = HAL_GetTick();
253 
254 	/* Check if the DMA2D is effectively disabled */
255 	while(!dma2d_hal_is_transfer_done()) {
256 		if ((HAL_GetTick() - tickstart ) > DMA2D_TIMEOUT_ABORT) {
257 			return BK_ERR_TIMEOUT;
258 		}
259 	}
260 	return BK_OK;
261 }
262 
263 
264 
265 #if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
266 
267 /* dma2d interrupt enter */
dma2d_isr(void)268 static void dma2d_isr(void)
269 {
270 	dma2d_isr_common();
271 }
272 
273 /* dma2d check interrupt flag and excute correponding isr function when enter interrupt */
dma2d_isr_common(void)274 static void dma2d_isr_common(void)
275 {
276 	uint32_t int_status;
277 	int_status = bk_dma2d_int_status_get();
278 	if (int_status & DMA2D_CFG_ERROR_STATUS) {
279 
280 		if (s_dma2d_isr[DMA2D_CFG_ERROR_ISR]) {
281 			s_dma2d_isr[DMA2D_CFG_ERROR_ISR]();
282 		}
283 	}
284 	//Transfer Error Interrupt management
285 	if (int_status & DMA2D_TRANS_ERROR_STATUS) {
286 		if (s_dma2d_isr[DMA2D_TRANS_ERROR_ISR]) {
287 			s_dma2d_isr[DMA2D_TRANS_ERROR_ISR]();
288 		}
289 	}
290 	if (int_status & DMA2D_TRANS_COMPLETE_STATUS) {
291 		if (s_dma2d_isr[DMA2D_TRANS_COMPLETE_ISR]) {
292 			s_dma2d_isr[DMA2D_TRANS_COMPLETE_ISR]();
293 		}
294 	}
295 	if (int_status & DMA2D_WARTERMARK_INT_STATUS) {
296 		if (s_dma2d_isr[DMA2D_WARTERMARK_INT_ISR]) {
297 			s_dma2d_isr[DMA2D_WARTERMARK_INT_ISR]();
298 		}
299 	}
300 	if (int_status & DMA2D_CLUT_TRANS_COMPLETE_STATUS) {
301 		if (s_dma2d_isr[DMA2D_CLUT_TRANS_COMPLETE_ISR]) {
302 			s_dma2d_isr[DMA2D_CLUT_TRANS_COMPLETE_ISR]();
303 		}
304 	}
305 	if (int_status & DMA2D_CLUT_TRANS_ERROR_STATUS) {
306 		if (s_dma2d_isr[DMA2D_CLUT_TRANS_ERROR_ISR]) {
307 			s_dma2d_isr[DMA2D_CLUT_TRANS_ERROR_ISR]();
308 		}
309 	}
310 }
311 
312 /**
313   * @brief  register dma2d int type isr ,user option function
314             open the macro  #define USE_HAL_DMA2D_REGISTER_CALLBACKS 1
315   * @param  isr_id based on int type, a int type can register a isr, select from:
316                              typedef enum
317                              {
318                                   DMA2D_CFG_ERROR_ISR = 0,
319                                   DMA2D_CLUT_TRANS_COMPLETE_ISR,
320                                   DMA2D_CLUT_TRANS_ERROR_ISR,
321                                   DMA2D_WARTERMARK_INT_ISR,
322                                   DMA2D_TRANS_COMPLETE_ISR,
323                                   DMA2D_TRANS_ERROR_ISR,
324                              }DMA2D_ISR_ID;
325   * @param  cb_isr the user register int callback function
326   * @retval bk_err_t status
327   */
bk_dma2d_register_int_callback_isr(DMA2D_ISR_ID isr_id,dma2d_isr_t cb_isr)328 bk_err_t bk_dma2d_register_int_callback_isr(DMA2D_ISR_ID isr_id, dma2d_isr_t cb_isr)
329 {
330 	if ((isr_id) >= DMA2D_ISR_NUM)
331 		return BK_FAIL;
332 
333 	uint32_t int_level = rtos_disable_int();
334 
335 	s_dma2d_isr[isr_id] = cb_isr;
336 
337 	rtos_enable_int(int_level);
338 
339 	return BK_OK;
340 }
341 
342 #endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */
343 
344 
345 
346