summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-06-17 00:20:12 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-06-17 00:29:25 +0200
commitb74a459189d06ea453199b79e4602c9490404682 (patch)
treec35d52732a2fbd1e2dc797b97a3d62f2452b4555
parent86ff093267171ca91cb4d10f6ff1b27bb1349dac (diff)
downloadrockbox-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
-rw-r--r--firmware/target/arm/imx233/ssp-imx233.c45
-rw-r--r--firmware/target/arm/imx233/ssp-imx233.h18
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 */
44struct ssp_dma_command_t 53struct 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
224void imx233_ssp_set_mode(int ssp, unsigned mode) 247void 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
252void imx233_ssp_set_block_size(int ssp, unsigned log_block_size) 279void 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,
322void imx233_ssp_sd_mmc_power_up_sequence(int ssp) 359void 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
331static int ssp_detect_oneshot_callback(struct timeout *tmo) 370static 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);
80enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, 97enum 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 */
83void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, 101void 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);
85void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, 103void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width,