summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/da8xx_gpio.c8
-rw-r--r--drivers/mmc/arm_pl180_mmci.c1
-rw-r--r--drivers/mmc/bfin_sdh.c69
-rw-r--r--drivers/mmc/davinci_mmc.c1
-rw-r--r--drivers/mmc/fsl_esdhc.c1
-rw-r--r--drivers/mmc/ftsdc010_esdhc.c1
-rw-r--r--drivers/mmc/gen_atmel_mci.c1
-rw-r--r--drivers/mmc/mmc.c17
-rw-r--r--drivers/mmc/mmc_spi.c1
-rw-r--r--drivers/mmc/mxcmmc.c1
-rw-r--r--drivers/mmc/mxsmmc.c1
-rw-r--r--drivers/mmc/omap_hsmmc.c103
-rw-r--r--drivers/mmc/sdhci.c1
-rw-r--r--drivers/mmc/sh_mmcif.c1
-rw-r--r--drivers/mmc/tegra_mmc.c1
-rw-r--r--drivers/mtd/nand/kmeter1_nand.c4
-rw-r--r--drivers/mtd/nand/nand_util.c19
-rw-r--r--drivers/mtd/onenand/onenand_spl.c14
-rw-r--r--drivers/net/cpsw.c20
-rw-r--r--drivers/net/fm/fm.c4
-rw-r--r--drivers/serial/sandbox.c44
-rw-r--r--drivers/serial/serial_ns16550.c12
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/bfin_spi6xx.c308
-rw-r--r--drivers/video/omap3_dss.c2
26 files changed, 570 insertions, 67 deletions
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 2d97b4f..9df1e26 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 271b8d9..76648d2 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 af1380a..ab2e81e 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 8d59d46..2631174 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 ee8f261..e2379e3 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 b90f3e7..54b5363 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 f1702fe..42f0e0c 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 67b2dbe..70a9f91 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 72e8ce6..7b5fdd9 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 11ba532..fe6a5a1 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 d58c18b..4f99617 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 b1537e2..a89660f 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 afd9b30..67cfcc2 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 b9cbe34..daca0ea 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 4588568..011d4f3 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 d749ab0..7258619 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 e8e5b7b..f044597 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 2ba0c5e..ff2d348 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 50eaa71..4bec2c2 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 db04795..93f8417 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 49c74c2..8d70586 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, &reg->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, &reg->muram);
fm_init_qmi(&reg->fm_qmi_common);
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index cb19401..b73520c 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 fc01a3c..b92eef4 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 83abcbd..b8264df 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 0000000..fde3447
--- /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 b1424bf..6efba12 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);