X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=drivers%2Fspi%2Fmxs_spi.c;h=e231e96e58102207ab8d2aa42967382af3434a58;hb=5575f79bdaa824a90747d5a3d063b5219521b066;hp=d475830f17857189adaea590d54bb198a82c46e4;hpb=c2050e10e11b7226f01aa18d49b9d4a2322723ca;p=platform%2Fkernel%2Fu-boot.git diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c index d475830..e231e96 100644 --- a/drivers/spi/mxs_spi.c +++ b/drivers/spi/mxs_spi.c @@ -13,9 +13,16 @@ */ #include +#include +#include +#include +#include +#include #include #include #include +#include +#include #include #include #include @@ -30,34 +37,20 @@ #define MXSSSP_SMALL_TRANSFER 512 -static void mxs_spi_start_xfer(struct mxs_ssp_regs *ssp_regs) -{ - writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_set); - writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_clr); -} - -static void mxs_spi_end_xfer(struct mxs_ssp_regs *ssp_regs) -{ - writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_clr); - writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_set); -} +/* Base numbers of i.MX2[38] clk for ssp0 IP block */ +#define MXS_SSP_IMX23_CLKID_SSP0 33 +#define MXS_SSP_IMX28_CLKID_SSP0 46 -#if !CONFIG_IS_ENABLED(DM_SPI) -struct mxs_spi_slave { - struct spi_slave slave; - uint32_t max_khz; - uint32_t mode; - struct mxs_ssp_regs *regs; -}; +#ifdef CONFIG_MX28 +#define dtd_fsl_imx_spi dtd_fsl_imx28_spi +#else /* CONFIG_MX23 */ +#define dtd_fsl_imx_spi dtd_fsl_imx23_spi +#endif -static inline struct mxs_spi_slave *to_mxs_slave(struct spi_slave *slave) -{ - return container_of(slave, struct mxs_spi_slave, slave); -} -#else -#include -#include struct mxs_spi_platdata { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_fsl_imx_spi dtplat; +#endif s32 frequency; /* Default clock frequency, -1 for none */ fdt_addr_t base; /* SPI IP block base address */ int num_cs; /* Number of CSes supported */ @@ -72,20 +65,24 @@ struct mxs_spi_priv { unsigned int clk_id; unsigned int mode; }; -#endif -#if !CONFIG_IS_ENABLED(DM_SPI) -static int mxs_spi_xfer_pio(struct mxs_spi_slave *slave, - char *data, int length, int write, unsigned long flags) +static void mxs_spi_start_xfer(struct mxs_ssp_regs *ssp_regs) { - struct mxs_ssp_regs *ssp_regs = slave->regs; -#else + writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_set); + writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_clr); +} + +static void mxs_spi_end_xfer(struct mxs_ssp_regs *ssp_regs) +{ + writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_clr); + writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_set); +} + static int mxs_spi_xfer_pio(struct mxs_spi_priv *priv, char *data, int length, int write, unsigned long flags) { struct mxs_ssp_regs *ssp_regs = priv->regs; -#endif if (flags & SPI_XFER_BEGIN) mxs_spi_start_xfer(ssp_regs); @@ -141,17 +138,10 @@ static int mxs_spi_xfer_pio(struct mxs_spi_priv *priv, return 0; } -#if !CONFIG_IS_ENABLED(DM_SPI) -static int mxs_spi_xfer_dma(struct mxs_spi_slave *slave, - char *data, int length, int write, unsigned long flags) -{ - struct mxs_ssp_regs *ssp_regs = slave->regs; -#else static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv, char *data, int length, int write, unsigned long flags) { struct mxs_ssp_regs *ssp_regs = priv->regs; -#endif const int xfer_max_sz = 0xff00; const int desc_count = DIV_ROUND_UP(length, xfer_max_sz) + 1; struct mxs_dma_desc *dp; @@ -192,11 +182,7 @@ static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv, /* Invalidate the area, so no writeback into the RAM races with DMA */ invalidate_dcache_range(dstart, dstart + cache_data_count); -#if !CONFIG_IS_ENABLED(DM_SPI) - dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + slave->slave.bus; -#else dmach = priv->dma_channel; -#endif dp = desc; while (length) { @@ -273,20 +259,12 @@ static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv, return ret; } -#if !CONFIG_IS_ENABLED(DM_SPI) -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave); - struct mxs_ssp_regs *ssp_regs = mxs_slave->regs; -#else int mxs_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct udevice *bus = dev_get_parent(dev); struct mxs_spi_priv *priv = dev_get_priv(bus); struct mxs_ssp_regs *ssp_regs = priv->regs; -#endif int len = bitlen / 8; char dummy; int write = 0; @@ -330,99 +308,13 @@ int mxs_spi_xfer(struct udevice *dev, unsigned int bitlen, if (!dma || (len < MXSSSP_SMALL_TRANSFER)) { writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_clr); -#if !CONFIG_IS_ENABLED(DM_SPI) - return mxs_spi_xfer_pio(mxs_slave, data, len, write, flags); -#else return mxs_spi_xfer_pio(priv, data, len, write, flags); -#endif } else { writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set); -#if !CONFIG_IS_ENABLED(DM_SPI) - return mxs_spi_xfer_dma(mxs_slave, data, len, write, flags); -#else return mxs_spi_xfer_dma(priv, data, len, write, flags); -#endif } } -#if !CONFIG_IS_ENABLED(DM_SPI) -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - /* MXS SPI: 4 ports and 3 chip selects maximum */ - if (!mxs_ssp_bus_id_valid(bus) || cs > 2) - return 0; - else - return 1; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct mxs_spi_slave *mxs_slave; - - if (!spi_cs_is_valid(bus, cs)) { - printf("mxs_spi: invalid bus %d / chip select %d\n", bus, cs); - return NULL; - } - - mxs_slave = spi_alloc_slave(struct mxs_spi_slave, bus, cs); - if (!mxs_slave) - return NULL; - - if (mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + bus)) - goto err_init; - - mxs_slave->max_khz = max_hz / 1000; - mxs_slave->mode = mode; - mxs_slave->regs = mxs_ssp_regs_by_bus(bus); - - return &mxs_slave->slave; - -err_init: - free(mxs_slave); - return NULL; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave); - - free(mxs_slave); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave); - struct mxs_ssp_regs *ssp_regs = mxs_slave->regs; - u32 reg = 0; - - mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg); - - writel((slave->cs << MXS_SSP_CHIPSELECT_SHIFT) | - SSP_CTRL0_BUS_WIDTH_ONE_BIT, - &ssp_regs->hw_ssp_ctrl0); - - reg = SSP_CTRL1_SSP_MODE_SPI | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS; - reg |= (mxs_slave->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0; - reg |= (mxs_slave->mode & SPI_CPHA) ? SSP_CTRL1_PHASE : 0; - writel(reg, &ssp_regs->hw_ssp_ctrl1); - - writel(0, &ssp_regs->hw_ssp_cmd0); - - mxs_set_ssp_busclock(slave->bus, mxs_slave->max_khz); - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ -} - -#else /* CONFIG_DM_SPI */ -/* Base numbers of i.MX2[38] clk for ssp0 IP block */ -#define MXS_SSP_IMX23_CLKID_SSP0 33 -#define MXS_SSP_IMX28_CLKID_SSP0 46 - static int mxs_spi_probe(struct udevice *bus) { struct mxs_spi_platdata *plat = dev_get_platdata(bus); @@ -430,11 +322,26 @@ static int mxs_spi_probe(struct udevice *bus) int ret; debug("%s: probe\n", __func__); + +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_fsl_imx_spi *dtplat = &plat->dtplat; + struct phandle_1_arg *p1a = &dtplat->clocks[0]; + + priv->regs = (struct mxs_ssp_regs *)dtplat->reg[0]; + priv->dma_channel = dtplat->dmas[1]; + priv->clk_id = p1a->arg[0]; + priv->max_freq = dtplat->spi_max_frequency; + plat->num_cs = dtplat->num_cs; + + debug("OF_PLATDATA: regs: 0x%x max freq: %d clkid: %d\n", + (unsigned int)priv->regs, priv->max_freq, priv->clk_id); +#else priv->regs = (struct mxs_ssp_regs *)plat->base; priv->max_freq = plat->frequency; priv->dma_channel = plat->dma_id; priv->clk_id = plat->clk_id; +#endif mxs_reset_block(&priv->regs->hw_ssp_ctrl0_reg); @@ -571,16 +478,20 @@ static int mxs_ofdata_to_platdata(struct udevice *bus) return 0; } -#endif static const struct udevice_id mxs_spi_ids[] = { { .compatible = "fsl,imx23-spi" }, { .compatible = "fsl,imx28-spi" }, { } }; +#endif U_BOOT_DRIVER(mxs_spi) = { - .name = "mxs_spi", +#ifdef CONFIG_MX28 + .name = "fsl_imx28_spi", +#else /* CONFIG_MX23 */ + .name = "fsl_imx23_spi", +#endif .id = UCLASS_SPI, #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) .of_match = mxs_spi_ids, @@ -591,4 +502,3 @@ U_BOOT_DRIVER(mxs_spi) = { .priv_auto_alloc_size = sizeof(struct mxs_spi_priv), .probe = mxs_spi_probe, }; -#endif