diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
| -rw-r--r-- | drivers/gpio/da8xx_gpio.c | 8 | ||||
| -rw-r--r-- | drivers/mmc/arm_pl180_mmci.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/bfin_sdh.c | 69 | ||||
| -rw-r--r-- | drivers/mmc/davinci_mmc.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/fsl_esdhc.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/ftsdc010_esdhc.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/gen_atmel_mci.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/mmc.c | 17 | ||||
| -rw-r--r-- | drivers/mmc/mmc_spi.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/mxcmmc.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/mxsmmc.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/omap_hsmmc.c | 103 | ||||
| -rw-r--r-- | drivers/mmc/sdhci.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/sh_mmcif.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/tegra_mmc.c | 1 | ||||
| -rw-r--r-- | drivers/mtd/nand/kmeter1_nand.c | 4 | ||||
| -rw-r--r-- | drivers/mtd/nand/nand_util.c | 19 | ||||
| -rw-r--r-- | drivers/mtd/onenand/onenand_spl.c | 14 | ||||
| -rw-r--r-- | drivers/net/cpsw.c | 20 | ||||
| -rw-r--r-- | drivers/net/fm/fm.c | 4 | ||||
| -rw-r--r-- | drivers/serial/sandbox.c | 44 | ||||
| -rw-r--r-- | drivers/serial/serial_ns16550.c | 12 | ||||
| -rw-r--r-- | drivers/spi/Makefile | 1 | ||||
| -rw-r--r-- | drivers/spi/bfin_spi6xx.c | 308 | ||||
| -rw-r--r-- | drivers/video/omap3_dss.c | 2 | 
26 files changed, 570 insertions, 67 deletions
| diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 2d97b4f1e..9df1e2632 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -39,6 +39,7 @@ COBJS-$(CONFIG_SANDBOX_GPIO)	+= sandbox.o  COBJS-$(CONFIG_SPEAR_GPIO)	+= spear_gpio.o  COBJS-$(CONFIG_TEGRA_GPIO)	+= tegra_gpio.o  COBJS-$(CONFIG_DA8XX_GPIO)	+= da8xx_gpio.o +COBJS-$(CONFIG_DM644X_GPIO)	+= da8xx_gpio.o  COBJS-$(CONFIG_ALTERA_PIO)	+= altera_pio.o  COBJS-$(CONFIG_MPC83XX_GPIO)	+= mpc83xx_gpio.o  COBJS-$(CONFIG_SH_GPIO_PFC)	+= sh_pfc.o diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c index 271b8d93f..76648d27d 100644 --- a/drivers/gpio/da8xx_gpio.c +++ b/drivers/gpio/da8xx_gpio.c @@ -31,6 +31,7 @@ static struct gpio_registry {  	char name[GPIO_NAME_SIZE];  } gpio_registry[MAX_NUM_GPIOS]; +#if defined(CONFIG_SOC_DA8XX)  #define pinmux(x)       (&davinci_syscfg_regs->pinmux[x])  #if defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850) @@ -164,7 +165,7 @@ static const struct pinmux_config gpio_pinmux[] = {  	{ pinmux(0), 1, 0 },  	{ pinmux(0), 1, 1 },  }; -#else +#else /* CONFIG_SOC_DA8XX && CONFIG_SOC_DA850 */  static const struct pinmux_config gpio_pinmux[] = {  	{ pinmux(1), 8, 7 },	/* GP0[0] */  	{ pinmux(1), 8, 6 }, @@ -311,7 +312,10 @@ static const struct pinmux_config gpio_pinmux[] = {  	{ pinmux(18), 8, 3 },  	{ pinmux(18), 8, 2 },  }; -#endif +#endif /* CONFIG_SOC_DA8XX && !CONFIG_SOC_DA850 */ +#else /* !CONFIG_SOC_DA8XX */ +#define davinci_configure_pin_mux(a, b) +#endif /* CONFIG_SOC_DA8XX */  int gpio_request(unsigned gpio, const char *label)  { diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index af1380a45..ab2e81e5d 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -377,6 +377,7 @@ int arm_pl180_mmci_init(struct pl180_mmc_host *host)  	dev->set_ios = host_set_ios;  	dev->init = mmc_host_reset;  	dev->getcd = NULL; +	dev->getwp = NULL;  	dev->host_caps = host->caps;  	dev->voltages = host->voltages;  	dev->f_min = host->clock_min; diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index 8d59d46c6..26311741f 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -19,9 +19,7 @@  #include <asm/mach-common/bits/sdh.h>  #include <asm/mach-common/bits/dma.h> -#if defined(__ADSPBF50x__) || defined(__ADSPBF51x__) -# define bfin_read_SDH_PWR_CTL		bfin_read_RSI_PWR_CONTROL -# define bfin_write_SDH_PWR_CTL		bfin_write_RSI_PWR_CONTROL +#if defined(__ADSPBF50x__) || defined(__ADSPBF51x__) || defined(__ADSPBF60x__)  # define bfin_read_SDH_CLK_CTL		bfin_read_RSI_CLK_CONTROL  # define bfin_write_SDH_CLK_CTL		bfin_write_RSI_CLK_CONTROL  # define bfin_write_SDH_ARGUMENT	bfin_write_RSI_ARGUMENT @@ -38,10 +36,21 @@  # define bfin_write_SDH_STATUS_CLR 	bfin_write_RSI_STATUSCL  # define bfin_read_SDH_CFG		bfin_read_RSI_CONFIG  # define bfin_write_SDH_CFG		bfin_write_RSI_CONFIG +# if defined(__ADSPBF60x__) +# define bfin_read_SDH_BLK_SIZE		bfin_read_RSI_BLKSZ +# define bfin_write_SDH_BLK_SIZE	bfin_write_RSI_BLKSZ +# define bfin_write_DMA_START_ADDR	bfin_write_DMA10_START_ADDR +# define bfin_write_DMA_X_COUNT		bfin_write_DMA10_X_COUNT +# define bfin_write_DMA_X_MODIFY	bfin_write_DMA10_X_MODIFY +# define bfin_write_DMA_CONFIG		bfin_write_DMA10_CONFIG +# else +# define bfin_read_SDH_PWR_CTL		bfin_read_RSI_PWR_CONTROL +# define bfin_write_SDH_PWR_CTL		bfin_write_RSI_PWR_CONTROL  # define bfin_write_DMA_START_ADDR	bfin_write_DMA4_START_ADDR  # define bfin_write_DMA_X_COUNT		bfin_write_DMA4_X_COUNT  # define bfin_write_DMA_X_MODIFY	bfin_write_DMA4_X_MODIFY  # define bfin_write_DMA_CONFIG		bfin_write_DMA4_CONFIG +# endif  # define PORTMUX_PINS \  	{ P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0 }  #elif defined(__ADSPBF54x__) @@ -70,6 +79,9 @@ sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)  		sdh_cmd |= CMD_RSP;  	if (flags & MMC_RSP_136)  		sdh_cmd |= CMD_L_RSP; +#ifdef RSI_BLKSZ +	sdh_cmd |= CMD_DATA0_BUSY; +#endif  	bfin_write_SDH_ARGUMENT(arg);  	bfin_write_SDH_COMMAND(sdh_cmd); @@ -104,6 +116,12 @@ sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)  	bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT |  				CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT); +#ifdef RSI_BLKSZ +	/* wait till card ready */ +	while (!(bfin_read_RSI_ESTAT() & SD_CARD_READY)) +		continue; +	bfin_write_RSI_ESTAT(SD_CARD_READY); +#endif  	return ret;  } @@ -113,16 +131,19 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data)  {  	u16 data_ctl = 0;  	u16 dma_cfg = 0; -	int ret = 0;  	unsigned long data_size = data->blocksize * data->blocks;  	/* Don't support write yet. */  	if (data->flags & MMC_DATA_WRITE)  		return UNUSABLE_ERR; +#ifndef RSI_BLKSZ  	data_ctl |= ((ffs(data_size) - 1) << 4); +#else +	bfin_write_SDH_BLK_SIZE(data_size); +#endif  	data_ctl |= DTX_DIR;  	bfin_write_SDH_DATA_CTL(data_ctl); -	dma_cfg = WDSIZE_32 | RESTART | WNR | DMAEN; +	dma_cfg = WDSIZE_32 | PSIZE_32 | RESTART | WNR | DMAEN;  	bfin_write_SDH_DATA_TIMER(-1); @@ -137,7 +158,7 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data)  	/* kick off transfer */  	bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E); -	return ret; +	return 0;  } @@ -147,13 +168,23 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd,  	u32 status;  	int ret = 0; +	if (data) { +		ret = sdh_setup_data(mmc, data); +		if (ret) +			return ret; +	} +  	ret = sdh_send_cmd(mmc, cmd);  	if (ret) { +		bfin_write_SDH_COMMAND(0); +		bfin_write_DMA_CONFIG(0); +		bfin_write_SDH_DATA_CTL(0); +		SSYNC();  		printf("sending CMD%d failed\n", cmd->cmdidx);  		return ret;  	} +  	if (data) { -		ret = sdh_setup_data(mmc, data);  		do {  			udelay(1);  			status = bfin_read_SDH_STATUS(); @@ -208,10 +239,12 @@ static void bfin_sdh_set_ios(struct mmc *mmc)  	if (mmc->bus_width == 4) {  		cfg = bfin_read_SDH_CFG(); -		cfg &= ~0x80; -		cfg |= 0x40; +#ifndef RSI_BLKSZ +		cfg &= ~PD_SDDAT3; +#endif +		cfg |= PUP_SDDAT3;  		bfin_write_SDH_CFG(cfg); -		clk_ctl |= WIDE_BUS; +		clk_ctl |= WIDE_BUS_4;  	}  	bfin_write_SDH_CLK_CTL(clk_ctl);  	sdh_set_clk(mmc->clock); @@ -220,20 +253,23 @@ static void bfin_sdh_set_ios(struct mmc *mmc)  static int bfin_sdh_init(struct mmc *mmc)  {  	const unsigned short pins[] = PORTMUX_PINS; -	u16 pwr_ctl = 0; +	int ret;  	/* Initialize sdh controller */ -	peripheral_request_list(pins, "bfin_sdh"); +	ret = peripheral_request_list(pins, "bfin_sdh"); +	if (ret < 0) +		return ret;  #if defined(__ADSPBF54x__)  	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);  #endif  	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);  	/* Disable card detect pin */  	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | 0x60); - -	pwr_ctl |= ROD_CTL; -	pwr_ctl |= PWR_ON; -	bfin_write_SDH_PWR_CTL(pwr_ctl); +#ifndef RSI_BLKSZ +	bfin_write_SDH_PWR_CTL(PWR_ON | ROD_CTL); +#else +	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | PWR_ON); +#endif  	return 0;  } @@ -251,6 +287,7 @@ int bfin_mmc_init(bd_t *bis)  	mmc->set_ios = bfin_sdh_set_ios;  	mmc->init = bfin_sdh_init;  	mmc->getcd = NULL; +	mmc->getwp = NULL;  	mmc->host_caps = MMC_MODE_4BIT;  	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index ee8f2614d..e2379e326 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -388,6 +388,7 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host)  	mmc->set_ios = dmmc_set_ios;  	mmc->init = dmmc_init;  	mmc->getcd = NULL; +	mmc->getwp = NULL;  	mmc->f_min = 200000;  	mmc->f_max = 25000000; diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index b90f3e776..54b536316 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -552,6 +552,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)  	mmc->set_ios = esdhc_set_ios;  	mmc->init = esdhc_init;  	mmc->getcd = esdhc_getcd; +	mmc->getwp = NULL;  	voltage_caps = 0;  	caps = regs->hostcapblt; diff --git a/drivers/mmc/ftsdc010_esdhc.c b/drivers/mmc/ftsdc010_esdhc.c index f1702fe33..42f0e0ce5 100644 --- a/drivers/mmc/ftsdc010_esdhc.c +++ b/drivers/mmc/ftsdc010_esdhc.c @@ -666,6 +666,7 @@ int ftsdc010_mmc_init(int dev_index)  	mmc->set_ios = ftsdc010_set_ios;  	mmc->init = ftsdc010_core_init;  	mmc->getcd = NULL; +	mmc->getwp = NULL;  	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index 67b2dbe8d..70a9f91c8 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -349,6 +349,7 @@ int atmel_mci_init(void *regs)  	mmc->set_ios = mci_set_ios;  	mmc->init = mci_init;  	mmc->getcd = NULL; +	mmc->getwp = NULL;  	/* need to be able to pass these in on a board by board basis */  	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 72e8ce6da..7b5fdd9f6 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -40,6 +40,23 @@  static struct list_head mmc_devices;  static int cur_dev_num = -1; +int __weak board_mmc_getwp(struct mmc *mmc) +{ +	return -1; +} + +int mmc_getwp(struct mmc *mmc) +{ +	int wp; + +	wp = board_mmc_getwp(mmc); + +	if ((wp < 0) && mmc->getwp) +		wp = mmc->getwp(mmc); + +	return wp; +} +  int __board_mmc_getcd(struct mmc *mmc) {  	return -1;  } diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index 11ba532b0..fe6a5a166 100644 --- a/drivers/mmc/mmc_spi.c +++ b/drivers/mmc/mmc_spi.c @@ -273,6 +273,7 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)  	mmc->set_ios = mmc_spi_set_ios;  	mmc->init = mmc_spi_init_p;  	mmc->getcd = NULL; +	mmc->getwp = NULL;  	mmc->host_caps = MMC_MODE_SPI;  	mmc->voltages = MMC_SPI_VOLTAGE; diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c index d58c18bc2..4f99617b9 100644 --- a/drivers/mmc/mxcmmc.c +++ b/drivers/mmc/mxcmmc.c @@ -499,6 +499,7 @@ static int mxcmci_initialize(bd_t *bis)  	mmc->set_ios = mxcmci_set_ios;  	mmc->init = mxcmci_init;  	mmc->getcd = NULL; +	mmc->getwp = NULL;  	mmc->host_caps = MMC_MODE_4BIT;  	host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE; diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index b1537e24a..a89660f13 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -420,6 +420,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))  	mmc->set_ios = mxsmmc_set_ios;  	mmc->init = mxsmmc_init;  	mmc->getcd = NULL; +	mmc->getwp = NULL;  	mmc->priv = priv;  	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index afd9b30b5..67cfcc24d 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -30,6 +30,7 @@  #include <twl4030.h>  #include <twl6030.h>  #include <twl6035.h> +#include <asm/gpio.h>  #include <asm/io.h>  #include <asm/arch/mmc_host_def.h>  #include <asm/arch/sys_proto.h> @@ -38,30 +39,71 @@  #define SYSCTL_SRC	(1 << 25)  #define SYSCTL_SRD	(1 << 26) +struct omap_hsmmc_data { +	struct hsmmc *base_addr; +	int cd_gpio; +	int wp_gpio; +}; +  /* If we fail after 1 second wait, something is really bad */  #define MAX_RETRY_MS	1000  static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);  static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,  			unsigned int siz); -static struct mmc hsmmc_dev[2]; +static struct mmc hsmmc_dev[3]; +static struct omap_hsmmc_data hsmmc_dev_data[3]; + +#if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \ +	(defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT)) +static int omap_mmc_setup_gpio_in(int gpio, const char *label) +{ +	if (!gpio_is_valid(gpio)) +		return -1; + +	if (gpio_request(gpio, label) < 0) +		return -1; + +	if (gpio_direction_input(gpio) < 0) +		return -1; + +	return gpio; +} + +static int omap_mmc_getcd(struct mmc *mmc) +{ +	int cd_gpio = ((struct omap_hsmmc_data *)mmc->priv)->cd_gpio; +	return gpio_get_value(cd_gpio); +} + +static int omap_mmc_getwp(struct mmc *mmc) +{ +	int wp_gpio = ((struct omap_hsmmc_data *)mmc->priv)->wp_gpio; +	return gpio_get_value(wp_gpio); +} +#else +static inline int omap_mmc_setup_gpio_in(int gpio, const char *label) +{ +	return -1; +} + +#define omap_mmc_getcd NULL +#define omap_mmc_getwp NULL +#endif  #if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER)  static void omap4_vmmc_pbias_config(struct mmc *mmc)  {  	u32 value = 0; -	struct omap_sys_ctrl_regs *const ctrl = -		(struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE; - -	value = readl(&ctrl->control_pbiaslite); +	value = readl((*ctrl)->control_pbiaslite);  	value &= ~(MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ); -	writel(value, &ctrl->control_pbiaslite); +	writel(value, (*ctrl)->control_pbiaslite);  	/* set VMMC to 3V */  	twl6030_power_mmc_init(); -	value = readl(&ctrl->control_pbiaslite); +	value = readl((*ctrl)->control_pbiaslite);  	value |= MMC1_PBIASLITE_VMODE | MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ; -	writel(value, &ctrl->control_pbiaslite); +	writel(value, (*ctrl)->control_pbiaslite);  }  #endif @@ -69,26 +111,24 @@ static void omap4_vmmc_pbias_config(struct mmc *mmc)  static void omap5_pbias_config(struct mmc *mmc)  {  	u32 value = 0; -	struct omap_sys_ctrl_regs *const ctrl = -		(struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE; -	value = readl(&ctrl->control_pbias); +	value = readl((*ctrl)->control_pbias);  	value &= ~(SDCARD_PWRDNZ | SDCARD_BIAS_PWRDNZ);  	value |= SDCARD_BIAS_HIZ_MODE; -	writel(value, &ctrl->control_pbias); +	writel(value, (*ctrl)->control_pbias);  	twl6035_mmc1_poweron_ldo(); -	value = readl(&ctrl->control_pbias); +	value = readl((*ctrl)->control_pbias);  	value &= ~SDCARD_BIAS_HIZ_MODE;  	value |= SDCARD_PBIASLITE_VMODE | SDCARD_PWRDNZ | SDCARD_BIAS_PWRDNZ; -	writel(value, &ctrl->control_pbias); +	writel(value, (*ctrl)->control_pbias); -	value = readl(&ctrl->control_pbias); +	value = readl((*ctrl)->control_pbias);  	if (value & (1 << 23)) {  		value &= ~(SDCARD_PWRDNZ | SDCARD_BIAS_PWRDNZ);  		value |= SDCARD_BIAS_HIZ_MODE; -		writel(value, &ctrl->control_pbias); +		writel(value, (*ctrl)->control_pbias);  	}  }  #endif @@ -177,11 +217,12 @@ void mmc_init_stream(struct hsmmc *mmc_base)  static int mmc_init_setup(struct mmc *mmc)  { -	struct hsmmc *mmc_base = (struct hsmmc *)mmc->priv; +	struct hsmmc *mmc_base;  	unsigned int reg_val;  	unsigned int dsor;  	ulong start; +	mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;  	mmc_board_init(mmc);  	writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET, @@ -262,10 +303,11 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)  static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,  			struct mmc_data *data)  { -	struct hsmmc *mmc_base = (struct hsmmc *)mmc->priv; +	struct hsmmc *mmc_base;  	unsigned int flags, mmc_stat;  	ulong start; +	mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;  	start = get_timer(0);  	while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {  		if (get_timer(0) - start > MAX_RETRY_MS) { @@ -489,10 +531,11 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,  static void mmc_set_ios(struct mmc *mmc)  { -	struct hsmmc *mmc_base = (struct hsmmc *)mmc->priv; +	struct hsmmc *mmc_base;  	unsigned int dsor = 0;  	ulong start; +	mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;  	/* configue bus width */  	switch (mmc->bus_width) {  	case 8: @@ -540,36 +583,40 @@ static void mmc_set_ios(struct mmc *mmc)  	writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);  } -int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max) +int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, +		int wp_gpio)  { -	struct mmc *mmc; - -	mmc = &hsmmc_dev[dev_index]; +	struct mmc *mmc = &hsmmc_dev[dev_index]; +	struct omap_hsmmc_data *priv_data = &hsmmc_dev_data[dev_index];  	sprintf(mmc->name, "OMAP SD/MMC");  	mmc->send_cmd = mmc_send_cmd;  	mmc->set_ios = mmc_set_ios;  	mmc->init = mmc_init_setup; -	mmc->getcd = NULL; +	mmc->getcd = omap_mmc_getcd; +	mmc->getwp = omap_mmc_getwp; +	mmc->priv = priv_data;  	switch (dev_index) {  	case 0: -		mmc->priv = (struct hsmmc *)OMAP_HSMMC1_BASE; +		priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;  		break;  #ifdef OMAP_HSMMC2_BASE  	case 1: -		mmc->priv = (struct hsmmc *)OMAP_HSMMC2_BASE; +		priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE;  		break;  #endif  #ifdef OMAP_HSMMC3_BASE  	case 2: -		mmc->priv = (struct hsmmc *)OMAP_HSMMC3_BASE; +		priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE;  		break;  #endif  	default: -		mmc->priv = (struct hsmmc *)OMAP_HSMMC1_BASE; +		priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;  		return 1;  	} +	priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd"); +	priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp");  	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;  	mmc->host_caps = (MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |  				MMC_MODE_HC) & ~host_caps_mask; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index b9cbe34f1..daca0ea4f 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -438,6 +438,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)  	mmc->set_ios = sdhci_set_ios;  	mmc->init = sdhci_init;  	mmc->getcd = NULL; +	mmc->getwp = NULL;  	caps = sdhci_readl(host, SDHCI_CAPABILITIES);  #ifdef CONFIG_MMC_SDMA diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 4588568a6..011d4f3e6 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -599,6 +599,7 @@ int mmcif_mmc_init(void)  	mmc->set_ios = sh_mmcif_set_ios;  	mmc->init = sh_mmcif_init;  	mmc->getcd = NULL; +	mmc->getwp = NULL;  	host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR;  	host->clk = CONFIG_SH_MMCIF_CLK;  	mmc->priv = host; diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index d749ab095..72586193c 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -563,6 +563,7 @@ int tegra_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio)  	mmc->set_ios = mmc_set_ios;  	mmc->init = mmc_core_init;  	mmc->getcd = tegra_mmc_getcd; +	mmc->getwp = NULL;  	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;  	mmc->host_caps = 0; diff --git a/drivers/mtd/nand/kmeter1_nand.c b/drivers/mtd/nand/kmeter1_nand.c index e8e5b7b85..f04459723 100644 --- a/drivers/mtd/nand/kmeter1_nand.c +++ b/drivers/mtd/nand/kmeter1_nand.c @@ -119,7 +119,11 @@ static int kpn_nand_dev_ready(struct mtd_info *mtd)  int board_nand_init(struct nand_chip *nand)  { +#if defined(CONFIG_NAND_ECC_BCH) +	nand->ecc.mode = NAND_ECC_SOFT_BCH; +#else  	nand->ecc.mode = NAND_ECC_SOFT; +#endif  	/* Reference hardware control function */  	nand->cmd_ctrl  = kpn_nand_hwcontrol; diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 2ba0c5ef9..ff2d34830 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -237,6 +237,14 @@ int nand_lock(struct mtd_info *mtd, int tight)  	/* select the NAND device */  	chip->select_chip(mtd, 0); +	/* check the Lock Tight Status */ +	chip->cmdfunc(mtd, NAND_CMD_LOCK_STATUS, -1, 0); +	if (chip->read_byte(mtd) & NAND_LOCK_STATUS_TIGHT) { +		printf("nand_lock: Device is locked tight!\n"); +		ret = -1; +		goto out; +	} +  	chip->cmdfunc(mtd,  		      (tight ? NAND_CMD_LOCK_TIGHT : NAND_CMD_LOCK),  		      -1, -1); @@ -249,6 +257,7 @@ int nand_lock(struct mtd_info *mtd, int tight)  		ret = -1;  	} + out:  	/* de-select the NAND device */  	chip->select_chip(mtd, -1);  	return ret; @@ -337,6 +346,15 @@ int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length,  		goto out;  	} +	/* check the Lock Tight Status */ +	page = (int)(start >> chip->page_shift); +	chip->cmdfunc(mtd, NAND_CMD_LOCK_STATUS, -1, page & chip->pagemask); +	if (chip->read_byte(mtd) & NAND_LOCK_STATUS_TIGHT) { +		printf("nand_unlock: Device is locked tight!\n"); +		ret = -1; +		goto out; +	} +  	if ((start & (mtd->erasesize - 1)) != 0) {  		printf("nand_unlock: Start address must be beginning of "  			"nand block!\n"); @@ -358,7 +376,6 @@ int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length,  	length -= mtd->erasesize;  	/* submit address of first page to unlock */ -	page = (int)(start >> chip->page_shift);  	chip->cmdfunc(mtd, NAND_CMD_UNLOCK1, -1, page & chip->pagemask);  	/* submit ADDRESS of LAST page to unlock */ diff --git a/drivers/mtd/onenand/onenand_spl.c b/drivers/mtd/onenand/onenand_spl.c index 50eaa7188..4bec2c2ad 100644 --- a/drivers/mtd/onenand/onenand_spl.c +++ b/drivers/mtd/onenand/onenand_spl.c @@ -112,7 +112,7 @@ static int onenand_spl_read_page(uint32_t block, uint32_t page, uint32_t *buf,  void onenand_spl_load_image(uint32_t offs, uint32_t size, void *dst)  {  	uint32_t *addr = (uint32_t *)dst; -	uint32_t total_pages; +	uint32_t to_page;  	uint32_t block;  	uint32_t page, rpage;  	enum onenand_spl_pagesize pagesize; @@ -125,22 +125,20 @@ void onenand_spl_load_image(uint32_t offs, uint32_t size, void *dst)  	 * pulling further unwanted functions into the SPL.  	 */  	if (pagesize == 2048) { -		total_pages = DIV_ROUND_UP(size, 2048);  		page = offs / 2048; +		to_page = page + DIV_ROUND_UP(size, 2048);  	} else { -		total_pages = DIV_ROUND_UP(size, 4096);  		page = offs / 4096; +		to_page = page + DIV_ROUND_UP(size, 4096);  	} -	for (; page <= total_pages; page++) { +	for (; page <= to_page; page++) {  		block = page / ONENAND_PAGES_PER_BLOCK;  		rpage = page & (ONENAND_PAGES_PER_BLOCK - 1);  		ret = onenand_spl_read_page(block, rpage, addr, pagesize); -		if (ret) { -			total_pages += ONENAND_PAGES_PER_BLOCK; +		if (ret)  			page += ONENAND_PAGES_PER_BLOCK - 1; -		} else { +		else  			addr += pagesize / 4; -		}  	}  } diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index db04795df..93f8417a4 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -227,6 +227,9 @@ struct cpsw_priv {  	struct cpsw_slave		*slaves;  	struct phy_device		*phydev;  	struct mii_dev			*bus; + +	u32				mdio_link; +	u32				phy_mask;  };  static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) @@ -598,10 +601,21 @@ static int cpsw_update_link(struct cpsw_priv *priv)  	for_each_slave(slave, priv)  		cpsw_slave_update_link(slave, priv, &link); - +	priv->mdio_link = readl(&mdio_regs->link);  	return link;  } +static int cpsw_check_link(struct cpsw_priv *priv) +{ +	u32 link = 0; + +	link = __raw_readl(&mdio_regs->link) & priv->phy_mask; +	if ((link) && (link == priv->mdio_link)) +		return 1; + +	return cpsw_update_link(priv); +} +  static inline u32  cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)  {  	if (priv->host_port == 0) @@ -631,6 +645,8 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)  	cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD);  	cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave_port); + +	priv->phy_mask |= 1 << slave->data->phy_id;  }  static struct cpdma_desc *cpdma_desc_alloc(struct cpsw_priv *priv) @@ -862,7 +878,7 @@ static int cpsw_send(struct eth_device *dev, void *packet, int length)  	int len;  	int timeout = CPDMA_TIMEOUT; -	if (!cpsw_update_link(priv)) +	if (!cpsw_check_link(priv))  		return -EIO;  	flush_dcache_range((unsigned long)packet, diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c index 49c74c278..8d7058693 100644 --- a/drivers/net/fm/fm.c +++ b/drivers/net/fm/fm.c @@ -362,7 +362,6 @@ static void fm_init_qmi(struct fm_qmi_common *qmi)  int fm_init_common(int index, struct ccsr_fman *reg)  {  	int rc; -	char env_addr[32];  #if defined(CONFIG_SYS_QE_FMAN_FW_IN_NOR)  	void *addr = (void *)CONFIG_SYS_QE_FMAN_FW_ADDR;  #elif defined(CONFIG_SYS_QE_FMAN_FW_IN_NAND) @@ -416,8 +415,7 @@ int fm_init_common(int index, struct ccsr_fman *reg)  	rc = fman_upload_firmware(index, ®->fm_imem, addr);  	if (rc)  		return rc; -	sprintf(env_addr, "0x%lx", (long unsigned int)addr); -	setenv("fman_ucode", env_addr); +	setenv_addr("fman_ucode", addr);  	fm_init_muram(index, ®->muram);  	fm_init_qmi(®->fm_qmi_common); diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c index cb19401df..b73520ca9 100644 --- a/drivers/serial/sandbox.c +++ b/drivers/serial/sandbox.c @@ -30,6 +30,19 @@  #include <serial.h>  #include <linux/compiler.h> +/* + * + *   serial_buf: A buffer that holds keyboard characters for the + *		 Sandbox U-boot. + * + * invariants: + *   serial_buf_write		 == serial_buf_read -> empty buffer + *   (serial_buf_write + 1) % 16 == serial_buf_read -> full buffer + */ +static char serial_buf[16]; +static unsigned int serial_buf_write; +static unsigned int serial_buf_read; +  static int sandbox_serial_init(void)  {  	os_tty_raw(0); @@ -50,18 +63,37 @@ static void sandbox_serial_puts(const char *str)  	os_write(1, str, strlen(str));  } -static int sandbox_serial_getc(void) +static unsigned int increment_buffer_index(unsigned int index) +{ +	return (index + 1) % ARRAY_SIZE(serial_buf); +} + +static int sandbox_serial_tstc(void)  { -	char buf; +	const unsigned int next_index = +		increment_buffer_index(serial_buf_write);  	ssize_t count; -	count = os_read(0, &buf, 1); -	return count == 1 ? buf : 0; +	os_usleep(100); +	if (next_index == serial_buf_read) +		return 1;	/* buffer full */ + +	count = os_read_no_block(0, &serial_buf[serial_buf_write], 1); +	if (count == 1) +		serial_buf_write = next_index; +	return serial_buf_write != serial_buf_read;  } -static int sandbox_serial_tstc(void) +static int sandbox_serial_getc(void)  { -	return 0; +	int result; + +	while (!sandbox_serial_tstc()) +		;	/* buffer empty */ + +	result = serial_buf[serial_buf_read]; +	serial_buf_read = increment_buffer_index(serial_buf_read); +	return result;  }  static struct serial_device sandbox_serial_drv = { diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index fc01a3c51..b92eef4db 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -247,24 +247,36 @@ serial_setbrg_dev(unsigned int dev_index)  	_serial_setbrg(dev_index);  } +#if defined(CONFIG_SYS_NS16550_COM1)  DECLARE_ESERIAL_FUNCTIONS(1);  struct serial_device eserial1_device =  	INIT_ESERIAL_STRUCTURE(1, "eserial0"); +#endif +#if defined(CONFIG_SYS_NS16550_COM2)  DECLARE_ESERIAL_FUNCTIONS(2);  struct serial_device eserial2_device =  	INIT_ESERIAL_STRUCTURE(2, "eserial1"); +#endif +#if defined(CONFIG_SYS_NS16550_COM3)  DECLARE_ESERIAL_FUNCTIONS(3);  struct serial_device eserial3_device =  	INIT_ESERIAL_STRUCTURE(3, "eserial2"); +#endif +#if defined(CONFIG_SYS_NS16550_COM4)  DECLARE_ESERIAL_FUNCTIONS(4);  struct serial_device eserial4_device =  	INIT_ESERIAL_STRUCTURE(4, "eserial3"); +#endif +#if defined(CONFIG_SYS_NS16550_COM5)  DECLARE_ESERIAL_FUNCTIONS(5);  struct serial_device eserial5_device =  	INIT_ESERIAL_STRUCTURE(5, "eserial4"); +#endif +#if defined(CONFIG_SYS_NS16550_COM6)  DECLARE_ESERIAL_FUNCTIONS(6);  struct serial_device eserial6_device =  	INIT_ESERIAL_STRUCTURE(6, "eserial5"); +#endif  __weak struct serial_device *default_serial_console(void)  { diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 83abcbda2..b8264df3a 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -31,6 +31,7 @@ COBJS-$(CONFIG_ARMADA100_SPI) += armada100_spi.o  COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o  COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o  COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o +COBJS-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o  COBJS-$(CONFIG_CF_SPI) += cf_spi.o  COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o  COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o diff --git a/drivers/spi/bfin_spi6xx.c b/drivers/spi/bfin_spi6xx.c new file mode 100644 index 000000000..fde344742 --- /dev/null +++ b/drivers/spi/bfin_spi6xx.c @@ -0,0 +1,308 @@ +/* + * Analog Devices SPI3 controller driver + * + * Copyright (c) 2011 Analog Devices Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <malloc.h> +#include <spi.h> + +#include <asm/blackfin.h> +#include <asm/gpio.h> +#include <asm/portmux.h> +#include <asm/mach-common/bits/spi6xx.h> + +struct bfin_spi_slave { +	struct spi_slave slave; +	u32 control, clock; +	struct bfin_spi_regs *regs; +	int cs_pol; +}; + +#define to_bfin_spi_slave(s) container_of(s, struct bfin_spi_slave, slave) + +#define gpio_cs(cs) ((cs) - MAX_CTRL_CS) +#ifdef CONFIG_BFIN_SPI_GPIO_CS +# define is_gpio_cs(cs) ((cs) > MAX_CTRL_CS) +#else +# define is_gpio_cs(cs) 0 +#endif + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ +	if (is_gpio_cs(cs)) +		return gpio_is_valid(gpio_cs(cs)); +	else +		return (cs >= 1 && cs <= MAX_CTRL_CS); +} + +void spi_cs_activate(struct spi_slave *slave) +{ +	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); + +	if (is_gpio_cs(slave->cs)) { +		unsigned int cs = gpio_cs(slave->cs); +		gpio_set_value(cs, bss->cs_pol); +	} else { +		u32 ssel; +		ssel = bfin_read32(&bss->regs->ssel); +		ssel |= 1 << slave->cs; +		if (bss->cs_pol) +			ssel |= (1 << 8) << slave->cs; +		else +			ssel &= ~((1 << 8) << slave->cs); +		bfin_write32(&bss->regs->ssel, ssel); +	} + +	SSYNC(); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ +	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); + +	if (is_gpio_cs(slave->cs)) { +		unsigned int cs = gpio_cs(slave->cs); +		gpio_set_value(cs, !bss->cs_pol); +	} else { +		u32 ssel; +		ssel = bfin_read32(&bss->regs->ssel); +		if (bss->cs_pol) +			ssel &= ~((1 << 8) << slave->cs); +		else +			ssel |= (1 << 8) << slave->cs; +		/* deassert cs */ +		bfin_write32(&bss->regs->ssel, ssel); +		SSYNC(); +		/* disable cs */ +		ssel &= ~(1 << slave->cs); +		bfin_write32(&bss->regs->ssel, ssel); +	} + +	SSYNC(); +} + +void spi_init() +{ +} + +#define SPI_PINS(n) \ +	{ 0, P_SPI##n##_SCK, P_SPI##n##_MISO, P_SPI##n##_MOSI, 0 } +static unsigned short pins[][5] = { +#ifdef SPI0_REGBASE +	[0] = SPI_PINS(0), +#endif +#ifdef SPI1_REGBASE +	[1] = SPI_PINS(1), +#endif +#ifdef SPI2_REGBASE +	[2] = SPI_PINS(2), +#endif +}; + +#define SPI_CS_PINS(n) \ +	{ \ +		P_SPI##n##_SSEL1, P_SPI##n##_SSEL2, P_SPI##n##_SSEL3, \ +		P_SPI##n##_SSEL4, P_SPI##n##_SSEL5, P_SPI##n##_SSEL6, \ +		P_SPI##n##_SSEL7, \ +	} +static const unsigned short cs_pins[][7] = { +#ifdef SPI0_REGBASE +	[0] = SPI_CS_PINS(0), +#endif +#ifdef SPI1_REGBASE +	[1] = SPI_CS_PINS(1), +#endif +#ifdef SPI2_REGBASE +	[2] = SPI_CS_PINS(2), +#endif +}; + +void spi_set_speed(struct spi_slave *slave, uint hz) +{ +	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); +	ulong sclk; +	u32 clock; + +	sclk = get_sclk1(); +	clock = sclk / hz; +	if (clock) +		clock--; +	bss->clock = clock; +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, +		unsigned int max_hz, unsigned int mode) +{ +	struct bfin_spi_slave *bss; +	u32 reg_base; + +	if (!spi_cs_is_valid(bus, cs)) +		return NULL; + +	if (bus >= ARRAY_SIZE(pins) || pins[bus] == NULL) { +		debug("%s: invalid bus %u\n", __func__, bus); +		return NULL; +	} +	switch (bus) { +#ifdef SPI0_REGBASE +	case 0: +		reg_base = SPI0_REGBASE; +		break; +#endif +#ifdef SPI1_REGBASE +	case 1: +		reg_base = SPI1_REGBASE; +		break; +#endif +#ifdef SPI2_REGBASE +	case 2: +		reg_base = SPI2_REGBASE; +		break; +#endif +	default: +		return NULL; +	} + +	bss = malloc(sizeof(*bss)); +	if (!bss) +		return NULL; + +	bss->slave.bus = bus; +	bss->slave.cs = cs; +	bss->regs = (struct bfin_spi_regs *)reg_base; +	bss->control = SPI_CTL_EN | SPI_CTL_MSTR; +	if (mode & SPI_CPHA) +		bss->control |= SPI_CTL_CPHA; +	if (mode & SPI_CPOL) +		bss->control |= SPI_CTL_CPOL; +	if (mode & SPI_LSB_FIRST) +		bss->control |= SPI_CTL_LSBF; +	bss->control &= ~SPI_CTL_ASSEL; +	bss->cs_pol = mode & SPI_CS_HIGH ? 1 : 0; +	spi_set_speed(&bss->slave, max_hz); + +	return &bss->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ +	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); +	free(bss); +} + +int spi_claim_bus(struct spi_slave *slave) +{ +	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); + +	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); + +	if (is_gpio_cs(slave->cs)) { +		unsigned int cs = gpio_cs(slave->cs); +		gpio_request(cs, "bfin-spi"); +		gpio_direction_output(cs, !bss->cs_pol); +		pins[slave->bus][0] = P_DONTCARE; +	} else +		pins[slave->bus][0] = cs_pins[slave->bus][slave->cs - 1]; +	peripheral_request_list(pins[slave->bus], "bfin-spi"); + +	bfin_write32(&bss->regs->control, bss->control); +	bfin_write32(&bss->regs->clock, bss->clock); +	bfin_write32(&bss->regs->delay, 0x0); +	bfin_write32(&bss->regs->rx_control, SPI_RXCTL_REN); +	bfin_write32(&bss->regs->tx_control, SPI_TXCTL_TEN | SPI_TXCTL_TTI); +	SSYNC(); + +	return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ +	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); + +	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); + +	peripheral_free_list(pins[slave->bus]); +	if (is_gpio_cs(slave->cs)) +		gpio_free(gpio_cs(slave->cs)); + +	bfin_write32(&bss->regs->rx_control, 0x0); +	bfin_write32(&bss->regs->tx_control, 0x0); +	bfin_write32(&bss->regs->control, 0x0); +	SSYNC(); +} + +#ifndef CONFIG_BFIN_SPI_IDLE_VAL +# define CONFIG_BFIN_SPI_IDLE_VAL 0xff +#endif + +static int spi_pio_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx, +			uint bytes) +{ +	/* discard invalid rx data and empty rfifo */ +	while (!(bfin_read32(&bss->regs->status) & SPI_STAT_RFE)) +		bfin_read32(&bss->regs->rfifo); + +	while (bytes--) { +		u8 value = (tx ? *tx++ : CONFIG_BFIN_SPI_IDLE_VAL); +		debug("%s: tx:%x ", __func__, value); +		bfin_write32(&bss->regs->tfifo, value); +		SSYNC(); +		while (bfin_read32(&bss->regs->status) & SPI_STAT_RFE) +			if (ctrlc()) +				return -1; +		value = bfin_read32(&bss->regs->rfifo); +		if (rx) +			*rx++ = value; +		debug("rx:%x\n", value); +	} + +	return 0; +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, +		void *din, unsigned long flags) +{ +	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); +	const u8 *tx = dout; +	u8 *rx = din; +	uint bytes = bitlen / 8; +	int ret = 0; + +	debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__, +		slave->bus, slave->cs, bitlen, bytes, flags); + +	if (bitlen == 0) +		goto done; + +	/* we can only do 8 bit transfers */ +	if (bitlen % 8) { +		flags |= SPI_XFER_END; +		goto done; +	} + +	if (flags & SPI_XFER_BEGIN) +		spi_cs_activate(slave); + +	ret = spi_pio_xfer(bss, tx, rx, bytes); + + done: +	if (flags & SPI_XFER_END) +		spi_cs_deactivate(slave); + +	return ret; +} diff --git a/drivers/video/omap3_dss.c b/drivers/video/omap3_dss.c index b1424bfd0..6efba122e 100644 --- a/drivers/video/omap3_dss.c +++ b/drivers/video/omap3_dss.c @@ -121,7 +121,7 @@ void omap3_dss_panel_config(const struct panel_config *panel_cfg)  	if (!panel_cfg->frame_buffer)  		return; -	writel(8 << GFX_FORMAT_SHIFT | GFX_ENABLE, &dispc->gfx_attributes); +	writel(panel_cfg->gfx_format | GFX_ENABLE, &dispc->gfx_attributes);  	writel(1, &dispc->gfx_row_inc);  	writel(1, &dispc->gfx_pixel_inc);  	writel(panel_cfg->lcd_size, &dispc->gfx_size); |