From b74a459189d06ea453199b79e4602c9490404682 Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Mon, 17 Jun 2013 00:20:12 +0200 Subject: 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 --- firmware/target/arm/imx233/ssp-imx233.c | 45 +++++++++++++++++++++++++++++++++ firmware/target/arm/imx233/ssp-imx233.h | 18 +++++++++++++ 2 files changed, 63 insertions(+) (limited to 'firmware/target/arm') 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 @@ #endif /* Hack to handle both single and multi devices at once */ +#if IMX233_SUBTARGET < 3700 +#define SSP_SETn(reg, n, field) BF_SET(reg, field) +#define SSP_CLRn(reg, n, field) BF_CLR(reg, field) +#define SSP_RDn(reg, n, field) BF_RD(reg, field) +#define SSP_WRn(reg, n, field, val) BF_WR(reg, field, val) +#define SSP_WRn_V(reg, n, field, val) BF_WR_V(reg, field, val) +#define SSP_REGn(reg, n) HW_##reg +#else #define SSP_SETn(reg, n, field) BF_SETn(reg, n, field) #define SSP_CLRn(reg, n, field) BF_CLRn(reg, n, field) #define SSP_RDn(reg, n, field) BF_RDn(reg, n, field) #define SSP_WRn(reg, n, field, val) BF_WRn(reg, n, field, val) #define SSP_WRn_V(reg, n, field, val) BF_WRn_V(reg, n, field, val) #define SSP_REGn(reg, n) HW_##reg(n) +#endif /* Used for DMA */ struct ssp_dma_command_t @@ -126,7 +135,9 @@ void imx233_ssp_start(int ssp) * intdiv = 5 => clk_ssp = 96Mhz */ imx233_clkctrl_enable(CLK_SSP, false); imx233_clkctrl_set_div(CLK_SSP, 5); +#if IMX233_SUBTARGET >= 3700 imx233_clkctrl_set_bypass(CLK_SSP, false); /* use IO */ +#endif imx233_clkctrl_enable(CLK_SSP, true); } ssp_nr_in_use++; @@ -178,12 +189,17 @@ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, } if(bus_width >= 8) { +#ifdef VPIN_SSP1_D4 if(use_alt) { +#ifdef VPIN_SSP1_D4_ALT imx233_pinctrl_setup_vpin(VPIN_SSP1_D4_ALT, "ssp1_d4", drive_strength, enable_pullups); imx233_pinctrl_setup_vpin(VPIN_SSP1_D5_ALT, "ssp1_d5", drive_strength, enable_pullups); imx233_pinctrl_setup_vpin(VPIN_SSP1_D6_ALT, "ssp1_d6", drive_strength, enable_pullups); imx233_pinctrl_setup_vpin(VPIN_SSP1_D7_ALT, "ssp1_d7", drive_strength, enable_pullups); +#else + panicf("there is ssp1 alt on this soc!"); +#endif } else { @@ -192,6 +208,9 @@ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, imx233_pinctrl_setup_vpin(VPIN_SSP1_D6, "ssp1_d6", drive_strength, enable_pullups); imx233_pinctrl_setup_vpin(VPIN_SSP1_D7, "ssp1_d7", drive_strength, enable_pullups); } +#else + panicf("ssp1 bus width is limited to 4 on this soc!"); +#endif } } @@ -201,6 +220,7 @@ void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, (void) enable_pullups; (void) bus_width; (void) drive_strength; +#ifdef VPIN_SSP2_CMD /* SSP_{CMD,SCK} */ imx233_pinctrl_setup_vpin(VPIN_SSP2_CMD, "ssp2_cmd", drive_strength, enable_pullups); 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, imx233_pinctrl_setup_vpin(VPIN_SSP2_D6, "ssp2_d6", drive_strength, enable_pullups); imx233_pinctrl_setup_vpin(VPIN_SSP2_D7, "ssp2_d7", drive_strength, enable_pullups); } +#else + panicf("there is no ssp2 on this soc!"); +#endif } void imx233_ssp_set_mode(int ssp, unsigned mode) @@ -245,13 +268,22 @@ void imx233_ssp_set_bus_width(int ssp, unsigned width) { case 1: ssp_bus_width[ssp - 1] = BV_SSP_CTRL0_BUS_WIDTH__ONE_BIT; break; case 4: ssp_bus_width[ssp - 1] = BV_SSP_CTRL0_BUS_WIDTH__FOUR_BIT; break; + /* STMP3600 cannot do 8-bit bus */ +#if IMX233_SUBTARGET >= 3700 case 8: ssp_bus_width[ssp - 1] = BV_SSP_CTRL0_BUS_WIDTH__EIGHT_BIT; break; +#endif + default: panicf("ssp: target doesn't handle %d-bits bus", width); } } void imx233_ssp_set_block_size(int ssp, unsigned log_block_size) { ASSERT_SSP(ssp) + /* STMP3600 cannot change block size */ +#if IMX233_SUBTARGET < 3600 + if(log_block_size != 9) + panicf("ssp: target doesn't block size %d", 1 << log_block_size); +#endif ssp_log_block_size[ssp - 1] = log_block_size; } @@ -268,8 +300,13 @@ enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, imx233_dma_enable_channel_interrupt(APB_SSP(ssp), true); unsigned xfer_size = block_count * (1 << ssp_log_block_size[ssp - 1]); + +#if IMX233_SUBTARGET < 3700 + ssp_dma_cmd[ssp - 1].cmd0 = BF_OR1(SSP_CMD0, CMD(cmd)); +#else ssp_dma_cmd[ssp - 1].cmd0 = BF_OR4(SSP_CMD0, CMD(cmd), APPEND_8CYC(1), BLOCK_SIZE(ssp_log_block_size[ssp - 1]), BLOCK_COUNT(block_count - 1)); +#endif ssp_dma_cmd[ssp - 1].cmd1 = cmd_arg; /* setup all flags and run */ 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, void imx233_ssp_sd_mmc_power_up_sequence(int ssp) { ASSERT_SSP(ssp) +#if IMX233_SUBTARGET >= 3780 SSP_CLRn(SSP_CMD0, ssp, SLOW_CLKING_EN); SSP_SETn(SSP_CMD0, ssp, CONT_CLKING_EN); mdelay(1); SSP_CLRn(SSP_CMD0, ssp, CONT_CLKING_EN); +#endif } 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, ASSERT_SSP(ssp) vpin_t vpin = VPIN_SSP1_DET; if(ssp == 2) + { +#ifdef VPIN_SSP2_DET vpin = VPIN_SSP2_DET; +#else + panicf("there is no ssp2 det on this soc!"); +#endif + } unsigned bank = VPIN_UNPACK_BANK(vpin), pin = VPIN_UNPACK_PIN(vpin); ssp_detect_cb[ssp - 1] = fn; 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 @@ #include "regs/regs-ssp.h" +#if IMX233_SUBTARGET < 3700 +#define IMX233_NR_SSP 1 +#else #define IMX233_NR_SSP 2 +#endif /* ssp can value 1 or 2 */ +#if IMX233_NR_SSP >= 2 #define __SSP_SELECT(ssp, ssp1, ssp2) ((ssp) == 1 ? (ssp1) : (ssp2)) +#else +#define __SSP_SELECT(ssp, ssp1, ssp2) (ssp1) +#endif #define INT_SRC_SSP_DMA(ssp) __SSP_SELECT(ssp, INT_SRC_SSP1_DMA, INT_SRC_SSP2_DMA) #define INT_SRC_SSP_ERROR(ssp) __SSP_SELECT(ssp, INT_SRC_SSP1_ERROR, INT_SRC_SSP2_ERROR) #define BP_SSP_CTRL1_ALL_IRQ 0 +#if IMX233_SUBTARGET < 3700 +#define BM_SSP_CTRL1_ALL_IRQ \ + BM_OR7(SSP_CTRL1, SDIO_IRQ, RESP_ERR_IRQ, RESP_TIMEOUT_IRQ, DATA_TIMEOUT_IRQ, \ + DATA_CRC_IRQ, RECV_TIMEOUT_IRQ, RECV_OVRFLW_IRQ) +#define BM_SSP_CTRL1_ALL_IRQ_EN \ + BM_OR7(SSP_CTRL1, SDIO_IRQ_EN, RESP_ERR_IRQ_EN, RESP_TIMEOUT_IRQ_EN, DATA_TIMEOUT_IRQ_EN, \ + DATA_CRC_IRQ_EN, RECV_TIMEOUT_IRQ_EN, RECV_OVRFLW_IRQ_EN) +#else #define BM_SSP_CTRL1_ALL_IRQ \ BM_OR8(SSP_CTRL1, SDIO_IRQ, RESP_ERR_IRQ, RESP_TIMEOUT_IRQ, DATA_TIMEOUT_IRQ, \ DATA_CRC_IRQ, FIFO_UNDERRUN_IRQ, RECV_TIMEOUT_IRQ, FIFO_OVERRUN_IRQ) #define BM_SSP_CTRL1_ALL_IRQ_EN \ BM_OR8(SSP_CTRL1, SDIO_IRQ_EN, RESP_ERR_IRQ_EN, RESP_TIMEOUT_IRQ_EN, DATA_TIMEOUT_IRQ_EN, \ DATA_CRC_IRQ_EN, FIFO_UNDERRUN_EN, RECV_TIMEOUT_IRQ_EN, FIFO_OVERRUN_IRQ_EN) +#endif #define BM_SSP_CTRL1_TIMEOUT_IRQ \ 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); enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, uint32_t cmd_arg, enum imx233_ssp_resp_t resp, void *buffer, unsigned block_count, bool wait4irq, bool read, uint32_t *resp_ptr); +/* pullups/alternative are ignored on targets which don't support it */ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, unsigned drive_strength, bool use_alt); void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, -- cgit v1.2.3