summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2010-06-30 10:10:32 +0200
committerWolfgang Denk <wd@denx.de>2010-06-30 10:10:32 +0200
commit39ddd10b046fb791f47281ffb2100be01909ad72 (patch)
treecec01ecc6502a65cbbbda406dfac23b93c093899 /drivers
parent55357b7846237d12aa5f07aec657c5dbfaf790ed (diff)
parent0a9463e93537a68e7246714f43fb69eca0b7b214 (diff)
downloadu-boot-imx-39ddd10b046fb791f47281ffb2100be01909ad72.zip
u-boot-imx-39ddd10b046fb791f47281ffb2100be01909ad72.tar.gz
u-boot-imx-39ddd10b046fb791f47281ffb2100be01909ad72.tar.bz2
Merge branch 'master' of ssh://gemini/home/wd/git/u-boot/master
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/pxa_mmc.c17
-rw-r--r--drivers/rtc/mc146818.c7
-rw-r--r--drivers/rtc/mk48t59.c18
-rw-r--r--drivers/spi/davinci_spi.c195
-rw-r--r--drivers/video/cfb_console.c12
-rw-r--r--drivers/video/sm501.c130
6 files changed, 258 insertions, 121 deletions
diff --git a/drivers/mmc/pxa_mmc.c b/drivers/mmc/pxa_mmc.c
index 8225235..8776903 100644
--- a/drivers/mmc/pxa_mmc.c
+++ b/drivers/mmc/pxa_mmc.c
@@ -126,7 +126,7 @@ mmc_block_read(uchar * dst, ulong src, ulong len)
MMC_I_MASK = ~MMC_I_MASK_RXFIFO_RD_REQ;
while (len) {
if (MMC_I_REG & MMC_I_REG_RXFIFO_RD_REQ) {
-#ifdef CONFIG_PXA27X
+#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
int i;
for (i = min(len, 32); i; i--) {
*dst++ = *((volatile uchar *)&MMC_RXFIFO);
@@ -558,8 +558,11 @@ mmc_legacy_init(int verbose)
set_GPIO_mode(GPIO6_MMCCLK_MD);
set_GPIO_mode(GPIO8_MMCCS0_MD);
#endif
+#ifdef CONFIG_CPU_MONAHANS /* pxa3xx */
+ CKENA |= CKENA_12_MMC0 | CKENA_13_MMC1;
+#else /* pxa2xx */
CKEN |= CKEN12_MMC; /* enable MMC unit clock */
-
+#endif
MMC_CLKRT = MMC_CLKRT_0_3125MHZ;
MMC_RESTO = MMC_RES_TO_MAX;
MMC_SPI = MMC_SPI_DISABLE;
@@ -584,11 +587,7 @@ mmc_legacy_init(int verbose)
debug("Detected SD card\n");
break;
}
-#ifdef CONFIG_PXA27X
- udelay(10000);
-#else
udelay(200000);
-#endif
}
if (retries <= 0 || !(IF_TYPE_SD == mmc_dev.if_type)) {
@@ -598,11 +597,7 @@ mmc_legacy_init(int verbose)
retries = 10;
while (retries-- && resp && !(resp[0] & 0x80000000)) {
-#ifdef CONFIG_PXA27X
- udelay(10000);
-#else
udelay(200000);
-#endif
resp =
mmc_cmd(MMC_CMD_SEND_OP_COND, 0x00ff, 0x8000,
MMC_CMDAT_R3);
@@ -632,7 +627,7 @@ mmc_legacy_init(int verbose)
MMC_CLKRT = 0; /* 20 MHz */
resp = mmc_cmd(MMC_CMD_SELECT_CARD, rca, 0, MMC_CMDAT_R1);
-#ifdef CONFIG_PXA27X
+#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
if (IF_TYPE_SD == mmc_dev.if_type) {
resp = mmc_cmd(MMC_CMD_APP_CMD, rca, 0, MMC_CMDAT_R1);
resp = mmc_cmd(SD_CMD_APP_SET_BUS_WIDTH, 0, 2, MMC_CMDAT_R1);
diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c
index d68b438..ac4eb6a 100644
--- a/drivers/rtc/mc146818.c
+++ b/drivers/rtc/mc146818.c
@@ -67,9 +67,6 @@ int rtc_get (struct rtc_time *tmp)
wday = rtc_read (RTC_DAY_OF_WEEK);
mon = rtc_read (RTC_MONTH);
year = rtc_read (RTC_YEAR);
-#ifdef CONFIG_AMIGAONEG3SE
- wday -= 1; /* VIA 686 stores Sunday = 1, Monday = 2, ... */
-#endif
#ifdef RTC_DEBUG
printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
"hr: %02x min: %02x sec: %02x\n",
@@ -114,11 +111,7 @@ int rtc_set (struct rtc_time *tmp)
rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
-#ifdef CONFIG_AMIGAONEG3SE
- rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)+1);
-#else
rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
-#endif
rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday));
rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
diff --git a/drivers/rtc/mk48t59.c b/drivers/rtc/mk48t59.c
index b176882..e285823 100644
--- a/drivers/rtc/mk48t59.c
+++ b/drivers/rtc/mk48t59.c
@@ -63,24 +63,6 @@ static void rtc_write (short reg, uchar val)
out8(RTC(reg),val);
}
-#elif defined(CONFIG_AMIGAONEG3SE)
-
-#include "../board/MAI/AmigaOneG3SE/via686.h"
-#include "../board/MAI/AmigaOneG3SE/memio.h"
-
-
-static uchar rtc_read (short reg)
-{
- out_byte(CMOS_ADDR, (uint8)reg);
- return in_byte(CMOS_DATA);
-}
-
-static void rtc_write (short reg, uchar val)
-{
- out_byte(CMOS_ADDR, (uint8)reg);
- out_byte(CMOS_DATA, (uint8)val);
-}
-
#elif defined(CONFIG_EVAL5200)
static uchar rtc_read (short reg)
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 08f837b..4518ecb 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -66,7 +66,7 @@ void spi_free_slave(struct spi_slave *slave)
int spi_claim_bus(struct spi_slave *slave)
{
struct davinci_spi_slave *ds = to_davinci_spi(slave);
- unsigned int scalar, data1_reg_val = 0;
+ unsigned int scalar;
/* Enable the SPI hardware */
writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
@@ -93,11 +93,6 @@ int spi_claim_bus(struct spi_slave *slave)
writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) |
(1 << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0);
- /* hold cs active at end of transfer until explicitly de-asserted */
- data1_reg_val = (1 << SPIDAT1_CSHOLD_SHIFT) |
- (slave->cs << SPIDAT1_CSNR_SHIFT);
- writel(data1_reg_val, &ds->regs->dat1);
-
/*
* Including a minor delay. No science here. Should be good even with
* no delay
@@ -113,8 +108,7 @@ int spi_claim_bus(struct spi_slave *slave)
writel(0, &ds->regs->lvl);
/* enable SPI */
- writel((readl(&ds->regs->gcr1) |
- SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
+ writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
return 0;
}
@@ -127,14 +121,125 @@ void spi_release_bus(struct spi_slave *slave)
writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
}
+/*
+ * This functions needs to act like a macro to avoid pipeline reloads in the
+ * loops below. Use always_inline. This gains us about 160KiB/s and the bloat
+ * appears to be zero bytes (da830).
+ */
+__attribute__((always_inline))
+static inline u32 davinci_spi_xfer_data(struct davinci_spi_slave *ds, u32 data)
+{
+ u32 buf_reg_val;
+
+ /* send out data */
+ writel(data, &ds->regs->dat1);
+
+ /* wait for the data to clock in/out */
+ while ((buf_reg_val = readl(&ds->regs->buf)) & SPIBUF_RXEMPTY_MASK)
+ ;
+
+ return buf_reg_val;
+}
+
+static int davinci_spi_read(struct spi_slave *slave, unsigned int len,
+ u8 *rxp, unsigned long flags)
+{
+ struct davinci_spi_slave *ds = to_davinci_spi(slave);
+ unsigned int data1_reg_val;
+
+ /* enable CS hold, CS[n] and clear the data bits */
+ data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
+ (slave->cs << SPIDAT1_CSNR_SHIFT));
+
+ /* wait till TXFULL is deasserted */
+ while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
+ ;
+
+ /* preload the TX buffer to avoid clock starvation */
+ writel(data1_reg_val, &ds->regs->dat1);
+
+ /* keep reading 1 byte until only 1 byte left */
+ while ((len--) > 1)
+ *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val);
+
+ /* clear CS hold when we reach the end */
+ if (flags & SPI_XFER_END)
+ data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
+
+ /* read the last byte */
+ *rxp = davinci_spi_xfer_data(ds, data1_reg_val);
+
+ return 0;
+}
+
+static int davinci_spi_write(struct spi_slave *slave, unsigned int len,
+ const u8 *txp, unsigned long flags)
+{
+ struct davinci_spi_slave *ds = to_davinci_spi(slave);
+ unsigned int data1_reg_val;
+
+ /* enable CS hold and clear the data bits */
+ data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
+ (slave->cs << SPIDAT1_CSNR_SHIFT));
+
+ /* wait till TXFULL is deasserted */
+ while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
+ ;
+
+ /* preload the TX buffer to avoid clock starvation */
+ if (len > 2) {
+ writel(data1_reg_val | *txp++, &ds->regs->dat1);
+ len--;
+ }
+
+ /* keep writing 1 byte until only 1 byte left */
+ while ((len--) > 1)
+ davinci_spi_xfer_data(ds, data1_reg_val | *txp++);
+
+ /* clear CS hold when we reach the end */
+ if (flags & SPI_XFER_END)
+ data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
+
+ /* write the last byte */
+ davinci_spi_xfer_data(ds, data1_reg_val | *txp);
+
+ return 0;
+}
+
+#ifndef CONFIG_SPI_HALF_DUPLEX
+static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len,
+ u8 *rxp, const u8 *txp, unsigned long flags)
+{
+ struct davinci_spi_slave *ds = to_davinci_spi(slave);
+ unsigned int data1_reg_val;
+
+ /* enable CS hold and clear the data bits */
+ data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
+ (slave->cs << SPIDAT1_CSNR_SHIFT));
+
+ /* wait till TXFULL is deasserted */
+ while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
+ ;
+
+ /* keep reading and writing 1 byte until only 1 byte left */
+ while ((len--) > 1)
+ *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val | *txp++);
+
+ /* clear CS hold when we reach the end */
+ if (flags & SPI_XFER_END)
+ data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
+
+ /* read and write the last byte */
+ *rxp = davinci_spi_xfer_data(ds, data1_reg_val | *txp);
+
+ return 0;
+}
+#endif
+
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
- struct davinci_spi_slave *ds = to_davinci_spi(slave);
- unsigned int len, data1_reg_val = readl(&ds->regs->dat1);
- unsigned int i_cnt = 0, o_cnt = 0, buf_reg_val;
- const u8 *txp = dout; /* dout can be NULL for read operation */
- u8 *rxp = din; /* din can be NULL for write operation */
+ unsigned int len;
if (bitlen == 0)
/* Finish any previously submitted transfers */
@@ -154,63 +259,19 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
len = bitlen / 8;
- /* do an empty read to clear the current contents */
- readl(&ds->regs->buf);
-
- /* keep writing and reading 1 byte until done */
- while ((i_cnt < len) || (o_cnt < len)) {
- /* read RX buffer and flags */
- buf_reg_val = readl(&ds->regs->buf);
-
- /* if data is available */
- if ((i_cnt < len) &&
- (buf_reg_val & SPIBUF_RXEMPTY_MASK) == 0) {
- /*
- * If there is no read buffer simply
- * ignore the read character
- */
- if (rxp)
- *rxp++ = buf_reg_val & 0xFF;
- /* increment read words count */
- i_cnt++;
- }
-
- /*
- * if the tx buffer is empty and there
- * is still data to transmit
- */
- if ((o_cnt < len) &&
- ((buf_reg_val & SPIBUF_TXFULL_MASK) == 0)) {
- /* write the data */
- data1_reg_val &= ~0xFFFF;
- if (txp)
- data1_reg_val |= *txp++;
- /*
- * Write to DAT1 is required to keep
- * the serial transfer going.
- * We just terminate when we reach the end.
- */
- if ((o_cnt == (len - 1)) && (flags & SPI_XFER_END)) {
- /* clear CS hold */
- writel(data1_reg_val &
- ~(1 << SPIDAT1_CSHOLD_SHIFT),
- &ds->regs->dat1);
- } else {
- /* enable CS hold and write TX register */
- data1_reg_val |= ((1 << SPIDAT1_CSHOLD_SHIFT) |
- (slave->cs << SPIDAT1_CSNR_SHIFT));
- writel(data1_reg_val, &ds->regs->dat1);
- }
- /* increment written words count */
- o_cnt++;
- }
- }
- return 0;
+ if (!dout)
+ return davinci_spi_read(slave, len, din, flags);
+ else if (!din)
+ return davinci_spi_write(slave, len, dout, flags);
+#ifndef CONFIG_SPI_HALF_DUPLEX
+ else
+ return davinci_spi_read_write(slave, len, din, dout, flags);
+#endif
out:
if (flags & SPI_XFER_END) {
- writel(data1_reg_val &
- ~(1 << SPIDAT1_CSHOLD_SHIFT), &ds->regs->dat1);
+ u8 dummy = 0;
+ davinci_spi_write(slave, 1, &dummy, flags);
}
return 0;
}
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index d1f47c9..96d52fb 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -749,6 +749,18 @@ void video_puts (const char *s)
/*****************************************************************************/
+/*
+ * Do not enforce drivers (or board code) to provide empty
+ * video_set_lut() if they do not support 8 bpp format.
+ * Implement weak default function instead.
+ */
+void __video_set_lut (unsigned int index, unsigned char r,
+ unsigned char g, unsigned char b)
+{
+}
+void video_set_lut (unsigned int, unsigned char, unsigned char, unsigned char)
+ __attribute__((weak, alias("__video_set_lut")));
+
#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
#define FILL_8BIT_332RGB(r,g,b) { \
diff --git a/drivers/video/sm501.c b/drivers/video/sm501.c
index 283d2d9..6a1e010 100644
--- a/drivers/video/sm501.c
+++ b/drivers/video/sm501.c
@@ -31,6 +31,7 @@
#include <common.h>
+#include <asm/io.h>
#include <video_fb.h>
#include <sm501.h>
@@ -54,6 +55,18 @@
GraphicDevice sm501;
+void write_be32(int off, unsigned int val)
+{
+ out_be32((unsigned __iomem *)(sm501.isaBase + off), val);
+}
+
+void write_le32(int off, unsigned int val)
+{
+ out_le32((unsigned __iomem *)(sm501.isaBase + off), val);
+}
+
+void (*write_reg32)(int off, unsigned int val) = write_be32;
+
/*-----------------------------------------------------------------------------
* SmiSetRegs --
*-----------------------------------------------------------------------------
@@ -66,7 +79,7 @@ static void SmiSetRegs (void)
*/
const SMI_REGS *preg = board_get_regs ();
while (preg->Index) {
- write32 (preg->Index, preg->Value);
+ write_reg32 (preg->Index, preg->Value);
/*
* Insert a delay between
*/
@@ -75,26 +88,120 @@ static void SmiSetRegs (void)
}
}
+#ifdef CONFIG_VIDEO_SM501_PCI
+static struct pci_device_id sm501_pci_tbl[] = {
+ { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_501 },
+ {}
+};
+#endif
+
+/*
+ * We do not enforce board code to provide empty/unused
+ * functions for this driver and define weak default
+ * functions here.
+ */
+unsigned int __board_video_init (void)
+{
+ return 0;
+}
+
+unsigned int board_video_init (void)
+ __attribute__((weak, alias("__board_video_init")));
+
+unsigned int __board_video_get_fb (void)
+{
+ return 0;
+}
+
+unsigned int board_video_get_fb (void)
+ __attribute__((weak, alias("__board_video_get_fb")));
+
+void __board_validate_screen (unsigned int base)
+{
+}
+
+void board_validate_screen (unsigned int base)
+ __attribute__((weak, alias("__board_validate_screen")));
+
/*-----------------------------------------------------------------------------
* video_hw_init --
*-----------------------------------------------------------------------------
*/
void *video_hw_init (void)
{
+#ifdef CONFIG_VIDEO_SM501_PCI
+ unsigned int pci_mem_base, pci_mmio_base;
+ unsigned int id;
+ unsigned short device_id;
+ pci_dev_t devbusfn;
+ int mem;
+#endif
unsigned int *vm, i;
memset (&sm501, 0, sizeof (GraphicDevice));
+#ifdef CONFIG_VIDEO_SM501_PCI
+ printf("Video: ");
+
+ /* Look for SM501/SM502 chips */
+ devbusfn = pci_find_devices(sm501_pci_tbl, 0);
+ if (devbusfn < 0) {
+ printf ("PCI Controller not found.\n");
+ goto not_pci;
+ }
+
+ /* Setup */
+ pci_write_config_dword (devbusfn, PCI_COMMAND,
+ (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+ pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
+ pci_read_config_dword (devbusfn, PCI_REVISION_ID, &id);
+ pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
+ pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_1, &pci_mmio_base);
+ sm501.frameAdrs = pci_mem_to_phys (devbusfn, pci_mem_base);
+ sm501.isaBase = pci_mem_to_phys (devbusfn, pci_mmio_base);
+
+ if (sm501.isaBase)
+ write_reg32 = write_le32;
+
+ mem = in_le32 ((unsigned __iomem *)(sm501.isaBase + 0x10));
+ mem = (mem & 0x0000e000) >> 13;
+ switch (mem) {
+ case 1:
+ mem = 8;
+ break;
+ case 2:
+ mem = 16;
+ break;
+ case 3:
+ mem = 32;
+ break;
+ case 4:
+ mem = 64;
+ break;
+ case 5:
+ mem = 2;
+ break;
+ case 0:
+ default:
+ mem = 4;
+ }
+ printf ("PCI SM50%d %d MB\n", ((id & 0xff) == 0xC0) ? 2 : 1, mem);
+not_pci:
+#endif
/*
* Initialization of the access to the graphic chipset Retreive base
* address of the chipset (see board/RPXClassic/eccx.c)
*/
- if ((sm501.isaBase = board_video_init ()) == 0) {
- return (NULL);
+ if (!sm501.isaBase) {
+ sm501.isaBase = board_video_init ();
+ if (!sm501.isaBase)
+ return NULL;
}
- if ((sm501.frameAdrs = board_video_get_fb ()) == 0) {
- return (NULL);
+ if (!sm501.frameAdrs) {
+ sm501.frameAdrs = board_video_get_fb ();
+ if (!sm501.frameAdrs)
+ return NULL;
}
sm501.winSizeX = board_get_width ();
@@ -131,16 +238,3 @@ void *video_hw_init (void)
return (&sm501);
}
-
-/*-----------------------------------------------------------------------------
- * video_set_lut --
- *-----------------------------------------------------------------------------
- */
-void video_set_lut (
- unsigned int index, /* color number */
- unsigned char r, /* red */
- unsigned char g, /* green */
- unsigned char b /* blue */
- )
-{
-}