summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-06-16 18:19:59 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-06-16 18:21:49 +0200
commit8390eb931eb409f3e6c769d9179d0e9415c0e080 (patch)
treee8a20994db1a4b6958a82ceae545ff0d51bda291
parent852a82b90a5b718538642ebcffa25a168c98b329 (diff)
downloadrockbox-8390eb931eb409f3e6c769d9179d0e9415c0e080.tar.gz
rockbox-8390eb931eb409f3e6c769d9179d0e9415c0e080.zip
imx233: rewrite dma using new register headers
Change-Id: If73b84d9c9f4a152a54fb9d2dbec895e72d2e753
-rw-r--r--firmware/target/arm/imx233/dma-imx233.c159
-rw-r--r--firmware/target/arm/imx233/dma-imx233.h174
-rw-r--r--firmware/target/arm/imx233/i2c-imx233.c16
-rw-r--r--firmware/target/arm/imx233/pcm-imx233.c6
-rw-r--r--firmware/target/arm/imx233/ssp-imx233.c11
5 files changed, 140 insertions, 226 deletions
diff --git a/firmware/target/arm/imx233/dma-imx233.c b/firmware/target/arm/imx233/dma-imx233.c
index 3d156b2dfd..5808731eef 100644
--- a/firmware/target/arm/imx233/dma-imx233.c
+++ b/firmware/target/arm/imx233/dma-imx233.c
@@ -36,22 +36,17 @@ void imx233_dma_init(void)
36 36
37void imx233_dma_reset_channel(unsigned chan) 37void imx233_dma_reset_channel(unsigned chan)
38{ 38{
39 volatile uint32_t *ptr; 39 uint32_t bm = 1 << APB_GET_DMA_CHANNEL(chan);
40 uint32_t bm;
41 if(APB_IS_APBX_CHANNEL(chan)) 40 if(APB_IS_APBX_CHANNEL(chan))
42 { 41 {
43 ptr = &HW_APBX_CHANNEL_CTRL; 42 BF_SETV(APBX_CHANNEL_CTRL, RESET_CHANNEL, bm);
44 bm = HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan)); 43 while(BF_RD(APBX_CHANNEL_CTRL, RESET_CHANNEL) & bm);
45 } 44 }
46 else 45 else
47 { 46 {
48 ptr = &HW_APBH_CTRL0; 47 BF_SETV(APBH_CTRL0, RESET_CHANNEL, bm);
49 bm = HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan)); 48 while(BF_RD(APBH_CTRL0, RESET_CHANNEL) & bm);
50 } 49 }
51 __REG_SET(*ptr) = bm;
52 /* wait for end of reset */
53 while(*ptr & bm)
54 ;
55} 50}
56 51
57void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock) 52void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock)
@@ -59,84 +54,72 @@ void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock)
59 if(APB_IS_APBX_CHANNEL(chan)) 54 if(APB_IS_APBX_CHANNEL(chan))
60 return; 55 return;
61 if(enable_clock) 56 if(enable_clock)
62 __REG_CLR(HW_APBH_CTRL0) = 57 BF_CLRV(APBH_CTRL0, CLKGATE_CHANNEL, 1 << APB_GET_DMA_CHANNEL(chan));
63 HW_APBH_CTRL0__CLKGATE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
64 else 58 else
65 __REG_SET(HW_APBH_CTRL0) = 59 BF_SETV(APBH_CTRL0, CLKGATE_CHANNEL, 1 << APB_GET_DMA_CHANNEL(chan));
66 HW_APBH_CTRL0__CLKGATE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
67} 60}
68 61
69void imx233_dma_freeze_channel(unsigned chan, bool freeze) 62void imx233_dma_freeze_channel(unsigned chan, bool freeze)
70{ 63{
71 volatile uint32_t *ptr; 64 uint32_t bm = 1 << APB_GET_DMA_CHANNEL(chan);
72 uint32_t bm;
73 if(APB_IS_APBX_CHANNEL(chan)) 65 if(APB_IS_APBX_CHANNEL(chan))
74 { 66 {
75 ptr = &HW_APBX_CHANNEL_CTRL; 67 if(freeze)
76 bm = HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(APB_GET_DMA_CHANNEL(chan)); 68 BF_SETV(APBX_CHANNEL_CTRL, FREEZE_CHANNEL, bm);
69 else
70 BF_CLRV(APBX_CHANNEL_CTRL, FREEZE_CHANNEL, bm);
77 } 71 }
78 else 72 else
79 { 73 {
80 ptr = &HW_APBH_CTRL0; 74 if(freeze)
81 bm = HW_APBH_CTRL0__FREEZE_CHANNEL(APB_GET_DMA_CHANNEL(chan)); 75 BF_SETV(APBH_CTRL0, FREEZE_CHANNEL, bm);
76 else
77 BF_CLRV(APBH_CTRL0, FREEZE_CHANNEL, bm);
82 } 78 }
83
84 if(freeze)
85 __REG_SET(*ptr) = bm;
86 else
87 __REG_CLR(*ptr) = bm;
88} 79}
89 80
90void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable) 81void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable)
91{ 82{
92 volatile uint32_t *ptr; 83 uint32_t bm = 1 << APB_GET_DMA_CHANNEL(chan);
93 uint32_t bm;
94 if(APB_IS_APBX_CHANNEL(chan)) 84 if(APB_IS_APBX_CHANNEL(chan))
95 { 85 {
96 ptr = &HW_APBX_CTRL1; 86 if(enable)
97 bm = HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(APB_GET_DMA_CHANNEL(chan)); 87 BF_SETV(APBX_CTRL1, CH_CMDCMPLT_IRQ_EN, bm);
88 else
89 BF_CLRV(APBX_CTRL1, CH_CMDCMPLT_IRQ_EN, bm);
98 } 90 }
99 else 91 else
100 { 92 {
101 ptr = &HW_APBH_CTRL1; 93 if(enable)
102 bm = HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(APB_GET_DMA_CHANNEL(chan)); 94 BF_SETV(APBH_CTRL1, CH_CMDCMPLT_IRQ_EN, bm);
103 } 95 else
104 96 BF_CLRV(APBH_CTRL1, CH_CMDCMPLT_IRQ_EN, bm);
105 if(enable)
106 {
107 __REG_SET(*ptr) = bm;
108 imx233_dma_clear_channel_interrupt(chan);
109 } 97 }
110 else 98 imx233_dma_clear_channel_interrupt(chan);
111 __REG_CLR(*ptr) = bm;
112} 99}
113 100
114void imx233_dma_clear_channel_interrupt(unsigned chan) 101void imx233_dma_clear_channel_interrupt(unsigned chan)
115{ 102{
103 uint32_t bm = 1 << APB_GET_DMA_CHANNEL(chan);
116 if(APB_IS_APBX_CHANNEL(chan)) 104 if(APB_IS_APBX_CHANNEL(chan))
117 { 105 {
118 __REG_CLR(HW_APBX_CTRL1) = 106 BF_CLRV(APBX_CTRL1, CH_CMDCMPLT_IRQ, bm);
119 HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(APB_GET_DMA_CHANNEL(chan)); 107 BF_CLRV(APBX_CTRL2, CH_ERROR_IRQ, bm);
120 __REG_CLR(HW_APBX_CTRL2) =
121 HW_APBX_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan));
122 } 108 }
123 else 109 else
124 { 110 {
125 __REG_CLR(HW_APBH_CTRL1) = 111 BF_CLRV(APBH_CTRL1, CH_CMDCMPLT_IRQ, bm);
126 HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(APB_GET_DMA_CHANNEL(chan)); 112 BF_CLRV(APBH_CTRL2, CH_ERROR_IRQ, bm);
127 __REG_CLR(HW_APBH_CTRL2) =
128 HW_APBH_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan));
129 } 113 }
130} 114}
131 115
132bool imx233_dma_is_channel_error_irq(unsigned chan) 116bool imx233_dma_is_channel_error_irq(unsigned chan)
133{ 117{
118 uint32_t bm = 1 << APB_GET_DMA_CHANNEL(chan);
134 if(APB_IS_APBX_CHANNEL(chan)) 119 if(APB_IS_APBX_CHANNEL(chan))
135 return !!(HW_APBX_CTRL2 & 120 return !!(BF_RD(APBX_CTRL2, CH_ERROR_IRQ) & bm);
136 HW_APBX_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan)));
137 else 121 else
138 return !!(HW_APBH_CTRL2 & 122 return !!(BF_RD(APBH_CTRL2, CH_ERROR_IRQ) & bm);
139 HW_APBH_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan)));
140} 123}
141 124
142/* Commit and/or discard all DMA descriptors and buffers pointed by them, 125/* Commit and/or discard all DMA descriptors and buffers pointed by them,
@@ -150,37 +133,37 @@ static void imx233_dma_commit_and_discard(unsigned chan, struct apb_dma_command_
150 * and then we go through the list another time to clear the mark and 133 * and then we go through the list another time to clear the mark and
151 * commit the descriptors */ 134 * commit the descriptors */
152 struct apb_dma_command_t *cur = cmd; 135 struct apb_dma_command_t *cur = cmd;
153 136
154 while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != HW_APB_CHx_CMD__UNUSED_MAGIC) 137 while(BF_RDX(cur->cmd, APB_CHx_CMD, UNUSED) != BV_APB_CHx_CMD_UNUSED__MAGIC)
155 { 138 {
156 cur->cmd = (cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM) | HW_APB_CHx_CMD__UNUSED_MAGIC; 139 BF_WR_VX(cur->cmd, APB_CHx_CMD, UNUSED, MAGIC);
157 int op = cur->cmd & HW_APB_CHx_CMD__COMMAND_BM; 140 int op = BF_RDX(cur->cmd, APB_CHx_CMD, COMMAND);
158 int sz = __XTRACT_EX(cur->cmd, HW_APB_CHx_CMD__XFER_COUNT); 141 int sz = BF_RDX(cur->cmd, APB_CHx_CMD, XFER_COUNT);
159 /* device > host: discard */ 142 /* device > host: discard */
160 if(op == HW_APB_CHx_CMD__COMMAND__WRITE) 143 if(op == BV_APB_CHx_CMD_COMMAND__WRITE)
161 discard_dcache_range(cur->buffer, sz); 144 discard_dcache_range(cur->buffer, sz);
162 /* host > device: commit and discard */ 145 /* host > device: commit and discard */
163 else if(op == HW_APB_CHx_CMD__COMMAND__READ) 146 else if(op == BV_APB_CHx_CMD_COMMAND__READ)
164 commit_discard_dcache_range(cur->buffer, sz); 147 commit_discard_dcache_range(cur->buffer, sz);
165 if((uint32_t)cur->buffer % CACHEALIGN_SIZE) 148 if((uint32_t)cur->buffer % CACHEALIGN_SIZE)
166 apb_nr_unaligned[chan]++; 149 apb_nr_unaligned[chan]++;
167 /* Virtual to physical buffer pointer conversion */ 150 /* Virtual to physical buffer pointer conversion */
168 cur->buffer = PHYSICAL_ADDR(cur->buffer); 151 cur->buffer = PHYSICAL_ADDR(cur->buffer);
169 /* chain ? */ 152 /* chain ? */
170 if(cur->cmd & HW_APB_CHx_CMD__CHAIN) 153 if(cur->cmd & BM_APB_CHx_CMD_CHAIN)
171 cur = cur->next; 154 cur = cur->next;
172 else 155 else
173 break; 156 break;
174 } 157 }
175 158
176 cur = cmd; 159 cur = cmd;
177 while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != 0) 160 while(BF_RDX(cur->cmd, APB_CHx, CMD_UNUSED) != 0)
178 { 161 {
179 cur->cmd = cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM; 162 BF_WRX(cur->cmd, APB_CHx, CMD_UNUSED, 0);
180 int sz = __XTRACT_EX(cur->cmd, HW_APB_CHx_CMD__CMDWORDS) * sizeof(uint32_t); 163 int sz = BF_RDX(cur->cmd, APB_CHx_CMD, CMDWORDS) * sizeof(uint32_t);
181 /* commit descriptor and discard descriptor */ 164 /* commit descriptor and discard descriptor */
182 /* chain ? */ 165 /* chain ? */
183 if(cur->cmd & HW_APB_CHx_CMD__CHAIN) 166 if(cur->cmd & BM_APB_CHx_CMD_CHAIN)
184 { 167 {
185 struct apb_dma_command_t *next = cur->next; 168 struct apb_dma_command_t *next = cur->next;
186 cur->next = PHYSICAL_ADDR(cur->next); 169 cur->next = PHYSICAL_ADDR(cur->next);
@@ -200,28 +183,28 @@ void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
200 imx233_dma_commit_and_discard(chan, cmd); 183 imx233_dma_commit_and_discard(chan, cmd);
201 if(APB_IS_APBX_CHANNEL(chan)) 184 if(APB_IS_APBX_CHANNEL(chan))
202 { 185 {
203 HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd); 186 HW_APBX_CHn_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd);
204 HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1; 187 HW_APBX_CHn_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
205 } 188 }
206 else 189 else
207 { 190 {
208 HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd); 191 HW_APBH_CHn_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd);
209 HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1; 192 HW_APBH_CHn_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
210 } 193 }
211} 194}
212 195
213int imx233_dma_wait_completion(unsigned chan, unsigned tmo) 196int imx233_dma_wait_completion(unsigned chan, unsigned tmo)
214{ 197{
215 tmo += current_tick; 198 tmo += current_tick;
216 volatile uint32_t *sema; 199 int value = 0;
217 if(APB_IS_APBX_CHANNEL(chan)) 200 if(APB_IS_APBX_CHANNEL(chan))
218 sema = &HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)); 201 while((value = BF_RDn(APBX_CHn_SEMA, APB_GET_DMA_CHANNEL(chan), PHORE)) && !TIME_AFTER(current_tick, tmo))
202 yield();
219 else 203 else
220 sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)); 204 while((value = BF_RDn(APBH_CHn_SEMA, APB_GET_DMA_CHANNEL(chan), PHORE)) && !TIME_AFTER(current_tick, tmo))
205 yield();
221 206
222 while(*sema & HW_APB_CHx_SEMA__PHORE_BM && !TIME_AFTER(current_tick, tmo)) 207 return value;
223 yield();
224 return __XTRACT_EX(*sema, HW_APB_CHx_SEMA__PHORE);
225} 208}
226 209
227struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags) 210struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags)
@@ -230,35 +213,29 @@ struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags)
230 memset(&s, 0, sizeof(s)); 213 memset(&s, 0, sizeof(s));
231 bool apbx = APB_IS_APBX_CHANNEL(chan); 214 bool apbx = APB_IS_APBX_CHANNEL(chan);
232 int dmac = APB_GET_DMA_CHANNEL(chan); 215 int dmac = APB_GET_DMA_CHANNEL(chan);
216 uint32_t bm = 1 << dmac;
233 if(flags & DMA_INFO_CURCMDADDR) 217 if(flags & DMA_INFO_CURCMDADDR)
234 s.cur_cmd_addr = apbx ? HW_APBX_CHx_CURCMDAR(dmac) : HW_APBH_CHx_CURCMDAR(dmac); 218 s.cur_cmd_addr = apbx ? HW_APBX_CHn_CURCMDAR(dmac) : HW_APBH_CHn_CURCMDAR(dmac);
235 if(flags & DMA_INFO_NXTCMDADDR) 219 if(flags & DMA_INFO_NXTCMDADDR)
236 s.nxt_cmd_addr = apbx ? HW_APBX_CHx_NXTCMDAR(dmac) : HW_APBH_CHx_NXTCMDAR(dmac); 220 s.nxt_cmd_addr = apbx ? HW_APBX_CHn_NXTCMDAR(dmac) : HW_APBH_CHn_NXTCMDAR(dmac);
237 if(flags & DMA_INFO_CMD) 221 if(flags & DMA_INFO_CMD)
238 s.cmd = apbx ? HW_APBX_CHx_CMD(dmac) : HW_APBH_CHx_CMD(dmac); 222 s.cmd = apbx ? HW_APBX_CHn_CMD(dmac) : HW_APBH_CHn_CMD(dmac);
239 if(flags & DMA_INFO_BAR) 223 if(flags & DMA_INFO_BAR)
240 s.bar = apbx ? HW_APBX_CHx_BAR(dmac) : HW_APBH_CHx_BAR(dmac); 224 s.bar = apbx ? HW_APBX_CHn_BAR(dmac) : HW_APBH_CHn_BAR(dmac);
241 if(flags & DMA_INFO_AHB_BYTES) 225 if(flags & DMA_INFO_AHB_BYTES)
242 s.ahb_bytes = apbx ? __XTRACT_EX(HW_APBX_CHx_DEBUG2(dmac), HW_APBX_CHx_DEBUG2__AHB_BYTES) : 226 s.ahb_bytes = apbx ? BF_RDn(APBX_CHn_DEBUG2, dmac, AHB_BYTES) : BF_RDn(APBH_CHn_DEBUG2, dmac, AHB_BYTES);
243 __XTRACT_EX(HW_APBH_CHx_DEBUG2(dmac), HW_APBH_CHx_DEBUG2__AHB_BYTES);
244 if(flags & DMA_INFO_APB_BYTES) 227 if(flags & DMA_INFO_APB_BYTES)
245 s.apb_bytes = apbx ? __XTRACT_EX(HW_APBX_CHx_DEBUG2(dmac), HW_APBX_CHx_DEBUG2__APB_BYTES) : 228 s.apb_bytes = apbx ? BF_RDn(APBX_CHn_DEBUG2, dmac, APB_BYTES) : BF_RDn(APBH_CHn_DEBUG2, dmac, APB_BYTES);
246 __XTRACT_EX(HW_APBH_CHx_DEBUG2(dmac), HW_APBH_CHx_DEBUG2__APB_BYTES);
247 if(flags & DMA_INFO_FREEZED) 229 if(flags & DMA_INFO_FREEZED)
248 s.freezed = apbx ? HW_APBX_CHANNEL_CTRL & HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(dmac) : 230 s.freezed = !!((apbx ? BF_RD(APBX_CHANNEL_CTRL, FREEZE_CHANNEL) : BF_RD(APBH_CTRL0, FREEZE_CHANNEL)) & bm);
249 HW_APBH_CTRL0 & HW_APBH_CTRL0__FREEZE_CHANNEL(dmac);
250 if(flags & DMA_INFO_GATED) 231 if(flags & DMA_INFO_GATED)
251 s.gated = apbx ? false : HW_APBH_CTRL0 & HW_APBH_CTRL0__CLKGATE_CHANNEL(dmac); 232 s.gated = apbx ? false : !!(BF_RD(APBH_CTRL0, CLKGATE_CHANNEL) & bm);
252 if(flags & DMA_INFO_INTERRUPT) 233 if(flags & DMA_INFO_INTERRUPT)
253 { 234 {
254 s.int_enabled = apbx ? HW_APBX_CTRL1 & HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(dmac) : 235 s.int_enabled = !!((apbx ? BF_RD(APBX_CTRL1, CH_CMDCMPLT_IRQ_EN) : BF_RD(APBH_CTRL1, CH_CMDCMPLT_IRQ_EN)) & bm);
255 HW_APBH_CTRL1 & HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(dmac); 236 s.int_cmdcomplt = !!((apbx ? BF_RD(APBX_CTRL1, CH_CMDCMPLT_IRQ) : BF_RD(APBH_CTRL1, CH_CMDCMPLT_IRQ)) & bm);
256 s.int_cmdcomplt = apbx ? HW_APBX_CTRL1 & HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(dmac) : 237 s.int_error = !!((apbx ? BF_RD(APBX_CTRL2, CH_ERROR_IRQ) : BF_RD(APBH_CTRL2, CH_ERROR_IRQ)) & bm);
257 HW_APBH_CTRL1 & HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(dmac);
258 s.int_error = apbx ? HW_APBX_CTRL2 & HW_APBX_CTRL2__CHx_ERROR_IRQ(dmac) :
259 HW_APBH_CTRL2 & HW_APBH_CTRL2__CHx_ERROR_IRQ(dmac);
260 } 238 }
261 s.nr_unaligned = apb_nr_unaligned[chan]; 239 s.nr_unaligned = apb_nr_unaligned[chan];
262 return s; 240 return s;
263} 241}
264
diff --git a/firmware/target/arm/imx233/dma-imx233.h b/firmware/target/arm/imx233/dma-imx233.h
index a6a957ce3b..692b8dc16d 100644
--- a/firmware/target/arm/imx233/dma-imx233.h
+++ b/firmware/target/arm/imx233/dma-imx233.h
@@ -25,91 +25,29 @@
25#include "system.h" 25#include "system.h"
26#include "system-target.h" 26#include "system-target.h"
27 27
28/******** 28#include "regs/regs-apbh.h"
29 * APHB * 29#include "regs/regs-apbx.h"
30 ********/
31 30
32#define HW_APBH_BASE 0x80004000 31/************
32 * CHANNELS *
33 ************/
33 34
34/* APHB channels */ 35#define APBH_DMA_CHANNEL(i) i
35#define HW_APBH_SSP(ssp) ssp 36#define APBX_DMA_CHANNEL(i) ((i) | 0x10)
36#define HW_APBH_NAND(dev) (4 + (ssp)) 37#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10)
37 38#define APB_GET_DMA_CHANNEL(x) ((x) & 0xf)
38#define HW_APBH_CTRL0 (*(volatile uint32_t *)(HW_APBH_BASE + 0x0))
39#define HW_APBH_CTRL0__FREEZE_CHANNEL(i) (1 << (i))
40#define HW_APBH_CTRL0__CLKGATE_CHANNEL(i) (1 << ((i) + 8))
41#define HW_APBH_CTRL0__RESET_CHANNEL(i) (1 << ((i) + 16))
42#define HW_APBH_CTRL0__APB_BURST4_EN (1 << 28)
43#define HW_APBH_CTRL0__APB_BURST8_EN (1 << 29)
44
45#define HW_APBH_CTRL1 (*(volatile uint32_t *)(HW_APBH_BASE + 0x10))
46#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
47#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
48
49#define HW_APBH_CTRL2 (*(volatile uint32_t *)(HW_APBH_BASE + 0x20))
50#define HW_APBH_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
51#define HW_APBH_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
52
53#define HW_APBH_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x40 + 0x70 * (i)))
54
55#define HW_APBH_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x50 + 0x70 * (i)))
56
57#define HW_APBH_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x60 + 0x70 * (i)))
58
59#define HW_APBH_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x70 + 0x70 * (i)))
60
61#define HW_APBH_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x80 + 0x70 * (i)))
62
63#define HW_APBH_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x90 + 0x70 * (i)))
64
65#define HW_APBH_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0xa0 + 0x70 * (i)))
66#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BP 0
67#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BM 0xffff
68#define HW_APBH_CHx_DEBUG2__APB_BYTES_BP 16
69#define HW_APBH_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
70
71/********
72 * APHX *
73 ********/
74
75/* APHX channels */
76#define HW_APBX_AUDIO_ADC 0
77#define HW_APBX_AUDIO_DAC 1
78#define HW_APBX_I2C 3
79
80#define HW_APBX_BASE 0x80024000
81
82#define HW_APBX_CTRL0 (*(volatile uint32_t *)(HW_APBX_BASE + 0x0))
83
84#define HW_APBX_CTRL1 (*(volatile uint32_t *)(HW_APBX_BASE + 0x10))
85#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
86#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
87
88#define HW_APBX_CTRL2 (*(volatile uint32_t *)(HW_APBX_BASE + 0x20))
89#define HW_APBX_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
90#define HW_APBX_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
91
92#define HW_APBX_CHANNEL_CTRL (*(volatile uint32_t *)(HW_APBX_BASE + 0x30))
93#define HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(i) (1 << (i))
94#define HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(i) (1 << ((i) + 16))
95
96#define HW_APBX_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x100 + (i) * 0x70))
97
98#define HW_APBX_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x110 + (i) * 0x70))
99
100#define HW_APBX_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x120 + (i) * 0x70))
101
102#define HW_APBX_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x130 + (i) * 0x70))
103 39
104#define HW_APBX_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x140 + (i) * 0x70)) 40// NOTE: although undocumented, the iMX233 channel 0 is actually the LCDIF one
41#define APB_LCDIF APBH_DMA_CHANNEL(0)
105 42
106#define HW_APBX_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x150 + (i) * 0x70)) 43#define APB_SSP(ssp) APBH_DMA_CHANNEL(ssp)
44#define APB_GPMI(dev) APBH_DMA_CHANNEL(4 + (dev))
107 45
108#define HW_APBX_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x160 + (i) * 0x70)) 46#define APB_AUDIO_ADC APBX_DMA_CHANNEL(0)
109#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BP 0 47#define APB_AUDIO_DAC APBX_DMA_CHANNEL(1)
110#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BM 0xffff 48#define APB_I2C APBX_DMA_CHANNEL(3)
111#define HW_APBX_CHx_DEBUG2__APB_BYTES_BP 16 49// NOTE: although undocumented, the IMX233 channel 5 is actually the DRI one
112#define HW_APBX_CHx_DEBUG2__APB_BYTES_BM 0xffff0000 50#define APB_DRI APBX_DMA_CHANNEL(5)
113 51
114/********** 52/**********
115 * COMMON * 53 * COMMON *
@@ -154,43 +92,49 @@ struct imx233_dma_info_t
154 int nr_unaligned; 92 int nr_unaligned;
155}; 93};
156 94
157#define APBH_DMA_CHANNEL(i) i 95#define BM_APB_CHx_CMD_COMMAND 0x3
158#define APBX_DMA_CHANNEL(i) ((i) | 0x10) 96#define BP_APB_CHx_CMD_COMMAND 0
159#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10) 97#define BF_APB_CHx_CMD_COMMAND(v) ((v) & 0x3)
160#define APB_GET_DMA_CHANNEL(x) ((x) & 0xf) 98#define BF_APB_CHx_CMD_COMMAND_V(v) BF_APB_CHx_CMD_COMMAND(BV_APB_CHx_CMD_COMMAND__##v)
161 99#define BV_APB_CHx_CMD_COMMAND__NO_XFER 0
162#define APB_SSP(ssp) APBH_DMA_CHANNEL(HW_APBH_SSP(ssp)) 100#define BV_APB_CHx_CMD_COMMAND__WRITE 1
163#define APB_AUDIO_ADC APBX_DMA_CHANNEL(HW_APBX_AUDIO_ADC) 101#define BV_APB_CHx_CMD_COMMAND__READ 2
164#define APB_AUDIO_DAC APBX_DMA_CHANNEL(HW_APBX_AUDIO_DAC) 102#define BV_APB_CHx_CMD_COMMAND__SENSE 3
165#define APB_I2C APBX_DMA_CHANNEL(HW_APBX_I2C) 103#define BM_APB_CHx_CMD_CHAIN (1 << 2)
166#define APB_NAND(dev) APBH_DMA_CHANNEL(HW_APBH_NAND(dev)) 104#define BP_APB_CHx_CMD_CHAIN 2
167 105#define BF_APB_CHx_CMD_CHAIN(v) (((v) & 1) << 2)
168#define HW_APB_CHx_CMD__COMMAND_BM 0x3 106#define BM_APB_CHx_CMD_IRQONCMPLT (1 << 3)
169#define HW_APB_CHx_CMD__COMMAND_BP 0 107#define BP_APB_CHx_CMD_IRQONCMPLT 3
170#define HW_APB_CHx_CMD__COMMAND__NO_XFER 0 108#define BF_APB_CHx_CMD_IRQONCMPLT(v) (((v) & 1) << 3)
171#define HW_APB_CHx_CMD__COMMAND__WRITE 1
172#define HW_APB_CHx_CMD__COMMAND__READ 2
173#define HW_APB_CHx_CMD__COMMAND__SENSE 3
174#define HW_APB_CHx_CMD__CHAIN (1 << 2)
175#define HW_APB_CHx_CMD__IRQONCMPLT (1 << 3)
176/* those two are only available on APHB */ 109/* those two are only available on APHB */
177#define HW_APBH_CHx_CMD__NANDLOCK (1 << 4) 110#define BM_APBH_CHx_CMD_NANDLOCK (1 << 4)
178#define HW_APBH_CHx_CMD__NANDWAIT4READY (1 << 5) 111#define BP_APBH_CHx_CMD_NANDLOCK 4
179#define HW_APB_CHx_CMD__SEMAPHORE (1 << 6) 112#define BF_APBH_CHx_CMD_NANDLOCK(v) (((v) & 1) << 4)
180#define HW_APB_CHx_CMD__WAIT4ENDCMD (1 << 7) 113#define BM_APBH_CHx_CMD_NANDWAIT4READY (1 << 5)
181/* An errata advise not to use it */ 114#define BP_APBH_CHx_CMD_NANDWAIT4READY 5
182#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8) 115#define BF_APBH_CHx_CMD_NANDWAIT4READY(v) (((v) & 1) << 5)
183#define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000 116
184#define HW_APB_CHx_CMD__CMDWORDS_BP 12 117#define BM_APB_CHx_CMD_SEMAPHORE (1 << 6)
185#define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000 118#define BP_APB_CHx_CMD_SEMAPHORE 6
186#define HW_APB_CHx_CMD__XFER_COUNT_BP 16 119#define BF_APB_CHx_CMD_SEMAPHORE(v) (((v) & 1) << 6)
120#define BM_APB_CHx_CMD_WAIT4ENDCMD (1 << 7)
121#define BP_APB_CHx_CMD_WAIT4ENDCMD 7
122#define BF_APB_CHx_CMD_WAIT4ENDCMD(v) (((v) & 1) << 7)
123/** WARNING: An errata advise not to use it */
124#define BM_APB_CHx_CMD_HALTONTERMINATE (1 << 8)
125#define BP_APB_CHx_CMD_HALTONTERMINATE 8
126#define BF_APB_CHx_CMD_HALTONTERMINATE(v) (((v) & 1) << 8)
127#define BM_APB_CHx_CMD_CMDWORDS 0xf000
128#define BP_APB_CHx_CMD_CMDWORDS 12
129#define BF_APB_CHx_CMD_CMDWORDS(v) (((v) & 0xf) << 12)
130#define BM_APB_CHx_CMD_XFER_COUNT 0xffff0000
131#define BP_APB_CHx_CMD_XFER_COUNT 16
132#define BF_APB_CHx_CMD_XFER_COUNT(v) (((v) & 0xffff) << 16)
187/* For software use */ 133/* For software use */
188#define HW_APB_CHx_CMD__UNUSED_BP 8 134#define BP_APB_CHx_CMD_UNUSED 8
189#define HW_APB_CHx_CMD__UNUSED_BM (0xf << 8) 135#define BM_APB_CHx_CMD_UNUSED (0xf << 8)
190#define HW_APB_CHx_CMD__UNUSED_MAGIC (0xa << 8) 136#define BF_APB_CHx_CMD_UNUSED(v) (((v) & 0xf) << 8)
191 137#define BV_APB_CHx_CMD_UNUSED__MAGIC 0xa
192#define HW_APB_CHx_SEMA__PHORE_BM 0xff0000
193#define HW_APB_CHx_SEMA__PHORE_BP 16
194 138
195/* A single descriptor cannot transfer more than 2^16 bytes but because of the 139/* A single descriptor cannot transfer more than 2^16 bytes but because of the
196 * weird 0=64KiB, it's safer to restrict to 2^15 */ 140 * weird 0=64KiB, it's safer to restrict to 2^15 */
diff --git a/firmware/target/arm/imx233/i2c-imx233.c b/firmware/target/arm/imx233/i2c-imx233.c
index f72be503fa..054ce09a28 100644
--- a/firmware/target/arm/imx233/i2c-imx233.c
+++ b/firmware/target/arm/imx233/i2c-imx233.c
@@ -145,17 +145,15 @@ enum imx233_i2c_error_t imx233_i2c_add(bool start, bool transmit, void *buffer,
145 if(i2c_nr_stages > 0) 145 if(i2c_nr_stages > 0)
146 { 146 {
147 i2c_stage[i2c_nr_stages - 1].dma.next = &i2c_stage[i2c_nr_stages].dma; 147 i2c_stage[i2c_nr_stages - 1].dma.next = &i2c_stage[i2c_nr_stages].dma;
148 i2c_stage[i2c_nr_stages - 1].dma.cmd |= HW_APB_CHx_CMD__CHAIN; 148 i2c_stage[i2c_nr_stages - 1].dma.cmd |= BM_APB_CHx_CMD_CHAIN;
149 if(!start) 149 if(!start)
150 i2c_stage[i2c_nr_stages - 1].ctrl0 |= BM_I2C_CTRL0_RETAIN_CLOCK; 150 i2c_stage[i2c_nr_stages - 1].ctrl0 |= BM_I2C_CTRL0_RETAIN_CLOCK;
151 } 151 }
152 i2c_stage[i2c_nr_stages].dma.buffer = i2c_buffer + start_off; 152 i2c_stage[i2c_nr_stages].dma.buffer = i2c_buffer + start_off;
153 i2c_stage[i2c_nr_stages].dma.next = NULL; 153 i2c_stage[i2c_nr_stages].dma.next = NULL;
154 i2c_stage[i2c_nr_stages].dma.cmd = 154 i2c_stage[i2c_nr_stages].dma.cmd = BF_OR4(APB_CHx_CMD,
155 (transmit ? HW_APB_CHx_CMD__COMMAND__READ : HW_APB_CHx_CMD__COMMAND__WRITE) | 155 COMMAND(transmit ? BV_APB_CHx_CMD_COMMAND__READ : BV_APB_CHx_CMD_COMMAND__WRITE),
156 HW_APB_CHx_CMD__WAIT4ENDCMD | 156 WAIT4ENDCMD(1), CMDWORDS(1), XFER_COUNT(size));
157 1 << HW_APB_CHx_CMD__CMDWORDS_BP |
158 size << HW_APB_CHx_CMD__XFER_COUNT_BP;
159 /* assume that any read is final (send nak on last) */ 157 /* assume that any read is final (send nak on last) */
160 i2c_stage[i2c_nr_stages].ctrl0 = BF_OR6(I2C_CTRL0, 158 i2c_stage[i2c_nr_stages].ctrl0 = BF_OR6(I2C_CTRL0,
161 XFER_COUNT(size), DIRECTION(transmit), SEND_NAK_ON_LAST(!transmit), 159 XFER_COUNT(size), DIRECTION(transmit), SEND_NAK_ON_LAST(!transmit),
@@ -170,8 +168,8 @@ static enum imx233_i2c_error_t imx233_i2c_finalize(void)
170 for(int i = 0; i < i2c_nr_stages; i++) 168 for(int i = 0; i < i2c_nr_stages; i++)
171 { 169 {
172 struct i2c_dma_command_t *c = &i2c_stage[i]; 170 struct i2c_dma_command_t *c = &i2c_stage[i];
173 if(__XTRACT_EX(c->dma.cmd, HW_APB_CHx_CMD__COMMAND) == HW_APB_CHx_CMD__COMMAND__WRITE) 171 if(BF_RDX(c->dma.cmd, APB_CHx_CMD, COMMAND) == BV_APB_CHx_CMD_COMMAND__WRITE)
174 memcpy(c->dst, c->src, __XTRACT_EX(c->dma.cmd, HW_APB_CHx_CMD__XFER_COUNT)); 172 memcpy(c->dst, c->src, BF_RDX(c->dma.cmd, APB_CHx_CMD, XFER_COUNT));
175 } 173 }
176 return I2C_SUCCESS; 174 return I2C_SUCCESS;
177} 175}
@@ -180,7 +178,7 @@ enum imx233_i2c_error_t imx233_i2c_end(unsigned timeout)
180{ 178{
181 if(i2c_nr_stages == 0) 179 if(i2c_nr_stages == 0)
182 return I2C_ERROR; 180 return I2C_ERROR;
183 i2c_stage[i2c_nr_stages - 1].dma.cmd |= HW_APB_CHx_CMD__SEMAPHORE | HW_APB_CHx_CMD__IRQONCMPLT; 181 i2c_stage[i2c_nr_stages - 1].dma.cmd |= BM_APB_CHx_CMD_SEMAPHORE | BM_APB_CHx_CMD_IRQONCMPLT;
184 182
185 BF_CLR(I2C_CTRL1, ALL_IRQ); 183 BF_CLR(I2C_CTRL1, ALL_IRQ);
186 imx233_dma_reset_channel(APB_I2C); 184 imx233_dma_reset_channel(APB_I2C);
diff --git a/firmware/target/arm/imx233/pcm-imx233.c b/firmware/target/arm/imx233/pcm-imx233.c
index 6969e61b40..2c5033471f 100644
--- a/firmware/target/arm/imx233/pcm-imx233.c
+++ b/firmware/target/arm/imx233/pcm-imx233.c
@@ -48,10 +48,8 @@ static void play(const void *addr, size_t size)
48{ 48{
49 dac_dma.dma.next = NULL; 49 dac_dma.dma.next = NULL;
50 dac_dma.dma.buffer = (void *)addr; 50 dac_dma.dma.buffer = (void *)addr;
51 dac_dma.dma.cmd = HW_APB_CHx_CMD__COMMAND__READ | 51 dac_dma.dma.cmd = BF_OR4(APB_CHx_CMD, COMMAND_V(READ),
52 HW_APB_CHx_CMD__IRQONCMPLT | 52 IRQONCMPLT(1), SEMAPHORE(1), XFER_COUNT(size));
53 HW_APB_CHx_CMD__SEMAPHORE |
54 size << HW_APB_CHx_CMD__XFER_COUNT_BP;
55 /* dma subsystem will make sure cached stuff is written to memory */ 53 /* dma subsystem will make sure cached stuff is written to memory */
56 imx233_dma_start_command(APB_AUDIO_DAC, &dac_dma.dma); 54 imx233_dma_start_command(APB_AUDIO_DAC, &dac_dma.dma);
57} 55}
diff --git a/firmware/target/arm/imx233/ssp-imx233.c b/firmware/target/arm/imx233/ssp-imx233.c
index 400a8d1f91..a6c3028d98 100644
--- a/firmware/target/arm/imx233/ssp-imx233.c
+++ b/firmware/target/arm/imx233/ssp-imx233.c
@@ -285,13 +285,10 @@ enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd,
285 /* setup the dma parameters */ 285 /* setup the dma parameters */
286 ssp_dma_cmd[ssp - 1].dma.buffer = buffer; 286 ssp_dma_cmd[ssp - 1].dma.buffer = buffer;
287 ssp_dma_cmd[ssp - 1].dma.next = NULL; 287 ssp_dma_cmd[ssp - 1].dma.next = NULL;
288 ssp_dma_cmd[ssp - 1].dma.cmd = 288 ssp_dma_cmd[ssp - 1].dma.cmd = BF_OR6(APB_CHx_CMD,
289 (buffer == NULL ? HW_APB_CHx_CMD__COMMAND__NO_XFER : 289 COMMAND(buffer == NULL ? BV_APB_CHx_CMD_COMMAND__NO_XFER :
290 read ? HW_APB_CHx_CMD__COMMAND__WRITE : HW_APB_CHx_CMD__COMMAND__READ) | 290 read ? BV_APB_CHx_CMD_COMMAND__WRITE : BV_APB_CHx_CMD_COMMAND__READ),
291 HW_APB_CHx_CMD__IRQONCMPLT | HW_APB_CHx_CMD__SEMAPHORE | 291 IRQONCMPLT(1), SEMAPHORE(1), WAIT4ENDCMD(1), CMDWORDS(3), XFER_COUNT(xfer_size));
292 HW_APB_CHx_CMD__WAIT4ENDCMD |
293 (3 << HW_APB_CHx_CMD__CMDWORDS_BP) |
294 (xfer_size << HW_APB_CHx_CMD__XFER_COUNT_BP);
295 292
296 SSP_CLRn(SSP_CTRL1, ssp, ALL_IRQ); 293 SSP_CLRn(SSP_CTRL1, ssp, ALL_IRQ);
297 294