diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2013-06-17 00:20:12 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2013-06-17 00:29:25 +0200 |
commit | b74a459189d06ea453199b79e4602c9490404682 (patch) | |
tree | c35d52732a2fbd1e2dc797b97a3d62f2452b4555 /firmware | |
parent | 86ff093267171ca91cb4d10f6ff1b27bb1349dac (diff) | |
download | rockbox-b74a459189d06ea453199b79e4602c9490404682.tar.gz rockbox-b74a459189d06ea453199b79e4602c9490404682.zip |
imx233: fix ssp for stmp3600 and stmp3700
Using the ssp macros, we can easily handle the stmp3600 which
has a single ssp block. Take care of all the nasty differences
between targets like bus width
Change-Id: If98a091cc262e9e6834f6fb9826f7c5515bfe621
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/imx233/ssp-imx233.c | 45 | ||||
-rw-r--r-- | firmware/target/arm/imx233/ssp-imx233.h | 18 |
2 files changed, 63 insertions, 0 deletions
diff --git a/firmware/target/arm/imx233/ssp-imx233.c b/firmware/target/arm/imx233/ssp-imx233.c index 90cd20fd19..e73c09bfca 100644 --- a/firmware/target/arm/imx233/ssp-imx233.c +++ b/firmware/target/arm/imx233/ssp-imx233.c | |||
@@ -33,12 +33,21 @@ | |||
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | /* Hack to handle both single and multi devices at once */ | 35 | /* Hack to handle both single and multi devices at once */ |
36 | #if IMX233_SUBTARGET < 3700 | ||
37 | #define SSP_SETn(reg, n, field) BF_SET(reg, field) | ||
38 | #define SSP_CLRn(reg, n, field) BF_CLR(reg, field) | ||
39 | #define SSP_RDn(reg, n, field) BF_RD(reg, field) | ||
40 | #define SSP_WRn(reg, n, field, val) BF_WR(reg, field, val) | ||
41 | #define SSP_WRn_V(reg, n, field, val) BF_WR_V(reg, field, val) | ||
42 | #define SSP_REGn(reg, n) HW_##reg | ||
43 | #else | ||
36 | #define SSP_SETn(reg, n, field) BF_SETn(reg, n, field) | 44 | #define SSP_SETn(reg, n, field) BF_SETn(reg, n, field) |
37 | #define SSP_CLRn(reg, n, field) BF_CLRn(reg, n, field) | 45 | #define SSP_CLRn(reg, n, field) BF_CLRn(reg, n, field) |
38 | #define SSP_RDn(reg, n, field) BF_RDn(reg, n, field) | 46 | #define SSP_RDn(reg, n, field) BF_RDn(reg, n, field) |
39 | #define SSP_WRn(reg, n, field, val) BF_WRn(reg, n, field, val) | 47 | #define SSP_WRn(reg, n, field, val) BF_WRn(reg, n, field, val) |
40 | #define SSP_WRn_V(reg, n, field, val) BF_WRn_V(reg, n, field, val) | 48 | #define SSP_WRn_V(reg, n, field, val) BF_WRn_V(reg, n, field, val) |
41 | #define SSP_REGn(reg, n) HW_##reg(n) | 49 | #define SSP_REGn(reg, n) HW_##reg(n) |
50 | #endif | ||
42 | 51 | ||
43 | /* Used for DMA */ | 52 | /* Used for DMA */ |
44 | struct ssp_dma_command_t | 53 | struct ssp_dma_command_t |
@@ -126,7 +135,9 @@ void imx233_ssp_start(int ssp) | |||
126 | * intdiv = 5 => clk_ssp = 96Mhz */ | 135 | * intdiv = 5 => clk_ssp = 96Mhz */ |
127 | imx233_clkctrl_enable(CLK_SSP, false); | 136 | imx233_clkctrl_enable(CLK_SSP, false); |
128 | imx233_clkctrl_set_div(CLK_SSP, 5); | 137 | imx233_clkctrl_set_div(CLK_SSP, 5); |
138 | #if IMX233_SUBTARGET >= 3700 | ||
129 | imx233_clkctrl_set_bypass(CLK_SSP, false); /* use IO */ | 139 | imx233_clkctrl_set_bypass(CLK_SSP, false); /* use IO */ |
140 | #endif | ||
130 | imx233_clkctrl_enable(CLK_SSP, true); | 141 | imx233_clkctrl_enable(CLK_SSP, true); |
131 | } | 142 | } |
132 | ssp_nr_in_use++; | 143 | ssp_nr_in_use++; |
@@ -178,12 +189,17 @@ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, | |||
178 | } | 189 | } |
179 | if(bus_width >= 8) | 190 | if(bus_width >= 8) |
180 | { | 191 | { |
192 | #ifdef VPIN_SSP1_D4 | ||
181 | if(use_alt) | 193 | if(use_alt) |
182 | { | 194 | { |
195 | #ifdef VPIN_SSP1_D4_ALT | ||
183 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D4_ALT, "ssp1_d4", drive_strength, enable_pullups); | 196 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D4_ALT, "ssp1_d4", drive_strength, enable_pullups); |
184 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D5_ALT, "ssp1_d5", drive_strength, enable_pullups); | 197 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D5_ALT, "ssp1_d5", drive_strength, enable_pullups); |
185 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D6_ALT, "ssp1_d6", drive_strength, enable_pullups); | 198 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D6_ALT, "ssp1_d6", drive_strength, enable_pullups); |
186 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D7_ALT, "ssp1_d7", drive_strength, enable_pullups); | 199 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D7_ALT, "ssp1_d7", drive_strength, enable_pullups); |
200 | #else | ||
201 | panicf("there is ssp1 alt on this soc!"); | ||
202 | #endif | ||
187 | } | 203 | } |
188 | else | 204 | else |
189 | { | 205 | { |
@@ -192,6 +208,9 @@ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, | |||
192 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D6, "ssp1_d6", drive_strength, enable_pullups); | 208 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D6, "ssp1_d6", drive_strength, enable_pullups); |
193 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D7, "ssp1_d7", drive_strength, enable_pullups); | 209 | imx233_pinctrl_setup_vpin(VPIN_SSP1_D7, "ssp1_d7", drive_strength, enable_pullups); |
194 | } | 210 | } |
211 | #else | ||
212 | panicf("ssp1 bus width is limited to 4 on this soc!"); | ||
213 | #endif | ||
195 | } | 214 | } |
196 | } | 215 | } |
197 | 216 | ||
@@ -201,6 +220,7 @@ void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, | |||
201 | (void) enable_pullups; | 220 | (void) enable_pullups; |
202 | (void) bus_width; | 221 | (void) bus_width; |
203 | (void) drive_strength; | 222 | (void) drive_strength; |
223 | #ifdef VPIN_SSP2_CMD | ||
204 | /* SSP_{CMD,SCK} */ | 224 | /* SSP_{CMD,SCK} */ |
205 | imx233_pinctrl_setup_vpin(VPIN_SSP2_CMD, "ssp2_cmd", drive_strength, enable_pullups); | 225 | imx233_pinctrl_setup_vpin(VPIN_SSP2_CMD, "ssp2_cmd", drive_strength, enable_pullups); |
206 | imx233_pinctrl_setup_vpin(VPIN_SSP2_SCK, "ssp2_sck", drive_strength, false); | 226 | imx233_pinctrl_setup_vpin(VPIN_SSP2_SCK, "ssp2_sck", drive_strength, false); |
@@ -219,6 +239,9 @@ void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, | |||
219 | imx233_pinctrl_setup_vpin(VPIN_SSP2_D6, "ssp2_d6", drive_strength, enable_pullups); | 239 | imx233_pinctrl_setup_vpin(VPIN_SSP2_D6, "ssp2_d6", drive_strength, enable_pullups); |
220 | imx233_pinctrl_setup_vpin(VPIN_SSP2_D7, "ssp2_d7", drive_strength, enable_pullups); | 240 | imx233_pinctrl_setup_vpin(VPIN_SSP2_D7, "ssp2_d7", drive_strength, enable_pullups); |
221 | } | 241 | } |
242 | #else | ||
243 | panicf("there is no ssp2 on this soc!"); | ||
244 | #endif | ||
222 | } | 245 | } |
223 | 246 | ||
224 | void imx233_ssp_set_mode(int ssp, unsigned mode) | 247 | void imx233_ssp_set_mode(int ssp, unsigned mode) |
@@ -245,13 +268,22 @@ void imx233_ssp_set_bus_width(int ssp, unsigned width) | |||
245 | { | 268 | { |
246 | case 1: ssp_bus_width[ssp - 1] = BV_SSP_CTRL0_BUS_WIDTH__ONE_BIT; break; | 269 | case 1: ssp_bus_width[ssp - 1] = BV_SSP_CTRL0_BUS_WIDTH__ONE_BIT; break; |
247 | case 4: ssp_bus_width[ssp - 1] = BV_SSP_CTRL0_BUS_WIDTH__FOUR_BIT; break; | 270 | case 4: ssp_bus_width[ssp - 1] = BV_SSP_CTRL0_BUS_WIDTH__FOUR_BIT; break; |
271 | /* STMP3600 cannot do 8-bit bus */ | ||
272 | #if IMX233_SUBTARGET >= 3700 | ||
248 | case 8: ssp_bus_width[ssp - 1] = BV_SSP_CTRL0_BUS_WIDTH__EIGHT_BIT; break; | 273 | case 8: ssp_bus_width[ssp - 1] = BV_SSP_CTRL0_BUS_WIDTH__EIGHT_BIT; break; |
274 | #endif | ||
275 | default: panicf("ssp: target doesn't handle %d-bits bus", width); | ||
249 | } | 276 | } |
250 | } | 277 | } |
251 | 278 | ||
252 | void imx233_ssp_set_block_size(int ssp, unsigned log_block_size) | 279 | void imx233_ssp_set_block_size(int ssp, unsigned log_block_size) |
253 | { | 280 | { |
254 | ASSERT_SSP(ssp) | 281 | ASSERT_SSP(ssp) |
282 | /* STMP3600 cannot change block size */ | ||
283 | #if IMX233_SUBTARGET < 3600 | ||
284 | if(log_block_size != 9) | ||
285 | panicf("ssp: target doesn't block size %d", 1 << log_block_size); | ||
286 | #endif | ||
255 | ssp_log_block_size[ssp - 1] = log_block_size; | 287 | ssp_log_block_size[ssp - 1] = log_block_size; |
256 | } | 288 | } |
257 | 289 | ||
@@ -268,8 +300,13 @@ enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, | |||
268 | imx233_dma_enable_channel_interrupt(APB_SSP(ssp), true); | 300 | imx233_dma_enable_channel_interrupt(APB_SSP(ssp), true); |
269 | 301 | ||
270 | unsigned xfer_size = block_count * (1 << ssp_log_block_size[ssp - 1]); | 302 | unsigned xfer_size = block_count * (1 << ssp_log_block_size[ssp - 1]); |
303 | |||
304 | #if IMX233_SUBTARGET < 3700 | ||
305 | ssp_dma_cmd[ssp - 1].cmd0 = BF_OR1(SSP_CMD0, CMD(cmd)); | ||
306 | #else | ||
271 | ssp_dma_cmd[ssp - 1].cmd0 = BF_OR4(SSP_CMD0, CMD(cmd), APPEND_8CYC(1), | 307 | ssp_dma_cmd[ssp - 1].cmd0 = BF_OR4(SSP_CMD0, CMD(cmd), APPEND_8CYC(1), |
272 | BLOCK_SIZE(ssp_log_block_size[ssp - 1]), BLOCK_COUNT(block_count - 1)); | 308 | BLOCK_SIZE(ssp_log_block_size[ssp - 1]), BLOCK_COUNT(block_count - 1)); |
309 | #endif | ||
273 | ssp_dma_cmd[ssp - 1].cmd1 = cmd_arg; | 310 | ssp_dma_cmd[ssp - 1].cmd1 = cmd_arg; |
274 | /* setup all flags and run */ | 311 | /* setup all flags and run */ |
275 | ssp_dma_cmd[ssp - 1].ctrl0 = BF_OR9(SSP_CTRL0, XFER_COUNT(xfer_size), | 312 | ssp_dma_cmd[ssp - 1].ctrl0 = BF_OR9(SSP_CTRL0, XFER_COUNT(xfer_size), |
@@ -322,10 +359,12 @@ enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, | |||
322 | void imx233_ssp_sd_mmc_power_up_sequence(int ssp) | 359 | void imx233_ssp_sd_mmc_power_up_sequence(int ssp) |
323 | { | 360 | { |
324 | ASSERT_SSP(ssp) | 361 | ASSERT_SSP(ssp) |
362 | #if IMX233_SUBTARGET >= 3780 | ||
325 | SSP_CLRn(SSP_CMD0, ssp, SLOW_CLKING_EN); | 363 | SSP_CLRn(SSP_CMD0, ssp, SLOW_CLKING_EN); |
326 | SSP_SETn(SSP_CMD0, ssp, CONT_CLKING_EN); | 364 | SSP_SETn(SSP_CMD0, ssp, CONT_CLKING_EN); |
327 | mdelay(1); | 365 | mdelay(1); |
328 | SSP_CLRn(SSP_CMD0, ssp, CONT_CLKING_EN); | 366 | SSP_CLRn(SSP_CMD0, ssp, CONT_CLKING_EN); |
367 | #endif | ||
329 | } | 368 | } |
330 | 369 | ||
331 | static int ssp_detect_oneshot_callback(struct timeout *tmo) | 370 | static int ssp_detect_oneshot_callback(struct timeout *tmo) |
@@ -353,7 +392,13 @@ void imx233_ssp_sdmmc_setup_detect(int ssp, bool enable, ssp_detect_cb_t fn, | |||
353 | ASSERT_SSP(ssp) | 392 | ASSERT_SSP(ssp) |
354 | vpin_t vpin = VPIN_SSP1_DET; | 393 | vpin_t vpin = VPIN_SSP1_DET; |
355 | if(ssp == 2) | 394 | if(ssp == 2) |
395 | { | ||
396 | #ifdef VPIN_SSP2_DET | ||
356 | vpin = VPIN_SSP2_DET; | 397 | vpin = VPIN_SSP2_DET; |
398 | #else | ||
399 | panicf("there is no ssp2 det on this soc!"); | ||
400 | #endif | ||
401 | } | ||
357 | unsigned bank = VPIN_UNPACK_BANK(vpin), pin = VPIN_UNPACK_PIN(vpin); | 402 | unsigned bank = VPIN_UNPACK_BANK(vpin), pin = VPIN_UNPACK_PIN(vpin); |
358 | ssp_detect_cb[ssp - 1] = fn; | 403 | ssp_detect_cb[ssp - 1] = fn; |
359 | ssp_detect_invert[ssp - 1] = invert; | 404 | ssp_detect_invert[ssp - 1] = invert; |
diff --git a/firmware/target/arm/imx233/ssp-imx233.h b/firmware/target/arm/imx233/ssp-imx233.h index 4387fc6370..e58c9e1c09 100644 --- a/firmware/target/arm/imx233/ssp-imx233.h +++ b/firmware/target/arm/imx233/ssp-imx233.h | |||
@@ -29,21 +29,38 @@ | |||
29 | 29 | ||
30 | #include "regs/regs-ssp.h" | 30 | #include "regs/regs-ssp.h" |
31 | 31 | ||
32 | #if IMX233_SUBTARGET < 3700 | ||
33 | #define IMX233_NR_SSP 1 | ||
34 | #else | ||
32 | #define IMX233_NR_SSP 2 | 35 | #define IMX233_NR_SSP 2 |
36 | #endif | ||
33 | 37 | ||
34 | /* ssp can value 1 or 2 */ | 38 | /* ssp can value 1 or 2 */ |
39 | #if IMX233_NR_SSP >= 2 | ||
35 | #define __SSP_SELECT(ssp, ssp1, ssp2) ((ssp) == 1 ? (ssp1) : (ssp2)) | 40 | #define __SSP_SELECT(ssp, ssp1, ssp2) ((ssp) == 1 ? (ssp1) : (ssp2)) |
41 | #else | ||
42 | #define __SSP_SELECT(ssp, ssp1, ssp2) (ssp1) | ||
43 | #endif | ||
36 | 44 | ||
37 | #define INT_SRC_SSP_DMA(ssp) __SSP_SELECT(ssp, INT_SRC_SSP1_DMA, INT_SRC_SSP2_DMA) | 45 | #define INT_SRC_SSP_DMA(ssp) __SSP_SELECT(ssp, INT_SRC_SSP1_DMA, INT_SRC_SSP2_DMA) |
38 | #define INT_SRC_SSP_ERROR(ssp) __SSP_SELECT(ssp, INT_SRC_SSP1_ERROR, INT_SRC_SSP2_ERROR) | 46 | #define INT_SRC_SSP_ERROR(ssp) __SSP_SELECT(ssp, INT_SRC_SSP1_ERROR, INT_SRC_SSP2_ERROR) |
39 | 47 | ||
40 | #define BP_SSP_CTRL1_ALL_IRQ 0 | 48 | #define BP_SSP_CTRL1_ALL_IRQ 0 |
49 | #if IMX233_SUBTARGET < 3700 | ||
50 | #define BM_SSP_CTRL1_ALL_IRQ \ | ||
51 | BM_OR7(SSP_CTRL1, SDIO_IRQ, RESP_ERR_IRQ, RESP_TIMEOUT_IRQ, DATA_TIMEOUT_IRQ, \ | ||
52 | DATA_CRC_IRQ, RECV_TIMEOUT_IRQ, RECV_OVRFLW_IRQ) | ||
53 | #define BM_SSP_CTRL1_ALL_IRQ_EN \ | ||
54 | BM_OR7(SSP_CTRL1, SDIO_IRQ_EN, RESP_ERR_IRQ_EN, RESP_TIMEOUT_IRQ_EN, DATA_TIMEOUT_IRQ_EN, \ | ||
55 | DATA_CRC_IRQ_EN, RECV_TIMEOUT_IRQ_EN, RECV_OVRFLW_IRQ_EN) | ||
56 | #else | ||
41 | #define BM_SSP_CTRL1_ALL_IRQ \ | 57 | #define BM_SSP_CTRL1_ALL_IRQ \ |
42 | BM_OR8(SSP_CTRL1, SDIO_IRQ, RESP_ERR_IRQ, RESP_TIMEOUT_IRQ, DATA_TIMEOUT_IRQ, \ | 58 | BM_OR8(SSP_CTRL1, SDIO_IRQ, RESP_ERR_IRQ, RESP_TIMEOUT_IRQ, DATA_TIMEOUT_IRQ, \ |
43 | DATA_CRC_IRQ, FIFO_UNDERRUN_IRQ, RECV_TIMEOUT_IRQ, FIFO_OVERRUN_IRQ) | 59 | DATA_CRC_IRQ, FIFO_UNDERRUN_IRQ, RECV_TIMEOUT_IRQ, FIFO_OVERRUN_IRQ) |
44 | #define BM_SSP_CTRL1_ALL_IRQ_EN \ | 60 | #define BM_SSP_CTRL1_ALL_IRQ_EN \ |
45 | BM_OR8(SSP_CTRL1, SDIO_IRQ_EN, RESP_ERR_IRQ_EN, RESP_TIMEOUT_IRQ_EN, DATA_TIMEOUT_IRQ_EN, \ | 61 | BM_OR8(SSP_CTRL1, SDIO_IRQ_EN, RESP_ERR_IRQ_EN, RESP_TIMEOUT_IRQ_EN, DATA_TIMEOUT_IRQ_EN, \ |
46 | DATA_CRC_IRQ_EN, FIFO_UNDERRUN_EN, RECV_TIMEOUT_IRQ_EN, FIFO_OVERRUN_IRQ_EN) | 62 | DATA_CRC_IRQ_EN, FIFO_UNDERRUN_EN, RECV_TIMEOUT_IRQ_EN, FIFO_OVERRUN_IRQ_EN) |
63 | #endif | ||
47 | 64 | ||
48 | #define BM_SSP_CTRL1_TIMEOUT_IRQ \ | 65 | #define BM_SSP_CTRL1_TIMEOUT_IRQ \ |
49 | BM_OR3(SSP_CTRL1, RESP_TIMEOUT_IRQ, DATA_TIMEOUT_IRQ, RECV_TIMEOUT_IRQ) | 66 | BM_OR3(SSP_CTRL1, RESP_TIMEOUT_IRQ, DATA_TIMEOUT_IRQ, RECV_TIMEOUT_IRQ) |
@@ -80,6 +97,7 @@ void imx233_ssp_set_block_size(int ssp, unsigned log_block_size); | |||
80 | enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, | 97 | enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, |
81 | uint32_t cmd_arg, enum imx233_ssp_resp_t resp, void *buffer, unsigned block_count, | 98 | uint32_t cmd_arg, enum imx233_ssp_resp_t resp, void *buffer, unsigned block_count, |
82 | bool wait4irq, bool read, uint32_t *resp_ptr); | 99 | bool wait4irq, bool read, uint32_t *resp_ptr); |
100 | /* pullups/alternative are ignored on targets which don't support it */ | ||
83 | void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, | 101 | void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, |
84 | unsigned drive_strength, bool use_alt); | 102 | unsigned drive_strength, bool use_alt); |
85 | void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, | 103 | void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, |