summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/arm/imx233/dma-imx233.c81
-rw-r--r--firmware/target/arm/imx233/dma-imx233.h39
2 files changed, 115 insertions, 5 deletions
diff --git a/firmware/target/arm/imx233/dma-imx233.c b/firmware/target/arm/imx233/dma-imx233.c
index 97001210d2..8dac284a38 100644
--- a/firmware/target/arm/imx233/dma-imx233.c
+++ b/firmware/target/arm/imx233/dma-imx233.c
@@ -24,6 +24,8 @@
24#include "config.h" 24#include "config.h"
25#include "system.h" 25#include "system.h"
26#include "dma-imx233.h" 26#include "dma-imx233.h"
27#include "lcd.h"
28#include "string.h"
27 29
28void imx233_dma_init(void) 30void imx233_dma_init(void)
29{ 31{
@@ -34,12 +36,22 @@ void imx233_dma_init(void)
34 36
35void imx233_dma_reset_channel(unsigned chan) 37void imx233_dma_reset_channel(unsigned chan)
36{ 38{
39 volatile uint32_t *ptr;
40 uint32_t bm;
37 if(APB_IS_APBX_CHANNEL(chan)) 41 if(APB_IS_APBX_CHANNEL(chan))
38 __REG_SET(HW_APBX_CHANNEL_CTRL) = 42 {
39 HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan)); 43 ptr = &HW_APBX_CHANNEL_CTRL;
44 bm = HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
45 }
40 else 46 else
41 __REG_SET(HW_APBH_CTRL0) = 47 {
42 HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan)); 48 ptr = &HW_APBH_CTRL0;
49 bm = HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
50 }
51 __REG_SET(*ptr) = bm;
52 /* wait for end of reset */
53 while(*ptr & bm)
54 ;
43} 55}
44 56
45void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock) 57void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock)
@@ -54,6 +66,27 @@ void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock)
54 HW_APBH_CTRL0__CLKGATE_CHANNEL(APB_GET_DMA_CHANNEL(chan)); 66 HW_APBH_CTRL0__CLKGATE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
55} 67}
56 68
69void imx233_dma_freeze_channel(unsigned chan, bool freeze)
70{
71 volatile uint32_t *ptr;
72 uint32_t bm;
73 if(APB_IS_APBX_CHANNEL(chan))
74 {
75 ptr = &HW_APBX_CHANNEL_CTRL;
76 bm = HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
77 }
78 else
79 {
80 ptr = &HW_APBH_CTRL0;
81 bm = HW_APBH_CTRL0__FREEZE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
82 }
83
84 if(freeze)
85 __REG_SET(*ptr) = bm;
86 else
87 __REG_CLR(*ptr) = bm;
88}
89
57void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable) 90void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable)
58{ 91{
59 volatile uint32_t *ptr; 92 volatile uint32_t *ptr;
@@ -65,7 +98,7 @@ void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable)
65 } 98 }
66 else 99 else
67 { 100 {
68 ptr = &HW_APBH_CTRL1;; 101 ptr = &HW_APBH_CTRL1;
69 bm = HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(APB_GET_DMA_CHANNEL(chan)); 102 bm = HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(APB_GET_DMA_CHANNEL(chan));
70 } 103 }
71 104
@@ -186,3 +219,41 @@ void imx233_dma_wait_completion(unsigned chan)
186 while(*sema & HW_APB_CHx_SEMA__PHORE_BM) 219 while(*sema & HW_APB_CHx_SEMA__PHORE_BM)
187 yield(); 220 yield();
188} 221}
222
223struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags)
224{
225 struct imx233_dma_info_t s;
226 memset(&s, 0, sizeof(s));
227 bool apbx = APB_IS_APBX_CHANNEL(chan);
228 int dmac = APB_GET_DMA_CHANNEL(chan);
229 if(flags & DMA_INFO_CURCMDADDR)
230 s.cur_cmd_addr = apbx ? HW_APBX_CHx_CURCMDAR(dmac) : HW_APBH_CHx_CURCMDAR(dmac);
231 if(flags & DMA_INFO_NXTCMDADDR)
232 s.nxt_cmd_addr = apbx ? HW_APBX_CHx_NXTCMDAR(dmac) : HW_APBH_CHx_NXTCMDAR(dmac);
233 if(flags & DMA_INFO_CMD)
234 s.cmd = apbx ? HW_APBX_CHx_CMD(dmac) : HW_APBH_CHx_CMD(dmac);
235 if(flags & DMA_INFO_BAR)
236 s.bar = apbx ? HW_APBX_CHx_BAR(dmac) : HW_APBH_CHx_BAR(dmac);
237 if(flags & DMA_INFO_AHB_BYTES)
238 s.ahb_bytes = apbx ? __XTRACT_EX(HW_APBX_CHx_DEBUG2(dmac), HW_APBX_CHx_DEBUG2__AHB_BYTES) :
239 __XTRACT_EX(HW_APBH_CHx_DEBUG2(dmac), HW_APBH_CHx_DEBUG2__AHB_BYTES);
240 if(flags & DMA_INFO_APB_BYTES)
241 s.apb_bytes = apbx ? __XTRACT_EX(HW_APBX_CHx_DEBUG2(dmac), HW_APBX_CHx_DEBUG2__APB_BYTES) :
242 __XTRACT_EX(HW_APBH_CHx_DEBUG2(dmac), HW_APBH_CHx_DEBUG2__APB_BYTES);
243 if(flags & DMA_INFO_FREEZED)
244 s.freezed = apbx ? HW_APBX_CHANNEL_CTRL & HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(dmac) :
245 HW_APBH_CTRL0 & HW_APBH_CTRL0__FREEZE_CHANNEL(dmac);
246 if(flags & DMA_INFO_GATED)
247 s.gated = apbx ? false : HW_APBH_CTRL0 & HW_APBH_CTRL0__CLKGATE_CHANNEL(dmac);
248 if(flags & DMA_INFO_INTERRUPT)
249 {
250 s.int_enabled = apbx ? HW_APBX_CTRL1 & HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(dmac) :
251 HW_APBH_CTRL1 & HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(dmac);
252 s.int_cmdcomplt = apbx ? HW_APBX_CTRL1 & HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(dmac) :
253 HW_APBH_CTRL1 & HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(dmac);
254 s.int_error = apbx ? HW_APBX_CTRL2 & HW_APBX_CTRL2__CHx_ERROR_IRQ(dmac) :
255 HW_APBH_CTRL2 & HW_APBH_CTRL2__CHx_ERROR_IRQ(dmac);
256 }
257 return s;
258}
259
diff --git a/firmware/target/arm/imx233/dma-imx233.h b/firmware/target/arm/imx233/dma-imx233.h
index c0727a51e1..05baea989c 100644
--- a/firmware/target/arm/imx233/dma-imx233.h
+++ b/firmware/target/arm/imx233/dma-imx233.h
@@ -65,6 +65,10 @@
65#define HW_APBH_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x90 + 0x70 * (i))) 65#define HW_APBH_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x90 + 0x70 * (i)))
66 66
67#define HW_APBH_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0xa0 + 0x70 * (i))) 67#define HW_APBH_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0xa0 + 0x70 * (i)))
68#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BP 0
69#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BM 0xffff
70#define HW_APBH_CHx_DEBUG2__APB_BYTES_BP 16
71#define HW_APBH_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
68 72
69/******** 73/********
70 * APHX * 74 * APHX *
@@ -104,6 +108,10 @@
104#define HW_APBX_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x150 + (i) * 0x70)) 108#define HW_APBX_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x150 + (i) * 0x70))
105 109
106#define HW_APBX_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x160 + (i) * 0x70)) 110#define HW_APBX_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x160 + (i) * 0x70))
111#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BP 0
112#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BM 0xffff
113#define HW_APBX_CHx_DEBUG2__APB_BYTES_BP 16
114#define HW_APBX_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
107 115
108/********** 116/**********
109 * COMMON * 117 * COMMON *
@@ -117,6 +125,32 @@ struct apb_dma_command_t
117 /* PIO words follow */ 125 /* PIO words follow */
118}; 126};
119 127
128#define DMA_INFO_CURCMDADDR (1 << 0)
129#define DMA_INFO_NXTCMDADDR (1 << 1)
130#define DMA_INFO_CMD (1 << 2)
131#define DMA_INFO_BAR (1 << 3)
132#define DMA_INFO_APB_BYTES (1 << 4)
133#define DMA_INFO_AHB_BYTES (1 << 5)
134#define DMA_INFO_FREEZED (1 << 6)
135#define DMA_INFO_GATED (1 << 7)
136#define DMA_INFO_INTERRUPT (1 << 8)
137#define DMA_INFO_ALL 0x1ff
138
139struct imx233_dma_info_t
140{
141 unsigned long cur_cmd_addr;
142 unsigned long nxt_cmd_addr;
143 unsigned long cmd;
144 unsigned long bar;
145 unsigned apb_bytes;
146 unsigned ahb_bytes;
147 bool freezed;
148 bool gated;
149 bool int_enabled;
150 bool int_cmdcomplt;
151 bool int_error;
152};
153
120#define APBH_DMA_CHANNEL(i) i 154#define APBH_DMA_CHANNEL(i) i
121#define APBX_DMA_CHANNEL(i) ((i) | 0x10) 155#define APBX_DMA_CHANNEL(i) ((i) | 0x10)
122#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10) 156#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10)
@@ -124,6 +158,7 @@ struct apb_dma_command_t
124 158
125#define APB_SSP(ssp) APBH_DMA_CHANNEL(HW_APBH_SSP(ssp)) 159#define APB_SSP(ssp) APBH_DMA_CHANNEL(HW_APBH_SSP(ssp))
126#define APB_AUDIO_ADC APBX_DMA_CHANNEL(HW_APBX_AUDIO_ADC) 160#define APB_AUDIO_ADC APBX_DMA_CHANNEL(HW_APBX_AUDIO_ADC)
161#define APB_AUDIO_DAC APBX_DMA_CHANNEL(HW_APBX_AUDIO_DAC)
127#define APB_I2C APBX_DMA_CHANNEL(HW_APBX_I2C) 162#define APB_I2C APBX_DMA_CHANNEL(HW_APBX_I2C)
128 163
129#define HW_APB_CHx_CMD__COMMAND_BM 0x3 164#define HW_APB_CHx_CMD__COMMAND_BM 0x3
@@ -160,6 +195,7 @@ void imx233_dma_reset_channel(unsigned chan);
160/* only apbh channel have clkgate control */ 195/* only apbh channel have clkgate control */
161void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock); 196void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock);
162 197
198void imx233_dma_freeze_channel(unsigned chan, bool freeze);
163void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable); 199void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable);
164/* clear both channel complete and error bits */ 200/* clear both channel complete and error bits */
165void imx233_dma_clear_channel_interrupt(unsigned chan); 201void imx233_dma_clear_channel_interrupt(unsigned chan);
@@ -167,5 +203,8 @@ bool imx233_dma_is_channel_error_irq(unsigned chan);
167/* assume no command is in progress */ 203/* assume no command is in progress */
168void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd); 204void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd);
169void imx233_dma_wait_completion(unsigned chan); 205void imx233_dma_wait_completion(unsigned chan);
206/* get some info
207 * WARNING: if channel is not freezed, data might not be coherent ! */
208struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags);
170 209
171#endif // __DMA_IMX233_H__ 210#endif // __DMA_IMX233_H__