From: cmc Date: Tue, 7 Dec 2010 08:08:45 +0000 (+0800) Subject: add iomux for spi X-Git-Tag: firefly_0821_release~10986 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2dc337889eb8aee3e230dbf899c7e65fe156da45;p=firefly-linux-kernel-4.4.55.git add iomux for spi --- diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c index 934626a29c92..26ecad0789f6 100755 --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -775,6 +775,18 @@ static void __init rk29_board_iomux_init(void) rk29_mux_api_set(GPIO2B4_UART3CTSN_I2C3SDA_NAME, GPIO2L_UART3_CTS_N); #endif #endif + #ifdef CONFIG_SPIM0_RK29 + rk29_mux_api_set(GPIO2C0_SPI0CLK_NAME, GPIO2H_SPI0_CLK); + rk29_mux_api_set(GPIO2C1_SPI0CSN0_NAME, GPIO2H_SPI0_CSN0); + rk29_mux_api_set(GPIO2C2_SPI0TXD_NAME, GPIO2H_SPI0_TXD); + rk29_mux_api_set(GPIO2C3_SPI0RXD_NAME, GPIO2H_SPI0_RXD); + #endif + #ifdef CONFIG_SPIM1_RK29 + rk29_mux_api_set(GPIO2C4_SPI1CLK_NAME, GPIO2H_SPI1_CLK); + rk29_mux_api_set(GPIO2C5_SPI1CSN0_NAME, GPIO2H_SPI1_CSN0); + rk29_mux_api_set(GPIO2C6_SPI1TXD_NAME, GPIO2H_SPI1_TXD); + rk29_mux_api_set(GPIO2C7_SPI1RXD_NAME, GPIO2H_SPI1_RXD); + #endif } static struct platform_device *devices[] __initdata = { @@ -870,13 +882,13 @@ struct spi_cs_gpio rk29xx_spi1_cs_gpios[SPI_CHIPSELECT_NUM] = { .name = "spi1 cs1", .cs_gpio = RK29_PIN1_PA3, .cs_iomux_name = GPIO1A3_EMMCDETECTN_SPI1CS1_NAME,//if no iomux,set it NULL - .cs_iomux_mode = GPIO1L_SPI0_CSN1, + .cs_iomux_mode = GPIO1L_SPI1_CSN1, } }; static int spi_io_init(struct spi_cs_gpio *cs_gpios, int cs_num) { -#if 0 +#if 1 int i,j,ret; //cs @@ -901,7 +913,7 @@ static int spi_io_init(struct spi_cs_gpio *cs_gpios, int cs_num) static int spi_io_deinit(struct spi_cs_gpio *cs_gpios, int cs_num) { -#if 0 +#if 1 int i; if (cs_gpios) { diff --git a/arch/arm/mach-rk29/include/mach/iomux.h b/arch/arm/mach-rk29/include/mach/iomux.h old mode 100644 new mode 100755 index 41fade1bdfcb..fb9822331485 --- a/arch/arm/mach-rk29/include/mach/iomux.h +++ b/arch/arm/mach-rk29/include/mach/iomux.h @@ -584,7 +584,7 @@ #define GPIO2D2_I2S0LRCKRX_MIITXERR_NAME "gpio2d2_i2s0lrckrx_miitxerr_name" #define GPIO2D1_I2S0SCLK_MIICRS_NAME "gpio2d1_i2s0sclk_miicrs_name" #define GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME "gpio2d0_i2s0clk_miirxclkin_name" -#define GPIO2C7_SPI1TXD_NAME "gpio2c7_spi1txd_name" +#define GPIO2C7_SPI1RXD_NAME "gpio2c7_spi1rxd_name" #define GPIO2C6_SPI1TXD_NAME "gpio2c6_spi1txd_name" #define GPIO2C5_SPI1CSN0_NAME "gpio2c5_spi1csn0_name" #define GPIO2C4_SPI1CLK_NAME "gpio2c4_spi1clk_name" diff --git a/arch/arm/mach-rk29/iomux.c b/arch/arm/mach-rk29/iomux.c old mode 100644 new mode 100755 index 914c40b9b59c..428e541be7c9 --- a/arch/arm/mach-rk29/iomux.c +++ b/arch/arm/mach-rk29/iomux.c @@ -117,7 +117,7 @@ MUX_CFG(GPIO2D3_I2S0SDI_MIICOL_NAME, GPIO2H, 22, 2, 0, DEFAULT) MUX_CFG(GPIO2D2_I2S0LRCKRX_MIITXERR_NAME, GPIO2H, 20, 2, 0, DEFAULT) MUX_CFG(GPIO2D1_I2S0SCLK_MIICRS_NAME, GPIO2H, 18, 2, 0, DEFAULT) MUX_CFG(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H, 16, 2, 0, DEFAULT) -MUX_CFG(GPIO2C7_SPI1TXD_NAME, GPIO2H, 14, 2, 0, DEFAULT) +MUX_CFG(GPIO2C7_SPI1RXD_NAME, GPIO2H, 14, 2, 0, DEFAULT) MUX_CFG(GPIO2C6_SPI1TXD_NAME, GPIO2H, 12, 2, 0, DEFAULT) MUX_CFG(GPIO2C5_SPI1CSN0_NAME, GPIO2H, 10, 2, 0, DEFAULT) MUX_CFG(GPIO2C4_SPI1CLK_NAME, GPIO2H, 8, 2, 0, DEFAULT) diff --git a/drivers/spi/rk29_spim.c b/drivers/spi/rk29_spim.c index 9d15abc10d59..b2ffd2ca1605 100755 --- a/drivers/spi/rk29_spim.c +++ b/drivers/spi/rk29_spim.c @@ -24,7 +24,7 @@ #include #include -#include "rk29xx_spim.h" +#include "rk29_spim.h" #include #include @@ -88,6 +88,28 @@ struct chip_data { #define RXBUSY (1<<2) #define TXBUSY (1<<3) +static void spi_dump_regs(struct rk29xx_spi *dws) { + printk("MRST SPI0 registers:\n"); + printk("=================================\n"); + printk("CTRL0: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_CTRLR0)); + printk("CTRL1: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_CTRLR1)); + printk("SSIENR: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_ENR)); + printk("SER: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_SER)); + printk("BAUDR: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_BAUDR)); + printk("TXFTLR: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_TXFTLR)); + printk("RXFTLR: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_RXFTLR)); + printk("TXFLR: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_TXFLR)); + printk("RXFLR: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_RXFLR)); + printk("SR: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_SR)); + printk("IMR: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_IMR)); + printk("ISR: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_ISR)); + printk("DMACR: \t\t0x%08x\n", rk29xx_readl(dws, SPIM_DMACR)); + printk("DMATDLR: \t0x%08x\n", rk29xx_readl(dws, SPIM_DMATDLR)); + printk("DMARDLR: \t0x%08x\n", rk29xx_readl(dws, SPIM_DMARDLR)); + printk("=================================\n"); + +} + #ifdef CONFIG_DEBUG_FS static int spi_show_regs_open(struct inode *inode, struct file *file) { @@ -220,9 +242,11 @@ static void flush(struct rk29xx_spi *dws) wait_till_not_busy(dws); } -#if 0 static void spi_cs_control(struct rk29xx_spi *dws, u32 cs, u8 flag) { + #if 1 + return; + #else struct rk29xx_spi_platform_data *pdata = dws->master->dev.platform_data; struct spi_cs_gpio *cs_gpios = pdata->chipselect_gpios; @@ -230,8 +254,8 @@ static void spi_cs_control(struct rk29xx_spi *dws, u32 cs, u8 flag) gpio_direction_output(cs_gpios[cs].cs_gpio, GPIO_HIGH); else gpio_direction_output(cs_gpios[cs].cs_gpio, GPIO_LOW); + #endif } -#endif static int null_writer(struct rk29xx_spi *dws) { @@ -261,6 +285,8 @@ static int null_reader(struct rk29xx_spi *dws) static int u8_writer(struct rk29xx_spi *dws) { + spi_dump_regs(dws); + DBG("tx: 0x%02x\n", *(u8 *)(dws->tx)); if ((rk29xx_readw(dws, SPIM_SR) & SR_TF_FULL) || (dws->tx == dws->tx_end)) return 0; @@ -353,12 +379,14 @@ static void rk29_spi_dma_txcb(void *buf_id, struct rk29xx_spi *dws = buf_id; unsigned long flags; + DBG("func: %s, line: %d\n", __FUNCTION__, __LINE__); + spin_lock_irqsave(&dws->lock, flags); if (res == RK29_RES_OK) dws->state &= ~TXBUSY; else - dev_err(&dws->master->dev, "DmaAbrtTx-%d \n", size); + dev_err(&dws->master->dev, "DmaAbrtTx-%d, size: %d \n", res, size); /* If the other done */ if (!(dws->state & RXBUSY)) @@ -421,7 +449,7 @@ static int map_dma_buffers(struct rk29xx_spi *dws) return -1; } if (rk29_dma_devconfig(dws->tx_dmach, RK29_DMASRC_MEM, - (unsigned long)dws->sfr_start + SPIM_TXDR)) { + dws->sfr_start + SPIM_TXDR)) { dev_err(&dws->master->dev, "rk29_dma_devconfig fail\n"); return -1; } @@ -434,7 +462,7 @@ static int map_dma_buffers(struct rk29xx_spi *dws) return -1; } if (rk29_dma_devconfig(dws->rx_dmach, RK29_DMASRC_HW, - (unsigned long)dws->sfr_start + SPIM_RXDR)) { + dws->sfr_start + SPIM_RXDR)) { dev_err(&dws->master->dev, "rk29_dma_devconfig fail\n"); return -1; } @@ -464,7 +492,7 @@ static void giveback(struct rk29xx_spi *dws) struct spi_transfer, transfer_list); - if (!last_transfer->cs_change) + if (!last_transfer->cs_change && dws->cs_control) dws->cs_control(dws,msg->spi->chip_select, MRST_SPI_DEASSERT); msg->state = NULL; @@ -501,7 +529,7 @@ static void transfer_complete(struct rk29xx_spi *dws) static irqreturn_t interrupt_transfer(struct rk29xx_spi *dws) { - u16 irq_status, irq_mask = 0x3f; + u16 irq_status, irq_mask = 0x1f; u32 int_level = dws->fifo_len / 2; u32 left; @@ -563,7 +591,7 @@ static void spi_chip_sel(struct rk29xx_spi *dws, u16 cs) return; if (dws->cs_control){ - dws->cs_control(dws, cs, 1); + dws->cs_control(dws, cs, MRST_SPI_ASSERT); } rk29xx_writel(dws, SPIM_SER, 1 << cs); } @@ -593,8 +621,7 @@ static void pump_transfers(unsigned long data) chip = dws->cur_chip; spi = message->spi; if (unlikely(!chip->clk_div)) - //chip->clk_div = clk_get_rate(dws->clock_spim) / chip->speed_hz; - chip->clk_div = 40000000 / chip->speed_hz; + chip->clk_div = clk_get_rate(dws->clock_spim) / chip->speed_hz; if (message->state == ERROR_STATE) { message->status = -EIO; goto early_exit; @@ -769,6 +796,7 @@ static void dma_transfer(struct rk29xx_spi *dws) //int cs_change) unsigned long val; int ms; int iRet; + int burst; u8 bits = 0; u8 spi_dfs = 0; u8 cs_change = 0; @@ -795,7 +823,7 @@ static void dma_transfer(struct rk29xx_spi *dws) //int cs_change) chip = dws->cur_chip; spi = message->spi; if (unlikely(!chip->clk_div)) - chip->clk_div = 40000000 / chip->speed_hz; + chip->clk_div = clk_get_rate(dws->clock_spim) / chip->speed_hz; if (message->state == ERROR_STATE) { message->status = -EIO; goto err_out; @@ -936,10 +964,18 @@ static void dma_transfer(struct rk29xx_spi *dws) //int cs_change) } INIT_COMPLETION(dws->xfer_completion); - + + spi_dump_regs(dws); + DBG("dws->tx_dmach: %d, dws->rx_dmach: %d, transfer->tx_dma: 0x%x\n", dws->tx_dmach, dws->rx_dmach, (unsigned int)transfer->tx_dma); if (transfer->tx_buf != NULL) { dws->state |= TXBUSY; - if (rk29_dma_config(dws->tx_dmach, 1)) { + if (transfer->len & 0x3) { + burst = 1; + } + else { + burst = 4; + } + if (rk29_dma_config(dws->tx_dmach, burst)) { dev_err(&dws->master->dev, "function: %s, line: %d\n", __FUNCTION__, __LINE__); goto err_out; } @@ -979,10 +1015,10 @@ static void dma_transfer(struct rk29xx_spi *dws) //int cs_change) } /* millisecs to xfer 'len' bytes @ 'cur_speed' */ - ms = transfer->len * 8 * 1000 / dws->cur_chip->speed_hz; + ms = transfer->len * 8 / dws->cur_chip->speed_hz; ms += 10; - val = msecs_to_jiffies(ms) + 500; + val = msecs_to_jiffies(ms) + 10; if (!wait_for_completion_timeout(&dws->xfer_completion, val)) { if (transfer->rx_buf != NULL && (dws->state & RXBUSY)) { rk29_dma_ctrl(dws->rx_dmach, RK29_DMAOP_FLUSH); @@ -1118,7 +1154,7 @@ static void msg_giveback(struct rk29xx_spi *dws) struct spi_transfer, transfer_list); - if (!last_transfer->cs_change) + if (!last_transfer->cs_change && dws->cs_control) dws->cs_control(dws,msg->spi->chip_select,MRST_SPI_DEASSERT); msg->state = NULL; @@ -1511,7 +1547,7 @@ static int rk29xx_spi_setup(struct spi_device *spi) if (!chip) return -ENOMEM; - chip->cs_control = NULL; + chip->cs_control = spi_cs_control; chip->enable_dma = 1; //0; } @@ -1570,6 +1606,7 @@ static int rk29xx_spi_setup(struct spi_device *spi) | (chip->tmode << SPI_TMOD_OFFSET); spi_set_ctldata(spi, chip); + DBG("RK29XX_SPI_SETUP: CRO: 0x%x ???????????????????\n", chip->cr0); return 0; } @@ -1661,9 +1698,7 @@ static void spi_hw_init(struct rk29xx_spi *dws) { spi_enable_chip(dws, 0); spi_mask_intr(dws, 0xff); - spi_enable_chip(dws, 1); - flush(dws); - + /* * Try to detect the FIFO depth if not set by interface driver, * the depth could be from 2 to 32 from HW spec @@ -1679,6 +1714,9 @@ static void spi_hw_init(struct rk29xx_spi *dws) dws->fifo_len = (fifo == 31) ? 0 : fifo; rk29xx_writew(dws, SPIM_TXFTLR, 0); } + + spi_enable_chip(dws, 1); + flush(dws); } /* cpufreq driver support */ @@ -1833,7 +1871,7 @@ static int __init rk29xx_spim_probe(struct platform_device *pdev) dev_err(&master->dev, "rk29xx spim failed to init cpufreq support\n"); goto err_queue_alloc; } - DBG(KERN_INFO "rk29xx_spim: driver initialized\n"); + DBG(KERN_INFO "rk29xx_spim: driver initialized, fifo_len: %d\n", dws->fifo_len); mrst_spi_debugfs_init(dws); return 0;